LCOV - code coverage report
Current view: top level - src/compiler - cpp_generator.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 487 492 99.0 %
Date: 2015-10-10 Functions: 24 24 100.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are
       8             :  * met:
       9             :  *
      10             :  *     * Redistributions of source code must retain the above copyright
      11             :  * notice, this list of conditions and the following disclaimer.
      12             :  *     * Redistributions in binary form must reproduce the above
      13             :  * copyright notice, this list of conditions and the following disclaimer
      14             :  * in the documentation and/or other materials provided with the
      15             :  * distribution.
      16             :  *     * Neither the name of Google Inc. nor the names of its
      17             :  * contributors may be used to endorse or promote products derived from
      18             :  * this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  */
      33             : 
      34             : #include <map>
      35             : 
      36             : #include "src/compiler/cpp_generator.h"
      37             : #include "src/compiler/cpp_generator_helpers.h"
      38             : 
      39             : #include "src/compiler/config.h"
      40             : 
      41             : #include <sstream>
      42             : 
      43             : namespace grpc_cpp_generator {
      44             : namespace {
      45             : 
      46             : template <class T>
      47         102 : grpc::string as_string(T x) {
      48         102 :   std::ostringstream out;
      49         102 :   out << x;
      50         102 :   return out.str();
      51             : }
      52             : 
      53         231 : bool NoStreaming(const grpc::protobuf::MethodDescriptor *method) {
      54         231 :   return !method->client_streaming() && !method->server_streaming();
      55             : }
      56             : 
      57         110 : bool ClientOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
      58         110 :   return method->client_streaming() && !method->server_streaming();
      59             : }
      60             : 
      61          88 : bool ServerOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
      62          88 :   return !method->client_streaming() && method->server_streaming();
      63             : }
      64             : 
      65          60 : bool BidiStreaming(const grpc::protobuf::MethodDescriptor *method) {
      66          60 :   return method->client_streaming() && method->server_streaming();
      67             : }
      68             : 
      69          16 : grpc::string FilenameIdentifier(const grpc::string &filename) {
      70          16 :   grpc::string result;
      71         428 :   for (unsigned i = 0; i < filename.size(); i++) {
      72         412 :     char c = filename[i];
      73         412 :     if (isalnum(c)) {
      74         350 :       result.push_back(c);
      75             :     } else {
      76             :       static char hex[] = "0123456789abcdef";
      77          62 :       result.push_back('_');
      78          62 :       result.push_back(hex[(c >> 4) & 0xf]);
      79          62 :       result.push_back(hex[c & 0xf]);
      80             :     }
      81             :   }
      82          16 :   return result;
      83             : }
      84             : }  // namespace
      85             : 
      86           8 : grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
      87             :                                const Parameters &params) {
      88           8 :   grpc::string output;
      89             :   {
      90             :     // Scope the output stream so it closes and finalizes output to the string.
      91           8 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
      92          16 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
      93          16 :     std::map<grpc::string, grpc::string> vars;
      94             : 
      95           8 :     vars["filename"] = file->name();
      96           8 :     vars["filename_identifier"] = FilenameIdentifier(file->name());
      97           8 :     vars["filename_base"] = grpc_generator::StripProto(file->name());
      98             : 
      99           8 :     printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
     100             :     printer.Print(vars,
     101           8 :                   "// If you make any local change, they will be lost.\n");
     102           8 :     printer.Print(vars, "// source: $filename$\n");
     103           8 :     printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
     104           8 :     printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
     105           8 :     printer.Print(vars, "\n");
     106           8 :     printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
     107          16 :     printer.Print(vars, "\n");
     108             :   }
     109           8 :   return output;
     110             : }
     111             : 
     112           8 : grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
     113             :                                const Parameters &params) {
     114             :   grpc::string temp =
     115             :       "#include <grpc++/support/async_stream.h>\n"
     116             :       "#include <grpc++/impl/rpc_method.h>\n"
     117             :       "#include <grpc++/impl/proto_utils.h>\n"
     118             :       "#include <grpc++/impl/service_type.h>\n"
     119             :       "#include <grpc++/support/async_unary_call.h>\n"
     120             :       "#include <grpc++/support/status.h>\n"
     121             :       "#include <grpc++/support/stub_options.h>\n"
     122             :       "#include <grpc++/support/sync_stream.h>\n"
     123             :       "\n"
     124             :       "namespace grpc {\n"
     125             :       "class CompletionQueue;\n"
     126             :       "class Channel;\n"
     127             :       "class RpcService;\n"
     128             :       "class ServerCompletionQueue;\n"
     129             :       "class ServerContext;\n"
     130           8 :       "}  // namespace grpc\n\n";
     131             : 
     132           8 :   if (!file->package().empty()) {
     133             :     std::vector<grpc::string> parts =
     134           8 :         grpc_generator::tokenize(file->package(), ".");
     135             : 
     136          31 :     for (auto part = parts.begin(); part != parts.end(); part++) {
     137          23 :       temp.append("namespace ");
     138          23 :       temp.append(*part);
     139          23 :       temp.append(" {\n");
     140             :     }
     141           8 :     temp.append("\n");
     142             :   }
     143             : 
     144           8 :   return temp;
     145             : }
     146             : 
     147          42 : void PrintHeaderClientMethodInterfaces(
     148             :     grpc::protobuf::io::Printer *printer,
     149             :     const grpc::protobuf::MethodDescriptor *method,
     150             :     std::map<grpc::string, grpc::string> *vars, bool is_public) {
     151          42 :   (*vars)["Method"] = method->name();
     152          84 :   (*vars)["Request"] =
     153          42 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     154          84 :   (*vars)["Response"] =
     155          42 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     156             : 
     157          42 :   if (is_public) {
     158          21 :     if (NoStreaming(method)) {
     159             :       printer->Print(
     160             :           *vars,
     161             :           "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
     162          11 :           "const $Request$& request, $Response$* response) = 0;\n");
     163             :       printer->Print(*vars,
     164             :                      "std::unique_ptr< "
     165             :                      "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
     166             :                      "Async$Method$(::grpc::ClientContext* context, "
     167             :                      "const $Request$& request, "
     168          11 :                      "::grpc::CompletionQueue* cq) {\n");
     169          11 :       printer->Indent();
     170             :       printer->Print(*vars,
     171             :                      "return std::unique_ptr< "
     172             :                      "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
     173          11 :                      "Async$Method$Raw(context, request, cq));\n");
     174          11 :       printer->Outdent();
     175          11 :       printer->Print("}\n");
     176          10 :     } else if (ClientOnlyStreaming(method)) {
     177             :       printer->Print(
     178             :           *vars,
     179             :           "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
     180             :           " $Method$("
     181           2 :           "::grpc::ClientContext* context, $Response$* response) {\n");
     182           2 :       printer->Indent();
     183             :       printer->Print(
     184             :           *vars,
     185             :           "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
     186           2 :           "($Method$Raw(context, response));\n");
     187           2 :       printer->Outdent();
     188           2 :       printer->Print("}\n");
     189             :       printer->Print(
     190             :           *vars,
     191             :           "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
     192             :           " Async$Method$(::grpc::ClientContext* context, $Response$* "
     193             :           "response, "
     194           2 :           "::grpc::CompletionQueue* cq, void* tag) {\n");
     195           2 :       printer->Indent();
     196             :       printer->Print(*vars,
     197             :                      "return std::unique_ptr< "
     198             :                      "::grpc::ClientAsyncWriterInterface< $Request$>>("
     199           2 :                      "Async$Method$Raw(context, response, cq, tag));\n");
     200           2 :       printer->Outdent();
     201           2 :       printer->Print("}\n");
     202           8 :     } else if (ServerOnlyStreaming(method)) {
     203             :       printer->Print(
     204             :           *vars,
     205             :           "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
     206             :           " $Method$(::grpc::ClientContext* context, const $Request$& request)"
     207           2 :           " {\n");
     208           2 :       printer->Indent();
     209             :       printer->Print(
     210             :           *vars,
     211             :           "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
     212           2 :           "($Method$Raw(context, request));\n");
     213           2 :       printer->Outdent();
     214           2 :       printer->Print("}\n");
     215             :       printer->Print(
     216             :           *vars,
     217             :           "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
     218             :           "Async$Method$("
     219             :           "::grpc::ClientContext* context, const $Request$& request, "
     220           2 :           "::grpc::CompletionQueue* cq, void* tag) {\n");
     221           2 :       printer->Indent();
     222             :       printer->Print(*vars,
     223             :                      "return std::unique_ptr< "
     224             :                      "::grpc::ClientAsyncReaderInterface< $Response$>>("
     225           2 :                      "Async$Method$Raw(context, request, cq, tag));\n");
     226           2 :       printer->Outdent();
     227           2 :       printer->Print("}\n");
     228           6 :     } else if (BidiStreaming(method)) {
     229             :       printer->Print(*vars,
     230             :                      "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
     231             :                      "$Request$, $Response$>> "
     232           6 :                      "$Method$(::grpc::ClientContext* context) {\n");
     233           6 :       printer->Indent();
     234             :       printer->Print(
     235             :           *vars,
     236             :           "return std::unique_ptr< "
     237             :           "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
     238           6 :           "$Method$Raw(context));\n");
     239           6 :       printer->Outdent();
     240           6 :       printer->Print("}\n");
     241             :       printer->Print(
     242             :           *vars,
     243             :           "std::unique_ptr< "
     244             :           "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
     245             :           "Async$Method$(::grpc::ClientContext* context, "
     246           6 :           "::grpc::CompletionQueue* cq, void* tag) {\n");
     247           6 :       printer->Indent();
     248             :       printer->Print(
     249             :           *vars,
     250             :           "return std::unique_ptr< "
     251             :           "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
     252           6 :           "Async$Method$Raw(context, cq, tag));\n");
     253           6 :       printer->Outdent();
     254           6 :       printer->Print("}\n");
     255             :     }
     256             :   } else {
     257          21 :     if (NoStreaming(method)) {
     258             :       printer->Print(
     259             :           *vars,
     260             :           "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
     261             :           "Async$Method$Raw(::grpc::ClientContext* context, "
     262             :           "const $Request$& request, "
     263          11 :           "::grpc::CompletionQueue* cq) = 0;\n");
     264          10 :     } else if (ClientOnlyStreaming(method)) {
     265             :       printer->Print(
     266             :           *vars,
     267             :           "virtual ::grpc::ClientWriterInterface< $Request$>*"
     268             :           " $Method$Raw("
     269           2 :           "::grpc::ClientContext* context, $Response$* response) = 0;\n");
     270             :       printer->Print(*vars,
     271             :                      "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
     272             :                      " Async$Method$Raw(::grpc::ClientContext* context, "
     273             :                      "$Response$* response, "
     274           2 :                      "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
     275           8 :     } else if (ServerOnlyStreaming(method)) {
     276             :       printer->Print(
     277             :           *vars,
     278             :           "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
     279           2 :           "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
     280             :       printer->Print(
     281             :           *vars,
     282             :           "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
     283             :           "Async$Method$Raw("
     284             :           "::grpc::ClientContext* context, const $Request$& request, "
     285           2 :           "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
     286           6 :     } else if (BidiStreaming(method)) {
     287             :       printer->Print(*vars,
     288             :                      "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
     289             :                      "$Response$>* "
     290           6 :                      "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
     291             :       printer->Print(*vars,
     292             :                      "virtual ::grpc::ClientAsyncReaderWriterInterface< "
     293             :                      "$Request$, $Response$>* "
     294             :                      "Async$Method$Raw(::grpc::ClientContext* context, "
     295           6 :                      "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
     296             :     }
     297             :   }
     298          42 : }
     299             : 
     300          42 : void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
     301             :                              const grpc::protobuf::MethodDescriptor *method,
     302             :                              std::map<grpc::string, grpc::string> *vars,
     303             :                              bool is_public) {
     304          42 :   (*vars)["Method"] = method->name();
     305          84 :   (*vars)["Request"] =
     306          42 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     307          84 :   (*vars)["Response"] =
     308          42 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     309          42 :   if (is_public) {
     310          21 :     if (NoStreaming(method)) {
     311             :       printer->Print(
     312             :           *vars,
     313             :           "::grpc::Status $Method$(::grpc::ClientContext* context, "
     314          11 :           "const $Request$& request, $Response$* response) GRPC_OVERRIDE;\n");
     315             :       printer->Print(
     316             :           *vars,
     317             :           "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
     318             :           "Async$Method$(::grpc::ClientContext* context, "
     319             :           "const $Request$& request, "
     320          11 :           "::grpc::CompletionQueue* cq) {\n");
     321          11 :       printer->Indent();
     322             :       printer->Print(*vars,
     323             :                      "return std::unique_ptr< "
     324             :                      "::grpc::ClientAsyncResponseReader< $Response$>>("
     325          11 :                      "Async$Method$Raw(context, request, cq));\n");
     326          11 :       printer->Outdent();
     327          11 :       printer->Print("}\n");
     328          10 :     } else if (ClientOnlyStreaming(method)) {
     329             :       printer->Print(
     330             :           *vars,
     331             :           "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
     332             :           " $Method$("
     333           2 :           "::grpc::ClientContext* context, $Response$* response) {\n");
     334           2 :       printer->Indent();
     335             :       printer->Print(*vars,
     336             :                      "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
     337           2 :                      "($Method$Raw(context, response));\n");
     338           2 :       printer->Outdent();
     339           2 :       printer->Print("}\n");
     340             :       printer->Print(*vars,
     341             :                      "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
     342             :                      " Async$Method$(::grpc::ClientContext* context, "
     343             :                      "$Response$* response, "
     344           2 :                      "::grpc::CompletionQueue* cq, void* tag) {\n");
     345           2 :       printer->Indent();
     346             :       printer->Print(
     347             :           *vars,
     348             :           "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
     349           2 :           "Async$Method$Raw(context, response, cq, tag));\n");
     350           2 :       printer->Outdent();
     351           2 :       printer->Print("}\n");
     352           8 :     } else if (ServerOnlyStreaming(method)) {
     353             :       printer->Print(
     354             :           *vars,
     355             :           "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
     356             :           " $Method$(::grpc::ClientContext* context, const $Request$& request)"
     357           2 :           " {\n");
     358           2 :       printer->Indent();
     359             :       printer->Print(
     360             :           *vars,
     361             :           "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
     362           2 :           "($Method$Raw(context, request));\n");
     363           2 :       printer->Outdent();
     364           2 :       printer->Print("}\n");
     365             :       printer->Print(
     366             :           *vars,
     367             :           "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
     368             :           "Async$Method$("
     369             :           "::grpc::ClientContext* context, const $Request$& request, "
     370           2 :           "::grpc::CompletionQueue* cq, void* tag) {\n");
     371           2 :       printer->Indent();
     372             :       printer->Print(
     373             :           *vars,
     374             :           "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
     375           2 :           "Async$Method$Raw(context, request, cq, tag));\n");
     376           2 :       printer->Outdent();
     377           2 :       printer->Print("}\n");
     378           6 :     } else if (BidiStreaming(method)) {
     379             :       printer->Print(
     380             :           *vars,
     381             :           "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
     382           6 :           " $Method$(::grpc::ClientContext* context) {\n");
     383           6 :       printer->Indent();
     384             :       printer->Print(*vars,
     385             :                      "return std::unique_ptr< "
     386             :                      "::grpc::ClientReaderWriter< $Request$, $Response$>>("
     387           6 :                      "$Method$Raw(context));\n");
     388           6 :       printer->Outdent();
     389           6 :       printer->Print("}\n");
     390             :       printer->Print(*vars,
     391             :                      "std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< "
     392             :                      "$Request$, $Response$>> "
     393             :                      "Async$Method$(::grpc::ClientContext* context, "
     394           6 :                      "::grpc::CompletionQueue* cq, void* tag) {\n");
     395           6 :       printer->Indent();
     396             :       printer->Print(*vars,
     397             :                      "return std::unique_ptr< "
     398             :                      "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
     399           6 :                      "Async$Method$Raw(context, cq, tag));\n");
     400           6 :       printer->Outdent();
     401           6 :       printer->Print("}\n");
     402             :     }
     403             :   } else {
     404          21 :     if (NoStreaming(method)) {
     405             :       printer->Print(*vars,
     406             :                      "::grpc::ClientAsyncResponseReader< $Response$>* "
     407             :                      "Async$Method$Raw(::grpc::ClientContext* context, "
     408             :                      "const $Request$& request, "
     409          11 :                      "::grpc::CompletionQueue* cq) GRPC_OVERRIDE;\n");
     410          10 :     } else if (ClientOnlyStreaming(method)) {
     411             :       printer->Print(*vars,
     412             :                      "::grpc::ClientWriter< $Request$>* $Method$Raw("
     413             :                      "::grpc::ClientContext* context, $Response$* response) "
     414           2 :                      "GRPC_OVERRIDE;\n");
     415             :       printer->Print(
     416             :           *vars,
     417             :           "::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
     418             :           "::grpc::ClientContext* context, $Response$* response, "
     419           2 :           "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
     420           8 :     } else if (ServerOnlyStreaming(method)) {
     421             :       printer->Print(*vars,
     422             :                      "::grpc::ClientReader< $Response$>* $Method$Raw("
     423             :                      "::grpc::ClientContext* context, const $Request$& request)"
     424           2 :                      " GRPC_OVERRIDE;\n");
     425             :       printer->Print(
     426             :           *vars,
     427             :           "::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw("
     428             :           "::grpc::ClientContext* context, const $Request$& request, "
     429           2 :           "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
     430           6 :     } else if (BidiStreaming(method)) {
     431             :       printer->Print(
     432             :           *vars,
     433             :           "::grpc::ClientReaderWriter< $Request$, $Response$>* "
     434           6 :           "$Method$Raw(::grpc::ClientContext* context) GRPC_OVERRIDE;\n");
     435             :       printer->Print(
     436             :           *vars,
     437             :           "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
     438             :           "Async$Method$Raw(::grpc::ClientContext* context, "
     439           6 :           "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
     440             :     }
     441             :   }
     442          42 : }
     443             : 
     444          21 : void PrintHeaderClientMethodData(grpc::protobuf::io::Printer *printer,
     445             :                                  const grpc::protobuf::MethodDescriptor *method,
     446             :                                  std::map<grpc::string, grpc::string> *vars) {
     447          21 :   (*vars)["Method"] = method->name();
     448          21 :   printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
     449          21 : }
     450             : 
     451          21 : void PrintHeaderServerMethodSync(grpc::protobuf::io::Printer *printer,
     452             :                                  const grpc::protobuf::MethodDescriptor *method,
     453             :                                  std::map<grpc::string, grpc::string> *vars) {
     454          21 :   (*vars)["Method"] = method->name();
     455          42 :   (*vars)["Request"] =
     456          21 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     457          42 :   (*vars)["Response"] =
     458          21 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     459          21 :   if (NoStreaming(method)) {
     460             :     printer->Print(*vars,
     461             :                    "virtual ::grpc::Status $Method$("
     462             :                    "::grpc::ServerContext* context, const $Request$* request, "
     463          11 :                    "$Response$* response);\n");
     464          10 :   } else if (ClientOnlyStreaming(method)) {
     465             :     printer->Print(*vars,
     466             :                    "virtual ::grpc::Status $Method$("
     467             :                    "::grpc::ServerContext* context, "
     468             :                    "::grpc::ServerReader< $Request$>* reader, "
     469           2 :                    "$Response$* response);\n");
     470           8 :   } else if (ServerOnlyStreaming(method)) {
     471             :     printer->Print(*vars,
     472             :                    "virtual ::grpc::Status $Method$("
     473             :                    "::grpc::ServerContext* context, const $Request$* request, "
     474           2 :                    "::grpc::ServerWriter< $Response$>* writer);\n");
     475           6 :   } else if (BidiStreaming(method)) {
     476             :     printer->Print(
     477             :         *vars,
     478             :         "virtual ::grpc::Status $Method$("
     479             :         "::grpc::ServerContext* context, "
     480             :         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
     481           6 :         "\n");
     482             :   }
     483          21 : }
     484             : 
     485          21 : void PrintHeaderServerMethodAsync(
     486             :     grpc::protobuf::io::Printer *printer,
     487             :     const grpc::protobuf::MethodDescriptor *method,
     488             :     std::map<grpc::string, grpc::string> *vars) {
     489          21 :   (*vars)["Method"] = method->name();
     490          42 :   (*vars)["Request"] =
     491          21 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     492          42 :   (*vars)["Response"] =
     493          21 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     494          21 :   if (NoStreaming(method)) {
     495             :     printer->Print(
     496             :         *vars,
     497             :         "void Request$Method$("
     498             :         "::grpc::ServerContext* context, $Request$* request, "
     499             :         "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
     500             :         "::grpc::CompletionQueue* new_call_cq, "
     501          11 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
     502          10 :   } else if (ClientOnlyStreaming(method)) {
     503             :     printer->Print(
     504             :         *vars,
     505             :         "void Request$Method$("
     506             :         "::grpc::ServerContext* context, "
     507             :         "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
     508             :         "::grpc::CompletionQueue* new_call_cq, "
     509           2 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
     510           8 :   } else if (ServerOnlyStreaming(method)) {
     511             :     printer->Print(
     512             :         *vars,
     513             :         "void Request$Method$("
     514             :         "::grpc::ServerContext* context, $Request$* request, "
     515             :         "::grpc::ServerAsyncWriter< $Response$>* writer, "
     516             :         "::grpc::CompletionQueue* new_call_cq, "
     517           2 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
     518           6 :   } else if (BidiStreaming(method)) {
     519             :     printer->Print(
     520             :         *vars,
     521             :         "void Request$Method$("
     522             :         "::grpc::ServerContext* context, "
     523             :         "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
     524             :         "::grpc::CompletionQueue* new_call_cq, "
     525           6 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
     526             :   }
     527          21 : }
     528             : 
     529           9 : void PrintHeaderService(grpc::protobuf::io::Printer *printer,
     530             :                         const grpc::protobuf::ServiceDescriptor *service,
     531             :                         std::map<grpc::string, grpc::string> *vars) {
     532           9 :   (*vars)["Service"] = service->name();
     533             : 
     534             :   printer->Print(*vars,
     535             :                  "class $Service$ GRPC_FINAL {\n"
     536           9 :                  " public:\n");
     537           9 :   printer->Indent();
     538             : 
     539             :   // Client side
     540             :   printer->Print(
     541             :       "class StubInterface {\n"
     542           9 :       " public:\n");
     543           9 :   printer->Indent();
     544           9 :   printer->Print("virtual ~StubInterface() {}\n");
     545          30 :   for (int i = 0; i < service->method_count(); ++i) {
     546          21 :     PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, true);
     547             :   }
     548           9 :   printer->Outdent();
     549           9 :   printer->Print("private:\n");
     550           9 :   printer->Indent();
     551          30 :   for (int i = 0; i < service->method_count(); ++i) {
     552          21 :     PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, false);
     553             :   }
     554           9 :   printer->Outdent();
     555           9 :   printer->Print("};\n");
     556             :   printer->Print(
     557             :       "class Stub GRPC_FINAL : public StubInterface"
     558           9 :       " {\n public:\n");
     559           9 :   printer->Indent();
     560           9 :   printer->Print("Stub(const std::shared_ptr< ::grpc::Channel>& channel);\n");
     561          30 :   for (int i = 0; i < service->method_count(); ++i) {
     562          21 :     PrintHeaderClientMethod(printer, service->method(i), vars, true);
     563             :   }
     564           9 :   printer->Outdent();
     565           9 :   printer->Print("\n private:\n");
     566           9 :   printer->Indent();
     567           9 :   printer->Print("std::shared_ptr< ::grpc::Channel> channel_;\n");
     568          30 :   for (int i = 0; i < service->method_count(); ++i) {
     569          21 :     PrintHeaderClientMethod(printer, service->method(i), vars, false);
     570             :   }
     571          30 :   for (int i = 0; i < service->method_count(); ++i) {
     572          21 :     PrintHeaderClientMethodData(printer, service->method(i), vars);
     573             :   }
     574           9 :   printer->Outdent();
     575           9 :   printer->Print("};\n");
     576             :   printer->Print(
     577             :       "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
     578             :       "::grpc::Channel>& channel, "
     579           9 :       "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
     580             : 
     581           9 :   printer->Print("\n");
     582             : 
     583             :   // Server side - Synchronous
     584             :   printer->Print(
     585             :       "class Service : public ::grpc::SynchronousService {\n"
     586           9 :       " public:\n");
     587           9 :   printer->Indent();
     588           9 :   printer->Print("Service() : service_(nullptr) {}\n");
     589           9 :   printer->Print("virtual ~Service();\n");
     590          30 :   for (int i = 0; i < service->method_count(); ++i) {
     591          21 :     PrintHeaderServerMethodSync(printer, service->method(i), vars);
     592             :   }
     593           9 :   printer->Print("::grpc::RpcService* service() GRPC_OVERRIDE GRPC_FINAL;\n");
     594           9 :   printer->Outdent();
     595             :   printer->Print(
     596             :       " private:\n"
     597           9 :       "  ::grpc::RpcService* service_;\n");
     598           9 :   printer->Print("};\n");
     599             : 
     600             :   // Server side - Asynchronous
     601             :   printer->Print(
     602             :       "class AsyncService GRPC_FINAL : public ::grpc::AsynchronousService {\n"
     603           9 :       " public:\n");
     604           9 :   printer->Indent();
     605           9 :   (*vars)["MethodCount"] = as_string(service->method_count());
     606           9 :   printer->Print("explicit AsyncService();\n");
     607           9 :   printer->Print("~AsyncService() {};\n");
     608          30 :   for (int i = 0; i < service->method_count(); ++i) {
     609          21 :     PrintHeaderServerMethodAsync(printer, service->method(i), vars);
     610             :   }
     611           9 :   printer->Outdent();
     612           9 :   printer->Print("};\n");
     613             : 
     614           9 :   printer->Outdent();
     615           9 :   printer->Print("};\n");
     616           9 : }
     617             : 
     618           8 : grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
     619             :                                const Parameters &params) {
     620           8 :   grpc::string output;
     621             :   {
     622             :     // Scope the output stream so it closes and finalizes output to the string.
     623           8 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
     624          16 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
     625          16 :     std::map<grpc::string, grpc::string> vars;
     626             : 
     627           8 :     if (!params.services_namespace.empty()) {
     628           0 :       vars["services_namespace"] = params.services_namespace;
     629           0 :       printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
     630             :     }
     631             : 
     632          17 :     for (int i = 0; i < file->service_count(); ++i) {
     633           9 :       PrintHeaderService(&printer, file->service(i), &vars);
     634           9 :       printer.Print("\n");
     635             :     }
     636             : 
     637           8 :     if (!params.services_namespace.empty()) {
     638           0 :       printer.Print(vars, "}  // namespace $services_namespace$\n\n");
     639           8 :     }
     640             :   }
     641           8 :   return output;
     642             : }
     643             : 
     644           8 : grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
     645             :                                const Parameters &params) {
     646           8 :   grpc::string output;
     647             :   {
     648             :     // Scope the output stream so it closes and finalizes output to the string.
     649           8 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
     650          16 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
     651          16 :     std::map<grpc::string, grpc::string> vars;
     652             : 
     653           8 :     vars["filename"] = file->name();
     654           8 :     vars["filename_identifier"] = FilenameIdentifier(file->name());
     655             : 
     656           8 :     if (!file->package().empty()) {
     657             :       std::vector<grpc::string> parts =
     658           8 :           grpc_generator::tokenize(file->package(), ".");
     659             : 
     660          31 :       for (auto part = parts.rbegin(); part != parts.rend(); part++) {
     661          23 :         vars["part"] = *part;
     662          23 :         printer.Print(vars, "}  // namespace $part$\n");
     663             :       }
     664           8 :       printer.Print(vars, "\n");
     665             :     }
     666             : 
     667           8 :     printer.Print(vars, "\n");
     668          16 :     printer.Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
     669             :   }
     670           8 :   return output;
     671             : }
     672             : 
     673           8 : grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
     674             :                                const Parameters &params) {
     675           8 :   grpc::string output;
     676             :   {
     677             :     // Scope the output stream so it closes and finalizes output to the string.
     678           8 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
     679          16 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
     680          16 :     std::map<grpc::string, grpc::string> vars;
     681             : 
     682           8 :     vars["filename"] = file->name();
     683           8 :     vars["filename_base"] = grpc_generator::StripProto(file->name());
     684             : 
     685           8 :     printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
     686             :     printer.Print(vars,
     687           8 :                   "// If you make any local change, they will be lost.\n");
     688           8 :     printer.Print(vars, "// source: $filename$\n\n");
     689           8 :     printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
     690           8 :     printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
     691          16 :     printer.Print(vars, "\n");
     692             :   }
     693           8 :   return output;
     694             : }
     695             : 
     696           8 : grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
     697             :                                const Parameters &param) {
     698           8 :   grpc::string output;
     699             :   {
     700             :     // Scope the output stream so it closes and finalizes output to the string.
     701           8 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
     702          16 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
     703          16 :     std::map<grpc::string, grpc::string> vars;
     704             : 
     705           8 :     printer.Print(vars, "#include <grpc++/channel.h>\n");
     706           8 :     printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
     707           8 :     printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
     708           8 :     printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
     709           8 :     printer.Print(vars, "#include <grpc++/support/async_unary_call.h>\n");
     710           8 :     printer.Print(vars, "#include <grpc++/support/async_stream.h>\n");
     711           8 :     printer.Print(vars, "#include <grpc++/support/sync_stream.h>\n");
     712             : 
     713           8 :     if (!file->package().empty()) {
     714             :       std::vector<grpc::string> parts =
     715           8 :           grpc_generator::tokenize(file->package(), ".");
     716             : 
     717          31 :       for (auto part = parts.begin(); part != parts.end(); part++) {
     718          23 :         vars["part"] = *part;
     719          23 :         printer.Print(vars, "namespace $part$ {\n");
     720           8 :       }
     721             :     }
     722             : 
     723          16 :     printer.Print(vars, "\n");
     724             :   }
     725           8 :   return output;
     726             : }
     727             : 
     728          21 : void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
     729             :                              const grpc::protobuf::MethodDescriptor *method,
     730             :                              std::map<grpc::string, grpc::string> *vars) {
     731          21 :   (*vars)["Method"] = method->name();
     732          42 :   (*vars)["Request"] =
     733          21 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     734          42 :   (*vars)["Response"] =
     735          21 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     736          21 :   if (NoStreaming(method)) {
     737             :     printer->Print(*vars,
     738             :                    "::grpc::Status $ns$$Service$::Stub::$Method$("
     739             :                    "::grpc::ClientContext* context, "
     740          11 :                    "const $Request$& request, $Response$* response) {\n");
     741             :     printer->Print(*vars,
     742             :                    "  return ::grpc::BlockingUnaryCall(channel_.get(), "
     743             :                    "rpcmethod_$Method$_, "
     744             :                    "context, request, response);\n"
     745          11 :                    "}\n\n");
     746             :     printer->Print(
     747             :         *vars,
     748             :         "::grpc::ClientAsyncResponseReader< $Response$>* "
     749             :         "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
     750             :         "const $Request$& request, "
     751          11 :         "::grpc::CompletionQueue* cq) {\n");
     752             :     printer->Print(*vars,
     753             :                    "  return new "
     754             :                    "::grpc::ClientAsyncResponseReader< $Response$>("
     755             :                    "channel_.get(), cq, "
     756             :                    "rpcmethod_$Method$_, "
     757             :                    "context, request);\n"
     758          11 :                    "}\n\n");
     759          10 :   } else if (ClientOnlyStreaming(method)) {
     760             :     printer->Print(*vars,
     761             :                    "::grpc::ClientWriter< $Request$>* "
     762             :                    "$ns$$Service$::Stub::$Method$Raw("
     763           2 :                    "::grpc::ClientContext* context, $Response$* response) {\n");
     764             :     printer->Print(*vars,
     765             :                    "  return new ::grpc::ClientWriter< $Request$>("
     766             :                    "channel_.get(), "
     767             :                    "rpcmethod_$Method$_, "
     768             :                    "context, response);\n"
     769           2 :                    "}\n\n");
     770             :     printer->Print(*vars,
     771             :                    "::grpc::ClientAsyncWriter< $Request$>* "
     772             :                    "$ns$$Service$::Stub::Async$Method$Raw("
     773             :                    "::grpc::ClientContext* context, $Response$* response, "
     774           2 :                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     775             :     printer->Print(*vars,
     776             :                    "  return new ::grpc::ClientAsyncWriter< $Request$>("
     777             :                    "channel_.get(), cq, "
     778             :                    "rpcmethod_$Method$_, "
     779             :                    "context, response, tag);\n"
     780           2 :                    "}\n\n");
     781           8 :   } else if (ServerOnlyStreaming(method)) {
     782             :     printer->Print(
     783             :         *vars,
     784             :         "::grpc::ClientReader< $Response$>* "
     785             :         "$ns$$Service$::Stub::$Method$Raw("
     786           2 :         "::grpc::ClientContext* context, const $Request$& request) {\n");
     787             :     printer->Print(*vars,
     788             :                    "  return new ::grpc::ClientReader< $Response$>("
     789             :                    "channel_.get(), "
     790             :                    "rpcmethod_$Method$_, "
     791             :                    "context, request);\n"
     792           2 :                    "}\n\n");
     793             :     printer->Print(*vars,
     794             :                    "::grpc::ClientAsyncReader< $Response$>* "
     795             :                    "$ns$$Service$::Stub::Async$Method$Raw("
     796             :                    "::grpc::ClientContext* context, const $Request$& request, "
     797           2 :                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     798             :     printer->Print(*vars,
     799             :                    "  return new ::grpc::ClientAsyncReader< $Response$>("
     800             :                    "channel_.get(), cq, "
     801             :                    "rpcmethod_$Method$_, "
     802             :                    "context, request, tag);\n"
     803           2 :                    "}\n\n");
     804           6 :   } else if (BidiStreaming(method)) {
     805             :     printer->Print(
     806             :         *vars,
     807             :         "::grpc::ClientReaderWriter< $Request$, $Response$>* "
     808           6 :         "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
     809             :     printer->Print(*vars,
     810             :                    "  return new ::grpc::ClientReaderWriter< "
     811             :                    "$Request$, $Response$>("
     812             :                    "channel_.get(), "
     813             :                    "rpcmethod_$Method$_, "
     814             :                    "context);\n"
     815           6 :                    "}\n\n");
     816             :     printer->Print(
     817             :         *vars,
     818             :         "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
     819             :         "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
     820           6 :         "::grpc::CompletionQueue* cq, void* tag) {\n");
     821             :     printer->Print(*vars,
     822             :                    "  return new "
     823             :                    "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
     824             :                    "channel_.get(), cq, "
     825             :                    "rpcmethod_$Method$_, "
     826             :                    "context, tag);\n"
     827           6 :                    "}\n\n");
     828             :   }
     829          21 : }
     830             : 
     831          21 : void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
     832             :                              const grpc::protobuf::MethodDescriptor *method,
     833             :                              std::map<grpc::string, grpc::string> *vars) {
     834          21 :   (*vars)["Method"] = method->name();
     835          42 :   (*vars)["Request"] =
     836          21 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     837          42 :   (*vars)["Response"] =
     838          21 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     839          21 :   if (NoStreaming(method)) {
     840             :     printer->Print(*vars,
     841             :                    "::grpc::Status $ns$$Service$::Service::$Method$("
     842             :                    "::grpc::ServerContext* context, "
     843          11 :                    "const $Request$* request, $Response$* response) {\n");
     844          11 :     printer->Print("  (void) context;\n");
     845          11 :     printer->Print("  (void) request;\n");
     846          11 :     printer->Print("  (void) response;\n");
     847             :     printer->Print(
     848             :         "  return ::grpc::Status("
     849          11 :         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
     850          11 :     printer->Print("}\n\n");
     851          10 :   } else if (ClientOnlyStreaming(method)) {
     852             :     printer->Print(*vars,
     853             :                    "::grpc::Status $ns$$Service$::Service::$Method$("
     854             :                    "::grpc::ServerContext* context, "
     855             :                    "::grpc::ServerReader< $Request$>* reader, "
     856           2 :                    "$Response$* response) {\n");
     857           2 :     printer->Print("  (void) context;\n");
     858           2 :     printer->Print("  (void) reader;\n");
     859           2 :     printer->Print("  (void) response;\n");
     860             :     printer->Print(
     861             :         "  return ::grpc::Status("
     862           2 :         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
     863           2 :     printer->Print("}\n\n");
     864           8 :   } else if (ServerOnlyStreaming(method)) {
     865             :     printer->Print(*vars,
     866             :                    "::grpc::Status $ns$$Service$::Service::$Method$("
     867             :                    "::grpc::ServerContext* context, "
     868             :                    "const $Request$* request, "
     869           2 :                    "::grpc::ServerWriter< $Response$>* writer) {\n");
     870           2 :     printer->Print("  (void) context;\n");
     871           2 :     printer->Print("  (void) request;\n");
     872           2 :     printer->Print("  (void) writer;\n");
     873             :     printer->Print(
     874             :         "  return ::grpc::Status("
     875           2 :         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
     876           2 :     printer->Print("}\n\n");
     877           6 :   } else if (BidiStreaming(method)) {
     878             :     printer->Print(*vars,
     879             :                    "::grpc::Status $ns$$Service$::Service::$Method$("
     880             :                    "::grpc::ServerContext* context, "
     881             :                    "::grpc::ServerReaderWriter< $Response$, $Request$>* "
     882           6 :                    "stream) {\n");
     883           6 :     printer->Print("  (void) context;\n");
     884           6 :     printer->Print("  (void) stream;\n");
     885             :     printer->Print(
     886             :         "  return ::grpc::Status("
     887           6 :         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
     888           6 :     printer->Print("}\n\n");
     889             :   }
     890          21 : }
     891             : 
     892          21 : void PrintSourceServerAsyncMethod(
     893             :     grpc::protobuf::io::Printer *printer,
     894             :     const grpc::protobuf::MethodDescriptor *method,
     895             :     std::map<grpc::string, grpc::string> *vars) {
     896          21 :   (*vars)["Method"] = method->name();
     897          42 :   (*vars)["Request"] =
     898          21 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     899          42 :   (*vars)["Response"] =
     900          21 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     901          21 :   if (NoStreaming(method)) {
     902             :     printer->Print(
     903             :         *vars,
     904             :         "void $ns$$Service$::AsyncService::Request$Method$("
     905             :         "::grpc::ServerContext* context, "
     906             :         "$Request$* request, "
     907             :         "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
     908             :         "::grpc::CompletionQueue* new_call_cq, "
     909          11 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     910             :     printer->Print(*vars,
     911             :                    "  AsynchronousService::RequestAsyncUnary($Idx$, context, "
     912          11 :                    "request, response, new_call_cq, notification_cq, tag);\n");
     913          11 :     printer->Print("}\n\n");
     914          10 :   } else if (ClientOnlyStreaming(method)) {
     915             :     printer->Print(
     916             :         *vars,
     917             :         "void $ns$$Service$::AsyncService::Request$Method$("
     918             :         "::grpc::ServerContext* context, "
     919             :         "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
     920             :         "::grpc::CompletionQueue* new_call_cq, "
     921           2 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     922             :     printer->Print(*vars,
     923             :                    "  AsynchronousService::RequestClientStreaming($Idx$, "
     924           2 :                    "context, reader, new_call_cq, notification_cq, tag);\n");
     925           2 :     printer->Print("}\n\n");
     926           8 :   } else if (ServerOnlyStreaming(method)) {
     927             :     printer->Print(
     928             :         *vars,
     929             :         "void $ns$$Service$::AsyncService::Request$Method$("
     930             :         "::grpc::ServerContext* context, "
     931             :         "$Request$* request, "
     932             :         "::grpc::ServerAsyncWriter< $Response$>* writer, "
     933             :         "::grpc::CompletionQueue* new_call_cq, "
     934           2 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     935             :     printer->Print(
     936             :         *vars,
     937             :         "  AsynchronousService::RequestServerStreaming($Idx$, "
     938           2 :         "context, request, writer, new_call_cq, notification_cq, tag);\n");
     939           2 :     printer->Print("}\n\n");
     940           6 :   } else if (BidiStreaming(method)) {
     941             :     printer->Print(
     942             :         *vars,
     943             :         "void $ns$$Service$::AsyncService::Request$Method$("
     944             :         "::grpc::ServerContext* context, "
     945             :         "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
     946             :         "::grpc::CompletionQueue* new_call_cq, "
     947           6 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     948             :     printer->Print(*vars,
     949             :                    "  AsynchronousService::RequestBidiStreaming($Idx$, "
     950           6 :                    "context, stream, new_call_cq, notification_cq, tag);\n");
     951           6 :     printer->Print("}\n\n");
     952             :   }
     953          21 : }
     954             : 
     955           9 : void PrintSourceService(grpc::protobuf::io::Printer *printer,
     956             :                         const grpc::protobuf::ServiceDescriptor *service,
     957             :                         std::map<grpc::string, grpc::string> *vars) {
     958           9 :   (*vars)["Service"] = service->name();
     959             : 
     960             :   printer->Print(*vars,
     961           9 :                  "static const char* $prefix$$Service$_method_names[] = {\n");
     962          30 :   for (int i = 0; i < service->method_count(); ++i) {
     963          21 :     (*vars)["Method"] = service->method(i)->name();
     964          21 :     printer->Print(*vars, "  \"/$Package$$Service$/$Method$\",\n");
     965             :   }
     966           9 :   printer->Print(*vars, "};\n\n");
     967             : 
     968             :   printer->Print(*vars,
     969             :                  "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
     970             :                  "const std::shared_ptr< ::grpc::Channel>& channel, "
     971             :                  "const ::grpc::StubOptions& options) {\n"
     972             :                  "  std::unique_ptr< $ns$$Service$::Stub> stub(new "
     973             :                  "$ns$$Service$::Stub(channel));\n"
     974             :                  "  return stub;\n"
     975           9 :                  "}\n\n");
     976             :   printer->Print(*vars,
     977             :                  "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
     978           9 :                  "::grpc::Channel>& channel)\n");
     979           9 :   printer->Indent();
     980           9 :   printer->Print(": channel_(channel)");
     981          30 :   for (int i = 0; i < service->method_count(); ++i) {
     982          21 :     const grpc::protobuf::MethodDescriptor *method = service->method(i);
     983          21 :     (*vars)["Method"] = method->name();
     984          21 :     (*vars)["Idx"] = as_string(i);
     985          21 :     if (NoStreaming(method)) {
     986          11 :       (*vars)["StreamingType"] = "NORMAL_RPC";
     987          10 :     } else if (ClientOnlyStreaming(method)) {
     988           2 :       (*vars)["StreamingType"] = "CLIENT_STREAMING";
     989           8 :     } else if (ServerOnlyStreaming(method)) {
     990           2 :       (*vars)["StreamingType"] = "SERVER_STREAMING";
     991             :     } else {
     992           6 :       (*vars)["StreamingType"] = "BIDI_STREAMING";
     993             :     }
     994             :     printer->Print(*vars,
     995             :                    ", rpcmethod_$Method$_("
     996             :                    "$prefix$$Service$_method_names[$Idx$], "
     997             :                    "::grpc::RpcMethod::$StreamingType$, "
     998             :                    "channel"
     999          21 :                    ")\n");
    1000             :   }
    1001           9 :   printer->Print("{}\n\n");
    1002           9 :   printer->Outdent();
    1003             : 
    1004          30 :   for (int i = 0; i < service->method_count(); ++i) {
    1005          21 :     (*vars)["Idx"] = as_string(i);
    1006          21 :     PrintSourceClientMethod(printer, service->method(i), vars);
    1007             :   }
    1008             : 
    1009           9 :   (*vars)["MethodCount"] = as_string(service->method_count());
    1010             :   printer->Print(*vars,
    1011             :                  "$ns$$Service$::AsyncService::AsyncService() : "
    1012             :                  "::grpc::AsynchronousService("
    1013             :                  "$prefix$$Service$_method_names, $MethodCount$) "
    1014           9 :                  "{}\n\n");
    1015             : 
    1016             :   printer->Print(*vars,
    1017             :                  "$ns$$Service$::Service::~Service() {\n"
    1018             :                  "  delete service_;\n"
    1019           9 :                  "}\n\n");
    1020          30 :   for (int i = 0; i < service->method_count(); ++i) {
    1021          21 :     (*vars)["Idx"] = as_string(i);
    1022          21 :     PrintSourceServerMethod(printer, service->method(i), vars);
    1023          21 :     PrintSourceServerAsyncMethod(printer, service->method(i), vars);
    1024             :   }
    1025             :   printer->Print(*vars,
    1026           9 :                  "::grpc::RpcService* $ns$$Service$::Service::service() {\n");
    1027           9 :   printer->Indent();
    1028             :   printer->Print(
    1029             :       "if (service_ != nullptr) {\n"
    1030             :       "  return service_;\n"
    1031           9 :       "}\n");
    1032           9 :   printer->Print("service_ = new ::grpc::RpcService();\n");
    1033          30 :   for (int i = 0; i < service->method_count(); ++i) {
    1034          21 :     const grpc::protobuf::MethodDescriptor *method = service->method(i);
    1035          21 :     (*vars)["Idx"] = as_string(i);
    1036          21 :     (*vars)["Method"] = method->name();
    1037          42 :     (*vars)["Request"] =
    1038          21 :         grpc_cpp_generator::ClassName(method->input_type(), true);
    1039          42 :     (*vars)["Response"] =
    1040          21 :         grpc_cpp_generator::ClassName(method->output_type(), true);
    1041          21 :     if (NoStreaming(method)) {
    1042             :       printer->Print(
    1043             :           *vars,
    1044             :           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
    1045             :           "    $prefix$$Service$_method_names[$Idx$],\n"
    1046             :           "    ::grpc::RpcMethod::NORMAL_RPC,\n"
    1047             :           "    new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
    1048             :           "$Request$, "
    1049             :           "$Response$>(\n"
    1050          11 :           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
    1051          10 :     } else if (ClientOnlyStreaming(method)) {
    1052             :       printer->Print(
    1053             :           *vars,
    1054             :           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
    1055             :           "    $prefix$$Service$_method_names[$Idx$],\n"
    1056             :           "    ::grpc::RpcMethod::CLIENT_STREAMING,\n"
    1057             :           "    new ::grpc::ClientStreamingHandler< "
    1058             :           "$ns$$Service$::Service, $Request$, $Response$>(\n"
    1059           2 :           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
    1060           8 :     } else if (ServerOnlyStreaming(method)) {
    1061             :       printer->Print(
    1062             :           *vars,
    1063             :           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
    1064             :           "    $prefix$$Service$_method_names[$Idx$],\n"
    1065             :           "    ::grpc::RpcMethod::SERVER_STREAMING,\n"
    1066             :           "    new ::grpc::ServerStreamingHandler< "
    1067             :           "$ns$$Service$::Service, $Request$, $Response$>(\n"
    1068           2 :           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
    1069           6 :     } else if (BidiStreaming(method)) {
    1070             :       printer->Print(
    1071             :           *vars,
    1072             :           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
    1073             :           "    $prefix$$Service$_method_names[$Idx$],\n"
    1074             :           "    ::grpc::RpcMethod::BIDI_STREAMING,\n"
    1075             :           "    new ::grpc::BidiStreamingHandler< "
    1076             :           "$ns$$Service$::Service, $Request$, $Response$>(\n"
    1077           6 :           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
    1078             :     }
    1079             :   }
    1080           9 :   printer->Print("return service_;\n");
    1081           9 :   printer->Outdent();
    1082           9 :   printer->Print("}\n\n");
    1083           9 : }
    1084             : 
    1085           8 : grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
    1086             :                                const Parameters &params) {
    1087           8 :   grpc::string output;
    1088             :   {
    1089             :     // Scope the output stream so it closes and finalizes output to the string.
    1090           8 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
    1091          16 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
    1092          16 :     std::map<grpc::string, grpc::string> vars;
    1093             :     // Package string is empty or ends with a dot. It is used to fully qualify
    1094             :     // method names.
    1095           8 :     vars["Package"] = file->package();
    1096           8 :     if (!file->package().empty()) {
    1097           8 :       vars["Package"].append(".");
    1098             :     }
    1099           8 :     if (!params.services_namespace.empty()) {
    1100           0 :       vars["ns"] = params.services_namespace + "::";
    1101           0 :       vars["prefix"] = params.services_namespace;
    1102             :     } else {
    1103           8 :       vars["ns"] = "";
    1104           8 :       vars["prefix"] = "";
    1105             :     }
    1106             : 
    1107          17 :     for (int i = 0; i < file->service_count(); ++i) {
    1108           9 :       PrintSourceService(&printer, file->service(i), &vars);
    1109           9 :       printer.Print("\n");
    1110           8 :     }
    1111             :   }
    1112           8 :   return output;
    1113             : }
    1114             : 
    1115           8 : grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
    1116             :                                const Parameters &params) {
    1117           8 :   grpc::string temp;
    1118             : 
    1119           8 :   if (!file->package().empty()) {
    1120             :     std::vector<grpc::string> parts =
    1121           8 :         grpc_generator::tokenize(file->package(), ".");
    1122             : 
    1123          31 :     for (auto part = parts.begin(); part != parts.end(); part++) {
    1124          23 :       temp.append("}  // namespace ");
    1125          23 :       temp.append(*part);
    1126          23 :       temp.append("\n");
    1127             :     }
    1128           8 :     temp.append("\n");
    1129             :   }
    1130             : 
    1131           8 :   return temp;
    1132             : }
    1133             : 
    1134             : }  // namespace grpc_cpp_generator

Generated by: LCOV version 1.10