blob: 278e5072b264d3c53cb15db18168373f8bb52541 [file] [log] [blame]
Masood Malekghassemif8e297a2015-02-19 15:39:32 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Masood Malekghassemif8e297a2015-02-19 15:39:32 -08004 * 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
Masood Malekghassemi40e8cbd2015-02-26 08:39:50 -080034#include <algorithm>
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080035#include <cassert>
36#include <cctype>
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -080037#include <cstring>
Masood Malekghassemid9539592016-10-20 14:47:14 -070038#include <fstream>
39#include <iostream>
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080040#include <map>
Masood Malekghassemi3bb52152015-03-17 21:52:52 -070041#include <memory>
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080042#include <ostream>
Bryan Blanchardc549a3e2016-12-13 07:46:28 -050043#include <set>
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080044#include <sstream>
Masood Malekghassemi3bb52152015-03-17 21:52:52 -070045#include <tuple>
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -080046#include <vector>
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080047
Masood Malekghassemi65c803b2015-03-20 06:48:47 -070048#include "src/compiler/config.h"
Nicolas "Pixel" Noble93fa0982015-02-27 21:50:58 +010049#include "src/compiler/generator_helpers.h"
Harsh Vardhan93077ae2016-12-26 18:23:45 +053050#include "src/compiler/protobuf_plugin.h"
Harsh Vardhan974f3d72017-03-03 14:19:32 +053051#include "src/compiler/python_generator.h"
Harsh Vardhan93077ae2016-12-26 18:23:45 +053052#include "src/compiler/python_generator_helpers.h"
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +053053#include "src/compiler/python_private_generator.h"
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080054
Masood Malekghassemi65c803b2015-03-20 06:48:47 -070055using grpc::protobuf::FileDescriptor;
Masood Malekghassemi65c803b2015-03-20 06:48:47 -070056using grpc::protobuf::compiler::GeneratorContext;
57using grpc::protobuf::io::CodedOutputStream;
Masood Malekghassemi65c803b2015-03-20 06:48:47 -070058using grpc::protobuf::io::ZeroCopyOutputStream;
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -080059using std::make_pair;
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080060using std::map;
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -080061using std::pair;
Masood Malekghassemi40e8cbd2015-02-26 08:39:50 -080062using std::replace;
Bryan Blanchardc549a3e2016-12-13 07:46:28 -050063using std::tuple;
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -080064using std::vector;
Bryan Blanchardc549a3e2016-12-13 07:46:28 -050065using std::set;
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080066
67namespace grpc_python_generator {
Masood Malekghassemi3bb52152015-03-17 21:52:52 -070068
Harsh Vardhan64741b22017-01-14 15:19:09 +053069grpc::string generator_file_name;
70
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080071namespace {
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080072
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -070073typedef map<grpc::string, grpc::string> StringMap;
74typedef vector<grpc::string> StringVector;
Bryan Blanchardc549a3e2016-12-13 07:46:28 -050075typedef tuple<grpc::string, grpc::string> StringPair;
76typedef set<StringPair> StringPairSet;
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -070077
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080078// Provides RAII indentation handling. Use as:
79// {
80// IndentScope raii_my_indent_var_name_here(my_py_printer);
81// // constructor indented my_py_printer
82// ...
83// // destructor called at end of scope, un-indenting my_py_printer
84// }
85class IndentScope {
86 public:
Harsh Vardhan93077ae2016-12-26 18:23:45 +053087 explicit IndentScope(grpc_generator::Printer* printer) : printer_(printer) {
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080088 printer_->Indent();
89 }
90
Masood Malekghassemiac592452016-07-01 11:58:04 -070091 ~IndentScope() { printer_->Outdent(); }
Masood Malekghassemif8e297a2015-02-19 15:39:32 -080092
93 private:
Harsh Vardhan93077ae2016-12-26 18:23:45 +053094 grpc_generator::Printer* printer_;
Masood Malekghassemid9539592016-10-20 14:47:14 -070095};
96
Masood Malekghassemid9539592016-10-20 14:47:14 -070097PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config,
Harsh Vardhan93077ae2016-12-26 18:23:45 +053098 const grpc_generator::File* file)
Masood Malekghassemi7780cc02016-10-24 15:30:05 -070099 : config(config), file(file) {}
Masood Malekghassemid9539592016-10-20 14:47:14 -0700100
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530101void PrivateGenerator::PrintAllComments(StringVector comments,
102 grpc_generator::Printer* out) {
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530103 if (comments.empty()) {
Mehrdad Afshari68f6a672017-04-12 14:19:49 -0700104 // Python requires code structures like class and def to have
105 // a body, even if it is just "pass" or a docstring. We need
106 // to ensure not to generate empty bodies. We could do something
107 // smarter and more sophisticated, but at the moment, if there is
108 // no docstring to print, we simply emit "pass" to ensure validity
109 // of the generated code.
110 out->Print("# missing associated documentation comment in .proto file\n");
111 out->Print("pass\n");
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530112 return;
113 }
114 out->Print("\"\"\"");
115 for (StringVector::iterator it = comments.begin(); it != comments.end();
116 ++it) {
117 size_t start_pos = it->find_first_not_of(' ');
118 if (start_pos != grpc::string::npos) {
119 out->Print(it->c_str() + start_pos);
yang-gb0de7162016-05-03 15:48:19 -0700120 }
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530121 out->Print("\n");
122 }
123 out->Print("\"\"\"\n");
yang-gb0de7162016-05-03 15:48:19 -0700124}
125
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530126bool PrivateGenerator::PrintBetaServicer(const grpc_generator::Service* service,
127 grpc_generator::Printer* out) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530128 StringMap service_dict;
129 service_dict["Service"] = service->name();
Ken Paysonbe187b02016-05-06 15:32:58 -0700130 out->Print("\n\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530131 out->Print(service_dict, "class Beta$Service$Servicer(object):\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000132 {
133 IndentScope raii_class_indent(out);
Nicolas "Pixel" Noblebeeeddd2016-09-29 20:27:23 +0200134 out->Print(
135 "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
136 "\nIt is recommended to use the GA API (classes and functions in this\n"
137 "file not marked beta) for all further purposes. This class was "
138 "generated\n"
139 "only to ease transition from grpcio<0.15.0 to "
140 "grpcio>=0.15.0.\"\"\"\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530141 StringVector service_comments = service->GetAllComments();
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530142 PrintAllComments(service_comments, out);
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000143 for (int i = 0; i < service->method_count(); ++i) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530144 auto method = service->method(i);
Masood Malekghassemiac592452016-07-01 11:58:04 -0700145 grpc::string arg_name =
Harsh Vardhan974f3d72017-03-03 14:19:32 +0530146 method->ClientStreaming() ? "request_iterator" : "request";
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530147 StringMap method_dict;
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530148 method_dict["Method"] = method->name();
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530149 method_dict["ArgName"] = arg_name;
150 out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000151 {
152 IndentScope raii_method_indent(out);
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530153 StringVector method_comments = method->GetAllComments();
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530154 PrintAllComments(method_comments, out);
Masood Malekghassemi832ae812016-04-27 18:38:54 -0700155 out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000156 }
157 }
158 }
159 return true;
160}
161
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530162bool PrivateGenerator::PrintBetaStub(const grpc_generator::Service* service,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530163 grpc_generator::Printer* out) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530164 StringMap service_dict;
165 service_dict["Service"] = service->name();
Ken Paysonbe187b02016-05-06 15:32:58 -0700166 out->Print("\n\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530167 out->Print(service_dict, "class Beta$Service$Stub(object):\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000168 {
169 IndentScope raii_class_indent(out);
Nicolas "Pixel" Noblebeeeddd2016-09-29 20:27:23 +0200170 out->Print(
171 "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
172 "\nIt is recommended to use the GA API (classes and functions in this\n"
173 "file not marked beta) for all further purposes. This class was "
174 "generated\n"
175 "only to ease transition from grpcio<0.15.0 to "
176 "grpcio>=0.15.0.\"\"\"\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530177 StringVector service_comments = service->GetAllComments();
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530178 PrintAllComments(service_comments, out);
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000179 for (int i = 0; i < service->method_count(); ++i) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530180 auto method = service->method(i);
Masood Malekghassemiac592452016-07-01 11:58:04 -0700181 grpc::string arg_name =
Harsh Vardhan974f3d72017-03-03 14:19:32 +0530182 method->ClientStreaming() ? "request_iterator" : "request";
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700183 StringMap method_dict;
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530184 method_dict["Method"] = method->name();
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700185 method_dict["ArgName"] = arg_name;
186 out->Print(method_dict,
Masood Malekghassemiac592452016-07-01 11:58:04 -0700187 "def $Method$(self, $ArgName$, timeout, metadata=None, "
188 "with_call=False, protocol_options=None):\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000189 {
190 IndentScope raii_method_indent(out);
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530191 StringVector method_comments = method->GetAllComments();
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530192 PrintAllComments(method_comments, out);
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000193 out->Print("raise NotImplementedError()\n");
194 }
Harsh Vardhan974f3d72017-03-03 14:19:32 +0530195 if (!method->ServerStreaming()) {
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700196 out->Print(method_dict, "$Method$.future = None\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000197 }
198 }
199 }
200 return true;
201}
202
Masood Malekghassemid9539592016-10-20 14:47:14 -0700203bool PrivateGenerator::PrintBetaServerFactory(
204 const grpc::string& package_qualified_service_name,
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530205 const grpc_generator::Service* service, grpc_generator::Printer* out) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530206 StringMap service_dict;
207 service_dict["Service"] = service->name();
Ken Paysonbe187b02016-05-06 15:32:58 -0700208 out->Print("\n\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530209 out->Print(service_dict,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530210 "def beta_create_$Service$_server(servicer, pool=None, "
211 "pool_size=None, default_timeout=None, maximum_timeout=None):\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000212 {
213 IndentScope raii_create_server_indent(out);
Nicolas "Pixel" Noblebeeeddd2016-09-29 20:27:23 +0200214 out->Print(
215 "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
216 "\nIt is recommended to use the GA API (classes and functions in this\n"
217 "file not marked beta) for all further purposes. This function was\n"
218 "generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
219 "\"\"\"\n");
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700220 StringMap method_implementation_constructors;
221 StringMap input_message_modules_and_classes;
222 StringMap output_message_modules_and_classes;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000223 for (int i = 0; i < service->method_count(); ++i) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530224 auto method = service->method(i);
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000225 const grpc::string method_implementation_constructor =
Harsh Vardhan974f3d72017-03-03 14:19:32 +0530226 grpc::string(method->ClientStreaming() ? "stream_" : "unary_") +
227 grpc::string(method->ServerStreaming() ? "stream_" : "unary_") +
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000228 "inline";
Ken Paysonbe187b02016-05-06 15:32:58 -0700229 grpc::string input_message_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530230 if (!method->get_module_and_message_path_input(
231 &input_message_module_and_class, generator_file_name,
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530232 generate_in_pb2_grpc, config.import_prefix)) {
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000233 return false;
234 }
Ken Paysonbe187b02016-05-06 15:32:58 -0700235 grpc::string output_message_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530236 if (!method->get_module_and_message_path_output(
237 &output_message_module_and_class, generator_file_name,
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530238 generate_in_pb2_grpc, config.import_prefix)) {
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000239 return false;
240 }
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000241 method_implementation_constructors.insert(
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530242 make_pair(method->name(), method_implementation_constructor));
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000243 input_message_modules_and_classes.insert(
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530244 make_pair(method->name(), input_message_module_and_class));
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000245 output_message_modules_and_classes.insert(
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530246 make_pair(method->name(), output_message_module_and_class));
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000247 }
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530248 StringMap method_dict;
249 method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000250 out->Print("request_deserializers = {\n");
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700251 for (StringMap::iterator name_and_input_module_class_pair =
Masood Malekghassemiac592452016-07-01 11:58:04 -0700252 input_message_modules_and_classes.begin();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000253 name_and_input_module_class_pair !=
Masood Malekghassemiac592452016-07-01 11:58:04 -0700254 input_message_modules_and_classes.end();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000255 name_and_input_module_class_pair++) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530256 method_dict["MethodName"] = name_and_input_module_class_pair->first;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530257 method_dict["InputTypeModuleAndClass"] =
258 name_and_input_module_class_pair->second;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000259 IndentScope raii_indent(out);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530260 out->Print(method_dict,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530261 "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
262 "$InputTypeModuleAndClass$.FromString,\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000263 }
264 out->Print("}\n");
265 out->Print("response_serializers = {\n");
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700266 for (StringMap::iterator name_and_output_module_class_pair =
Masood Malekghassemiac592452016-07-01 11:58:04 -0700267 output_message_modules_and_classes.begin();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000268 name_and_output_module_class_pair !=
Masood Malekghassemiac592452016-07-01 11:58:04 -0700269 output_message_modules_and_classes.end();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000270 name_and_output_module_class_pair++) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530271 method_dict["MethodName"] = name_and_output_module_class_pair->first;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530272 method_dict["OutputTypeModuleAndClass"] =
273 name_and_output_module_class_pair->second;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000274 IndentScope raii_indent(out);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530275 out->Print(method_dict,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530276 "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
277 "$OutputTypeModuleAndClass$.SerializeToString,\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000278 }
279 out->Print("}\n");
280 out->Print("method_implementations = {\n");
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700281 for (StringMap::iterator name_and_implementation_constructor =
Masood Malekghassemiac592452016-07-01 11:58:04 -0700282 method_implementation_constructors.begin();
283 name_and_implementation_constructor !=
284 method_implementation_constructors.end();
285 name_and_implementation_constructor++) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530286 method_dict["Method"] = name_and_implementation_constructor->first;
287 method_dict["Constructor"] = name_and_implementation_constructor->second;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000288 IndentScope raii_descriptions_indent(out);
289 const grpc::string method_name =
290 name_and_implementation_constructor->first;
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530291 out->Print(method_dict,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530292 "(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
293 "face_utilities.$Constructor$(servicer.$Method$),\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000294 }
295 out->Print("}\n");
Masood Malekghassemiac592452016-07-01 11:58:04 -0700296 out->Print(
297 "server_options = beta_implementations.server_options("
298 "request_deserializers=request_deserializers, "
299 "response_serializers=response_serializers, "
300 "thread_pool=pool, thread_pool_size=pool_size, "
301 "default_timeout=default_timeout, "
302 "maximum_timeout=maximum_timeout)\n");
303 out->Print(
304 "return beta_implementations.server(method_implementations, "
305 "options=server_options)\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000306 }
307 return true;
308}
309
Masood Malekghassemid9539592016-10-20 14:47:14 -0700310bool PrivateGenerator::PrintBetaStubFactory(
311 const grpc::string& package_qualified_service_name,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530312 const grpc_generator::Service* service, grpc_generator::Printer* out) {
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700313 StringMap dict;
Masood Malekghassemid9539592016-10-20 14:47:14 -0700314 dict["Service"] = service->name();
Ken Paysonbe187b02016-05-06 15:32:58 -0700315 out->Print("\n\n");
Masood Malekghassemiac592452016-07-01 11:58:04 -0700316 out->Print(dict,
317 "def beta_create_$Service$_stub(channel, host=None,"
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000318 " metadata_transformer=None, pool=None, pool_size=None):\n");
319 {
320 IndentScope raii_create_server_indent(out);
Nicolas "Pixel" Noblebeeeddd2016-09-29 20:27:23 +0200321 out->Print(
322 "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
323 "\nIt is recommended to use the GA API (classes and functions in this\n"
324 "file not marked beta) for all further purposes. This function was\n"
325 "generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
326 "\"\"\"\n");
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700327 StringMap method_cardinalities;
328 StringMap input_message_modules_and_classes;
329 StringMap output_message_modules_and_classes;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000330 for (int i = 0; i < service->method_count(); ++i) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530331 auto method = service->method(i);
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000332 const grpc::string method_cardinality =
Harsh Vardhan974f3d72017-03-03 14:19:32 +0530333 grpc::string(method->ClientStreaming() ? "STREAM" : "UNARY") + "_" +
334 grpc::string(method->ServerStreaming() ? "STREAM" : "UNARY");
Ken Paysonbe187b02016-05-06 15:32:58 -0700335 grpc::string input_message_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530336 if (!method->get_module_and_message_path_input(
337 &input_message_module_and_class, generator_file_name,
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530338 generate_in_pb2_grpc, config.import_prefix)) {
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000339 return false;
340 }
Ken Paysonbe187b02016-05-06 15:32:58 -0700341 grpc::string output_message_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530342 if (!method->get_module_and_message_path_output(
343 &output_message_module_and_class, generator_file_name,
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530344 generate_in_pb2_grpc, config.import_prefix)) {
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000345 return false;
346 }
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000347 method_cardinalities.insert(
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530348 make_pair(method->name(), method_cardinality));
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000349 input_message_modules_and_classes.insert(
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530350 make_pair(method->name(), input_message_module_and_class));
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000351 output_message_modules_and_classes.insert(
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530352 make_pair(method->name(), output_message_module_and_class));
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000353 }
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530354 StringMap method_dict;
355 method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000356 out->Print("request_serializers = {\n");
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700357 for (StringMap::iterator name_and_input_module_class_pair =
Masood Malekghassemiac592452016-07-01 11:58:04 -0700358 input_message_modules_and_classes.begin();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000359 name_and_input_module_class_pair !=
Masood Malekghassemiac592452016-07-01 11:58:04 -0700360 input_message_modules_and_classes.end();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000361 name_and_input_module_class_pair++) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530362 method_dict["MethodName"] = name_and_input_module_class_pair->first;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530363 method_dict["InputTypeModuleAndClass"] =
364 name_and_input_module_class_pair->second;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000365 IndentScope raii_indent(out);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530366 out->Print(method_dict,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530367 "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
368 "$InputTypeModuleAndClass$.SerializeToString,\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000369 }
370 out->Print("}\n");
371 out->Print("response_deserializers = {\n");
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700372 for (StringMap::iterator name_and_output_module_class_pair =
Masood Malekghassemiac592452016-07-01 11:58:04 -0700373 output_message_modules_and_classes.begin();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000374 name_and_output_module_class_pair !=
Masood Malekghassemiac592452016-07-01 11:58:04 -0700375 output_message_modules_and_classes.end();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000376 name_and_output_module_class_pair++) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530377 method_dict["MethodName"] = name_and_output_module_class_pair->first;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530378 method_dict["OutputTypeModuleAndClass"] =
379 name_and_output_module_class_pair->second;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000380 IndentScope raii_indent(out);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530381 out->Print(method_dict,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530382 "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
383 "$OutputTypeModuleAndClass$.FromString,\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000384 }
385 out->Print("}\n");
386 out->Print("cardinalities = {\n");
Masood Malekghassemi7780cc02016-10-24 15:30:05 -0700387 for (StringMap::iterator name_and_cardinality =
388 method_cardinalities.begin();
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000389 name_and_cardinality != method_cardinalities.end();
390 name_and_cardinality++) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530391 method_dict["Method"] = name_and_cardinality->first;
392 method_dict["Cardinality"] = name_and_cardinality->second;
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000393 IndentScope raii_descriptions_indent(out);
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530394 out->Print(method_dict,
395 "\'$Method$\': cardinality.Cardinality.$Cardinality$,\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000396 }
397 out->Print("}\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000398 out->Print(
Masood Malekghassemiac592452016-07-01 11:58:04 -0700399 "stub_options = beta_implementations.stub_options("
400 "host=host, metadata_transformer=metadata_transformer, "
401 "request_serializers=request_serializers, "
402 "response_deserializers=response_deserializers, "
403 "thread_pool=pool, thread_pool_size=pool_size)\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530404 out->Print(method_dict,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530405 "return beta_implementations.dynamic_stub(channel, "
406 "\'$PackageQualifiedServiceName$\', "
407 "cardinalities, options=stub_options)\n");
Nathaniel Manistacd9ec0e2015-08-31 07:49:45 +0000408 }
409 return true;
410}
411
Masood Malekghassemi7780cc02016-10-24 15:30:05 -0700412bool PrivateGenerator::PrintStub(
413 const grpc::string& package_qualified_service_name,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530414 const grpc_generator::Service* service, grpc_generator::Printer* out) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530415 StringMap dict;
416 dict["Service"] = service->name();
Nathaniel Manista45479402016-06-13 20:14:18 +0000417 out->Print("\n\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530418 out->Print(dict, "class $Service$Stub(object):\n");
Nathaniel Manista45479402016-06-13 20:14:18 +0000419 {
420 IndentScope raii_class_indent(out);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530421 StringVector service_comments = service->GetAllComments();
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530422 PrintAllComments(service_comments, out);
Nathaniel Manista45479402016-06-13 20:14:18 +0000423 out->Print("\n");
424 out->Print("def __init__(self, channel):\n");
425 {
426 IndentScope raii_init_indent(out);
427 out->Print("\"\"\"Constructor.\n");
428 out->Print("\n");
429 out->Print("Args:\n");
430 {
431 IndentScope raii_args_indent(out);
Masood Malekghassemiac592452016-07-01 11:58:04 -0700432 out->Print("channel: A grpc.Channel.\n");
Nathaniel Manista45479402016-06-13 20:14:18 +0000433 }
434 out->Print("\"\"\"\n");
435 for (int i = 0; i < service->method_count(); ++i) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530436 auto method = service->method(i);
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700437 grpc::string multi_callable_constructor =
Harsh Vardhan974f3d72017-03-03 14:19:32 +0530438 grpc::string(method->ClientStreaming() ? "stream" : "unary") + "_" +
439 grpc::string(method->ServerStreaming() ? "stream" : "unary");
Masood Malekghassemiac592452016-07-01 11:58:04 -0700440 grpc::string request_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530441 if (!method->get_module_and_message_path_input(
442 &request_module_and_class, generator_file_name,
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530443 generate_in_pb2_grpc, config.import_prefix)) {
Nathaniel Manista45479402016-06-13 20:14:18 +0000444 return false;
Masood Malekghassemiac592452016-07-01 11:58:04 -0700445 }
446 grpc::string response_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530447 if (!method->get_module_and_message_path_output(
448 &response_module_and_class, generator_file_name,
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530449 generate_in_pb2_grpc, config.import_prefix)) {
Masood Malekghassemiac592452016-07-01 11:58:04 -0700450 return false;
451 }
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530452 StringMap method_dict;
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530453 method_dict["Method"] = method->name();
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530454 method_dict["MultiCallableConstructor"] = multi_callable_constructor;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530455 out->Print(method_dict,
456 "self.$Method$ = channel.$MultiCallableConstructor$(\n");
Masood Malekghassemiac592452016-07-01 11:58:04 -0700457 {
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530458 method_dict["PackageQualifiedService"] =
459 package_qualified_service_name;
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530460 method_dict["RequestModuleAndClass"] = request_module_and_class;
461 method_dict["ResponseModuleAndClass"] = response_module_and_class;
Nathaniel Manista45479402016-06-13 20:14:18 +0000462 IndentScope raii_first_attribute_indent(out);
463 IndentScope raii_second_attribute_indent(out);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530464 out->Print(method_dict, "'/$PackageQualifiedService$/$Method$',\n");
465 out->Print(method_dict,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530466 "request_serializer=$RequestModuleAndClass$."
467 "SerializeToString,\n");
468 out->Print(
469 method_dict,
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530470 "response_deserializer=$ResponseModuleAndClass$.FromString,\n");
Masood Malekghassemiac592452016-07-01 11:58:04 -0700471 out->Print(")\n");
472 }
Nathaniel Manista45479402016-06-13 20:14:18 +0000473 }
474 }
475 }
476 return true;
477}
478
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530479bool PrivateGenerator::PrintServicer(const grpc_generator::Service* service,
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530480 grpc_generator::Printer* out) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530481 StringMap service_dict;
482 service_dict["Service"] = service->name();
Nathaniel Manista45479402016-06-13 20:14:18 +0000483 out->Print("\n\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530484 out->Print(service_dict, "class $Service$Servicer(object):\n");
Nathaniel Manista45479402016-06-13 20:14:18 +0000485 {
486 IndentScope raii_class_indent(out);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530487 StringVector service_comments = service->GetAllComments();
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530488 PrintAllComments(service_comments, out);
Nathaniel Manista45479402016-06-13 20:14:18 +0000489 for (int i = 0; i < service->method_count(); ++i) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530490 auto method = service->method(i);
Masood Malekghassemiac592452016-07-01 11:58:04 -0700491 grpc::string arg_name =
Harsh Vardhan974f3d72017-03-03 14:19:32 +0530492 method->ClientStreaming() ? "request_iterator" : "request";
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530493 StringMap method_dict;
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530494 method_dict["Method"] = method->name();
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530495 method_dict["ArgName"] = arg_name;
Nathaniel Manista45479402016-06-13 20:14:18 +0000496 out->Print("\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530497 out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
Nathaniel Manista45479402016-06-13 20:14:18 +0000498 {
499 IndentScope raii_method_indent(out);
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530500 StringVector method_comments = method->GetAllComments();
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530501 PrintAllComments(method_comments, out);
Nathaniel Manista45479402016-06-13 20:14:18 +0000502 out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
503 out->Print("context.set_details('Method not implemented!')\n");
504 out->Print("raise NotImplementedError('Method not implemented!')\n");
505 }
506 }
507 }
508 return true;
509}
510
Masood Malekghassemid9539592016-10-20 14:47:14 -0700511bool PrivateGenerator::PrintAddServicerToServer(
Masood Malekghassemiac592452016-07-01 11:58:04 -0700512 const grpc::string& package_qualified_service_name,
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530513 const grpc_generator::Service* service, grpc_generator::Printer* out) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530514 StringMap service_dict;
515 service_dict["Service"] = service->name();
Nathaniel Manista45479402016-06-13 20:14:18 +0000516 out->Print("\n\n");
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530517 out->Print(service_dict,
518 "def add_$Service$Servicer_to_server(servicer, server):\n");
Nathaniel Manista45479402016-06-13 20:14:18 +0000519 {
520 IndentScope raii_class_indent(out);
521 out->Print("rpc_method_handlers = {\n");
522 {
523 IndentScope raii_dict_first_indent(out);
524 IndentScope raii_dict_second_indent(out);
525 for (int i = 0; i < service->method_count(); ++i) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530526 auto method = service->method(i);
Masood Malekghassemi4a051cc2016-10-20 14:50:49 -0700527 grpc::string method_handler_constructor =
Harsh Vardhan974f3d72017-03-03 14:19:32 +0530528 grpc::string(method->ClientStreaming() ? "stream" : "unary") + "_" +
529 grpc::string(method->ServerStreaming() ? "stream" : "unary") +
Nathaniel Manista45479402016-06-13 20:14:18 +0000530 "_rpc_method_handler";
Masood Malekghassemiac592452016-07-01 11:58:04 -0700531 grpc::string request_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530532 if (!method->get_module_and_message_path_input(
533 &request_module_and_class, generator_file_name,
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530534 generate_in_pb2_grpc, config.import_prefix)) {
Nathaniel Manista45479402016-06-13 20:14:18 +0000535 return false;
Masood Malekghassemiac592452016-07-01 11:58:04 -0700536 }
537 grpc::string response_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530538 if (!method->get_module_and_message_path_output(
539 &response_module_and_class, generator_file_name,
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530540 generate_in_pb2_grpc, config.import_prefix)) {
Masood Malekghassemiac592452016-07-01 11:58:04 -0700541 return false;
542 }
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530543 StringMap method_dict;
Harsh Vardhan0f12cd92017-02-18 19:17:51 +0530544 method_dict["Method"] = method->name();
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530545 method_dict["MethodHandlerConstructor"] = method_handler_constructor;
546 method_dict["RequestModuleAndClass"] = request_module_and_class;
547 method_dict["ResponseModuleAndClass"] = response_module_and_class;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530548 out->Print(method_dict,
549 "'$Method$': grpc.$MethodHandlerConstructor$(\n");
Masood Malekghassemiac592452016-07-01 11:58:04 -0700550 {
Nathaniel Manista45479402016-06-13 20:14:18 +0000551 IndentScope raii_call_first_indent(out);
Masood Malekghassemiac592452016-07-01 11:58:04 -0700552 IndentScope raii_call_second_indent(out);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530553 out->Print(method_dict, "servicer.$Method$,\n");
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530554 out->Print(
555 method_dict,
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530556 "request_deserializer=$RequestModuleAndClass$.FromString,\n");
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530557 out->Print(
558 method_dict,
Masood Malekghassemiac592452016-07-01 11:58:04 -0700559 "response_serializer=$ResponseModuleAndClass$.SerializeToString,"
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530560 "\n");
Masood Malekghassemiac592452016-07-01 11:58:04 -0700561 }
562 out->Print("),\n");
Nathaniel Manista45479402016-06-13 20:14:18 +0000563 }
564 }
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530565 StringMap method_dict;
566 method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
Nathaniel Manista45479402016-06-13 20:14:18 +0000567 out->Print("}\n");
568 out->Print("generic_handler = grpc.method_handlers_generic_handler(\n");
569 {
570 IndentScope raii_call_first_indent(out);
571 IndentScope raii_call_second_indent(out);
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530572 out->Print(method_dict,
573 "'$PackageQualifiedServiceName$', rpc_method_handlers)\n");
Nathaniel Manista45479402016-06-13 20:14:18 +0000574 }
575 out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
576 }
577 return true;
578}
579
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530580bool PrivateGenerator::PrintBetaPreamble(grpc_generator::Printer* out) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530581 StringMap var;
582 var["Package"] = config.beta_package_root;
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530583 out->Print(var,
584 "from $Package$ import implementations as beta_implementations\n");
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530585 out->Print(var, "from $Package$ import interfaces as beta_interfaces\n");
Nathaniel Manista2f390db2017-03-22 16:57:48 +0000586 out->Print("from grpc.framework.common import cardinality\n");
587 out->Print(
588 "from grpc.framework.interfaces.face import utilities as "
589 "face_utilities\n");
Masood Malekghassemid9539592016-10-20 14:47:14 -0700590 return true;
591}
592
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530593bool PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530594 StringMap var;
595 var["Package"] = config.grpc_package_root;
596 out->Print(var, "import $Package$\n");
Masood Malekghassemid9539592016-10-20 14:47:14 -0700597 if (generate_in_pb2_grpc) {
598 out->Print("\n");
Bryan Blanchardc549a3e2016-12-13 07:46:28 -0500599 StringPairSet imports_set;
Masood Malekghassemid9539592016-10-20 14:47:14 -0700600 for (int i = 0; i < file->service_count(); ++i) {
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530601 auto service = file->service(i);
Masood Malekghassemid9539592016-10-20 14:47:14 -0700602 for (int j = 0; j < service->method_count(); ++j) {
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530603 auto method = service.get()->method(j);
604
605 grpc::string input_type_file_name = method->get_input_type_name();
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530606 grpc::string input_module_name =
607 ModuleName(input_type_file_name, config.import_prefix);
608 grpc::string input_module_alias =
609 ModuleAlias(input_type_file_name, config.import_prefix);
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530610 imports_set.insert(
611 std::make_tuple(input_module_name, input_module_alias));
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530612
613 grpc::string output_type_file_name = method->get_output_type_name();
Harsh Vardhanabf9ce22017-03-14 22:56:31 +0530614 grpc::string output_module_name =
615 ModuleName(output_type_file_name, config.import_prefix);
616 grpc::string output_module_alias =
617 ModuleAlias(output_type_file_name, config.import_prefix);
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530618 imports_set.insert(
619 std::make_tuple(output_module_name, output_module_alias));
Masood Malekghassemid9539592016-10-20 14:47:14 -0700620 }
621 }
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530622
Bryan Blanchardc549a3e2016-12-13 07:46:28 -0500623 for (StringPairSet::iterator it = imports_set.begin();
624 it != imports_set.end(); ++it) {
Manuel Kroiss65808942017-04-26 17:36:56 +0100625 auto module_name = std::get<0>(*it);
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530626 var["ModuleAlias"] = std::get<1>(*it);
Manuel Kroiss65808942017-04-26 17:36:56 +0100627 const size_t last_dot_pos = module_name.rfind('.');
628 if (last_dot_pos == grpc::string::npos) {
629 var["ImportStatement"] = "import " + module_name;
630 } else {
631 var["ImportStatement"] = "from " + module_name.substr(0, last_dot_pos) +
632 " import " +
633 module_name.substr(last_dot_pos + 1);
634 }
635 out->Print(var, "$ImportStatement$ as $ModuleAlias$\n");
Bryan Blanchardc549a3e2016-12-13 07:46:28 -0500636 }
Masood Malekghassemid9539592016-10-20 14:47:14 -0700637 }
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -0800638 return true;
Masood Malekghassemif8e297a2015-02-19 15:39:32 -0800639}
640
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530641bool PrivateGenerator::PrintGAServices(grpc_generator::Printer* out) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700642 grpc::string package = file->package();
643 if (!package.empty()) {
644 package = package.append(".");
645 }
646 for (int i = 0; i < file->service_count(); ++i) {
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530647 auto service = file->service(i);
Masood Malekghassemid9539592016-10-20 14:47:14 -0700648 grpc::string package_qualified_service_name = package + service->name();
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530649 if (!(PrintStub(package_qualified_service_name, service.get(), out) &&
650 PrintServicer(service.get(), out) &&
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530651 PrintAddServicerToServer(package_qualified_service_name,
652 service.get(), out))) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700653 return false;
654 }
655 }
656 return true;
657}
Masood Malekghassemif8e297a2015-02-19 15:39:32 -0800658
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530659bool PrivateGenerator::PrintBetaServices(grpc_generator::Printer* out) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700660 grpc::string package = file->package();
661 if (!package.empty()) {
662 package = package.append(".");
663 }
664 for (int i = 0; i < file->service_count(); ++i) {
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530665 auto service = file->service(i);
Masood Malekghassemid9539592016-10-20 14:47:14 -0700666 grpc::string package_qualified_service_name = package + service->name();
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530667 if (!(PrintBetaServicer(service.get(), out) &&
668 PrintBetaStub(service.get(), out) &&
669 PrintBetaServerFactory(package_qualified_service_name, service.get(),
670 out) &&
671 PrintBetaStubFactory(package_qualified_service_name, service.get(),
672 out))) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700673 return false;
674 }
675 }
676 return true;
677}
Harsh Vardhan4b0ba1a2017-02-25 20:54:52 +0530678
Masood Malekghassemid9539592016-10-20 14:47:14 -0700679pair<bool, grpc::string> PrivateGenerator::GetGrpcServices() {
Masood Malekghassemi65c803b2015-03-20 06:48:47 -0700680 grpc::string output;
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -0800681 {
682 // Scope the output stream so it closes and finalizes output to the string.
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530683 auto out = file->CreatePrinter(&output);
Masood Malekghassemid9539592016-10-20 14:47:14 -0700684 if (generate_in_pb2_grpc) {
Masood Malekghassemi0d62d7e2016-12-28 14:28:44 -0800685 out->Print(
686 "# Generated by the gRPC Python protocol compiler plugin. "
687 "DO NOT EDIT!\n");
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530688 if (!PrintPreamble(out.get())) {
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -0800689 return make_pair(false, "");
690 }
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530691 if (!PrintGAServices(out.get())) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700692 return make_pair(false, "");
693 }
694 } else {
695 out->Print("try:\n");
696 {
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530697 IndentScope raii_dict_try_indent(out.get());
Masood Malekghassemi7780cc02016-10-24 15:30:05 -0700698 out->Print(
699 "# THESE ELEMENTS WILL BE DEPRECATED.\n"
700 "# Please use the generated *_pb2_grpc.py files instead.\n");
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530701 if (!PrintPreamble(out.get())) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700702 return make_pair(false, "");
703 }
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530704 if (!PrintBetaPreamble(out.get())) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700705 return make_pair(false, "");
706 }
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530707 if (!PrintGAServices(out.get())) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700708 return make_pair(false, "");
709 }
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530710 if (!PrintBetaServices(out.get())) {
Masood Malekghassemid9539592016-10-20 14:47:14 -0700711 return make_pair(false, "");
712 }
713 }
714 out->Print("except ImportError:\n");
715 {
Harsh Vardhan6a9950d2017-02-07 12:01:44 +0530716 IndentScope raii_dict_except_indent(out.get());
Masood Malekghassemid9539592016-10-20 14:47:14 -0700717 out->Print("pass");
718 }
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -0800719 }
Masood Malekghassemif8e297a2015-02-19 15:39:32 -0800720 }
Masood Malekghassemi59d9ff42015-02-23 15:28:07 -0800721 return make_pair(true, std::move(output));
Masood Malekghassemif8e297a2015-02-19 15:39:32 -0800722}
723
Masood Malekghassemid9539592016-10-20 14:47:14 -0700724} // namespace
725
726GeneratorConfiguration::GeneratorConfiguration()
Nathaniel Manista40d55f92017-03-14 00:01:35 +0000727 : grpc_package_root("grpc"),
728 beta_package_root("grpc.beta"),
729 import_prefix("") {}
Masood Malekghassemid9539592016-10-20 14:47:14 -0700730
731PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
732 : config_(config) {}
733
734PythonGrpcGenerator::~PythonGrpcGenerator() {}
735
Masood Malekghassemi561dce42016-11-30 20:20:32 -0800736static bool GenerateGrpc(GeneratorContext* context, PrivateGenerator& generator,
737 grpc::string file_name, bool generate_in_pb2_grpc) {
738 bool success;
739 std::unique_ptr<ZeroCopyOutputStream> output;
740 std::unique_ptr<CodedOutputStream> coded_output;
741 grpc::string grpc_code;
742
743 if (generate_in_pb2_grpc) {
744 output.reset(context->Open(file_name));
745 generator.generate_in_pb2_grpc = true;
746 } else {
747 output.reset(context->OpenForInsert(file_name, "module_scope"));
748 generator.generate_in_pb2_grpc = false;
749 }
750
751 coded_output.reset(new CodedOutputStream(output.get()));
752 tie(success, grpc_code) = generator.GetGrpcServices();
753
754 if (success) {
755 coded_output->WriteRaw(grpc_code.data(), grpc_code.size());
756 return true;
757 } else {
758 return false;
759 }
760}
761
Masood Malekghassemid9539592016-10-20 14:47:14 -0700762bool PythonGrpcGenerator::Generate(const FileDescriptor* file,
763 const grpc::string& parameter,
764 GeneratorContext* context,
765 grpc::string* error) const {
766 // Get output file name.
767 grpc::string pb2_file_name;
768 grpc::string pb2_grpc_file_name;
769 static const int proto_suffix_length = strlen(".proto");
770 if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
771 file->name().find_last_of(".proto") == file->name().size() - 1) {
Masood Malekghassemi7780cc02016-10-24 15:30:05 -0700772 grpc::string base =
773 file->name().substr(0, file->name().size() - proto_suffix_length);
Masood Malekghassemid9539592016-10-20 14:47:14 -0700774 pb2_file_name = base + "_pb2.py";
775 pb2_grpc_file_name = base + "_pb2_grpc.py";
776 } else {
777 *error = "Invalid proto file name. Proto file must end with .proto";
778 return false;
779 }
Harsh Vardhan93077ae2016-12-26 18:23:45 +0530780 generator_file_name = file->name();
Masood Malekghassemid9539592016-10-20 14:47:14 -0700781
Harsh Vardhan64741b22017-01-14 15:19:09 +0530782 ProtoBufFile pbfile(file);
783 PrivateGenerator generator(config_, &pbfile);
Masood Malekghassemi561dce42016-11-30 20:20:32 -0800784 if (parameter == "grpc_2_0") {
785 return GenerateGrpc(context, generator, pb2_grpc_file_name, true);
786 } else if (parameter == "") {
787 return GenerateGrpc(context, generator, pb2_grpc_file_name, true) &&
788 GenerateGrpc(context, generator, pb2_file_name, false);
789 } else {
790 *error = "Invalid parameter '" + parameter + "'.";
791 return false;
Masood Malekghassemid9539592016-10-20 14:47:14 -0700792 }
Masood Malekghassemid9539592016-10-20 14:47:14 -0700793}
794
Masood Malekghassemif8e297a2015-02-19 15:39:32 -0800795} // namespace grpc_python_generator