LCOV - code coverage report
Current view: top level - compiler - python_generator.cc (source / functions) Hit Total Coverage
Test: tmp.CaZ6RjdVn2 Lines: 385 399 96.5 %
Date: 2015-12-10 22:15:08 Functions: 19 20 95.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 <algorithm>
      35             : #include <cassert>
      36             : #include <cctype>
      37             : #include <cstring>
      38             : #include <map>
      39             : #include <memory>
      40             : #include <ostream>
      41             : #include <sstream>
      42             : #include <tuple>
      43             : #include <vector>
      44             : 
      45             : #include <grpc++/support/config.h>
      46             : #include "src/compiler/config.h"
      47             : #include "src/compiler/generator_helpers.h"
      48             : #include "src/compiler/python_generator.h"
      49             : 
      50             : using grpc_generator::StringReplace;
      51             : using grpc_generator::StripProto;
      52             : using grpc::protobuf::Descriptor;
      53             : using grpc::protobuf::FileDescriptor;
      54             : using grpc::protobuf::MethodDescriptor;
      55             : using grpc::protobuf::ServiceDescriptor;
      56             : using grpc::protobuf::compiler::GeneratorContext;
      57             : using grpc::protobuf::io::CodedOutputStream;
      58             : using grpc::protobuf::io::Printer;
      59             : using grpc::protobuf::io::StringOutputStream;
      60             : using grpc::protobuf::io::ZeroCopyOutputStream;
      61             : using std::initializer_list;
      62             : using std::make_pair;
      63             : using std::map;
      64             : using std::pair;
      65             : using std::replace;
      66             : using std::vector;
      67             : 
      68             : namespace grpc_python_generator {
      69             : 
      70          23 : PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
      71          23 :     : config_(config) {}
      72             : 
      73          23 : PythonGrpcGenerator::~PythonGrpcGenerator() {}
      74             : 
      75          27 : bool PythonGrpcGenerator::Generate(
      76             :     const FileDescriptor* file, const grpc::string& parameter,
      77             :     GeneratorContext* context, grpc::string* error) const {
      78             :   // Get output file name.
      79          27 :   grpc::string file_name;
      80             :   static const int proto_suffix_length = strlen(".proto");
      81          54 :   if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
      82          27 :       file->name().find_last_of(".proto") == file->name().size() - 1) {
      83          27 :     file_name = file->name().substr(
      84          54 :         0, file->name().size() - proto_suffix_length) + "_pb2.py";
      85             :   } else {
      86           0 :     *error = "Invalid proto file name. Proto file must end with .proto";
      87           0 :     return false;
      88             :   }
      89             : 
      90             :   std::unique_ptr<ZeroCopyOutputStream> output(
      91          54 :       context->OpenForInsert(file_name, "module_scope"));
      92          54 :   CodedOutputStream coded_out(output.get());
      93          27 :   bool success = false;
      94          54 :   grpc::string code = "";
      95          27 :   tie(success, code) = grpc_python_generator::GetServices(file, config_);
      96          27 :   if (success) {
      97          27 :     coded_out.WriteRaw(code.data(), code.size());
      98          27 :     return true;
      99             :   } else {
     100           0 :     return false;
     101          27 :   }
     102             : }
     103             : 
     104             : namespace {
     105             : //////////////////////////////////
     106             : // BEGIN FORMATTING BOILERPLATE //
     107             : //////////////////////////////////
     108             : 
     109             : // Converts an initializer list of the form { key0, value0, key1, value1, ... }
     110             : // into a map of key* to value*. Is merely a readability helper for later code.
     111         435 : map<grpc::string, grpc::string> ListToDict(
     112             :     const initializer_list<grpc::string>& values) {
     113         435 :   assert(values.size() % 2 == 0);
     114         435 :   map<grpc::string, grpc::string> value_map;
     115         435 :   auto value_iter = values.begin();
     116        1251 :   for (unsigned i = 0; i < values.size()/2; ++i) {
     117         816 :     grpc::string key = *value_iter;
     118         816 :     ++value_iter;
     119        1632 :     grpc::string value = *value_iter;
     120         816 :     value_map[key] = value;
     121         816 :     ++value_iter;
     122         816 :   }
     123         435 :   return value_map;
     124             : }
     125             : 
     126             : // Provides RAII indentation handling. Use as:
     127             : // {
     128             : //   IndentScope raii_my_indent_var_name_here(my_py_printer);
     129             : //   // constructor indented my_py_printer
     130             : //   ...
     131             : //   // destructor called at end of scope, un-indenting my_py_printer
     132             : // }
     133             : class IndentScope {
     134             :  public:
     135        2019 :   explicit IndentScope(Printer* printer) : printer_(printer) {
     136        2019 :     printer_->Indent();
     137        2019 :   }
     138             : 
     139        2019 :   ~IndentScope() {
     140        2019 :     printer_->Outdent();
     141        2019 :   }
     142             : 
     143             :  private:
     144             :   Printer* printer_;
     145             : };
     146             : 
     147             : ////////////////////////////////
     148             : // END FORMATTING BOILERPLATE //
     149             : ////////////////////////////////
     150             : 
     151          27 : bool PrintAlphaServicer(const ServiceDescriptor* service,
     152             :                         Printer* out) {
     153          27 :   grpc::string doc = "<fill me in later!>";
     154             :   map<grpc::string, grpc::string> dict = ListToDict({
     155          27 :         "Service", service->name(),
     156             :         "Documentation", doc,
     157          81 :       });
     158          27 :   out->Print(dict, "class EarlyAdopter$Service$Servicer(object):\n");
     159             :   {
     160          27 :     IndentScope raii_class_indent(out);
     161          27 :     out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
     162          27 :     out->Print("__metaclass__ = abc.ABCMeta\n");
     163         150 :     for (int i = 0; i < service->method_count(); ++i) {
     164         123 :       auto meth = service->method(i);
     165         123 :       grpc::string arg_name = meth->client_streaming() ?
     166         246 :           "request_iterator" : "request";
     167         123 :       out->Print("@abc.abstractmethod\n");
     168             :       out->Print("def $Method$(self, $ArgName$, context):\n",
     169         123 :                  "Method", meth->name(), "ArgName", arg_name);
     170             :       {
     171         123 :         IndentScope raii_method_indent(out);
     172         123 :         out->Print("raise NotImplementedError()\n");
     173             :       }
     174         150 :     }
     175             :   }
     176          54 :   return true;
     177             : }
     178             : 
     179          27 : bool PrintAlphaServer(const ServiceDescriptor* service, Printer* out) {
     180          27 :   grpc::string doc = "<fill me in later!>";
     181             :   map<grpc::string, grpc::string> dict = ListToDict({
     182          27 :         "Service", service->name(),
     183             :         "Documentation", doc,
     184          81 :       });
     185          27 :   out->Print(dict, "class EarlyAdopter$Service$Server(object):\n");
     186             :   {
     187          27 :     IndentScope raii_class_indent(out);
     188          27 :     out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
     189          27 :     out->Print("__metaclass__ = abc.ABCMeta\n");
     190          27 :     out->Print("@abc.abstractmethod\n");
     191          27 :     out->Print("def start(self):\n");
     192             :     {
     193          27 :       IndentScope raii_method_indent(out);
     194          27 :       out->Print("raise NotImplementedError()\n");
     195             :     }
     196             : 
     197          27 :     out->Print("@abc.abstractmethod\n");
     198          27 :     out->Print("def stop(self):\n");
     199             :     {
     200          27 :       IndentScope raii_method_indent(out);
     201          27 :       out->Print("raise NotImplementedError()\n");
     202          27 :     }
     203             :   }
     204          54 :   return true;
     205             : }
     206             : 
     207          27 : bool PrintAlphaStub(const ServiceDescriptor* service,
     208             :                     Printer* out) {
     209          27 :   grpc::string doc = "<fill me in later!>";
     210             :   map<grpc::string, grpc::string> dict = ListToDict({
     211          27 :         "Service", service->name(),
     212             :         "Documentation", doc,
     213          81 :       });
     214          27 :   out->Print(dict, "class EarlyAdopter$Service$Stub(object):\n");
     215             :   {
     216          27 :     IndentScope raii_class_indent(out);
     217          27 :     out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
     218          27 :     out->Print("__metaclass__ = abc.ABCMeta\n");
     219         150 :     for (int i = 0; i < service->method_count(); ++i) {
     220         123 :       const MethodDescriptor* meth = service->method(i);
     221         123 :       grpc::string arg_name = meth->client_streaming() ?
     222         246 :           "request_iterator" : "request";
     223         246 :       auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
     224         123 :       out->Print("@abc.abstractmethod\n");
     225         123 :       out->Print(methdict, "def $Method$(self, $ArgName$):\n");
     226             :       {
     227         123 :         IndentScope raii_method_indent(out);
     228         123 :         out->Print("raise NotImplementedError()\n");
     229             :       }
     230         123 :       out->Print(methdict, "$Method$.async = None\n");
     231         150 :     }
     232             :   }
     233          54 :   return true;
     234             : }
     235             : 
     236             : // TODO(protobuf team): Export `ModuleName` from protobuf's
     237             : // `src/google/protobuf/compiler/python/python_generator.cc` file.
     238         984 : grpc::string ModuleName(const grpc::string& filename) {
     239         984 :   grpc::string basename = StripProto(filename);
     240         984 :   basename = StringReplace(basename, "-", "_");
     241         984 :   basename = StringReplace(basename, "/", ".");
     242         984 :   return basename + "_pb2";
     243             : }
     244             : 
     245         984 : bool GetModuleAndMessagePath(const Descriptor* type,
     246             :                              pair<grpc::string, grpc::string>* out) {
     247         984 :   const Descriptor* path_elem_type = type;
     248         984 :   vector<const Descriptor*> message_path;
     249         984 :   do {
     250         984 :     message_path.push_back(path_elem_type);
     251         984 :     path_elem_type = path_elem_type->containing_type();
     252             :   } while (path_elem_type); // implicit nullptr comparison; don't be explicit
     253        1968 :   grpc::string file_name = type->file()->name();
     254             :   static const int proto_suffix_length = strlen(".proto");
     255        1968 :   if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
     256         984 :         file_name.find_last_of(".proto") == file_name.size() - 1)) {
     257           0 :     return false;
     258             :   }
     259        1968 :   grpc::string module = ModuleName(file_name);
     260        1968 :   grpc::string message_type;
     261        5904 :   for (auto path_iter = message_path.rbegin();
     262        3936 :        path_iter != message_path.rend(); ++path_iter) {
     263         984 :     message_type += (*path_iter)->name() + ".";
     264             :   }
     265             :   // no pop_back prior to C++11
     266         984 :   message_type.resize(message_type.size() - 1);
     267         984 :   *out = make_pair(module, message_type);
     268        1968 :   return true;
     269             : }
     270             : 
     271          27 : bool PrintAlphaServerFactory(const grpc::string& package_qualified_service_name,
     272             :                              const ServiceDescriptor* service, Printer* out) {
     273             :   out->Print("def early_adopter_create_$Service$_server(servicer, port, "
     274             :              "private_key=None, certificate_chain=None):\n",
     275          27 :              "Service", service->name());
     276             :   {
     277          27 :     IndentScope raii_create_server_indent(out);
     278          54 :     map<grpc::string, grpc::string> method_description_constructors;
     279             :     map<grpc::string, pair<grpc::string, grpc::string>>
     280          54 :         input_message_modules_and_classes;
     281             :     map<grpc::string, pair<grpc::string, grpc::string>>
     282          54 :         output_message_modules_and_classes;
     283         150 :     for (int i = 0; i < service->method_count(); ++i) {
     284         123 :       const MethodDescriptor* method = service->method(i);
     285             :       const grpc::string method_description_constructor =
     286         492 :           grpc::string(method->client_streaming() ? "stream_" : "unary_") +
     287         123 :           grpc::string(method->server_streaming() ? "stream_" : "unary_") +
     288         246 :           "service_description";
     289         246 :       pair<grpc::string, grpc::string> input_message_module_and_class;
     290         123 :       if (!GetModuleAndMessagePath(method->input_type(),
     291         123 :                                    &input_message_module_and_class)) {
     292           0 :         return false;
     293             :       }
     294         246 :       pair<grpc::string, grpc::string> output_message_module_and_class;
     295         123 :       if (!GetModuleAndMessagePath(method->output_type(),
     296         123 :                                    &output_message_module_and_class)) {
     297           0 :         return false;
     298             :       }
     299             :       // Import the modules that define the messages used in RPCs.
     300             :       out->Print("import $Module$\n", "Module",
     301         123 :                  input_message_module_and_class.first);
     302             :       out->Print("import $Module$\n", "Module",
     303         123 :                  output_message_module_and_class.first);
     304             :       method_description_constructors.insert(
     305         123 :           make_pair(method->name(), method_description_constructor));
     306             :       input_message_modules_and_classes.insert(
     307         123 :           make_pair(method->name(), input_message_module_and_class));
     308             :       output_message_modules_and_classes.insert(
     309         123 :           make_pair(method->name(), output_message_module_and_class));
     310         123 :     }
     311          27 :     out->Print("method_service_descriptions = {\n");
     312         450 :     for (auto name_and_description_constructor =
     313          27 :            method_description_constructors.begin();
     314         300 :          name_and_description_constructor !=
     315             :            method_description_constructors.end();
     316             :          name_and_description_constructor++) {
     317         123 :       IndentScope raii_descriptions_indent(out);
     318         246 :       const grpc::string method_name = name_and_description_constructor->first;
     319             :       auto input_message_module_and_class =
     320         123 :           input_message_modules_and_classes.find(method_name);
     321             :       auto output_message_module_and_class =
     322         123 :           output_message_modules_and_classes.find(method_name);
     323             :       out->Print("\"$Method$\": alpha_utilities.$Constructor$(\n", "Method",
     324             :                  method_name, "Constructor",
     325         123 :                  name_and_description_constructor->second);
     326             :       {
     327         123 :         IndentScope raii_description_arguments_indent(out);
     328         123 :         out->Print("servicer.$Method$,\n", "Method", method_name);
     329             :         out->Print(
     330             :             "$InputTypeModule$.$InputTypeClass$.FromString,\n",
     331         123 :             "InputTypeModule", input_message_module_and_class->second.first,
     332         246 :             "InputTypeClass", input_message_module_and_class->second.second);
     333             :         out->Print(
     334             :             "$OutputTypeModule$.$OutputTypeClass$.SerializeToString,\n",
     335         123 :             "OutputTypeModule", output_message_module_and_class->second.first,
     336         246 :             "OutputTypeClass", output_message_module_and_class->second.second);
     337             :       }
     338         123 :       out->Print("),\n");
     339         123 :     }
     340          27 :     out->Print("}\n");
     341             :     out->Print(
     342             :         "return early_adopter_implementations.server("
     343             :         "\"$PackageQualifiedServiceName$\","
     344             :         " method_service_descriptions, port, private_key=private_key,"
     345             :         " certificate_chain=certificate_chain)\n",
     346          54 :         "PackageQualifiedServiceName", package_qualified_service_name);
     347             :   }
     348          27 :   return true;
     349             : }
     350             : 
     351          27 : bool PrintAlphaStubFactory(const grpc::string& package_qualified_service_name,
     352             :                            const ServiceDescriptor* service, Printer* out) {
     353             :   map<grpc::string, grpc::string> dict = ListToDict({
     354          27 :         "Service", service->name(),
     355          54 :       });
     356             :   out->Print(dict, "def early_adopter_create_$Service$_stub(host, port,"
     357             :              " metadata_transformer=None,"
     358             :              " secure=False, root_certificates=None, private_key=None,"
     359          27 :              " certificate_chain=None, server_host_override=None):\n");
     360             :   {
     361          27 :     IndentScope raii_create_server_indent(out);
     362          54 :     map<grpc::string, grpc::string> method_description_constructors;
     363             :     map<grpc::string, pair<grpc::string, grpc::string>>
     364          54 :         input_message_modules_and_classes;
     365             :     map<grpc::string, pair<grpc::string, grpc::string>>
     366          54 :         output_message_modules_and_classes;
     367         150 :     for (int i = 0; i < service->method_count(); ++i) {
     368         123 :       const MethodDescriptor* method = service->method(i);
     369             :       const grpc::string method_description_constructor =
     370         492 :           grpc::string(method->client_streaming() ? "stream_" : "unary_") +
     371         123 :           grpc::string(method->server_streaming() ? "stream_" : "unary_") +
     372         246 :           "invocation_description";
     373         246 :       pair<grpc::string, grpc::string> input_message_module_and_class;
     374         123 :       if (!GetModuleAndMessagePath(method->input_type(),
     375         123 :                                    &input_message_module_and_class)) {
     376           0 :         return false;
     377             :       }
     378         246 :       pair<grpc::string, grpc::string> output_message_module_and_class;
     379         123 :       if (!GetModuleAndMessagePath(method->output_type(),
     380         123 :                                    &output_message_module_and_class)) {
     381           0 :         return false;
     382             :       }
     383             :       // Import the modules that define the messages used in RPCs.
     384             :       out->Print("import $Module$\n", "Module",
     385         123 :                  input_message_module_and_class.first);
     386             :       out->Print("import $Module$\n", "Module",
     387         123 :                  output_message_module_and_class.first);
     388             :       method_description_constructors.insert(
     389         123 :           make_pair(method->name(), method_description_constructor));
     390             :       input_message_modules_and_classes.insert(
     391         123 :           make_pair(method->name(), input_message_module_and_class));
     392             :       output_message_modules_and_classes.insert(
     393         123 :           make_pair(method->name(), output_message_module_and_class));
     394         123 :     }
     395          27 :     out->Print("method_invocation_descriptions = {\n");
     396         450 :     for (auto name_and_description_constructor =
     397          27 :            method_description_constructors.begin();
     398         300 :          name_and_description_constructor !=
     399             :            method_description_constructors.end();
     400             :          name_and_description_constructor++) {
     401         123 :       IndentScope raii_descriptions_indent(out);
     402         246 :       const grpc::string method_name = name_and_description_constructor->first;
     403             :       auto input_message_module_and_class =
     404         123 :           input_message_modules_and_classes.find(method_name);
     405             :       auto output_message_module_and_class =
     406         123 :           output_message_modules_and_classes.find(method_name);
     407             :       out->Print("\"$Method$\": alpha_utilities.$Constructor$(\n", "Method",
     408             :                  method_name, "Constructor",
     409         123 :                  name_and_description_constructor->second);
     410             :       {
     411         123 :         IndentScope raii_description_arguments_indent(out);
     412             :         out->Print(
     413             :             "$InputTypeModule$.$InputTypeClass$.SerializeToString,\n",
     414         123 :             "InputTypeModule", input_message_module_and_class->second.first,
     415         246 :             "InputTypeClass", input_message_module_and_class->second.second);
     416             :         out->Print(
     417             :             "$OutputTypeModule$.$OutputTypeClass$.FromString,\n",
     418         123 :             "OutputTypeModule", output_message_module_and_class->second.first,
     419         246 :             "OutputTypeClass", output_message_module_and_class->second.second);
     420             :       }
     421         123 :       out->Print("),\n");
     422         123 :     }
     423          27 :     out->Print("}\n");
     424             :     out->Print(
     425             :         "return early_adopter_implementations.stub("
     426             :         "\"$PackageQualifiedServiceName$\","
     427             :         " method_invocation_descriptions, host, port,"
     428             :         " metadata_transformer=metadata_transformer, secure=secure,"
     429             :         " root_certificates=root_certificates, private_key=private_key,"
     430             :         " certificate_chain=certificate_chain,"
     431             :         " server_host_override=server_host_override)\n",
     432          54 :         "PackageQualifiedServiceName", package_qualified_service_name);
     433             :   }
     434          27 :   return true;
     435             : }
     436             : 
     437          27 : bool PrintBetaServicer(const ServiceDescriptor* service,
     438             :                        Printer* out) {
     439          27 :   grpc::string doc = "<fill me in later!>";
     440             :   map<grpc::string, grpc::string> dict = ListToDict({
     441          27 :         "Service", service->name(),
     442             :         "Documentation", doc,
     443          81 :       });
     444          27 :   out->Print("\n");
     445          27 :   out->Print(dict, "class Beta$Service$Servicer(object):\n");
     446             :   {
     447          27 :     IndentScope raii_class_indent(out);
     448          27 :     out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
     449          27 :     out->Print("__metaclass__ = abc.ABCMeta\n");
     450         150 :     for (int i = 0; i < service->method_count(); ++i) {
     451         123 :       auto meth = service->method(i);
     452         123 :       grpc::string arg_name = meth->client_streaming() ?
     453         246 :           "request_iterator" : "request";
     454         123 :       out->Print("@abc.abstractmethod\n");
     455             :       out->Print("def $Method$(self, $ArgName$, context):\n",
     456         123 :                  "Method", meth->name(), "ArgName", arg_name);
     457             :       {
     458         123 :         IndentScope raii_method_indent(out);
     459         123 :         out->Print("raise NotImplementedError()\n");
     460             :       }
     461         150 :     }
     462             :   }
     463          54 :   return true;
     464             : }
     465             : 
     466          27 : bool PrintBetaStub(const ServiceDescriptor* service,
     467             :                    Printer* out) {
     468          27 :   grpc::string doc = "The interface to which stubs will conform.";
     469             :   map<grpc::string, grpc::string> dict = ListToDict({
     470          27 :         "Service", service->name(),
     471             :         "Documentation", doc,
     472          81 :       });
     473          27 :   out->Print("\n");
     474          27 :   out->Print(dict, "class Beta$Service$Stub(object):\n");
     475             :   {
     476          27 :     IndentScope raii_class_indent(out);
     477          27 :     out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
     478          27 :     out->Print("__metaclass__ = abc.ABCMeta\n");
     479         150 :     for (int i = 0; i < service->method_count(); ++i) {
     480         123 :       const MethodDescriptor* meth = service->method(i);
     481         123 :       grpc::string arg_name = meth->client_streaming() ?
     482         246 :           "request_iterator" : "request";
     483         246 :       auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
     484         123 :       out->Print("@abc.abstractmethod\n");
     485         123 :       out->Print(methdict, "def $Method$(self, $ArgName$, timeout):\n");
     486             :       {
     487         123 :         IndentScope raii_method_indent(out);
     488         123 :         out->Print("raise NotImplementedError()\n");
     489             :       }
     490         123 :       if (!meth->server_streaming()) {
     491          54 :         out->Print(methdict, "$Method$.future = None\n");
     492             :       }
     493         150 :     }
     494             :   }
     495          54 :   return true;
     496             : }
     497             : 
     498          27 : bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name,
     499             :                             const ServiceDescriptor* service, Printer* out) {
     500          27 :   out->Print("\n");
     501             :   out->Print("def beta_create_$Service$_server(servicer, pool=None, "
     502             :              "pool_size=None, default_timeout=None, maximum_timeout=None):\n",
     503          27 :              "Service", service->name());
     504             :   {
     505          27 :     IndentScope raii_create_server_indent(out);
     506          54 :     map<grpc::string, grpc::string> method_implementation_constructors;
     507             :     map<grpc::string, pair<grpc::string, grpc::string>>
     508          54 :         input_message_modules_and_classes;
     509             :     map<grpc::string, pair<grpc::string, grpc::string>>
     510          54 :         output_message_modules_and_classes;
     511         150 :     for (int i = 0; i < service->method_count(); ++i) {
     512         123 :       const MethodDescriptor* method = service->method(i);
     513             :       const grpc::string method_implementation_constructor =
     514         492 :           grpc::string(method->client_streaming() ? "stream_" : "unary_") +
     515         123 :           grpc::string(method->server_streaming() ? "stream_" : "unary_") +
     516         246 :           "inline";
     517         246 :       pair<grpc::string, grpc::string> input_message_module_and_class;
     518         123 :       if (!GetModuleAndMessagePath(method->input_type(),
     519         123 :                                    &input_message_module_and_class)) {
     520           0 :         return false;
     521             :       }
     522         246 :       pair<grpc::string, grpc::string> output_message_module_and_class;
     523         123 :       if (!GetModuleAndMessagePath(method->output_type(),
     524         123 :                                    &output_message_module_and_class)) {
     525           0 :         return false;
     526             :       }
     527             :       // Import the modules that define the messages used in RPCs.
     528             :       out->Print("import $Module$\n", "Module",
     529         123 :                  input_message_module_and_class.first);
     530             :       out->Print("import $Module$\n", "Module",
     531         123 :                  output_message_module_and_class.first);
     532             :       method_implementation_constructors.insert(
     533         123 :           make_pair(method->name(), method_implementation_constructor));
     534             :       input_message_modules_and_classes.insert(
     535         123 :           make_pair(method->name(), input_message_module_and_class));
     536             :       output_message_modules_and_classes.insert(
     537         123 :           make_pair(method->name(), output_message_module_and_class));
     538         123 :     }
     539          27 :     out->Print("request_deserializers = {\n");
     540         450 :     for (auto name_and_input_module_class_pair =
     541          27 :            input_message_modules_and_classes.begin();
     542         300 :          name_and_input_module_class_pair !=
     543             :            input_message_modules_and_classes.end();
     544             :          name_and_input_module_class_pair++) {
     545         123 :       IndentScope raii_indent(out);
     546             :       out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
     547             :                  "$InputTypeModule$.$InputTypeClass$.FromString,\n",
     548             :                  "PackageQualifiedServiceName", package_qualified_service_name,
     549         123 :                  "MethodName", name_and_input_module_class_pair->first,
     550             :                  "InputTypeModule",
     551         123 :                  name_and_input_module_class_pair->second.first,
     552             :                  "InputTypeClass",
     553         369 :                  name_and_input_module_class_pair->second.second);
     554         123 :     }
     555          27 :     out->Print("}\n");
     556          27 :     out->Print("response_serializers = {\n");
     557         450 :     for (auto name_and_output_module_class_pair =
     558          27 :            output_message_modules_and_classes.begin();
     559         300 :          name_and_output_module_class_pair !=
     560             :            output_message_modules_and_classes.end();
     561             :          name_and_output_module_class_pair++) {
     562         123 :       IndentScope raii_indent(out);
     563             :       out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
     564             :                  "$OutputTypeModule$.$OutputTypeClass$.SerializeToString,\n",
     565             :                  "PackageQualifiedServiceName", package_qualified_service_name,
     566         123 :                  "MethodName", name_and_output_module_class_pair->first,
     567             :                  "OutputTypeModule",
     568         123 :                  name_and_output_module_class_pair->second.first,
     569             :                  "OutputTypeClass",
     570         369 :                  name_and_output_module_class_pair->second.second);
     571         123 :     }
     572          27 :     out->Print("}\n");
     573          27 :     out->Print("method_implementations = {\n");
     574         450 :     for (auto name_and_implementation_constructor =
     575          27 :            method_implementation_constructors.begin();
     576         300 :          name_and_implementation_constructor !=
     577             :            method_implementation_constructors.end();
     578             :          name_and_implementation_constructor++) {
     579         123 :       IndentScope raii_descriptions_indent(out);
     580             :       const grpc::string method_name =
     581         246 :           name_and_implementation_constructor->first;
     582             :       out->Print("(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
     583             :                  "face_utilities.$Constructor$(servicer.$Method$),\n",
     584             :                  "PackageQualifiedServiceName", package_qualified_service_name,
     585         123 :                  "Method", name_and_implementation_constructor->first,
     586         246 :                  "Constructor", name_and_implementation_constructor->second);
     587         123 :     }
     588          27 :     out->Print("}\n");
     589             :     out->Print("server_options = beta_implementations.server_options("
     590             :                "request_deserializers=request_deserializers, "
     591             :                "response_serializers=response_serializers, "
     592             :                "thread_pool=pool, thread_pool_size=pool_size, "
     593             :                "default_timeout=default_timeout, "
     594          27 :                "maximum_timeout=maximum_timeout)\n");
     595             :     out->Print("return beta_implementations.server(method_implementations, "
     596          54 :                "options=server_options)\n");
     597             :   }
     598          27 :   return true;
     599             : }
     600             : 
     601          27 : bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
     602             :                           const ServiceDescriptor* service, Printer* out) {
     603             :   map<grpc::string, grpc::string> dict = ListToDict({
     604          27 :         "Service", service->name(),
     605          54 :       });
     606          27 :   out->Print("\n");
     607             :   out->Print(dict, "def beta_create_$Service$_stub(channel, host=None,"
     608          27 :              " metadata_transformer=None, pool=None, pool_size=None):\n");
     609             :   {
     610          27 :     IndentScope raii_create_server_indent(out);
     611          54 :     map<grpc::string, grpc::string> method_cardinalities;
     612             :     map<grpc::string, pair<grpc::string, grpc::string>>
     613          54 :         input_message_modules_and_classes;
     614             :     map<grpc::string, pair<grpc::string, grpc::string>>
     615          54 :         output_message_modules_and_classes;
     616         150 :     for (int i = 0; i < service->method_count(); ++i) {
     617         123 :       const MethodDescriptor* method = service->method(i);
     618             :       const grpc::string method_cardinality =
     619         246 :           grpc::string(method->client_streaming() ? "STREAM" : "UNARY") +
     620             :           "_" +
     621         369 :           grpc::string(method->server_streaming() ? "STREAM" : "UNARY");
     622         246 :       pair<grpc::string, grpc::string> input_message_module_and_class;
     623         123 :       if (!GetModuleAndMessagePath(method->input_type(),
     624         123 :                                    &input_message_module_and_class)) {
     625           0 :         return false;
     626             :       }
     627         246 :       pair<grpc::string, grpc::string> output_message_module_and_class;
     628         123 :       if (!GetModuleAndMessagePath(method->output_type(),
     629         123 :                                    &output_message_module_and_class)) {
     630           0 :         return false;
     631             :       }
     632             :       // Import the modules that define the messages used in RPCs.
     633             :       out->Print("import $Module$\n", "Module",
     634         123 :                  input_message_module_and_class.first);
     635             :       out->Print("import $Module$\n", "Module",
     636         123 :                  output_message_module_and_class.first);
     637             :       method_cardinalities.insert(
     638         123 :           make_pair(method->name(), method_cardinality));
     639             :       input_message_modules_and_classes.insert(
     640         123 :           make_pair(method->name(), input_message_module_and_class));
     641             :       output_message_modules_and_classes.insert(
     642         123 :           make_pair(method->name(), output_message_module_and_class));
     643         123 :     }
     644          27 :     out->Print("request_serializers = {\n");
     645         450 :     for (auto name_and_input_module_class_pair =
     646          27 :            input_message_modules_and_classes.begin();
     647         300 :          name_and_input_module_class_pair !=
     648             :            input_message_modules_and_classes.end();
     649             :          name_and_input_module_class_pair++) {
     650         123 :       IndentScope raii_indent(out);
     651             :       out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
     652             :                  "$InputTypeModule$.$InputTypeClass$.SerializeToString,\n",
     653             :                  "PackageQualifiedServiceName", package_qualified_service_name,
     654         123 :                  "MethodName", name_and_input_module_class_pair->first,
     655             :                  "InputTypeModule",
     656         123 :                  name_and_input_module_class_pair->second.first,
     657             :                  "InputTypeClass",
     658         369 :                  name_and_input_module_class_pair->second.second);
     659         123 :     }
     660          27 :     out->Print("}\n");
     661          27 :     out->Print("response_deserializers = {\n");
     662         450 :     for (auto name_and_output_module_class_pair =
     663          27 :            output_message_modules_and_classes.begin();
     664         300 :          name_and_output_module_class_pair !=
     665             :            output_message_modules_and_classes.end();
     666             :          name_and_output_module_class_pair++) {
     667         123 :       IndentScope raii_indent(out);
     668             :       out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
     669             :                  "$OutputTypeModule$.$OutputTypeClass$.FromString,\n",
     670             :                  "PackageQualifiedServiceName", package_qualified_service_name,
     671         123 :                  "MethodName", name_and_output_module_class_pair->first,
     672             :                  "OutputTypeModule",
     673         123 :                  name_and_output_module_class_pair->second.first,
     674             :                  "OutputTypeClass",
     675         369 :                  name_and_output_module_class_pair->second.second);
     676         123 :     }
     677          27 :     out->Print("}\n");
     678          27 :     out->Print("cardinalities = {\n");
     679         450 :     for (auto name_and_cardinality = method_cardinalities.begin();
     680         300 :          name_and_cardinality != method_cardinalities.end();
     681             :          name_and_cardinality++) {
     682         123 :       IndentScope raii_descriptions_indent(out);
     683             :       out->Print("\'$Method$\': cardinality.Cardinality.$Cardinality$,\n",
     684         123 :                  "Method", name_and_cardinality->first,
     685         246 :                  "Cardinality", name_and_cardinality->second);
     686         123 :     }
     687          27 :     out->Print("}\n");
     688             :     out->Print("stub_options = beta_implementations.stub_options("
     689             :                "host=host, metadata_transformer=metadata_transformer, "
     690             :                "request_serializers=request_serializers, "
     691             :                "response_deserializers=response_deserializers, "
     692          27 :                "thread_pool=pool, thread_pool_size=pool_size)\n");
     693             :     out->Print(
     694             :         "return beta_implementations.dynamic_stub(channel, \'$PackageQualifiedServiceName$\', "
     695             :         "cardinalities, options=stub_options)\n",
     696          54 :         "PackageQualifiedServiceName", package_qualified_service_name);
     697             :   }
     698          27 :   return true;
     699             : }
     700             : 
     701          27 : bool PrintPreamble(const FileDescriptor* file,
     702             :                    const GeneratorConfiguration& config, Printer* out) {
     703          27 :   out->Print("import abc\n");
     704             :   out->Print("from $Package$ import implementations as beta_implementations\n",
     705          27 :              "Package", config.beta_package_root);
     706             :   out->Print("from $Package$ import implementations as early_adopter_implementations\n",
     707          27 :              "Package", config.early_adopter_package_root);
     708          27 :   out->Print("from grpc.framework.alpha import utilities as alpha_utilities\n");
     709          27 :   out->Print("from grpc.framework.common import cardinality\n");
     710          27 :   out->Print("from grpc.framework.interfaces.face import utilities as face_utilities\n");
     711          27 :   return true;
     712             : }
     713             : 
     714             : }  // namespace
     715             : 
     716          27 : pair<bool, grpc::string> GetServices(const FileDescriptor* file,
     717             :                                     const GeneratorConfiguration& config) {
     718          27 :   grpc::string output;
     719             :   {
     720             :     // Scope the output stream so it closes and finalizes output to the string.
     721          27 :     StringOutputStream output_stream(&output);
     722          54 :     Printer out(&output_stream, '$');
     723          27 :     if (!PrintPreamble(file, config, &out)) {
     724           0 :       return make_pair(false, "");
     725             :     }
     726          54 :     auto package = file->package();
     727          27 :     if (!package.empty()) {
     728          27 :       package = package.append(".");
     729             :     }
     730          54 :     for (int i = 0; i < file->service_count(); ++i) {
     731          27 :       auto service = file->service(i);
     732          27 :       auto package_qualified_service_name = package + service->name();
     733          81 :       if (!(PrintAlphaServicer(service, &out) &&
     734          54 :             PrintAlphaServer(service, &out) &&
     735          54 :             PrintAlphaStub(service, &out) &&
     736          54 :             PrintAlphaServerFactory(package_qualified_service_name, service, &out) &&
     737          54 :             PrintAlphaStubFactory(package_qualified_service_name, service, &out) &&
     738          54 :             PrintBetaServicer(service, &out) &&
     739          54 :             PrintBetaStub(service, &out) &&
     740          27 :             PrintBetaServerFactory(package_qualified_service_name, service, &out) &&
     741          54 :             PrintBetaStubFactory(package_qualified_service_name, service, &out))) {
     742           0 :         return make_pair(false, "");
     743             :       }
     744          54 :     }
     745             :   }
     746          27 :   return make_pair(true, std::move(output));
     747             : }
     748             : 
     749             : }  // namespace grpc_python_generator

Generated by: LCOV version 1.11