/*
 *
 * 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 <map>

#include "src/compiler/cpp_generator.h"

#include <sstream>

namespace grpc_cpp_generator {
namespace {

template <class T>
grpc::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();
}

grpc::string FilenameIdentifier(const grpc::string& filename) {
  grpc::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<grpc::string>& headers,
                   bool use_system_headers, const grpc::string& search_path) {
  std::map<grpc::string, grpc::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");
  }
}

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

    vars["filename"] = file->filename();
    vars["filename_identifier"] = FilenameIdentifier(file->filename());
    vars["filename_base"] = file->filename_without_ext();
    vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;

    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");
    grpc::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;
}

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

    if (!params.additional_header_includes.empty()) {
      PrintIncludes(printer.get(), params.additional_header_includes, false,
                    "");
    }
    static const char* headers_strs[] = {
        "functional",
        "grpcpp/impl/codegen/async_generic_service.h",
        "grpcpp/impl/codegen/async_stream.h",
        "grpcpp/impl/codegen/async_unary_call.h",
        "grpcpp/impl/codegen/client_callback.h",
        "grpcpp/impl/codegen/method_handler_impl.h",
        "grpcpp/impl/codegen/proto_utils.h",
        "grpcpp/impl/codegen/rpc_method.h",
        "grpcpp/impl/codegen/server_callback.h",
        "grpcpp/impl/codegen/service_type.h",
        "grpcpp/impl/codegen/status.h",
        "grpcpp/impl/codegen/stub_options.h",
        "grpcpp/impl/codegen/sync_stream.h"};
    std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
    PrintIncludes(printer.get(), headers, params.use_system_headers,
                  params.grpc_search_path);
    printer->Print(vars, "\n");
    printer->Print(vars, "namespace grpc {\n");
    printer->Print(vars, "class CompletionQueue;\n");
    printer->Print(vars, "class Channel;\n");
    printer->Print(vars, "class ServerCompletionQueue;\n");
    printer->Print(vars, "class ServerContext;\n");
    printer->Print(vars, "}  // namespace grpc\n\n");

    if (!file->package().empty()) {
      std::vector<grpc::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,
    std::map<grpc::string, grpc::string>* vars, bool is_public) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();

  struct {
    grpc::string prefix;
    grpc::string method_params;  // extra arguments to method
    grpc::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");
      for (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");
      for (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");
      for (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");
      for (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()) {
      for (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");
      for (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");
      for (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");
      for (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,
                             std::map<grpc::string, grpc::string>* vars,
                             bool is_public) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  struct {
    grpc::string prefix;
    grpc::string method_params;  // extra arguments to method
    grpc::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");
      for (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");
      for (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");
      for (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");
      for (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()) {
      for (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");
      for (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");
      for (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");
      for (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<grpc::string, grpc::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 experimental_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 ~experimental_async_interface() {}\n");
}

void PrintHeaderClientMethodCallbackInterfaces(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    std::map<grpc::string, grpc::string>* vars, bool is_public) {
  // Reserve is_public for future expansion
  assert(is_public);

  (*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");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(*vars,
                   "virtual void $Method$(::grpc::ClientContext* context, "
                   "$Response$* response, "
                   "::grpc::experimental::ClientWriteReactor< $Request$>* "
                   "reactor) = 0;\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(*vars,
                   "virtual void $Method$(::grpc::ClientContext* context, "
                   "$Request$* request, "
                   "::grpc::experimental::ClientReadReactor< $Response$>* "
                   "reactor) = 0;\n");
  } else if (method->BidiStreaming()) {
    printer->Print(*vars,
                   "virtual void $Method$(::grpc::ClientContext* context, "
                   "::grpc::experimental::ClientBidiReactor< "
                   "$Request$,$Response$>* reactor) = 0;\n");
  }
}

void PrintHeaderClientMethodCallbackInterfacesEnd(
    grpc_generator::Printer* printer,
    std::map<grpc::string, grpc::string>* vars) {
  printer->Outdent();
  printer->Print("};\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.
  printer->Print(
      "virtual class experimental_async_interface* experimental_async() { "
      "return nullptr; }\n");
}

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

void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
                                     const grpc_generator::Method* method,
                                     std::map<grpc::string, grpc::string>* vars,
                                     bool is_public) {
  // Reserve is_public for future expansion
  assert(is_public);

  (*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");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(*vars,
                   "void $Method$(::grpc::ClientContext* context, "
                   "$Response$* response, "
                   "::grpc::experimental::ClientWriteReactor< $Request$>* "
                   "reactor) override;\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(*vars,
                   "void $Method$(::grpc::ClientContext* context, "
                   "$Request$* request, "
                   "::grpc::experimental::ClientReadReactor< $Response$>* "
                   "reactor) override;\n");

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

void PrintHeaderClientMethodCallbackEnd(
    grpc_generator::Printer* printer,
    std::map<grpc::string, grpc::string>* vars) {
  printer->Outdent();
  printer->Print(" private:\n");
  printer->Indent();
  printer->Print("friend class Stub;\n");
  printer->Print("explicit experimental_async(Stub* stub): stub_(stub) { }\n");
  // include a function with a dummy 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 experimental_async_interface* experimental_async() override { "
      "return &async_stub_; }\n");
}

void PrintHeaderClientMethodData(grpc_generator::Printer* printer,
                                 const grpc_generator::Method* method,
                                 std::map<grpc::string, grpc::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,
                                 std::map<grpc::string, grpc::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 (method->NoStreaming()) {
    printer->Print(*vars,
                   "virtual ::grpc::Status $Method$("
                   "::grpc::ServerContext* context, const $Request$* request, "
                   "$Response$* response);\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(*vars,
                   "virtual ::grpc::Status $Method$("
                   "::grpc::ServerContext* context, "
                   "::grpc::ServerReader< $Request$>* reader, "
                   "$Response$* response);\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(*vars,
                   "virtual ::grpc::Status $Method$("
                   "::grpc::ServerContext* context, const $Request$* request, "
                   "::grpc::ServerWriter< $Response$>* writer);\n");
  } else if (method->BidiStreaming()) {
    printer->Print(
        *vars,
        "virtual ::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,
    std::map<grpc::string, grpc::string>* vars) {
  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");
    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)) {
    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)) {
    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()) {
    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,
                                  std::map<grpc::string, grpc::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, 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,
    std::map<grpc::string, grpc::string>* vars) {
  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");
    printer->Print(
        *vars,
        "virtual void $Method$("
        "::grpc::ServerContext* context, const $RealRequest$* request, "
        "$RealResponse$* response, "
        "::grpc::experimental::ServerCallbackRpcController* "
        "controller) { controller->Finish(::grpc::Status("
        "::grpc::StatusCode::UNIMPLEMENTED, \"\")); }\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");
    printer->Print(*vars,
                   "virtual ::grpc::experimental::ServerReadReactor< "
                   "$RealRequest$, $RealResponse$>* $Method$() {\n"
                   "  return new ::grpc::internal::UnimplementedReadReactor<\n"
                   "    $RealRequest$, $RealResponse$>;}\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");
    printer->Print(*vars,
                   "virtual ::grpc::experimental::ServerWriteReactor< "
                   "$RealRequest$, $RealResponse$>* $Method$() {\n"
                   "  return new ::grpc::internal::UnimplementedWriteReactor<\n"
                   "    $RealRequest$, $RealResponse$>;}\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->Print(*vars,
                   "virtual ::grpc::experimental::ServerBidiReactor< "
                   "$RealRequest$, $RealResponse$>* $Method$() {\n"
                   "  return new ::grpc::internal::UnimplementedBidiReactor<\n"
                   "    $RealRequest$, $RealResponse$>;}\n");
  }
}

void PrintHeaderServerMethodCallback(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    std::map<grpc::string, grpc::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 ExperimentalWithCallbackMethod_$Method$ : public BaseClass {\n");
  printer->Print(
      " private:\n"
      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  printer->Print(" public:\n");
  printer->Indent();
  printer->Print(*vars, "ExperimentalWithCallbackMethod_$Method$() {\n");
  if (method->NoStreaming()) {
    printer->Print(
        *vars,
        "  ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
        "    new ::grpc::internal::CallbackUnaryHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "      [this](::grpc::ServerContext* context,\n"
        "             const $RealRequest$* request,\n"
        "             $RealResponse$* response,\n"
        "             ::grpc::experimental::ServerCallbackRpcController* "
        "controller) {\n"
        "               return this->$"
        "Method$(context, request, response, controller);\n"
        "             }));\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "  ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
        "    new ::grpc::internal::CallbackClientStreamingHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "      [this] { return this->$Method$(); }));\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "  ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
        "    new ::grpc::internal::CallbackServerStreamingHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "      [this] { return this->$Method$(); }));\n");
  } else if (method->BidiStreaming()) {
    printer->Print(
        *vars,
        "  ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
        "    new ::grpc::internal::CallbackBidiHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "      [this] { return this->$Method$(); }));\n");
  }
  printer->Print(*vars, "}\n");
  printer->Print(*vars,
                 "~ExperimentalWithCallbackMethod_$Method$() override {\n"
                 "  BaseClassMustBeDerivedFromService(this);\n"
                 "}\n");
  PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
  printer->Outdent();
  printer->Print(*vars, "};\n");
}

void PrintHeaderServerMethodRawCallback(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    std::map<grpc::string, grpc::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 ExperimentalWithRawCallbackMethod_$Method$ : public "
                 "BaseClass {\n");
  printer->Print(
      " private:\n"
      "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  printer->Print(" public:\n");
  printer->Indent();
  printer->Print(*vars, "ExperimentalWithRawCallbackMethod_$Method$() {\n");
  if (method->NoStreaming()) {
    printer->Print(
        *vars,
        "  ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
        "    new ::grpc::internal::CallbackUnaryHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "      [this](::grpc::ServerContext* context,\n"
        "             const $RealRequest$* request,\n"
        "             $RealResponse$* response,\n"
        "             ::grpc::experimental::ServerCallbackRpcController* "
        "controller) {\n"
        "               this->$"
        "Method$(context, request, response, controller);\n"
        "             }));\n");
  } else if (ClientOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "  ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
        "    new ::grpc::internal::CallbackClientStreamingHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "      [this] { return this->$Method$(); }));\n");
  } else if (ServerOnlyStreaming(method)) {
    printer->Print(
        *vars,
        "  ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
        "    new ::grpc::internal::CallbackServerStreamingHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "      [this] { return this->$Method$(); }));\n");
  } else if (method->BidiStreaming()) {
    printer->Print(
        *vars,
        "  ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
        "    new ::grpc::internal::CallbackBidiHandler< "
        "$RealRequest$, $RealResponse$>(\n"
        "      [this] { return this->$Method$(); }));\n");
  }
  printer->Print(*vars, "}\n");
  printer->Print(*vars,
                 "~ExperimentalWithRawCallbackMethod_$Method$() override {\n"
                 "  BaseClassMustBeDerivedFromService(this);\n"
                 "}\n");
  PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
  printer->Outdent();
  printer->Print(*vars, "};\n");
}

void PrintHeaderServerMethodStreamedUnary(
    grpc_generator::Printer* printer, const grpc_generator::Method* method,
    std::map<grpc::string, grpc::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< $Request$, "
                   "$Response$>(std::bind"
                   "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
                   "Streamed$Method$, this, std::placeholders::_1, "
                   "std::placeholders::_2)));\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<grpc::string, grpc::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< $Request$, "
        "$Response$>(std::bind"
        "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
        "Streamed$Method$, this, std::placeholders::_1, "
        "std::placeholders::_2)));\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,
    std::map<grpc::string, grpc::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 (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,
                                std::map<grpc::string, grpc::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, vars);
  printer->Outdent();
  printer->Print(*vars, "};\n");
}

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

  printer->Print(service->GetLeadingComments("//").c_str());
  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(), 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, true);
    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(), 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);\n");
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
  }
  PrintHeaderClientMethodCallbackStart(printer, vars);
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars,
                                    true);
  }
  PrintHeaderClientMethodCallbackEnd(printer, vars);
  printer->Outdent();
  printer->Print("\n private:\n");
  printer->Indent();
  printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
  printer->Print("class experimental_async async_stub_{this};\n");
  for (int i = 0; i < service->method_count(); ++i) {
    PrintHeaderClientMethod(printer, service->method(i).get(), 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(), vars);
  }
  printer->Outdent();
  printer->Print("};\n");

  // Server side - Asynchronous
  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["Idx"] = as_string(i);
    PrintHeaderServerMethodAsync(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();
    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(), vars);
  }

  printer->Print("typedef ");

  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["method_name"] = service->method(i)->name();
    printer->Print(*vars, "ExperimentalWithCallbackMethod_$method_name$<");
  }
  printer->Print("Service");
  for (int i = 0; i < service->method_count(); ++i) {
    printer->Print(" >");
  }
  printer->Print(" 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(), vars);
  }

  // Server side - Raw
  for (int i = 0; i < service->method_count(); ++i) {
    (*vars)["Idx"] = as_string(i);
    PrintHeaderServerMethodRaw(printer, service->method(i).get(), 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(), vars);
  }

  // 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());
}

grpc::string GetHeaderServices(grpc_generator::File* file,
                               const Parameters& params) {
  grpc::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<grpc::string, grpc::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(), &vars);
      printer->Print("\n");
    }

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

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

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

    if (!file->package().empty()) {
      std::vector<grpc::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_$filename_identifier$__INCLUDED\n");

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

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

    vars["filename"] = file->filename();
    vars["filename_base"] = file->filename_without_ext();
    vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
    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;
}

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

    static const char* headers_strs[] = {
        "functional",
        "grpcpp/impl/codegen/async_stream.h",
        "grpcpp/impl/codegen/async_unary_call.h",
        "grpcpp/impl/codegen/channel_interface.h",
        "grpcpp/impl/codegen/client_unary_call.h",
        "grpcpp/impl/codegen/client_callback.h",
        "grpcpp/impl/codegen/method_handler_impl.h",
        "grpcpp/impl/codegen/rpc_service_method.h",
        "grpcpp/impl/codegen/server_callback.h",
        "grpcpp/impl/codegen/service_type.h",
        "grpcpp/impl/codegen/sync_stream.h"};
    std::vector<grpc::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<grpc::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,
                             std::map<grpc::string, grpc::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();
  struct {
    grpc::string prefix;
    grpc::string start;          // bool literal expressed as string
    grpc::string method_params;  // extra arguments to method
    grpc::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"
                   "(channel_.get(), rpcmethod_$Method$_, "
                   "context, request, response);\n}\n\n");

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

    for (auto async_prefix : async_prefixes) {
      (*vars)["AsyncPrefix"] = async_prefix.prefix;
      (*vars)["AsyncStart"] = async_prefix.start;
      printer->Print(*vars,
                     "::grpc::ClientAsyncResponseReader< $Response$>* "
                     "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
                     "ClientContext* context, "
                     "const $Request$& request, "
                     "::grpc::CompletionQueue* cq) {\n");
      printer->Print(
          *vars,
          "  return "
          "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
          "::Create(channel_.get(), cq, "
          "rpcmethod_$Method$_, "
          "context, request, $AsyncStart$);\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::experimental_async::$Method$(::grpc::ClientContext* context, "
        "$Response$* response, "
        "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n");
    printer->Print(*vars,
                   "  ::grpc::internal::ClientCallbackWriterFactory< "
                   "$Request$>::Create("
                   "stub_->channel_.get(), "
                   "stub_->rpcmethod_$Method$_, "
                   "context, response, reactor);\n"
                   "}\n\n");

    for (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::experimental_async::$Method$(::grpc::"
        "ClientContext* context, "
        "$Request$* request, "
        "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n");
    printer->Print(*vars,
                   "  ::grpc::internal::ClientCallbackReaderFactory< "
                   "$Response$>::Create("
                   "stub_->channel_.get(), "
                   "stub_->rpcmethod_$Method$_, "
                   "context, request, reactor);\n"
                   "}\n\n");

    for (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::experimental_async::$Method$(::grpc::"
        "ClientContext* context, "
        "::grpc::experimental::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");

    for (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,
                             std::map<grpc::string, grpc::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");
    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");
    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");
    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");
    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,
                        std::map<grpc::string, grpc::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));\n"
                 "  return stub;\n"
                 "}\n\n");
  printer->Print(*vars,
                 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
                 "::grpc::ChannelInterface>& channel)\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$], "
                   "::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(), 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$>(\n"
          "        std::mem_fn(&$ns$$Service$::Service::$Method$), 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"
          "        std::mem_fn(&$ns$$Service$::Service::$Method$), 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"
          "        std::mem_fn(&$ns$$Service$::Service::$Method$), 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"
          "        std::mem_fn(&$ns$$Service$::Service::$Method$), 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(), vars);
  }
}

grpc::string GetSourceServices(grpc_generator::File* file,
                               const Parameters& params) {
  grpc::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<grpc::string, grpc::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(), &vars);
      printer->Print("\n");
    }
  }
  return output;
}

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

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

    for (auto part = parts.begin(); part != parts.end(); part++) {
      temp.append("}  // namespace ");
      temp.append(*part);
      temp.append("\n");
    }
    temp.append("\n");
  }

  return temp;
}

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

    vars["filename"] = file->filename();
    vars["filename_base"] = file->filename_without_ext();
    vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
    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, file->additional_headers().c_str());
    printer->Print(vars, "\n");
  }
  return output;
}

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

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

    std::vector<grpc::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<grpc::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,
                            std::map<grpc::string, grpc::string>* vars) {
  (*vars)["Method"] = method->name();
  (*vars)["Request"] = method->input_type_name();
  (*vars)["Response"] = method->output_type_name();

  struct {
    grpc::string prefix;
    grpc::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");
    for (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");
    for (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");
    for (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");
    for (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,
                      std::map<grpc::string, grpc::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(), vars);
  }
  printer->Outdent();
  printer->Print("};\n");
}

grpc::string GetMockServices(grpc_generator::File* file,
                             const Parameters& params) {
  grpc::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.
    auto printer = file->CreatePrinter(&output);
    std::map<grpc::string, grpc::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(), &vars);
      printer->Print("\n");
    }

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

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

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

    for (auto part = parts.begin(); part != parts.end(); part++) {
      temp.append("} // namespace ");
      temp.append(*part);
      temp.append("\n");
    }
    temp.append("\n");
  }

  return temp;
}

}  // namespace grpc_cpp_generator
