From 375a82b35c24952f35a728e5ea4d54dced982977 Mon Sep 17 00:00:00 2001
From: "Nicolas \"Pixel\" Noble" <pixel@nobis-crew.org>
Date: Tue, 24 Mar 2015 02:33:18 +0100
Subject: [PATCH] Adding the ability to specify a service namespace on protoc's
 command line.

Usage example: protoc ... --grpc_out=services_namespace=xyz:./path/to/output/dir ...

This is difficult to add a test for this without significantly changing all of the examples, or the build system. However this has been successfully tested locally.
---
 src/compiler/cpp_generator.cc    | 122 ++++++++++++++++++-------------
 src/compiler/cpp_generator.h     |  17 ++++-
 src/compiler/cpp_plugin.cc       |  25 ++++++-
 src/compiler/generator_helpers.h |  20 +++++
 4 files changed, 125 insertions(+), 59 deletions(-)

diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index d5004624d4..0a84c73520 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -111,7 +111,8 @@ bool HasBidiStreaming(const grpc::protobuf::FileDescriptor *file) {
 }
 }  // namespace
 
-grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file) {
+grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params) {
   grpc::string temp =
       "#include <grpc++/impl/internal_stub.h>\n"
       "#include <grpc++/impl/service_type.h>\n"
@@ -158,7 +159,7 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file) {
   return temp;
 }
 
-grpc::string GetSourceIncludes() {
+grpc::string GetSourceIncludes(const Parameters &param) {
   return "#include <grpc++/async_unary_call.h>\n"
          "#include <grpc++/channel_interface.h>\n"
          "#include <grpc++/impl/client_unary_call.h>\n"
@@ -353,16 +354,27 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
   printer->Print("};\n");
 }
 
-grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file) {
+grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params) {
   grpc::string output;
   grpc::protobuf::io::StringOutputStream output_stream(&output);
   grpc::protobuf::io::Printer printer(&output_stream, '$');
   std::map<grpc::string, grpc::string> vars;
 
+  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, file->service(i), &vars);
     printer.Print("\n");
   }
+
+  if (!params.services_namespace.empty()) {
+    printer.Print(vars, "}  // namespace $services_namespace$\n\n");
+  }
+
   return output;
 }
 
@@ -376,18 +388,18 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
       grpc_cpp_generator::ClassName(method->output_type(), true);
   if (NoStreaming(method)) {
     printer->Print(*vars,
-                   "::grpc::Status $Service$::Stub::$Method$("
+                   "::grpc::Status $ns$$Service$::Stub::$Method$("
                    "::grpc::ClientContext* context, "
                    "const $Request$& request, $Response$* response) {\n");
     printer->Print(*vars,
                    "  return ::grpc::BlockingUnaryCall(channel(),"
-                   "::grpc::RpcMethod($Service$_method_names[$Idx$]), "
+                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$]), "
                    "context, request, response);\n"
                    "}\n\n");
     printer->Print(
         *vars,
         "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
-        "$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
+        "$ns$$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
         "const $Request$& request, "
         "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
@@ -395,32 +407,32 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
                    "::grpc::ClientAsyncResponseReader< $Response$>>(new "
                    "::grpc::ClientAsyncResponseReader< $Response$>("
                    "channel(), cq, "
-                   "::grpc::RpcMethod($Service$_method_names[$Idx$]), "
+                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$]), "
                    "context, request, tag));\n"
                    "}\n\n");
   } else if (ClientOnlyStreaming(method)) {
     printer->Print(*vars,
                    "std::unique_ptr< ::grpc::ClientWriter< $Request$>> "
-                   "$Service$::Stub::$Method$("
+                   "$ns$$Service$::Stub::$Method$("
                    "::grpc::ClientContext* context, $Response$* response) {\n");
     printer->Print(*vars,
                    "  return std::unique_ptr< ::grpc::ClientWriter< "
                    "$Request$>>(new ::grpc::ClientWriter< $Request$>("
                    "channel(),"
-                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
                    "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
                    "context, response));\n"
                    "}\n\n");
     printer->Print(*vars,
                    "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>> "
-                   "$Service$::Stub::Async$Method$("
+                   "$ns$$Service$::Stub::Async$Method$("
                    "::grpc::ClientContext* context, $Response$* response, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
                    "  return std::unique_ptr< ::grpc::ClientAsyncWriter< "
                    "$Request$>>(new ::grpc::ClientAsyncWriter< $Request$>("
                    "channel(), cq, "
-                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
                    "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
                    "context, response, tag));\n"
                    "}\n\n");
@@ -428,26 +440,26 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
     printer->Print(
         *vars,
         "std::unique_ptr< ::grpc::ClientReader< $Response$>> "
-        "$Service$::Stub::$Method$("
+        "$ns$$Service$::Stub::$Method$("
         "::grpc::ClientContext* context, const $Request$& request) {\n");
     printer->Print(*vars,
                    "  return std::unique_ptr< ::grpc::ClientReader< "
                    "$Response$>>(new ::grpc::ClientReader< $Response$>("
                    "channel(),"
-                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
                    "::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
                    "context, request));\n"
                    "}\n\n");
     printer->Print(*vars,
                    "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
-                   "$Service$::Stub::Async$Method$("
+                   "$ns$$Service$::Stub::Async$Method$("
                    "::grpc::ClientContext* context, const $Request$& request, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
                    "  return std::unique_ptr< ::grpc::ClientAsyncReader< "
                    "$Response$>>(new ::grpc::ClientAsyncReader< $Response$>("
                    "channel(), cq, "
-                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
                    "::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
                    "context, request, tag));\n"
                    "}\n\n");
@@ -455,27 +467,27 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
     printer->Print(
         *vars,
         "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>> "
-        "$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n");
+        "$ns$$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n");
     printer->Print(*vars,
                    "  return std::unique_ptr< ::grpc::ClientReaderWriter< "
                    "$Request$, $Response$>>(new ::grpc::ClientReaderWriter< "
                    "$Request$, $Response$>("
                    "channel(),"
-                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
                    "::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
                    "context));\n"
                    "}\n\n");
     printer->Print(*vars,
                    "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
                    "$Request$, $Response$>> "
-                   "$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
+                   "$ns$$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
                    "  return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
                    "$Request$, $Response$>>(new "
                    "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
                    "channel(), cq, "
-                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
                    "::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
                    "context, tag));\n"
                    "}\n\n");
@@ -492,7 +504,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
       grpc_cpp_generator::ClassName(method->output_type(), true);
   if (NoStreaming(method)) {
     printer->Print(*vars,
-                   "::grpc::Status $Service$::Service::$Method$("
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
                    "::grpc::ServerContext* context, "
                    "const $Request$* request, $Response$* response) {\n");
     printer->Print(
@@ -501,7 +513,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
     printer->Print("}\n\n");
   } else if (ClientOnlyStreaming(method)) {
     printer->Print(*vars,
-                   "::grpc::Status $Service$::Service::$Method$("
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
                    "::grpc::ServerContext* context, "
                    "::grpc::ServerReader< $Request$>* reader, "
                    "$Response$* response) {\n");
@@ -511,7 +523,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
     printer->Print("}\n\n");
   } else if (ServerOnlyStreaming(method)) {
     printer->Print(*vars,
-                   "::grpc::Status $Service$::Service::$Method$("
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
                    "::grpc::ServerContext* context, "
                    "const $Request$* request, "
                    "::grpc::ServerWriter< $Response$>* writer) {\n");
@@ -521,7 +533,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
     printer->Print("}\n\n");
   } else if (BidiStreaming(method)) {
     printer->Print(*vars,
-                   "::grpc::Status $Service$::Service::$Method$("
+                   "::grpc::Status $ns$$Service$::Service::$Method$("
                    "::grpc::ServerContext* context, "
                    "::grpc::ServerReaderWriter< $Response$, $Request$>* "
                    "stream) {\n");
@@ -543,7 +555,7 @@ void PrintSourceServerAsyncMethod(
       grpc_cpp_generator::ClassName(method->output_type(), true);
   if (NoStreaming(method)) {
     printer->Print(*vars,
-                   "void $Service$::AsyncService::Request$Method$("
+                   "void $ns$$Service$::AsyncService::Request$Method$("
                    "::grpc::ServerContext* context, "
                    "$Request$* request, "
                    "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
@@ -554,7 +566,7 @@ void PrintSourceServerAsyncMethod(
     printer->Print("}\n\n");
   } else if (ClientOnlyStreaming(method)) {
     printer->Print(*vars,
-                   "void $Service$::AsyncService::Request$Method$("
+                   "void $ns$$Service$::AsyncService::Request$Method$("
                    "::grpc::ServerContext* context, "
                    "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
@@ -564,7 +576,7 @@ void PrintSourceServerAsyncMethod(
     printer->Print("}\n\n");
   } else if (ServerOnlyStreaming(method)) {
     printer->Print(*vars,
-                   "void $Service$::AsyncService::Request$Method$("
+                   "void $ns$$Service$::AsyncService::Request$Method$("
                    "::grpc::ServerContext* context, "
                    "$Request$* request, "
                    "::grpc::ServerAsyncWriter< $Response$>* writer, "
@@ -576,7 +588,7 @@ void PrintSourceServerAsyncMethod(
   } else if (BidiStreaming(method)) {
     printer->Print(
         *vars,
-        "void $Service$::AsyncService::Request$Method$("
+        "void $ns$$Service$::AsyncService::Request$Method$("
         "::grpc::ServerContext* context, "
         "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
         "::grpc::CompletionQueue* cq, void *tag) {\n");
@@ -592,7 +604,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
                         std::map<grpc::string, grpc::string> *vars) {
   (*vars)["Service"] = service->name();
 
-  printer->Print(*vars, "static const char* $Service$_method_names[] = {\n");
+  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");
@@ -601,9 +613,9 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
 
   printer->Print(
       *vars,
-      "std::unique_ptr< $Service$::Stub> $Service$::NewStub("
+      "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
       "const std::shared_ptr< ::grpc::ChannelInterface>& channel) {\n"
-      "  std::unique_ptr< $Service$::Stub> stub(new $Service$::Stub());\n"
+      "  std::unique_ptr< $ns$$Service$::Stub> stub(new $ns$$Service$::Stub());\n"
       "  stub->set_channel(channel);\n"
       "  return stub;\n"
       "}\n\n");
@@ -615,12 +627,12 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
   (*vars)["MethodCount"] = as_string(service->method_count());
   printer->Print(
       *vars,
-      "$Service$::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : "
-      "::grpc::AsynchronousService(cq, $Service$_method_names, $MethodCount$) "
+      "$ns$$Service$::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : "
+      "::grpc::AsynchronousService(cq, $prefix$$Service$_method_names, $MethodCount$) "
       "{}\n\n");
 
   printer->Print(*vars,
-                 "$Service$::Service::~Service() {\n"
+                 "$ns$$Service$::Service::~Service() {\n"
                  "  delete service_;\n"
                  "}\n\n");
   for (int i = 0; i < service->method_count(); ++i) {
@@ -629,7 +641,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
     PrintSourceServerAsyncMethod(printer, service->method(i), vars);
   }
   printer->Print(*vars,
-                 "::grpc::RpcService* $Service$::Service::service() {\n");
+                 "::grpc::RpcService* $ns$$Service$::Service::service() {\n");
   printer->Indent();
   printer->Print(
       "if (service_ != nullptr) {\n"
@@ -648,52 +660,52 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
       printer->Print(
           *vars,
           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
-          "    $Service$_method_names[$Idx$],\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
           "    ::grpc::RpcMethod::NORMAL_RPC,\n"
-          "    new ::grpc::RpcMethodHandler< $Service$::Service, $Request$, "
+          "    new ::grpc::RpcMethodHandler< $ns$$Service$::Service, $Request$, "
           "$Response$>(\n"
-          "        std::function< ::grpc::Status($Service$::Service*, "
+          "        std::function< ::grpc::Status($ns$$Service$::Service*, "
           "::grpc::ServerContext*, const $Request$*, $Response$*)>("
-          "&$Service$::Service::$Method$), this),\n"
+          "&$ns$$Service$::Service::$Method$), this),\n"
           "    new $Request$, new $Response$));\n");
     } else if (ClientOnlyStreaming(method)) {
       printer->Print(
           *vars,
           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
-          "    $Service$_method_names[$Idx$],\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
           "    ::grpc::RpcMethod::CLIENT_STREAMING,\n"
           "    new ::grpc::ClientStreamingHandler< "
-          "$Service$::Service, $Request$, $Response$>(\n"
-          "        std::function< ::grpc::Status($Service$::Service*, "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::function< ::grpc::Status($ns$$Service$::Service*, "
           "::grpc::ServerContext*, "
           "::grpc::ServerReader< $Request$>*, $Response$*)>("
-          "&$Service$::Service::$Method$), this),\n"
+          "&$ns$$Service$::Service::$Method$), this),\n"
           "    new $Request$, new $Response$));\n");
     } else if (ServerOnlyStreaming(method)) {
       printer->Print(
           *vars,
           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
-          "    $Service$_method_names[$Idx$],\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
           "    ::grpc::RpcMethod::SERVER_STREAMING,\n"
           "    new ::grpc::ServerStreamingHandler< "
-          "$Service$::Service, $Request$, $Response$>(\n"
-          "        std::function< ::grpc::Status($Service$::Service*, "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::function< ::grpc::Status($ns$$Service$::Service*, "
           "::grpc::ServerContext*, "
           "const $Request$*, ::grpc::ServerWriter< $Response$>*)>("
-          "&$Service$::Service::$Method$), this),\n"
+          "&$ns$$Service$::Service::$Method$), this),\n"
           "    new $Request$, new $Response$));\n");
     } else if (BidiStreaming(method)) {
       printer->Print(
           *vars,
           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
-          "    $Service$_method_names[$Idx$],\n"
+          "    $prefix$$Service$_method_names[$Idx$],\n"
           "    ::grpc::RpcMethod::BIDI_STREAMING,\n"
           "    new ::grpc::BidiStreamingHandler< "
-          "$Service$::Service, $Request$, $Response$>(\n"
-          "        std::function< ::grpc::Status($Service$::Service*, "
+          "$ns$$Service$::Service, $Request$, $Response$>(\n"
+          "        std::function< ::grpc::Status($ns$$Service$::Service*, "
           "::grpc::ServerContext*, "
           "::grpc::ServerReaderWriter< $Response$, $Request$>*)>("
-          "&$Service$::Service::$Method$), this),\n"
+          "&$ns$$Service$::Service::$Method$), this),\n"
           "    new $Request$, new $Response$));\n");
     }
   }
@@ -702,7 +714,8 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
   printer->Print("}\n\n");
 }
 
-grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file) {
+grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params) {
   grpc::string output;
   grpc::protobuf::io::StringOutputStream output_stream(&output);
   grpc::protobuf::io::Printer printer(&output_stream, '$');
@@ -713,6 +726,13 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file) {
   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, file->service(i), &vars);
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index 2ecdb5c47e..04ad71c067 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -38,17 +38,26 @@
 
 namespace grpc_cpp_generator {
 
+// Contains all the parameters that are parsed from the command line.
+struct Parameters {
+  // Puts the service into a namespace
+  grpc::string services_namespace;
+};
+
 // Return the includes needed for generated header file.
-grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file);
+grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params);
 
 // Return the includes needed for generated source file.
-grpc::string GetSourceIncludes();
+grpc::string GetSourceIncludes(const Parameters &params);
 
 // Return the services for generated header file.
-grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file);
+grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params);
 
 // Return the services for generated source file.
-grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file);
+grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params);
 
 }  // namespace grpc_cpp_generator
 
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index 5b83aa85cf..534abdeed0 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -58,18 +58,35 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
       return false;
     }
 
+    grpc_cpp_generator::Parameters generator_parameters;
+
+    if (!parameter.empty()) {
+      std::vector<grpc::string> parameters_list =
+        grpc_generator::tokenize(parameter, ",");
+      for (auto &parameter_string: parameters_list) {
+        std::vector<grpc::string> param =
+          grpc_generator::tokenize(parameter_string, "=");
+        if (param[0] == "services_namespace") {
+          generator_parameters.services_namespace = param[1];
+        } else {
+          *error = grpc::string("Unknown parameter: ") + parameter_string;
+          return false;
+        }
+      }
+    }
+
     grpc::string file_name = grpc_generator::StripProto(file->name());
 
     // Generate .pb.h
     Insert(context, file_name + ".pb.h", "includes",
-           grpc_cpp_generator::GetHeaderIncludes(file));
+           grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters));
     Insert(context, file_name + ".pb.h", "namespace_scope",
-           grpc_cpp_generator::GetHeaderServices(file));
+           grpc_cpp_generator::GetHeaderServices(file, generator_parameters));
     // Generate .pb.cc
     Insert(context, file_name + ".pb.cc", "includes",
-           grpc_cpp_generator::GetSourceIncludes());
+           grpc_cpp_generator::GetSourceIncludes(generator_parameters));
     Insert(context, file_name + ".pb.cc", "namespace_scope",
-           grpc_cpp_generator::GetSourceServices(file));
+           grpc_cpp_generator::GetSourceServices(file, generator_parameters));
 
     return true;
   }
diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h
index 1e6727dd4c..30857891c7 100644
--- a/src/compiler/generator_helpers.h
+++ b/src/compiler/generator_helpers.h
@@ -75,6 +75,26 @@ inline grpc::string StringReplace(grpc::string str, const grpc::string &from,
   return str;
 }
 
+inline std::vector<grpc::string> tokenize(const grpc::string &input,
+                                          const grpc::string &delimiters) {
+  std::vector<grpc::string> tokens;
+  size_t pos, last_pos = 0;
+
+  for (;;) {
+    bool done = false;
+    pos = input.find_first_of(delimiters, last_pos);
+    if (pos == grpc::string::npos) {
+      done = true;
+      pos = input.length();
+    }
+
+    tokens.push_back(input.substr(last_pos, pos - last_pos));
+    if (done) return tokens;
+
+    last_pos = pos + 1;
+  }
+}
+
 }  // namespace grpc_generator
 
 #endif  // GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H
-- 
GitLab