blob: acac1475f7c174b8c439cd69bf2cf8c72b0fa4ff [file] [log] [blame]
nnobleebebb7e2014-12-10 16:31:01 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
nnobleebebb7e2014-12-10 16:31:01 -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
Nicolas "Pixel" Noble36f53232015-01-16 06:39:58 +010034#include <map>
35
nnobleebebb7e2014-12-10 16:31:01 -080036#include "src/compiler/cpp_generator.h"
nnobleebebb7e2014-12-10 16:31:01 -080037#include "src/compiler/cpp_generator_helpers.h"
Nicolas Nobled446eb82015-03-12 17:22:33 -070038
39#include "src/compiler/config.h"
40
Craig Tiller8c8d0aa2015-02-12 11:38:36 -080041#include <sstream>
nnobleebebb7e2014-12-10 16:31:01 -080042
43namespace grpc_cpp_generator {
44namespace {
45
Craig Tiller8c8d0aa2015-02-12 11:38:36 -080046template <class T>
Nicolas Nobled446eb82015-03-12 17:22:33 -070047grpc::string as_string(T x) {
Craig Tiller8c8d0aa2015-02-12 11:38:36 -080048 std::ostringstream out;
49 out << x;
50 return out.str();
51}
52
Nicolas Nobled446eb82015-03-12 17:22:33 -070053bool NoStreaming(const grpc::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080054 return !method->client_streaming() && !method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080055}
56
Nicolas Nobled446eb82015-03-12 17:22:33 -070057bool ClientOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080058 return method->client_streaming() && !method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080059}
60
Nicolas Nobled446eb82015-03-12 17:22:33 -070061bool ServerOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
yangg1b151092015-01-09 15:31:05 -080062 return !method->client_streaming() && method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080063}
64
Nicolas Nobled446eb82015-03-12 17:22:33 -070065bool BidiStreaming(const grpc::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080066 return method->client_streaming() && method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080067}
68
Craig Tiller277d3cf2015-04-14 14:04:51 -070069grpc::string FilenameIdentifier(const grpc::string &filename) {
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +020070 grpc::string result;
71 for (unsigned i = 0; i < filename.size(); i++) {
72 char c = filename[i];
73 if (isalnum(c)) {
74 result.push_back(c);
75 } else {
76 static char hex[] = "0123456789abcdef";
77 result.push_back('_');
78 result.push_back(hex[(c >> 4) & 0xf]);
79 result.push_back(hex[c & 0xf]);
80 }
81 }
82 return result;
83}
nnobleebebb7e2014-12-10 16:31:01 -080084} // namespace
85
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +020086grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
87 const Parameters &params) {
88 grpc::string output;
89 grpc::protobuf::io::StringOutputStream output_stream(&output);
90 grpc::protobuf::io::Printer printer(&output_stream, '$');
91 std::map<grpc::string, grpc::string> vars;
92
93 vars["filename"] = file->name();
94 vars["filename_identifier"] = FilenameIdentifier(file->name());
95 vars["filename_base"] = grpc_generator::StripProto(file->name());
96
97 printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
98 printer.Print(vars, "// If you make any local change, they will be lost.\n");
99 printer.Print(vars, "// source: $filename$\n");
100 printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
101 printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
102 printer.Print(vars, "\n");
103 printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
104 printer.Print(vars, "\n");
105
106 return output;
107}
108
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100109grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
110 const Parameters &params) {
Nicolas Nobled446eb82015-03-12 17:22:33 -0700111 grpc::string temp =
Craig Tiller14a65f92015-02-09 13:13:14 -0800112 "#include <grpc++/impl/internal_stub.h>\n"
Craig Tillerbd6c6182015-04-10 17:08:15 -0700113 "#include <grpc++/impl/rpc_method.h>\n"
Craig Tiller14a65f92015-02-09 13:13:14 -0800114 "#include <grpc++/impl/service_type.h>\n"
Yang Gaoc6924c82015-05-05 10:42:51 -0700115 "#include <grpc++/async_unary_call.h>\n"
Craig Tiller14a65f92015-02-09 13:13:14 -0800116 "#include <grpc++/status.h>\n"
Yang Gaoc6924c82015-05-05 10:42:51 -0700117 "#include <grpc++/stream.h>\n"
nnobleebebb7e2014-12-10 16:31:01 -0800118 "\n"
119 "namespace grpc {\n"
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800120 "class CompletionQueue;\n"
nnobleebebb7e2014-12-10 16:31:01 -0800121 "class ChannelInterface;\n"
yangga4b6f5d2014-12-17 15:53:12 -0800122 "class RpcService;\n"
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700123 "class ServerCompletionQueue;\n"
Yang Gaoc6924c82015-05-05 10:42:51 -0700124 "class ServerContext;\n"
125 "} // namespace grpc\n\n";
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200126
Yang Gao1dc1a432015-04-10 13:53:11 -0700127 if (!file->package().empty()) {
128 std::vector<grpc::string> parts =
129 grpc_generator::tokenize(file->package(), ".");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200130
Yang Gao1dc1a432015-04-10 13:53:11 -0700131 for (auto part = parts.begin(); part != parts.end(); part++) {
132 temp.append("namespace ");
133 temp.append(*part);
134 temp.append(" {\n");
135 }
136 temp.append("\n");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200137 }
138
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200139 return temp;
nnobleebebb7e2014-12-10 16:31:01 -0800140}
141
Yang Gaoc6924c82015-05-05 10:42:51 -0700142void PrintHeaderClientMethodInterfaces(grpc::protobuf::io::Printer *printer,
Nicolas Nobled446eb82015-03-12 17:22:33 -0700143 const grpc::protobuf::MethodDescriptor *method,
Yang Gao72e0fb82015-05-01 16:24:07 -0700144 std::map<grpc::string, grpc::string> *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700145 bool is_public) {
nnobleebebb7e2014-12-10 16:31:01 -0800146 (*vars)["Method"] = method->name();
147 (*vars)["Request"] =
148 grpc_cpp_generator::ClassName(method->input_type(), true);
149 (*vars)["Response"] =
150 grpc_cpp_generator::ClassName(method->output_type(), true);
Yang Gaoc6924c82015-05-05 10:42:51 -0700151
152 if (is_public) {
153 if (NoStreaming(method)) {
154 printer->Print(
155 *vars,
156 "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
157 "const $Request$& request, $Response$* response) = 0;\n");
158 printer->Print(
159 *vars,
160 "std::unique_ptr< "
161 "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
162 "Async$Method$(::grpc::ClientContext* context, "
163 "const $Request$& request, "
Craig Tiller5f871ac2015-05-08 13:05:51 -0700164 "::grpc::CompletionQueue* cq) {\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700165 printer->Indent();
166 printer->Print(
167 *vars,
168 "return std::unique_ptr< "
169 "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
Craig Tiller5f871ac2015-05-08 13:05:51 -0700170 "Async$Method$Raw(context, request, cq));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700171 printer->Outdent();
172 printer->Print("}\n");
173 } else if (ClientOnlyStreaming(method)) {
174 printer->Print(
175 *vars,
176 "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
177 " $Method$("
178 "::grpc::ClientContext* context, $Response$* response) {\n");
179 printer->Indent();
180 printer->Print(
181 *vars,
182 "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
183 "($Method$Raw(context, response));\n");
184 printer->Outdent();
185 printer->Print("}\n");
186 printer->Print(
187 *vars,
188 "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
189 " Async$Method$(::grpc::ClientContext* context, $Response$* response, "
190 "::grpc::CompletionQueue* cq, void* tag) {\n");
191 printer->Indent();
192 printer->Print(
193 *vars,
194 "return std::unique_ptr< "
195 "::grpc::ClientAsyncWriterInterface< $Request$>>("
196 "Async$Method$Raw(context, response, cq, tag));\n");
197 printer->Outdent();
198 printer->Print("}\n");
199 } else if (ServerOnlyStreaming(method)) {
200 printer->Print(
201 *vars,
202 "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
203 " $Method$(::grpc::ClientContext* context, const $Request$& request)"
204 " {\n");
205 printer->Indent();
206 printer->Print(
207 *vars,
208 "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
209 "($Method$Raw(context, request));\n");
210 printer->Outdent();
211 printer->Print("}\n");
212 printer->Print(
213 *vars,
214 "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
215 "Async$Method$("
216 "::grpc::ClientContext* context, const $Request$& request, "
217 "::grpc::CompletionQueue* cq, void* tag) {\n");
218 printer->Indent();
219 printer->Print(
220 *vars,
221 "return std::unique_ptr< "
222 "::grpc::ClientAsyncReaderInterface< $Response$>>("
223 "Async$Method$Raw(context, request, cq, tag));\n");
224 printer->Outdent();
225 printer->Print("}\n");
226 } else if (BidiStreaming(method)) {
227 printer->Print(
228 *vars,
229 "std::unique_ptr< ::grpc::ClientReaderWriterInterface< $Request$, $Response$>> "
230 "$Method$(::grpc::ClientContext* context) {\n");
231 printer->Indent();
232 printer->Print(
233 *vars,
234 "return std::unique_ptr< "
235 "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
236 "$Method$Raw(context));\n");
237 printer->Outdent();
238 printer->Print("}\n");
239 printer->Print(
240 *vars,
241 "std::unique_ptr< "
242 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
243 "Async$Method$(::grpc::ClientContext* context, "
244 "::grpc::CompletionQueue* cq, void* tag) {\n");
245 printer->Indent();
246 printer->Print(
247 *vars,
248 "return std::unique_ptr< "
249 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
250 "Async$Method$Raw(context, cq, tag));\n");
251 printer->Outdent();
252 printer->Print("}\n");
253 }
254 } else {
255 if (NoStreaming(method)) {
256 printer->Print(
257 *vars,
258 "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
259 "Async$Method$Raw(::grpc::ClientContext* context, "
260 "const $Request$& request, "
Craig Tiller5f871ac2015-05-08 13:05:51 -0700261 "::grpc::CompletionQueue* cq) = 0;\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700262 } else if (ClientOnlyStreaming(method)) {
263 printer->Print(
264 *vars,
265 "virtual ::grpc::ClientWriterInterface< $Request$>*"
266 " $Method$Raw("
267 "::grpc::ClientContext* context, $Response$* response) = 0;\n");
268 printer->Print(
269 *vars,
270 "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
271 " Async$Method$Raw(::grpc::ClientContext* context, "
272 "$Response$* response, "
273 "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
274 } else if (ServerOnlyStreaming(method)) {
275 printer->Print(
276 *vars,
277 "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
278 "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
279 printer->Print(
280 *vars,
281 "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
282 "Async$Method$Raw("
283 "::grpc::ClientContext* context, const $Request$& request, "
284 "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
285 } else if (BidiStreaming(method)) {
286 printer->Print(
287 *vars,
288 "virtual ::grpc::ClientReaderWriterInterface< $Request$, $Response$>* "
289 "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
290 printer->Print(
291 *vars,
292 "virtual ::grpc::ClientAsyncReaderWriterInterface< "
293 "$Request$, $Response$>* "
294 "Async$Method$Raw(::grpc::ClientContext* context, "
295 "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
296 }
297 }
298}
299
300void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
301 const grpc::protobuf::MethodDescriptor *method,
302 std::map<grpc::string, grpc::string> *vars,
303 bool is_public) {
304 (*vars)["Method"] = method->name();
305 (*vars)["Request"] =
306 grpc_cpp_generator::ClassName(method->input_type(), true);
307 (*vars)["Response"] =
308 grpc_cpp_generator::ClassName(method->output_type(), true);
Yang Gaoc6924c82015-05-05 10:42:51 -0700309 if (is_public) {
310 if (NoStreaming(method)) {
311 printer->Print(
312 *vars,
313 "::grpc::Status $Method$(::grpc::ClientContext* context, "
314 "const $Request$& request, $Response$* response) GRPC_OVERRIDE;\n");
315 printer->Print(
316 *vars,
317 "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
318 "Async$Method$(::grpc::ClientContext* context, "
319 "const $Request$& request, "
Craig Tiller5f871ac2015-05-08 13:05:51 -0700320 "::grpc::CompletionQueue* cq) {\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700321 printer->Indent();
322 printer->Print(
323 *vars,
324 "return std::unique_ptr< "
325 "::grpc::ClientAsyncResponseReader< $Response$>>("
Craig Tiller5f871ac2015-05-08 13:05:51 -0700326 "Async$Method$Raw(context, request, cq));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700327 printer->Outdent();
328 printer->Print("}\n");
329 } else if (ClientOnlyStreaming(method)) {
330 printer->Print(
331 *vars,
332 "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
333 " $Method$("
334 "::grpc::ClientContext* context, $Response$* response) {\n");
335 printer->Indent();
336 printer->Print(
337 *vars,
338 "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
339 "($Method$Raw(context, response));\n");
340 printer->Outdent();
341 printer->Print("}\n");
342 printer->Print(
343 *vars,
344 "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
345 " Async$Method$(::grpc::ClientContext* context, $Response$* response, "
346 "::grpc::CompletionQueue* cq, void* tag) {\n");
347 printer->Indent();
348 printer->Print(
349 *vars,
350 "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
351 "Async$Method$Raw(context, response, cq, tag));\n");
352 printer->Outdent();
353 printer->Print("}\n");
354 } else if (ServerOnlyStreaming(method)) {
355 printer->Print(
356 *vars,
357 "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
358 " $Method$(::grpc::ClientContext* context, const $Request$& request)"
359 " {\n");
360 printer->Indent();
361 printer->Print(
362 *vars,
363 "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
364 "($Method$Raw(context, request));\n");
365 printer->Outdent();
366 printer->Print("}\n");
367 printer->Print(
368 *vars,
369 "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
370 "Async$Method$("
371 "::grpc::ClientContext* context, const $Request$& request, "
372 "::grpc::CompletionQueue* cq, void* tag) {\n");
373 printer->Indent();
374 printer->Print(
375 *vars,
376 "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
377 "Async$Method$Raw(context, request, cq, tag));\n");
378 printer->Outdent();
379 printer->Print("}\n");
380 } else if (BidiStreaming(method)) {
381 printer->Print(
382 *vars,
383 "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
384 " $Method$(::grpc::ClientContext* context) {\n");
385 printer->Indent();
386 printer->Print(
387 *vars,
388 "return std::unique_ptr< "
389 "::grpc::ClientReaderWriter< $Request$, $Response$>>("
390 "$Method$Raw(context));\n");
391 printer->Outdent();
392 printer->Print("}\n");
393 printer->Print(
394 *vars,
395 "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
396 "$Request$, $Response$>> "
397 "Async$Method$(::grpc::ClientContext* context, "
398 "::grpc::CompletionQueue* cq, void* tag) {\n");
399 printer->Indent();
400 printer->Print(
401 *vars,
402 "return std::unique_ptr< "
403 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
404 "Async$Method$Raw(context, cq, tag));\n");
405 printer->Outdent();
406 printer->Print("}\n");
407 }
408 } else {
409 if (NoStreaming(method)) {
410 printer->Print(
411 *vars,
412 "::grpc::ClientAsyncResponseReader< $Response$>* "
413 "Async$Method$Raw(::grpc::ClientContext* context, "
414 "const $Request$& request, "
Craig Tiller5f871ac2015-05-08 13:05:51 -0700415 "::grpc::CompletionQueue* cq) GRPC_OVERRIDE;\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700416 } else if (ClientOnlyStreaming(method)) {
417 printer->Print(
418 *vars,
419 "::grpc::ClientWriter< $Request$>* $Method$Raw("
420 "::grpc::ClientContext* context, $Response$* response) "
421 "GRPC_OVERRIDE;\n");
422 printer->Print(
423 *vars,
424 "::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
425 "::grpc::ClientContext* context, $Response$* response, "
426 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
427 } else if (ServerOnlyStreaming(method)) {
428 printer->Print(
429 *vars,
430 "::grpc::ClientReader< $Response$>* $Method$Raw("
431 "::grpc::ClientContext* context, const $Request$& request)"
432 " GRPC_OVERRIDE;\n");
433 printer->Print(
434 *vars,
435 "::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw("
436 "::grpc::ClientContext* context, const $Request$& request, "
437 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
438 } else if (BidiStreaming(method)) {
439 printer->Print(
440 *vars,
441 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
442 "$Method$Raw(::grpc::ClientContext* context) GRPC_OVERRIDE;\n");
443 printer->Print(
444 *vars,
445 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
446 "Async$Method$Raw(::grpc::ClientContext* context, "
447 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
448 }
nnobleebebb7e2014-12-10 16:31:01 -0800449 }
450}
451
Craig Tillerbd6c6182015-04-10 17:08:15 -0700452void PrintHeaderClientMethodData(grpc::protobuf::io::Printer *printer,
453 const grpc::protobuf::MethodDescriptor *method,
454 std::map<grpc::string, grpc::string> *vars) {
455 (*vars)["Method"] = method->name();
456 printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
457}
458
Craig Tiller277d3cf2015-04-14 14:04:51 -0700459void PrintHeaderServerMethodSync(grpc::protobuf::io::Printer *printer,
460 const grpc::protobuf::MethodDescriptor *method,
461 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800462 (*vars)["Method"] = method->name();
463 (*vars)["Request"] =
464 grpc_cpp_generator::ClassName(method->input_type(), true);
465 (*vars)["Response"] =
466 grpc_cpp_generator::ClassName(method->output_type(), true);
467 if (NoStreaming(method)) {
468 printer->Print(*vars,
yangga4b6f5d2014-12-17 15:53:12 -0800469 "virtual ::grpc::Status $Method$("
470 "::grpc::ServerContext* context, const $Request$* request, "
nnobleebebb7e2014-12-10 16:31:01 -0800471 "$Response$* response);\n");
472 } else if (ClientOnlyStreaming(method)) {
473 printer->Print(*vars,
474 "virtual ::grpc::Status $Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800475 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800476 "::grpc::ServerReader< $Request$>* reader, "
nnobleebebb7e2014-12-10 16:31:01 -0800477 "$Response$* response);\n");
478 } else if (ServerOnlyStreaming(method)) {
479 printer->Print(*vars,
yangga4b6f5d2014-12-17 15:53:12 -0800480 "virtual ::grpc::Status $Method$("
481 "::grpc::ServerContext* context, const $Request$* request, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800482 "::grpc::ServerWriter< $Response$>* writer);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800483 } else if (BidiStreaming(method)) {
Yang Gao5680ff42015-01-14 12:14:21 -0800484 printer->Print(
485 *vars,
486 "virtual ::grpc::Status $Method$("
487 "::grpc::ServerContext* context, "
488 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
489 "\n");
nnobleebebb7e2014-12-10 16:31:01 -0800490 }
491}
492
Craig Tiller5ef5db12015-02-09 12:47:21 -0800493void PrintHeaderServerMethodAsync(
Nicolas Nobled446eb82015-03-12 17:22:33 -0700494 grpc::protobuf::io::Printer *printer,
495 const grpc::protobuf::MethodDescriptor *method,
496 std::map<grpc::string, grpc::string> *vars) {
Craig Tiller2dff17d2015-02-09 12:42:23 -0800497 (*vars)["Method"] = method->name();
498 (*vars)["Request"] =
499 grpc_cpp_generator::ClassName(method->input_type(), true);
500 (*vars)["Response"] =
501 grpc_cpp_generator::ClassName(method->output_type(), true);
502 if (NoStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700503 printer->Print(
504 *vars,
505 "void Request$Method$("
506 "::grpc::ServerContext* context, $Request$* request, "
507 "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
508 "::grpc::CompletionQueue* new_call_cq, "
509 "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800510 } else if (ClientOnlyStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700511 printer->Print(
512 *vars,
513 "void Request$Method$("
514 "::grpc::ServerContext* context, "
515 "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
516 "::grpc::CompletionQueue* new_call_cq, "
517 "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800518 } else if (ServerOnlyStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700519 printer->Print(
520 *vars,
521 "void Request$Method$("
522 "::grpc::ServerContext* context, $Request$* request, "
523 "::grpc::ServerAsyncWriter< $Response$>* writer, "
524 "::grpc::CompletionQueue* new_call_cq, "
525 "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800526 } else if (BidiStreaming(method)) {
527 printer->Print(
528 *vars,
Yang Gaoca3cb3e2015-02-12 00:05:11 -0800529 "void Request$Method$("
Craig Tiller2dff17d2015-02-09 12:42:23 -0800530 "::grpc::ServerContext* context, "
Craig Tiller225f7be2015-02-09 22:32:37 -0800531 "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700532 "::grpc::CompletionQueue* new_call_cq, "
533 "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800534 }
535}
536
Nicolas Nobled446eb82015-03-12 17:22:33 -0700537void PrintHeaderService(grpc::protobuf::io::Printer *printer,
538 const grpc::protobuf::ServiceDescriptor *service,
539 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800540 (*vars)["Service"] = service->name();
541
542 printer->Print(*vars,
Craig Tillercf133f42015-02-26 14:05:56 -0800543 "class $Service$ GRPC_FINAL {\n"
nnobleebebb7e2014-12-10 16:31:01 -0800544 " public:\n");
545 printer->Indent();
546
547 // Client side
Craig Tillerb5dcec52015-01-13 11:13:42 -0800548 printer->Print(
Yang Gao72e0fb82015-05-01 16:24:07 -0700549 "class StubInterface {\n"
Craig Tillerb5dcec52015-01-13 11:13:42 -0800550 " public:\n");
nnobleebebb7e2014-12-10 16:31:01 -0800551 printer->Indent();
Yang Gao72e0fb82015-05-01 16:24:07 -0700552 printer->Print("virtual ~StubInterface() {}\n");
553 for (int i = 0; i < service->method_count(); ++i) {
Yang Gaoc6924c82015-05-05 10:42:51 -0700554 PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, true);
555 }
556 printer->Outdent();
557 printer->Print("private:\n");
558 printer->Indent();
559 for (int i = 0; i < service->method_count(); ++i) {
560 PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, false);
Yang Gao72e0fb82015-05-01 16:24:07 -0700561 }
562 printer->Outdent();
563 printer->Print("};\n");
564 printer->Print(
565 "class Stub GRPC_FINAL : public StubInterface,"
566 " public ::grpc::InternalStub {\n public:\n");
567 printer->Indent();
Craig Tiller277d3cf2015-04-14 14:04:51 -0700568 printer->Print(
569 "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800570 for (int i = 0; i < service->method_count(); ++i) {
Yang Gaoc6924c82015-05-05 10:42:51 -0700571 PrintHeaderClientMethod(printer, service->method(i), vars, true);
nnobleebebb7e2014-12-10 16:31:01 -0800572 }
573 printer->Outdent();
Yang Gaoc6924c82015-05-05 10:42:51 -0700574 printer->Print("\n private:\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -0700575 printer->Indent();
576 for (int i = 0; i < service->method_count(); ++i) {
Yang Gaoc6924c82015-05-05 10:42:51 -0700577 PrintHeaderClientMethod(printer, service->method(i), vars, false);
578 }
579 for (int i = 0; i < service->method_count(); ++i) {
Craig Tillerbd6c6182015-04-10 17:08:15 -0700580 PrintHeaderClientMethodData(printer, service->method(i), vars);
581 }
582 printer->Outdent();
nnobleebebb7e2014-12-10 16:31:01 -0800583 printer->Print("};\n");
584 printer->Print(
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800585 "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
586 "::grpc::ChannelInterface>& "
nnobleebebb7e2014-12-10 16:31:01 -0800587 "channel);\n");
588
589 printer->Print("\n");
590
Craig Tiller2dff17d2015-02-09 12:42:23 -0800591 // Server side - Synchronous
Craig Tillerb5dcec52015-01-13 11:13:42 -0800592 printer->Print(
Craig Tiller14a65f92015-02-09 13:13:14 -0800593 "class Service : public ::grpc::SynchronousService {\n"
Craig Tillerb5dcec52015-01-13 11:13:42 -0800594 " public:\n");
nnobleebebb7e2014-12-10 16:31:01 -0800595 printer->Indent();
596 printer->Print("Service() : service_(nullptr) {}\n");
597 printer->Print("virtual ~Service();\n");
598 for (int i = 0; i < service->method_count(); ++i) {
Craig Tiller2dff17d2015-02-09 12:42:23 -0800599 PrintHeaderServerMethodSync(printer, service->method(i), vars);
600 }
Craig Tillercf133f42015-02-26 14:05:56 -0800601 printer->Print("::grpc::RpcService* service() GRPC_OVERRIDE GRPC_FINAL;\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800602 printer->Outdent();
603 printer->Print(
604 " private:\n"
605 " ::grpc::RpcService* service_;\n");
606 printer->Print("};\n");
607
608 // Server side - Asynchronous
609 printer->Print(
Craig Tillercf133f42015-02-26 14:05:56 -0800610 "class AsyncService GRPC_FINAL : public ::grpc::AsynchronousService {\n"
Craig Tiller2dff17d2015-02-09 12:42:23 -0800611 " public:\n");
612 printer->Indent();
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800613 (*vars)["MethodCount"] = as_string(service->method_count());
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700614 printer->Print("explicit AsyncService();\n");
Craig Tiller0220cf12015-02-12 17:39:26 -0800615 printer->Print("~AsyncService() {};\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800616 for (int i = 0; i < service->method_count(); ++i) {
617 PrintHeaderServerMethodAsync(printer, service->method(i), vars);
nnobleebebb7e2014-12-10 16:31:01 -0800618 }
nnobleebebb7e2014-12-10 16:31:01 -0800619 printer->Outdent();
nnobleebebb7e2014-12-10 16:31:01 -0800620 printer->Print("};\n");
621
622 printer->Outdent();
623 printer->Print("};\n");
624}
625
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100626grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
627 const Parameters &params) {
Nicolas Nobled446eb82015-03-12 17:22:33 -0700628 grpc::string output;
629 grpc::protobuf::io::StringOutputStream output_stream(&output);
630 grpc::protobuf::io::Printer printer(&output_stream, '$');
631 std::map<grpc::string, grpc::string> vars;
nnobleebebb7e2014-12-10 16:31:01 -0800632
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100633 if (!params.services_namespace.empty()) {
634 vars["services_namespace"] = params.services_namespace;
635 printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
636 }
637
nnobleebebb7e2014-12-10 16:31:01 -0800638 for (int i = 0; i < file->service_count(); ++i) {
samuelwca9f3592014-12-15 14:22:04 -0800639 PrintHeaderService(&printer, file->service(i), &vars);
nnobleebebb7e2014-12-10 16:31:01 -0800640 printer.Print("\n");
641 }
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100642
643 if (!params.services_namespace.empty()) {
644 printer.Print(vars, "} // namespace $services_namespace$\n\n");
645 }
646
nnobleebebb7e2014-12-10 16:31:01 -0800647 return output;
648}
649
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200650grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
651 const Parameters &params) {
652 grpc::string output;
653 grpc::protobuf::io::StringOutputStream output_stream(&output);
654 grpc::protobuf::io::Printer printer(&output_stream, '$');
655 std::map<grpc::string, grpc::string> vars;
656
657 vars["filename"] = file->name();
658 vars["filename_identifier"] = FilenameIdentifier(file->name());
659
Yang Gao1dc1a432015-04-10 13:53:11 -0700660 if (!file->package().empty()) {
661 std::vector<grpc::string> parts =
662 grpc_generator::tokenize(file->package(), ".");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200663
Yang Gao1dc1a432015-04-10 13:53:11 -0700664 for (auto part = parts.rbegin(); part != parts.rend(); part++) {
665 vars["part"] = *part;
666 printer.Print(vars, "} // namespace $part$\n");
667 }
668 printer.Print(vars, "\n");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200669 }
670
Yang Gao1dc1a432015-04-10 13:53:11 -0700671 printer.Print(vars, "\n");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200672 printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
673
674 return output;
675}
676
677grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
678 const Parameters &params) {
679 grpc::string output;
680 grpc::protobuf::io::StringOutputStream output_stream(&output);
681 grpc::protobuf::io::Printer printer(&output_stream, '$');
682 std::map<grpc::string, grpc::string> vars;
683
684 vars["filename"] = file->name();
685 vars["filename_base"] = grpc_generator::StripProto(file->name());
686
687 printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
688 printer.Print(vars, "// If you make any local change, they will be lost.\n");
689 printer.Print(vars, "// source: $filename$\n\n");
690 printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
691 printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
692 printer.Print(vars, "\n");
693
694 return output;
695}
696
697grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
698 const Parameters &param) {
699 grpc::string output;
700 grpc::protobuf::io::StringOutputStream output_stream(&output);
701 grpc::protobuf::io::Printer printer(&output_stream, '$');
702 std::map<grpc::string, grpc::string> vars;
703
704 printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
705 printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
706 printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200707 printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
708 printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
709 printer.Print(vars, "#include <grpc++/stream.h>\n");
710
Yang Gao1dc1a432015-04-10 13:53:11 -0700711 if (!file->package().empty()) {
712 std::vector<grpc::string> parts =
713 grpc_generator::tokenize(file->package(), ".");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200714
Yang Gao1dc1a432015-04-10 13:53:11 -0700715 for (auto part = parts.begin(); part != parts.end(); part++) {
716 vars["part"] = *part;
717 printer.Print(vars, "namespace $part$ {\n");
718 }
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200719 }
720
721 printer.Print(vars, "\n");
722
723 return output;
724}
725
Nicolas Nobled446eb82015-03-12 17:22:33 -0700726void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
727 const grpc::protobuf::MethodDescriptor *method,
728 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800729 (*vars)["Method"] = method->name();
730 (*vars)["Request"] =
731 grpc_cpp_generator::ClassName(method->input_type(), true);
732 (*vars)["Response"] =
733 grpc_cpp_generator::ClassName(method->output_type(), true);
734 if (NoStreaming(method)) {
735 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100736 "::grpc::Status $ns$$Service$::Stub::$Method$("
nnobleebebb7e2014-12-10 16:31:01 -0800737 "::grpc::ClientContext* context, "
738 "const $Request$& request, $Response$* response) {\n");
739 printer->Print(*vars,
Craig Tillerbd6c6182015-04-10 17:08:15 -0700740 " return ::grpc::BlockingUnaryCall(channel(), "
741 "rpcmethod_$Method$_, "
nnobleebebb7e2014-12-10 16:31:01 -0800742 "context, request, response);\n"
743 "}\n\n");
Yang Gao5680ff42015-01-14 12:14:21 -0800744 printer->Print(
745 *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700746 "::grpc::ClientAsyncResponseReader< $Response$>* "
747 "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800748 "const $Request$& request, "
Craig Tiller3676b382015-05-06 13:01:05 -0700749 "::grpc::CompletionQueue* cq) {\n");
yangg5bcea0d2015-01-06 10:35:03 -0800750 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700751 " return new "
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800752 "::grpc::ClientAsyncResponseReader< $Response$>("
753 "channel(), cq, "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700754 "rpcmethod_$Method$_, "
Craig Tiller5f871ac2015-05-08 13:05:51 -0700755 "context, request);\n"
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800756 "}\n\n");
757 } else if (ClientOnlyStreaming(method)) {
758 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700759 "::grpc::ClientWriter< $Request$>* "
760 "$ns$$Service$::Stub::$Method$Raw("
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800761 "::grpc::ClientContext* context, $Response$* response) {\n");
762 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700763 " return new ::grpc::ClientWriter< $Request$>("
764 "channel(), "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700765 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700766 "context, response);\n"
yangg5bcea0d2015-01-06 10:35:03 -0800767 "}\n\n");
Yang Gao068c85b2015-02-12 15:21:24 -0800768 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700769 "::grpc::ClientAsyncWriter< $Request$>* "
770 "$ns$$Service$::Stub::Async$Method$Raw("
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800771 "::grpc::ClientContext* context, $Response$* response, "
772 "::grpc::CompletionQueue* cq, void* tag) {\n");
773 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700774 " return new ::grpc::ClientAsyncWriter< $Request$>("
Yang Gao068c85b2015-02-12 15:21:24 -0800775 "channel(), cq, "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700776 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700777 "context, response, tag);\n"
Yang Gao068c85b2015-02-12 15:21:24 -0800778 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800779 } else if (ServerOnlyStreaming(method)) {
780 printer->Print(
781 *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700782 "::grpc::ClientReader< $Response$>* "
783 "$ns$$Service$::Stub::$Method$Raw("
Yang Gao07d83042015-02-13 14:11:31 -0800784 "::grpc::ClientContext* context, const $Request$& request) {\n");
yangg5bcea0d2015-01-06 10:35:03 -0800785 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700786 " return new ::grpc::ClientReader< $Response$>("
787 "channel(), "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700788 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700789 "context, request);\n"
yangg5bcea0d2015-01-06 10:35:03 -0800790 "}\n\n");
Yang Gao068c85b2015-02-12 15:21:24 -0800791 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700792 "::grpc::ClientAsyncReader< $Response$>* "
793 "$ns$$Service$::Stub::Async$Method$Raw("
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800794 "::grpc::ClientContext* context, const $Request$& request, "
795 "::grpc::CompletionQueue* cq, void* tag) {\n");
796 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700797 " return new ::grpc::ClientAsyncReader< $Response$>("
Yang Gao068c85b2015-02-12 15:21:24 -0800798 "channel(), cq, "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700799 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700800 "context, request, tag);\n"
Yang Gao068c85b2015-02-12 15:21:24 -0800801 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800802 } else if (BidiStreaming(method)) {
803 printer->Print(
804 *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700805 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
806 "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800807 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700808 " return new ::grpc::ClientReaderWriter< "
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800809 "$Request$, $Response$>("
Yang Gaoc6924c82015-05-05 10:42:51 -0700810 "channel(), "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700811 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700812 "context);\n"
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800813 "}\n\n");
Craig Tiller277d3cf2015-04-14 14:04:51 -0700814 printer->Print(
815 *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700816 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
817 "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
Craig Tiller277d3cf2015-04-14 14:04:51 -0700818 "::grpc::CompletionQueue* cq, void* tag) {\n");
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800819 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700820 " return new "
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800821 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
822 "channel(), cq, "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700823 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700824 "context, tag);\n"
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800825 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800826 }
827}
828
Nicolas Nobled446eb82015-03-12 17:22:33 -0700829void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
830 const grpc::protobuf::MethodDescriptor *method,
831 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800832 (*vars)["Method"] = method->name();
833 (*vars)["Request"] =
834 grpc_cpp_generator::ClassName(method->input_type(), true);
835 (*vars)["Response"] =
836 grpc_cpp_generator::ClassName(method->output_type(), true);
837 if (NoStreaming(method)) {
838 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100839 "::grpc::Status $ns$$Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800840 "::grpc::ServerContext* context, "
nnobleebebb7e2014-12-10 16:31:01 -0800841 "const $Request$* request, $Response$* response) {\n");
842 printer->Print(
843 " return ::grpc::Status("
844 "::grpc::StatusCode::UNIMPLEMENTED);\n");
845 printer->Print("}\n\n");
846 } else if (ClientOnlyStreaming(method)) {
847 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100848 "::grpc::Status $ns$$Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800849 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800850 "::grpc::ServerReader< $Request$>* reader, "
nnobleebebb7e2014-12-10 16:31:01 -0800851 "$Response$* response) {\n");
852 printer->Print(
853 " return ::grpc::Status("
854 "::grpc::StatusCode::UNIMPLEMENTED);\n");
855 printer->Print("}\n\n");
856 } else if (ServerOnlyStreaming(method)) {
857 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100858 "::grpc::Status $ns$$Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800859 "::grpc::ServerContext* context, "
nnobleebebb7e2014-12-10 16:31:01 -0800860 "const $Request$* request, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800861 "::grpc::ServerWriter< $Response$>* writer) {\n");
nnobleebebb7e2014-12-10 16:31:01 -0800862 printer->Print(
863 " return ::grpc::Status("
864 "::grpc::StatusCode::UNIMPLEMENTED);\n");
865 printer->Print("}\n\n");
866 } else if (BidiStreaming(method)) {
867 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100868 "::grpc::Status $ns$$Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800869 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800870 "::grpc::ServerReaderWriter< $Response$, $Request$>* "
nnobleebebb7e2014-12-10 16:31:01 -0800871 "stream) {\n");
872 printer->Print(
873 " return ::grpc::Status("
874 "::grpc::StatusCode::UNIMPLEMENTED);\n");
875 printer->Print("}\n\n");
876 }
877}
878
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800879void PrintSourceServerAsyncMethod(
Nicolas Nobled446eb82015-03-12 17:22:33 -0700880 grpc::protobuf::io::Printer *printer,
881 const grpc::protobuf::MethodDescriptor *method,
882 std::map<grpc::string, grpc::string> *vars) {
Craig Tiller225f7be2015-02-09 22:32:37 -0800883 (*vars)["Method"] = method->name();
884 (*vars)["Request"] =
885 grpc_cpp_generator::ClassName(method->input_type(), true);
886 (*vars)["Response"] =
887 grpc_cpp_generator::ClassName(method->output_type(), true);
888 if (NoStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700889 printer->Print(
890 *vars,
891 "void $ns$$Service$::AsyncService::Request$Method$("
892 "::grpc::ServerContext* context, "
893 "$Request$* request, "
894 "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
895 "::grpc::CompletionQueue* new_call_cq, "
896 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
Craig Tiller277d3cf2015-04-14 14:04:51 -0700897 printer->Print(*vars,
898 " AsynchronousService::RequestAsyncUnary($Idx$, context, "
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700899 "request, response, new_call_cq, notification_cq, tag);\n");
Craig Tiller225f7be2015-02-09 22:32:37 -0800900 printer->Print("}\n\n");
901 } else if (ClientOnlyStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700902 printer->Print(
903 *vars,
904 "void $ns$$Service$::AsyncService::Request$Method$("
905 "::grpc::ServerContext* context, "
906 "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
907 "::grpc::CompletionQueue* new_call_cq, "
908 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
Craig Tiller277d3cf2015-04-14 14:04:51 -0700909 printer->Print(*vars,
910 " AsynchronousService::RequestClientStreaming($Idx$, "
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700911 "context, reader, new_call_cq, notification_cq, tag);\n");
Craig Tiller225f7be2015-02-09 22:32:37 -0800912 printer->Print("}\n\n");
913 } else if (ServerOnlyStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700914 printer->Print(
915 *vars,
916 "void $ns$$Service$::AsyncService::Request$Method$("
917 "::grpc::ServerContext* context, "
918 "$Request$* request, "
919 "::grpc::ServerAsyncWriter< $Response$>* writer, "
920 "::grpc::CompletionQueue* new_call_cq, "
921 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
922 printer->Print(
923 *vars,
924 " AsynchronousService::RequestServerStreaming($Idx$, "
925 "context, request, writer, new_call_cq, notification_cq, tag);\n");
Craig Tiller225f7be2015-02-09 22:32:37 -0800926 printer->Print("}\n\n");
927 } else if (BidiStreaming(method)) {
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800928 printer->Print(
929 *vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100930 "void $ns$$Service$::AsyncService::Request$Method$("
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800931 "::grpc::ServerContext* context, "
932 "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700933 "::grpc::CompletionQueue* new_call_cq, "
934 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
Craig Tiller277d3cf2015-04-14 14:04:51 -0700935 printer->Print(*vars,
936 " AsynchronousService::RequestBidiStreaming($Idx$, "
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700937 "context, stream, new_call_cq, notification_cq, tag);\n");
Craig Tiller225f7be2015-02-09 22:32:37 -0800938 printer->Print("}\n\n");
939 }
940}
941
Nicolas Nobled446eb82015-03-12 17:22:33 -0700942void PrintSourceService(grpc::protobuf::io::Printer *printer,
943 const grpc::protobuf::ServiceDescriptor *service,
944 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800945 (*vars)["Service"] = service->name();
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800946
Craig Tiller277d3cf2015-04-14 14:04:51 -0700947 printer->Print(*vars,
948 "static const char* $prefix$$Service$_method_names[] = {\n");
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800949 for (int i = 0; i < service->method_count(); ++i) {
950 (*vars)["Method"] = service->method(i)->name();
951 printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
952 }
953 printer->Print(*vars, "};\n\n");
954
Yang Gao5680ff42015-01-14 12:14:21 -0800955 printer->Print(
956 *vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100957 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
Yang Gao5680ff42015-01-14 12:14:21 -0800958 "const std::shared_ptr< ::grpc::ChannelInterface>& channel) {\n"
Craig Tiller277d3cf2015-04-14 14:04:51 -0700959 " std::unique_ptr< $ns$$Service$::Stub> stub(new "
960 "$ns$$Service$::Stub(channel));\n"
Yang Gao5680ff42015-01-14 12:14:21 -0800961 " return stub;\n"
Todd Poynor2a6fd262015-02-26 20:04:26 -0800962 "}\n\n");
Craig Tiller277d3cf2015-04-14 14:04:51 -0700963 printer->Print(*vars,
964 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
965 "::grpc::ChannelInterface>& channel)\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -0700966 printer->Indent();
Craig Tiller3beef682015-04-14 13:55:03 -0700967 printer->Print(": ::grpc::InternalStub(channel)");
Craig Tillerbd6c6182015-04-10 17:08:15 -0700968 for (int i = 0; i < service->method_count(); ++i) {
969 const grpc::protobuf::MethodDescriptor *method = service->method(i);
Craig Tillerbd6c6182015-04-10 17:08:15 -0700970 (*vars)["Method"] = method->name();
971 (*vars)["Idx"] = as_string(i);
972 if (NoStreaming(method)) {
973 (*vars)["StreamingType"] = "NORMAL_RPC";
974 } else if (ClientOnlyStreaming(method)) {
975 (*vars)["StreamingType"] = "CLIENT_STREAMING";
976 } else if (ServerOnlyStreaming(method)) {
977 (*vars)["StreamingType"] = "SERVER_STREAMING";
978 } else {
979 (*vars)["StreamingType"] = "BIDI_STREAMING";
980 }
Craig Tiller277d3cf2015-04-14 14:04:51 -0700981 printer->Print(
982 *vars,
983 ", rpcmethod_$Method$_("
984 "$prefix$$Service$_method_names[$Idx$], "
985 "::grpc::RpcMethod::$StreamingType$, "
986 "channel->RegisterMethod($prefix$$Service$_method_names[$Idx$])"
987 ")\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -0700988 }
Craig Tiller3beef682015-04-14 13:55:03 -0700989 printer->Print("{}\n\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -0700990 printer->Outdent();
991
nnobleebebb7e2014-12-10 16:31:01 -0800992 for (int i = 0; i < service->method_count(); ++i) {
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800993 (*vars)["Idx"] = as_string(i);
nnobleebebb7e2014-12-10 16:31:01 -0800994 PrintSourceClientMethod(printer, service->method(i), vars);
995 }
996
Craig Tiller8c8d0aa2015-02-12 11:38:36 -0800997 (*vars)["MethodCount"] = as_string(service->method_count());
Craig Tiller277d3cf2015-04-14 14:04:51 -0700998 printer->Print(*vars,
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700999 "$ns$$Service$::AsyncService::AsyncService() : "
1000 "::grpc::AsynchronousService("
Craig Tiller277d3cf2015-04-14 14:04:51 -07001001 "$prefix$$Service$_method_names, $MethodCount$) "
1002 "{}\n\n");
Craig Tiller8c8d0aa2015-02-12 11:38:36 -08001003
nnobleebebb7e2014-12-10 16:31:01 -08001004 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001005 "$ns$$Service$::Service::~Service() {\n"
nnobleebebb7e2014-12-10 16:31:01 -08001006 " delete service_;\n"
1007 "}\n\n");
1008 for (int i = 0; i < service->method_count(); ++i) {
Craig Tiller1c9a2a92015-02-12 14:10:25 -08001009 (*vars)["Idx"] = as_string(i);
nnobleebebb7e2014-12-10 16:31:01 -08001010 PrintSourceServerMethod(printer, service->method(i), vars);
Craig Tiller225f7be2015-02-09 22:32:37 -08001011 PrintSourceServerAsyncMethod(printer, service->method(i), vars);
nnobleebebb7e2014-12-10 16:31:01 -08001012 }
1013 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001014 "::grpc::RpcService* $ns$$Service$::Service::service() {\n");
nnobleebebb7e2014-12-10 16:31:01 -08001015 printer->Indent();
Craig Tillerb5dcec52015-01-13 11:13:42 -08001016 printer->Print(
1017 "if (service_ != nullptr) {\n"
1018 " return service_;\n"
1019 "}\n");
nnobleebebb7e2014-12-10 16:31:01 -08001020 printer->Print("service_ = new ::grpc::RpcService();\n");
1021 for (int i = 0; i < service->method_count(); ++i) {
Nicolas Nobled446eb82015-03-12 17:22:33 -07001022 const grpc::protobuf::MethodDescriptor *method = service->method(i);
Craig Tiller8c8d0aa2015-02-12 11:38:36 -08001023 (*vars)["Idx"] = as_string(i);
nnobleebebb7e2014-12-10 16:31:01 -08001024 (*vars)["Method"] = method->name();
1025 (*vars)["Request"] =
1026 grpc_cpp_generator::ClassName(method->input_type(), true);
1027 (*vars)["Response"] =
1028 grpc_cpp_generator::ClassName(method->output_type(), true);
1029 if (NoStreaming(method)) {
1030 printer->Print(
1031 *vars,
1032 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001033 " $prefix$$Service$_method_names[$Idx$],\n"
yangg5bcea0d2015-01-06 10:35:03 -08001034 " ::grpc::RpcMethod::NORMAL_RPC,\n"
Craig Tiller277d3cf2015-04-14 14:04:51 -07001035 " new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
1036 "$Request$, "
nnobleebebb7e2014-12-10 16:31:01 -08001037 "$Response$>(\n"
Nicolas "Pixel" Noble99076fe2015-05-02 01:07:07 -07001038 " std::mem_fn(&$ns$$Service$::Service::$Method$), this),\n"
nnobleebebb7e2014-12-10 16:31:01 -08001039 " new $Request$, new $Response$));\n");
1040 } else if (ClientOnlyStreaming(method)) {
1041 printer->Print(
1042 *vars,
1043 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001044 " $prefix$$Service$_method_names[$Idx$],\n"
yangg5bcea0d2015-01-06 10:35:03 -08001045 " ::grpc::RpcMethod::CLIENT_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -08001046 " new ::grpc::ClientStreamingHandler< "
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001047 "$ns$$Service$::Service, $Request$, $Response$>(\n"
Nicolas "Pixel" Noble99076fe2015-05-02 01:07:07 -07001048 " std::mem_fn(&$ns$$Service$::Service::$Method$), this),\n"
nnobleebebb7e2014-12-10 16:31:01 -08001049 " new $Request$, new $Response$));\n");
1050 } else if (ServerOnlyStreaming(method)) {
1051 printer->Print(
1052 *vars,
1053 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001054 " $prefix$$Service$_method_names[$Idx$],\n"
yangg5bcea0d2015-01-06 10:35:03 -08001055 " ::grpc::RpcMethod::SERVER_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -08001056 " new ::grpc::ServerStreamingHandler< "
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001057 "$ns$$Service$::Service, $Request$, $Response$>(\n"
Nicolas "Pixel" Noble99076fe2015-05-02 01:07:07 -07001058 " std::mem_fn(&$ns$$Service$::Service::$Method$), this),\n"
nnobleebebb7e2014-12-10 16:31:01 -08001059 " new $Request$, new $Response$));\n");
1060 } else if (BidiStreaming(method)) {
1061 printer->Print(
1062 *vars,
1063 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001064 " $prefix$$Service$_method_names[$Idx$],\n"
yangg5bcea0d2015-01-06 10:35:03 -08001065 " ::grpc::RpcMethod::BIDI_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -08001066 " new ::grpc::BidiStreamingHandler< "
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001067 "$ns$$Service$::Service, $Request$, $Response$>(\n"
Nicolas "Pixel" Noble99076fe2015-05-02 01:07:07 -07001068 " std::mem_fn(&$ns$$Service$::Service::$Method$), this),\n"
nnobleebebb7e2014-12-10 16:31:01 -08001069 " new $Request$, new $Response$));\n");
1070 }
1071 }
1072 printer->Print("return service_;\n");
1073 printer->Outdent();
1074 printer->Print("}\n\n");
1075}
1076
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001077grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
1078 const Parameters &params) {
Nicolas Nobled446eb82015-03-12 17:22:33 -07001079 grpc::string output;
1080 grpc::protobuf::io::StringOutputStream output_stream(&output);
1081 grpc::protobuf::io::Printer printer(&output_stream, '$');
1082 std::map<grpc::string, grpc::string> vars;
yangg5bcea0d2015-01-06 10:35:03 -08001083 // Package string is empty or ends with a dot. It is used to fully qualify
1084 // method names.
1085 vars["Package"] = file->package();
1086 if (!file->package().empty()) {
1087 vars["Package"].append(".");
1088 }
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001089 if (!params.services_namespace.empty()) {
1090 vars["ns"] = params.services_namespace + "::";
1091 vars["prefix"] = params.services_namespace;
1092 } else {
1093 vars["ns"] = "";
1094 vars["prefix"] = "";
1095 }
nnobleebebb7e2014-12-10 16:31:01 -08001096
1097 for (int i = 0; i < file->service_count(); ++i) {
samuelwca9f3592014-12-15 14:22:04 -08001098 PrintSourceService(&printer, file->service(i), &vars);
nnobleebebb7e2014-12-10 16:31:01 -08001099 printer.Print("\n");
1100 }
1101 return output;
1102}
1103
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +02001104grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
1105 const Parameters &params) {
1106 grpc::string temp;
1107
Yang Gao1dc1a432015-04-10 13:53:11 -07001108 if (!file->package().empty()) {
1109 std::vector<grpc::string> parts =
1110 grpc_generator::tokenize(file->package(), ".");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +02001111
Yang Gao1dc1a432015-04-10 13:53:11 -07001112 for (auto part = parts.begin(); part != parts.end(); part++) {
1113 temp.append("} // namespace ");
1114 temp.append(*part);
1115 temp.append("\n");
1116 }
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +02001117 temp.append("\n");
1118 }
1119
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +02001120 return temp;
1121}
1122
Craig Tiller190d3602015-02-18 09:23:38 -08001123} // namespace grpc_cpp_generator