Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include <map>
35 :
36 : #include "src/compiler/cpp_generator.h"
37 : #include "src/compiler/cpp_generator_helpers.h"
38 :
39 : #include "src/compiler/config.h"
40 :
41 : #include <sstream>
42 :
43 : namespace grpc_cpp_generator {
44 : namespace {
45 :
46 : template <class T>
47 112 : grpc::string as_string(T x) {
48 112 : std::ostringstream out;
49 112 : out << x;
50 112 : return out.str();
51 : }
52 :
53 253 : bool NoStreaming(const grpc::protobuf::MethodDescriptor *method) {
54 253 : return !method->client_streaming() && !method->server_streaming();
55 : }
56 :
57 121 : bool ClientOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
58 121 : return method->client_streaming() && !method->server_streaming();
59 : }
60 :
61 99 : bool ServerOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
62 99 : return !method->client_streaming() && method->server_streaming();
63 : }
64 :
65 60 : bool BidiStreaming(const grpc::protobuf::MethodDescriptor *method) {
66 60 : return method->client_streaming() && method->server_streaming();
67 : }
68 :
69 24 : grpc::string FilenameIdentifier(const grpc::string &filename) {
70 24 : grpc::string result;
71 712 : for (unsigned i = 0; i < filename.size(); i++) {
72 688 : char c = filename[i];
73 688 : if (isalnum(c)) {
74 596 : result.push_back(c);
75 : } else {
76 : static char hex[] = "0123456789abcdef";
77 92 : result.push_back('_');
78 92 : result.push_back(hex[(c >> 4) & 0xf]);
79 92 : result.push_back(hex[c & 0xf]);
80 : }
81 : }
82 24 : return result;
83 : }
84 : } // namespace
85 :
86 12 : grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
87 : const Parameters ¶ms) {
88 12 : grpc::string output;
89 : {
90 : // Scope the output stream so it closes and finalizes output to the string.
91 12 : grpc::protobuf::io::StringOutputStream output_stream(&output);
92 24 : grpc::protobuf::io::Printer printer(&output_stream, '$');
93 24 : std::map<grpc::string, grpc::string> vars;
94 :
95 12 : vars["filename"] = file->name();
96 12 : vars["filename_identifier"] = FilenameIdentifier(file->name());
97 12 : vars["filename_base"] = grpc_generator::StripProto(file->name());
98 :
99 12 : printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
100 : printer.Print(vars,
101 12 : "// If you make any local change, they will be lost.\n");
102 12 : printer.Print(vars, "// source: $filename$\n");
103 12 : printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
104 12 : printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
105 12 : printer.Print(vars, "\n");
106 12 : printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
107 24 : printer.Print(vars, "\n");
108 : }
109 12 : return output;
110 : }
111 :
112 12 : grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
113 : const Parameters ¶ms) {
114 : grpc::string temp =
115 : "#include <grpc++/support/async_stream.h>\n"
116 : "#include <grpc++/impl/rpc_method.h>\n"
117 : "#include <grpc++/impl/proto_utils.h>\n"
118 : "#include <grpc++/impl/service_type.h>\n"
119 : "#include <grpc++/support/async_unary_call.h>\n"
120 : "#include <grpc++/support/status.h>\n"
121 : "#include <grpc++/support/stub_options.h>\n"
122 : "#include <grpc++/support/sync_stream.h>\n"
123 : "\n"
124 : "namespace grpc {\n"
125 : "class CompletionQueue;\n"
126 : "class Channel;\n"
127 : "class RpcService;\n"
128 : "class ServerCompletionQueue;\n"
129 : "class ServerContext;\n"
130 12 : "} // namespace grpc\n\n";
131 :
132 12 : if (!file->package().empty()) {
133 : std::vector<grpc::string> parts =
134 12 : grpc_generator::tokenize(file->package(), ".");
135 :
136 43 : for (auto part = parts.begin(); part != parts.end(); part++) {
137 31 : temp.append("namespace ");
138 31 : temp.append(*part);
139 31 : temp.append(" {\n");
140 : }
141 12 : temp.append("\n");
142 : }
143 :
144 12 : return temp;
145 : }
146 :
147 46 : void PrintHeaderClientMethodInterfaces(
148 : grpc::protobuf::io::Printer *printer,
149 : const grpc::protobuf::MethodDescriptor *method,
150 : std::map<grpc::string, grpc::string> *vars, bool is_public) {
151 46 : (*vars)["Method"] = method->name();
152 92 : (*vars)["Request"] =
153 46 : grpc_cpp_generator::ClassName(method->input_type(), true);
154 92 : (*vars)["Response"] =
155 46 : grpc_cpp_generator::ClassName(method->output_type(), true);
156 :
157 46 : if (is_public) {
158 23 : if (NoStreaming(method)) {
159 : printer->Print(
160 : *vars,
161 : "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
162 12 : "const $Request$& request, $Response$* response) = 0;\n");
163 : printer->Print(*vars,
164 : "std::unique_ptr< "
165 : "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
166 : "Async$Method$(::grpc::ClientContext* context, "
167 : "const $Request$& request, "
168 12 : "::grpc::CompletionQueue* cq) {\n");
169 12 : printer->Indent();
170 : printer->Print(*vars,
171 : "return std::unique_ptr< "
172 : "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
173 12 : "Async$Method$Raw(context, request, cq));\n");
174 12 : printer->Outdent();
175 12 : printer->Print("}\n");
176 11 : } else if (ClientOnlyStreaming(method)) {
177 : printer->Print(
178 : *vars,
179 : "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
180 : " $Method$("
181 2 : "::grpc::ClientContext* context, $Response$* response) {\n");
182 2 : printer->Indent();
183 : printer->Print(
184 : *vars,
185 : "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
186 2 : "($Method$Raw(context, response));\n");
187 2 : printer->Outdent();
188 2 : printer->Print("}\n");
189 : printer->Print(
190 : *vars,
191 : "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
192 : " Async$Method$(::grpc::ClientContext* context, $Response$* "
193 : "response, "
194 2 : "::grpc::CompletionQueue* cq, void* tag) {\n");
195 2 : printer->Indent();
196 : printer->Print(*vars,
197 : "return std::unique_ptr< "
198 : "::grpc::ClientAsyncWriterInterface< $Request$>>("
199 2 : "Async$Method$Raw(context, response, cq, tag));\n");
200 2 : printer->Outdent();
201 2 : printer->Print("}\n");
202 9 : } else if (ServerOnlyStreaming(method)) {
203 : printer->Print(
204 : *vars,
205 : "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
206 : " $Method$(::grpc::ClientContext* context, const $Request$& request)"
207 3 : " {\n");
208 3 : printer->Indent();
209 : printer->Print(
210 : *vars,
211 : "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
212 3 : "($Method$Raw(context, request));\n");
213 3 : printer->Outdent();
214 3 : printer->Print("}\n");
215 : printer->Print(
216 : *vars,
217 : "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
218 : "Async$Method$("
219 : "::grpc::ClientContext* context, const $Request$& request, "
220 3 : "::grpc::CompletionQueue* cq, void* tag) {\n");
221 3 : printer->Indent();
222 : printer->Print(*vars,
223 : "return std::unique_ptr< "
224 : "::grpc::ClientAsyncReaderInterface< $Response$>>("
225 3 : "Async$Method$Raw(context, request, cq, tag));\n");
226 3 : printer->Outdent();
227 3 : printer->Print("}\n");
228 6 : } else if (BidiStreaming(method)) {
229 : printer->Print(*vars,
230 : "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
231 : "$Request$, $Response$>> "
232 6 : "$Method$(::grpc::ClientContext* context) {\n");
233 6 : printer->Indent();
234 : printer->Print(
235 : *vars,
236 : "return std::unique_ptr< "
237 : "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
238 6 : "$Method$Raw(context));\n");
239 6 : printer->Outdent();
240 6 : printer->Print("}\n");
241 : printer->Print(
242 : *vars,
243 : "std::unique_ptr< "
244 : "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
245 : "Async$Method$(::grpc::ClientContext* context, "
246 6 : "::grpc::CompletionQueue* cq, void* tag) {\n");
247 6 : printer->Indent();
248 : printer->Print(
249 : *vars,
250 : "return std::unique_ptr< "
251 : "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
252 6 : "Async$Method$Raw(context, cq, tag));\n");
253 6 : printer->Outdent();
254 6 : printer->Print("}\n");
255 : }
256 : } else {
257 23 : if (NoStreaming(method)) {
258 : printer->Print(
259 : *vars,
260 : "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
261 : "Async$Method$Raw(::grpc::ClientContext* context, "
262 : "const $Request$& request, "
263 12 : "::grpc::CompletionQueue* cq) = 0;\n");
264 11 : } else if (ClientOnlyStreaming(method)) {
265 : printer->Print(
266 : *vars,
267 : "virtual ::grpc::ClientWriterInterface< $Request$>*"
268 : " $Method$Raw("
269 2 : "::grpc::ClientContext* context, $Response$* response) = 0;\n");
270 : printer->Print(*vars,
271 : "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
272 : " Async$Method$Raw(::grpc::ClientContext* context, "
273 : "$Response$* response, "
274 2 : "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
275 9 : } else if (ServerOnlyStreaming(method)) {
276 : printer->Print(
277 : *vars,
278 : "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
279 3 : "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
280 : printer->Print(
281 : *vars,
282 : "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
283 : "Async$Method$Raw("
284 : "::grpc::ClientContext* context, const $Request$& request, "
285 3 : "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
286 6 : } else if (BidiStreaming(method)) {
287 : printer->Print(*vars,
288 : "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
289 : "$Response$>* "
290 6 : "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
291 : printer->Print(*vars,
292 : "virtual ::grpc::ClientAsyncReaderWriterInterface< "
293 : "$Request$, $Response$>* "
294 : "Async$Method$Raw(::grpc::ClientContext* context, "
295 6 : "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
296 : }
297 : }
298 46 : }
299 :
300 46 : void 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 46 : (*vars)["Method"] = method->name();
305 92 : (*vars)["Request"] =
306 46 : grpc_cpp_generator::ClassName(method->input_type(), true);
307 92 : (*vars)["Response"] =
308 46 : grpc_cpp_generator::ClassName(method->output_type(), true);
309 46 : if (is_public) {
310 23 : if (NoStreaming(method)) {
311 : printer->Print(
312 : *vars,
313 : "::grpc::Status $Method$(::grpc::ClientContext* context, "
314 12 : "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, "
320 12 : "::grpc::CompletionQueue* cq) {\n");
321 12 : printer->Indent();
322 : printer->Print(*vars,
323 : "return std::unique_ptr< "
324 : "::grpc::ClientAsyncResponseReader< $Response$>>("
325 12 : "Async$Method$Raw(context, request, cq));\n");
326 12 : printer->Outdent();
327 12 : printer->Print("}\n");
328 11 : } else if (ClientOnlyStreaming(method)) {
329 : printer->Print(
330 : *vars,
331 : "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
332 : " $Method$("
333 2 : "::grpc::ClientContext* context, $Response$* response) {\n");
334 2 : printer->Indent();
335 : printer->Print(*vars,
336 : "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
337 2 : "($Method$Raw(context, response));\n");
338 2 : printer->Outdent();
339 2 : printer->Print("}\n");
340 : printer->Print(*vars,
341 : "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
342 : " Async$Method$(::grpc::ClientContext* context, "
343 : "$Response$* response, "
344 2 : "::grpc::CompletionQueue* cq, void* tag) {\n");
345 2 : printer->Indent();
346 : printer->Print(
347 : *vars,
348 : "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
349 2 : "Async$Method$Raw(context, response, cq, tag));\n");
350 2 : printer->Outdent();
351 2 : printer->Print("}\n");
352 9 : } else if (ServerOnlyStreaming(method)) {
353 : printer->Print(
354 : *vars,
355 : "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
356 : " $Method$(::grpc::ClientContext* context, const $Request$& request)"
357 3 : " {\n");
358 3 : printer->Indent();
359 : printer->Print(
360 : *vars,
361 : "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
362 3 : "($Method$Raw(context, request));\n");
363 3 : printer->Outdent();
364 3 : printer->Print("}\n");
365 : printer->Print(
366 : *vars,
367 : "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
368 : "Async$Method$("
369 : "::grpc::ClientContext* context, const $Request$& request, "
370 3 : "::grpc::CompletionQueue* cq, void* tag) {\n");
371 3 : printer->Indent();
372 : printer->Print(
373 : *vars,
374 : "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
375 3 : "Async$Method$Raw(context, request, cq, tag));\n");
376 3 : printer->Outdent();
377 3 : printer->Print("}\n");
378 6 : } else if (BidiStreaming(method)) {
379 : printer->Print(
380 : *vars,
381 : "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
382 6 : " $Method$(::grpc::ClientContext* context) {\n");
383 6 : printer->Indent();
384 : printer->Print(*vars,
385 : "return std::unique_ptr< "
386 : "::grpc::ClientReaderWriter< $Request$, $Response$>>("
387 6 : "$Method$Raw(context));\n");
388 6 : printer->Outdent();
389 6 : printer->Print("}\n");
390 : printer->Print(*vars,
391 : "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
392 : "$Request$, $Response$>> "
393 : "Async$Method$(::grpc::ClientContext* context, "
394 6 : "::grpc::CompletionQueue* cq, void* tag) {\n");
395 6 : printer->Indent();
396 : printer->Print(*vars,
397 : "return std::unique_ptr< "
398 : "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
399 6 : "Async$Method$Raw(context, cq, tag));\n");
400 6 : printer->Outdent();
401 6 : printer->Print("}\n");
402 : }
403 : } else {
404 23 : if (NoStreaming(method)) {
405 : printer->Print(*vars,
406 : "::grpc::ClientAsyncResponseReader< $Response$>* "
407 : "Async$Method$Raw(::grpc::ClientContext* context, "
408 : "const $Request$& request, "
409 12 : "::grpc::CompletionQueue* cq) GRPC_OVERRIDE;\n");
410 11 : } else if (ClientOnlyStreaming(method)) {
411 : printer->Print(*vars,
412 : "::grpc::ClientWriter< $Request$>* $Method$Raw("
413 : "::grpc::ClientContext* context, $Response$* response) "
414 2 : "GRPC_OVERRIDE;\n");
415 : printer->Print(
416 : *vars,
417 : "::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
418 : "::grpc::ClientContext* context, $Response$* response, "
419 2 : "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
420 9 : } else if (ServerOnlyStreaming(method)) {
421 : printer->Print(*vars,
422 : "::grpc::ClientReader< $Response$>* $Method$Raw("
423 : "::grpc::ClientContext* context, const $Request$& request)"
424 3 : " GRPC_OVERRIDE;\n");
425 : printer->Print(
426 : *vars,
427 : "::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw("
428 : "::grpc::ClientContext* context, const $Request$& request, "
429 3 : "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
430 6 : } else if (BidiStreaming(method)) {
431 : printer->Print(
432 : *vars,
433 : "::grpc::ClientReaderWriter< $Request$, $Response$>* "
434 6 : "$Method$Raw(::grpc::ClientContext* context) GRPC_OVERRIDE;\n");
435 : printer->Print(
436 : *vars,
437 : "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
438 : "Async$Method$Raw(::grpc::ClientContext* context, "
439 6 : "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
440 : }
441 : }
442 46 : }
443 :
444 23 : void PrintHeaderClientMethodData(grpc::protobuf::io::Printer *printer,
445 : const grpc::protobuf::MethodDescriptor *method,
446 : std::map<grpc::string, grpc::string> *vars) {
447 23 : (*vars)["Method"] = method->name();
448 23 : printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
449 23 : }
450 :
451 23 : void PrintHeaderServerMethodSync(grpc::protobuf::io::Printer *printer,
452 : const grpc::protobuf::MethodDescriptor *method,
453 : std::map<grpc::string, grpc::string> *vars) {
454 23 : (*vars)["Method"] = method->name();
455 46 : (*vars)["Request"] =
456 23 : grpc_cpp_generator::ClassName(method->input_type(), true);
457 46 : (*vars)["Response"] =
458 23 : grpc_cpp_generator::ClassName(method->output_type(), true);
459 23 : if (NoStreaming(method)) {
460 : printer->Print(*vars,
461 : "virtual ::grpc::Status $Method$("
462 : "::grpc::ServerContext* context, const $Request$* request, "
463 12 : "$Response$* response);\n");
464 11 : } else if (ClientOnlyStreaming(method)) {
465 : printer->Print(*vars,
466 : "virtual ::grpc::Status $Method$("
467 : "::grpc::ServerContext* context, "
468 : "::grpc::ServerReader< $Request$>* reader, "
469 2 : "$Response$* response);\n");
470 9 : } else if (ServerOnlyStreaming(method)) {
471 : printer->Print(*vars,
472 : "virtual ::grpc::Status $Method$("
473 : "::grpc::ServerContext* context, const $Request$* request, "
474 3 : "::grpc::ServerWriter< $Response$>* writer);\n");
475 6 : } else if (BidiStreaming(method)) {
476 : printer->Print(
477 : *vars,
478 : "virtual ::grpc::Status $Method$("
479 : "::grpc::ServerContext* context, "
480 : "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
481 6 : "\n");
482 : }
483 23 : }
484 :
485 23 : void PrintHeaderServerMethodAsync(
486 : grpc::protobuf::io::Printer *printer,
487 : const grpc::protobuf::MethodDescriptor *method,
488 : std::map<grpc::string, grpc::string> *vars) {
489 23 : (*vars)["Method"] = method->name();
490 46 : (*vars)["Request"] =
491 23 : grpc_cpp_generator::ClassName(method->input_type(), true);
492 46 : (*vars)["Response"] =
493 23 : grpc_cpp_generator::ClassName(method->output_type(), true);
494 23 : if (NoStreaming(method)) {
495 : printer->Print(
496 : *vars,
497 : "void Request$Method$("
498 : "::grpc::ServerContext* context, $Request$* request, "
499 : "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
500 : "::grpc::CompletionQueue* new_call_cq, "
501 12 : "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
502 11 : } else if (ClientOnlyStreaming(method)) {
503 : printer->Print(
504 : *vars,
505 : "void Request$Method$("
506 : "::grpc::ServerContext* context, "
507 : "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
508 : "::grpc::CompletionQueue* new_call_cq, "
509 2 : "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
510 9 : } else if (ServerOnlyStreaming(method)) {
511 : printer->Print(
512 : *vars,
513 : "void Request$Method$("
514 : "::grpc::ServerContext* context, $Request$* request, "
515 : "::grpc::ServerAsyncWriter< $Response$>* writer, "
516 : "::grpc::CompletionQueue* new_call_cq, "
517 3 : "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
518 6 : } else if (BidiStreaming(method)) {
519 : printer->Print(
520 : *vars,
521 : "void Request$Method$("
522 : "::grpc::ServerContext* context, "
523 : "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
524 : "::grpc::CompletionQueue* new_call_cq, "
525 6 : "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
526 : }
527 23 : }
528 :
529 10 : void PrintHeaderService(grpc::protobuf::io::Printer *printer,
530 : const grpc::protobuf::ServiceDescriptor *service,
531 : std::map<grpc::string, grpc::string> *vars) {
532 10 : (*vars)["Service"] = service->name();
533 :
534 : printer->Print(*vars,
535 : "class $Service$ GRPC_FINAL {\n"
536 10 : " public:\n");
537 10 : printer->Indent();
538 :
539 : // Client side
540 : printer->Print(
541 : "class StubInterface {\n"
542 10 : " public:\n");
543 10 : printer->Indent();
544 10 : printer->Print("virtual ~StubInterface() {}\n");
545 33 : for (int i = 0; i < service->method_count(); ++i) {
546 23 : PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, true);
547 : }
548 10 : printer->Outdent();
549 10 : printer->Print("private:\n");
550 10 : printer->Indent();
551 33 : for (int i = 0; i < service->method_count(); ++i) {
552 23 : PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, false);
553 : }
554 10 : printer->Outdent();
555 10 : printer->Print("};\n");
556 : printer->Print(
557 : "class Stub GRPC_FINAL : public StubInterface"
558 10 : " {\n public:\n");
559 10 : printer->Indent();
560 10 : printer->Print("Stub(const std::shared_ptr< ::grpc::Channel>& channel);\n");
561 33 : for (int i = 0; i < service->method_count(); ++i) {
562 23 : PrintHeaderClientMethod(printer, service->method(i), vars, true);
563 : }
564 10 : printer->Outdent();
565 10 : printer->Print("\n private:\n");
566 10 : printer->Indent();
567 10 : printer->Print("std::shared_ptr< ::grpc::Channel> channel_;\n");
568 33 : for (int i = 0; i < service->method_count(); ++i) {
569 23 : PrintHeaderClientMethod(printer, service->method(i), vars, false);
570 : }
571 33 : for (int i = 0; i < service->method_count(); ++i) {
572 23 : PrintHeaderClientMethodData(printer, service->method(i), vars);
573 : }
574 10 : printer->Outdent();
575 10 : printer->Print("};\n");
576 : printer->Print(
577 : "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
578 : "::grpc::Channel>& channel, "
579 10 : "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
580 :
581 10 : printer->Print("\n");
582 :
583 : // Server side - Synchronous
584 : printer->Print(
585 : "class Service : public ::grpc::SynchronousService {\n"
586 10 : " public:\n");
587 10 : printer->Indent();
588 10 : printer->Print("Service();\n");
589 10 : printer->Print("virtual ~Service();\n");
590 33 : for (int i = 0; i < service->method_count(); ++i) {
591 23 : PrintHeaderServerMethodSync(printer, service->method(i), vars);
592 : }
593 10 : printer->Print("::grpc::RpcService* service() GRPC_OVERRIDE GRPC_FINAL;\n");
594 10 : printer->Outdent();
595 : printer->Print(
596 : " private:\n"
597 10 : " std::unique_ptr< ::grpc::RpcService> service_;\n");
598 10 : printer->Print("};\n");
599 :
600 : // Server side - Asynchronous
601 : printer->Print(
602 : "class AsyncService GRPC_FINAL : public ::grpc::AsynchronousService {\n"
603 10 : " public:\n");
604 10 : printer->Indent();
605 10 : (*vars)["MethodCount"] = as_string(service->method_count());
606 10 : printer->Print("explicit AsyncService();\n");
607 10 : printer->Print("~AsyncService() {};\n");
608 33 : for (int i = 0; i < service->method_count(); ++i) {
609 23 : PrintHeaderServerMethodAsync(printer, service->method(i), vars);
610 : }
611 10 : printer->Outdent();
612 10 : printer->Print("};\n");
613 :
614 10 : printer->Outdent();
615 10 : printer->Print("};\n");
616 10 : }
617 :
618 12 : grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
619 : const Parameters ¶ms) {
620 12 : grpc::string output;
621 : {
622 : // Scope the output stream so it closes and finalizes output to the string.
623 12 : grpc::protobuf::io::StringOutputStream output_stream(&output);
624 24 : grpc::protobuf::io::Printer printer(&output_stream, '$');
625 24 : std::map<grpc::string, grpc::string> vars;
626 :
627 12 : if (!params.services_namespace.empty()) {
628 0 : vars["services_namespace"] = params.services_namespace;
629 0 : printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
630 : }
631 :
632 22 : for (int i = 0; i < file->service_count(); ++i) {
633 10 : PrintHeaderService(&printer, file->service(i), &vars);
634 10 : printer.Print("\n");
635 : }
636 :
637 12 : if (!params.services_namespace.empty()) {
638 0 : printer.Print(vars, "} // namespace $services_namespace$\n\n");
639 12 : }
640 : }
641 12 : return output;
642 : }
643 :
644 12 : grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
645 : const Parameters ¶ms) {
646 12 : grpc::string output;
647 : {
648 : // Scope the output stream so it closes and finalizes output to the string.
649 12 : grpc::protobuf::io::StringOutputStream output_stream(&output);
650 24 : grpc::protobuf::io::Printer printer(&output_stream, '$');
651 24 : std::map<grpc::string, grpc::string> vars;
652 :
653 12 : vars["filename"] = file->name();
654 12 : vars["filename_identifier"] = FilenameIdentifier(file->name());
655 :
656 12 : if (!file->package().empty()) {
657 : std::vector<grpc::string> parts =
658 12 : grpc_generator::tokenize(file->package(), ".");
659 :
660 43 : for (auto part = parts.rbegin(); part != parts.rend(); part++) {
661 31 : vars["part"] = *part;
662 31 : printer.Print(vars, "} // namespace $part$\n");
663 : }
664 12 : printer.Print(vars, "\n");
665 : }
666 :
667 12 : printer.Print(vars, "\n");
668 24 : printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
669 : }
670 12 : return output;
671 : }
672 :
673 12 : grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
674 : const Parameters ¶ms) {
675 12 : grpc::string output;
676 : {
677 : // Scope the output stream so it closes and finalizes output to the string.
678 12 : grpc::protobuf::io::StringOutputStream output_stream(&output);
679 24 : grpc::protobuf::io::Printer printer(&output_stream, '$');
680 24 : std::map<grpc::string, grpc::string> vars;
681 :
682 12 : vars["filename"] = file->name();
683 12 : vars["filename_base"] = grpc_generator::StripProto(file->name());
684 :
685 12 : printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
686 : printer.Print(vars,
687 12 : "// If you make any local change, they will be lost.\n");
688 12 : printer.Print(vars, "// source: $filename$\n\n");
689 12 : printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
690 12 : printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
691 24 : printer.Print(vars, "\n");
692 : }
693 12 : return output;
694 : }
695 :
696 12 : grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
697 : const Parameters ¶m) {
698 12 : grpc::string output;
699 : {
700 : // Scope the output stream so it closes and finalizes output to the string.
701 12 : grpc::protobuf::io::StringOutputStream output_stream(&output);
702 24 : grpc::protobuf::io::Printer printer(&output_stream, '$');
703 24 : std::map<grpc::string, grpc::string> vars;
704 :
705 12 : printer.Print(vars, "#include <grpc++/channel.h>\n");
706 12 : printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
707 12 : printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
708 12 : printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
709 12 : printer.Print(vars, "#include <grpc++/support/async_unary_call.h>\n");
710 12 : printer.Print(vars, "#include <grpc++/support/async_stream.h>\n");
711 12 : printer.Print(vars, "#include <grpc++/support/sync_stream.h>\n");
712 :
713 12 : if (!file->package().empty()) {
714 : std::vector<grpc::string> parts =
715 12 : grpc_generator::tokenize(file->package(), ".");
716 :
717 43 : for (auto part = parts.begin(); part != parts.end(); part++) {
718 31 : vars["part"] = *part;
719 31 : printer.Print(vars, "namespace $part$ {\n");
720 12 : }
721 : }
722 :
723 24 : printer.Print(vars, "\n");
724 : }
725 12 : return output;
726 : }
727 :
728 23 : void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
729 : const grpc::protobuf::MethodDescriptor *method,
730 : std::map<grpc::string, grpc::string> *vars) {
731 23 : (*vars)["Method"] = method->name();
732 46 : (*vars)["Request"] =
733 23 : grpc_cpp_generator::ClassName(method->input_type(), true);
734 46 : (*vars)["Response"] =
735 23 : grpc_cpp_generator::ClassName(method->output_type(), true);
736 23 : if (NoStreaming(method)) {
737 : printer->Print(*vars,
738 : "::grpc::Status $ns$$Service$::Stub::$Method$("
739 : "::grpc::ClientContext* context, "
740 12 : "const $Request$& request, $Response$* response) {\n");
741 : printer->Print(*vars,
742 : " return ::grpc::BlockingUnaryCall(channel_.get(), "
743 : "rpcmethod_$Method$_, "
744 : "context, request, response);\n"
745 12 : "}\n\n");
746 : printer->Print(
747 : *vars,
748 : "::grpc::ClientAsyncResponseReader< $Response$>* "
749 : "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
750 : "const $Request$& request, "
751 12 : "::grpc::CompletionQueue* cq) {\n");
752 : printer->Print(*vars,
753 : " return new "
754 : "::grpc::ClientAsyncResponseReader< $Response$>("
755 : "channel_.get(), cq, "
756 : "rpcmethod_$Method$_, "
757 : "context, request);\n"
758 12 : "}\n\n");
759 11 : } else if (ClientOnlyStreaming(method)) {
760 : printer->Print(*vars,
761 : "::grpc::ClientWriter< $Request$>* "
762 : "$ns$$Service$::Stub::$Method$Raw("
763 2 : "::grpc::ClientContext* context, $Response$* response) {\n");
764 : printer->Print(*vars,
765 : " return new ::grpc::ClientWriter< $Request$>("
766 : "channel_.get(), "
767 : "rpcmethod_$Method$_, "
768 : "context, response);\n"
769 2 : "}\n\n");
770 : printer->Print(*vars,
771 : "::grpc::ClientAsyncWriter< $Request$>* "
772 : "$ns$$Service$::Stub::Async$Method$Raw("
773 : "::grpc::ClientContext* context, $Response$* response, "
774 2 : "::grpc::CompletionQueue* cq, void* tag) {\n");
775 : printer->Print(*vars,
776 : " return new ::grpc::ClientAsyncWriter< $Request$>("
777 : "channel_.get(), cq, "
778 : "rpcmethod_$Method$_, "
779 : "context, response, tag);\n"
780 2 : "}\n\n");
781 9 : } else if (ServerOnlyStreaming(method)) {
782 : printer->Print(
783 : *vars,
784 : "::grpc::ClientReader< $Response$>* "
785 : "$ns$$Service$::Stub::$Method$Raw("
786 3 : "::grpc::ClientContext* context, const $Request$& request) {\n");
787 : printer->Print(*vars,
788 : " return new ::grpc::ClientReader< $Response$>("
789 : "channel_.get(), "
790 : "rpcmethod_$Method$_, "
791 : "context, request);\n"
792 3 : "}\n\n");
793 : printer->Print(*vars,
794 : "::grpc::ClientAsyncReader< $Response$>* "
795 : "$ns$$Service$::Stub::Async$Method$Raw("
796 : "::grpc::ClientContext* context, const $Request$& request, "
797 3 : "::grpc::CompletionQueue* cq, void* tag) {\n");
798 : printer->Print(*vars,
799 : " return new ::grpc::ClientAsyncReader< $Response$>("
800 : "channel_.get(), cq, "
801 : "rpcmethod_$Method$_, "
802 : "context, request, tag);\n"
803 3 : "}\n\n");
804 6 : } else if (BidiStreaming(method)) {
805 : printer->Print(
806 : *vars,
807 : "::grpc::ClientReaderWriter< $Request$, $Response$>* "
808 6 : "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
809 : printer->Print(*vars,
810 : " return new ::grpc::ClientReaderWriter< "
811 : "$Request$, $Response$>("
812 : "channel_.get(), "
813 : "rpcmethod_$Method$_, "
814 : "context);\n"
815 6 : "}\n\n");
816 : printer->Print(
817 : *vars,
818 : "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
819 : "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
820 6 : "::grpc::CompletionQueue* cq, void* tag) {\n");
821 : printer->Print(*vars,
822 : " return new "
823 : "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
824 : "channel_.get(), cq, "
825 : "rpcmethod_$Method$_, "
826 : "context, tag);\n"
827 6 : "}\n\n");
828 : }
829 23 : }
830 :
831 23 : void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
832 : const grpc::protobuf::MethodDescriptor *method,
833 : std::map<grpc::string, grpc::string> *vars) {
834 23 : (*vars)["Method"] = method->name();
835 46 : (*vars)["Request"] =
836 23 : grpc_cpp_generator::ClassName(method->input_type(), true);
837 46 : (*vars)["Response"] =
838 23 : grpc_cpp_generator::ClassName(method->output_type(), true);
839 23 : if (NoStreaming(method)) {
840 : printer->Print(*vars,
841 : "::grpc::Status $ns$$Service$::Service::$Method$("
842 : "::grpc::ServerContext* context, "
843 12 : "const $Request$* request, $Response$* response) {\n");
844 12 : printer->Print(" (void) context;\n");
845 12 : printer->Print(" (void) request;\n");
846 12 : printer->Print(" (void) response;\n");
847 : printer->Print(
848 : " return ::grpc::Status("
849 12 : "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
850 12 : printer->Print("}\n\n");
851 11 : } else if (ClientOnlyStreaming(method)) {
852 : printer->Print(*vars,
853 : "::grpc::Status $ns$$Service$::Service::$Method$("
854 : "::grpc::ServerContext* context, "
855 : "::grpc::ServerReader< $Request$>* reader, "
856 2 : "$Response$* response) {\n");
857 2 : printer->Print(" (void) context;\n");
858 2 : printer->Print(" (void) reader;\n");
859 2 : printer->Print(" (void) response;\n");
860 : printer->Print(
861 : " return ::grpc::Status("
862 2 : "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
863 2 : printer->Print("}\n\n");
864 9 : } else if (ServerOnlyStreaming(method)) {
865 : printer->Print(*vars,
866 : "::grpc::Status $ns$$Service$::Service::$Method$("
867 : "::grpc::ServerContext* context, "
868 : "const $Request$* request, "
869 3 : "::grpc::ServerWriter< $Response$>* writer) {\n");
870 3 : printer->Print(" (void) context;\n");
871 3 : printer->Print(" (void) request;\n");
872 3 : printer->Print(" (void) writer;\n");
873 : printer->Print(
874 : " return ::grpc::Status("
875 3 : "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
876 3 : printer->Print("}\n\n");
877 6 : } else if (BidiStreaming(method)) {
878 : printer->Print(*vars,
879 : "::grpc::Status $ns$$Service$::Service::$Method$("
880 : "::grpc::ServerContext* context, "
881 : "::grpc::ServerReaderWriter< $Response$, $Request$>* "
882 6 : "stream) {\n");
883 6 : printer->Print(" (void) context;\n");
884 6 : printer->Print(" (void) stream;\n");
885 : printer->Print(
886 : " return ::grpc::Status("
887 6 : "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
888 6 : printer->Print("}\n\n");
889 : }
890 23 : }
891 :
892 23 : void PrintSourceServerAsyncMethod(
893 : grpc::protobuf::io::Printer *printer,
894 : const grpc::protobuf::MethodDescriptor *method,
895 : std::map<grpc::string, grpc::string> *vars) {
896 23 : (*vars)["Method"] = method->name();
897 46 : (*vars)["Request"] =
898 23 : grpc_cpp_generator::ClassName(method->input_type(), true);
899 46 : (*vars)["Response"] =
900 23 : grpc_cpp_generator::ClassName(method->output_type(), true);
901 23 : if (NoStreaming(method)) {
902 : printer->Print(
903 : *vars,
904 : "void $ns$$Service$::AsyncService::Request$Method$("
905 : "::grpc::ServerContext* context, "
906 : "$Request$* request, "
907 : "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
908 : "::grpc::CompletionQueue* new_call_cq, "
909 12 : "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
910 : printer->Print(*vars,
911 : " AsynchronousService::RequestAsyncUnary($Idx$, context, "
912 12 : "request, response, new_call_cq, notification_cq, tag);\n");
913 12 : printer->Print("}\n\n");
914 11 : } else if (ClientOnlyStreaming(method)) {
915 : printer->Print(
916 : *vars,
917 : "void $ns$$Service$::AsyncService::Request$Method$("
918 : "::grpc::ServerContext* context, "
919 : "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
920 : "::grpc::CompletionQueue* new_call_cq, "
921 2 : "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
922 : printer->Print(*vars,
923 : " AsynchronousService::RequestClientStreaming($Idx$, "
924 2 : "context, reader, new_call_cq, notification_cq, tag);\n");
925 2 : printer->Print("}\n\n");
926 9 : } else if (ServerOnlyStreaming(method)) {
927 : printer->Print(
928 : *vars,
929 : "void $ns$$Service$::AsyncService::Request$Method$("
930 : "::grpc::ServerContext* context, "
931 : "$Request$* request, "
932 : "::grpc::ServerAsyncWriter< $Response$>* writer, "
933 : "::grpc::CompletionQueue* new_call_cq, "
934 3 : "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
935 : printer->Print(
936 : *vars,
937 : " AsynchronousService::RequestServerStreaming($Idx$, "
938 3 : "context, request, writer, new_call_cq, notification_cq, tag);\n");
939 3 : printer->Print("}\n\n");
940 6 : } else if (BidiStreaming(method)) {
941 : printer->Print(
942 : *vars,
943 : "void $ns$$Service$::AsyncService::Request$Method$("
944 : "::grpc::ServerContext* context, "
945 : "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
946 : "::grpc::CompletionQueue* new_call_cq, "
947 6 : "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
948 : printer->Print(*vars,
949 : " AsynchronousService::RequestBidiStreaming($Idx$, "
950 6 : "context, stream, new_call_cq, notification_cq, tag);\n");
951 6 : printer->Print("}\n\n");
952 : }
953 23 : }
954 :
955 10 : void PrintSourceService(grpc::protobuf::io::Printer *printer,
956 : const grpc::protobuf::ServiceDescriptor *service,
957 : std::map<grpc::string, grpc::string> *vars) {
958 10 : (*vars)["Service"] = service->name();
959 :
960 : printer->Print(*vars,
961 10 : "static const char* $prefix$$Service$_method_names[] = {\n");
962 33 : for (int i = 0; i < service->method_count(); ++i) {
963 23 : (*vars)["Method"] = service->method(i)->name();
964 23 : printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
965 : }
966 10 : printer->Print(*vars, "};\n\n");
967 :
968 : printer->Print(*vars,
969 : "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
970 : "const std::shared_ptr< ::grpc::Channel>& channel, "
971 : "const ::grpc::StubOptions& options) {\n"
972 : " std::unique_ptr< $ns$$Service$::Stub> stub(new "
973 : "$ns$$Service$::Stub(channel));\n"
974 : " return stub;\n"
975 10 : "}\n\n");
976 : printer->Print(*vars,
977 : "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
978 10 : "::grpc::Channel>& channel)\n");
979 10 : printer->Indent();
980 10 : printer->Print(": channel_(channel)");
981 33 : for (int i = 0; i < service->method_count(); ++i) {
982 23 : const grpc::protobuf::MethodDescriptor *method = service->method(i);
983 23 : (*vars)["Method"] = method->name();
984 23 : (*vars)["Idx"] = as_string(i);
985 23 : if (NoStreaming(method)) {
986 12 : (*vars)["StreamingType"] = "NORMAL_RPC";
987 11 : } else if (ClientOnlyStreaming(method)) {
988 2 : (*vars)["StreamingType"] = "CLIENT_STREAMING";
989 9 : } else if (ServerOnlyStreaming(method)) {
990 3 : (*vars)["StreamingType"] = "SERVER_STREAMING";
991 : } else {
992 6 : (*vars)["StreamingType"] = "BIDI_STREAMING";
993 : }
994 : printer->Print(*vars,
995 : ", rpcmethod_$Method$_("
996 : "$prefix$$Service$_method_names[$Idx$], "
997 : "::grpc::RpcMethod::$StreamingType$, "
998 : "channel"
999 23 : ")\n");
1000 : }
1001 10 : printer->Print("{}\n\n");
1002 10 : printer->Outdent();
1003 :
1004 33 : for (int i = 0; i < service->method_count(); ++i) {
1005 23 : (*vars)["Idx"] = as_string(i);
1006 23 : PrintSourceClientMethod(printer, service->method(i), vars);
1007 : }
1008 :
1009 10 : (*vars)["MethodCount"] = as_string(service->method_count());
1010 : printer->Print(*vars,
1011 : "$ns$$Service$::AsyncService::AsyncService() : "
1012 : "::grpc::AsynchronousService("
1013 : "$prefix$$Service$_method_names, $MethodCount$) "
1014 10 : "{}\n\n");
1015 :
1016 : printer->Print(*vars,
1017 : "$ns$$Service$::Service::Service() {\n"
1018 10 : "}\n\n");
1019 : printer->Print(*vars,
1020 : "$ns$$Service$::Service::~Service() {\n"
1021 10 : "}\n\n");
1022 33 : for (int i = 0; i < service->method_count(); ++i) {
1023 23 : (*vars)["Idx"] = as_string(i);
1024 23 : PrintSourceServerMethod(printer, service->method(i), vars);
1025 23 : PrintSourceServerAsyncMethod(printer, service->method(i), vars);
1026 : }
1027 : printer->Print(*vars,
1028 10 : "::grpc::RpcService* $ns$$Service$::Service::service() {\n");
1029 10 : printer->Indent();
1030 : printer->Print(
1031 : "if (service_) {\n"
1032 : " return service_.get();\n"
1033 10 : "}\n");
1034 10 : printer->Print("service_ = std::unique_ptr< ::grpc::RpcService>(new ::grpc::RpcService());\n");
1035 33 : for (int i = 0; i < service->method_count(); ++i) {
1036 23 : const grpc::protobuf::MethodDescriptor *method = service->method(i);
1037 23 : (*vars)["Idx"] = as_string(i);
1038 23 : (*vars)["Method"] = method->name();
1039 46 : (*vars)["Request"] =
1040 23 : grpc_cpp_generator::ClassName(method->input_type(), true);
1041 46 : (*vars)["Response"] =
1042 23 : grpc_cpp_generator::ClassName(method->output_type(), true);
1043 23 : if (NoStreaming(method)) {
1044 : printer->Print(
1045 : *vars,
1046 : "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
1047 : " $prefix$$Service$_method_names[$Idx$],\n"
1048 : " ::grpc::RpcMethod::NORMAL_RPC,\n"
1049 : " new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
1050 : "$Request$, "
1051 : "$Response$>(\n"
1052 12 : " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1053 11 : } else if (ClientOnlyStreaming(method)) {
1054 : printer->Print(
1055 : *vars,
1056 : "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
1057 : " $prefix$$Service$_method_names[$Idx$],\n"
1058 : " ::grpc::RpcMethod::CLIENT_STREAMING,\n"
1059 : " new ::grpc::ClientStreamingHandler< "
1060 : "$ns$$Service$::Service, $Request$, $Response$>(\n"
1061 2 : " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1062 9 : } else if (ServerOnlyStreaming(method)) {
1063 : printer->Print(
1064 : *vars,
1065 : "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
1066 : " $prefix$$Service$_method_names[$Idx$],\n"
1067 : " ::grpc::RpcMethod::SERVER_STREAMING,\n"
1068 : " new ::grpc::ServerStreamingHandler< "
1069 : "$ns$$Service$::Service, $Request$, $Response$>(\n"
1070 3 : " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1071 6 : } else if (BidiStreaming(method)) {
1072 : printer->Print(
1073 : *vars,
1074 : "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
1075 : " $prefix$$Service$_method_names[$Idx$],\n"
1076 : " ::grpc::RpcMethod::BIDI_STREAMING,\n"
1077 : " new ::grpc::BidiStreamingHandler< "
1078 : "$ns$$Service$::Service, $Request$, $Response$>(\n"
1079 6 : " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1080 : }
1081 : }
1082 10 : printer->Print("return service_.get();\n");
1083 10 : printer->Outdent();
1084 10 : printer->Print("}\n\n");
1085 10 : }
1086 :
1087 12 : grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
1088 : const Parameters ¶ms) {
1089 12 : grpc::string output;
1090 : {
1091 : // Scope the output stream so it closes and finalizes output to the string.
1092 12 : grpc::protobuf::io::StringOutputStream output_stream(&output);
1093 24 : grpc::protobuf::io::Printer printer(&output_stream, '$');
1094 24 : std::map<grpc::string, grpc::string> vars;
1095 : // Package string is empty or ends with a dot. It is used to fully qualify
1096 : // method names.
1097 12 : vars["Package"] = file->package();
1098 12 : if (!file->package().empty()) {
1099 12 : vars["Package"].append(".");
1100 : }
1101 12 : if (!params.services_namespace.empty()) {
1102 0 : vars["ns"] = params.services_namespace + "::";
1103 0 : vars["prefix"] = params.services_namespace;
1104 : } else {
1105 12 : vars["ns"] = "";
1106 12 : vars["prefix"] = "";
1107 : }
1108 :
1109 22 : for (int i = 0; i < file->service_count(); ++i) {
1110 10 : PrintSourceService(&printer, file->service(i), &vars);
1111 10 : printer.Print("\n");
1112 12 : }
1113 : }
1114 12 : return output;
1115 : }
1116 :
1117 12 : grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
1118 : const Parameters ¶ms) {
1119 12 : grpc::string temp;
1120 :
1121 12 : if (!file->package().empty()) {
1122 : std::vector<grpc::string> parts =
1123 12 : grpc_generator::tokenize(file->package(), ".");
1124 :
1125 43 : for (auto part = parts.begin(); part != parts.end(); part++) {
1126 31 : temp.append("} // namespace ");
1127 31 : temp.append(*part);
1128 31 : temp.append("\n");
1129 : }
1130 12 : temp.append("\n");
1131 : }
1132 :
1133 12 : return temp;
1134 : }
1135 :
1136 : } // namespace grpc_cpp_generator
|