3 * Copyright 2015 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include "src/compiler/cpp_generator.h"
25 namespace grpc_cpp_generator {
29 grpc::string as_string(T x) {
30 std::ostringstream out;
35 inline bool ClientOnlyStreaming(const grpc_generator::Method* method) {
36 return method->ClientStreaming() && !method->ServerStreaming();
39 inline bool ServerOnlyStreaming(const grpc_generator::Method* method) {
40 return !method->ClientStreaming() && method->ServerStreaming();
43 grpc::string FilenameIdentifier(const grpc::string& filename) {
45 for (unsigned i = 0; i < filename.size(); i++) {
50 static char hex[] = "0123456789abcdef";
51 result.push_back('_');
52 result.push_back(hex[(c >> 4) & 0xf]);
53 result.push_back(hex[c & 0xf]);
60 template <class T, size_t N>
61 T* array_end(T (&array)[N]) {
65 void 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;
70 vars["l"] = use_system_headers ? '<' : '"';
71 vars["r"] = use_system_headers ? '>' : '"';
73 if (!search_path.empty()) {
74 vars["l"] += search_path;
75 if (search_path[search_path.size() - 1] != '/') {
80 for (auto i = headers.begin(); i != headers.end(); i++) {
82 printer->Print(vars, "#include $l$$h$$r$\n");
86 grpc::string GetHeaderPrologue(grpc_generator::File* file,
87 const Parameters& /*params*/) {
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;
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"] = kCppGeneratorMessageHeaderExt;
99 printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
101 "// If you make any local change, they will be lost.\n");
102 printer->Print(vars, "// source: $filename$\n");
103 grpc::string leading_comments = file->GetLeadingComments("//");
104 if (!leading_comments.empty()) {
105 printer->Print(vars, "// Original file comments:\n");
106 printer->PrintRaw(leading_comments.c_str());
108 printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
109 printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
110 printer->Print(vars, "\n");
111 printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
112 printer->Print(vars, file->additional_headers().c_str());
113 printer->Print(vars, "\n");
118 grpc::string GetHeaderIncludes(grpc_generator::File* file,
119 const Parameters& params) {
122 // Scope the output stream so it closes and finalizes output to the string.
123 auto printer = file->CreatePrinter(&output);
124 std::map<grpc::string, grpc::string> vars;
126 if (!params.additional_header_includes.empty()) {
127 PrintIncludes(printer.get(), params.additional_header_includes, false,
130 static const char* headers_strs[] = {
132 "grpcpp/impl/codegen/async_generic_service.h",
133 "grpcpp/impl/codegen/async_stream.h",
134 "grpcpp/impl/codegen/async_unary_call.h",
135 "grpcpp/impl/codegen/client_callback.h",
136 "grpcpp/impl/codegen/method_handler_impl.h",
137 "grpcpp/impl/codegen/proto_utils.h",
138 "grpcpp/impl/codegen/rpc_method.h",
139 "grpcpp/impl/codegen/server_callback.h",
140 "grpcpp/impl/codegen/service_type.h",
141 "grpcpp/impl/codegen/status.h",
142 "grpcpp/impl/codegen/stub_options.h",
143 "grpcpp/impl/codegen/sync_stream.h"};
144 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
145 PrintIncludes(printer.get(), headers, params.use_system_headers,
146 params.grpc_search_path);
147 printer->Print(vars, "\n");
148 printer->Print(vars, "namespace grpc {\n");
149 printer->Print(vars, "class CompletionQueue;\n");
150 printer->Print(vars, "class Channel;\n");
151 printer->Print(vars, "class ServerCompletionQueue;\n");
152 printer->Print(vars, "class ServerContext;\n");
153 printer->Print(vars, "} // namespace grpc\n\n");
155 if (!file->package().empty()) {
156 std::vector<grpc::string> parts = file->package_parts();
158 for (auto part = parts.begin(); part != parts.end(); part++) {
159 vars["part"] = *part;
160 printer->Print(vars, "namespace $part$ {\n");
162 printer->Print(vars, "\n");
168 void PrintHeaderClientMethodInterfaces(
169 grpc_generator::Printer* printer, const grpc_generator::Method* method,
170 std::map<grpc::string, grpc::string>* vars, bool is_public) {
171 (*vars)["Method"] = method->name();
172 (*vars)["Request"] = method->input_type_name();
173 (*vars)["Response"] = method->output_type_name();
177 grpc::string method_params; // extra arguments to method
178 grpc::string raw_args; // extra arguments to raw version of method
179 } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
180 {"PrepareAsync", "", ""}};
183 if (method->NoStreaming()) {
186 "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
187 "const $Request$& request, $Response$* response) = 0;\n");
188 for (auto async_prefix : async_prefixes) {
189 (*vars)["AsyncPrefix"] = async_prefix.prefix;
193 "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
194 "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
195 "const $Request$& request, "
196 "::grpc::CompletionQueue* cq) {\n");
200 "return std::unique_ptr< "
201 "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
202 "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
204 printer->Print("}\n");
206 } else if (ClientOnlyStreaming(method)) {
209 "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
211 "::grpc::ClientContext* context, $Response$* response) {\n");
215 "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
216 "($Method$Raw(context, response));\n");
218 printer->Print("}\n");
219 for (auto async_prefix : async_prefixes) {
220 (*vars)["AsyncPrefix"] = async_prefix.prefix;
221 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
222 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
225 "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
226 " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
229 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
231 printer->Print(*vars,
232 "return std::unique_ptr< "
233 "::grpc::ClientAsyncWriterInterface< $Request$>>("
234 "$AsyncPrefix$$Method$Raw(context, response, "
235 "cq$AsyncRawArgs$));\n");
237 printer->Print("}\n");
239 } else if (ServerOnlyStreaming(method)) {
242 "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
243 " $Method$(::grpc::ClientContext* context, const $Request$& request)"
248 "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
249 "($Method$Raw(context, request));\n");
251 printer->Print("}\n");
252 for (auto async_prefix : async_prefixes) {
253 (*vars)["AsyncPrefix"] = async_prefix.prefix;
254 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
255 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
258 "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
259 "$AsyncPrefix$$Method$("
260 "::grpc::ClientContext* context, const $Request$& request, "
261 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
265 "return std::unique_ptr< "
266 "::grpc::ClientAsyncReaderInterface< $Response$>>("
267 "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
269 printer->Print("}\n");
271 } else if (method->BidiStreaming()) {
272 printer->Print(*vars,
273 "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
274 "$Request$, $Response$>> "
275 "$Method$(::grpc::ClientContext* context) {\n");
279 "return std::unique_ptr< "
280 "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
281 "$Method$Raw(context));\n");
283 printer->Print("}\n");
284 for (auto async_prefix : async_prefixes) {
285 (*vars)["AsyncPrefix"] = async_prefix.prefix;
286 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
287 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
291 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
292 "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
293 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
297 "return std::unique_ptr< "
298 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
299 "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
301 printer->Print("}\n");
305 if (method->NoStreaming()) {
306 for (auto async_prefix : async_prefixes) {
307 (*vars)["AsyncPrefix"] = async_prefix.prefix;
310 "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
311 "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
312 "const $Request$& request, "
313 "::grpc::CompletionQueue* cq) = 0;\n");
315 } else if (ClientOnlyStreaming(method)) {
318 "virtual ::grpc::ClientWriterInterface< $Request$>*"
320 "::grpc::ClientContext* context, $Response$* response) = 0;\n");
321 for (auto async_prefix : async_prefixes) {
322 (*vars)["AsyncPrefix"] = async_prefix.prefix;
323 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
326 "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
327 " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
328 "$Response$* response, "
329 "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
331 } else if (ServerOnlyStreaming(method)) {
334 "virtual ::grpc::ClientReaderInterface< $Response$>* "
336 "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
337 for (auto async_prefix : async_prefixes) {
338 (*vars)["AsyncPrefix"] = async_prefix.prefix;
339 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
342 "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
343 "$AsyncPrefix$$Method$Raw("
344 "::grpc::ClientContext* context, const $Request$& request, "
345 "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
347 } else if (method->BidiStreaming()) {
348 printer->Print(*vars,
349 "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
351 "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
352 for (auto async_prefix : async_prefixes) {
353 (*vars)["AsyncPrefix"] = async_prefix.prefix;
354 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
357 "virtual ::grpc::ClientAsyncReaderWriterInterface< "
358 "$Request$, $Response$>* "
359 "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
360 "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
366 void PrintHeaderClientMethod(grpc_generator::Printer* printer,
367 const grpc_generator::Method* method,
368 std::map<grpc::string, grpc::string>* vars,
370 (*vars)["Method"] = method->name();
371 (*vars)["Request"] = method->input_type_name();
372 (*vars)["Response"] = method->output_type_name();
375 grpc::string method_params; // extra arguments to method
376 grpc::string raw_args; // extra arguments to raw version of method
377 } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
378 {"PrepareAsync", "", ""}};
381 if (method->NoStreaming()) {
384 "::grpc::Status $Method$(::grpc::ClientContext* context, "
385 "const $Request$& request, $Response$* response) override;\n");
386 for (auto async_prefix : async_prefixes) {
387 (*vars)["AsyncPrefix"] = async_prefix.prefix;
390 "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
391 "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
392 "const $Request$& request, "
393 "::grpc::CompletionQueue* cq) {\n");
395 printer->Print(*vars,
396 "return std::unique_ptr< "
397 "::grpc::ClientAsyncResponseReader< $Response$>>("
398 "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
400 printer->Print("}\n");
402 } else if (ClientOnlyStreaming(method)) {
405 "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
407 "::grpc::ClientContext* context, $Response$* response) {\n");
409 printer->Print(*vars,
410 "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
411 "($Method$Raw(context, response));\n");
413 printer->Print("}\n");
414 for (auto async_prefix : async_prefixes) {
415 (*vars)["AsyncPrefix"] = async_prefix.prefix;
416 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
417 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
418 printer->Print(*vars,
419 "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
420 " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
421 "$Response$* response, "
422 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
426 "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
427 "$AsyncPrefix$$Method$Raw(context, response, "
428 "cq$AsyncRawArgs$));\n");
430 printer->Print("}\n");
432 } else if (ServerOnlyStreaming(method)) {
435 "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
436 " $Method$(::grpc::ClientContext* context, const $Request$& request)"
441 "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
442 "($Method$Raw(context, request));\n");
444 printer->Print("}\n");
445 for (auto async_prefix : async_prefixes) {
446 (*vars)["AsyncPrefix"] = async_prefix.prefix;
447 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
448 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
451 "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
452 "$AsyncPrefix$$Method$("
453 "::grpc::ClientContext* context, const $Request$& request, "
454 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
458 "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
459 "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
461 printer->Print("}\n");
463 } else if (method->BidiStreaming()) {
466 "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
467 " $Method$(::grpc::ClientContext* context) {\n");
469 printer->Print(*vars,
470 "return std::unique_ptr< "
471 "::grpc::ClientReaderWriter< $Request$, $Response$>>("
472 "$Method$Raw(context));\n");
474 printer->Print("}\n");
475 for (auto async_prefix : async_prefixes) {
476 (*vars)["AsyncPrefix"] = async_prefix.prefix;
477 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
478 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
479 printer->Print(*vars,
480 "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
481 "$Request$, $Response$>> "
482 "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
483 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
487 "return std::unique_ptr< "
488 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
489 "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
491 printer->Print("}\n");
495 if (method->NoStreaming()) {
496 for (auto async_prefix : async_prefixes) {
497 (*vars)["AsyncPrefix"] = async_prefix.prefix;
500 "::grpc::ClientAsyncResponseReader< $Response$>* "
501 "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
502 "const $Request$& request, "
503 "::grpc::CompletionQueue* cq) override;\n");
505 } else if (ClientOnlyStreaming(method)) {
506 printer->Print(*vars,
507 "::grpc::ClientWriter< $Request$>* $Method$Raw("
508 "::grpc::ClientContext* context, $Response$* response) "
510 for (auto async_prefix : async_prefixes) {
511 (*vars)["AsyncPrefix"] = async_prefix.prefix;
512 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
513 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
516 "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
517 "::grpc::ClientContext* context, $Response$* response, "
518 "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
520 } else if (ServerOnlyStreaming(method)) {
521 printer->Print(*vars,
522 "::grpc::ClientReader< $Response$>* $Method$Raw("
523 "::grpc::ClientContext* context, const $Request$& request)"
525 for (auto async_prefix : async_prefixes) {
526 (*vars)["AsyncPrefix"] = async_prefix.prefix;
527 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
528 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
531 "::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw("
532 "::grpc::ClientContext* context, const $Request$& request, "
533 "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
535 } else if (method->BidiStreaming()) {
536 printer->Print(*vars,
537 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
538 "$Method$Raw(::grpc::ClientContext* context) override;\n");
539 for (auto async_prefix : async_prefixes) {
540 (*vars)["AsyncPrefix"] = async_prefix.prefix;
541 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
542 (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
545 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
546 "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
547 "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
553 void PrintHeaderClientMethodCallbackInterfacesStart(
554 grpc_generator::Printer* printer,
555 std::map<grpc::string, grpc::string>* vars) {
556 // This declares the interface for the callback-based API. The components
557 // are pure; even though this is new (post-1.0) API, it can be pure because
558 // it is an entirely new interface that happens to be scoped within
559 // StubInterface, not new additions to StubInterface itself
560 printer->Print("class experimental_async_interface {\n");
561 // All methods in this new interface are public. There is no need for private
562 // "Raw" methods since the callback-based API returns unowned raw pointers
563 printer->Print(" public:\n");
565 printer->Print("virtual ~experimental_async_interface() {}\n");
568 void PrintHeaderClientMethodCallbackInterfaces(
569 grpc_generator::Printer* printer, const grpc_generator::Method* method,
570 std::map<grpc::string, grpc::string>* vars, bool is_public) {
571 // Reserve is_public for future expansion
574 (*vars)["Method"] = method->name();
575 (*vars)["Request"] = method->input_type_name();
576 (*vars)["Response"] = method->output_type_name();
578 if (method->NoStreaming()) {
579 printer->Print(*vars,
580 "virtual void $Method$(::grpc::ClientContext* context, "
581 "const $Request$* request, $Response$* response, "
582 "std::function<void(::grpc::Status)>) = 0;\n");
583 printer->Print(*vars,
584 "virtual void $Method$(::grpc::ClientContext* context, "
585 "const ::grpc::ByteBuffer* request, $Response$* response, "
586 "std::function<void(::grpc::Status)>) = 0;\n");
587 } else if (ClientOnlyStreaming(method)) {
588 printer->Print(*vars,
589 "virtual void $Method$(::grpc::ClientContext* context, "
590 "$Response$* response, "
591 "::grpc::experimental::ClientWriteReactor< $Request$>* "
593 } else if (ServerOnlyStreaming(method)) {
594 printer->Print(*vars,
595 "virtual void $Method$(::grpc::ClientContext* context, "
596 "$Request$* request, "
597 "::grpc::experimental::ClientReadReactor< $Response$>* "
599 } else if (method->BidiStreaming()) {
600 printer->Print(*vars,
601 "virtual void $Method$(::grpc::ClientContext* context, "
602 "::grpc::experimental::ClientBidiReactor< "
603 "$Request$,$Response$>* reactor) = 0;\n");
607 void PrintHeaderClientMethodCallbackInterfacesEnd(
608 grpc_generator::Printer* printer,
609 std::map<grpc::string, grpc::string>* vars) {
611 printer->Print("};\n");
613 // Declare a function to give the async stub contents. It can't be pure
614 // since this is a new API in StubInterface, but it is meaningless by default
615 // (since any stub that wants to use it must have its own implementation of
616 // the callback functions therein), so make the default return value nullptr.
617 // Intentionally include the word "class" to avoid possible shadowing.
619 "virtual class experimental_async_interface* experimental_async() { "
620 "return nullptr; }\n");
623 void PrintHeaderClientMethodCallbackStart(
624 grpc_generator::Printer* printer,
625 std::map<grpc::string, grpc::string>* vars) {
626 // This declares the stub entry for the callback-based API.
627 printer->Print("class experimental_async final :\n");
628 printer->Print(" public StubInterface::experimental_async_interface {\n");
629 printer->Print(" public:\n");
633 void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
634 const grpc_generator::Method* method,
635 std::map<grpc::string, grpc::string>* vars,
637 // Reserve is_public for future expansion
640 (*vars)["Method"] = method->name();
641 (*vars)["Request"] = method->input_type_name();
642 (*vars)["Response"] = method->output_type_name();
644 if (method->NoStreaming()) {
645 printer->Print(*vars,
646 "void $Method$(::grpc::ClientContext* context, "
647 "const $Request$* request, $Response$* response, "
648 "std::function<void(::grpc::Status)>) override;\n");
649 printer->Print(*vars,
650 "void $Method$(::grpc::ClientContext* context, "
651 "const ::grpc::ByteBuffer* request, $Response$* response, "
652 "std::function<void(::grpc::Status)>) override;\n");
653 } else if (ClientOnlyStreaming(method)) {
654 printer->Print(*vars,
655 "void $Method$(::grpc::ClientContext* context, "
656 "$Response$* response, "
657 "::grpc::experimental::ClientWriteReactor< $Request$>* "
658 "reactor) override;\n");
659 } else if (ServerOnlyStreaming(method)) {
660 printer->Print(*vars,
661 "void $Method$(::grpc::ClientContext* context, "
662 "$Request$* request, "
663 "::grpc::experimental::ClientReadReactor< $Response$>* "
664 "reactor) override;\n");
666 } else if (method->BidiStreaming()) {
667 printer->Print(*vars,
668 "void $Method$(::grpc::ClientContext* context, "
669 "::grpc::experimental::ClientBidiReactor< "
670 "$Request$,$Response$>* reactor) override;\n");
674 void PrintHeaderClientMethodCallbackEnd(
675 grpc_generator::Printer* printer,
676 std::map<grpc::string, grpc::string>* vars) {
678 printer->Print(" private:\n");
680 printer->Print("friend class Stub;\n");
681 printer->Print("explicit experimental_async(Stub* stub): stub_(stub) { }\n");
682 // include a function with a dummy use of stub_ to avoid an unused
683 // private member warning for service with no methods
684 printer->Print("Stub* stub() { return stub_; }\n");
685 printer->Print("Stub* stub_;\n");
687 printer->Print("};\n");
690 "class experimental_async_interface* experimental_async() override { "
691 "return &async_stub_; }\n");
694 void PrintHeaderClientMethodData(grpc_generator::Printer* printer,
695 const grpc_generator::Method* method,
696 std::map<grpc::string, grpc::string>* vars) {
697 (*vars)["Method"] = method->name();
698 printer->Print(*vars,
699 "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
702 void PrintHeaderServerMethodSync(grpc_generator::Printer* printer,
703 const grpc_generator::Method* method,
704 std::map<grpc::string, grpc::string>* vars) {
705 (*vars)["Method"] = method->name();
706 (*vars)["Request"] = method->input_type_name();
707 (*vars)["Response"] = method->output_type_name();
708 printer->Print(method->GetLeadingComments("//").c_str());
709 if (method->NoStreaming()) {
710 printer->Print(*vars,
711 "virtual ::grpc::Status $Method$("
712 "::grpc::ServerContext* context, const $Request$* request, "
713 "$Response$* response);\n");
714 } else if (ClientOnlyStreaming(method)) {
715 printer->Print(*vars,
716 "virtual ::grpc::Status $Method$("
717 "::grpc::ServerContext* context, "
718 "::grpc::ServerReader< $Request$>* reader, "
719 "$Response$* response);\n");
720 } else if (ServerOnlyStreaming(method)) {
721 printer->Print(*vars,
722 "virtual ::grpc::Status $Method$("
723 "::grpc::ServerContext* context, const $Request$* request, "
724 "::grpc::ServerWriter< $Response$>* writer);\n");
725 } else if (method->BidiStreaming()) {
728 "virtual ::grpc::Status $Method$("
729 "::grpc::ServerContext* context, "
730 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
733 printer->Print(method->GetTrailingComments("//").c_str());
736 // Helper generator. Disables the sync API for Request and Response, then adds
737 // in an async API for RealRequest and RealResponse types. This is to be used
738 // to generate async and raw async APIs.
739 void PrintHeaderServerAsyncMethodsHelper(
740 grpc_generator::Printer* printer, const grpc_generator::Method* method,
741 std::map<grpc::string, grpc::string>* vars) {
742 if (method->NoStreaming()) {
745 "// disable synchronous version of this method\n"
746 "::grpc::Status $Method$("
747 "::grpc::ServerContext* context, const $Request$* request, "
748 "$Response$* response) override {\n"
750 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
754 "void Request$Method$("
755 "::grpc::ServerContext* context, $RealRequest$* request, "
756 "::grpc::ServerAsyncResponseWriter< $RealResponse$>* response, "
757 "::grpc::CompletionQueue* new_call_cq, "
758 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
759 printer->Print(*vars,
760 " ::grpc::Service::RequestAsyncUnary($Idx$, context, "
761 "request, response, new_call_cq, notification_cq, tag);\n");
762 printer->Print("}\n");
763 } else if (ClientOnlyStreaming(method)) {
766 "// disable synchronous version of this method\n"
767 "::grpc::Status $Method$("
768 "::grpc::ServerContext* context, "
769 "::grpc::ServerReader< $Request$>* reader, "
770 "$Response$* response) override {\n"
772 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
776 "void Request$Method$("
777 "::grpc::ServerContext* context, "
778 "::grpc::ServerAsyncReader< $RealResponse$, $RealRequest$>* reader, "
779 "::grpc::CompletionQueue* new_call_cq, "
780 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
781 printer->Print(*vars,
782 " ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
783 "context, reader, new_call_cq, notification_cq, tag);\n");
784 printer->Print("}\n");
785 } else if (ServerOnlyStreaming(method)) {
788 "// disable synchronous version of this method\n"
789 "::grpc::Status $Method$("
790 "::grpc::ServerContext* context, const $Request$* request, "
791 "::grpc::ServerWriter< $Response$>* writer) override "
794 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
798 "void Request$Method$("
799 "::grpc::ServerContext* context, $RealRequest$* request, "
800 "::grpc::ServerAsyncWriter< $RealResponse$>* writer, "
801 "::grpc::CompletionQueue* new_call_cq, "
802 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
805 " ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
806 "context, request, writer, new_call_cq, notification_cq, tag);\n");
807 printer->Print("}\n");
808 } else if (method->BidiStreaming()) {
811 "// disable synchronous version of this method\n"
812 "::grpc::Status $Method$("
813 "::grpc::ServerContext* context, "
814 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
817 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
821 "void Request$Method$("
822 "::grpc::ServerContext* context, "
823 "::grpc::ServerAsyncReaderWriter< $RealResponse$, $RealRequest$>* "
825 "::grpc::CompletionQueue* new_call_cq, "
826 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
827 printer->Print(*vars,
828 " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
829 "context, stream, new_call_cq, notification_cq, tag);\n");
830 printer->Print("}\n");
834 void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
835 const grpc_generator::Method* method,
836 std::map<grpc::string, grpc::string>* vars) {
837 (*vars)["Method"] = method->name();
838 // These will be disabled
839 (*vars)["Request"] = method->input_type_name();
840 (*vars)["Response"] = method->output_type_name();
841 // These will be used for the async API
842 (*vars)["RealRequest"] = method->input_type_name();
843 (*vars)["RealResponse"] = method->output_type_name();
844 printer->Print(*vars, "template <class BaseClass>\n");
845 printer->Print(*vars,
846 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
849 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
850 printer->Print(" public:\n");
852 printer->Print(*vars,
853 "WithAsyncMethod_$Method$() {\n"
854 " ::grpc::Service::MarkMethodAsync($Idx$);\n"
856 printer->Print(*vars,
857 "~WithAsyncMethod_$Method$() override {\n"
858 " BaseClassMustBeDerivedFromService(this);\n"
860 PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
862 printer->Print(*vars, "};\n");
865 // Helper generator. Disables the sync API for Request and Response, then adds
866 // in a callback API for RealRequest and RealResponse types. This is to be used
867 // to generate callback and raw callback APIs.
868 void PrintHeaderServerCallbackMethodsHelper(
869 grpc_generator::Printer* printer, const grpc_generator::Method* method,
870 std::map<grpc::string, grpc::string>* vars) {
871 if (method->NoStreaming()) {
874 "// disable synchronous version of this method\n"
875 "::grpc::Status $Method$("
876 "::grpc::ServerContext* context, const $Request$* request, "
877 "$Response$* response) override {\n"
879 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
883 "virtual void $Method$("
884 "::grpc::ServerContext* context, const $RealRequest$* request, "
885 "$RealResponse$* response, "
886 "::grpc::experimental::ServerCallbackRpcController* "
887 "controller) { controller->Finish(::grpc::Status("
888 "::grpc::StatusCode::UNIMPLEMENTED, \"\")); }\n");
889 } else if (ClientOnlyStreaming(method)) {
892 "// disable synchronous version of this method\n"
893 "::grpc::Status $Method$("
894 "::grpc::ServerContext* context, "
895 "::grpc::ServerReader< $Request$>* reader, "
896 "$Response$* response) override {\n"
898 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
900 printer->Print(*vars,
901 "virtual ::grpc::experimental::ServerReadReactor< "
902 "$RealRequest$, $RealResponse$>* $Method$() {\n"
903 " return new ::grpc::internal::UnimplementedReadReactor<\n"
904 " $RealRequest$, $RealResponse$>;}\n");
905 } else if (ServerOnlyStreaming(method)) {
908 "// disable synchronous version of this method\n"
909 "::grpc::Status $Method$("
910 "::grpc::ServerContext* context, const $Request$* request, "
911 "::grpc::ServerWriter< $Response$>* writer) override "
914 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
916 printer->Print(*vars,
917 "virtual ::grpc::experimental::ServerWriteReactor< "
918 "$RealRequest$, $RealResponse$>* $Method$() {\n"
919 " return new ::grpc::internal::UnimplementedWriteReactor<\n"
920 " $RealRequest$, $RealResponse$>;}\n");
921 } else if (method->BidiStreaming()) {
924 "// disable synchronous version of this method\n"
925 "::grpc::Status $Method$("
926 "::grpc::ServerContext* context, "
927 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
930 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
932 printer->Print(*vars,
933 "virtual ::grpc::experimental::ServerBidiReactor< "
934 "$RealRequest$, $RealResponse$>* $Method$() {\n"
935 " return new ::grpc::internal::UnimplementedBidiReactor<\n"
936 " $RealRequest$, $RealResponse$>;}\n");
940 void PrintHeaderServerMethodCallback(
941 grpc_generator::Printer* printer, const grpc_generator::Method* method,
942 std::map<grpc::string, grpc::string>* vars) {
943 (*vars)["Method"] = method->name();
944 // These will be disabled
945 (*vars)["Request"] = method->input_type_name();
946 (*vars)["Response"] = method->output_type_name();
947 // These will be used for the callback API
948 (*vars)["RealRequest"] = method->input_type_name();
949 (*vars)["RealResponse"] = method->output_type_name();
950 printer->Print(*vars, "template <class BaseClass>\n");
953 "class ExperimentalWithCallbackMethod_$Method$ : public BaseClass {\n");
956 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
957 printer->Print(" public:\n");
959 printer->Print(*vars, "ExperimentalWithCallbackMethod_$Method$() {\n");
960 if (method->NoStreaming()) {
963 " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
964 " new ::grpc::internal::CallbackUnaryHandler< "
965 "$RealRequest$, $RealResponse$>(\n"
966 " [this](::grpc::ServerContext* context,\n"
967 " const $RealRequest$* request,\n"
968 " $RealResponse$* response,\n"
969 " ::grpc::experimental::ServerCallbackRpcController* "
972 "Method$(context, request, response, controller);\n"
974 } else if (ClientOnlyStreaming(method)) {
977 " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
978 " new ::grpc::internal::CallbackClientStreamingHandler< "
979 "$RealRequest$, $RealResponse$>(\n"
980 " [this] { return this->$Method$(); }));\n");
981 } else if (ServerOnlyStreaming(method)) {
984 " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
985 " new ::grpc::internal::CallbackServerStreamingHandler< "
986 "$RealRequest$, $RealResponse$>(\n"
987 " [this] { return this->$Method$(); }));\n");
988 } else if (method->BidiStreaming()) {
991 " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
992 " new ::grpc::internal::CallbackBidiHandler< "
993 "$RealRequest$, $RealResponse$>(\n"
994 " [this] { return this->$Method$(); }));\n");
996 printer->Print(*vars, "}\n");
997 printer->Print(*vars,
998 "~ExperimentalWithCallbackMethod_$Method$() override {\n"
999 " BaseClassMustBeDerivedFromService(this);\n"
1001 PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
1003 printer->Print(*vars, "};\n");
1006 void PrintHeaderServerMethodRawCallback(
1007 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1008 std::map<grpc::string, grpc::string>* vars) {
1009 (*vars)["Method"] = method->name();
1010 // These will be disabled
1011 (*vars)["Request"] = method->input_type_name();
1012 (*vars)["Response"] = method->output_type_name();
1013 // These will be used for raw API
1014 (*vars)["RealRequest"] = "::grpc::ByteBuffer";
1015 (*vars)["RealResponse"] = "::grpc::ByteBuffer";
1016 printer->Print(*vars, "template <class BaseClass>\n");
1017 printer->Print(*vars,
1018 "class ExperimentalWithRawCallbackMethod_$Method$ : public "
1022 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1023 printer->Print(" public:\n");
1025 printer->Print(*vars, "ExperimentalWithRawCallbackMethod_$Method$() {\n");
1026 if (method->NoStreaming()) {
1029 " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1030 " new ::grpc::internal::CallbackUnaryHandler< "
1031 "$RealRequest$, $RealResponse$>(\n"
1032 " [this](::grpc::ServerContext* context,\n"
1033 " const $RealRequest$* request,\n"
1034 " $RealResponse$* response,\n"
1035 " ::grpc::experimental::ServerCallbackRpcController* "
1038 "Method$(context, request, response, controller);\n"
1040 } else if (ClientOnlyStreaming(method)) {
1043 " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1044 " new ::grpc::internal::CallbackClientStreamingHandler< "
1045 "$RealRequest$, $RealResponse$>(\n"
1046 " [this] { return this->$Method$(); }));\n");
1047 } else if (ServerOnlyStreaming(method)) {
1050 " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1051 " new ::grpc::internal::CallbackServerStreamingHandler< "
1052 "$RealRequest$, $RealResponse$>(\n"
1053 " [this] { return this->$Method$(); }));\n");
1054 } else if (method->BidiStreaming()) {
1057 " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1058 " new ::grpc::internal::CallbackBidiHandler< "
1059 "$RealRequest$, $RealResponse$>(\n"
1060 " [this] { return this->$Method$(); }));\n");
1062 printer->Print(*vars, "}\n");
1063 printer->Print(*vars,
1064 "~ExperimentalWithRawCallbackMethod_$Method$() override {\n"
1065 " BaseClassMustBeDerivedFromService(this);\n"
1067 PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
1069 printer->Print(*vars, "};\n");
1072 void PrintHeaderServerMethodStreamedUnary(
1073 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1074 std::map<grpc::string, grpc::string>* vars) {
1075 (*vars)["Method"] = method->name();
1076 (*vars)["Request"] = method->input_type_name();
1077 (*vars)["Response"] = method->output_type_name();
1078 if (method->NoStreaming()) {
1079 printer->Print(*vars, "template <class BaseClass>\n");
1080 printer->Print(*vars,
1081 "class WithStreamedUnaryMethod_$Method$ : "
1082 "public BaseClass {\n");
1085 " void BaseClassMustBeDerivedFromService(const Service *service) "
1087 printer->Print(" public:\n");
1089 printer->Print(*vars,
1090 "WithStreamedUnaryMethod_$Method$() {\n"
1091 " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
1092 " new ::grpc::internal::StreamedUnaryHandler< $Request$, "
1093 "$Response$>(std::bind"
1094 "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
1095 "Streamed$Method$, this, std::placeholders::_1, "
1096 "std::placeholders::_2)));\n"
1098 printer->Print(*vars,
1099 "~WithStreamedUnaryMethod_$Method$() override {\n"
1100 " BaseClassMustBeDerivedFromService(this);\n"
1104 "// disable regular version of this method\n"
1105 "::grpc::Status $Method$("
1106 "::grpc::ServerContext* context, const $Request$* request, "
1107 "$Response$* response) override {\n"
1109 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1111 printer->Print(*vars,
1112 "// replace default version of method with streamed unary\n"
1113 "virtual ::grpc::Status Streamed$Method$("
1114 "::grpc::ServerContext* context, "
1115 "::grpc::ServerUnaryStreamer< "
1116 "$Request$,$Response$>* server_unary_streamer)"
1119 printer->Print(*vars, "};\n");
1123 void PrintHeaderServerMethodSplitStreaming(
1124 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1125 std::map<grpc::string, grpc::string>* vars) {
1126 (*vars)["Method"] = method->name();
1127 (*vars)["Request"] = method->input_type_name();
1128 (*vars)["Response"] = method->output_type_name();
1129 if (ServerOnlyStreaming(method)) {
1130 printer->Print(*vars, "template <class BaseClass>\n");
1131 printer->Print(*vars,
1132 "class WithSplitStreamingMethod_$Method$ : "
1133 "public BaseClass {\n");
1136 " void BaseClassMustBeDerivedFromService(const Service *service) "
1138 printer->Print(" public:\n");
1142 "WithSplitStreamingMethod_$Method$() {\n"
1143 " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
1144 " new ::grpc::internal::SplitServerStreamingHandler< $Request$, "
1145 "$Response$>(std::bind"
1146 "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
1147 "Streamed$Method$, this, std::placeholders::_1, "
1148 "std::placeholders::_2)));\n"
1150 printer->Print(*vars,
1151 "~WithSplitStreamingMethod_$Method$() override {\n"
1152 " BaseClassMustBeDerivedFromService(this);\n"
1156 "// disable regular version of this method\n"
1157 "::grpc::Status $Method$("
1158 "::grpc::ServerContext* context, const $Request$* request, "
1159 "::grpc::ServerWriter< $Response$>* writer) override "
1162 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1164 printer->Print(*vars,
1165 "// replace default version of method with split streamed\n"
1166 "virtual ::grpc::Status Streamed$Method$("
1167 "::grpc::ServerContext* context, "
1168 "::grpc::ServerSplitStreamer< "
1169 "$Request$,$Response$>* server_split_streamer)"
1172 printer->Print(*vars, "};\n");
1176 void PrintHeaderServerMethodGeneric(
1177 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1178 std::map<grpc::string, grpc::string>* vars) {
1179 (*vars)["Method"] = method->name();
1180 (*vars)["Request"] = method->input_type_name();
1181 (*vars)["Response"] = method->output_type_name();
1182 printer->Print(*vars, "template <class BaseClass>\n");
1183 printer->Print(*vars,
1184 "class WithGenericMethod_$Method$ : public BaseClass {\n");
1187 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1188 printer->Print(" public:\n");
1190 printer->Print(*vars,
1191 "WithGenericMethod_$Method$() {\n"
1192 " ::grpc::Service::MarkMethodGeneric($Idx$);\n"
1194 printer->Print(*vars,
1195 "~WithGenericMethod_$Method$() override {\n"
1196 " BaseClassMustBeDerivedFromService(this);\n"
1198 if (method->NoStreaming()) {
1201 "// disable synchronous version of this method\n"
1202 "::grpc::Status $Method$("
1203 "::grpc::ServerContext* context, const $Request$* request, "
1204 "$Response$* response) override {\n"
1206 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1208 } else if (ClientOnlyStreaming(method)) {
1211 "// disable synchronous version of this method\n"
1212 "::grpc::Status $Method$("
1213 "::grpc::ServerContext* context, "
1214 "::grpc::ServerReader< $Request$>* reader, "
1215 "$Response$* response) override {\n"
1217 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1219 } else if (ServerOnlyStreaming(method)) {
1222 "// disable synchronous version of this method\n"
1223 "::grpc::Status $Method$("
1224 "::grpc::ServerContext* context, const $Request$* request, "
1225 "::grpc::ServerWriter< $Response$>* writer) override "
1228 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1230 } else if (method->BidiStreaming()) {
1233 "// disable synchronous version of this method\n"
1234 "::grpc::Status $Method$("
1235 "::grpc::ServerContext* context, "
1236 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
1239 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1243 printer->Print(*vars, "};\n");
1246 void PrintHeaderServerMethodRaw(grpc_generator::Printer* printer,
1247 const grpc_generator::Method* method,
1248 std::map<grpc::string, grpc::string>* vars) {
1249 (*vars)["Method"] = method->name();
1250 // These will be disabled
1251 (*vars)["Request"] = method->input_type_name();
1252 (*vars)["Response"] = method->output_type_name();
1253 // These will be used for raw API
1254 (*vars)["RealRequest"] = "::grpc::ByteBuffer";
1255 (*vars)["RealResponse"] = "::grpc::ByteBuffer";
1256 printer->Print(*vars, "template <class BaseClass>\n");
1257 printer->Print(*vars, "class WithRawMethod_$Method$ : public BaseClass {\n");
1260 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1261 printer->Print(" public:\n");
1263 printer->Print(*vars,
1264 "WithRawMethod_$Method$() {\n"
1265 " ::grpc::Service::MarkMethodRaw($Idx$);\n"
1267 printer->Print(*vars,
1268 "~WithRawMethod_$Method$() override {\n"
1269 " BaseClassMustBeDerivedFromService(this);\n"
1271 PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
1273 printer->Print(*vars, "};\n");
1276 void PrintHeaderService(grpc_generator::Printer* printer,
1277 const grpc_generator::Service* service,
1278 std::map<grpc::string, grpc::string>* vars) {
1279 (*vars)["Service"] = service->name();
1281 printer->Print(service->GetLeadingComments("//").c_str());
1282 printer->Print(*vars,
1283 "class $Service$ final {\n"
1288 printer->Print(*vars,
1289 "static constexpr char const* service_full_name() {\n"
1290 " return \"$Package$$Service$\";\n"
1295 "class StubInterface {\n"
1298 printer->Print("virtual ~StubInterface() {}\n");
1299 for (int i = 0; i < service->method_count(); ++i) {
1300 printer->Print(service->method(i)->GetLeadingComments("//").c_str());
1301 PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
1303 printer->Print(service->method(i)->GetTrailingComments("//").c_str());
1305 PrintHeaderClientMethodCallbackInterfacesStart(printer, vars);
1306 for (int i = 0; i < service->method_count(); ++i) {
1307 printer->Print(service->method(i)->GetLeadingComments("//").c_str());
1308 PrintHeaderClientMethodCallbackInterfaces(printer, service->method(i).get(),
1310 printer->Print(service->method(i)->GetTrailingComments("//").c_str());
1312 PrintHeaderClientMethodCallbackInterfacesEnd(printer, vars);
1314 printer->Print("private:\n");
1316 for (int i = 0; i < service->method_count(); ++i) {
1317 PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
1321 printer->Print("};\n");
1323 "class Stub final : public StubInterface"
1327 "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
1329 for (int i = 0; i < service->method_count(); ++i) {
1330 PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
1332 PrintHeaderClientMethodCallbackStart(printer, vars);
1333 for (int i = 0; i < service->method_count(); ++i) {
1334 PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars,
1337 PrintHeaderClientMethodCallbackEnd(printer, vars);
1339 printer->Print("\n private:\n");
1341 printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
1342 printer->Print("class experimental_async async_stub_{this};\n");
1343 for (int i = 0; i < service->method_count(); ++i) {
1344 PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
1346 for (int i = 0; i < service->method_count(); ++i) {
1347 PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
1350 printer->Print("};\n");
1352 "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
1353 "::grpc::ChannelInterface>& channel, "
1354 "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
1356 printer->Print("\n");
1358 // Server side - base
1360 "class Service : public ::grpc::Service {\n"
1363 printer->Print("Service();\n");
1364 printer->Print("virtual ~Service();\n");
1365 for (int i = 0; i < service->method_count(); ++i) {
1366 PrintHeaderServerMethodSync(printer, service->method(i).get(), vars);
1369 printer->Print("};\n");
1371 // Server side - Asynchronous
1372 for (int i = 0; i < service->method_count(); ++i) {
1373 (*vars)["Idx"] = as_string(i);
1374 PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars);
1377 printer->Print("typedef ");
1379 for (int i = 0; i < service->method_count(); ++i) {
1380 (*vars)["method_name"] = service->method(i)->name();
1381 printer->Print(*vars, "WithAsyncMethod_$method_name$<");
1383 printer->Print("Service");
1384 for (int i = 0; i < service->method_count(); ++i) {
1385 printer->Print(" >");
1387 printer->Print(" AsyncService;\n");
1389 // Server side - Callback
1390 for (int i = 0; i < service->method_count(); ++i) {
1391 (*vars)["Idx"] = as_string(i);
1392 PrintHeaderServerMethodCallback(printer, service->method(i).get(), vars);
1395 printer->Print("typedef ");
1397 for (int i = 0; i < service->method_count(); ++i) {
1398 (*vars)["method_name"] = service->method(i)->name();
1399 printer->Print(*vars, "ExperimentalWithCallbackMethod_$method_name$<");
1401 printer->Print("Service");
1402 for (int i = 0; i < service->method_count(); ++i) {
1403 printer->Print(" >");
1405 printer->Print(" ExperimentalCallbackService;\n");
1407 // Server side - Generic
1408 for (int i = 0; i < service->method_count(); ++i) {
1409 (*vars)["Idx"] = as_string(i);
1410 PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
1413 // Server side - Raw
1414 for (int i = 0; i < service->method_count(); ++i) {
1415 (*vars)["Idx"] = as_string(i);
1416 PrintHeaderServerMethodRaw(printer, service->method(i).get(), vars);
1419 // Server side - Raw Callback
1420 for (int i = 0; i < service->method_count(); ++i) {
1421 (*vars)["Idx"] = as_string(i);
1422 PrintHeaderServerMethodRawCallback(printer, service->method(i).get(), vars);
1425 // Server side - Streamed Unary
1426 for (int i = 0; i < service->method_count(); ++i) {
1427 (*vars)["Idx"] = as_string(i);
1428 PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
1432 printer->Print("typedef ");
1433 for (int i = 0; i < service->method_count(); ++i) {
1434 (*vars)["method_name"] = service->method(i)->name();
1435 if (service->method(i)->NoStreaming()) {
1436 printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
1439 printer->Print("Service");
1440 for (int i = 0; i < service->method_count(); ++i) {
1441 if (service->method(i)->NoStreaming()) {
1442 printer->Print(" >");
1445 printer->Print(" StreamedUnaryService;\n");
1447 // Server side - controlled server-side streaming
1448 for (int i = 0; i < service->method_count(); ++i) {
1449 (*vars)["Idx"] = as_string(i);
1450 PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(),
1454 printer->Print("typedef ");
1455 for (int i = 0; i < service->method_count(); ++i) {
1456 (*vars)["method_name"] = service->method(i)->name();
1457 auto method = service->method(i);
1458 if (ServerOnlyStreaming(method.get())) {
1459 printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
1462 printer->Print("Service");
1463 for (int i = 0; i < service->method_count(); ++i) {
1464 auto method = service->method(i);
1465 if (ServerOnlyStreaming(method.get())) {
1466 printer->Print(" >");
1469 printer->Print(" SplitStreamedService;\n");
1471 // Server side - typedef for controlled both unary and server-side streaming
1472 printer->Print("typedef ");
1473 for (int i = 0; i < service->method_count(); ++i) {
1474 (*vars)["method_name"] = service->method(i)->name();
1475 auto method = service->method(i);
1476 if (ServerOnlyStreaming(method.get())) {
1477 printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
1479 if (service->method(i)->NoStreaming()) {
1480 printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
1483 printer->Print("Service");
1484 for (int i = 0; i < service->method_count(); ++i) {
1485 auto method = service->method(i);
1486 if (service->method(i)->NoStreaming() ||
1487 ServerOnlyStreaming(method.get())) {
1488 printer->Print(" >");
1491 printer->Print(" StreamedService;\n");
1494 printer->Print("};\n");
1495 printer->Print(service->GetTrailingComments("//").c_str());
1498 grpc::string GetHeaderServices(grpc_generator::File* file,
1499 const Parameters& params) {
1500 grpc::string output;
1502 // Scope the output stream so it closes and finalizes output to the string.
1503 auto printer = file->CreatePrinter(&output);
1504 std::map<grpc::string, grpc::string> vars;
1505 // Package string is empty or ends with a dot. It is used to fully qualify
1507 vars["Package"] = file->package();
1508 if (!file->package().empty()) {
1509 vars["Package"].append(".");
1512 if (!params.services_namespace.empty()) {
1513 vars["services_namespace"] = params.services_namespace;
1514 printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
1517 for (int i = 0; i < file->service_count(); ++i) {
1518 PrintHeaderService(printer.get(), file->service(i).get(), &vars);
1519 printer->Print("\n");
1522 if (!params.services_namespace.empty()) {
1523 printer->Print(vars, "} // namespace $services_namespace$\n\n");
1529 grpc::string GetHeaderEpilogue(grpc_generator::File* file,
1530 const Parameters& /*params*/) {
1531 grpc::string output;
1533 // Scope the output stream so it closes and finalizes output to the string.
1534 auto printer = file->CreatePrinter(&output);
1535 std::map<grpc::string, grpc::string> vars;
1537 vars["filename"] = file->filename();
1538 vars["filename_identifier"] = FilenameIdentifier(file->filename());
1540 if (!file->package().empty()) {
1541 std::vector<grpc::string> parts = file->package_parts();
1543 for (auto part = parts.rbegin(); part != parts.rend(); part++) {
1544 vars["part"] = *part;
1545 printer->Print(vars, "} // namespace $part$\n");
1547 printer->Print(vars, "\n");
1550 printer->Print(vars, "\n");
1551 printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
1553 printer->Print(file->GetTrailingComments("//").c_str());
1558 grpc::string GetSourcePrologue(grpc_generator::File* file,
1559 const Parameters& /*params*/) {
1560 grpc::string output;
1562 // Scope the output stream so it closes and finalizes output to the string.
1563 auto printer = file->CreatePrinter(&output);
1564 std::map<grpc::string, grpc::string> vars;
1566 vars["filename"] = file->filename();
1567 vars["filename_base"] = file->filename_without_ext();
1568 vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
1569 vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
1571 printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
1572 printer->Print(vars,
1573 "// If you make any local change, they will be lost.\n");
1574 printer->Print(vars, "// source: $filename$\n\n");
1576 printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
1577 printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
1578 printer->Print(vars, "\n");
1583 grpc::string GetSourceIncludes(grpc_generator::File* file,
1584 const Parameters& params) {
1585 grpc::string output;
1587 // Scope the output stream so it closes and finalizes output to the string.
1588 auto printer = file->CreatePrinter(&output);
1589 std::map<grpc::string, grpc::string> vars;
1591 static const char* headers_strs[] = {
1593 "grpcpp/impl/codegen/async_stream.h",
1594 "grpcpp/impl/codegen/async_unary_call.h",
1595 "grpcpp/impl/codegen/channel_interface.h",
1596 "grpcpp/impl/codegen/client_unary_call.h",
1597 "grpcpp/impl/codegen/client_callback.h",
1598 "grpcpp/impl/codegen/method_handler_impl.h",
1599 "grpcpp/impl/codegen/rpc_service_method.h",
1600 "grpcpp/impl/codegen/server_callback.h",
1601 "grpcpp/impl/codegen/service_type.h",
1602 "grpcpp/impl/codegen/sync_stream.h"};
1603 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
1604 PrintIncludes(printer.get(), headers, params.use_system_headers,
1605 params.grpc_search_path);
1607 if (!file->package().empty()) {
1608 std::vector<grpc::string> parts = file->package_parts();
1610 for (auto part = parts.begin(); part != parts.end(); part++) {
1611 vars["part"] = *part;
1612 printer->Print(vars, "namespace $part$ {\n");
1616 printer->Print(vars, "\n");
1621 void PrintSourceClientMethod(grpc_generator::Printer* printer,
1622 const grpc_generator::Method* method,
1623 std::map<grpc::string, grpc::string>* vars) {
1624 (*vars)["Method"] = method->name();
1625 (*vars)["Request"] = method->input_type_name();
1626 (*vars)["Response"] = method->output_type_name();
1628 grpc::string prefix;
1629 grpc::string start; // bool literal expressed as string
1630 grpc::string method_params; // extra arguments to method
1631 grpc::string create_args; // extra arguments to creator
1632 } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
1633 {"PrepareAsync", "false", "", ", nullptr"}};
1634 if (method->NoStreaming()) {
1635 printer->Print(*vars,
1636 "::grpc::Status $ns$$Service$::Stub::$Method$("
1637 "::grpc::ClientContext* context, "
1638 "const $Request$& request, $Response$* response) {\n");
1639 printer->Print(*vars,
1640 " return ::grpc::internal::BlockingUnaryCall"
1641 "(channel_.get(), rpcmethod_$Method$_, "
1642 "context, request, response);\n}\n\n");
1644 printer->Print(*vars,
1645 "void $ns$$Service$::Stub::experimental_async::$Method$("
1646 "::grpc::ClientContext* context, "
1647 "const $Request$* request, $Response$* response, "
1648 "std::function<void(::grpc::Status)> f) {\n");
1649 printer->Print(*vars,
1650 " return ::grpc::internal::CallbackUnaryCall"
1651 "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
1652 "context, request, response, std::move(f));\n}\n\n");
1654 printer->Print(*vars,
1655 "void $ns$$Service$::Stub::experimental_async::$Method$("
1656 "::grpc::ClientContext* context, "
1657 "const ::grpc::ByteBuffer* request, $Response$* response, "
1658 "std::function<void(::grpc::Status)> f) {\n");
1659 printer->Print(*vars,
1660 " return ::grpc::internal::CallbackUnaryCall"
1661 "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
1662 "context, request, response, std::move(f));\n}\n\n");
1664 for (auto async_prefix : async_prefixes) {
1665 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1666 (*vars)["AsyncStart"] = async_prefix.start;
1667 printer->Print(*vars,
1668 "::grpc::ClientAsyncResponseReader< $Response$>* "
1669 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
1670 "ClientContext* context, "
1671 "const $Request$& request, "
1672 "::grpc::CompletionQueue* cq) {\n");
1676 "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
1677 "::Create(channel_.get(), cq, "
1678 "rpcmethod_$Method$_, "
1679 "context, request, $AsyncStart$);\n"
1682 } else if (ClientOnlyStreaming(method)) {
1683 printer->Print(*vars,
1684 "::grpc::ClientWriter< $Request$>* "
1685 "$ns$$Service$::Stub::$Method$Raw("
1686 "::grpc::ClientContext* context, $Response$* response) {\n");
1689 " return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
1691 "rpcmethod_$Method$_, "
1692 "context, response);\n"
1697 "void $ns$$Service$::"
1698 "Stub::experimental_async::$Method$(::grpc::ClientContext* context, "
1699 "$Response$* response, "
1700 "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n");
1701 printer->Print(*vars,
1702 " ::grpc::internal::ClientCallbackWriterFactory< "
1703 "$Request$>::Create("
1704 "stub_->channel_.get(), "
1705 "stub_->rpcmethod_$Method$_, "
1706 "context, response, reactor);\n"
1709 for (auto async_prefix : async_prefixes) {
1710 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1711 (*vars)["AsyncStart"] = async_prefix.start;
1712 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
1713 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
1714 printer->Print(*vars,
1715 "::grpc::ClientAsyncWriter< $Request$>* "
1716 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
1717 "::grpc::ClientContext* context, $Response$* response, "
1718 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
1721 " return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
1722 "::Create(channel_.get(), cq, "
1723 "rpcmethod_$Method$_, "
1724 "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
1727 } else if (ServerOnlyStreaming(method)) {
1730 "::grpc::ClientReader< $Response$>* "
1731 "$ns$$Service$::Stub::$Method$Raw("
1732 "::grpc::ClientContext* context, const $Request$& request) {\n");
1735 " return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
1737 "rpcmethod_$Method$_, "
1738 "context, request);\n"
1743 "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
1744 "ClientContext* context, "
1745 "$Request$* request, "
1746 "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n");
1747 printer->Print(*vars,
1748 " ::grpc::internal::ClientCallbackReaderFactory< "
1749 "$Response$>::Create("
1750 "stub_->channel_.get(), "
1751 "stub_->rpcmethod_$Method$_, "
1752 "context, request, reactor);\n"
1755 for (auto async_prefix : async_prefixes) {
1756 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1757 (*vars)["AsyncStart"] = async_prefix.start;
1758 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
1759 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
1762 "::grpc::ClientAsyncReader< $Response$>* "
1763 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
1764 "::grpc::ClientContext* context, const $Request$& request, "
1765 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
1768 " return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
1769 "::Create(channel_.get(), cq, "
1770 "rpcmethod_$Method$_, "
1771 "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
1774 } else if (method->BidiStreaming()) {
1777 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
1778 "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
1779 printer->Print(*vars,
1780 " return ::grpc::internal::ClientReaderWriterFactory< "
1781 "$Request$, $Response$>::Create("
1783 "rpcmethod_$Method$_, "
1789 "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
1790 "ClientContext* context, "
1791 "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* "
1793 printer->Print(*vars,
1794 " ::grpc::internal::ClientCallbackReaderWriterFactory< "
1795 "$Request$,$Response$>::Create("
1796 "stub_->channel_.get(), "
1797 "stub_->rpcmethod_$Method$_, "
1798 "context, reactor);\n"
1801 for (auto async_prefix : async_prefixes) {
1802 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1803 (*vars)["AsyncStart"] = async_prefix.start;
1804 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
1805 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
1806 printer->Print(*vars,
1807 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
1808 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
1809 "ClientContext* context, "
1810 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
1811 printer->Print(*vars,
1813 "::grpc::internal::ClientAsyncReaderWriterFactory< "
1814 "$Request$, $Response$>::Create("
1815 "channel_.get(), cq, "
1816 "rpcmethod_$Method$_, "
1817 "context, $AsyncStart$$AsyncCreateArgs$);\n"
1823 void PrintSourceServerMethod(grpc_generator::Printer* printer,
1824 const grpc_generator::Method* method,
1825 std::map<grpc::string, grpc::string>* vars) {
1826 (*vars)["Method"] = method->name();
1827 (*vars)["Request"] = method->input_type_name();
1828 (*vars)["Response"] = method->output_type_name();
1829 if (method->NoStreaming()) {
1830 printer->Print(*vars,
1831 "::grpc::Status $ns$$Service$::Service::$Method$("
1832 "::grpc::ServerContext* context, "
1833 "const $Request$* request, $Response$* response) {\n");
1834 printer->Print(" (void) context;\n");
1835 printer->Print(" (void) request;\n");
1836 printer->Print(" (void) response;\n");
1838 " return ::grpc::Status("
1839 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1840 printer->Print("}\n\n");
1841 } else if (ClientOnlyStreaming(method)) {
1842 printer->Print(*vars,
1843 "::grpc::Status $ns$$Service$::Service::$Method$("
1844 "::grpc::ServerContext* context, "
1845 "::grpc::ServerReader< $Request$>* reader, "
1846 "$Response$* response) {\n");
1847 printer->Print(" (void) context;\n");
1848 printer->Print(" (void) reader;\n");
1849 printer->Print(" (void) response;\n");
1851 " return ::grpc::Status("
1852 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1853 printer->Print("}\n\n");
1854 } else if (ServerOnlyStreaming(method)) {
1855 printer->Print(*vars,
1856 "::grpc::Status $ns$$Service$::Service::$Method$("
1857 "::grpc::ServerContext* context, "
1858 "const $Request$* request, "
1859 "::grpc::ServerWriter< $Response$>* writer) {\n");
1860 printer->Print(" (void) context;\n");
1861 printer->Print(" (void) request;\n");
1862 printer->Print(" (void) writer;\n");
1864 " return ::grpc::Status("
1865 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1866 printer->Print("}\n\n");
1867 } else if (method->BidiStreaming()) {
1868 printer->Print(*vars,
1869 "::grpc::Status $ns$$Service$::Service::$Method$("
1870 "::grpc::ServerContext* context, "
1871 "::grpc::ServerReaderWriter< $Response$, $Request$>* "
1873 printer->Print(" (void) context;\n");
1874 printer->Print(" (void) stream;\n");
1876 " return ::grpc::Status("
1877 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1878 printer->Print("}\n\n");
1882 void PrintSourceService(grpc_generator::Printer* printer,
1883 const grpc_generator::Service* service,
1884 std::map<grpc::string, grpc::string>* vars) {
1885 (*vars)["Service"] = service->name();
1887 if (service->method_count() > 0) {
1888 printer->Print(*vars,
1889 "static const char* $prefix$$Service$_method_names[] = {\n");
1890 for (int i = 0; i < service->method_count(); ++i) {
1891 (*vars)["Method"] = service->method(i)->name();
1892 printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
1894 printer->Print(*vars, "};\n\n");
1897 printer->Print(*vars,
1898 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
1899 "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
1900 "const ::grpc::StubOptions& options) {\n"
1902 " std::unique_ptr< $ns$$Service$::Stub> stub(new "
1903 "$ns$$Service$::Stub(channel));\n"
1906 printer->Print(*vars,
1907 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
1908 "::grpc::ChannelInterface>& channel)\n");
1910 printer->Print(": channel_(channel)");
1911 for (int i = 0; i < service->method_count(); ++i) {
1912 auto method = service->method(i);
1913 (*vars)["Method"] = method->name();
1914 (*vars)["Idx"] = as_string(i);
1915 if (method->NoStreaming()) {
1916 (*vars)["StreamingType"] = "NORMAL_RPC";
1917 // NOTE: There is no reason to consider streamed-unary as a separate
1918 // category here since this part is setting up the client-side stub
1919 // and this appears as a NORMAL_RPC from the client-side.
1920 } else if (ClientOnlyStreaming(method.get())) {
1921 (*vars)["StreamingType"] = "CLIENT_STREAMING";
1922 } else if (ServerOnlyStreaming(method.get())) {
1923 (*vars)["StreamingType"] = "SERVER_STREAMING";
1925 (*vars)["StreamingType"] = "BIDI_STREAMING";
1927 printer->Print(*vars,
1928 ", rpcmethod_$Method$_("
1929 "$prefix$$Service$_method_names[$Idx$], "
1930 "::grpc::internal::RpcMethod::$StreamingType$, "
1934 printer->Print("{}\n\n");
1937 for (int i = 0; i < service->method_count(); ++i) {
1938 (*vars)["Idx"] = as_string(i);
1939 PrintSourceClientMethod(printer, service->method(i).get(), vars);
1942 printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
1944 for (int i = 0; i < service->method_count(); ++i) {
1945 auto method = service->method(i);
1946 (*vars)["Idx"] = as_string(i);
1947 (*vars)["Method"] = method->name();
1948 (*vars)["Request"] = method->input_type_name();
1949 (*vars)["Response"] = method->output_type_name();
1950 if (method->NoStreaming()) {
1953 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
1954 " $prefix$$Service$_method_names[$Idx$],\n"
1955 " ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
1956 " new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
1959 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1960 } else if (ClientOnlyStreaming(method.get())) {
1963 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
1964 " $prefix$$Service$_method_names[$Idx$],\n"
1965 " ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
1966 " new ::grpc::internal::ClientStreamingHandler< "
1967 "$ns$$Service$::Service, $Request$, $Response$>(\n"
1968 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1969 } else if (ServerOnlyStreaming(method.get())) {
1972 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
1973 " $prefix$$Service$_method_names[$Idx$],\n"
1974 " ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
1975 " new ::grpc::internal::ServerStreamingHandler< "
1976 "$ns$$Service$::Service, $Request$, $Response$>(\n"
1977 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1978 } else if (method->BidiStreaming()) {
1981 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
1982 " $prefix$$Service$_method_names[$Idx$],\n"
1983 " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
1984 " new ::grpc::internal::BidiStreamingHandler< "
1985 "$ns$$Service$::Service, $Request$, $Response$>(\n"
1986 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1990 printer->Print(*vars, "}\n\n");
1991 printer->Print(*vars,
1992 "$ns$$Service$::Service::~Service() {\n"
1994 for (int i = 0; i < service->method_count(); ++i) {
1995 (*vars)["Idx"] = as_string(i);
1996 PrintSourceServerMethod(printer, service->method(i).get(), vars);
2000 grpc::string GetSourceServices(grpc_generator::File* file,
2001 const Parameters& params) {
2002 grpc::string output;
2004 // Scope the output stream so it closes and finalizes output to the string.
2005 auto printer = file->CreatePrinter(&output);
2006 std::map<grpc::string, grpc::string> vars;
2007 // Package string is empty or ends with a dot. It is used to fully qualify
2009 vars["Package"] = file->package();
2010 if (!file->package().empty()) {
2011 vars["Package"].append(".");
2013 if (!params.services_namespace.empty()) {
2014 vars["ns"] = params.services_namespace + "::";
2015 vars["prefix"] = params.services_namespace;
2018 vars["prefix"] = "";
2021 for (int i = 0; i < file->service_count(); ++i) {
2022 PrintSourceService(printer.get(), file->service(i).get(), &vars);
2023 printer->Print("\n");
2029 grpc::string GetSourceEpilogue(grpc_generator::File* file,
2030 const Parameters& /*params*/) {
2033 if (!file->package().empty()) {
2034 std::vector<grpc::string> parts = file->package_parts();
2036 for (auto part = parts.begin(); part != parts.end(); part++) {
2037 temp.append("} // namespace ");
2047 // TODO(mmukhi): Make sure we need parameters or not.
2048 grpc::string GetMockPrologue(grpc_generator::File* file,
2049 const Parameters& /*params*/) {
2050 grpc::string output;
2052 // Scope the output stream so it closes and finalizes output to the string.
2053 auto printer = file->CreatePrinter(&output);
2054 std::map<grpc::string, grpc::string> vars;
2056 vars["filename"] = file->filename();
2057 vars["filename_base"] = file->filename_without_ext();
2058 vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
2059 vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
2061 printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
2062 printer->Print(vars,
2063 "// If you make any local change, they will be lost.\n");
2064 printer->Print(vars, "// source: $filename$\n\n");
2066 printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
2067 printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
2068 printer->Print(vars, file->additional_headers().c_str());
2069 printer->Print(vars, "\n");
2074 // TODO(mmukhi): Add client-stream and completion-queue headers.
2075 grpc::string GetMockIncludes(grpc_generator::File* file,
2076 const Parameters& params) {
2077 grpc::string output;
2079 // Scope the output stream so it closes and finalizes output to the string.
2080 auto printer = file->CreatePrinter(&output);
2081 std::map<grpc::string, grpc::string> vars;
2083 static const char* headers_strs[] = {
2084 "grpcpp/impl/codegen/async_stream.h",
2085 "grpcpp/impl/codegen/sync_stream.h",
2087 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
2088 PrintIncludes(printer.get(), headers, params.use_system_headers,
2089 params.grpc_search_path);
2091 std::vector<grpc::string> gmock_header;
2092 if (params.gmock_search_path.empty()) {
2093 gmock_header.push_back("gmock/gmock.h");
2094 PrintIncludes(printer.get(), gmock_header, params.use_system_headers,
2095 params.grpc_search_path);
2097 gmock_header.push_back("gmock.h");
2098 // We use local includes when a gmock_search_path is given
2099 PrintIncludes(printer.get(), gmock_header, false,
2100 params.gmock_search_path);
2103 if (!file->package().empty()) {
2104 std::vector<grpc::string> parts = file->package_parts();
2106 for (auto part = parts.begin(); part != parts.end(); part++) {
2107 vars["part"] = *part;
2108 printer->Print(vars, "namespace $part$ {\n");
2112 printer->Print(vars, "\n");
2117 void PrintMockClientMethods(grpc_generator::Printer* printer,
2118 const grpc_generator::Method* method,
2119 std::map<grpc::string, grpc::string>* vars) {
2120 (*vars)["Method"] = method->name();
2121 (*vars)["Request"] = method->input_type_name();
2122 (*vars)["Response"] = method->output_type_name();
2125 grpc::string prefix;
2126 grpc::string method_params; // extra arguments to method
2127 int extra_method_param_count;
2128 } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
2130 if (method->NoStreaming()) {
2133 "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
2134 "const $Request$& request, $Response$* response));\n");
2135 for (auto async_prefix : async_prefixes) {
2136 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2139 "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
2140 "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
2141 "(::grpc::ClientContext* context, const $Request$& request, "
2142 "::grpc::CompletionQueue* cq));\n");
2144 } else if (ClientOnlyStreaming(method)) {
2147 "MOCK_METHOD2($Method$Raw, "
2148 "::grpc::ClientWriterInterface< $Request$>*"
2149 "(::grpc::ClientContext* context, $Response$* response));\n");
2150 for (auto async_prefix : async_prefixes) {
2151 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2152 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2153 (*vars)["MockArgs"] =
2154 std::to_string(3 + async_prefix.extra_method_param_count);
2155 printer->Print(*vars,
2156 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2157 "::grpc::ClientAsyncWriterInterface< $Request$>*"
2158 "(::grpc::ClientContext* context, $Response$* response, "
2159 "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
2161 } else if (ServerOnlyStreaming(method)) {
2164 "MOCK_METHOD2($Method$Raw, "
2165 "::grpc::ClientReaderInterface< $Response$>*"
2166 "(::grpc::ClientContext* context, const $Request$& request));\n");
2167 for (auto async_prefix : async_prefixes) {
2168 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2169 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2170 (*vars)["MockArgs"] =
2171 std::to_string(3 + async_prefix.extra_method_param_count);
2174 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2175 "::grpc::ClientAsyncReaderInterface< $Response$>*"
2176 "(::grpc::ClientContext* context, const $Request$& request, "
2177 "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
2179 } else if (method->BidiStreaming()) {
2182 "MOCK_METHOD1($Method$Raw, "
2183 "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
2184 "(::grpc::ClientContext* context));\n");
2185 for (auto async_prefix : async_prefixes) {
2186 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2187 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2188 (*vars)["MockArgs"] =
2189 std::to_string(2 + async_prefix.extra_method_param_count);
2192 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2193 "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
2194 "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
2195 "$AsyncMethodParams$));\n");
2200 void PrintMockService(grpc_generator::Printer* printer,
2201 const grpc_generator::Service* service,
2202 std::map<grpc::string, grpc::string>* vars) {
2203 (*vars)["Service"] = service->name();
2205 printer->Print(*vars,
2206 "class Mock$Service$Stub : public $Service$::StubInterface {\n"
2209 for (int i = 0; i < service->method_count(); ++i) {
2210 PrintMockClientMethods(printer, service->method(i).get(), vars);
2213 printer->Print("};\n");
2216 grpc::string GetMockServices(grpc_generator::File* file,
2217 const Parameters& params) {
2218 grpc::string output;
2220 // Scope the output stream so it closes and finalizes output to the string.
2221 auto printer = file->CreatePrinter(&output);
2222 std::map<grpc::string, grpc::string> vars;
2223 // Package string is empty or ends with a dot. It is used to fully qualify
2225 vars["Package"] = file->package();
2226 if (!file->package().empty()) {
2227 vars["Package"].append(".");
2230 if (!params.services_namespace.empty()) {
2231 vars["services_namespace"] = params.services_namespace;
2232 printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
2235 for (int i = 0; i < file->service_count(); i++) {
2236 PrintMockService(printer.get(), file->service(i).get(), &vars);
2237 printer->Print("\n");
2240 if (!params.services_namespace.empty()) {
2241 printer->Print(vars, "} // namespace $services_namespace$\n\n");
2247 grpc::string GetMockEpilogue(grpc_generator::File* file,
2248 const Parameters& /*params*/) {
2251 if (!file->package().empty()) {
2252 std::vector<grpc::string> parts = file->package_parts();
2254 for (auto part = parts.begin(); part != parts.end(); part++) {
2255 temp.append("} // namespace ");
2265 } // namespace grpc_cpp_generator