1/*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19#include <map>
20
21#include "src/compiler/cpp_generator.h"
22
23#include <sstream>
24
25namespace grpc_cpp_generator {
26namespace {
27
28template <class T>
29grpc::string as_string(T x) {
30 std::ostringstream out;
31 out << x;
32 return out.str();
33}
34
35inline bool ClientOnlyStreaming(const grpc_generator::Method* method) {
36 return method->ClientStreaming() && !method->ServerStreaming();
37}
38
39inline bool ServerOnlyStreaming(const grpc_generator::Method* method) {
40 return !method->ClientStreaming() && method->ServerStreaming();
41}
42
43grpc::string FilenameIdentifier(const grpc::string& filename) {
44 grpc::string result;
45 for (unsigned i = 0; i < filename.size(); i++) {
46 char c = filename[i];
47 if (isalnum(c)) {
48 result.push_back(c);
49 } else {
50 static char hex[] = "0123456789abcdef";
51 result.push_back('_');
52 result.push_back(hex[(c >> 4) & 0xf]);
53 result.push_back(hex[c & 0xf]);
54 }
55 }
56 return result;
57}
58} // namespace
59
60template <class T, size_t N>
61T* array_end(T (&array)[N]) {
62 return array + N;
63}
64
65void PrintIncludes(grpc_generator::Printer* printer,
66 const std::vector<grpc::string>& headers,
67 bool use_system_headers, const grpc::string& search_path) {
68 std::map<grpc::string, grpc::string> vars;
69
70 vars["l"] = use_system_headers ? '<' : '"';
71 vars["r"] = use_system_headers ? '>' : '"';
72
73 if (!search_path.empty()) {
74 vars["l"] += search_path;
75 if (search_path[search_path.size() - 1] != '/') {
76 vars["l"] += '/';
77 }
78 }
79
80 for (auto i = headers.begin(); i != headers.end(); i++) {
81 vars["h"] = *i;
82 printer->Print(vars, "#include $l$$h$$r$\n");
83 }
84}
85
86grpc::string GetHeaderPrologue(grpc_generator::File* file,
87 const Parameters& params) {
88 grpc::string output;
89 {
90 // Scope the output stream so it closes and finalizes output to the string.
91 auto printer = file->CreatePrinter(&output);
92 std::map<grpc::string, grpc::string> vars;
93
94 vars["filename"] = file->filename();
95 vars["filename_identifier"] = FilenameIdentifier(file->filename());
96 vars["filename_base"] = file->filename_without_ext();
97 vars["message_header_ext"] = params.message_header_extension.empty()
98 ? kCppGeneratorMessageHeaderExt
99 : params.message_header_extension;
100
101 printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
102 printer->Print(vars,
103 "// If you make any local change, they will be lost.\n");
104 printer->Print(vars, "// source: $filename$\n");
105 grpc::string leading_comments = file->GetLeadingComments("//");
106 if (!leading_comments.empty()) {
107 printer->Print(vars, "// Original file comments:\n");
108 printer->PrintRaw(leading_comments.c_str());
109 }
110 printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
111 printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
112 printer->Print(vars, "\n");
113 printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
114 printer->Print(vars, file->additional_headers().c_str());
115 printer->Print(vars, "\n");
116 }
117 return output;
118}
119
120// Convert from "a/b/c.proto" to "#include \"a/b/c$message_header_ext$\"\n"
121grpc::string ImportInludeFromProtoName(const grpc::string& proto_name) {
122 return grpc::string("#include \"") +
123 proto_name.substr(0, proto_name.size() - 6) +
124 grpc::string("$message_header_ext$\"\n");
125}
126
127grpc::string GetHeaderIncludes(grpc_generator::File* file,
128 const Parameters& params) {
129 grpc::string output;
130 {
131 // Scope the output stream so it closes and finalizes output to the string.
132 auto printer = file->CreatePrinter(&output);
133 std::map<grpc::string, grpc::string> vars;
134
135 if (!params.additional_header_includes.empty()) {
136 PrintIncludes(printer.get(), params.additional_header_includes, false,
137 "");
138 }
139 // TODO(vjpai): Remove port_platform.h from header list when callback API is
140 // fully de-experimentalized since we will no longer be using
141 // macros from it.
142 static const char* headers_strs[] = {
143 "functional",
144 "grpc/impl/codegen/port_platform.h",
145 "grpcpp/impl/codegen/async_generic_service.h",
146 "grpcpp/impl/codegen/async_stream.h",
147 "grpcpp/impl/codegen/async_unary_call.h",
148 "grpcpp/impl/codegen/client_callback.h",
149 "grpcpp/impl/codegen/client_context.h",
150 "grpcpp/impl/codegen/completion_queue.h",
151 "grpcpp/impl/codegen/message_allocator.h",
152 "grpcpp/impl/codegen/method_handler.h",
153 "grpcpp/impl/codegen/proto_utils.h",
154 "grpcpp/impl/codegen/rpc_method.h",
155 "grpcpp/impl/codegen/server_callback.h",
156 "grpcpp/impl/codegen/server_callback_handlers.h",
157 "grpcpp/impl/codegen/server_context.h",
158 "grpcpp/impl/codegen/service_type.h",
159 "grpcpp/impl/codegen/status.h",
160 "grpcpp/impl/codegen/stub_options.h",
161 "grpcpp/impl/codegen/sync_stream.h",
162 };
163 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
164 PrintIncludes(printer.get(), headers, params.use_system_headers,
165 params.grpc_search_path);
166 printer->Print(vars, "\n");
167
168 vars["message_header_ext"] = params.message_header_extension.empty()
169 ? kCppGeneratorMessageHeaderExt
170 : params.message_header_extension;
171
172 if (params.include_import_headers) {
173 const std::vector<grpc::string> import_names = file->GetImportNames();
174 for (const auto& import_name : import_names) {
175 const grpc::string include_name =
176 ImportInludeFromProtoName(import_name);
177 printer->Print(vars, include_name.c_str());
178 }
179 printer->PrintRaw("\n");
180 }
181
182 if (!file->package().empty()) {
183 std::vector<grpc::string> parts = file->package_parts();
184
185 for (auto part = parts.begin(); part != parts.end(); part++) {
186 vars["part"] = *part;
187 printer->Print(vars, "namespace $part$ {\n");
188 }
189 printer->Print(vars, "\n");
190 }
191 }
192 return output;
193}
194
195void PrintHeaderClientMethodInterfaces(
196 grpc_generator::Printer* printer, const grpc_generator::Method* method,
197 std::map<grpc::string, grpc::string>* vars, bool is_public) {
198 (*vars)["Method"] = method->name();
199 (*vars)["Request"] = method->input_type_name();
200 (*vars)["Response"] = method->output_type_name();
201
202 struct {
203 grpc::string prefix;
204 grpc::string method_params; // extra arguments to method
205 grpc::string raw_args; // extra arguments to raw version of method
206 } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
207 {"PrepareAsync", "", ""}};
208
209 if (is_public) {
210 if (method->NoStreaming()) {
211 printer->Print(
212 *vars,
213 "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
214 "const $Request$& request, $Response$* response) = 0;\n");
215 for (auto async_prefix : async_prefixes) {
216 (*vars)["AsyncPrefix"] = async_prefix.prefix;
217 printer->Print(
218 *vars,
219 "std::unique_ptr< "
220 "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
221 "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
222 "const $Request$& request, "
223 "::grpc::CompletionQueue* cq) {\n");
224 printer->Indent();
225 printer->Print(
226 *vars,
227 "return std::unique_ptr< "
228 "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
229 "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
230 printer->Outdent();
231 printer->Print("}\n");
232 }
233 } else if (ClientOnlyStreaming(method)) {
234 printer->Print(
235 *vars,
236 "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
237 " $Method$("
238 "::grpc::ClientContext* context, $Response$* response) {\n");
239 printer->Indent();
240 printer->Print(
241 *vars,
242 "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
243 "($Method$Raw(context, response));\n");
244 printer->Outdent();
245 printer->Print("}\n");
246 for (auto async_prefix : async_prefixes) {
247 (*vars)["AsyncPrefix"] = async_prefix.prefix;
248 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
249 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
250 printer->Print(
251 *vars,
252 "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
253 " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
254 "$Response$* "
255 "response, "
256 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
257 printer->Indent();
258 printer->Print(*vars,
259 "return std::unique_ptr< "
260 "::grpc::ClientAsyncWriterInterface< $Request$>>("
261 "$AsyncPrefix$$Method$Raw(context, response, "
262 "cq$AsyncRawArgs$));\n");
263 printer->Outdent();
264 printer->Print("}\n");
265 }
266 } else if (ServerOnlyStreaming(method)) {
267 printer->Print(
268 *vars,
269 "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
270 " $Method$(::grpc::ClientContext* context, const $Request$& request)"
271 " {\n");
272 printer->Indent();
273 printer->Print(
274 *vars,
275 "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
276 "($Method$Raw(context, request));\n");
277 printer->Outdent();
278 printer->Print("}\n");
279 for (auto async_prefix : async_prefixes) {
280 (*vars)["AsyncPrefix"] = async_prefix.prefix;
281 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
282 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
283 printer->Print(
284 *vars,
285 "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
286 "$AsyncPrefix$$Method$("
287 "::grpc::ClientContext* context, const $Request$& request, "
288 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
289 printer->Indent();
290 printer->Print(
291 *vars,
292 "return std::unique_ptr< "
293 "::grpc::ClientAsyncReaderInterface< $Response$>>("
294 "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
295 printer->Outdent();
296 printer->Print("}\n");
297 }
298 } else if (method->BidiStreaming()) {
299 printer->Print(*vars,
300 "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
301 "$Request$, $Response$>> "
302 "$Method$(::grpc::ClientContext* context) {\n");
303 printer->Indent();
304 printer->Print(
305 *vars,
306 "return std::unique_ptr< "
307 "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
308 "$Method$Raw(context));\n");
309 printer->Outdent();
310 printer->Print("}\n");
311 for (auto async_prefix : async_prefixes) {
312 (*vars)["AsyncPrefix"] = async_prefix.prefix;
313 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
314 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
315 printer->Print(
316 *vars,
317 "std::unique_ptr< "
318 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
319 "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
320 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
321 printer->Indent();
322 printer->Print(
323 *vars,
324 "return std::unique_ptr< "
325 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
326 "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
327 printer->Outdent();
328 printer->Print("}\n");
329 }
330 }
331 } else {
332 if (method->NoStreaming()) {
333 for (auto async_prefix : async_prefixes) {
334 (*vars)["AsyncPrefix"] = async_prefix.prefix;
335 printer->Print(
336 *vars,
337 "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
338 "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
339 "const $Request$& request, "
340 "::grpc::CompletionQueue* cq) = 0;\n");
341 }
342 } else if (ClientOnlyStreaming(method)) {
343 printer->Print(
344 *vars,
345 "virtual ::grpc::ClientWriterInterface< $Request$>*"
346 " $Method$Raw("
347 "::grpc::ClientContext* context, $Response$* response) = 0;\n");
348 for (auto async_prefix : async_prefixes) {
349 (*vars)["AsyncPrefix"] = async_prefix.prefix;
350 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
351 printer->Print(
352 *vars,
353 "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
354 " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
355 "$Response$* response, "
356 "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
357 }
358 } else if (ServerOnlyStreaming(method)) {
359 printer->Print(
360 *vars,
361 "virtual ::grpc::ClientReaderInterface< $Response$>* "
362 "$Method$Raw("
363 "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
364 for (auto async_prefix : async_prefixes) {
365 (*vars)["AsyncPrefix"] = async_prefix.prefix;
366 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
367 printer->Print(
368 *vars,
369 "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
370 "$AsyncPrefix$$Method$Raw("
371 "::grpc::ClientContext* context, const $Request$& request, "
372 "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
373 }
374 } else if (method->BidiStreaming()) {
375 printer->Print(*vars,
376 "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
377 "$Response$>* "
378 "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
379 for (auto async_prefix : async_prefixes) {
380 (*vars)["AsyncPrefix"] = async_prefix.prefix;
381 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
382 printer->Print(
383 *vars,
384 "virtual ::grpc::ClientAsyncReaderWriterInterface< "
385 "$Request$, $Response$>* "
386 "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
387 "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
388 }
389 }
390 }
391}
392
393void PrintHeaderClientMethod(grpc_generator::Printer* printer,
394 const grpc_generator::Method* method,
395 std::map<grpc::string, grpc::string>* vars,
396 bool is_public) {
397 (*vars)["Method"] = method->name();
398 (*vars)["Request"] = method->input_type_name();
399 (*vars)["Response"] = method->output_type_name();
400 struct {
401 grpc::string prefix;
402 grpc::string method_params; // extra arguments to method
403 grpc::string raw_args; // extra arguments to raw version of method
404 } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
405 {"PrepareAsync", "", ""}};
406
407 if (is_public) {
408 if (method->NoStreaming()) {
409 printer->Print(
410 *vars,
411 "::grpc::Status $Method$(::grpc::ClientContext* context, "
412 "const $Request$& request, $Response$* response) override;\n");
413 for (auto async_prefix : async_prefixes) {
414 (*vars)["AsyncPrefix"] = async_prefix.prefix;
415 printer->Print(
416 *vars,
417 "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
418 "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
419 "const $Request$& request, "
420 "::grpc::CompletionQueue* cq) {\n");
421 printer->Indent();
422 printer->Print(*vars,
423 "return std::unique_ptr< "
424 "::grpc::ClientAsyncResponseReader< $Response$>>("
425 "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
426 printer->Outdent();
427 printer->Print("}\n");
428 }
429 } else if (ClientOnlyStreaming(method)) {
430 printer->Print(
431 *vars,
432 "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
433 " $Method$("
434 "::grpc::ClientContext* context, $Response$* response) {\n");
435 printer->Indent();
436 printer->Print(*vars,
437 "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
438 "($Method$Raw(context, response));\n");
439 printer->Outdent();
440 printer->Print("}\n");
441 for (auto async_prefix : async_prefixes) {
442 (*vars)["AsyncPrefix"] = async_prefix.prefix;
443 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
444 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
445 printer->Print(*vars,
446 "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
447 " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
448 "$Response$* response, "
449 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
450 printer->Indent();
451 printer->Print(
452 *vars,
453 "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
454 "$AsyncPrefix$$Method$Raw(context, response, "
455 "cq$AsyncRawArgs$));\n");
456 printer->Outdent();
457 printer->Print("}\n");
458 }
459 } else if (ServerOnlyStreaming(method)) {
460 printer->Print(
461 *vars,
462 "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
463 " $Method$(::grpc::ClientContext* context, const $Request$& request)"
464 " {\n");
465 printer->Indent();
466 printer->Print(
467 *vars,
468 "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
469 "($Method$Raw(context, request));\n");
470 printer->Outdent();
471 printer->Print("}\n");
472 for (auto async_prefix : async_prefixes) {
473 (*vars)["AsyncPrefix"] = async_prefix.prefix;
474 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
475 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
476 printer->Print(
477 *vars,
478 "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
479 "$AsyncPrefix$$Method$("
480 "::grpc::ClientContext* context, const $Request$& request, "
481 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
482 printer->Indent();
483 printer->Print(
484 *vars,
485 "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
486 "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
487 printer->Outdent();
488 printer->Print("}\n");
489 }
490 } else if (method->BidiStreaming()) {
491 printer->Print(
492 *vars,
493 "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
494 " $Method$(::grpc::ClientContext* context) {\n");
495 printer->Indent();
496 printer->Print(*vars,
497 "return std::unique_ptr< "
498 "::grpc::ClientReaderWriter< $Request$, $Response$>>("
499 "$Method$Raw(context));\n");
500 printer->Outdent();
501 printer->Print("}\n");
502 for (auto async_prefix : async_prefixes) {
503 (*vars)["AsyncPrefix"] = async_prefix.prefix;
504 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
505 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
506 printer->Print(*vars,
507 "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
508 "$Request$, $Response$>> "
509 "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
510 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
511 printer->Indent();
512 printer->Print(
513 *vars,
514 "return std::unique_ptr< "
515 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
516 "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
517 printer->Outdent();
518 printer->Print("}\n");
519 }
520 }
521 } else {
522 if (method->NoStreaming()) {
523 for (auto async_prefix : async_prefixes) {
524 (*vars)["AsyncPrefix"] = async_prefix.prefix;
525 printer->Print(
526 *vars,
527 "::grpc::ClientAsyncResponseReader< $Response$>* "
528 "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
529 "const $Request$& request, "
530 "::grpc::CompletionQueue* cq) override;\n");
531 }
532 } else if (ClientOnlyStreaming(method)) {
533 printer->Print(*vars,
534 "::grpc::ClientWriter< $Request$>* $Method$Raw("
535 "::grpc::ClientContext* context, $Response$* response) "
536 "override;\n");
537 for (auto async_prefix : async_prefixes) {
538 (*vars)["AsyncPrefix"] = async_prefix.prefix;
539 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
540 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
541 printer->Print(
542 *vars,
543 "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
544 "::grpc::ClientContext* context, $Response$* response, "
545 "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
546 }
547 } else if (ServerOnlyStreaming(method)) {
548 printer->Print(*vars,
549 "::grpc::ClientReader< $Response$>* $Method$Raw("
550 "::grpc::ClientContext* context, const $Request$& request)"
551 " override;\n");
552 for (auto async_prefix : async_prefixes) {
553 (*vars)["AsyncPrefix"] = async_prefix.prefix;
554 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
555 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
556 printer->Print(
557 *vars,
558 "::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw("
559 "::grpc::ClientContext* context, const $Request$& request, "
560 "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
561 }
562 } else if (method->BidiStreaming()) {
563 printer->Print(*vars,
564 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
565 "$Method$Raw(::grpc::ClientContext* context) override;\n");
566 for (auto async_prefix : async_prefixes) {
567 (*vars)["AsyncPrefix"] = async_prefix.prefix;
568 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
569 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
570 printer->Print(
571 *vars,
572 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
573 "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
574 "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
575 }
576 }
577 }
578}
579
580void PrintHeaderClientMethodCallbackInterfacesStart(
581 grpc_generator::Printer* printer,
582 std::map<grpc::string, grpc::string>* /*vars*/) {
583 // This declares the interface for the callback-based API. The components
584 // are pure; even though this is new (post-1.0) API, it can be pure because
585 // it is an entirely new interface that happens to be scoped within
586 // StubInterface, not new additions to StubInterface itself
587 printer->Print("class experimental_async_interface {\n");
588 // All methods in this new interface are public. There is no need for private
589 // "Raw" methods since the callback-based API returns unowned raw pointers
590 printer->Print(" public:\n");
591 printer->Indent();
592 printer->Print("virtual ~experimental_async_interface() {}\n");
593}
594
595void PrintHeaderClientMethodCallbackInterfaces(
596 grpc_generator::Printer* printer, const grpc_generator::Method* method,
597 std::map<grpc::string, grpc::string>* vars) {
598 (*vars)["Method"] = method->name();
599 (*vars)["Request"] = method->input_type_name();
600 (*vars)["Response"] = method->output_type_name();
601
602 if (method->NoStreaming()) {
603 printer->Print(*vars,
604 "virtual void $Method$(::grpc::ClientContext* context, "
605 "const $Request$* request, $Response$* response, "
606 "std::function<void(::grpc::Status)>) = 0;\n");
607 printer->Print(*vars,
608 "virtual void $Method$(::grpc::ClientContext* context, "
609 "const ::grpc::ByteBuffer* request, $Response$* response, "
610 "std::function<void(::grpc::Status)>) = 0;\n");
611 // TODO(vjpai): Remove experimental versions and macros when callback API is
612 // fully de-experimentalized.
613 printer->Print(*vars,
614 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
615 "virtual void $Method$(::grpc::ClientContext* context, "
616 "const $Request$* request, $Response$* response, "
617 "::grpc::ClientUnaryReactor* reactor) = 0;\n"
618 "#else\n"
619 "virtual void $Method$(::grpc::ClientContext* context, "
620 "const $Request$* request, $Response$* response, "
621 "::grpc::experimental::ClientUnaryReactor* reactor) = 0;\n"
622 "#endif\n");
623 printer->Print(*vars,
624 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
625 "virtual void $Method$(::grpc::ClientContext* context, "
626 "const ::grpc::ByteBuffer* request, $Response$* response, "
627 "::grpc::ClientUnaryReactor* reactor) = 0;\n"
628 "#else\n"
629 "virtual void $Method$(::grpc::ClientContext* context, "
630 "const ::grpc::ByteBuffer* request, $Response$* response, "
631 "::grpc::experimental::ClientUnaryReactor* reactor) = 0;\n"
632 "#endif\n");
633 } else if (ClientOnlyStreaming(method)) {
634 printer->Print(*vars,
635 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
636 "virtual void $Method$(::grpc::ClientContext* context, "
637 "$Response$* response, "
638 "::grpc::ClientWriteReactor< $Request$>* "
639 "reactor) = 0;\n"
640 "#else\n"
641 "virtual void $Method$(::grpc::ClientContext* context, "
642 "$Response$* response, "
643 "::grpc::experimental::ClientWriteReactor< $Request$>* "
644 "reactor) = 0;\n"
645 "#endif\n");
646 } else if (ServerOnlyStreaming(method)) {
647 printer->Print(*vars,
648 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
649 "virtual void $Method$(::grpc::ClientContext* context, "
650 "$Request$* request, "
651 "::grpc::ClientReadReactor< $Response$>* "
652 "reactor) = 0;\n"
653 "#else\n"
654 "virtual void $Method$(::grpc::ClientContext* context, "
655 "$Request$* request, "
656 "::grpc::experimental::ClientReadReactor< $Response$>* "
657 "reactor) = 0;\n"
658 "#endif\n");
659 } else if (method->BidiStreaming()) {
660 printer->Print(*vars,
661 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
662 "virtual void $Method$(::grpc::ClientContext* context, "
663 "::grpc::ClientBidiReactor< "
664 "$Request$,$Response$>* reactor) = 0;\n"
665 "#else\n"
666 "virtual void $Method$(::grpc::ClientContext* context, "
667 "::grpc::experimental::ClientBidiReactor< "
668 "$Request$,$Response$>* reactor) = 0;\n"
669 "#endif\n");
670 }
671}
672
673void PrintHeaderClientMethodCallbackInterfacesEnd(
674 grpc_generator::Printer* printer,
675 std::map<grpc::string, grpc::string>* /*vars*/) {
676 printer->Outdent();
677 printer->Print("};\n");
678 printer->Print(
679 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
680 "typedef class experimental_async_interface async_interface;\n"
681 "#endif\n");
682
683 // Declare a function to give the async stub contents. It can't be pure
684 // since this is a new API in StubInterface, but it is meaningless by default
685 // (since any stub that wants to use it must have its own implementation of
686 // the callback functions therein), so make the default return value nullptr.
687 // Intentionally include the word "class" to avoid possible shadowing.
688 printer->Print(
689 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
690 "async_interface* async() { return experimental_async(); }\n"
691 "#endif\n");
692 printer->Print(
693 "virtual class experimental_async_interface* experimental_async() { "
694 "return nullptr; }\n");
695}
696
697void PrintHeaderClientMethodCallbackStart(
698 grpc_generator::Printer* printer,
699 std::map<grpc::string, grpc::string>* /*vars*/) {
700 // This declares the stub entry for the callback-based API.
701 printer->Print("class experimental_async final :\n");
702 printer->Print(" public StubInterface::experimental_async_interface {\n");
703 printer->Print(" public:\n");
704 printer->Indent();
705}
706
707void PrintHeaderClientMethodCallback(
708 grpc_generator::Printer* printer, const grpc_generator::Method* method,
709 std::map<grpc::string, grpc::string>* vars) {
710 (*vars)["Method"] = method->name();
711 (*vars)["Request"] = method->input_type_name();
712 (*vars)["Response"] = method->output_type_name();
713
714 if (method->NoStreaming()) {
715 printer->Print(*vars,
716 "void $Method$(::grpc::ClientContext* context, "
717 "const $Request$* request, $Response$* response, "
718 "std::function<void(::grpc::Status)>) override;\n");
719 printer->Print(*vars,
720 "void $Method$(::grpc::ClientContext* context, "
721 "const ::grpc::ByteBuffer* request, $Response$* response, "
722 "std::function<void(::grpc::Status)>) override;\n");
723 printer->Print(
724 *vars,
725 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
726 "void $Method$(::grpc::ClientContext* context, "
727 "const $Request$* request, $Response$* response, "
728 "::grpc::ClientUnaryReactor* reactor) override;\n"
729 "#else\n"
730 "void $Method$(::grpc::ClientContext* context, "
731 "const $Request$* request, $Response$* response, "
732 "::grpc::experimental::ClientUnaryReactor* reactor) override;\n"
733 "#endif\n");
734 printer->Print(
735 *vars,
736 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
737 "void $Method$(::grpc::ClientContext* context, "
738 "const ::grpc::ByteBuffer* request, $Response$* response, "
739 "::grpc::ClientUnaryReactor* reactor) override;\n"
740 "#else\n"
741 "void $Method$(::grpc::ClientContext* context, "
742 "const ::grpc::ByteBuffer* request, $Response$* response, "
743 "::grpc::experimental::ClientUnaryReactor* reactor) override;\n"
744 "#endif\n");
745 } else if (ClientOnlyStreaming(method)) {
746 printer->Print(*vars,
747 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
748 "void $Method$(::grpc::ClientContext* context, "
749 "$Response$* response, "
750 "::grpc::ClientWriteReactor< $Request$>* "
751 "reactor) override;\n"
752 "#else\n"
753 "void $Method$(::grpc::ClientContext* context, "
754 "$Response$* response, "
755 "::grpc::experimental::ClientWriteReactor< $Request$>* "
756 "reactor) override;\n"
757 "#endif\n");
758 } else if (ServerOnlyStreaming(method)) {
759 printer->Print(*vars,
760 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
761 "void $Method$(::grpc::ClientContext* context, "
762 "$Request$* request, "
763 "::grpc::ClientReadReactor< $Response$>* "
764 "reactor) override;\n"
765 "#else\n"
766 "void $Method$(::grpc::ClientContext* context, "
767 "$Request$* request, "
768 "::grpc::experimental::ClientReadReactor< $Response$>* "
769 "reactor) override;\n"
770 "#endif\n");
771
772 } else if (method->BidiStreaming()) {
773 printer->Print(*vars,
774 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
775 "void $Method$(::grpc::ClientContext* context, "
776 "::grpc::ClientBidiReactor< "
777 "$Request$,$Response$>* reactor) override;\n"
778 "#else\n"
779 "void $Method$(::grpc::ClientContext* context, "
780 "::grpc::experimental::ClientBidiReactor< "
781 "$Request$,$Response$>* reactor) override;\n"
782 "#endif\n");
783 }
784}
785
786void PrintHeaderClientMethodCallbackEnd(
787 grpc_generator::Printer* printer,
788 std::map<grpc::string, grpc::string>* /*vars*/) {
789 printer->Outdent();
790 printer->Print(" private:\n");
791 printer->Indent();
792 printer->Print("friend class Stub;\n");
793 printer->Print("explicit experimental_async(Stub* stub): stub_(stub) { }\n");
794 // include a function with a dummy use of stub_ to avoid an unused
795 // private member warning for service with no methods
796 printer->Print("Stub* stub() { return stub_; }\n");
797 printer->Print("Stub* stub_;\n");
798 printer->Outdent();
799 printer->Print("};\n");
800
801 printer->Print(
802 "class experimental_async_interface* experimental_async() override { "
803 "return &async_stub_; }\n");
804}
805
806void PrintHeaderClientMethodData(grpc_generator::Printer* printer,
807 const grpc_generator::Method* method,
808 std::map<grpc::string, grpc::string>* vars) {
809 (*vars)["Method"] = method->name();
810 printer->Print(*vars,
811 "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
812}
813
814void PrintHeaderServerMethodSync(grpc_generator::Printer* printer,
815 const grpc_generator::Method* method,
816 std::map<grpc::string, grpc::string>* vars) {
817 (*vars)["Method"] = method->name();
818 (*vars)["Request"] = method->input_type_name();
819 (*vars)["Response"] = method->output_type_name();
820 printer->Print(method->GetLeadingComments("//").c_str());
821 if (method->NoStreaming()) {
822 printer->Print(*vars,
823 "virtual ::grpc::Status $Method$("
824 "::grpc::ServerContext* context, const $Request$* request, "
825 "$Response$* response);\n");
826 } else if (ClientOnlyStreaming(method)) {
827 printer->Print(*vars,
828 "virtual ::grpc::Status $Method$("
829 "::grpc::ServerContext* context, "
830 "::grpc::ServerReader< $Request$>* reader, "
831 "$Response$* response);\n");
832 } else if (ServerOnlyStreaming(method)) {
833 printer->Print(*vars,
834 "virtual ::grpc::Status $Method$("
835 "::grpc::ServerContext* context, const $Request$* request, "
836 "::grpc::ServerWriter< $Response$>* writer);\n");
837 } else if (method->BidiStreaming()) {
838 printer->Print(
839 *vars,
840 "virtual ::grpc::Status $Method$("
841 "::grpc::ServerContext* context, "
842 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
843 "\n");
844 }
845 printer->Print(method->GetTrailingComments("//").c_str());
846}
847
848// Helper generator. Disables the sync API for Request and Response, then adds
849// in an async API for RealRequest and RealResponse types. This is to be used
850// to generate async and raw async APIs.
851void PrintHeaderServerAsyncMethodsHelper(
852 grpc_generator::Printer* printer, const grpc_generator::Method* method,
853 std::map<grpc::string, grpc::string>* vars) {
854 if (method->NoStreaming()) {
855 printer->Print(
856 *vars,
857 "// disable synchronous version of this method\n"
858 "::grpc::Status $Method$("
859 "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
860 "$Response$* /*response*/) override {\n"
861 " abort();\n"
862 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
863 "}\n");
864 printer->Print(
865 *vars,
866 "void Request$Method$("
867 "::grpc::ServerContext* context, $RealRequest$* request, "
868 "::grpc::ServerAsyncResponseWriter< $RealResponse$>* response, "
869 "::grpc::CompletionQueue* new_call_cq, "
870 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
871 printer->Print(*vars,
872 " ::grpc::Service::RequestAsyncUnary($Idx$, context, "
873 "request, response, new_call_cq, notification_cq, tag);\n");
874 printer->Print("}\n");
875 } else if (ClientOnlyStreaming(method)) {
876 printer->Print(
877 *vars,
878 "// disable synchronous version of this method\n"
879 "::grpc::Status $Method$("
880 "::grpc::ServerContext* /*context*/, "
881 "::grpc::ServerReader< $Request$>* /*reader*/, "
882 "$Response$* /*response*/) override {\n"
883 " abort();\n"
884 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
885 "}\n");
886 printer->Print(
887 *vars,
888 "void Request$Method$("
889 "::grpc::ServerContext* context, "
890 "::grpc::ServerAsyncReader< $RealResponse$, $RealRequest$>* reader, "
891 "::grpc::CompletionQueue* new_call_cq, "
892 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
893 printer->Print(*vars,
894 " ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
895 "context, reader, new_call_cq, notification_cq, tag);\n");
896 printer->Print("}\n");
897 } else if (ServerOnlyStreaming(method)) {
898 printer->Print(
899 *vars,
900 "// disable synchronous version of this method\n"
901 "::grpc::Status $Method$("
902 "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
903 "::grpc::ServerWriter< $Response$>* /*writer*/) override "
904 "{\n"
905 " abort();\n"
906 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
907 "}\n");
908 printer->Print(
909 *vars,
910 "void Request$Method$("
911 "::grpc::ServerContext* context, $RealRequest$* request, "
912 "::grpc::ServerAsyncWriter< $RealResponse$>* writer, "
913 "::grpc::CompletionQueue* new_call_cq, "
914 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
915 printer->Print(
916 *vars,
917 " ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
918 "context, request, writer, new_call_cq, notification_cq, tag);\n");
919 printer->Print("}\n");
920 } else if (method->BidiStreaming()) {
921 printer->Print(
922 *vars,
923 "// disable synchronous version of this method\n"
924 "::grpc::Status $Method$("
925 "::grpc::ServerContext* /*context*/, "
926 "::grpc::ServerReaderWriter< $Response$, $Request$>* /*stream*/) "
927 " override {\n"
928 " abort();\n"
929 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
930 "}\n");
931 printer->Print(
932 *vars,
933 "void Request$Method$("
934 "::grpc::ServerContext* context, "
935 "::grpc::ServerAsyncReaderWriter< $RealResponse$, $RealRequest$>* "
936 "stream, "
937 "::grpc::CompletionQueue* new_call_cq, "
938 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
939 printer->Print(*vars,
940 " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
941 "context, stream, new_call_cq, notification_cq, tag);\n");
942 printer->Print("}\n");
943 }
944}
945
946void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
947 const grpc_generator::Method* method,
948 std::map<grpc::string, grpc::string>* vars) {
949 (*vars)["Method"] = method->name();
950 // These will be disabled
951 (*vars)["Request"] = method->input_type_name();
952 (*vars)["Response"] = method->output_type_name();
953 // These will be used for the async API
954 (*vars)["RealRequest"] = method->input_type_name();
955 (*vars)["RealResponse"] = method->output_type_name();
956 printer->Print(*vars, "template <class BaseClass>\n");
957 printer->Print(*vars,
958 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
959 printer->Print(
960 " private:\n"
961 " void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
962 "{}\n");
963 printer->Print(" public:\n");
964 printer->Indent();
965 printer->Print(*vars,
966 "WithAsyncMethod_$Method$() {\n"
967 " ::grpc::Service::MarkMethodAsync($Idx$);\n"
968 "}\n");
969 printer->Print(*vars,
970 "~WithAsyncMethod_$Method$() override {\n"
971 " BaseClassMustBeDerivedFromService(this);\n"
972 "}\n");
973 PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
974 printer->Outdent();
975 printer->Print(*vars, "};\n");
976}
977
978// Helper generator. Disables the sync API for Request and Response, then adds
979// in a callback API for RealRequest and RealResponse types. This is to be used
980// to generate callback and raw callback APIs.
981void PrintHeaderServerCallbackMethodsHelper(
982 grpc_generator::Printer* printer, const grpc_generator::Method* method,
983 std::map<grpc::string, grpc::string>* vars) {
984 if (method->NoStreaming()) {
985 printer->Print(
986 *vars,
987 "// disable synchronous version of this method\n"
988 "::grpc::Status $Method$("
989 "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
990 "$Response$* /*response*/) override {\n"
991 " abort();\n"
992 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
993 "}\n");
994 printer->Print(*vars,
995 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
996 "virtual ::grpc::ServerUnaryReactor* $Method$(\n"
997 " ::grpc::CallbackServerContext* /*context*/, "
998 "const $RealRequest$* /*request*/, "
999 "$RealResponse$* /*response*/)\n"
1000 "#else\n"
1001 "virtual ::grpc::experimental::ServerUnaryReactor* "
1002 "$Method$(\n"
1003 " ::grpc::experimental::CallbackServerContext* "
1004 "/*context*/, const $RealRequest$* /*request*/, "
1005 "$RealResponse$* /*response*/)\n"
1006 "#endif\n"
1007 " { return nullptr; }\n");
1008 } else if (ClientOnlyStreaming(method)) {
1009 printer->Print(
1010 *vars,
1011 "// disable synchronous version of this method\n"
1012 "::grpc::Status $Method$("
1013 "::grpc::ServerContext* /*context*/, "
1014 "::grpc::ServerReader< $Request$>* /*reader*/, "
1015 "$Response$* /*response*/) override {\n"
1016 " abort();\n"
1017 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1018 "}\n");
1019 printer->Print(*vars,
1020 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1021 "virtual ::grpc::ServerReadReactor< "
1022 "$RealRequest$>* $Method$(\n"
1023 " ::grpc::CallbackServerContext* "
1024 "/*context*/, $RealResponse$* /*response*/)\n"
1025 "#else\n"
1026 "virtual ::grpc::experimental::ServerReadReactor< "
1027 "$RealRequest$>* $Method$(\n"
1028 " ::grpc::experimental::CallbackServerContext* "
1029 "/*context*/, $RealResponse$* /*response*/)\n"
1030 "#endif\n"
1031 " { return nullptr; }\n");
1032 } else if (ServerOnlyStreaming(method)) {
1033 printer->Print(
1034 *vars,
1035 "// disable synchronous version of this method\n"
1036 "::grpc::Status $Method$("
1037 "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
1038 "::grpc::ServerWriter< $Response$>* /*writer*/) override "
1039 "{\n"
1040 " abort();\n"
1041 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1042 "}\n");
1043 printer->Print(
1044 *vars,
1045 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1046 "virtual ::grpc::ServerWriteReactor< $RealResponse$>* $Method$(\n"
1047 " ::grpc::CallbackServerContext* "
1048 "/*context*/, const $RealRequest$* /*request*/)\n"
1049 "#else\n"
1050 "virtual ::grpc::experimental::ServerWriteReactor< $RealResponse$>* "
1051 "$Method$(\n"
1052 " ::grpc::experimental::CallbackServerContext* "
1053 "/*context*/, const $RealRequest$* /*request*/)\n"
1054 "#endif\n"
1055 " { return nullptr; }\n");
1056 } else if (method->BidiStreaming()) {
1057 printer->Print(
1058 *vars,
1059 "// disable synchronous version of this method\n"
1060 "::grpc::Status $Method$("
1061 "::grpc::ServerContext* /*context*/, "
1062 "::grpc::ServerReaderWriter< $Response$, $Request$>* /*stream*/) "
1063 " override {\n"
1064 " abort();\n"
1065 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1066 "}\n");
1067 printer->Print(
1068 *vars,
1069 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1070 "virtual ::grpc::ServerBidiReactor< $RealRequest$, $RealResponse$>* "
1071 "$Method$(\n"
1072 " ::grpc::CallbackServerContext* /*context*/)\n"
1073 "#else\n"
1074 "virtual ::grpc::experimental::ServerBidiReactor< "
1075 "$RealRequest$, $RealResponse$>* "
1076 "$Method$(\n"
1077 " ::grpc::experimental::CallbackServerContext* /*context*/)\n"
1078 "#endif\n"
1079 " { return nullptr; }\n");
1080 }
1081}
1082
1083void PrintHeaderServerMethodCallback(
1084 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1085 std::map<grpc::string, grpc::string>* vars) {
1086 (*vars)["Method"] = method->name();
1087 // These will be disabled
1088 (*vars)["Request"] = method->input_type_name();
1089 (*vars)["Response"] = method->output_type_name();
1090 // These will be used for the callback API
1091 (*vars)["RealRequest"] = method->input_type_name();
1092 (*vars)["RealResponse"] = method->output_type_name();
1093 printer->Print(*vars, "template <class BaseClass>\n");
1094 printer->Print(
1095 *vars,
1096 "class ExperimentalWithCallbackMethod_$Method$ : public BaseClass {\n");
1097 printer->Print(
1098 " private:\n"
1099 " void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
1100 "{}\n");
1101 printer->Print(" public:\n");
1102 printer->Indent();
1103 printer->Print(*vars, "ExperimentalWithCallbackMethod_$Method$() {\n");
1104 if (method->NoStreaming()) {
1105 printer->Print(
1106 *vars,
1107 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1108 " ::grpc::Service::\n"
1109 "#else\n"
1110 " ::grpc::Service::experimental().\n"
1111 "#endif\n"
1112 " MarkMethodCallback($Idx$,\n"
1113 " new ::grpc_impl::internal::CallbackUnaryHandler< "
1114 "$RealRequest$, $RealResponse$>(\n"
1115 " [this](\n"
1116 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1117 " ::grpc::CallbackServerContext*\n"
1118 "#else\n"
1119 " ::grpc::experimental::CallbackServerContext*\n"
1120 "#endif\n"
1121 " context, "
1122 "const $RealRequest$* "
1123 "request, "
1124 "$RealResponse$* response) { "
1125 "return this->$Method$(context, request, response); }));}\n");
1126 printer->Print(*vars,
1127 "void SetMessageAllocatorFor_$Method$(\n"
1128 " ::grpc::experimental::MessageAllocator< "
1129 "$RealRequest$, $RealResponse$>* allocator) {\n"
1130 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1131 " ::grpc::internal::MethodHandler* const handler = "
1132 "::grpc::Service::GetHandler($Idx$);\n"
1133 "#else\n"
1134 " ::grpc::internal::MethodHandler* const handler = "
1135 "::grpc::Service::experimental().GetHandler($Idx$);\n"
1136 "#endif\n"
1137 " static_cast<::grpc_impl::internal::CallbackUnaryHandler< "
1138 "$RealRequest$, $RealResponse$>*>(handler)\n"
1139 " ->SetMessageAllocator(allocator);\n");
1140 } else if (ClientOnlyStreaming(method)) {
1141 printer->Print(
1142 *vars,
1143 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1144 " ::grpc::Service::\n"
1145 "#else\n"
1146 " ::grpc::Service::experimental().\n"
1147 "#endif\n"
1148 " MarkMethodCallback($Idx$,\n"
1149 " new ::grpc_impl::internal::CallbackClientStreamingHandler< "
1150 "$RealRequest$, $RealResponse$>(\n"
1151 " [this](\n"
1152 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1153 " ::grpc::CallbackServerContext*\n"
1154 "#else\n"
1155 " ::grpc::experimental::CallbackServerContext*\n"
1156 "#endif\n"
1157 " context, "
1158 "$RealResponse$* "
1159 "response) { "
1160 "return this->$Method$(context, response); }));\n");
1161 } else if (ServerOnlyStreaming(method)) {
1162 printer->Print(
1163 *vars,
1164 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1165 " ::grpc::Service::\n"
1166 "#else\n"
1167 " ::grpc::Service::experimental().\n"
1168 "#endif\n"
1169 " MarkMethodCallback($Idx$,\n"
1170 " new ::grpc_impl::internal::CallbackServerStreamingHandler< "
1171 "$RealRequest$, $RealResponse$>(\n"
1172 " [this](\n"
1173 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1174 " ::grpc::CallbackServerContext*\n"
1175 "#else\n"
1176 " ::grpc::experimental::CallbackServerContext*\n"
1177 "#endif\n"
1178 " context, "
1179 "const $RealRequest$* "
1180 "request) { "
1181 "return this->$Method$(context, request); }));\n");
1182 } else if (method->BidiStreaming()) {
1183 printer->Print(
1184 *vars,
1185 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1186 " ::grpc::Service::\n"
1187 "#else\n"
1188 " ::grpc::Service::experimental().\n"
1189 "#endif\n"
1190 " MarkMethodCallback($Idx$,\n"
1191 " new ::grpc_impl::internal::CallbackBidiHandler< "
1192 "$RealRequest$, $RealResponse$>(\n"
1193 " [this](\n"
1194 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1195 " ::grpc::CallbackServerContext*\n"
1196 "#else\n"
1197 " ::grpc::experimental::CallbackServerContext*\n"
1198 "#endif\n"
1199 " context) "
1200 "{ return this->$Method$(context); }));\n");
1201 }
1202 printer->Print(*vars, "}\n");
1203 printer->Print(*vars,
1204 "~ExperimentalWithCallbackMethod_$Method$() override {\n"
1205 " BaseClassMustBeDerivedFromService(this);\n"
1206 "}\n");
1207 PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
1208 printer->Outdent();
1209 printer->Print(*vars, "};\n");
1210}
1211
1212void PrintHeaderServerMethodRawCallback(
1213 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1214 std::map<grpc::string, grpc::string>* vars) {
1215 (*vars)["Method"] = method->name();
1216 // These will be disabled
1217 (*vars)["Request"] = method->input_type_name();
1218 (*vars)["Response"] = method->output_type_name();
1219 // These will be used for raw API
1220 (*vars)["RealRequest"] = "::grpc::ByteBuffer";
1221 (*vars)["RealResponse"] = "::grpc::ByteBuffer";
1222 printer->Print(*vars, "template <class BaseClass>\n");
1223 printer->Print(*vars,
1224 "class ExperimentalWithRawCallbackMethod_$Method$ : public "
1225 "BaseClass {\n");
1226 printer->Print(
1227 " private:\n"
1228 " void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
1229 "{}\n");
1230 printer->Print(" public:\n");
1231 printer->Indent();
1232 printer->Print(*vars, "ExperimentalWithRawCallbackMethod_$Method$() {\n");
1233 if (method->NoStreaming()) {
1234 printer->Print(
1235 *vars,
1236 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1237 " ::grpc::Service::\n"
1238 "#else\n"
1239 " ::grpc::Service::experimental().\n"
1240 "#endif\n"
1241 " MarkMethodRawCallback($Idx$,\n"
1242 " new ::grpc_impl::internal::CallbackUnaryHandler< "
1243 "$RealRequest$, $RealResponse$>(\n"
1244 " [this](\n"
1245 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1246 " ::grpc::CallbackServerContext*\n"
1247 "#else\n"
1248 " ::grpc::experimental::CallbackServerContext*\n"
1249 "#endif\n"
1250 " context, "
1251 "const $RealRequest$* "
1252 "request, "
1253 "$RealResponse$* response) { return "
1254 "this->$Method$(context, request, response); }));\n");
1255 } else if (ClientOnlyStreaming(method)) {
1256 printer->Print(
1257 *vars,
1258 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1259 " ::grpc::Service::\n"
1260 "#else\n"
1261 " ::grpc::Service::experimental().\n"
1262 "#endif\n"
1263 " MarkMethodRawCallback($Idx$,\n"
1264 " new ::grpc_impl::internal::CallbackClientStreamingHandler< "
1265 "$RealRequest$, $RealResponse$>(\n"
1266 " [this](\n"
1267 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1268 " ::grpc::CallbackServerContext*\n"
1269 "#else\n"
1270 " ::grpc::experimental::CallbackServerContext*\n"
1271 "#endif\n"
1272 " context, "
1273 "$RealResponse$* response) "
1274 "{ return this->$Method$(context, response); }));\n");
1275 } else if (ServerOnlyStreaming(method)) {
1276 printer->Print(
1277 *vars,
1278 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1279 " ::grpc::Service::\n"
1280 "#else\n"
1281 " ::grpc::Service::experimental().\n"
1282 "#endif\n"
1283 " MarkMethodRawCallback($Idx$,\n"
1284 " new ::grpc_impl::internal::CallbackServerStreamingHandler< "
1285 "$RealRequest$, $RealResponse$>(\n"
1286 " [this](\n"
1287 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1288 " ::grpc::CallbackServerContext*\n"
1289 "#else\n"
1290 " ::grpc::experimental::CallbackServerContext*\n"
1291 "#endif\n"
1292 " context, "
1293 "const"
1294 "$RealRequest$* request) { return "
1295 "this->$Method$(context, request); }));\n");
1296 } else if (method->BidiStreaming()) {
1297 printer->Print(
1298 *vars,
1299 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1300 " ::grpc::Service::\n"
1301 "#else\n"
1302 " ::grpc::Service::experimental().\n"
1303 "#endif\n"
1304 " MarkMethodRawCallback($Idx$,\n"
1305 " new ::grpc_impl::internal::CallbackBidiHandler< "
1306 "$RealRequest$, $RealResponse$>(\n"
1307 " [this](\n"
1308 "#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n"
1309 " ::grpc::CallbackServerContext*\n"
1310 "#else\n"
1311 " ::grpc::experimental::CallbackServerContext*\n"
1312 "#endif\n"
1313 " context) "
1314 "{ return this->$Method$(context); }));\n");
1315 }
1316 printer->Print(*vars, "}\n");
1317 printer->Print(*vars,
1318 "~ExperimentalWithRawCallbackMethod_$Method$() override {\n"
1319 " BaseClassMustBeDerivedFromService(this);\n"
1320 "}\n");
1321 PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
1322 printer->Outdent();
1323 printer->Print(*vars, "};\n");
1324}
1325
1326void PrintHeaderServerMethodStreamedUnary(
1327 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1328 std::map<grpc::string, grpc::string>* vars) {
1329 (*vars)["Method"] = method->name();
1330 (*vars)["Request"] = method->input_type_name();
1331 (*vars)["Response"] = method->output_type_name();
1332 if (method->NoStreaming()) {
1333 printer->Print(*vars, "template <class BaseClass>\n");
1334 printer->Print(*vars,
1335 "class WithStreamedUnaryMethod_$Method$ : "
1336 "public BaseClass {\n");
1337 printer->Print(
1338 " private:\n"
1339 " void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
1340 "{}\n");
1341 printer->Print(" public:\n");
1342 printer->Indent();
1343 printer->Print(*vars,
1344 "WithStreamedUnaryMethod_$Method$() {\n"
1345 " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
1346 " new ::grpc::internal::StreamedUnaryHandler< $Request$, "
1347 "$Response$>(std::bind"
1348 "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
1349 "Streamed$Method$, this, std::placeholders::_1, "
1350 "std::placeholders::_2)));\n"
1351 "}\n");
1352 printer->Print(*vars,
1353 "~WithStreamedUnaryMethod_$Method$() override {\n"
1354 " BaseClassMustBeDerivedFromService(this);\n"
1355 "}\n");
1356 printer->Print(
1357 *vars,
1358 "// disable regular version of this method\n"
1359 "::grpc::Status $Method$("
1360 "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
1361 "$Response$* /*response*/) override {\n"
1362 " abort();\n"
1363 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1364 "}\n");
1365 printer->Print(*vars,
1366 "// replace default version of method with streamed unary\n"
1367 "virtual ::grpc::Status Streamed$Method$("
1368 "::grpc::ServerContext* context, "
1369 "::grpc::ServerUnaryStreamer< "
1370 "$Request$,$Response$>* server_unary_streamer)"
1371 " = 0;\n");
1372 printer->Outdent();
1373 printer->Print(*vars, "};\n");
1374 }
1375}
1376
1377void PrintHeaderServerMethodSplitStreaming(
1378 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1379 std::map<grpc::string, grpc::string>* vars) {
1380 (*vars)["Method"] = method->name();
1381 (*vars)["Request"] = method->input_type_name();
1382 (*vars)["Response"] = method->output_type_name();
1383 if (ServerOnlyStreaming(method)) {
1384 printer->Print(*vars, "template <class BaseClass>\n");
1385 printer->Print(*vars,
1386 "class WithSplitStreamingMethod_$Method$ : "
1387 "public BaseClass {\n");
1388 printer->Print(
1389 " private:\n"
1390 " void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
1391 "{}\n");
1392 printer->Print(" public:\n");
1393 printer->Indent();
1394 printer->Print(
1395 *vars,
1396 "WithSplitStreamingMethod_$Method$() {\n"
1397 " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
1398 " new ::grpc::internal::SplitServerStreamingHandler< $Request$, "
1399 "$Response$>(std::bind"
1400 "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
1401 "Streamed$Method$, this, std::placeholders::_1, "
1402 "std::placeholders::_2)));\n"
1403 "}\n");
1404 printer->Print(*vars,
1405 "~WithSplitStreamingMethod_$Method$() override {\n"
1406 " BaseClassMustBeDerivedFromService(this);\n"
1407 "}\n");
1408 printer->Print(
1409 *vars,
1410 "// disable regular version of this method\n"
1411 "::grpc::Status $Method$("
1412 "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
1413 "::grpc::ServerWriter< $Response$>* /*writer*/) override "
1414 "{\n"
1415 " abort();\n"
1416 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1417 "}\n");
1418 printer->Print(*vars,
1419 "// replace default version of method with split streamed\n"
1420 "virtual ::grpc::Status Streamed$Method$("
1421 "::grpc::ServerContext* context, "
1422 "::grpc::ServerSplitStreamer< "
1423 "$Request$,$Response$>* server_split_streamer)"
1424 " = 0;\n");
1425 printer->Outdent();
1426 printer->Print(*vars, "};\n");
1427 }
1428}
1429
1430void PrintHeaderServerMethodGeneric(
1431 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1432 std::map<grpc::string, grpc::string>* vars) {
1433 (*vars)["Method"] = method->name();
1434 (*vars)["Request"] = method->input_type_name();
1435 (*vars)["Response"] = method->output_type_name();
1436 printer->Print(*vars, "template <class BaseClass>\n");
1437 printer->Print(*vars,
1438 "class WithGenericMethod_$Method$ : public BaseClass {\n");
1439 printer->Print(
1440 " private:\n"
1441 " void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
1442 "{}\n");
1443 printer->Print(" public:\n");
1444 printer->Indent();
1445 printer->Print(*vars,
1446 "WithGenericMethod_$Method$() {\n"
1447 " ::grpc::Service::MarkMethodGeneric($Idx$);\n"
1448 "}\n");
1449 printer->Print(*vars,
1450 "~WithGenericMethod_$Method$() override {\n"
1451 " BaseClassMustBeDerivedFromService(this);\n"
1452 "}\n");
1453 if (method->NoStreaming()) {
1454 printer->Print(
1455 *vars,
1456 "// disable synchronous version of this method\n"
1457 "::grpc::Status $Method$("
1458 "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
1459 "$Response$* /*response*/) override {\n"
1460 " abort();\n"
1461 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1462 "}\n");
1463 } else if (ClientOnlyStreaming(method)) {
1464 printer->Print(
1465 *vars,
1466 "// disable synchronous version of this method\n"
1467 "::grpc::Status $Method$("
1468 "::grpc::ServerContext* /*context*/, "
1469 "::grpc::ServerReader< $Request$>* /*reader*/, "
1470 "$Response$* /*response*/) override {\n"
1471 " abort();\n"
1472 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1473 "}\n");
1474 } else if (ServerOnlyStreaming(method)) {
1475 printer->Print(
1476 *vars,
1477 "// disable synchronous version of this method\n"
1478 "::grpc::Status $Method$("
1479 "::grpc::ServerContext* /*context*/, const $Request$* /*request*/, "
1480 "::grpc::ServerWriter< $Response$>* /*writer*/) override "
1481 "{\n"
1482 " abort();\n"
1483 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1484 "}\n");
1485 } else if (method->BidiStreaming()) {
1486 printer->Print(
1487 *vars,
1488 "// disable synchronous version of this method\n"
1489 "::grpc::Status $Method$("
1490 "::grpc::ServerContext* /*context*/, "
1491 "::grpc::ServerReaderWriter< $Response$, $Request$>* /*stream*/) "
1492 " override {\n"
1493 " abort();\n"
1494 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1495 "}\n");
1496 }
1497 printer->Outdent();
1498 printer->Print(*vars, "};\n");
1499}
1500
1501void PrintHeaderServerMethodRaw(grpc_generator::Printer* printer,
1502 const grpc_generator::Method* method,
1503 std::map<grpc::string, grpc::string>* vars) {
1504 (*vars)["Method"] = method->name();
1505 // These will be disabled
1506 (*vars)["Request"] = method->input_type_name();
1507 (*vars)["Response"] = method->output_type_name();
1508 // These will be used for raw API
1509 (*vars)["RealRequest"] = "::grpc::ByteBuffer";
1510 (*vars)["RealResponse"] = "::grpc::ByteBuffer";
1511 printer->Print(*vars, "template <class BaseClass>\n");
1512 printer->Print(*vars, "class WithRawMethod_$Method$ : public BaseClass {\n");
1513 printer->Print(
1514 " private:\n"
1515 " void BaseClassMustBeDerivedFromService(const Service* /*service*/) "
1516 "{}\n");
1517 printer->Print(" public:\n");
1518 printer->Indent();
1519 printer->Print(*vars,
1520 "WithRawMethod_$Method$() {\n"
1521 " ::grpc::Service::MarkMethodRaw($Idx$);\n"
1522 "}\n");
1523 printer->Print(*vars,
1524 "~WithRawMethod_$Method$() override {\n"
1525 " BaseClassMustBeDerivedFromService(this);\n"
1526 "}\n");
1527 PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
1528 printer->Outdent();
1529 printer->Print(*vars, "};\n");
1530}
1531
1532void PrintHeaderService(grpc_generator::Printer* printer,
1533 const grpc_generator::Service* service,
1534 std::map<grpc::string, grpc::string>* vars) {
1535 (*vars)["Service"] = service->name();
1536
1537 printer->Print(service->GetLeadingComments("//").c_str());
1538 printer->Print(*vars,
1539 "class $Service$ final {\n"
1540 " public:\n");
1541 printer->Indent();
1542
1543 // Service metadata
1544 printer->Print(*vars,
1545 "static constexpr char const* service_full_name() {\n"
1546 " return \"$Package$$Service$\";\n"
1547 "}\n");
1548
1549 // Client side
1550 printer->Print(
1551 "class StubInterface {\n"
1552 " public:\n");
1553 printer->Indent();
1554 printer->Print("virtual ~StubInterface() {}\n");
1555 for (int i = 0; i < service->method_count(); ++i) {
1556 printer->Print(service->method(i)->GetLeadingComments("//").c_str());
1557 PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
1558 true);
1559 printer->Print(service->method(i)->GetTrailingComments("//").c_str());
1560 }
1561 PrintHeaderClientMethodCallbackInterfacesStart(printer, vars);
1562 for (int i = 0; i < service->method_count(); ++i) {
1563 printer->Print(service->method(i)->GetLeadingComments("//").c_str());
1564 PrintHeaderClientMethodCallbackInterfaces(printer, service->method(i).get(),
1565 vars);
1566 printer->Print(service->method(i)->GetTrailingComments("//").c_str());
1567 }
1568 PrintHeaderClientMethodCallbackInterfacesEnd(printer, vars);
1569 printer->Outdent();
1570 printer->Print("private:\n");
1571 printer->Indent();
1572 for (int i = 0; i < service->method_count(); ++i) {
1573 PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
1574 false);
1575 }
1576 printer->Outdent();
1577 printer->Print("};\n");
1578 printer->Print(
1579 "class Stub final : public StubInterface"
1580 " {\n public:\n");
1581 printer->Indent();
1582 printer->Print(
1583 "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
1584 "channel);\n");
1585 for (int i = 0; i < service->method_count(); ++i) {
1586 PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
1587 }
1588 PrintHeaderClientMethodCallbackStart(printer, vars);
1589 for (int i = 0; i < service->method_count(); ++i) {
1590 PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars);
1591 }
1592 PrintHeaderClientMethodCallbackEnd(printer, vars);
1593 printer->Outdent();
1594 printer->Print("\n private:\n");
1595 printer->Indent();
1596 printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
1597 printer->Print("class experimental_async async_stub_{this};\n");
1598 for (int i = 0; i < service->method_count(); ++i) {
1599 PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
1600 }
1601 for (int i = 0; i < service->method_count(); ++i) {
1602 PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
1603 }
1604 printer->Outdent();
1605 printer->Print("};\n");
1606 printer->Print(
1607 "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
1608 "::grpc::ChannelInterface>& channel, "
1609 "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
1610
1611 printer->Print("\n");
1612
1613 // Server side - base
1614 printer->Print(
1615 "class Service : public ::grpc::Service {\n"
1616 " public:\n");
1617 printer->Indent();
1618 printer->Print("Service();\n");
1619 printer->Print("virtual ~Service();\n");
1620 for (int i = 0; i < service->method_count(); ++i) {
1621 PrintHeaderServerMethodSync(printer, service->method(i).get(), vars);
1622 }
1623 printer->Outdent();
1624 printer->Print("};\n");
1625
1626 // Server side - Asynchronous
1627 for (int i = 0; i < service->method_count(); ++i) {
1628 (*vars)["Idx"] = as_string(i);
1629 PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars);
1630 }
1631
1632 printer->Print("typedef ");
1633
1634 for (int i = 0; i < service->method_count(); ++i) {
1635 (*vars)["method_name"] = service->method(i)->name();
1636 printer->Print(*vars, "WithAsyncMethod_$method_name$<");
1637 }
1638 printer->Print("Service");
1639 for (int i = 0; i < service->method_count(); ++i) {
1640 printer->Print(" >");
1641 }
1642 printer->Print(" AsyncService;\n");
1643
1644 // Server side - Callback
1645 for (int i = 0; i < service->method_count(); ++i) {
1646 (*vars)["Idx"] = as_string(i);
1647 PrintHeaderServerMethodCallback(printer, service->method(i).get(), vars);
1648 }
1649
1650 printer->Print("#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL\n");
1651 printer->Print("typedef ");
1652
1653 for (int i = 0; i < service->method_count(); ++i) {
1654 (*vars)["method_name"] = service->method(i)->name();
1655 printer->Print(*vars, "ExperimentalWithCallbackMethod_$method_name$<");
1656 }
1657 printer->Print("Service");
1658 for (int i = 0; i < service->method_count(); ++i) {
1659 printer->Print(" >");
1660 }
1661 printer->Print(" CallbackService;\n");
1662 printer->Print("#endif\n\n");
1663
1664 printer->Print("typedef ");
1665
1666 for (int i = 0; i < service->method_count(); ++i) {
1667 (*vars)["method_name"] = service->method(i)->name();
1668 printer->Print(*vars, "ExperimentalWithCallbackMethod_$method_name$<");
1669 }
1670 printer->Print("Service");
1671 for (int i = 0; i < service->method_count(); ++i) {
1672 printer->Print(" >");
1673 }
1674 printer->Print(" ExperimentalCallbackService;\n");
1675
1676 // Server side - Generic
1677 for (int i = 0; i < service->method_count(); ++i) {
1678 (*vars)["Idx"] = as_string(i);
1679 PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
1680 }
1681
1682 // Server side - Raw
1683 for (int i = 0; i < service->method_count(); ++i) {
1684 (*vars)["Idx"] = as_string(i);
1685 PrintHeaderServerMethodRaw(printer, service->method(i).get(), vars);
1686 }
1687
1688 // Server side - Raw Callback
1689 for (int i = 0; i < service->method_count(); ++i) {
1690 (*vars)["Idx"] = as_string(i);
1691 PrintHeaderServerMethodRawCallback(printer, service->method(i).get(), vars);
1692 }
1693
1694 // Server side - Streamed Unary
1695 for (int i = 0; i < service->method_count(); ++i) {
1696 (*vars)["Idx"] = as_string(i);
1697 PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
1698 vars);
1699 }
1700
1701 printer->Print("typedef ");
1702 for (int i = 0; i < service->method_count(); ++i) {
1703 (*vars)["method_name"] = service->method(i)->name();
1704 if (service->method(i)->NoStreaming()) {
1705 printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
1706 }
1707 }
1708 printer->Print("Service");
1709 for (int i = 0; i < service->method_count(); ++i) {
1710 if (service->method(i)->NoStreaming()) {
1711 printer->Print(" >");
1712 }
1713 }
1714 printer->Print(" StreamedUnaryService;\n");
1715
1716 // Server side - controlled server-side streaming
1717 for (int i = 0; i < service->method_count(); ++i) {
1718 (*vars)["Idx"] = as_string(i);
1719 PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(),
1720 vars);
1721 }
1722
1723 printer->Print("typedef ");
1724 for (int i = 0; i < service->method_count(); ++i) {
1725 (*vars)["method_name"] = service->method(i)->name();
1726 auto method = service->method(i);
1727 if (ServerOnlyStreaming(method.get())) {
1728 printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
1729 }
1730 }
1731 printer->Print("Service");
1732 for (int i = 0; i < service->method_count(); ++i) {
1733 auto method = service->method(i);
1734 if (ServerOnlyStreaming(method.get())) {
1735 printer->Print(" >");
1736 }
1737 }
1738 printer->Print(" SplitStreamedService;\n");
1739
1740 // Server side - typedef for controlled both unary and server-side streaming
1741 printer->Print("typedef ");
1742 for (int i = 0; i < service->method_count(); ++i) {
1743 (*vars)["method_name"] = service->method(i)->name();
1744 auto method = service->method(i);
1745 if (ServerOnlyStreaming(method.get())) {
1746 printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
1747 }
1748 if (service->method(i)->NoStreaming()) {
1749 printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
1750 }
1751 }
1752 printer->Print("Service");
1753 for (int i = 0; i < service->method_count(); ++i) {
1754 auto method = service->method(i);
1755 if (service->method(i)->NoStreaming() ||
1756 ServerOnlyStreaming(method.get())) {
1757 printer->Print(" >");
1758 }
1759 }
1760 printer->Print(" StreamedService;\n");
1761
1762 printer->Outdent();
1763 printer->Print("};\n");
1764 printer->Print(service->GetTrailingComments("//").c_str());
1765}
1766
1767grpc::string GetHeaderServices(grpc_generator::File* file,
1768 const Parameters& params) {
1769 grpc::string output;
1770 {
1771 // Scope the output stream so it closes and finalizes output to the string.
1772 auto printer = file->CreatePrinter(&output);
1773 std::map<grpc::string, grpc::string> vars;
1774 // Package string is empty or ends with a dot. It is used to fully qualify
1775 // method names.
1776 vars["Package"] = file->package();
1777 if (!file->package().empty()) {
1778 vars["Package"].append(".");
1779 }
1780
1781 if (!params.services_namespace.empty()) {
1782 vars["services_namespace"] = params.services_namespace;
1783 printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
1784 }
1785
1786 for (int i = 0; i < file->service_count(); ++i) {
1787 PrintHeaderService(printer.get(), file->service(i).get(), &vars);
1788 printer->Print("\n");
1789 }
1790
1791 if (!params.services_namespace.empty()) {
1792 printer->Print(vars, "} // namespace $services_namespace$\n\n");
1793 }
1794 }
1795 return output;
1796}
1797
1798grpc::string GetHeaderEpilogue(grpc_generator::File* file,
1799 const Parameters& /*params*/) {
1800 grpc::string output;
1801 {
1802 // Scope the output stream so it closes and finalizes output to the string.
1803 auto printer = file->CreatePrinter(&output);
1804 std::map<grpc::string, grpc::string> vars;
1805
1806 vars["filename"] = file->filename();
1807 vars["filename_identifier"] = FilenameIdentifier(file->filename());
1808
1809 if (!file->package().empty()) {
1810 std::vector<grpc::string> parts = file->package_parts();
1811
1812 for (auto part = parts.rbegin(); part != parts.rend(); part++) {
1813 vars["part"] = *part;
1814 printer->Print(vars, "} // namespace $part$\n");
1815 }
1816 printer->Print(vars, "\n");
1817 }
1818
1819 printer->Print(vars, "\n");
1820 printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
1821
1822 printer->Print(file->GetTrailingComments("//").c_str());
1823 }
1824 return output;
1825}
1826
1827grpc::string GetSourcePrologue(grpc_generator::File* file,
1828 const Parameters& params) {
1829 grpc::string output;
1830 {
1831 // Scope the output stream so it closes and finalizes output to the string.
1832 auto printer = file->CreatePrinter(&output);
1833 std::map<grpc::string, grpc::string> vars;
1834
1835 vars["filename"] = file->filename();
1836 vars["filename_base"] = file->filename_without_ext();
1837 vars["message_header_ext"] = params.message_header_extension.empty()
1838 ? kCppGeneratorMessageHeaderExt
1839 : params.message_header_extension;
1840 vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
1841
1842 printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
1843 printer->Print(vars,
1844 "// If you make any local change, they will be lost.\n");
1845 printer->Print(vars, "// source: $filename$\n\n");
1846
1847 printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
1848 printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
1849 printer->Print(vars, "\n");
1850 }
1851 return output;
1852}
1853
1854grpc::string GetSourceIncludes(grpc_generator::File* file,
1855 const Parameters& params) {
1856 grpc::string output;
1857 {
1858 // Scope the output stream so it closes and finalizes output to the string.
1859 auto printer = file->CreatePrinter(&output);
1860 std::map<grpc::string, grpc::string> vars;
1861 static const char* headers_strs[] = {
1862 "functional",
1863 "grpcpp/impl/codegen/async_stream.h",
1864 "grpcpp/impl/codegen/async_unary_call.h",
1865 "grpcpp/impl/codegen/channel_interface.h",
1866 "grpcpp/impl/codegen/client_unary_call.h",
1867 "grpcpp/impl/codegen/client_callback.h",
1868 "grpcpp/impl/codegen/message_allocator.h",
1869 "grpcpp/impl/codegen/method_handler.h",
1870 "grpcpp/impl/codegen/rpc_service_method.h",
1871 "grpcpp/impl/codegen/server_callback.h",
1872 "grpcpp/impl/codegen/server_callback_handlers.h",
1873 "grpcpp/impl/codegen/server_context.h",
1874 "grpcpp/impl/codegen/service_type.h",
1875 "grpcpp/impl/codegen/sync_stream.h"};
1876 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
1877 PrintIncludes(printer.get(), headers, params.use_system_headers,
1878 params.grpc_search_path);
1879
1880 if (!file->package().empty()) {
1881 std::vector<grpc::string> parts = file->package_parts();
1882
1883 for (auto part = parts.begin(); part != parts.end(); part++) {
1884 vars["part"] = *part;
1885 printer->Print(vars, "namespace $part$ {\n");
1886 }
1887 }
1888
1889 printer->Print(vars, "\n");
1890 }
1891 return output;
1892}
1893
1894void PrintSourceClientMethod(grpc_generator::Printer* printer,
1895 const grpc_generator::Method* method,
1896 std::map<grpc::string, grpc::string>* vars) {
1897 (*vars)["Method"] = method->name();
1898 (*vars)["Request"] = method->input_type_name();
1899 (*vars)["Response"] = method->output_type_name();
1900 struct {
1901 grpc::string prefix;
1902 grpc::string start; // bool literal expressed as string
1903 grpc::string method_params; // extra arguments to method
1904 grpc::string create_args; // extra arguments to creator
1905 } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
1906 {"PrepareAsync", "false", "", ", nullptr"}};
1907 if (method->NoStreaming()) {
1908 printer->Print(*vars,
1909 "::grpc::Status $ns$$Service$::Stub::$Method$("
1910 "::grpc::ClientContext* context, "
1911 "const $Request$& request, $Response$* response) {\n");
1912 printer->Print(*vars,
1913 " return ::grpc::internal::BlockingUnaryCall"
1914 "(channel_.get(), rpcmethod_$Method$_, "
1915 "context, request, response);\n}\n\n");
1916
1917 printer->Print(*vars,
1918 "void $ns$$Service$::Stub::experimental_async::$Method$("
1919 "::grpc::ClientContext* context, "
1920 "const $Request$* request, $Response$* response, "
1921 "std::function<void(::grpc::Status)> f) {\n");
1922 printer->Print(*vars,
1923 " ::grpc_impl::internal::CallbackUnaryCall"
1924 "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
1925 "context, request, response, std::move(f));\n}\n\n");
1926
1927 printer->Print(*vars,
1928 "void $ns$$Service$::Stub::experimental_async::$Method$("
1929 "::grpc::ClientContext* context, "
1930 "const ::grpc::ByteBuffer* request, $Response$* response, "
1931 "std::function<void(::grpc::Status)> f) {\n");
1932 printer->Print(*vars,
1933 " ::grpc_impl::internal::CallbackUnaryCall"
1934 "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
1935 "context, request, response, std::move(f));\n}\n\n");
1936
1937 printer->Print(*vars,
1938 "void $ns$$Service$::Stub::experimental_async::$Method$("
1939 "::grpc::ClientContext* context, "
1940 "const $Request$* request, $Response$* response, "
1941 "::grpc::experimental::ClientUnaryReactor* reactor) {\n");
1942 printer->Print(*vars,
1943 " ::grpc_impl::internal::ClientCallbackUnaryFactory::Create"
1944 "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
1945 "context, request, response, reactor);\n}\n\n");
1946
1947 printer->Print(*vars,
1948 "void $ns$$Service$::Stub::experimental_async::$Method$("
1949 "::grpc::ClientContext* context, "
1950 "const ::grpc::ByteBuffer* request, $Response$* response, "
1951 "::grpc::experimental::ClientUnaryReactor* reactor) {\n");
1952 printer->Print(*vars,
1953 " ::grpc_impl::internal::ClientCallbackUnaryFactory::Create"
1954 "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
1955 "context, request, response, reactor);\n}\n\n");
1956
1957 for (auto async_prefix : async_prefixes) {
1958 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1959 (*vars)["AsyncStart"] = async_prefix.start;
1960 printer->Print(*vars,
1961 "::grpc::ClientAsyncResponseReader< $Response$>* "
1962 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
1963 "ClientContext* context, "
1964 "const $Request$& request, "
1965 "::grpc::CompletionQueue* cq) {\n");
1966 printer->Print(
1967 *vars,
1968 " return "
1969 "::grpc_impl::internal::ClientAsyncResponseReaderFactory< $Response$>"
1970 "::Create(channel_.get(), cq, "
1971 "rpcmethod_$Method$_, "
1972 "context, request, $AsyncStart$);\n"
1973 "}\n\n");
1974 }
1975 } else if (ClientOnlyStreaming(method)) {
1976 printer->Print(*vars,
1977 "::grpc::ClientWriter< $Request$>* "
1978 "$ns$$Service$::Stub::$Method$Raw("
1979 "::grpc::ClientContext* context, $Response$* response) {\n");
1980 printer->Print(*vars,
1981 " return ::grpc_impl::internal::ClientWriterFactory< "
1982 "$Request$>::Create("
1983 "channel_.get(), "
1984 "rpcmethod_$Method$_, "
1985 "context, response);\n"
1986 "}\n\n");
1987
1988 printer->Print(
1989 *vars,
1990 "void $ns$$Service$::"
1991 "Stub::experimental_async::$Method$(::grpc::ClientContext* context, "
1992 "$Response$* response, "
1993 "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n");
1994 printer->Print(*vars,
1995 " ::grpc_impl::internal::ClientCallbackWriterFactory< "
1996 "$Request$>::Create("
1997 "stub_->channel_.get(), "
1998 "stub_->rpcmethod_$Method$_, "
1999 "context, response, reactor);\n"
2000 "}\n\n");
2001
2002 for (auto async_prefix : async_prefixes) {
2003 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2004 (*vars)["AsyncStart"] = async_prefix.start;
2005 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2006 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
2007 printer->Print(*vars,
2008 "::grpc::ClientAsyncWriter< $Request$>* "
2009 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
2010 "::grpc::ClientContext* context, $Response$* response, "
2011 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
2012 printer->Print(
2013 *vars,
2014 " return ::grpc_impl::internal::ClientAsyncWriterFactory< $Request$>"
2015 "::Create(channel_.get(), cq, "
2016 "rpcmethod_$Method$_, "
2017 "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
2018 "}\n\n");
2019 }
2020 } else if (ServerOnlyStreaming(method)) {
2021 printer->Print(
2022 *vars,
2023 "::grpc::ClientReader< $Response$>* "
2024 "$ns$$Service$::Stub::$Method$Raw("
2025 "::grpc::ClientContext* context, const $Request$& request) {\n");
2026 printer->Print(*vars,
2027 " return ::grpc_impl::internal::ClientReaderFactory< "
2028 "$Response$>::Create("
2029 "channel_.get(), "
2030 "rpcmethod_$Method$_, "
2031 "context, request);\n"
2032 "}\n\n");
2033
2034 printer->Print(
2035 *vars,
2036 "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
2037 "ClientContext* context, "
2038 "$Request$* request, "
2039 "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n");
2040 printer->Print(*vars,
2041 " ::grpc_impl::internal::ClientCallbackReaderFactory< "
2042 "$Response$>::Create("
2043 "stub_->channel_.get(), "
2044 "stub_->rpcmethod_$Method$_, "
2045 "context, request, reactor);\n"
2046 "}\n\n");
2047
2048 for (auto async_prefix : async_prefixes) {
2049 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2050 (*vars)["AsyncStart"] = async_prefix.start;
2051 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2052 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
2053 printer->Print(
2054 *vars,
2055 "::grpc::ClientAsyncReader< $Response$>* "
2056 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
2057 "::grpc::ClientContext* context, const $Request$& request, "
2058 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
2059 printer->Print(
2060 *vars,
2061 " return ::grpc_impl::internal::ClientAsyncReaderFactory< "
2062 "$Response$>"
2063 "::Create(channel_.get(), cq, "
2064 "rpcmethod_$Method$_, "
2065 "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
2066 "}\n\n");
2067 }
2068 } else if (method->BidiStreaming()) {
2069 printer->Print(
2070 *vars,
2071 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
2072 "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
2073 printer->Print(*vars,
2074 " return ::grpc_impl::internal::ClientReaderWriterFactory< "
2075 "$Request$, $Response$>::Create("
2076 "channel_.get(), "
2077 "rpcmethod_$Method$_, "
2078 "context);\n"
2079 "}\n\n");
2080
2081 printer->Print(
2082 *vars,
2083 "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
2084 "ClientContext* context, "
2085 "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* "
2086 "reactor) {\n");
2087 printer->Print(
2088 *vars,
2089 " ::grpc_impl::internal::ClientCallbackReaderWriterFactory< "
2090 "$Request$,$Response$>::Create("
2091 "stub_->channel_.get(), "
2092 "stub_->rpcmethod_$Method$_, "
2093 "context, reactor);\n"
2094 "}\n\n");
2095
2096 for (auto async_prefix : async_prefixes) {
2097 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2098 (*vars)["AsyncStart"] = async_prefix.start;
2099 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2100 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
2101 printer->Print(*vars,
2102 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
2103 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
2104 "ClientContext* context, "
2105 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
2106 printer->Print(*vars,
2107 " return "
2108 "::grpc_impl::internal::ClientAsyncReaderWriterFactory< "
2109 "$Request$, $Response$>::Create("
2110 "channel_.get(), cq, "
2111 "rpcmethod_$Method$_, "
2112 "context, $AsyncStart$$AsyncCreateArgs$);\n"
2113 "}\n\n");
2114 }
2115 }
2116}
2117
2118void PrintSourceServerMethod(grpc_generator::Printer* printer,
2119 const grpc_generator::Method* method,
2120 std::map<grpc::string, grpc::string>* vars) {
2121 (*vars)["Method"] = method->name();
2122 (*vars)["Request"] = method->input_type_name();
2123 (*vars)["Response"] = method->output_type_name();
2124 if (method->NoStreaming()) {
2125 printer->Print(*vars,
2126 "::grpc::Status $ns$$Service$::Service::$Method$("
2127 "::grpc::ServerContext* context, "
2128 "const $Request$* request, $Response$* response) {\n");
2129 printer->Print(" (void) context;\n");
2130 printer->Print(" (void) request;\n");
2131 printer->Print(" (void) response;\n");
2132 printer->Print(
2133 " return ::grpc::Status("
2134 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
2135 printer->Print("}\n\n");
2136 } else if (ClientOnlyStreaming(method)) {
2137 printer->Print(*vars,
2138 "::grpc::Status $ns$$Service$::Service::$Method$("
2139 "::grpc::ServerContext* context, "
2140 "::grpc::ServerReader< $Request$>* reader, "
2141 "$Response$* response) {\n");
2142 printer->Print(" (void) context;\n");
2143 printer->Print(" (void) reader;\n");
2144 printer->Print(" (void) response;\n");
2145 printer->Print(
2146 " return ::grpc::Status("
2147 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
2148 printer->Print("}\n\n");
2149 } else if (ServerOnlyStreaming(method)) {
2150 printer->Print(*vars,
2151 "::grpc::Status $ns$$Service$::Service::$Method$("
2152 "::grpc::ServerContext* context, "
2153 "const $Request$* request, "
2154 "::grpc::ServerWriter< $Response$>* writer) {\n");
2155 printer->Print(" (void) context;\n");
2156 printer->Print(" (void) request;\n");
2157 printer->Print(" (void) writer;\n");
2158 printer->Print(
2159 " return ::grpc::Status("
2160 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
2161 printer->Print("}\n\n");
2162 } else if (method->BidiStreaming()) {
2163 printer->Print(*vars,
2164 "::grpc::Status $ns$$Service$::Service::$Method$("
2165 "::grpc::ServerContext* context, "
2166 "::grpc::ServerReaderWriter< $Response$, $Request$>* "
2167 "stream) {\n");
2168 printer->Print(" (void) context;\n");
2169 printer->Print(" (void) stream;\n");
2170 printer->Print(
2171 " return ::grpc::Status("
2172 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
2173 printer->Print("}\n\n");
2174 }
2175}
2176
2177void PrintSourceService(grpc_generator::Printer* printer,
2178 const grpc_generator::Service* service,
2179 std::map<grpc::string, grpc::string>* vars) {
2180 (*vars)["Service"] = service->name();
2181
2182 if (service->method_count() > 0) {
2183 printer->Print(*vars,
2184 "static const char* $prefix$$Service$_method_names[] = {\n");
2185 for (int i = 0; i < service->method_count(); ++i) {
2186 (*vars)["Method"] = service->method(i)->name();
2187 printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
2188 }
2189 printer->Print(*vars, "};\n\n");
2190 }
2191
2192 printer->Print(*vars,
2193 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
2194 "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
2195 "const ::grpc::StubOptions& options) {\n"
2196 " (void)options;\n"
2197 " std::unique_ptr< $ns$$Service$::Stub> stub(new "
2198 "$ns$$Service$::Stub(channel));\n"
2199 " return stub;\n"
2200 "}\n\n");
2201 printer->Print(*vars,
2202 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
2203 "::grpc::ChannelInterface>& channel)\n");
2204 printer->Indent();
2205 printer->Print(": channel_(channel)");
2206 for (int i = 0; i < service->method_count(); ++i) {
2207 auto method = service->method(i);
2208 (*vars)["Method"] = method->name();
2209 (*vars)["Idx"] = as_string(i);
2210 if (method->NoStreaming()) {
2211 (*vars)["StreamingType"] = "NORMAL_RPC";
2212 // NOTE: There is no reason to consider streamed-unary as a separate
2213 // category here since this part is setting up the client-side stub
2214 // and this appears as a NORMAL_RPC from the client-side.
2215 } else if (ClientOnlyStreaming(method.get())) {
2216 (*vars)["StreamingType"] = "CLIENT_STREAMING";
2217 } else if (ServerOnlyStreaming(method.get())) {
2218 (*vars)["StreamingType"] = "SERVER_STREAMING";
2219 } else {
2220 (*vars)["StreamingType"] = "BIDI_STREAMING";
2221 }
2222 printer->Print(*vars,
2223 ", rpcmethod_$Method$_("
2224 "$prefix$$Service$_method_names[$Idx$], "
2225 "::grpc::internal::RpcMethod::$StreamingType$, "
2226 "channel"
2227 ")\n");
2228 }
2229 printer->Print("{}\n\n");
2230 printer->Outdent();
2231
2232 for (int i = 0; i < service->method_count(); ++i) {
2233 (*vars)["Idx"] = as_string(i);
2234 PrintSourceClientMethod(printer, service->method(i).get(), vars);
2235 }
2236
2237 printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
2238 printer->Indent();
2239 for (int i = 0; i < service->method_count(); ++i) {
2240 auto method = service->method(i);
2241 (*vars)["Idx"] = as_string(i);
2242 (*vars)["Method"] = method->name();
2243 (*vars)["Request"] = method->input_type_name();
2244 (*vars)["Response"] = method->output_type_name();
2245 if (method->NoStreaming()) {
2246 printer->Print(
2247 *vars,
2248 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
2249 " $prefix$$Service$_method_names[$Idx$],\n"
2250 " ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
2251 " new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
2252 "$Request$, "
2253 "$Response$>(\n"
2254 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
2255 } else if (ClientOnlyStreaming(method.get())) {
2256 printer->Print(
2257 *vars,
2258 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
2259 " $prefix$$Service$_method_names[$Idx$],\n"
2260 " ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
2261 " new ::grpc::internal::ClientStreamingHandler< "
2262 "$ns$$Service$::Service, $Request$, $Response$>(\n"
2263 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
2264 } else if (ServerOnlyStreaming(method.get())) {
2265 printer->Print(
2266 *vars,
2267 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
2268 " $prefix$$Service$_method_names[$Idx$],\n"
2269 " ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
2270 " new ::grpc::internal::ServerStreamingHandler< "
2271 "$ns$$Service$::Service, $Request$, $Response$>(\n"
2272 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
2273 } else if (method->BidiStreaming()) {
2274 printer->Print(
2275 *vars,
2276 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
2277 " $prefix$$Service$_method_names[$Idx$],\n"
2278 " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
2279 " new ::grpc::internal::BidiStreamingHandler< "
2280 "$ns$$Service$::Service, $Request$, $Response$>(\n"
2281 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
2282 }
2283 }
2284 printer->Outdent();
2285 printer->Print(*vars, "}\n\n");
2286 printer->Print(*vars,
2287 "$ns$$Service$::Service::~Service() {\n"
2288 "}\n\n");
2289 for (int i = 0; i < service->method_count(); ++i) {
2290 (*vars)["Idx"] = as_string(i);
2291 PrintSourceServerMethod(printer, service->method(i).get(), vars);
2292 }
2293}
2294
2295grpc::string GetSourceServices(grpc_generator::File* file,
2296 const Parameters& params) {
2297 grpc::string output;
2298 {
2299 // Scope the output stream so it closes and finalizes output to the string.
2300 auto printer = file->CreatePrinter(&output);
2301 std::map<grpc::string, grpc::string> vars;
2302 // Package string is empty or ends with a dot. It is used to fully qualify
2303 // method names.
2304 vars["Package"] = file->package();
2305 if (!file->package().empty()) {
2306 vars["Package"].append(".");
2307 }
2308 if (!params.services_namespace.empty()) {
2309 vars["ns"] = params.services_namespace + "::";
2310 vars["prefix"] = params.services_namespace;
2311 } else {
2312 vars["ns"] = "";
2313 vars["prefix"] = "";
2314 }
2315
2316 for (int i = 0; i < file->service_count(); ++i) {
2317 PrintSourceService(printer.get(), file->service(i).get(), &vars);
2318 printer->Print("\n");
2319 }
2320 }
2321 return output;
2322}
2323
2324grpc::string GetSourceEpilogue(grpc_generator::File* file,
2325 const Parameters& /*params*/) {
2326 grpc::string temp;
2327
2328 if (!file->package().empty()) {
2329 std::vector<grpc::string> parts = file->package_parts();
2330
2331 for (auto part = parts.begin(); part != parts.end(); part++) {
2332 temp.append("} // namespace ");
2333 temp.append(*part);
2334 temp.append("\n");
2335 }
2336 temp.append("\n");
2337 }
2338
2339 return temp;
2340}
2341
2342// TODO(mmukhi): Make sure we need parameters or not.
2343grpc::string GetMockPrologue(grpc_generator::File* file,
2344 const Parameters& params) {
2345 grpc::string output;
2346 {
2347 // Scope the output stream so it closes and finalizes output to the string.
2348 auto printer = file->CreatePrinter(&output);
2349 std::map<grpc::string, grpc::string> vars;
2350
2351 vars["filename"] = file->filename();
2352 vars["filename_base"] = file->filename_without_ext();
2353 vars["message_header_ext"] = params.message_header_extension.empty()
2354 ? kCppGeneratorMessageHeaderExt
2355 : params.message_header_extension;
2356 vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
2357
2358 printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
2359 printer->Print(vars,
2360 "// If you make any local change, they will be lost.\n");
2361 printer->Print(vars, "// source: $filename$\n\n");
2362
2363 printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
2364 printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
2365 if (params.include_import_headers) {
2366 const std::vector<grpc::string> import_names = file->GetImportNames();
2367 for (const auto& import_name : import_names) {
2368 const grpc::string include_name =
2369 ImportInludeFromProtoName(import_name);
2370 printer->Print(vars, include_name.c_str());
2371 }
2372 printer->PrintRaw("\n");
2373 }
2374 printer->Print(vars, file->additional_headers().c_str());
2375 printer->Print(vars, "\n");
2376 }
2377 return output;
2378}
2379
2380// TODO(mmukhi): Add client-stream and completion-queue headers.
2381grpc::string GetMockIncludes(grpc_generator::File* file,
2382 const Parameters& params) {
2383 grpc::string output;
2384 {
2385 // Scope the output stream so it closes and finalizes output to the string.
2386 auto printer = file->CreatePrinter(&output);
2387 std::map<grpc::string, grpc::string> vars;
2388
2389 static const char* headers_strs[] = {
2390 "grpcpp/impl/codegen/async_stream.h",
2391 "grpcpp/impl/codegen/sync_stream.h",
2392 };
2393 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
2394 PrintIncludes(printer.get(), headers, params.use_system_headers,
2395 params.grpc_search_path);
2396
2397 std::vector<grpc::string> gmock_header;
2398 if (params.gmock_search_path.empty()) {
2399 gmock_header.push_back("gmock/gmock.h");
2400 PrintIncludes(printer.get(), gmock_header, params.use_system_headers,
2401 params.grpc_search_path);
2402 } else {
2403 gmock_header.push_back("gmock.h");
2404 // We use local includes when a gmock_search_path is given
2405 PrintIncludes(printer.get(), gmock_header, false,
2406 params.gmock_search_path);
2407 }
2408
2409 if (!file->package().empty()) {
2410 std::vector<grpc::string> parts = file->package_parts();
2411
2412 for (auto part = parts.begin(); part != parts.end(); part++) {
2413 vars["part"] = *part;
2414 printer->Print(vars, "namespace $part$ {\n");
2415 }
2416 }
2417
2418 printer->Print(vars, "\n");
2419 }
2420 return output;
2421}
2422
2423void PrintMockClientMethods(grpc_generator::Printer* printer,
2424 const grpc_generator::Method* method,
2425 std::map<grpc::string, grpc::string>* vars) {
2426 (*vars)["Method"] = method->name();
2427 (*vars)["Request"] = method->input_type_name();
2428 (*vars)["Response"] = method->output_type_name();
2429
2430 struct {
2431 grpc::string prefix;
2432 grpc::string method_params; // extra arguments to method
2433 int extra_method_param_count;
2434 } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
2435
2436 if (method->NoStreaming()) {
2437 printer->Print(
2438 *vars,
2439 "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
2440 "const $Request$& request, $Response$* response));\n");
2441 for (auto async_prefix : async_prefixes) {
2442 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2443 printer->Print(
2444 *vars,
2445 "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
2446 "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
2447 "(::grpc::ClientContext* context, const $Request$& request, "
2448 "::grpc::CompletionQueue* cq));\n");
2449 }
2450 } else if (ClientOnlyStreaming(method)) {
2451 printer->Print(
2452 *vars,
2453 "MOCK_METHOD2($Method$Raw, "
2454 "::grpc::ClientWriterInterface< $Request$>*"
2455 "(::grpc::ClientContext* context, $Response$* response));\n");
2456 for (auto async_prefix : async_prefixes) {
2457 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2458 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2459 (*vars)["MockArgs"] =
2460 std::to_string(3 + async_prefix.extra_method_param_count);
2461 printer->Print(*vars,
2462 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2463 "::grpc::ClientAsyncWriterInterface< $Request$>*"
2464 "(::grpc::ClientContext* context, $Response$* response, "
2465 "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
2466 }
2467 } else if (ServerOnlyStreaming(method)) {
2468 printer->Print(
2469 *vars,
2470 "MOCK_METHOD2($Method$Raw, "
2471 "::grpc::ClientReaderInterface< $Response$>*"
2472 "(::grpc::ClientContext* context, const $Request$& request));\n");
2473 for (auto async_prefix : async_prefixes) {
2474 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2475 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2476 (*vars)["MockArgs"] =
2477 std::to_string(3 + async_prefix.extra_method_param_count);
2478 printer->Print(
2479 *vars,
2480 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2481 "::grpc::ClientAsyncReaderInterface< $Response$>*"
2482 "(::grpc::ClientContext* context, const $Request$& request, "
2483 "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
2484 }
2485 } else if (method->BidiStreaming()) {
2486 printer->Print(
2487 *vars,
2488 "MOCK_METHOD1($Method$Raw, "
2489 "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
2490 "(::grpc::ClientContext* context));\n");
2491 for (auto async_prefix : async_prefixes) {
2492 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2493 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2494 (*vars)["MockArgs"] =
2495 std::to_string(2 + async_prefix.extra_method_param_count);
2496 printer->Print(
2497 *vars,
2498 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2499 "::grpc::ClientAsyncReaderWriterInterface<$Request$, "
2500 "$Response$>*"
2501 "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
2502 "$AsyncMethodParams$));\n");
2503 }
2504 }
2505}
2506
2507void PrintMockService(grpc_generator::Printer* printer,
2508 const grpc_generator::Service* service,
2509 std::map<grpc::string, grpc::string>* vars) {
2510 (*vars)["Service"] = service->name();
2511
2512 printer->Print(*vars,
2513 "class Mock$Service$Stub : public $Service$::StubInterface {\n"
2514 " public:\n");
2515 printer->Indent();
2516 for (int i = 0; i < service->method_count(); ++i) {
2517 PrintMockClientMethods(printer, service->method(i).get(), vars);
2518 }
2519 printer->Outdent();
2520 printer->Print("};\n");
2521}
2522
2523grpc::string GetMockServices(grpc_generator::File* file,
2524 const Parameters& params) {
2525 grpc::string output;
2526 {
2527 // Scope the output stream so it closes and finalizes output to the string.
2528 auto printer = file->CreatePrinter(&output);
2529 std::map<grpc::string, grpc::string> vars;
2530 // Package string is empty or ends with a dot. It is used to fully qualify
2531 // method names.
2532 vars["Package"] = file->package();
2533 if (!file->package().empty()) {
2534 vars["Package"].append(".");
2535 }
2536
2537 if (!params.services_namespace.empty()) {
2538 vars["services_namespace"] = params.services_namespace;
2539 printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
2540 }
2541
2542 for (int i = 0; i < file->service_count(); i++) {
2543 PrintMockService(printer.get(), file->service(i).get(), &vars);
2544 printer->Print("\n");
2545 }
2546
2547 if (!params.services_namespace.empty()) {
2548 printer->Print(vars, "} // namespace $services_namespace$\n\n");
2549 }
2550 }
2551 return output;
2552}
2553
2554grpc::string GetMockEpilogue(grpc_generator::File* file,
2555 const Parameters& /*params*/) {
2556 grpc::string temp;
2557
2558 if (!file->package().empty()) {
2559 std::vector<grpc::string> parts = file->package_parts();
2560
2561 for (auto part = parts.begin(); part != parts.end(); part++) {
2562 temp.append("} // namespace ");
2563 temp.append(*part);
2564 temp.append("\n");
2565 }
2566 temp.append("\n");
2567 }
2568
2569 return temp;
2570}
2571
2572} // namespace grpc_cpp_generator
2573