/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "src/compiler/cpp_generator.h"

#include <map>
#include <sstream>
#include <vector>

namespace grpc_cpp_generator {
namespace {

template <class T>
std::string as_string(T x) {
  std::ostringstream out;
  out << x;
  return out.str();
}

inline bool ClientOnlyStreaming(const grpc_generator::Method* method) {
  return method->ClientStreaming() && !method->ServerStreaming();
}

inline bool ServerOnlyStreaming(const grpc_generator::Method* method) {
  return !method->ClientStreaming() && method->ServerStreaming();
}

std::string FilenameIdentifier(const std::string& filename) {
  std::string result;
  for (unsigned i = 0; i < filename.size(); i++) {
    char c = filename[i];
    if (isalnum(c)) {
      result.push_back(c);
    } else {
      static char hex[] = "0123456789abcdef";
      result.push_back('_');
      result.push_back(hex[(c >> 4) & 0xf]);
      result.push_back(hex[c & 0xf]);
    }
  }
  return result;
}

}  // namespace

template <class T, size_t N>
T* array_end(T (&array)[N]) {
  return array + N;
}

void PrintIncludes(grpc_generator::Printer* printer,
                   const std::vector<std::string>& headers,
                   bool use_system_headers, const std::string& search_path) {
  std::map<std::string, std::string> vars;

  vars["l"] = use_system_headers ? '<' : '"';
  vars["r"] = use_system_headers ? '>' : '"';

  if (!search_path.empty()) {
    vars["l"] += search_path;
    if (search_path[search_path.size() - 1] != '/') {
      vars["l"] += '/';
    }
  }

  for (auto i = headers.begin(); i != headers.end(); i++) {
    vars["h"] = *i;
    printer->Print(vars, "#include $l$$h$$r$\n");
  }
}

std::string GetHeaderPrologue(grpc_generator::File* file,
                              const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;

    vars["filename"] = file->filename();
    vars["filename_identifier"] = FilenameIdentifier(file->filename());
    vars["filename_base"] = file->filename_without_ext();
    vars["message_header_ext"] = params.message_header_extension.empty()
                                     ? kCppGeneratorMessageHeaderExt
                                     : params.message_header_extension;

    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
    printer->Print(vars,
                   "// If you make any local change, they will be lost.\n");
    printer->Print(vars, "// source: $filename$\n");
    std::string leading_comments = file->GetLeadingComments("//");
    if (!leading_comments.empty()) {
      printer->Print(vars, "// Original file comments:\n");
      printer->PrintRaw(leading_comments.c_str());
    }
    printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
    printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
    printer->Print(vars, "\n");
    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
    printer->Print(vars, file->additional_headers().c_str());
    printer->Print(vars, "\n");
  }
  return output;
}

// Convert from "a/b/c.proto" to "#include \"a/b/c$message_header_ext$\"\n"
std::string ImportInludeFromProtoName(const std::string& proto_name) {
  return std::string("#include \"") +
         proto_name.substr(0, proto_name.size() - 6) +
         std::string("$message_header_ext$\"\n");
}

std::string GetHeaderIncludes(grpc_generator::File* file,
                              const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;

    if (!params.additional_header_includes.empty()) {
      PrintIncludes(printer.get(), params.additional_header_includes, false,
                    "");
    }
    static const char* headers_strs[] = {
        "functional",
        "grpcpp/generic/async_generic_service.h",
        "grpcpp/support/async_stream.h",
        "grpcpp/support/async_unary_call.h",
        "grpcpp/support/client_callback.h",
        "grpcpp/client_context.h",
        "grpcpp/completion_queue.h",
        "grpcpp/support/message_allocator.h",
        "grpcpp/support/method_handler.h",
        "grpcpp/impl/proto_utils.h",
        "grpcpp/impl/rpc_method.h",
        "grpcpp/support/server_callback.h",
        "grpcpp/impl/server_callback_handlers.h",
        "grpcpp/server_context.h",
        "grpcpp/impl/service_type.h",
        "grpcpp/support/status.h",
        "grpcpp/support/stub_options.h",
        "grpcpp/support/sync_stream.h",
        // ports_def.inc Must be included at last
        "grpcpp/ports_def.inc",
    };
    std::vector<std::string> headers(headers_strs, array_end(headers_strs));
    PrintIncludes(printer.get(), headers, params.use_system_headers,
                  params.grpc_search_path);
    printer->Print(vars, "\n");

    vars["message_header_ext"] = params.message_header_extension.empty()
                                     ? kCppGeneratorMessageHeaderExt
                                     : params.message_header_extension;

    if (params.include_import_headers) {
      const std::vector<std::string> import_names = file->GetImportNames();
      for (const auto& import_name : import_names) {
        const std::string include_name = ImportInludeFromProtoName(import_name);
        printer->Print(vars, include_name.c_str());
      }
      printer->PrintRaw("\n");
    }

    if (!file->package().empty()) {
      std::vector<std::string> parts = file->package_parts();

      for (auto part = parts.begin(); part != parts.end(); part++) {
        vars["part"] = *part;
        printer->Print(vars, "namespace $part$ {\n");
      }
      printer->Print(vars, "\n");
    }
  }
  return output;
}

void PrintHeaderClientMethodInterfaces(grpc_generator::Printer* printer,
                                       const grpc_generator::Method* method,
                                       const Parameters& params,
                                       std::map<std::string, std::string>* vars,
                                       bool is_public) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();

  struct {
    std::string prefix;
    std::string method_params;  // extra arguments to method
    std::string raw_args;       // extra arguments to raw version of method
  } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
                        {"PrepareAsync", "", ""}};

  if (is_public) {
    if (method->NoStreaming()) {
      printer->Print(
          *vars,
          "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
          "const $Request$& request, $Response$* response) = 0;\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          printer->Print(
              *vars,
              "std::unique_ptr< "
              "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
              "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
              "const $Request$& request, "
              "::grpc::CompletionQueue* cq) {\n");
          printer->Indent();
          printer->Print(
              *vars,
              "return std::unique_ptr< "
              "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
              "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
          printer->Outdent();
          printer->Print("}\n");
        }
      }
    } else if (ClientOnlyStreaming(method)) {
      printer->Print(
          *vars,
          "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
          " $Method$("
          "::grpc::ClientContext* context, $Response$* response) {\n");
      printer->Indent();
      printer->Print(
          *vars,
          "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
          "($Method$Raw(context, response));\n");
      printer->Outdent();
      printer->Print("}\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
              " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
              "$Response$* "
              "response, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
          printer->Indent();
          printer->Print(*vars,
                         "return std::unique_ptr< "
                         "::grpc::ClientAsyncWriterInterface< $Request$>>("
                         "$AsyncPrefix$$Method$Raw(context, response, "
                         "cq$AsyncRawArgs$));\n");
          printer->Outdent();
          printer->Print("}\n");
        }
      }
    } else if (ServerOnlyStreaming(method)) {
      printer->Print(
          *vars,
          "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
          " $Method$(::grpc::ClientContext* context, const $Request$& request)"
          " {\n");
      printer->Indent();
      printer->Print(
          *vars,
          "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
          "($Method$Raw(context, request));\n");
      printer->Outdent();
      printer->Print("}\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< "
              "$Response$>> "
              "$AsyncPrefix$$Method$("
              "::grpc::ClientContext* context, const $Request$& request, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
          printer->Indent();
          printer->Print(*vars,
                         "return std::unique_ptr< "
                         "::grpc::ClientAsyncReaderInterface< $Response$>>("
                         "$AsyncPrefix$$Method$Raw(context, request, "
                         "cq$AsyncRawArgs$));\n");
          printer->Outdent();
          printer->Print("}\n");
        }
      }
    } else if (method->BidiStreaming()) {
      printer->Print(*vars,
                     "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
                     "$Request$, $Response$>> "
                     "$Method$(::grpc::ClientContext* context) {\n");
      printer->Indent();
      printer->Print(
          *vars,
          "return std::unique_ptr< "
          "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
          "$Method$Raw(context));\n");
      printer->Outdent();
      printer->Print("}\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "std::unique_ptr< "
              "::grpc::ClientAsyncReaderWriterInterface< $Request$, "
              "$Response$>> "
              "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
          printer->Indent();
          printer->Print(
              *vars,
              "return std::unique_ptr< "
              "::grpc::ClientAsyncReaderWriterInterface< $Request$, "
              "$Response$>>("
              "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
          printer->Outdent();
          printer->Print("}\n");
        }
      }
    }
  } else {
    if (method->NoStreaming()) {
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          printer->Print(
              *vars,
              "virtual ::grpc::ClientAsyncResponseReaderInterface< "
              "$Response$>* "
              "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
              "const $Request$& request, "
              "::grpc::CompletionQueue* cq) = 0;\n");
        }
      }
    } else if (ClientOnlyStreaming(method)) {
      printer->Print(
          *vars,
          "virtual ::grpc::ClientWriterInterface< $Request$>*"
          " $Method$Raw("
          "::grpc::ClientContext* context, $Response$* response) = 0;\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          printer->Print(
              *vars,
              "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
              " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
              "$Response$* response, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
        }
      }
    } else if (ServerOnlyStreaming(method)) {
      printer->Print(
          *vars,
          "virtual ::grpc::ClientReaderInterface< $Response$>* "
          "$Method$Raw("
          "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          printer->Print(
              *vars,
              "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
              "$AsyncPrefix$$Method$Raw("
              "::grpc::ClientContext* context, const $Request$& request, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
        }
      }
    } else if (method->BidiStreaming()) {
      printer->Print(*vars,
                     "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
                     "$Response$>* "
                     "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          printer->Print(
              *vars,
              "virtual ::grpc::ClientAsyncReaderWriterInterface< "
              "$Request$, $Response$>* "
              "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
        }
      }
    }
  }
}

void PrintHeaderClientMethod(grpc_generator::Printer* printer,
                             const grpc_generator::Method* method,
                             const Parameters& params,
                             std::map<std::string, std::string>* vars,
                             bool is_public) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  struct {
    std::string prefix;
    std::string method_params;  // extra arguments to method
    std::string raw_args;       // extra arguments to raw version of method
  } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
                        {"PrepareAsync", "", ""}};

  if (is_public) {
    if (method->NoStreaming()) {
      printer->Print(
          *vars,
          "::grpc::Status $Method$(::grpc::ClientContext* context, "
          "const $Request$& request, $Response$* response) override;\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          printer->Print(
              *vars,
              "std::unique_ptr< ::grpc::ClientAsyncResponseReader< "
              "$Response$>> "
              "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
              "const $Request$& request, "
              "::grpc::CompletionQueue* cq) {\n");
          printer->Indent();
          printer->Print(*vars,
                         "return std::unique_ptr< "
                         "::grpc::ClientAsyncResponseReader< $Response$>>("
                         "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
          printer->Outdent();
          printer->Print("}\n");
        }
      }
    } else if (ClientOnlyStreaming(method)) {
      printer->Print(
          *vars,
          "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
          " $Method$("
          "::grpc::ClientContext* context, $Response$* response) {\n");
      printer->Indent();
      printer->Print(*vars,
                     "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
                     "($Method$Raw(context, response));\n");
      printer->Outdent();
      printer->Print("}\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
              " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
              "$Response$* response, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
          printer->Indent();
          printer->Print(
              *vars,
              "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
              "$AsyncPrefix$$Method$Raw(context, response, "
              "cq$AsyncRawArgs$));\n");
          printer->Outdent();
          printer->Print("}\n");
        }
      }
    } else if (ServerOnlyStreaming(method)) {
      printer->Print(
          *vars,
          "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
          " $Method$(::grpc::ClientContext* context, const $Request$& request)"
          " {\n");
      printer->Indent();
      printer->Print(
          *vars,
          "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
          "($Method$Raw(context, request));\n");
      printer->Outdent();
      printer->Print("}\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
              "$AsyncPrefix$$Method$("
              "::grpc::ClientContext* context, const $Request$& request, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
          printer->Indent();
          printer->Print(
              *vars,
              "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
              "$AsyncPrefix$$Method$Raw(context, request, "
              "cq$AsyncRawArgs$));\n");
          printer->Outdent();
          printer->Print("}\n");
        }
      }
    } else if (method->BidiStreaming()) {
      printer->Print(
          *vars,
          "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
          " $Method$(::grpc::ClientContext* context) {\n");
      printer->Indent();
      printer->Print(*vars,
                     "return std::unique_ptr< "
                     "::grpc::ClientReaderWriter< $Request$, $Response$>>("
                     "$Method$Raw(context));\n");
      printer->Outdent();
      printer->Print("}\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< "
              "$Request$, $Response$>> "
              "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
          printer->Indent();
          printer->Print(
              *vars,
              "return std::unique_ptr< "
              "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
              "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
          printer->Outdent();
          printer->Print("}\n");
        }
      }
    }
  } else {
    if (method->NoStreaming()) {
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          printer->Print(
              *vars,
              "::grpc::ClientAsyncResponseReader< $Response$>* "
              "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
              "const $Request$& request, "
              "::grpc::CompletionQueue* cq) override;\n");
        }
      }
    } else if (ClientOnlyStreaming(method)) {
      printer->Print(*vars,
                     "::grpc::ClientWriter< $Request$>* $Method$Raw("
                     "::grpc::ClientContext* context, $Response$* response) "
                     "override;\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
              "::grpc::ClientContext* context, $Response$* response, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
        }
      }
    } else if (ServerOnlyStreaming(method)) {
      printer->Print(*vars,
                     "::grpc::ClientReader< $Response$>* $Method$Raw("
                     "::grpc::ClientContext* context, const $Request$& request)"
                     " override;\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "::grpc::ClientAsyncReader< $Response$>* "
              "$AsyncPrefix$$Method$Raw("
              "::grpc::ClientContext* context, const $Request$& request, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
        }
      }
    } else if (method->BidiStreaming()) {
      printer->Print(*vars,
                     "::grpc::ClientReaderWriter< $Request$, $Response$>* "
                     "$Method$Raw(::grpc::ClientContext* context) override;\n");
      if (params.allow_cq_api) {
        for (const auto& async_prefix : async_prefixes) {
          (*vars)["AsyncPrefix"] = async_prefix.prefix;
          (*vars)["AsyncMethodParams"] = async_prefix.method_params;
          (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
          printer->Print(
              *vars,
              "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
              "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
              "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
        }
      }
    }
  }
}

void PrintHeaderClientMethodCallbackInterfacesStart(
    grpc_generator::Printer* printer,
    std::map<std::string, std::string>* /*vars*/) {
  // This declares the interface for the callback-based API. The components
  // are pure; even though this is new (post-1.0) API, it can be pure because
  // it is an entirely new interface that happens to be scoped within
  // StubInterface, not new additions to StubInterface itself
  printer->Print("class async_interface {\n");
  // All methods in this new interface are public. There is no need for private
  // "Raw" methods since the callback-based API returns unowned raw pointers
  printer->Print(" public:\n");
  printer->Indent();
  printer->Print("virtual ~async_interface() {}\n");
}

void PrintHeaderClientMethodCallbackInterfaces(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();

  if (method->NoStreaming()) {
    printer->Print(*vars,
                   "virtual void $Method$(::grpc::ClientContext* context, "
                   "const $Request$* request, $Response$* response, "
                   "std::function<void(::grpc::Status)>) = 0;\n");
    printer->Print(*vars,
                   "virtual void $Method$(::grpc::ClientContext* context, "
                   "const $Request$* request, $Response$* response, "
                   "::grpc::ClientUnaryReactor* reactor) = 0;\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(*vars,
                   "virtual void $Method$(::grpc::ClientContext* context, "
                   "$Response$* response, "
                   "::grpc::ClientWriteReactor< $Request$>* "
                   "reactor) = 0;\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(*vars,
                   "virtual void $Method$(::grpc::ClientContext* context, "
                   "const $Request$* request, "
                   "::grpc::ClientReadReactor< $Response$>* "
                   "reactor) = 0;\n");
  } else if (method->BidiStreaming()) {
    printer->Print(*vars,
                   "virtual void $Method$(::grpc::ClientContext* context, "
                   "::grpc::ClientBidiReactor< "
                   "$Request$,$Response$>* reactor) = 0;\n");
  }
}

void PrintHeaderClientMethodCallbackInterfacesEnd(
    grpc_generator::Printer* printer,
    std::map<std::string, std::string>* /*vars*/) {
  printer->Outdent();
  printer->Print("};\n");
  // TODO: Remove typedef when all uses of experimental_async are migrated off.
  printer->Print(
      "typedef class async_interface experimental_async_interface;\n");

  // Declare a function to give the async stub contents. It can't be pure
  // since this is a new API in StubInterface, but it is meaningless by default
  // (since any stub that wants to use it must have its own implementation of
  // the callback functions therein), so make the default return value nullptr.
  // Intentionally include the word "class" to avoid possible shadowing.
  // TODO: Remove experimental_async call when possible, replace with nullptr.
  printer->Print(
      "virtual class async_interface* async() { return nullptr; }\n");

  // TODO: Remove experimental_async call when possible.
  printer->Print(
      "class async_interface* experimental_async() { return async(); }\n");
}

void PrintHeaderClientMethodCallbackStart(
    grpc_generator::Printer* printer,
    std::map<std::string, std::string>* /*vars*/) {
  // This declares the stub entry for the callback-based API.
  printer->Print("class async final :\n");
  printer->Print("  public StubInterface::async_interface {\n");
  printer->Print(" public:\n");
  printer->Indent();
}

void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
                                     const grpc_generator::Method* method,
                                     std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();

  if (method->NoStreaming()) {
    printer->Print(*vars,
                   "void $Method$(::grpc::ClientContext* context, "
                   "const $Request$* request, $Response$* response, "
                   "std::function<void(::grpc::Status)>) override;\n");
    printer->Print(*vars,
                   "void $Method$(::grpc::ClientContext* context, "
                   "const $Request$* request, $Response$* response, "
                   "::grpc::ClientUnaryReactor* reactor) override;\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(*vars,
                   "void $Method$(::grpc::ClientContext* context, "
                   "$Response$* response, "
                   "::grpc::ClientWriteReactor< $Request$>* "
                   "reactor) override;\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(*vars,
                   "void $Method$(::grpc::ClientContext* context, "
                   "const $Request$* request, "
                   "::grpc::ClientReadReactor< $Response$>* "
                   "reactor) override;\n");

  } else if (method->BidiStreaming()) {
    printer->Print(*vars,
                   "void $Method$(::grpc::ClientContext* context, "
                   "::grpc::ClientBidiReactor< "
                   "$Request$,$Response$>* reactor) override;\n");
  }
}

void PrintHeaderClientMethodCallbackEnd(
    grpc_generator::Printer* printer,
    std::map<std::string, std::string>* /*vars*/) {
  printer->Outdent();
  printer->Print(" private:\n");
  printer->Indent();
  printer->Print("friend class Stub;\n");
  printer->Print("explicit async(Stub* stub): stub_(stub) { }\n");
  // include a function with a phony use of stub_ to avoid an unused
  // private member warning for service with no methods
  printer->Print("Stub* stub() { return stub_; }\n");
  printer->Print("Stub* stub_;\n");
  printer->Outdent();
  printer->Print("};\n");

  printer->Print(
      "class async* async() override { "
      "return &async_stub_; }\n");
}

void PrintHeaderClientMethodData(grpc_generator::Printer* printer,
                                 const grpc_generator::Method* method,
                                 std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  printer->Print(*vars,
                 "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
}

void PrintHeaderServerMethodSync(grpc_generator::Printer* printer,
                                 const grpc_generator::Method* method,
                                 const Parameters& params,
                                 std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  printer->Print(method->GetLeadingComments("//").c_str());
  if (params.allow_sync_server_api) {
    printer->Print("virtual ");
  }
  if (method->NoStreaming()) {
    printer->Print(*vars,
                   "::grpc::Status $Method$("
                   "::grpc::ServerContext* context, const $Request$* request, "
                   "$Response$* response);\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(*vars,
                   "::grpc::Status $Method$("
                   "::grpc::ServerContext* context, "
                   "::grpc::ServerReader< $Request$>* reader, "
                   "$Response$* response);\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(*vars,
                   "::grpc::Status $Method$("
                   "::grpc::ServerContext* context, const $Request$* request, "
                   "::grpc::ServerWriter< $Response$>* writer);\n");
  } else if (method->BidiStreaming()) {
    printer->Print(
        *vars,
        "::grpc::Status $Method$("
        "::grpc::ServerContext* context, "
        "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
        "\n");
  }
  printer->Print(method->GetTrailingComments("//").c_str());
}

// Helper generator. Disables the sync API for Request and Response, then adds
// in an async API for RealRequest and RealResponse types. This is to be used
// to generate async and raw async APIs.
void PrintHeaderServerAsyncMethodsHelper(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    const Parameters& params, std::map<std::string, std::string>* vars) {
  if (method->NoStreaming()) {
    if (params.allow_sync_server_api) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
          "$Response$* /*response*/) override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
    printer->Print(
        *vars,
        "void Request$Method$("
        "::grpc::ServerContext* context, $RealRequest$* request, "
        "::grpc::ServerAsyncResponseWriter< $RealResponse$>* response, "
        "::grpc::CompletionQueue* new_call_cq, "
        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
    printer->Print(*vars,
                   "  ::grpc::Service::RequestAsyncUnary($Idx$, context, "
                   "request, response, new_call_cq, notification_cq, tag);\n");
    printer->Print("}\n");
  } else if (ClientOnlyStreaming(method)) {
    if (params.allow_sync_server_api) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, "
          "::grpc::ServerReader< $Request$>* /*reader*/, "
          "$Response$* /*response*/) override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
    printer->Print(
        *vars,
        "void Request$Method$("
        "::grpc::ServerContext* context, "
        "::grpc::ServerAsyncReader< $RealResponse$, $RealRequest$>* reader, "
        "::grpc::CompletionQueue* new_call_cq, "
        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
    printer->Print(*vars,
                   "  ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
                   "context, reader, new_call_cq, notification_cq, tag);\n");
    printer->Print("}\n");
  } else if (ServerOnlyStreaming(method)) {
    if (params.allow_sync_server_api) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
          "::grpc::ServerWriter< $Response$>* /*writer*/) override "
          "{\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
    printer->Print(
        *vars,
        "void Request$Method$("
        "::grpc::ServerContext* context, $RealRequest$* request, "
        "::grpc::ServerAsyncWriter< $RealResponse$>* writer, "
        "::grpc::CompletionQueue* new_call_cq, "
        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
    printer->Print(
        *vars,
        "  ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
        "context, request, writer, new_call_cq, notification_cq, tag);\n");
    printer->Print("}\n");
  } else if (method->BidiStreaming()) {
    if (params.allow_sync_server_api) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, "
          "::grpc::ServerReaderWriter< $Response$, $Request$>* /*stream*/) "
          " override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
    printer->Print(
        *vars,
        "void Request$Method$("
        "::grpc::ServerContext* context, "
        "::grpc::ServerAsyncReaderWriter< $RealResponse$, $RealRequest$>* "
        "stream, "
        "::grpc::CompletionQueue* new_call_cq, "
        "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
    printer->Print(*vars,
                   "  ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
                   "context, stream, new_call_cq, notification_cq, tag);\n");
    printer->Print("}\n");
  }
}

void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
                                  const grpc_generator::Method* method,
                                  const Parameters& params,
                                  std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  // These will be disabled
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  // These will be used for the async API
  (*vars)["RealRequest"] = method->input_type_name();
  (*vars)["RealResponse"] = method->output_type_name();
  printer->Print(*vars, "template <class BaseClass>\n");
  printer->Print(*vars,
                 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
  printer->Print(
      " private:\n"
      "  void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
      "{}\n");
  printer->Print(" public:\n");
  printer->Indent();
  printer->Print(*vars,
                 "WithAsyncMethod_$Method$() {\n"
                 "  ::grpc::Service::MarkMethodAsync($Idx$);\n"
                 "}\n");
  printer->Print(*vars,
                 "~WithAsyncMethod_$Method$() override {\n"
                 "  BaseClassMustBeDerivedFromService(this);\n"
                 "}\n");
  PrintHeaderServerAsyncMethodsHelper(printer, method, params, vars);
  printer->Outdent();
  printer->Print(*vars, "};\n");
}

// Helper generator. Disables the sync API for Request and Response, then adds
// in a callback API for RealRequest and RealResponse types. This is to be used
// to generate callback and raw callback APIs.
void PrintHeaderServerCallbackMethodsHelper(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    const Parameters& params, std::map<std::string, std::string>* vars) {
  if (method->NoStreaming()) {
    if (params.allow_sync_server_api) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
          "$Response$* /*response*/) override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
    printer->Print(*vars,
                   "virtual ::grpc::ServerUnaryReactor* $Method$(\n"
                   "  ::grpc::CallbackServerContext* /*context*/, "
                   "const $RealRequest$* /*request*/, "
                   "$RealResponse$* /*response*/)"
                   "  { return nullptr; }\n");
  } else if (ClientOnlyStreaming(method)) {
    if (params.allow_sync_server_api) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, "
          "::grpc::ServerReader< $Request$>* /*reader*/, "
          "$Response$* /*response*/) override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
    printer->Print(*vars,
                   "virtual ::grpc::ServerReadReactor< "
                   "$RealRequest$>* $Method$(\n"
                   "  ::grpc::CallbackServerContext* "
                   "/*context*/, $RealResponse$* /*response*/)"
                   "  { return nullptr; }\n");
  } else if (ServerOnlyStreaming(method)) {
    if (params.allow_sync_server_api) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
          "::grpc::ServerWriter< $Response$>* /*writer*/) override "
          "{\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
    printer->Print(
        *vars,
        "virtual ::grpc::ServerWriteReactor< $RealResponse$>* $Method$(\n"
        "  ::grpc::CallbackServerContext* "
        "/*context*/, const $RealRequest$* /*request*/)"
        "  { return nullptr; }\n");
  } else if (method->BidiStreaming()) {
    if (params.allow_sync_server_api) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, "
          "::grpc::ServerReaderWriter< $Response$, $Request$>* /*stream*/) "
          " override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
    printer->Print(
        *vars,
        "virtual ::grpc::ServerBidiReactor< $RealRequest$, $RealResponse$>* "
        "$Method$(\n"
        "  ::grpc::CallbackServerContext* /*context*/)\n"
        "  { return nullptr; }\n");
  }
}

void PrintHeaderServerMethodCallback(grpc_generator::Printer* printer,
                                     const grpc_generator::Method* method,
                                     const Parameters& params,
                                     std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  // These will be disabled
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  // These will be used for the callback API
  (*vars)["RealRequest"] = method->input_type_name();
  (*vars)["RealResponse"] = method->output_type_name();
  printer->Print(*vars, "template <class BaseClass>\n");
  printer->Print(*vars,
                 "class WithCallbackMethod_$Method$ : public BaseClass {\n");
  printer->Print(
      " private:\n"
      "  void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
      "{}\n");
  printer->Print(" public:\n");
  printer->Indent();
  printer->Print(*vars, "WithCallbackMethod_$Method$() {\n");
  if (method->NoStreaming()) {
    printer->Print(
        *vars,
        "  ::grpc::Service::MarkMethodCallback($Idx$,\n"
        "      new ::grpc::internal::CallbackUnaryHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "        [this](\n"
        "               ::grpc::CallbackServerContext* context, "
        "const $RealRequest$* "
        "request, "
        "$RealResponse$* response) { "
        "return this->$Method$(context, request, response); }));}\n");
    printer->Print(*vars,
                   "void SetMessageAllocatorFor_$Method$(\n"
                   "    ::grpc::MessageAllocator< "
                   "$RealRequest$, $RealResponse$>* allocator) {\n"
                   "  ::grpc::internal::MethodHandler* const handler = "
                   "::grpc::Service::GetHandler($Idx$);\n"
                   "  static_cast<::grpc::internal::CallbackUnaryHandler< "
                   "$RealRequest$, $RealResponse$>*>(handler)\n"
                   "          ->SetMessageAllocator(allocator);\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "  ::grpc::Service::MarkMethodCallback($Idx$,\n"
        "      new ::grpc::internal::CallbackClientStreamingHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "        [this](\n"
        "               ::grpc::CallbackServerContext* context, "
        "$RealResponse$* "
        "response) { "
        "return this->$Method$(context, response); }));\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "  ::grpc::Service::MarkMethodCallback($Idx$,\n"
        "      new ::grpc::internal::CallbackServerStreamingHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "        [this](\n"
        "               ::grpc::CallbackServerContext* context, "
        "const $RealRequest$* "
        "request) { "
        "return this->$Method$(context, request); }));\n");
  } else if (method->BidiStreaming()) {
    printer->Print(*vars,
                   "  ::grpc::Service::MarkMethodCallback($Idx$,\n"
                   "      new ::grpc::internal::CallbackBidiHandler< "
                   "$RealRequest$, $RealResponse$>(\n"
                   "        [this](\n"
                   "               ::grpc::CallbackServerContext* context) "
                   "{ return this->$Method$(context); }));\n");
  }
  printer->Print(*vars, "}\n");
  printer->Print(*vars,
                 "~WithCallbackMethod_$Method$() override {\n"
                 "  BaseClassMustBeDerivedFromService(this);\n"
                 "}\n");
  PrintHeaderServerCallbackMethodsHelper(printer, method, params, vars);
  printer->Outdent();
  printer->Print(*vars, "};\n");
}

void PrintHeaderServerMethodRawCallback(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    const Parameters& params, std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  // These will be disabled
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  // These will be used for raw API
  (*vars)["RealRequest"] = "::grpc::ByteBuffer";
  (*vars)["RealResponse"] = "::grpc::ByteBuffer";
  printer->Print(*vars, "template <class BaseClass>\n");
  printer->Print(*vars,
                 "class WithRawCallbackMethod_$Method$ : public "
                 "BaseClass {\n");
  printer->Print(
      " private:\n"
      "  void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
      "{}\n");
  printer->Print(" public:\n");
  printer->Indent();
  printer->Print(*vars, "WithRawCallbackMethod_$Method$() {\n");
  if (method->NoStreaming()) {
    printer->Print(*vars,
                   "  ::grpc::Service::MarkMethodRawCallback($Idx$,\n"
                   "      new ::grpc::internal::CallbackUnaryHandler< "
                   "$RealRequest$, $RealResponse$>(\n"
                   "        [this](\n"
                   "               ::grpc::CallbackServerContext* context, "
                   "const $RealRequest$* "
                   "request, "
                   "$RealResponse$* response) { return "
                   "this->$Method$(context, request, response); }));\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "  ::grpc::Service::MarkMethodRawCallback($Idx$,\n"
        "      new ::grpc::internal::CallbackClientStreamingHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "        [this](\n"
        "               ::grpc::CallbackServerContext* context, "
        "$RealResponse$* response) "
        "{ return this->$Method$(context, response); }));\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "  ::grpc::Service::MarkMethodRawCallback($Idx$,\n"
        "      new ::grpc::internal::CallbackServerStreamingHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "        [this](\n"
        "               ::grpc::CallbackServerContext* context, "
        "const"
        "$RealRequest$* request) { return "
        "this->$Method$(context, request); }));\n");
  } else if (method->BidiStreaming()) {
    printer->Print(*vars,
                   "  ::grpc::Service::MarkMethodRawCallback($Idx$,\n"
                   "      new ::grpc::internal::CallbackBidiHandler< "
                   "$RealRequest$, $RealResponse$>(\n"
                   "        [this](\n"
                   "               ::grpc::CallbackServerContext* context) "
                   "{ return this->$Method$(context); }));\n");
  }
  printer->Print(*vars, "}\n");
  printer->Print(*vars,
                 "~WithRawCallbackMethod_$Method$() override {\n"
                 "  BaseClassMustBeDerivedFromService(this);\n"
                 "}\n");
  PrintHeaderServerCallbackMethodsHelper(printer, method, params, vars);
  printer->Outdent();
  printer->Print(*vars, "};\n");
}

void PrintHeaderServerMethodStreamedUnary(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  if (method->NoStreaming()) {
    printer->Print(*vars, "template <class BaseClass>\n");
    printer->Print(*vars,
                   "class WithStreamedUnaryMethod_$Method$ : "
                   "public BaseClass {\n");
    printer->Print(
        " private:\n"
        "  void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
        "{}\n");
    printer->Print(" public:\n");
    printer->Indent();
    printer->Print(*vars,
                   "WithStreamedUnaryMethod_$Method$() {\n"
                   "  ::grpc::Service::MarkMethodStreamed($Idx$,\n"
                   "    new ::grpc::internal::StreamedUnaryHandler<\n"
                   "      $Request$, $Response$>(\n"
                   "        [this](::grpc::ServerContext* context,\n"
                   "               ::grpc::ServerUnaryStreamer<\n"
                   "                 $Request$, $Response$>* streamer) {\n"
                   "                   return this->Streamed$Method$(context,\n"
                   "                     streamer);\n"
                   "              }));\n"
                   "}\n");
    printer->Print(*vars,
                   "~WithStreamedUnaryMethod_$Method$() override {\n"
                   "  BaseClassMustBeDerivedFromService(this);\n"
                   "}\n");
    printer->Print(
        *vars,
        "// disable regular version of this method\n"
        "::grpc::Status $Method$("
        "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
        "$Response$* /*response*/) override {\n"
        "  abort();\n"
        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
        "}\n");
    printer->Print(*vars,
                   "// replace default version of method with streamed unary\n"
                   "virtual ::grpc::Status Streamed$Method$("
                   "::grpc::ServerContext* context, "
                   "::grpc::ServerUnaryStreamer< "
                   "$Request$,$Response$>* server_unary_streamer)"
                   " = 0;\n");
    printer->Outdent();
    printer->Print(*vars, "};\n");
  }
}

void PrintHeaderServerMethodSplitStreaming(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  if (ServerOnlyStreaming(method)) {
    printer->Print(*vars, "template <class BaseClass>\n");
    printer->Print(*vars,
                   "class WithSplitStreamingMethod_$Method$ : "
                   "public BaseClass {\n");
    printer->Print(
        " private:\n"
        "  void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
        "{}\n");
    printer->Print(" public:\n");
    printer->Indent();
    printer->Print(*vars,
                   "WithSplitStreamingMethod_$Method$() {\n"
                   "  ::grpc::Service::MarkMethodStreamed($Idx$,\n"
                   "    new ::grpc::internal::SplitServerStreamingHandler<\n"
                   "      $Request$, $Response$>(\n"
                   "        [this](::grpc::ServerContext* context,\n"
                   "               ::grpc::ServerSplitStreamer<\n"
                   "                 $Request$, $Response$>* streamer) {\n"
                   "                   return this->Streamed$Method$(context,\n"
                   "                     streamer);\n"
                   "              }));\n"
                   "}\n");
    printer->Print(*vars,
                   "~WithSplitStreamingMethod_$Method$() override {\n"
                   "  BaseClassMustBeDerivedFromService(this);\n"
                   "}\n");
    printer->Print(
        *vars,
        "// disable regular version of this method\n"
        "::grpc::Status $Method$("
        "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
        "::grpc::ServerWriter< $Response$>* /*writer*/) override "
        "{\n"
        "  abort();\n"
        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
        "}\n");
    printer->Print(*vars,
                   "// replace default version of method with split streamed\n"
                   "virtual ::grpc::Status Streamed$Method$("
                   "::grpc::ServerContext* context, "
                   "::grpc::ServerSplitStreamer< "
                   "$Request$,$Response$>* server_split_streamer)"
                   " = 0;\n");
    printer->Outdent();
    printer->Print(*vars, "};\n");
  }
}

void PrintHeaderServerMethodGeneric(grpc_generator::Printer* printer,
                                    const grpc_generator::Method* method,
                                    const Parameters& params,
                                    std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  printer->Print(*vars, "template <class BaseClass>\n");
  printer->Print(*vars,
                 "class WithGenericMethod_$Method$ : public BaseClass {\n");
  printer->Print(
      " private:\n"
      "  void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
      "{}\n");
  printer->Print(" public:\n");
  printer->Indent();
  printer->Print(*vars,
                 "WithGenericMethod_$Method$() {\n"
                 "  ::grpc::Service::MarkMethodGeneric($Idx$);\n"
                 "}\n");
  printer->Print(*vars,
                 "~WithGenericMethod_$Method$() override {\n"
                 "  BaseClassMustBeDerivedFromService(this);\n"
                 "}\n");
  if (params.allow_sync_server_api) {
    if (method->NoStreaming()) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
          "$Response$* /*response*/) override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    } else if (ClientOnlyStreaming(method)) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, "
          "::grpc::ServerReader< $Request$>* /*reader*/, "
          "$Response$* /*response*/) override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    } else if (ServerOnlyStreaming(method)) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
          "::grpc::ServerWriter< $Response$>* /*writer*/) override "
          "{\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    } else if (method->BidiStreaming()) {
      printer->Print(
          *vars,
          "// disable synchronous version of this method\n"
          "::grpc::Status $Method$("
          "::grpc::ServerContext* /*context*/, "
          "::grpc::ServerReaderWriter< $Response$, $Request$>* /*stream*/) "
          " override {\n"
          "  abort();\n"
          "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
          "}\n");
    }
  }
  printer->Outdent();
  printer->Print(*vars, "};\n");
}

void PrintHeaderServerMethodRaw(grpc_generator::Printer* printer,
                                const grpc_generator::Method* method,
                                const Parameters& params,
                                std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  // These will be disabled
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  // These will be used for raw API
  (*vars)["RealRequest"] = "::grpc::ByteBuffer";
  (*vars)["RealResponse"] = "::grpc::ByteBuffer";
  printer->Print(*vars, "template <class BaseClass>\n");
  printer->Print(*vars, "class WithRawMethod_$Method$ : public BaseClass {\n");
  printer->Print(
      " private:\n"
      "  void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
      "{}\n");
  printer->Print(" public:\n");
  printer->Indent();
  printer->Print(*vars,
                 "WithRawMethod_$Method$() {\n"
                 "  ::grpc::Service::MarkMethodRaw($Idx$);\n"
                 "}\n");
  printer->Print(*vars,
                 "~WithRawMethod_$Method$() override {\n"
                 "  BaseClassMustBeDerivedFromService(this);\n"
                 "}\n");
  PrintHeaderServerAsyncMethodsHelper(printer, method, params, vars);
  printer->Outdent();
  printer->Print(*vars, "};\n");
}

void PrintHeaderService(grpc_generator::Printer* printer,
                        const grpc_generator::Service* service,
                        const Parameters& params,
                        std::map<std::string, std::string>* vars) {
  (*vars)["Service"] = service->name();

  printer->Print(service->GetLeadingComments("//").c_str());
  if (params.allow_deprecated && service->is_deprecated()) {
    printer->Print(*vars,
                   "class [[deprecated]] $Service$ final {\n"
                   " public:\n");
  } else {
    printer->Print(*vars,
                   "class $Service$ final {\n"
                   " public:\n");
  }
  printer->Indent();

  // Service metadata
  printer->Print(*vars,
                 "static constexpr char const* service_full_name() {\n"
                 "  return \"$Package$$Service$\";\n"
                 "}\n");

  // Client side
  printer->Print(
      "class StubInterface {\n"
      " public:\n");
  printer->Indent();
  printer->Print("virtual ~StubInterface() {}\n");
  for (int i = 0; i < service->method_count(); ++i) {
    printer->Print(service->method(i)->GetLeadingComments("//").c_str());
    PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), params,
                                      vars, true);
    printer->Print(service->method(i)->GetTrailingComments("//").c_str());
  }
  PrintHeaderClientMethodCallbackInterfacesStart(printer, vars);
  for (int i = 0; i < service->method_count(); ++i) {
    printer->Print(service->method(i)->GetLeadingComments("//").c_str());
    PrintHeaderClientMethodCallbackInterfaces(printer, service->method(i).get(),
                                              vars);
    printer->Print(service->method(i)->GetTrailingComments("//").c_str());
  }
  PrintHeaderClientMethodCallbackInterfacesEnd(printer, vars);
  printer->Outdent();
  printer->Print(" private:\n");
  printer->Indent();
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), params,
                                      vars, false);
  }
  printer->Outdent();
  printer->Print("};\n");
  printer->Print(
      "class Stub final : public StubInterface"
      " {\n public:\n");
  printer->Indent();
  printer->Print(
      "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
      "channel, const ::grpc::StubOptions& options = "
      "::grpc::StubOptions());\n");
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderClientMethod(printer, service->method(i).get(), params, vars,
                            true);
  }
  PrintHeaderClientMethodCallbackStart(printer, vars);
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars);
  }
  PrintHeaderClientMethodCallbackEnd(printer, vars);
  printer->Outdent();
  printer->Print("\n private:\n");
  printer->Indent();
  printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
  printer->Print("class async async_stub_{this};\n");
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderClientMethod(printer, service->method(i).get(), params, vars,
                            false);
  }
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
  }
  printer->Outdent();
  printer->Print("};\n");
  printer->Print(
      "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
      "::grpc::ChannelInterface>& channel, "
      "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");

  printer->Print("\n");

  // Server side - base
  printer->Print(
      "class Service : public ::grpc::Service {\n"
      " public:\n");
  printer->Indent();
  printer->Print("Service();\n");
  printer->Print("virtual ~Service();\n");
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderServerMethodSync(printer, service->method(i).get(), params,
                                vars);
  }
  printer->Outdent();
  printer->Print("};\n");

  if (params.allow_cq_api) {
    // Server side - Asynchronous
    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["Idx"] = as_string(i);
      PrintHeaderServerMethodAsync(printer, service->method(i).get(), params,
                                   vars);
    }

    printer->Print("typedef ");

    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["method_name"] = service->method(i)->name();
      printer->Print(*vars, "WithAsyncMethod_$method_name$<");
    }
    printer->Print("Service");
    for (int i = 0; i < service->method_count(); ++i) {
      printer->Print(" >");
    }
    printer->Print(" AsyncService;\n");
  }

  // Server side - Callback
  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["Idx"] = as_string(i);
    PrintHeaderServerMethodCallback(printer, service->method(i).get(), params,
                                    vars);
  }

  printer->Print("typedef ");

  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["method_name"] = service->method(i)->name();
    printer->Print(*vars, "WithCallbackMethod_$method_name$<");
  }
  printer->Print("Service");
  for (int i = 0; i < service->method_count(); ++i) {
    printer->Print(" >");
  }
  printer->Print(" CallbackService;\n");

  // TODO: Remove following typedef once all uses of ExperimentalCallbackService
  //       are migrated to CallbackService
  printer->Print("typedef CallbackService ExperimentalCallbackService;\n");

  // Server side - Generic
  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["Idx"] = as_string(i);
    PrintHeaderServerMethodGeneric(printer, service->method(i).get(), params,
                                   vars);
  }

  // Server side - Raw Async
  if (params.allow_cq_api) {
    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["Idx"] = as_string(i);
      PrintHeaderServerMethodRaw(printer, service->method(i).get(), params,
                                 vars);
    }
  }

  // Server side - Raw Callback
  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["Idx"] = as_string(i);
    PrintHeaderServerMethodRawCallback(printer, service->method(i).get(),
                                       params, vars);
  }

  if (params.allow_sync_server_api) {
    // Server side - Streamed Unary
    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["Idx"] = as_string(i);
      PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
                                           vars);
    }

    printer->Print("typedef ");
    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["method_name"] = service->method(i)->name();
      if (service->method(i)->NoStreaming()) {
        printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
      }
    }
    printer->Print("Service");
    for (int i = 0; i < service->method_count(); ++i) {
      if (service->method(i)->NoStreaming()) {
        printer->Print(" >");
      }
    }
    printer->Print(" StreamedUnaryService;\n");

    // Server side - controlled server-side streaming
    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["Idx"] = as_string(i);
      PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(),
                                            vars);
    }

    printer->Print("typedef ");
    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["method_name"] = service->method(i)->name();
      auto method = service->method(i);
      if (ServerOnlyStreaming(method.get())) {
        printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
      }
    }
    printer->Print("Service");
    for (int i = 0; i < service->method_count(); ++i) {
      auto method = service->method(i);
      if (ServerOnlyStreaming(method.get())) {
        printer->Print(" >");
      }
    }
    printer->Print(" SplitStreamedService;\n");

    // Server side - typedef for controlled both unary and server-side streaming
    printer->Print("typedef ");
    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["method_name"] = service->method(i)->name();
      auto method = service->method(i);
      if (ServerOnlyStreaming(method.get())) {
        printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
      }
      if (service->method(i)->NoStreaming()) {
        printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
      }
    }
    printer->Print("Service");
    for (int i = 0; i < service->method_count(); ++i) {
      auto method = service->method(i);
      if (service->method(i)->NoStreaming() ||
          ServerOnlyStreaming(method.get())) {
        printer->Print(" >");
      }
    }
    printer->Print(" StreamedService;\n");
  }

  printer->Outdent();
  printer->Print("};\n");
  printer->Print(service->GetTrailingComments("//").c_str());
}

std::string GetHeaderServices(grpc_generator::File* file,
                              const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;
    // Package string is empty or ends with a dot. It is used to fully qualify
    // method names.
    vars["Package"] = file->package();
    if (!file->package().empty()) {
      vars["Package"].append(".");
    }

    if (!params.services_namespace.empty()) {
      vars["services_namespace"] = params.services_namespace;
      printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
    }

    for (int i = 0; i < file->service_count(); ++i) {
      PrintHeaderService(printer.get(), file->service(i).get(), params, &vars);
      printer->Print("\n");
    }

    if (!params.services_namespace.empty()) {
      printer->Print(vars, "}  // namespace $services_namespace$\n\n");
    }
  }
  return output;
}

std::string GetHeaderEpilogue(grpc_generator::File* file,
                              const Parameters& /*params*/) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;

    vars["filename"] = file->filename();
    vars["filename_identifier"] = FilenameIdentifier(file->filename());

    if (!file->package().empty()) {
      std::vector<std::string> parts = file->package_parts();

      for (auto part = parts.rbegin(); part != parts.rend(); part++) {
        vars["part"] = *part;
        printer->Print(vars, "}  // namespace $part$\n");
      }
      printer->Print(vars, "\n");
    }

    printer->Print(vars, "\n");

    // Must be included at end of file
    printer->Print("#include <grpcpp/ports_undef.inc>\n");
    printer->Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");

    printer->Print(file->GetTrailingComments("//").c_str());
  }
  return output;
}

std::string GetSourcePrologue(grpc_generator::File* file,
                              const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;

    vars["filename"] = file->filename();
    vars["filename_base"] = file->filename_without_ext();
    vars["message_header_ext"] = params.message_header_extension.empty()
                                     ? kCppGeneratorMessageHeaderExt
                                     : params.message_header_extension;
    vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;

    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
    printer->Print(vars,
                   "// If you make any local change, they will be lost.\n");
    printer->Print(vars, "// source: $filename$\n\n");

    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
    printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
    printer->Print(vars, "\n");
  }
  return output;
}

std::string GetSourceIncludes(grpc_generator::File* file,
                              const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;
    static const char* headers_strs[] = {
        "functional", "grpcpp/support/async_stream.h",
        "grpcpp/support/async_unary_call.h", "grpcpp/impl/channel_interface.h",
        "grpcpp/impl/client_unary_call.h", "grpcpp/support/client_callback.h",
        "grpcpp/support/message_allocator.h", "grpcpp/support/method_handler.h",
        "grpcpp/impl/rpc_service_method.h", "grpcpp/support/server_callback.h",
        "grpcpp/impl/server_callback_handlers.h", "grpcpp/server_context.h",
        "grpcpp/impl/service_type.h", "grpcpp/support/sync_stream.h",
        // ports_def.inc Must be included as last
        "grpcpp/ports_def.inc"};
    std::vector<std::string> headers(headers_strs, array_end(headers_strs));
    PrintIncludes(printer.get(), headers, params.use_system_headers,
                  params.grpc_search_path);

    if (!file->package().empty()) {
      std::vector<std::string> parts = file->package_parts();

      for (auto part = parts.begin(); part != parts.end(); part++) {
        vars["part"] = *part;
        printer->Print(vars, "namespace $part$ {\n");
      }
    }

    printer->Print(vars, "\n");
  }
  return output;
}

void PrintSourceClientMethod(grpc_generator::Printer* printer,
                             const grpc_generator::Method* method,
                             const Parameters& params,
                             std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  struct {
    std::string prefix;
    std::string start;          // bool literal expressed as string
    std::string method_params;  // extra arguments to method
    std::string create_args;    // extra arguments to creator
  } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
                        {"PrepareAsync", "false", "", ", nullptr"}};
  if (method->NoStreaming()) {
    printer->Print(*vars,
                   "::grpc::Status $ns$$Service$::Stub::$Method$("
                   "::grpc::ClientContext* context, "
                   "const $Request$& request, $Response$* response) {\n");
    printer->Print(*vars,
                   "  return ::grpc::internal::BlockingUnaryCall"
                   "< $Request$, $Response$, ::grpc::protobuf::MessageLite, "
                   "::grpc::protobuf::MessageLite>"
                   "(channel_.get(), rpcmethod_$Method$_, "
                   "context, request, response);\n}\n\n");

    printer->Print(*vars,
                   "void $ns$$Service$::Stub::async::$Method$("
                   "::grpc::ClientContext* context, "
                   "const $Request$* request, $Response$* response, "
                   "std::function<void(::grpc::Status)> f) {\n");
    printer->Print(*vars,
                   "  ::grpc::internal::CallbackUnaryCall"
                   "< $Request$, $Response$, ::grpc::protobuf::MessageLite, "
                   "::grpc::protobuf::MessageLite>"
                   "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
                   "context, request, response, std::move(f));\n}\n\n");

    printer->Print(*vars,
                   "void $ns$$Service$::Stub::async::$Method$("
                   "::grpc::ClientContext* context, "
                   "const $Request$* request, $Response$* response, "
                   "::grpc::ClientUnaryReactor* reactor) {\n");
    printer->Print(*vars,
                   "  ::grpc::internal::ClientCallbackUnaryFactory::Create"
                   "< ::grpc::protobuf::MessageLite, "
                   "::grpc::protobuf::MessageLite>"
                   "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
                   "context, request, response, reactor);\n}\n\n");

    if (params.allow_cq_api) {
      printer->Print(*vars,
                     "::grpc::ClientAsyncResponseReader< $Response$>* "
                     "$ns$$Service$::Stub::PrepareAsync$Method$Raw(::grpc::"
                     "ClientContext* context, "
                     "const $Request$& request, "
                     "::grpc::CompletionQueue* cq) {\n");
      printer->Print(*vars,
                     "  return "
                     "::grpc::internal::ClientAsyncResponseReaderHelper::Create"
                     "< $Response$, $Request$, ::grpc::protobuf::MessageLite, "
                     "::grpc::protobuf::MessageLite>"
                     "(channel_.get(), cq, rpcmethod_$Method$_, "
                     "context, request);\n"
                     "}\n\n");
      printer->Print(*vars,
                     "::grpc::ClientAsyncResponseReader< $Response$>* "
                     "$ns$$Service$::Stub::Async$Method$Raw(::grpc::"
                     "ClientContext* context, "
                     "const $Request$& request, "
                     "::grpc::CompletionQueue* cq) {\n");
      printer->Print(
          *vars,
          "  auto* result =\n"
          "    this->PrepareAsync$Method$Raw(context, request, cq);\n"
          "  result->StartCall();\n"
          "  return result;\n"
          "}\n\n");
    }
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(*vars,
                   "::grpc::ClientWriter< $Request$>* "
                   "$ns$$Service$::Stub::$Method$Raw("
                   "::grpc::ClientContext* context, $Response$* response) {\n");
    printer->Print(*vars,
                   "  return ::grpc::internal::ClientWriterFactory< "
                   "$Request$>::Create("
                   "channel_.get(), "
                   "rpcmethod_$Method$_, "
                   "context, response);\n"
                   "}\n\n");

    printer->Print(*vars,
                   "void $ns$$Service$::"
                   "Stub::async::$Method$(::grpc::ClientContext* context, "
                   "$Response$* response, "
                   "::grpc::ClientWriteReactor< $Request$>* reactor) {\n");
    printer->Print(*vars,
                   "  ::grpc::internal::ClientCallbackWriterFactory< "
                   "$Request$>::Create("
                   "stub_->channel_.get(), "
                   "stub_->rpcmethod_$Method$_, "
                   "context, response, reactor);\n"
                   "}\n\n");

    if (params.allow_cq_api) {
      for (const auto& async_prefix : async_prefixes) {
        (*vars)["AsyncPrefix"] = async_prefix.prefix;
        (*vars)["AsyncStart"] = async_prefix.start;
        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
        (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
        printer->Print(*vars,
                       "::grpc::ClientAsyncWriter< $Request$>* "
                       "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
                       "::grpc::ClientContext* context, $Response$* response, "
                       "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
        printer->Print(
            *vars,
            "  return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
            "::Create(channel_.get(), cq, "
            "rpcmethod_$Method$_, "
            "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
            "}\n\n");
      }
    }
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "::grpc::ClientReader< $Response$>* "
        "$ns$$Service$::Stub::$Method$Raw("
        "::grpc::ClientContext* context, const $Request$& request) {\n");
    printer->Print(*vars,
                   "  return ::grpc::internal::ClientReaderFactory< "
                   "$Response$>::Create("
                   "channel_.get(), "
                   "rpcmethod_$Method$_, "
                   "context, request);\n"
                   "}\n\n");

    printer->Print(*vars,
                   "void $ns$$Service$::Stub::async::$Method$(::grpc::"
                   "ClientContext* context, "
                   "const $Request$* request, "
                   "::grpc::ClientReadReactor< $Response$>* reactor) {\n");
    printer->Print(*vars,
                   "  ::grpc::internal::ClientCallbackReaderFactory< "
                   "$Response$>::Create("
                   "stub_->channel_.get(), "
                   "stub_->rpcmethod_$Method$_, "
                   "context, request, reactor);\n"
                   "}\n\n");

    if (params.allow_cq_api) {
      for (const auto& async_prefix : async_prefixes) {
        (*vars)["AsyncPrefix"] = async_prefix.prefix;
        (*vars)["AsyncStart"] = async_prefix.start;
        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
        (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
        printer->Print(
            *vars,
            "::grpc::ClientAsyncReader< $Response$>* "
            "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
            "::grpc::ClientContext* context, const $Request$& request, "
            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
        printer->Print(*vars,
                       "  return ::grpc::internal::ClientAsyncReaderFactory< "
                       "$Response$>"
                       "::Create(channel_.get(), cq, "
                       "rpcmethod_$Method$_, "
                       "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
                       "}\n\n");
      }
    }
  } else if (method->BidiStreaming()) {
    printer->Print(
        *vars,
        "::grpc::ClientReaderWriter< $Request$, $Response$>* "
        "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
    printer->Print(*vars,
                   "  return ::grpc::internal::ClientReaderWriterFactory< "
                   "$Request$, $Response$>::Create("
                   "channel_.get(), "
                   "rpcmethod_$Method$_, "
                   "context);\n"
                   "}\n\n");

    printer->Print(*vars,
                   "void $ns$$Service$::Stub::async::$Method$(::grpc::"
                   "ClientContext* context, "
                   "::grpc::ClientBidiReactor< $Request$,$Response$>* "
                   "reactor) {\n");
    printer->Print(*vars,
                   "  ::grpc::internal::ClientCallbackReaderWriterFactory< "
                   "$Request$,$Response$>::Create("
                   "stub_->channel_.get(), "
                   "stub_->rpcmethod_$Method$_, "
                   "context, reactor);\n"
                   "}\n\n");

    if (params.allow_cq_api) {
      for (const auto& async_prefix : async_prefixes) {
        (*vars)["AsyncPrefix"] = async_prefix.prefix;
        (*vars)["AsyncStart"] = async_prefix.start;
        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
        (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
        printer->Print(
            *vars,
            "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
            "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
            "ClientContext* context, "
            "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
        printer->Print(*vars,
                       "  return "
                       "::grpc::internal::ClientAsyncReaderWriterFactory< "
                       "$Request$, $Response$>::Create("
                       "channel_.get(), cq, "
                       "rpcmethod_$Method$_, "
                       "context, $AsyncStart$$AsyncCreateArgs$);\n"
                       "}\n\n");
      }
    }
  }
}

void PrintSourceServerMethod(grpc_generator::Printer* printer,
                             const grpc_generator::Method* method,
                             const Parameters& params,
                             std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  if (method->NoStreaming()) {
    printer->Print(*vars,
                   "::grpc::Status $ns$$Service$::Service::$Method$("
                   "::grpc::ServerContext* context, "
                   "const $Request$* request, $Response$* response) {\n");
    if (!params.allow_sync_server_api) {
      printer->Print("  abort();\n");
    }
    printer->Print("  (void) context;\n");
    printer->Print("  (void) request;\n");
    printer->Print("  (void) response;\n");
    printer->Print(
        "  return ::grpc::Status("
        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
    printer->Print("}\n\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(*vars,
                   "::grpc::Status $ns$$Service$::Service::$Method$("
                   "::grpc::ServerContext* context, "
                   "::grpc::ServerReader< $Request$>* reader, "
                   "$Response$* response) {\n");
    if (!params.allow_sync_server_api) {
      printer->Print("  abort();\n");
    }
    printer->Print("  (void) context;\n");
    printer->Print("  (void) reader;\n");
    printer->Print("  (void) response;\n");
    printer->Print(
        "  return ::grpc::Status("
        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
    printer->Print("}\n\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(*vars,
                   "::grpc::Status $ns$$Service$::Service::$Method$("
                   "::grpc::ServerContext* context, "
                   "const $Request$* request, "
                   "::grpc::ServerWriter< $Response$>* writer) {\n");
    if (!params.allow_sync_server_api) {
      printer->Print("  abort();\n");
    }
    printer->Print("  (void) context;\n");
    printer->Print("  (void) request;\n");
    printer->Print("  (void) writer;\n");
    printer->Print(
        "  return ::grpc::Status("
        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
    printer->Print("}\n\n");
  } else if (method->BidiStreaming()) {
    printer->Print(*vars,
                   "::grpc::Status $ns$$Service$::Service::$Method$("
                   "::grpc::ServerContext* context, "
                   "::grpc::ServerReaderWriter< $Response$, $Request$>* "
                   "stream) {\n");
    if (!params.allow_sync_server_api) {
      printer->Print("  abort();\n");
    }
    printer->Print("  (void) context;\n");
    printer->Print("  (void) stream;\n");
    printer->Print(
        "  return ::grpc::Status("
        "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
    printer->Print("}\n\n");
  }
}

void PrintSourceService(grpc_generator::Printer* printer,
                        const grpc_generator::Service* service,
                        const Parameters& params,
                        std::map<std::string, std::string>* vars) {
  (*vars)["Service"] = service->name();

  if (service->method_count() > 0) {
    printer->Print(*vars,
                   "static const char* $prefix$$Service$_method_names[] = {\n");
    for (int i = 0; i < service->method_count(); ++i) {
      (*vars)["Method"] = service->method(i)->name();
      printer->Print(*vars, "  \"/$Package$$Service$/$Method$\",\n");
    }
    printer->Print(*vars, "};\n\n");
  }

  printer->Print(*vars,
                 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
                 "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
                 "const ::grpc::StubOptions& options) {\n"
                 "  (void)options;\n"
                 "  std::unique_ptr< $ns$$Service$::Stub> stub(new "
                 "$ns$$Service$::Stub(channel, options));\n"
                 "  return stub;\n"
                 "}\n\n");
  printer->Print(*vars,
                 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
                 "::grpc::ChannelInterface>& channel, const "
                 "::grpc::StubOptions& options)\n");
  printer->Indent();
  printer->Print(": channel_(channel)");
  for (int i = 0; i < service->method_count(); ++i) {
    auto method = service->method(i);
    (*vars)["Method"] = method->name();
    (*vars)["Idx"] = as_string(i);
    if (method->NoStreaming()) {
      (*vars)["StreamingType"] = "NORMAL_RPC";
      // NOTE: There is no reason to consider streamed-unary as a separate
      // category here since this part is setting up the client-side stub
      // and this appears as a NORMAL_RPC from the client-side.
    } else if (ClientOnlyStreaming(method.get())) {
      (*vars)["StreamingType"] = "CLIENT_STREAMING";
    } else if (ServerOnlyStreaming(method.get())) {
      (*vars)["StreamingType"] = "SERVER_STREAMING";
    } else {
      (*vars)["StreamingType"] = "BIDI_STREAMING";
    }
    printer->Print(
        *vars,
        ", rpcmethod_$Method$_("
        "$prefix$$Service$_method_names[$Idx$], options.suffix_for_stats(),"
        "::grpc::internal::RpcMethod::$StreamingType$, "
        "channel"
        ")\n");
  }
  printer->Print("{}\n\n");
  printer->Outdent();

  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["Idx"] = as_string(i);
    PrintSourceClientMethod(printer, service->method(i).get(), params, vars);
  }

  printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
  printer->Indent();
  for (int i = 0; i < service->method_count(); ++i) {
    auto method = service->method(i);
    (*vars)["Idx"] = as_string(i);
    (*vars)["Method"] = method->name();
    (*vars)["Request"] = method->input_type_name();
    (*vars)["Response"] = method->output_type_name();
    if (method->NoStreaming()) {
      printer->Print(
          *vars,
          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
          "    $prefix$$Service$_method_names[$Idx$],\n"
          "    ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
          "    new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
          "$Request$, $Response$, ::grpc::protobuf::MessageLite, "
          "::grpc::protobuf::MessageLite>(\n"
          "        []($ns$$Service$::Service* service,\n"
          "           ::grpc::ServerContext* ctx,\n"
          "           const $Request$* req,\n"
          "           $Response$* resp) {\n"
          "             return service->$Method$(ctx, req, resp);\n"
          "           }, this)));\n");
    } else if (ClientOnlyStreaming(method.get())) {
      printer->Print(
          *vars,
          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
          "    $prefix$$Service$_method_names[$Idx$],\n"
          "    ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
          "    new ::grpc::internal::ClientStreamingHandler< "
          "$ns$$Service$::Service, $Request$, $Response$>(\n"
          "        []($ns$$Service$::Service* service,\n"
          "           ::grpc::ServerContext* ctx,\n"
          "           ::grpc::ServerReader<$Request$>* reader,\n"
          "           $Response$* resp) {\n"
          "             return service->$Method$(ctx, reader, resp);\n"
          "           }, this)));\n");
    } else if (ServerOnlyStreaming(method.get())) {
      printer->Print(
          *vars,
          "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
          "    $prefix$$Service$_method_names[$Idx$],\n"
          "    ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
          "    new ::grpc::internal::ServerStreamingHandler< "
          "$ns$$Service$::Service, $Request$, $Response$>(\n"
          "        []($ns$$Service$::Service* service,\n"
          "           ::grpc::ServerContext* ctx,\n"
          "           const $Request$* req,\n"
          "           ::grpc::ServerWriter<$Response$>* writer) {\n"
          "             return service->$Method$(ctx, req, writer);\n"
          "           }, this)));\n");
    } else if (method->BidiStreaming()) {
      printer->Print(*vars,
                     "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
                     "    $prefix$$Service$_method_names[$Idx$],\n"
                     "    ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
                     "    new ::grpc::internal::BidiStreamingHandler< "
                     "$ns$$Service$::Service, $Request$, $Response$>(\n"
                     "        []($ns$$Service$::Service* service,\n"
                     "           ::grpc::ServerContext* ctx,\n"
                     "           ::grpc::ServerReaderWriter<$Response$,\n"
                     "           $Request$>* stream) {\n"
                     "             return service->$Method$(ctx, stream);\n"
                     "           }, this)));\n");
    }
  }
  printer->Outdent();
  printer->Print(*vars, "}\n\n");
  printer->Print(*vars,
                 "$ns$$Service$::Service::~Service() {\n"
                 "}\n\n");
  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["Idx"] = as_string(i);
    PrintSourceServerMethod(printer, service->method(i).get(), params, vars);
  }
}

std::string GetSourceServices(grpc_generator::File* file,
                              const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;
    // Package string is empty or ends with a dot. It is used to fully qualify
    // method names.
    vars["Package"] = file->package();
    if (!file->package().empty()) {
      vars["Package"].append(".");
    }
    if (!params.services_namespace.empty()) {
      vars["ns"] = params.services_namespace + "::";
      vars["prefix"] = params.services_namespace;
    } else {
      vars["ns"] = "";
      vars["prefix"] = "";
    }

    for (int i = 0; i < file->service_count(); ++i) {
      PrintSourceService(printer.get(), file->service(i).get(), params, &vars);
      printer->Print("\n");
    }
  }
  return output;
}

std::string GetSourceEpilogue(grpc_generator::File* file,
                              const Parameters& /*params*/) {
  std::string temp;

  if (!file->package().empty()) {
    std::vector<std::string> parts = file->package_parts();

    for (auto part = parts.begin(); part != parts.end(); part++) {
      temp.append("}  // namespace ");
      temp.append(*part);
      temp.append("\n");
    }
    // Must be included at end of file
    temp.append("#include <grpcpp/ports_undef.inc>\n");
    temp.append("\n");
  }

  return temp;
}

// TODO(mmukhi): Make sure we need parameters or not.
std::string GetMockPrologue(grpc_generator::File* file,
                            const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;

    vars["filename"] = file->filename();
    vars["filename_identifier"] = FilenameIdentifier(file->filename());
    vars["filename_base"] = file->filename_without_ext();
    vars["message_header_ext"] = params.message_header_extension.empty()
                                     ? kCppGeneratorMessageHeaderExt
                                     : params.message_header_extension;
    vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;

    printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
    printer->Print(vars,
                   "// If you make any local change, they will be lost.\n");
    printer->Print(vars, "// source: $filename$\n\n");

    printer->Print(vars, "#ifndef GRPC_MOCK_$filename_identifier$__INCLUDED\n");
    printer->Print(vars, "#define GRPC_MOCK_$filename_identifier$__INCLUDED\n");
    printer->Print(vars, "\n");
    printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
    printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
    if (params.include_import_headers) {
      const std::vector<std::string> import_names = file->GetImportNames();
      for (const auto& import_name : import_names) {
        const std::string include_name = ImportInludeFromProtoName(import_name);
        printer->Print(vars, include_name.c_str());
      }
      printer->PrintRaw("\n");
    }
    printer->Print(vars, file->additional_headers().c_str());
    printer->Print(vars, "\n");
  }
  return output;
}

// TODO(mmukhi): Add client-stream and completion-queue headers.
std::string GetMockIncludes(grpc_generator::File* file,
                            const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;

    static const char* headers_strs[] = {
        "grpcpp/support/async_stream.h",
        "grpcpp/support/sync_stream.h",
    };
    std::vector<std::string> headers(headers_strs, array_end(headers_strs));
    PrintIncludes(printer.get(), headers, params.use_system_headers,
                  params.grpc_search_path);

    std::vector<std::string> gmock_header;
    if (params.gmock_search_path.empty()) {
      gmock_header.push_back("gmock/gmock.h");
      PrintIncludes(printer.get(), gmock_header, params.use_system_headers,
                    params.grpc_search_path);
    } else {
      gmock_header.push_back("gmock.h");
      // We use local includes when a gmock_search_path is given
      PrintIncludes(printer.get(), gmock_header, false,
                    params.gmock_search_path);
    }

    if (!file->package().empty()) {
      std::vector<std::string> parts = file->package_parts();

      for (auto part = parts.begin(); part != parts.end(); part++) {
        vars["part"] = *part;
        printer->Print(vars, "namespace $part$ {\n");
      }
    }

    printer->Print(vars, "\n");
  }
  return output;
}

void PrintMockClientMethods(grpc_generator::Printer* printer,
                            const grpc_generator::Method* method,
                            const Parameters& params,
                            std::map<std::string, std::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();

  struct {
    std::string prefix;
    std::string method_params;  // extra arguments to method
    int extra_method_param_count;
  } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};

  if (method->NoStreaming()) {
    printer->Print(
        *vars,
        "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
        "const $Request$& request, $Response$* response));\n");
    if (params.allow_cq_api) {
      for (const auto& async_prefix : async_prefixes) {
        (*vars)["AsyncPrefix"] = async_prefix.prefix;
        printer->Print(
            *vars,
            "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
            "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
            "(::grpc::ClientContext* context, const $Request$& request, "
            "::grpc::CompletionQueue* cq));\n");
      }
    }
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "MOCK_METHOD2($Method$Raw, "
        "::grpc::ClientWriterInterface< $Request$>*"
        "(::grpc::ClientContext* context, $Response$* response));\n");
    if (params.allow_cq_api) {
      for (const auto& async_prefix : async_prefixes) {
        (*vars)["AsyncPrefix"] = async_prefix.prefix;
        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
        (*vars)["MockArgs"] =
            std::to_string(3 + async_prefix.extra_method_param_count);
        printer->Print(*vars,
                       "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
                       "::grpc::ClientAsyncWriterInterface< $Request$>*"
                       "(::grpc::ClientContext* context, $Response$* response, "
                       "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
      }
    }
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "MOCK_METHOD2($Method$Raw, "
        "::grpc::ClientReaderInterface< $Response$>*"
        "(::grpc::ClientContext* context, const $Request$& request));\n");
    if (params.allow_cq_api) {
      for (const auto& async_prefix : async_prefixes) {
        (*vars)["AsyncPrefix"] = async_prefix.prefix;
        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
        (*vars)["MockArgs"] =
            std::to_string(3 + async_prefix.extra_method_param_count);
        printer->Print(
            *vars,
            "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
            "::grpc::ClientAsyncReaderInterface< $Response$>*"
            "(::grpc::ClientContext* context, const $Request$& request, "
            "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
      }
    }
  } else if (method->BidiStreaming()) {
    printer->Print(
        *vars,
        "MOCK_METHOD1($Method$Raw, "
        "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
        "(::grpc::ClientContext* context));\n");
    if (params.allow_cq_api) {
      for (const auto& async_prefix : async_prefixes) {
        (*vars)["AsyncPrefix"] = async_prefix.prefix;
        (*vars)["AsyncMethodParams"] = async_prefix.method_params;
        (*vars)["MockArgs"] =
            std::to_string(2 + async_prefix.extra_method_param_count);
        printer->Print(
            *vars,
            "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
            "::grpc::ClientAsyncReaderWriterInterface<$Request$, "
            "$Response$>*"
            "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
            "$AsyncMethodParams$));\n");
      }
    }
  }
}

void PrintMockService(grpc_generator::Printer* printer,
                      const grpc_generator::Service* service,
                      const Parameters& params,
                      std::map<std::string, std::string>* vars) {
  (*vars)["Service"] = service->name();

  printer->Print(*vars,
                 "class Mock$Service$Stub : public $Service$::StubInterface {\n"
                 " public:\n");
  printer->Indent();
  for (int i = 0; i < service->method_count(); ++i) {
    PrintMockClientMethods(printer, service->method(i).get(), params, vars);
  }
  printer->Outdent();
  printer->Print("};\n");
}

std::string GetMockServices(grpc_generator::File* file,
                            const Parameters& params) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;
    // Package string is empty or ends with a dot. It is used to fully qualify
    // method names.
    vars["Package"] = file->package();
    if (!file->package().empty()) {
      vars["Package"].append(".");
    }

    if (!params.services_namespace.empty()) {
      vars["services_namespace"] = params.services_namespace;
      printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
    }

    for (int i = 0; i < file->service_count(); i++) {
      PrintMockService(printer.get(), file->service(i).get(), params, &vars);
      printer->Print("\n");
    }

    if (!params.services_namespace.empty()) {
      printer->Print(vars, "} // namespace $services_namespace$\n\n");
    }
  }
  return output;
}

std::string GetMockEpilogue(grpc_generator::File* file,
                            const Parameters& /*params*/) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<std::string, std::string> vars;
    vars["filename_identifier"] = FilenameIdentifier(file->filename());

    if (!file->package().empty()) {
      std::vector<std::string> parts = file->package_parts();
      for (auto part = parts.rbegin(); part != parts.rend(); part++) {
        vars["part"] = *part;
        printer->Print(vars, "}  // namespace $part$\n");
      }
      printer->Print(vars, "\n");
    }

    printer->Print(vars, "\n");
    printer->Print(vars,
                   "#endif  // GRPC_MOCK_$filename_identifier$__INCLUDED\n");
  }
  return output;
}

}  // namespace grpc_cpp_generator
