LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/cpp - cpp_service.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 97 98 99.0 %
Date: 2015-10-10 Functions: 12 12 100.0 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // https://developers.google.com/protocol-buffers/
       4             : //
       5             : // Redistribution and use in source and binary forms, with or without
       6             : // modification, are permitted provided that the following conditions are
       7             : // met:
       8             : //
       9             : //     * Redistributions of source code must retain the above copyright
      10             : // notice, this list of conditions and the following disclaimer.
      11             : //     * Redistributions in binary form must reproduce the above
      12             : // copyright notice, this list of conditions and the following disclaimer
      13             : // in the documentation and/or other materials provided with the
      14             : // distribution.
      15             : //     * Neither the name of Google Inc. nor the names of its
      16             : // contributors may be used to endorse or promote products derived from
      17             : // this software without specific prior written permission.
      18             : //
      19             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      20             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      21             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      22             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      23             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      24             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      25             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      29             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             : 
      31             : // Author: kenton@google.com (Kenton Varda)
      32             : //  Based on original Protocol Buffers design by
      33             : //  Sanjay Ghemawat, Jeff Dean, and others.
      34             : 
      35             : #include <google/protobuf/compiler/cpp/cpp_service.h>
      36             : #include <google/protobuf/compiler/cpp/cpp_helpers.h>
      37             : #include <google/protobuf/io/printer.h>
      38             : #include <google/protobuf/stubs/strutil.h>
      39             : 
      40             : namespace google {
      41             : namespace protobuf {
      42             : namespace compiler {
      43             : namespace cpp {
      44             : 
      45          21 : ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
      46             :                                    const Options& options)
      47          21 :   : descriptor_(descriptor) {
      48          63 :   vars_["classname"] = descriptor_->name();
      49          63 :   vars_["full_name"] = descriptor_->full_name();
      50          42 :   if (options.dllexport_decl.empty()) {
      51          42 :     vars_["dllexport"] = "";
      52             :   } else {
      53           0 :     vars_["dllexport"] = options.dllexport_decl + " ";
      54             :   }
      55          21 : }
      56             : 
      57          42 : ServiceGenerator::~ServiceGenerator() {}
      58             : 
      59           4 : void ServiceGenerator::GenerateDeclarations(io::Printer* printer) {
      60             :   // Forward-declare the stub type.
      61             :   printer->Print(vars_,
      62             :     "class $classname$_Stub;\n"
      63           4 :     "\n");
      64             : 
      65           4 :   GenerateInterface(printer);
      66           4 :   GenerateStubDefinition(printer);
      67           4 : }
      68             : 
      69           4 : void ServiceGenerator::GenerateInterface(io::Printer* printer) {
      70             :   printer->Print(vars_,
      71             :     "class $dllexport$$classname$ : public ::google::protobuf::Service {\n"
      72             :     " protected:\n"
      73             :     "  // This class should be treated as an abstract interface.\n"
      74             :     "  inline $classname$() {};\n"
      75             :     " public:\n"
      76           4 :     "  virtual ~$classname$();\n");
      77           4 :   printer->Indent();
      78             : 
      79             :   printer->Print(vars_,
      80             :     "\n"
      81             :     "typedef $classname$_Stub Stub;\n"
      82             :     "\n"
      83             :     "static const ::google::protobuf::ServiceDescriptor* descriptor();\n"
      84           4 :     "\n");
      85             : 
      86           4 :   GenerateMethodSignatures(VIRTUAL, printer);
      87             : 
      88             :   printer->Print(
      89             :     "\n"
      90             :     "// implements Service ----------------------------------------------\n"
      91             :     "\n"
      92             :     "const ::google::protobuf::ServiceDescriptor* GetDescriptor();\n"
      93             :     "void CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
      94             :     "                ::google::protobuf::RpcController* controller,\n"
      95             :     "                const ::google::protobuf::Message* request,\n"
      96             :     "                ::google::protobuf::Message* response,\n"
      97             :     "                ::google::protobuf::Closure* done);\n"
      98             :     "const ::google::protobuf::Message& GetRequestPrototype(\n"
      99             :     "  const ::google::protobuf::MethodDescriptor* method) const;\n"
     100             :     "const ::google::protobuf::Message& GetResponsePrototype(\n"
     101           4 :     "  const ::google::protobuf::MethodDescriptor* method) const;\n");
     102             : 
     103           4 :   printer->Outdent();
     104             :   printer->Print(vars_,
     105             :     "\n"
     106             :     " private:\n"
     107             :     "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
     108             :     "};\n"
     109           4 :     "\n");
     110           4 : }
     111             : 
     112           4 : void ServiceGenerator::GenerateStubDefinition(io::Printer* printer) {
     113             :   printer->Print(vars_,
     114             :     "class $dllexport$$classname$_Stub : public $classname$ {\n"
     115           4 :     " public:\n");
     116             : 
     117           4 :   printer->Indent();
     118             : 
     119             :   printer->Print(vars_,
     120             :     "$classname$_Stub(::google::protobuf::RpcChannel* channel);\n"
     121             :     "$classname$_Stub(::google::protobuf::RpcChannel* channel,\n"
     122             :     "                 ::google::protobuf::Service::ChannelOwnership ownership);\n"
     123             :     "~$classname$_Stub();\n"
     124             :     "\n"
     125             :     "inline ::google::protobuf::RpcChannel* channel() { return channel_; }\n"
     126             :     "\n"
     127             :     "// implements $classname$ ------------------------------------------\n"
     128           4 :     "\n");
     129             : 
     130           4 :   GenerateMethodSignatures(NON_VIRTUAL, printer);
     131             : 
     132           4 :   printer->Outdent();
     133             :   printer->Print(vars_,
     134             :     " private:\n"
     135             :     "  ::google::protobuf::RpcChannel* channel_;\n"
     136             :     "  bool owns_channel_;\n"
     137             :     "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n"
     138             :     "};\n"
     139           4 :     "\n");
     140           4 : }
     141             : 
     142           8 : void ServiceGenerator::GenerateMethodSignatures(
     143             :     VirtualOrNon virtual_or_non, io::Printer* printer) {
     144          36 :   for (int i = 0; i < descriptor_->method_count(); i++) {
     145          68 :     const MethodDescriptor* method = descriptor_->method(i);
     146             :     map<string, string> sub_vars;
     147          20 :     sub_vars["name"] = method->name();
     148          30 :     sub_vars["input_type"] = ClassName(method->input_type(), true);
     149          30 :     sub_vars["output_type"] = ClassName(method->output_type(), true);
     150          20 :     sub_vars["virtual"] = virtual_or_non == VIRTUAL ? "virtual " : "";
     151             : 
     152             :     printer->Print(sub_vars,
     153             :       "$virtual$void $name$(::google::protobuf::RpcController* controller,\n"
     154             :       "                     const $input_type$* request,\n"
     155             :       "                     $output_type$* response,\n"
     156          10 :       "                     ::google::protobuf::Closure* done);\n");
     157             :   }
     158           8 : }
     159             : 
     160             : // ===================================================================
     161             : 
     162           4 : void ServiceGenerator::GenerateDescriptorInitializer(
     163             :     io::Printer* printer, int index) {
     164             :   map<string, string> vars;
     165           8 :   vars["classname"] = descriptor_->name();
     166          12 :   vars["index"] = SimpleItoa(index);
     167             : 
     168             :   printer->Print(vars,
     169           4 :     "$classname$_descriptor_ = file->service($index$);\n");
     170           4 : }
     171             : 
     172             : // ===================================================================
     173             : 
     174           4 : void ServiceGenerator::GenerateImplementation(io::Printer* printer) {
     175             :   printer->Print(vars_,
     176             :     "$classname$::~$classname$() {}\n"
     177             :     "\n"
     178             :     "const ::google::protobuf::ServiceDescriptor* $classname$::descriptor() {\n"
     179             :     "  protobuf_AssignDescriptorsOnce();\n"
     180             :     "  return $classname$_descriptor_;\n"
     181             :     "}\n"
     182             :     "\n"
     183             :     "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n"
     184             :     "  protobuf_AssignDescriptorsOnce();\n"
     185             :     "  return $classname$_descriptor_;\n"
     186             :     "}\n"
     187           4 :     "\n");
     188             : 
     189             :   // Generate methods of the interface.
     190           4 :   GenerateNotImplementedMethods(printer);
     191           4 :   GenerateCallMethod(printer);
     192           4 :   GenerateGetPrototype(REQUEST, printer);
     193           4 :   GenerateGetPrototype(RESPONSE, printer);
     194             : 
     195             :   // Generate stub implementation.
     196             :   printer->Print(vars_,
     197             :     "$classname$_Stub::$classname$_Stub(::google::protobuf::RpcChannel* channel)\n"
     198             :     "  : channel_(channel), owns_channel_(false) {}\n"
     199             :     "$classname$_Stub::$classname$_Stub(\n"
     200             :     "    ::google::protobuf::RpcChannel* channel,\n"
     201             :     "    ::google::protobuf::Service::ChannelOwnership ownership)\n"
     202             :     "  : channel_(channel),\n"
     203             :     "    owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {}\n"
     204             :     "$classname$_Stub::~$classname$_Stub() {\n"
     205             :     "  if (owns_channel_) delete channel_;\n"
     206             :     "}\n"
     207           4 :     "\n");
     208             : 
     209           4 :   GenerateStubMethods(printer);
     210           4 : }
     211             : 
     212           4 : void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) {
     213          18 :   for (int i = 0; i < descriptor_->method_count(); i++) {
     214          39 :     const MethodDescriptor* method = descriptor_->method(i);
     215             :     map<string, string> sub_vars;
     216          10 :     sub_vars["classname"] = descriptor_->name();
     217          10 :     sub_vars["name"] = method->name();
     218          15 :     sub_vars["index"] = SimpleItoa(i);
     219          15 :     sub_vars["input_type"] = ClassName(method->input_type(), true);
     220          15 :     sub_vars["output_type"] = ClassName(method->output_type(), true);
     221             : 
     222             :     printer->Print(sub_vars,
     223             :       "void $classname$::$name$(::google::protobuf::RpcController* controller,\n"
     224             :       "                         const $input_type$*,\n"
     225             :       "                         $output_type$*,\n"
     226             :       "                         ::google::protobuf::Closure* done) {\n"
     227             :       "  controller->SetFailed(\"Method $name$() not implemented.\");\n"
     228             :       "  done->Run();\n"
     229             :       "}\n"
     230           5 :       "\n");
     231             :   }
     232           4 : }
     233             : 
     234           4 : void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
     235             :   printer->Print(vars_,
     236             :     "void $classname$::CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
     237             :     "                             ::google::protobuf::RpcController* controller,\n"
     238             :     "                             const ::google::protobuf::Message* request,\n"
     239             :     "                             ::google::protobuf::Message* response,\n"
     240             :     "                             ::google::protobuf::Closure* done) {\n"
     241             :     "  GOOGLE_DCHECK_EQ(method->service(), $classname$_descriptor_);\n"
     242           4 :     "  switch(method->index()) {\n");
     243             : 
     244          18 :   for (int i = 0; i < descriptor_->method_count(); i++) {
     245          34 :     const MethodDescriptor* method = descriptor_->method(i);
     246             :     map<string, string> sub_vars;
     247          10 :     sub_vars["name"] = method->name();
     248          15 :     sub_vars["index"] = SimpleItoa(i);
     249          15 :     sub_vars["input_type"] = ClassName(method->input_type(), true);
     250          15 :     sub_vars["output_type"] = ClassName(method->output_type(), true);
     251             : 
     252             :     // Note:  down_cast does not work here because it only works on pointers,
     253             :     //   not references.
     254             :     printer->Print(sub_vars,
     255             :       "    case $index$:\n"
     256             :       "      $name$(controller,\n"
     257             :       "             ::google::protobuf::down_cast<const $input_type$*>(request),\n"
     258             :       "             ::google::protobuf::down_cast< $output_type$*>(response),\n"
     259             :       "             done);\n"
     260           5 :       "      break;\n");
     261             :   }
     262             : 
     263             :   printer->Print(vars_,
     264             :     "    default:\n"
     265             :     "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
     266             :     "      break;\n"
     267             :     "  }\n"
     268             :     "}\n"
     269           4 :     "\n");
     270           4 : }
     271             : 
     272           8 : void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
     273             :                                             io::Printer* printer) {
     274           8 :   if (which == REQUEST) {
     275             :     printer->Print(vars_,
     276           4 :       "const ::google::protobuf::Message& $classname$::GetRequestPrototype(\n");
     277             :   } else {
     278             :     printer->Print(vars_,
     279           4 :       "const ::google::protobuf::Message& $classname$::GetResponsePrototype(\n");
     280             :   }
     281             : 
     282             :   printer->Print(vars_,
     283             :     "    const ::google::protobuf::MethodDescriptor* method) const {\n"
     284             :     "  GOOGLE_DCHECK_EQ(method->service(), descriptor());\n"
     285           8 :     "  switch(method->index()) {\n");
     286             : 
     287          36 :   for (int i = 0; i < descriptor_->method_count(); i++) {
     288          48 :     const MethodDescriptor* method = descriptor_->method(i);
     289             :     const Descriptor* type =
     290          20 :       (which == REQUEST) ? method->input_type() : method->output_type();
     291             : 
     292             :     map<string, string> sub_vars;
     293          30 :     sub_vars["index"] = SimpleItoa(i);
     294          30 :     sub_vars["type"] = ClassName(type, true);
     295             : 
     296             :     printer->Print(sub_vars,
     297             :       "    case $index$:\n"
     298          10 :       "      return $type$::default_instance();\n");
     299             :   }
     300             : 
     301             :   printer->Print(vars_,
     302             :     "    default:\n"
     303             :     "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
     304             :     "      return *static_cast< ::google::protobuf::Message*>(NULL);\n"
     305             :     "  }\n"
     306             :     "}\n"
     307           8 :     "\n");
     308           8 : }
     309             : 
     310           4 : void ServiceGenerator::GenerateStubMethods(io::Printer* printer) {
     311          18 :   for (int i = 0; i < descriptor_->method_count(); i++) {
     312          39 :     const MethodDescriptor* method = descriptor_->method(i);
     313             :     map<string, string> sub_vars;
     314          10 :     sub_vars["classname"] = descriptor_->name();
     315          10 :     sub_vars["name"] = method->name();
     316          15 :     sub_vars["index"] = SimpleItoa(i);
     317          15 :     sub_vars["input_type"] = ClassName(method->input_type(), true);
     318          15 :     sub_vars["output_type"] = ClassName(method->output_type(), true);
     319             : 
     320             :     printer->Print(sub_vars,
     321             :       "void $classname$_Stub::$name$(::google::protobuf::RpcController* controller,\n"
     322             :       "                              const $input_type$* request,\n"
     323             :       "                              $output_type$* response,\n"
     324             :       "                              ::google::protobuf::Closure* done) {\n"
     325             :       "  channel_->CallMethod(descriptor()->method($index$),\n"
     326             :       "                       controller, request, response, done);\n"
     327           5 :       "}\n");
     328             :   }
     329           4 : }
     330             : 
     331             : }  // namespace cpp
     332             : }  // namespace compiler
     333             : }  // namespace protobuf
     334             : }  // namespace google

Generated by: LCOV version 1.10