• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <map>
20 #include <sstream>
21 
22 #include "flatbuffers/util.h"
23 #include "src/compiler/python_generator.h"
24 
25 namespace grpc_python_generator {
26 
GenerateMethodType(const grpc_generator::Method * method)27 grpc::string GenerateMethodType(const grpc_generator::Method *method) {
28 
29   if (method->NoStreaming())
30     return "unary_unary";
31 
32   if (method->ServerStreaming())
33     return "unary_stream";
34 
35   if (method->ClientStreaming())
36     return "stream_unary";
37 
38   return "stream_stream";
39 }
40 
GenerateMethodInput(const grpc_generator::Method * method)41 grpc::string GenerateMethodInput(const grpc_generator::Method *method) {
42 
43   if (method->NoStreaming() || method->ServerStreaming())
44     return "self, request, context";
45 
46   return "self, request_iterator, context";
47 }
48 
GenerateStub(const grpc_generator::Service * service,grpc_generator::Printer * printer,std::map<grpc::string,grpc::string> * dictonary)49 void GenerateStub(const grpc_generator::Service *service,
50                   grpc_generator::Printer *printer,
51                   std::map<grpc::string, grpc::string> *dictonary) {
52   auto vars = *dictonary;
53   printer->Print(vars, "class $ServiceName$Stub(object):\n");
54   printer->Indent();
55   printer->Print("\"\"\" Interface exported by the server. \"\"\"");
56   printer->Print("\n\n");
57   printer->Print("def __init__(self, channel):\n");
58   printer->Indent();
59   printer->Print("\"\"\" Constructor. \n\n");
60   printer->Print("Args: \n");
61   printer->Print("channel: A grpc.Channel. \n");
62   printer->Print("\"\"\"\n\n");
63 
64   for (int j = 0; j < service->method_count(); j++) {
65     auto method = service->method(j);
66     vars["MethodName"] = method->name();
67     vars["MethodType"] = GenerateMethodType(&*method);
68     printer->Print(vars, "self.$MethodName$ = channel.$MethodType$(\n");
69     printer->Indent();
70     printer->Print(vars, "\"/$PATH$$ServiceName$/$MethodName$\"\n");
71     printer->Print(")\n");
72     printer->Outdent();
73     printer->Print("\n");
74   }
75   printer->Outdent();
76   printer->Outdent();
77   printer->Print("\n");
78 }
79 
GenerateServicer(const grpc_generator::Service * service,grpc_generator::Printer * printer,std::map<grpc::string,grpc::string> * dictonary)80 void GenerateServicer(const grpc_generator::Service *service,
81                       grpc_generator::Printer *printer,
82                       std::map<grpc::string, grpc::string> *dictonary) {
83   auto vars = *dictonary;
84   printer->Print(vars, "class $ServiceName$Servicer(object):\n");
85   printer->Indent();
86   printer->Print("\"\"\" Interface exported by the server. \"\"\"");
87   printer->Print("\n\n");
88 
89   for (int j = 0; j < service->method_count(); j++) {
90     auto method = service->method(j);
91     vars["MethodName"] = method->name();
92     vars["MethodInput"] = GenerateMethodInput(&*method);
93     printer->Print(vars, "def $MethodName$($MethodInput$):\n");
94     printer->Indent();
95     printer->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
96     printer->Print("context.set_details('Method not implemented!')\n");
97     printer->Print("raise NotImplementedError('Method not implemented!')\n");
98     printer->Outdent();
99     printer->Print("\n\n");
100   }
101   printer->Outdent();
102   printer->Print("\n");
103 
104 }
105 
GenerateRegister(const grpc_generator::Service * service,grpc_generator::Printer * printer,std::map<grpc::string,grpc::string> * dictonary)106 void GenerateRegister(const grpc_generator::Service *service,
107                       grpc_generator::Printer *printer,
108                       std::map<grpc::string, grpc::string> *dictonary) {
109   auto vars = *dictonary;
110   printer->Print(vars, "def add_$ServiceName$Servicer_to_server(servicer, server):\n");
111   printer->Indent();
112   printer->Print("rpc_method_handlers = {\n");
113   printer->Indent();
114   for (int j = 0; j < service->method_count(); j++) {
115     auto method = service->method(j);
116     vars["MethodName"] = method->name();
117     vars["MethodType"] = GenerateMethodType(&*method);
118     printer->Print(vars, "'$MethodName$': grpc.$MethodType$_rpc_method_handler(\n");
119     printer->Indent();
120     printer->Print(vars, "servicer.$MethodName$\n");
121     printer->Outdent();
122     printer->Print("),\n");
123   }
124   printer->Outdent();
125   printer->Print("}\n");
126   printer->Print(vars, "generic_handler = grpc.method_handlers_generic_handler(\n");
127   printer->Indent();
128   printer->Print(vars, "'$PATH$$ServiceName$', rpc_method_handlers)\n");
129   printer->Outdent();
130   printer->Print("server.add_generic_rpc_handlers((generic_handler,))");
131   printer->Outdent();
132   printer->Print("\n");
133 }
134 
Generate(grpc_generator::File * file,const grpc_generator::Service * service)135 grpc::string Generate(grpc_generator::File *file,
136                       const grpc_generator::Service *service) {
137   grpc::string output;
138   std::map<grpc::string, grpc::string> vars;
139   vars["PATH"] = file->package();
140   if (!file->package().empty()) { vars["PATH"].append("."); }
141   vars["ServiceName"] = service->name();
142   auto printer = file->CreatePrinter(&output);
143   GenerateStub(service, &*printer, &vars);
144   GenerateServicer(service, &*printer, &vars);
145   GenerateRegister(service, &*printer, &vars);
146   return output;
147 }
148 
149 }  // namespace grpc_python_generator
150