LCOV - code coverage report
Current view: top level - compiler - cpp_generator.cc (source / functions) Hit Total Coverage
Test: tmp.CaZ6RjdVn2 Lines: 488 493 99.0 %
Date: 2015-12-10 22:15:08 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         112 : grpc::string as_string(T x) {
      48         112 :   std::ostringstream out;
      49         112 :   out << x;
      50         112 :   return out.str();
      51             : }
      52             : 
      53         253 : bool NoStreaming(const grpc::protobuf::MethodDescriptor *method) {
      54         253 :   return !method->client_streaming() && !method->server_streaming();
      55             : }
      56             : 
      57         121 : bool ClientOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
      58         121 :   return method->client_streaming() && !method->server_streaming();
      59             : }
      60             : 
      61          99 : bool ServerOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
      62          99 :   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          24 : grpc::string FilenameIdentifier(const grpc::string &filename) {
      70          24 :   grpc::string result;
      71         712 :   for (unsigned i = 0; i < filename.size(); i++) {
      72         688 :     char c = filename[i];
      73         688 :     if (isalnum(c)) {
      74         596 :       result.push_back(c);
      75             :     } else {
      76             :       static char hex[] = "0123456789abcdef";
      77          92 :       result.push_back('_');
      78          92 :       result.push_back(hex[(c >> 4) & 0xf]);
      79          92 :       result.push_back(hex[c & 0xf]);
      80             :     }
      81             :   }
      82          24 :   return result;
      83             : }
      84             : }  // namespace
      85             : 
      86          12 : grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
      87             :                                const Parameters &params) {
      88          12 :   grpc::string output;
      89             :   {
      90             :     // Scope the output stream so it closes and finalizes output to the string.
      91          12 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
      92          24 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
      93          24 :     std::map<grpc::string, grpc::string> vars;
      94             : 
      95          12 :     vars["filename"] = file->name();
      96          12 :     vars["filename_identifier"] = FilenameIdentifier(file->name());
      97          12 :     vars["filename_base"] = grpc_generator::StripProto(file->name());
      98             : 
      99          12 :     printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
     100             :     printer.Print(vars,
     101          12 :                   "// If you make any local change, they will be lost.\n");
     102          12 :     printer.Print(vars, "// source: $filename$\n");
     103          12 :     printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
     104          12 :     printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
     105          12 :     printer.Print(vars, "\n");
     106          12 :     printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
     107          24 :     printer.Print(vars, "\n");
     108             :   }
     109          12 :   return output;
     110             : }
     111             : 
     112          12 : 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          12 :       "}  // namespace grpc\n\n";
     131             : 
     132          12 :   if (!file->package().empty()) {
     133             :     std::vector<grpc::string> parts =
     134          12 :         grpc_generator::tokenize(file->package(), ".");
     135             : 
     136          43 :     for (auto part = parts.begin(); part != parts.end(); part++) {
     137          31 :       temp.append("namespace ");
     138          31 :       temp.append(*part);
     139          31 :       temp.append(" {\n");
     140             :     }
     141          12 :     temp.append("\n");
     142             :   }
     143             : 
     144          12 :   return temp;
     145             : }
     146             : 
     147          46 : 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          46 :   (*vars)["Method"] = method->name();
     152          92 :   (*vars)["Request"] =
     153          46 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     154          92 :   (*vars)["Response"] =
     155          46 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     156             : 
     157          46 :   if (is_public) {
     158          23 :     if (NoStreaming(method)) {
     159             :       printer->Print(
     160             :           *vars,
     161             :           "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
     162          12 :           "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          12 :                      "::grpc::CompletionQueue* cq) {\n");
     169          12 :       printer->Indent();
     170             :       printer->Print(*vars,
     171             :                      "return std::unique_ptr< "
     172             :                      "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
     173          12 :                      "Async$Method$Raw(context, request, cq));\n");
     174          12 :       printer->Outdent();
     175          12 :       printer->Print("}\n");
     176          11 :     } 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           9 :     } 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           3 :           " {\n");
     208           3 :       printer->Indent();
     209             :       printer->Print(
     210             :           *vars,
     211             :           "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
     212           3 :           "($Method$Raw(context, request));\n");
     213           3 :       printer->Outdent();
     214           3 :       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           3 :           "::grpc::CompletionQueue* cq, void* tag) {\n");
     221           3 :       printer->Indent();
     222             :       printer->Print(*vars,
     223             :                      "return std::unique_ptr< "
     224             :                      "::grpc::ClientAsyncReaderInterface< $Response$>>("
     225           3 :                      "Async$Method$Raw(context, request, cq, tag));\n");
     226           3 :       printer->Outdent();
     227           3 :       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          23 :     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          12 :           "::grpc::CompletionQueue* cq) = 0;\n");
     264          11 :     } 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           9 :     } else if (ServerOnlyStreaming(method)) {
     276             :       printer->Print(
     277             :           *vars,
     278             :           "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
     279           3 :           "::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           3 :           "::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          46 : }
     299             : 
     300          46 : 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          46 :   (*vars)["Method"] = method->name();
     305          92 :   (*vars)["Request"] =
     306          46 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     307          92 :   (*vars)["Response"] =
     308          46 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     309          46 :   if (is_public) {
     310          23 :     if (NoStreaming(method)) {
     311             :       printer->Print(
     312             :           *vars,
     313             :           "::grpc::Status $Method$(::grpc::ClientContext* context, "
     314          12 :           "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          12 :           "::grpc::CompletionQueue* cq) {\n");
     321          12 :       printer->Indent();
     322             :       printer->Print(*vars,
     323             :                      "return std::unique_ptr< "
     324             :                      "::grpc::ClientAsyncResponseReader< $Response$>>("
     325          12 :                      "Async$Method$Raw(context, request, cq));\n");
     326          12 :       printer->Outdent();
     327          12 :       printer->Print("}\n");
     328          11 :     } 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           9 :     } 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           3 :           " {\n");
     358           3 :       printer->Indent();
     359             :       printer->Print(
     360             :           *vars,
     361             :           "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
     362           3 :           "($Method$Raw(context, request));\n");
     363           3 :       printer->Outdent();
     364           3 :       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           3 :           "::grpc::CompletionQueue* cq, void* tag) {\n");
     371           3 :       printer->Indent();
     372             :       printer->Print(
     373             :           *vars,
     374             :           "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
     375           3 :           "Async$Method$Raw(context, request, cq, tag));\n");
     376           3 :       printer->Outdent();
     377           3 :       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          23 :     if (NoStreaming(method)) {
     405             :       printer->Print(*vars,
     406             :                      "::grpc::ClientAsyncResponseReader< $Response$>* "
     407             :                      "Async$Method$Raw(::grpc::ClientContext* context, "
     408             :                      "const $Request$& request, "
     409          12 :                      "::grpc::CompletionQueue* cq) GRPC_OVERRIDE;\n");
     410          11 :     } 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           9 :     } else if (ServerOnlyStreaming(method)) {
     421             :       printer->Print(*vars,
     422             :                      "::grpc::ClientReader< $Response$>* $Method$Raw("
     423             :                      "::grpc::ClientContext* context, const $Request$& request)"
     424           3 :                      " GRPC_OVERRIDE;\n");
     425             :       printer->Print(
     426             :           *vars,
     427             :           "::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw("
     428             :           "::grpc::ClientContext* context, const $Request$& request, "
     429           3 :           "::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          46 : }
     443             : 
     444          23 : void PrintHeaderClientMethodData(grpc::protobuf::io::Printer *printer,
     445             :                                  const grpc::protobuf::MethodDescriptor *method,
     446             :                                  std::map<grpc::string, grpc::string> *vars) {
     447          23 :   (*vars)["Method"] = method->name();
     448          23 :   printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
     449          23 : }
     450             : 
     451          23 : void PrintHeaderServerMethodSync(grpc::protobuf::io::Printer *printer,
     452             :                                  const grpc::protobuf::MethodDescriptor *method,
     453             :                                  std::map<grpc::string, grpc::string> *vars) {
     454          23 :   (*vars)["Method"] = method->name();
     455          46 :   (*vars)["Request"] =
     456          23 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     457          46 :   (*vars)["Response"] =
     458          23 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     459          23 :   if (NoStreaming(method)) {
     460             :     printer->Print(*vars,
     461             :                    "virtual ::grpc::Status $Method$("
     462             :                    "::grpc::ServerContext* context, const $Request$* request, "
     463          12 :                    "$Response$* response);\n");
     464          11 :   } 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           9 :   } else if (ServerOnlyStreaming(method)) {
     471             :     printer->Print(*vars,
     472             :                    "virtual ::grpc::Status $Method$("
     473             :                    "::grpc::ServerContext* context, const $Request$* request, "
     474           3 :                    "::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          23 : }
     484             : 
     485          23 : void PrintHeaderServerMethodAsync(
     486             :     grpc::protobuf::io::Printer *printer,
     487             :     const grpc::protobuf::MethodDescriptor *method,
     488             :     std::map<grpc::string, grpc::string> *vars) {
     489          23 :   (*vars)["Method"] = method->name();
     490          46 :   (*vars)["Request"] =
     491          23 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     492          46 :   (*vars)["Response"] =
     493          23 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     494          23 :   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          12 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
     502          11 :   } 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           9 :   } 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           3 :         "::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          23 : }
     528             : 
     529          10 : void PrintHeaderService(grpc::protobuf::io::Printer *printer,
     530             :                         const grpc::protobuf::ServiceDescriptor *service,
     531             :                         std::map<grpc::string, grpc::string> *vars) {
     532          10 :   (*vars)["Service"] = service->name();
     533             : 
     534             :   printer->Print(*vars,
     535             :                  "class $Service$ GRPC_FINAL {\n"
     536          10 :                  " public:\n");
     537          10 :   printer->Indent();
     538             : 
     539             :   // Client side
     540             :   printer->Print(
     541             :       "class StubInterface {\n"
     542          10 :       " public:\n");
     543          10 :   printer->Indent();
     544          10 :   printer->Print("virtual ~StubInterface() {}\n");
     545          33 :   for (int i = 0; i < service->method_count(); ++i) {
     546          23 :     PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, true);
     547             :   }
     548          10 :   printer->Outdent();
     549          10 :   printer->Print("private:\n");
     550          10 :   printer->Indent();
     551          33 :   for (int i = 0; i < service->method_count(); ++i) {
     552          23 :     PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, false);
     553             :   }
     554          10 :   printer->Outdent();
     555          10 :   printer->Print("};\n");
     556             :   printer->Print(
     557             :       "class Stub GRPC_FINAL : public StubInterface"
     558          10 :       " {\n public:\n");
     559          10 :   printer->Indent();
     560          10 :   printer->Print("Stub(const std::shared_ptr< ::grpc::Channel>& channel);\n");
     561          33 :   for (int i = 0; i < service->method_count(); ++i) {
     562          23 :     PrintHeaderClientMethod(printer, service->method(i), vars, true);
     563             :   }
     564          10 :   printer->Outdent();
     565          10 :   printer->Print("\n private:\n");
     566          10 :   printer->Indent();
     567          10 :   printer->Print("std::shared_ptr< ::grpc::Channel> channel_;\n");
     568          33 :   for (int i = 0; i < service->method_count(); ++i) {
     569          23 :     PrintHeaderClientMethod(printer, service->method(i), vars, false);
     570             :   }
     571          33 :   for (int i = 0; i < service->method_count(); ++i) {
     572          23 :     PrintHeaderClientMethodData(printer, service->method(i), vars);
     573             :   }
     574          10 :   printer->Outdent();
     575          10 :   printer->Print("};\n");
     576             :   printer->Print(
     577             :       "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
     578             :       "::grpc::Channel>& channel, "
     579          10 :       "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
     580             : 
     581          10 :   printer->Print("\n");
     582             : 
     583             :   // Server side - Synchronous
     584             :   printer->Print(
     585             :       "class Service : public ::grpc::SynchronousService {\n"
     586          10 :       " public:\n");
     587          10 :   printer->Indent();
     588          10 :   printer->Print("Service();\n");
     589          10 :   printer->Print("virtual ~Service();\n");
     590          33 :   for (int i = 0; i < service->method_count(); ++i) {
     591          23 :     PrintHeaderServerMethodSync(printer, service->method(i), vars);
     592             :   }
     593          10 :   printer->Print("::grpc::RpcService* service() GRPC_OVERRIDE GRPC_FINAL;\n");
     594          10 :   printer->Outdent();
     595             :   printer->Print(
     596             :       " private:\n"
     597          10 :       "  std::unique_ptr< ::grpc::RpcService> service_;\n");
     598          10 :   printer->Print("};\n");
     599             : 
     600             :   // Server side - Asynchronous
     601             :   printer->Print(
     602             :       "class AsyncService GRPC_FINAL : public ::grpc::AsynchronousService {\n"
     603          10 :       " public:\n");
     604          10 :   printer->Indent();
     605          10 :   (*vars)["MethodCount"] = as_string(service->method_count());
     606          10 :   printer->Print("explicit AsyncService();\n");
     607          10 :   printer->Print("~AsyncService() {};\n");
     608          33 :   for (int i = 0; i < service->method_count(); ++i) {
     609          23 :     PrintHeaderServerMethodAsync(printer, service->method(i), vars);
     610             :   }
     611          10 :   printer->Outdent();
     612          10 :   printer->Print("};\n");
     613             : 
     614          10 :   printer->Outdent();
     615          10 :   printer->Print("};\n");
     616          10 : }
     617             : 
     618          12 : grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
     619             :                                const Parameters &params) {
     620          12 :   grpc::string output;
     621             :   {
     622             :     // Scope the output stream so it closes and finalizes output to the string.
     623          12 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
     624          24 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
     625          24 :     std::map<grpc::string, grpc::string> vars;
     626             : 
     627          12 :     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          22 :     for (int i = 0; i < file->service_count(); ++i) {
     633          10 :       PrintHeaderService(&printer, file->service(i), &vars);
     634          10 :       printer.Print("\n");
     635             :     }
     636             : 
     637          12 :     if (!params.services_namespace.empty()) {
     638           0 :       printer.Print(vars, "}  // namespace $services_namespace$\n\n");
     639          12 :     }
     640             :   }
     641          12 :   return output;
     642             : }
     643             : 
     644          12 : grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
     645             :                                const Parameters &params) {
     646          12 :   grpc::string output;
     647             :   {
     648             :     // Scope the output stream so it closes and finalizes output to the string.
     649          12 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
     650          24 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
     651          24 :     std::map<grpc::string, grpc::string> vars;
     652             : 
     653          12 :     vars["filename"] = file->name();
     654          12 :     vars["filename_identifier"] = FilenameIdentifier(file->name());
     655             : 
     656          12 :     if (!file->package().empty()) {
     657             :       std::vector<grpc::string> parts =
     658          12 :           grpc_generator::tokenize(file->package(), ".");
     659             : 
     660          43 :       for (auto part = parts.rbegin(); part != parts.rend(); part++) {
     661          31 :         vars["part"] = *part;
     662          31 :         printer.Print(vars, "}  // namespace $part$\n");
     663             :       }
     664          12 :       printer.Print(vars, "\n");
     665             :     }
     666             : 
     667          12 :     printer.Print(vars, "\n");
     668          24 :     printer.Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
     669             :   }
     670          12 :   return output;
     671             : }
     672             : 
     673          12 : grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
     674             :                                const Parameters &params) {
     675          12 :   grpc::string output;
     676             :   {
     677             :     // Scope the output stream so it closes and finalizes output to the string.
     678          12 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
     679          24 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
     680          24 :     std::map<grpc::string, grpc::string> vars;
     681             : 
     682          12 :     vars["filename"] = file->name();
     683          12 :     vars["filename_base"] = grpc_generator::StripProto(file->name());
     684             : 
     685          12 :     printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
     686             :     printer.Print(vars,
     687          12 :                   "// If you make any local change, they will be lost.\n");
     688          12 :     printer.Print(vars, "// source: $filename$\n\n");
     689          12 :     printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
     690          12 :     printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
     691          24 :     printer.Print(vars, "\n");
     692             :   }
     693          12 :   return output;
     694             : }
     695             : 
     696          12 : grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
     697             :                                const Parameters &param) {
     698          12 :   grpc::string output;
     699             :   {
     700             :     // Scope the output stream so it closes and finalizes output to the string.
     701          12 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
     702          24 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
     703          24 :     std::map<grpc::string, grpc::string> vars;
     704             : 
     705          12 :     printer.Print(vars, "#include <grpc++/channel.h>\n");
     706          12 :     printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
     707          12 :     printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
     708          12 :     printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
     709          12 :     printer.Print(vars, "#include <grpc++/support/async_unary_call.h>\n");
     710          12 :     printer.Print(vars, "#include <grpc++/support/async_stream.h>\n");
     711          12 :     printer.Print(vars, "#include <grpc++/support/sync_stream.h>\n");
     712             : 
     713          12 :     if (!file->package().empty()) {
     714             :       std::vector<grpc::string> parts =
     715          12 :           grpc_generator::tokenize(file->package(), ".");
     716             : 
     717          43 :       for (auto part = parts.begin(); part != parts.end(); part++) {
     718          31 :         vars["part"] = *part;
     719          31 :         printer.Print(vars, "namespace $part$ {\n");
     720          12 :       }
     721             :     }
     722             : 
     723          24 :     printer.Print(vars, "\n");
     724             :   }
     725          12 :   return output;
     726             : }
     727             : 
     728          23 : void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
     729             :                              const grpc::protobuf::MethodDescriptor *method,
     730             :                              std::map<grpc::string, grpc::string> *vars) {
     731          23 :   (*vars)["Method"] = method->name();
     732          46 :   (*vars)["Request"] =
     733          23 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     734          46 :   (*vars)["Response"] =
     735          23 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     736          23 :   if (NoStreaming(method)) {
     737             :     printer->Print(*vars,
     738             :                    "::grpc::Status $ns$$Service$::Stub::$Method$("
     739             :                    "::grpc::ClientContext* context, "
     740          12 :                    "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          12 :                    "}\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          12 :         "::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          12 :                    "}\n\n");
     759          11 :   } 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           9 :   } else if (ServerOnlyStreaming(method)) {
     782             :     printer->Print(
     783             :         *vars,
     784             :         "::grpc::ClientReader< $Response$>* "
     785             :         "$ns$$Service$::Stub::$Method$Raw("
     786           3 :         "::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           3 :                    "}\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           3 :                    "::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           3 :                    "}\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          23 : }
     830             : 
     831          23 : void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
     832             :                              const grpc::protobuf::MethodDescriptor *method,
     833             :                              std::map<grpc::string, grpc::string> *vars) {
     834          23 :   (*vars)["Method"] = method->name();
     835          46 :   (*vars)["Request"] =
     836          23 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     837          46 :   (*vars)["Response"] =
     838          23 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     839          23 :   if (NoStreaming(method)) {
     840             :     printer->Print(*vars,
     841             :                    "::grpc::Status $ns$$Service$::Service::$Method$("
     842             :                    "::grpc::ServerContext* context, "
     843          12 :                    "const $Request$* request, $Response$* response) {\n");
     844          12 :     printer->Print("  (void) context;\n");
     845          12 :     printer->Print("  (void) request;\n");
     846          12 :     printer->Print("  (void) response;\n");
     847             :     printer->Print(
     848             :         "  return ::grpc::Status("
     849          12 :         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
     850          12 :     printer->Print("}\n\n");
     851          11 :   } 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           9 :   } else if (ServerOnlyStreaming(method)) {
     865             :     printer->Print(*vars,
     866             :                    "::grpc::Status $ns$$Service$::Service::$Method$("
     867             :                    "::grpc::ServerContext* context, "
     868             :                    "const $Request$* request, "
     869           3 :                    "::grpc::ServerWriter< $Response$>* writer) {\n");
     870           3 :     printer->Print("  (void) context;\n");
     871           3 :     printer->Print("  (void) request;\n");
     872           3 :     printer->Print("  (void) writer;\n");
     873             :     printer->Print(
     874             :         "  return ::grpc::Status("
     875           3 :         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
     876           3 :     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          23 : }
     891             : 
     892          23 : void PrintSourceServerAsyncMethod(
     893             :     grpc::protobuf::io::Printer *printer,
     894             :     const grpc::protobuf::MethodDescriptor *method,
     895             :     std::map<grpc::string, grpc::string> *vars) {
     896          23 :   (*vars)["Method"] = method->name();
     897          46 :   (*vars)["Request"] =
     898          23 :       grpc_cpp_generator::ClassName(method->input_type(), true);
     899          46 :   (*vars)["Response"] =
     900          23 :       grpc_cpp_generator::ClassName(method->output_type(), true);
     901          23 :   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          12 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     910             :     printer->Print(*vars,
     911             :                    "  AsynchronousService::RequestAsyncUnary($Idx$, context, "
     912          12 :                    "request, response, new_call_cq, notification_cq, tag);\n");
     913          12 :     printer->Print("}\n\n");
     914          11 :   } 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           9 :   } 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           3 :         "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
     935             :     printer->Print(
     936             :         *vars,
     937             :         "  AsynchronousService::RequestServerStreaming($Idx$, "
     938           3 :         "context, request, writer, new_call_cq, notification_cq, tag);\n");
     939           3 :     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          23 : }
     954             : 
     955          10 : void PrintSourceService(grpc::protobuf::io::Printer *printer,
     956             :                         const grpc::protobuf::ServiceDescriptor *service,
     957             :                         std::map<grpc::string, grpc::string> *vars) {
     958          10 :   (*vars)["Service"] = service->name();
     959             : 
     960             :   printer->Print(*vars,
     961          10 :                  "static const char* $prefix$$Service$_method_names[] = {\n");
     962          33 :   for (int i = 0; i < service->method_count(); ++i) {
     963          23 :     (*vars)["Method"] = service->method(i)->name();
     964          23 :     printer->Print(*vars, "  \"/$Package$$Service$/$Method$\",\n");
     965             :   }
     966          10 :   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          10 :                  "}\n\n");
     976             :   printer->Print(*vars,
     977             :                  "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
     978          10 :                  "::grpc::Channel>& channel)\n");
     979          10 :   printer->Indent();
     980          10 :   printer->Print(": channel_(channel)");
     981          33 :   for (int i = 0; i < service->method_count(); ++i) {
     982          23 :     const grpc::protobuf::MethodDescriptor *method = service->method(i);
     983          23 :     (*vars)["Method"] = method->name();
     984          23 :     (*vars)["Idx"] = as_string(i);
     985          23 :     if (NoStreaming(method)) {
     986          12 :       (*vars)["StreamingType"] = "NORMAL_RPC";
     987          11 :     } else if (ClientOnlyStreaming(method)) {
     988           2 :       (*vars)["StreamingType"] = "CLIENT_STREAMING";
     989           9 :     } else if (ServerOnlyStreaming(method)) {
     990           3 :       (*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          23 :                    ")\n");
    1000             :   }
    1001          10 :   printer->Print("{}\n\n");
    1002          10 :   printer->Outdent();
    1003             : 
    1004          33 :   for (int i = 0; i < service->method_count(); ++i) {
    1005          23 :     (*vars)["Idx"] = as_string(i);
    1006          23 :     PrintSourceClientMethod(printer, service->method(i), vars);
    1007             :   }
    1008             : 
    1009          10 :   (*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          10 :                  "{}\n\n");
    1015             : 
    1016             :   printer->Print(*vars,
    1017             :                  "$ns$$Service$::Service::Service() {\n"
    1018          10 :                  "}\n\n");
    1019             :   printer->Print(*vars,
    1020             :                  "$ns$$Service$::Service::~Service() {\n"
    1021          10 :                  "}\n\n");
    1022          33 :   for (int i = 0; i < service->method_count(); ++i) {
    1023          23 :     (*vars)["Idx"] = as_string(i);
    1024          23 :     PrintSourceServerMethod(printer, service->method(i), vars);
    1025          23 :     PrintSourceServerAsyncMethod(printer, service->method(i), vars);
    1026             :   }
    1027             :   printer->Print(*vars,
    1028          10 :                  "::grpc::RpcService* $ns$$Service$::Service::service() {\n");
    1029          10 :   printer->Indent();
    1030             :   printer->Print(
    1031             :       "if (service_) {\n"
    1032             :       "  return service_.get();\n"
    1033          10 :       "}\n");
    1034          10 :   printer->Print("service_ = std::unique_ptr< ::grpc::RpcService>(new ::grpc::RpcService());\n");
    1035          33 :   for (int i = 0; i < service->method_count(); ++i) {
    1036          23 :     const grpc::protobuf::MethodDescriptor *method = service->method(i);
    1037          23 :     (*vars)["Idx"] = as_string(i);
    1038          23 :     (*vars)["Method"] = method->name();
    1039          46 :     (*vars)["Request"] =
    1040          23 :         grpc_cpp_generator::ClassName(method->input_type(), true);
    1041          46 :     (*vars)["Response"] =
    1042          23 :         grpc_cpp_generator::ClassName(method->output_type(), true);
    1043          23 :     if (NoStreaming(method)) {
    1044             :       printer->Print(
    1045             :           *vars,
    1046             :           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
    1047             :           "    $prefix$$Service$_method_names[$Idx$],\n"
    1048             :           "    ::grpc::RpcMethod::NORMAL_RPC,\n"
    1049             :           "    new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
    1050             :           "$Request$, "
    1051             :           "$Response$>(\n"
    1052          12 :           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
    1053          11 :     } else if (ClientOnlyStreaming(method)) {
    1054             :       printer->Print(
    1055             :           *vars,
    1056             :           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
    1057             :           "    $prefix$$Service$_method_names[$Idx$],\n"
    1058             :           "    ::grpc::RpcMethod::CLIENT_STREAMING,\n"
    1059             :           "    new ::grpc::ClientStreamingHandler< "
    1060             :           "$ns$$Service$::Service, $Request$, $Response$>(\n"
    1061           2 :           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
    1062           9 :     } else if (ServerOnlyStreaming(method)) {
    1063             :       printer->Print(
    1064             :           *vars,
    1065             :           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
    1066             :           "    $prefix$$Service$_method_names[$Idx$],\n"
    1067             :           "    ::grpc::RpcMethod::SERVER_STREAMING,\n"
    1068             :           "    new ::grpc::ServerStreamingHandler< "
    1069             :           "$ns$$Service$::Service, $Request$, $Response$>(\n"
    1070           3 :           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
    1071           6 :     } else if (BidiStreaming(method)) {
    1072             :       printer->Print(
    1073             :           *vars,
    1074             :           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
    1075             :           "    $prefix$$Service$_method_names[$Idx$],\n"
    1076             :           "    ::grpc::RpcMethod::BIDI_STREAMING,\n"
    1077             :           "    new ::grpc::BidiStreamingHandler< "
    1078             :           "$ns$$Service$::Service, $Request$, $Response$>(\n"
    1079           6 :           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
    1080             :     }
    1081             :   }
    1082          10 :   printer->Print("return service_.get();\n");
    1083          10 :   printer->Outdent();
    1084          10 :   printer->Print("}\n\n");
    1085          10 : }
    1086             : 
    1087          12 : grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
    1088             :                                const Parameters &params) {
    1089          12 :   grpc::string output;
    1090             :   {
    1091             :     // Scope the output stream so it closes and finalizes output to the string.
    1092          12 :     grpc::protobuf::io::StringOutputStream output_stream(&output);
    1093          24 :     grpc::protobuf::io::Printer printer(&output_stream, '$');
    1094          24 :     std::map<grpc::string, grpc::string> vars;
    1095             :     // Package string is empty or ends with a dot. It is used to fully qualify
    1096             :     // method names.
    1097          12 :     vars["Package"] = file->package();
    1098          12 :     if (!file->package().empty()) {
    1099          12 :       vars["Package"].append(".");
    1100             :     }
    1101          12 :     if (!params.services_namespace.empty()) {
    1102           0 :       vars["ns"] = params.services_namespace + "::";
    1103           0 :       vars["prefix"] = params.services_namespace;
    1104             :     } else {
    1105          12 :       vars["ns"] = "";
    1106          12 :       vars["prefix"] = "";
    1107             :     }
    1108             : 
    1109          22 :     for (int i = 0; i < file->service_count(); ++i) {
    1110          10 :       PrintSourceService(&printer, file->service(i), &vars);
    1111          10 :       printer.Print("\n");
    1112          12 :     }
    1113             :   }
    1114          12 :   return output;
    1115             : }
    1116             : 
    1117          12 : grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
    1118             :                                const Parameters &params) {
    1119          12 :   grpc::string temp;
    1120             : 
    1121          12 :   if (!file->package().empty()) {
    1122             :     std::vector<grpc::string> parts =
    1123          12 :         grpc_generator::tokenize(file->package(), ".");
    1124             : 
    1125          43 :     for (auto part = parts.begin(); part != parts.end(); part++) {
    1126          31 :       temp.append("}  // namespace ");
    1127          31 :       temp.append(*part);
    1128          31 :       temp.append("\n");
    1129             :     }
    1130          12 :     temp.append("\n");
    1131             :   }
    1132             : 
    1133          12 :   return temp;
    1134             : }
    1135             : 
    1136             : }  // namespace grpc_cpp_generator

Generated by: LCOV version 1.11