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 } else if (ClientOnlyStreaming(method)) {
584 printer->Print(*vars,
585 "virtual void $Method$(::grpc::ClientContext* context, "
586 "$Response$* response, "
587 "::grpc::experimental::ClientWriteReactor< $Request$>* "
589 } else if (ServerOnlyStreaming(method)) {
590 printer->Print(*vars,
591 "virtual void $Method$(::grpc::ClientContext* context, "
592 "$Request$* request, "
593 "::grpc::experimental::ClientReadReactor< $Response$>* "
595 } else if (method->BidiStreaming()) {
596 printer->Print(*vars,
597 "virtual void $Method$(::grpc::ClientContext* context, "
598 "::grpc::experimental::ClientBidiReactor< "
599 "$Request$,$Response$>* reactor) = 0;\n");
603 void PrintHeaderClientMethodCallbackInterfacesEnd(
604 grpc_generator::Printer* printer,
605 std::map<grpc::string, grpc::string>* vars) {
607 printer->Print("};\n");
609 // Declare a function to give the async stub contents. It can't be pure
610 // since this is a new API in StubInterface, but it is meaningless by default
611 // (since any stub that wants to use it must have its own implementation of
612 // the callback functions therein), so make the default return value nullptr.
613 // Intentionally include the word "class" to avoid possible shadowing.
615 "virtual class experimental_async_interface* experimental_async() { "
616 "return nullptr; }\n");
619 void PrintHeaderClientMethodCallbackStart(
620 grpc_generator::Printer* printer,
621 std::map<grpc::string, grpc::string>* vars) {
622 // This declares the stub entry for the callback-based API.
623 printer->Print("class experimental_async final :\n");
624 printer->Print(" public StubInterface::experimental_async_interface {\n");
625 printer->Print(" public:\n");
629 void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
630 const grpc_generator::Method* method,
631 std::map<grpc::string, grpc::string>* vars,
633 // Reserve is_public for future expansion
636 (*vars)["Method"] = method->name();
637 (*vars)["Request"] = method->input_type_name();
638 (*vars)["Response"] = method->output_type_name();
640 if (method->NoStreaming()) {
641 printer->Print(*vars,
642 "void $Method$(::grpc::ClientContext* context, "
643 "const $Request$* request, $Response$* response, "
644 "std::function<void(::grpc::Status)>) override;\n");
645 } else if (ClientOnlyStreaming(method)) {
646 printer->Print(*vars,
647 "void $Method$(::grpc::ClientContext* context, "
648 "$Response$* response, "
649 "::grpc::experimental::ClientWriteReactor< $Request$>* "
650 "reactor) override;\n");
651 } else if (ServerOnlyStreaming(method)) {
652 printer->Print(*vars,
653 "void $Method$(::grpc::ClientContext* context, "
654 "$Request$* request, "
655 "::grpc::experimental::ClientReadReactor< $Response$>* "
656 "reactor) override;\n");
658 } else if (method->BidiStreaming()) {
659 printer->Print(*vars,
660 "void $Method$(::grpc::ClientContext* context, "
661 "::grpc::experimental::ClientBidiReactor< "
662 "$Request$,$Response$>* reactor) override;\n");
666 void PrintHeaderClientMethodCallbackEnd(
667 grpc_generator::Printer* printer,
668 std::map<grpc::string, grpc::string>* vars) {
670 printer->Print(" private:\n");
672 printer->Print("friend class Stub;\n");
673 printer->Print("explicit experimental_async(Stub* stub): stub_(stub) { }\n");
674 // include a function with a dummy use of stub_ to avoid an unused
675 // private member warning for service with no methods
676 printer->Print("Stub* stub() { return stub_; }\n");
677 printer->Print("Stub* stub_;\n");
679 printer->Print("};\n");
682 "class experimental_async_interface* experimental_async() override { "
683 "return &async_stub_; }\n");
686 void PrintHeaderClientMethodData(grpc_generator::Printer* printer,
687 const grpc_generator::Method* method,
688 std::map<grpc::string, grpc::string>* vars) {
689 (*vars)["Method"] = method->name();
690 printer->Print(*vars,
691 "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
694 void PrintHeaderServerMethodSync(grpc_generator::Printer* printer,
695 const grpc_generator::Method* method,
696 std::map<grpc::string, grpc::string>* vars) {
697 (*vars)["Method"] = method->name();
698 (*vars)["Request"] = method->input_type_name();
699 (*vars)["Response"] = method->output_type_name();
700 printer->Print(method->GetLeadingComments("//").c_str());
701 if (method->NoStreaming()) {
702 printer->Print(*vars,
703 "virtual ::grpc::Status $Method$("
704 "::grpc::ServerContext* context, const $Request$* request, "
705 "$Response$* response);\n");
706 } else if (ClientOnlyStreaming(method)) {
707 printer->Print(*vars,
708 "virtual ::grpc::Status $Method$("
709 "::grpc::ServerContext* context, "
710 "::grpc::ServerReader< $Request$>* reader, "
711 "$Response$* response);\n");
712 } else if (ServerOnlyStreaming(method)) {
713 printer->Print(*vars,
714 "virtual ::grpc::Status $Method$("
715 "::grpc::ServerContext* context, const $Request$* request, "
716 "::grpc::ServerWriter< $Response$>* writer);\n");
717 } else if (method->BidiStreaming()) {
720 "virtual ::grpc::Status $Method$("
721 "::grpc::ServerContext* context, "
722 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
725 printer->Print(method->GetTrailingComments("//").c_str());
728 // Helper generator. Disables the sync API for Request and Response, then adds
729 // in an async API for RealRequest and RealResponse types. This is to be used
730 // to generate async and raw async APIs.
731 void PrintHeaderServerAsyncMethodsHelper(
732 grpc_generator::Printer* printer, const grpc_generator::Method* method,
733 std::map<grpc::string, grpc::string>* vars) {
734 if (method->NoStreaming()) {
737 "// disable synchronous version of this method\n"
738 "::grpc::Status $Method$("
739 "::grpc::ServerContext* context, const $Request$* request, "
740 "$Response$* response) override {\n"
742 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
746 "void Request$Method$("
747 "::grpc::ServerContext* context, $RealRequest$* request, "
748 "::grpc::ServerAsyncResponseWriter< $RealResponse$>* response, "
749 "::grpc::CompletionQueue* new_call_cq, "
750 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
751 printer->Print(*vars,
752 " ::grpc::Service::RequestAsyncUnary($Idx$, context, "
753 "request, response, new_call_cq, notification_cq, tag);\n");
754 printer->Print("}\n");
755 } else if (ClientOnlyStreaming(method)) {
758 "// disable synchronous version of this method\n"
759 "::grpc::Status $Method$("
760 "::grpc::ServerContext* context, "
761 "::grpc::ServerReader< $Request$>* reader, "
762 "$Response$* response) override {\n"
764 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
768 "void Request$Method$("
769 "::grpc::ServerContext* context, "
770 "::grpc::ServerAsyncReader< $RealResponse$, $RealRequest$>* reader, "
771 "::grpc::CompletionQueue* new_call_cq, "
772 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
773 printer->Print(*vars,
774 " ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
775 "context, reader, new_call_cq, notification_cq, tag);\n");
776 printer->Print("}\n");
777 } else if (ServerOnlyStreaming(method)) {
780 "// disable synchronous version of this method\n"
781 "::grpc::Status $Method$("
782 "::grpc::ServerContext* context, const $Request$* request, "
783 "::grpc::ServerWriter< $Response$>* writer) override "
786 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
790 "void Request$Method$("
791 "::grpc::ServerContext* context, $RealRequest$* request, "
792 "::grpc::ServerAsyncWriter< $RealResponse$>* writer, "
793 "::grpc::CompletionQueue* new_call_cq, "
794 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
797 " ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
798 "context, request, writer, new_call_cq, notification_cq, tag);\n");
799 printer->Print("}\n");
800 } else if (method->BidiStreaming()) {
803 "// disable synchronous version of this method\n"
804 "::grpc::Status $Method$("
805 "::grpc::ServerContext* context, "
806 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
809 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
813 "void Request$Method$("
814 "::grpc::ServerContext* context, "
815 "::grpc::ServerAsyncReaderWriter< $RealResponse$, $RealRequest$>* "
817 "::grpc::CompletionQueue* new_call_cq, "
818 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
819 printer->Print(*vars,
820 " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
821 "context, stream, new_call_cq, notification_cq, tag);\n");
822 printer->Print("}\n");
826 void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
827 const grpc_generator::Method* method,
828 std::map<grpc::string, grpc::string>* vars) {
829 (*vars)["Method"] = method->name();
830 // These will be disabled
831 (*vars)["Request"] = method->input_type_name();
832 (*vars)["Response"] = method->output_type_name();
833 // These will be used for the async API
834 (*vars)["RealRequest"] = method->input_type_name();
835 (*vars)["RealResponse"] = method->output_type_name();
836 printer->Print(*vars, "template <class BaseClass>\n");
837 printer->Print(*vars,
838 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
841 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
842 printer->Print(" public:\n");
844 printer->Print(*vars,
845 "WithAsyncMethod_$Method$() {\n"
846 " ::grpc::Service::MarkMethodAsync($Idx$);\n"
848 printer->Print(*vars,
849 "~WithAsyncMethod_$Method$() override {\n"
850 " BaseClassMustBeDerivedFromService(this);\n"
852 PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
854 printer->Print(*vars, "};\n");
857 // Helper generator. Disables the sync API for Request and Response, then adds
858 // in a callback API for RealRequest and RealResponse types. This is to be used
859 // to generate callback and raw callback APIs.
860 void PrintHeaderServerCallbackMethodsHelper(
861 grpc_generator::Printer* printer, const grpc_generator::Method* method,
862 std::map<grpc::string, grpc::string>* vars) {
863 if (method->NoStreaming()) {
866 "// disable synchronous version of this method\n"
867 "::grpc::Status $Method$("
868 "::grpc::ServerContext* context, const $Request$* request, "
869 "$Response$* response) override {\n"
871 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
875 "virtual void $Method$("
876 "::grpc::ServerContext* context, const $RealRequest$* request, "
877 "$RealResponse$* response, "
878 "::grpc::experimental::ServerCallbackRpcController* "
879 "controller) { controller->Finish(::grpc::Status("
880 "::grpc::StatusCode::UNIMPLEMENTED, \"\")); }\n");
881 } else if (ClientOnlyStreaming(method)) {
884 "// disable synchronous version of this method\n"
885 "::grpc::Status $Method$("
886 "::grpc::ServerContext* context, "
887 "::grpc::ServerReader< $Request$>* reader, "
888 "$Response$* response) override {\n"
890 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
892 printer->Print(*vars,
893 "virtual ::grpc::experimental::ServerReadReactor< "
894 "$RealRequest$, $RealResponse$>* $Method$() {\n"
895 " return new ::grpc::internal::UnimplementedReadReactor<\n"
896 " $RealRequest$, $RealResponse$>;}\n");
897 } else if (ServerOnlyStreaming(method)) {
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 "
906 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
908 printer->Print(*vars,
909 "virtual ::grpc::experimental::ServerWriteReactor< "
910 "$RealRequest$, $RealResponse$>* $Method$() {\n"
911 " return new ::grpc::internal::UnimplementedWriteReactor<\n"
912 " $RealRequest$, $RealResponse$>;}\n");
913 } else if (method->BidiStreaming()) {
916 "// disable synchronous version of this method\n"
917 "::grpc::Status $Method$("
918 "::grpc::ServerContext* context, "
919 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
922 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
924 printer->Print(*vars,
925 "virtual ::grpc::experimental::ServerBidiReactor< "
926 "$RealRequest$, $RealResponse$>* $Method$() {\n"
927 " return new ::grpc::internal::UnimplementedBidiReactor<\n"
928 " $RealRequest$, $RealResponse$>;}\n");
932 void PrintHeaderServerMethodCallback(
933 grpc_generator::Printer* printer, const grpc_generator::Method* method,
934 std::map<grpc::string, grpc::string>* vars) {
935 (*vars)["Method"] = method->name();
936 // These will be disabled
937 (*vars)["Request"] = method->input_type_name();
938 (*vars)["Response"] = method->output_type_name();
939 // These will be used for the callback API
940 (*vars)["RealRequest"] = method->input_type_name();
941 (*vars)["RealResponse"] = method->output_type_name();
942 printer->Print(*vars, "template <class BaseClass>\n");
945 "class ExperimentalWithCallbackMethod_$Method$ : public BaseClass {\n");
948 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
949 printer->Print(" public:\n");
951 printer->Print(*vars, "ExperimentalWithCallbackMethod_$Method$() {\n");
952 if (method->NoStreaming()) {
955 " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
956 " new ::grpc::internal::CallbackUnaryHandler< "
957 "$RealRequest$, $RealResponse$>(\n"
958 " [this](::grpc::ServerContext* context,\n"
959 " const $RealRequest$* request,\n"
960 " $RealResponse$* response,\n"
961 " ::grpc::experimental::ServerCallbackRpcController* "
964 "Method$(context, request, response, controller);\n"
966 } else if (ClientOnlyStreaming(method)) {
969 " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
970 " new ::grpc::internal::CallbackClientStreamingHandler< "
971 "$RealRequest$, $RealResponse$>(\n"
972 " [this] { return this->$Method$(); }));\n");
973 } else if (ServerOnlyStreaming(method)) {
976 " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
977 " new ::grpc::internal::CallbackServerStreamingHandler< "
978 "$RealRequest$, $RealResponse$>(\n"
979 " [this] { return this->$Method$(); }));\n");
980 } else if (method->BidiStreaming()) {
983 " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
984 " new ::grpc::internal::CallbackBidiHandler< "
985 "$RealRequest$, $RealResponse$>(\n"
986 " [this] { return this->$Method$(); }));\n");
988 printer->Print(*vars, "}\n");
989 printer->Print(*vars,
990 "~ExperimentalWithCallbackMethod_$Method$() override {\n"
991 " BaseClassMustBeDerivedFromService(this);\n"
993 PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
995 printer->Print(*vars, "};\n");
998 void PrintHeaderServerMethodRawCallback(
999 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1000 std::map<grpc::string, grpc::string>* vars) {
1001 (*vars)["Method"] = method->name();
1002 // These will be disabled
1003 (*vars)["Request"] = method->input_type_name();
1004 (*vars)["Response"] = method->output_type_name();
1005 // These will be used for raw API
1006 (*vars)["RealRequest"] = "::grpc::ByteBuffer";
1007 (*vars)["RealResponse"] = "::grpc::ByteBuffer";
1008 printer->Print(*vars, "template <class BaseClass>\n");
1009 printer->Print(*vars,
1010 "class ExperimentalWithRawCallbackMethod_$Method$ : public "
1014 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1015 printer->Print(" public:\n");
1017 printer->Print(*vars, "ExperimentalWithRawCallbackMethod_$Method$() {\n");
1018 if (method->NoStreaming()) {
1021 " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1022 " new ::grpc::internal::CallbackUnaryHandler< "
1023 "$RealRequest$, $RealResponse$>(\n"
1024 " [this](::grpc::ServerContext* context,\n"
1025 " const $RealRequest$* request,\n"
1026 " $RealResponse$* response,\n"
1027 " ::grpc::experimental::ServerCallbackRpcController* "
1030 "Method$(context, request, response, controller);\n"
1032 } else if (ClientOnlyStreaming(method)) {
1035 " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1036 " new ::grpc::internal::CallbackClientStreamingHandler< "
1037 "$RealRequest$, $RealResponse$>(\n"
1038 " [this] { return this->$Method$(); }));\n");
1039 } else if (ServerOnlyStreaming(method)) {
1042 " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1043 " new ::grpc::internal::CallbackServerStreamingHandler< "
1044 "$RealRequest$, $RealResponse$>(\n"
1045 " [this] { return this->$Method$(); }));\n");
1046 } else if (method->BidiStreaming()) {
1049 " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1050 " new ::grpc::internal::CallbackBidiHandler< "
1051 "$RealRequest$, $RealResponse$>(\n"
1052 " [this] { return this->$Method$(); }));\n");
1054 printer->Print(*vars, "}\n");
1055 printer->Print(*vars,
1056 "~ExperimentalWithRawCallbackMethod_$Method$() override {\n"
1057 " BaseClassMustBeDerivedFromService(this);\n"
1059 PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
1061 printer->Print(*vars, "};\n");
1064 void PrintHeaderServerMethodStreamedUnary(
1065 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1066 std::map<grpc::string, grpc::string>* vars) {
1067 (*vars)["Method"] = method->name();
1068 (*vars)["Request"] = method->input_type_name();
1069 (*vars)["Response"] = method->output_type_name();
1070 if (method->NoStreaming()) {
1071 printer->Print(*vars, "template <class BaseClass>\n");
1072 printer->Print(*vars,
1073 "class WithStreamedUnaryMethod_$Method$ : "
1074 "public BaseClass {\n");
1077 " void BaseClassMustBeDerivedFromService(const Service *service) "
1079 printer->Print(" public:\n");
1081 printer->Print(*vars,
1082 "WithStreamedUnaryMethod_$Method$() {\n"
1083 " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
1084 " new ::grpc::internal::StreamedUnaryHandler< $Request$, "
1085 "$Response$>(std::bind"
1086 "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
1087 "Streamed$Method$, this, std::placeholders::_1, "
1088 "std::placeholders::_2)));\n"
1090 printer->Print(*vars,
1091 "~WithStreamedUnaryMethod_$Method$() override {\n"
1092 " BaseClassMustBeDerivedFromService(this);\n"
1096 "// disable regular version of this method\n"
1097 "::grpc::Status $Method$("
1098 "::grpc::ServerContext* context, const $Request$* request, "
1099 "$Response$* response) override {\n"
1101 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1103 printer->Print(*vars,
1104 "// replace default version of method with streamed unary\n"
1105 "virtual ::grpc::Status Streamed$Method$("
1106 "::grpc::ServerContext* context, "
1107 "::grpc::ServerUnaryStreamer< "
1108 "$Request$,$Response$>* server_unary_streamer)"
1111 printer->Print(*vars, "};\n");
1115 void PrintHeaderServerMethodSplitStreaming(
1116 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1117 std::map<grpc::string, grpc::string>* vars) {
1118 (*vars)["Method"] = method->name();
1119 (*vars)["Request"] = method->input_type_name();
1120 (*vars)["Response"] = method->output_type_name();
1121 if (ServerOnlyStreaming(method)) {
1122 printer->Print(*vars, "template <class BaseClass>\n");
1123 printer->Print(*vars,
1124 "class WithSplitStreamingMethod_$Method$ : "
1125 "public BaseClass {\n");
1128 " void BaseClassMustBeDerivedFromService(const Service *service) "
1130 printer->Print(" public:\n");
1134 "WithSplitStreamingMethod_$Method$() {\n"
1135 " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
1136 " new ::grpc::internal::SplitServerStreamingHandler< $Request$, "
1137 "$Response$>(std::bind"
1138 "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
1139 "Streamed$Method$, this, std::placeholders::_1, "
1140 "std::placeholders::_2)));\n"
1142 printer->Print(*vars,
1143 "~WithSplitStreamingMethod_$Method$() override {\n"
1144 " BaseClassMustBeDerivedFromService(this);\n"
1148 "// disable regular version of this method\n"
1149 "::grpc::Status $Method$("
1150 "::grpc::ServerContext* context, const $Request$* request, "
1151 "::grpc::ServerWriter< $Response$>* writer) override "
1154 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1156 printer->Print(*vars,
1157 "// replace default version of method with split streamed\n"
1158 "virtual ::grpc::Status Streamed$Method$("
1159 "::grpc::ServerContext* context, "
1160 "::grpc::ServerSplitStreamer< "
1161 "$Request$,$Response$>* server_split_streamer)"
1164 printer->Print(*vars, "};\n");
1168 void PrintHeaderServerMethodGeneric(
1169 grpc_generator::Printer* printer, const grpc_generator::Method* method,
1170 std::map<grpc::string, grpc::string>* vars) {
1171 (*vars)["Method"] = method->name();
1172 (*vars)["Request"] = method->input_type_name();
1173 (*vars)["Response"] = method->output_type_name();
1174 printer->Print(*vars, "template <class BaseClass>\n");
1175 printer->Print(*vars,
1176 "class WithGenericMethod_$Method$ : public BaseClass {\n");
1179 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1180 printer->Print(" public:\n");
1182 printer->Print(*vars,
1183 "WithGenericMethod_$Method$() {\n"
1184 " ::grpc::Service::MarkMethodGeneric($Idx$);\n"
1186 printer->Print(*vars,
1187 "~WithGenericMethod_$Method$() override {\n"
1188 " BaseClassMustBeDerivedFromService(this);\n"
1190 if (method->NoStreaming()) {
1193 "// disable synchronous version of this method\n"
1194 "::grpc::Status $Method$("
1195 "::grpc::ServerContext* context, const $Request$* request, "
1196 "$Response$* response) override {\n"
1198 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1200 } else if (ClientOnlyStreaming(method)) {
1203 "// disable synchronous version of this method\n"
1204 "::grpc::Status $Method$("
1205 "::grpc::ServerContext* context, "
1206 "::grpc::ServerReader< $Request$>* reader, "
1207 "$Response$* response) override {\n"
1209 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1211 } else if (ServerOnlyStreaming(method)) {
1214 "// disable synchronous version of this method\n"
1215 "::grpc::Status $Method$("
1216 "::grpc::ServerContext* context, const $Request$* request, "
1217 "::grpc::ServerWriter< $Response$>* writer) override "
1220 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1222 } else if (method->BidiStreaming()) {
1225 "// disable synchronous version of this method\n"
1226 "::grpc::Status $Method$("
1227 "::grpc::ServerContext* context, "
1228 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
1231 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1235 printer->Print(*vars, "};\n");
1238 void PrintHeaderServerMethodRaw(grpc_generator::Printer* printer,
1239 const grpc_generator::Method* method,
1240 std::map<grpc::string, grpc::string>* vars) {
1241 (*vars)["Method"] = method->name();
1242 // These will be disabled
1243 (*vars)["Request"] = method->input_type_name();
1244 (*vars)["Response"] = method->output_type_name();
1245 // These will be used for raw API
1246 (*vars)["RealRequest"] = "::grpc::ByteBuffer";
1247 (*vars)["RealResponse"] = "::grpc::ByteBuffer";
1248 printer->Print(*vars, "template <class BaseClass>\n");
1249 printer->Print(*vars, "class WithRawMethod_$Method$ : public BaseClass {\n");
1252 " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1253 printer->Print(" public:\n");
1255 printer->Print(*vars,
1256 "WithRawMethod_$Method$() {\n"
1257 " ::grpc::Service::MarkMethodRaw($Idx$);\n"
1259 printer->Print(*vars,
1260 "~WithRawMethod_$Method$() override {\n"
1261 " BaseClassMustBeDerivedFromService(this);\n"
1263 PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
1265 printer->Print(*vars, "};\n");
1268 void PrintHeaderService(grpc_generator::Printer* printer,
1269 const grpc_generator::Service* service,
1270 std::map<grpc::string, grpc::string>* vars) {
1271 (*vars)["Service"] = service->name();
1273 printer->Print(service->GetLeadingComments("//").c_str());
1274 printer->Print(*vars,
1275 "class $Service$ final {\n"
1280 printer->Print(*vars,
1281 "static constexpr char const* service_full_name() {\n"
1282 " return \"$Package$$Service$\";\n"
1287 "class StubInterface {\n"
1290 printer->Print("virtual ~StubInterface() {}\n");
1291 for (int i = 0; i < service->method_count(); ++i) {
1292 printer->Print(service->method(i)->GetLeadingComments("//").c_str());
1293 PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
1295 printer->Print(service->method(i)->GetTrailingComments("//").c_str());
1297 PrintHeaderClientMethodCallbackInterfacesStart(printer, vars);
1298 for (int i = 0; i < service->method_count(); ++i) {
1299 printer->Print(service->method(i)->GetLeadingComments("//").c_str());
1300 PrintHeaderClientMethodCallbackInterfaces(printer, service->method(i).get(),
1302 printer->Print(service->method(i)->GetTrailingComments("//").c_str());
1304 PrintHeaderClientMethodCallbackInterfacesEnd(printer, vars);
1306 printer->Print("private:\n");
1308 for (int i = 0; i < service->method_count(); ++i) {
1309 PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
1313 printer->Print("};\n");
1315 "class Stub final : public StubInterface"
1319 "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
1321 for (int i = 0; i < service->method_count(); ++i) {
1322 PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
1324 PrintHeaderClientMethodCallbackStart(printer, vars);
1325 for (int i = 0; i < service->method_count(); ++i) {
1326 PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars,
1329 PrintHeaderClientMethodCallbackEnd(printer, vars);
1331 printer->Print("\n private:\n");
1333 printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
1334 printer->Print("class experimental_async async_stub_{this};\n");
1335 for (int i = 0; i < service->method_count(); ++i) {
1336 PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
1338 for (int i = 0; i < service->method_count(); ++i) {
1339 PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
1342 printer->Print("};\n");
1344 "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
1345 "::grpc::ChannelInterface>& channel, "
1346 "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
1348 printer->Print("\n");
1350 // Server side - base
1352 "class Service : public ::grpc::Service {\n"
1355 printer->Print("Service();\n");
1356 printer->Print("virtual ~Service();\n");
1357 for (int i = 0; i < service->method_count(); ++i) {
1358 PrintHeaderServerMethodSync(printer, service->method(i).get(), vars);
1361 printer->Print("};\n");
1363 // Server side - Asynchronous
1364 for (int i = 0; i < service->method_count(); ++i) {
1365 (*vars)["Idx"] = as_string(i);
1366 PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars);
1369 printer->Print("typedef ");
1371 for (int i = 0; i < service->method_count(); ++i) {
1372 (*vars)["method_name"] = service->method(i)->name();
1373 printer->Print(*vars, "WithAsyncMethod_$method_name$<");
1375 printer->Print("Service");
1376 for (int i = 0; i < service->method_count(); ++i) {
1377 printer->Print(" >");
1379 printer->Print(" AsyncService;\n");
1381 // Server side - Callback
1382 for (int i = 0; i < service->method_count(); ++i) {
1383 (*vars)["Idx"] = as_string(i);
1384 PrintHeaderServerMethodCallback(printer, service->method(i).get(), vars);
1387 printer->Print("typedef ");
1389 for (int i = 0; i < service->method_count(); ++i) {
1390 (*vars)["method_name"] = service->method(i)->name();
1391 printer->Print(*vars, "ExperimentalWithCallbackMethod_$method_name$<");
1393 printer->Print("Service");
1394 for (int i = 0; i < service->method_count(); ++i) {
1395 printer->Print(" >");
1397 printer->Print(" ExperimentalCallbackService;\n");
1399 // Server side - Generic
1400 for (int i = 0; i < service->method_count(); ++i) {
1401 (*vars)["Idx"] = as_string(i);
1402 PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
1405 // Server side - Raw
1406 for (int i = 0; i < service->method_count(); ++i) {
1407 (*vars)["Idx"] = as_string(i);
1408 PrintHeaderServerMethodRaw(printer, service->method(i).get(), vars);
1411 // Server side - Raw Callback
1412 for (int i = 0; i < service->method_count(); ++i) {
1413 (*vars)["Idx"] = as_string(i);
1414 PrintHeaderServerMethodRawCallback(printer, service->method(i).get(), vars);
1417 // Server side - Streamed Unary
1418 for (int i = 0; i < service->method_count(); ++i) {
1419 (*vars)["Idx"] = as_string(i);
1420 PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
1424 printer->Print("typedef ");
1425 for (int i = 0; i < service->method_count(); ++i) {
1426 (*vars)["method_name"] = service->method(i)->name();
1427 if (service->method(i)->NoStreaming()) {
1428 printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
1431 printer->Print("Service");
1432 for (int i = 0; i < service->method_count(); ++i) {
1433 if (service->method(i)->NoStreaming()) {
1434 printer->Print(" >");
1437 printer->Print(" StreamedUnaryService;\n");
1439 // Server side - controlled server-side streaming
1440 for (int i = 0; i < service->method_count(); ++i) {
1441 (*vars)["Idx"] = as_string(i);
1442 PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(),
1446 printer->Print("typedef ");
1447 for (int i = 0; i < service->method_count(); ++i) {
1448 (*vars)["method_name"] = service->method(i)->name();
1449 auto method = service->method(i);
1450 if (ServerOnlyStreaming(method.get())) {
1451 printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
1454 printer->Print("Service");
1455 for (int i = 0; i < service->method_count(); ++i) {
1456 auto method = service->method(i);
1457 if (ServerOnlyStreaming(method.get())) {
1458 printer->Print(" >");
1461 printer->Print(" SplitStreamedService;\n");
1463 // Server side - typedef for controlled both unary and server-side streaming
1464 printer->Print("typedef ");
1465 for (int i = 0; i < service->method_count(); ++i) {
1466 (*vars)["method_name"] = service->method(i)->name();
1467 auto method = service->method(i);
1468 if (ServerOnlyStreaming(method.get())) {
1469 printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
1471 if (service->method(i)->NoStreaming()) {
1472 printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
1475 printer->Print("Service");
1476 for (int i = 0; i < service->method_count(); ++i) {
1477 auto method = service->method(i);
1478 if (service->method(i)->NoStreaming() ||
1479 ServerOnlyStreaming(method.get())) {
1480 printer->Print(" >");
1483 printer->Print(" StreamedService;\n");
1486 printer->Print("};\n");
1487 printer->Print(service->GetTrailingComments("//").c_str());
1490 grpc::string GetHeaderServices(grpc_generator::File* file,
1491 const Parameters& params) {
1492 grpc::string output;
1494 // Scope the output stream so it closes and finalizes output to the string.
1495 auto printer = file->CreatePrinter(&output);
1496 std::map<grpc::string, grpc::string> vars;
1497 // Package string is empty or ends with a dot. It is used to fully qualify
1499 vars["Package"] = file->package();
1500 if (!file->package().empty()) {
1501 vars["Package"].append(".");
1504 if (!params.services_namespace.empty()) {
1505 vars["services_namespace"] = params.services_namespace;
1506 printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
1509 for (int i = 0; i < file->service_count(); ++i) {
1510 PrintHeaderService(printer.get(), file->service(i).get(), &vars);
1511 printer->Print("\n");
1514 if (!params.services_namespace.empty()) {
1515 printer->Print(vars, "} // namespace $services_namespace$\n\n");
1521 grpc::string GetHeaderEpilogue(grpc_generator::File* file,
1522 const Parameters& /*params*/) {
1523 grpc::string output;
1525 // Scope the output stream so it closes and finalizes output to the string.
1526 auto printer = file->CreatePrinter(&output);
1527 std::map<grpc::string, grpc::string> vars;
1529 vars["filename"] = file->filename();
1530 vars["filename_identifier"] = FilenameIdentifier(file->filename());
1532 if (!file->package().empty()) {
1533 std::vector<grpc::string> parts = file->package_parts();
1535 for (auto part = parts.rbegin(); part != parts.rend(); part++) {
1536 vars["part"] = *part;
1537 printer->Print(vars, "} // namespace $part$\n");
1539 printer->Print(vars, "\n");
1542 printer->Print(vars, "\n");
1543 printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
1545 printer->Print(file->GetTrailingComments("//").c_str());
1550 grpc::string GetSourcePrologue(grpc_generator::File* file,
1551 const Parameters& /*params*/) {
1552 grpc::string output;
1554 // Scope the output stream so it closes and finalizes output to the string.
1555 auto printer = file->CreatePrinter(&output);
1556 std::map<grpc::string, grpc::string> vars;
1558 vars["filename"] = file->filename();
1559 vars["filename_base"] = file->filename_without_ext();
1560 vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
1561 vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
1563 printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
1564 printer->Print(vars,
1565 "// If you make any local change, they will be lost.\n");
1566 printer->Print(vars, "// source: $filename$\n\n");
1568 printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
1569 printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
1570 printer->Print(vars, "\n");
1575 grpc::string GetSourceIncludes(grpc_generator::File* file,
1576 const Parameters& params) {
1577 grpc::string output;
1579 // Scope the output stream so it closes and finalizes output to the string.
1580 auto printer = file->CreatePrinter(&output);
1581 std::map<grpc::string, grpc::string> vars;
1583 static const char* headers_strs[] = {
1585 "grpcpp/impl/codegen/async_stream.h",
1586 "grpcpp/impl/codegen/async_unary_call.h",
1587 "grpcpp/impl/codegen/channel_interface.h",
1588 "grpcpp/impl/codegen/client_unary_call.h",
1589 "grpcpp/impl/codegen/client_callback.h",
1590 "grpcpp/impl/codegen/method_handler_impl.h",
1591 "grpcpp/impl/codegen/rpc_service_method.h",
1592 "grpcpp/impl/codegen/server_callback.h",
1593 "grpcpp/impl/codegen/service_type.h",
1594 "grpcpp/impl/codegen/sync_stream.h"};
1595 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
1596 PrintIncludes(printer.get(), headers, params.use_system_headers,
1597 params.grpc_search_path);
1599 if (!file->package().empty()) {
1600 std::vector<grpc::string> parts = file->package_parts();
1602 for (auto part = parts.begin(); part != parts.end(); part++) {
1603 vars["part"] = *part;
1604 printer->Print(vars, "namespace $part$ {\n");
1608 printer->Print(vars, "\n");
1613 void PrintSourceClientMethod(grpc_generator::Printer* printer,
1614 const grpc_generator::Method* method,
1615 std::map<grpc::string, grpc::string>* vars) {
1616 (*vars)["Method"] = method->name();
1617 (*vars)["Request"] = method->input_type_name();
1618 (*vars)["Response"] = method->output_type_name();
1620 grpc::string prefix;
1621 grpc::string start; // bool literal expressed as string
1622 grpc::string method_params; // extra arguments to method
1623 grpc::string create_args; // extra arguments to creator
1624 } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
1625 {"PrepareAsync", "false", "", ", nullptr"}};
1626 if (method->NoStreaming()) {
1627 printer->Print(*vars,
1628 "::grpc::Status $ns$$Service$::Stub::$Method$("
1629 "::grpc::ClientContext* context, "
1630 "const $Request$& request, $Response$* response) {\n");
1631 printer->Print(*vars,
1632 " return ::grpc::internal::BlockingUnaryCall"
1633 "(channel_.get(), rpcmethod_$Method$_, "
1634 "context, request, response);\n}\n\n");
1636 printer->Print(*vars,
1637 "void $ns$$Service$::Stub::experimental_async::$Method$("
1638 "::grpc::ClientContext* context, "
1639 "const $Request$* request, $Response$* response, "
1640 "std::function<void(::grpc::Status)> f) {\n");
1641 printer->Print(*vars,
1642 " return ::grpc::internal::CallbackUnaryCall"
1643 "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
1644 "context, request, response, std::move(f));\n}\n\n");
1646 for (auto async_prefix : async_prefixes) {
1647 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1648 (*vars)["AsyncStart"] = async_prefix.start;
1649 printer->Print(*vars,
1650 "::grpc::ClientAsyncResponseReader< $Response$>* "
1651 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
1652 "ClientContext* context, "
1653 "const $Request$& request, "
1654 "::grpc::CompletionQueue* cq) {\n");
1658 "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
1659 "::Create(channel_.get(), cq, "
1660 "rpcmethod_$Method$_, "
1661 "context, request, $AsyncStart$);\n"
1664 } else if (ClientOnlyStreaming(method)) {
1665 printer->Print(*vars,
1666 "::grpc::ClientWriter< $Request$>* "
1667 "$ns$$Service$::Stub::$Method$Raw("
1668 "::grpc::ClientContext* context, $Response$* response) {\n");
1671 " return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
1673 "rpcmethod_$Method$_, "
1674 "context, response);\n"
1679 "void $ns$$Service$::"
1680 "Stub::experimental_async::$Method$(::grpc::ClientContext* context, "
1681 "$Response$* response, "
1682 "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n");
1683 printer->Print(*vars,
1684 " ::grpc::internal::ClientCallbackWriterFactory< "
1685 "$Request$>::Create("
1686 "stub_->channel_.get(), "
1687 "stub_->rpcmethod_$Method$_, "
1688 "context, response, reactor);\n"
1691 for (auto async_prefix : async_prefixes) {
1692 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1693 (*vars)["AsyncStart"] = async_prefix.start;
1694 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
1695 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
1696 printer->Print(*vars,
1697 "::grpc::ClientAsyncWriter< $Request$>* "
1698 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
1699 "::grpc::ClientContext* context, $Response$* response, "
1700 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
1703 " return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
1704 "::Create(channel_.get(), cq, "
1705 "rpcmethod_$Method$_, "
1706 "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
1709 } else if (ServerOnlyStreaming(method)) {
1712 "::grpc::ClientReader< $Response$>* "
1713 "$ns$$Service$::Stub::$Method$Raw("
1714 "::grpc::ClientContext* context, const $Request$& request) {\n");
1717 " return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
1719 "rpcmethod_$Method$_, "
1720 "context, request);\n"
1725 "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
1726 "ClientContext* context, "
1727 "$Request$* request, "
1728 "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n");
1729 printer->Print(*vars,
1730 " ::grpc::internal::ClientCallbackReaderFactory< "
1731 "$Response$>::Create("
1732 "stub_->channel_.get(), "
1733 "stub_->rpcmethod_$Method$_, "
1734 "context, request, reactor);\n"
1737 for (auto async_prefix : async_prefixes) {
1738 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1739 (*vars)["AsyncStart"] = async_prefix.start;
1740 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
1741 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
1744 "::grpc::ClientAsyncReader< $Response$>* "
1745 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
1746 "::grpc::ClientContext* context, const $Request$& request, "
1747 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
1750 " return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
1751 "::Create(channel_.get(), cq, "
1752 "rpcmethod_$Method$_, "
1753 "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
1756 } else if (method->BidiStreaming()) {
1759 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
1760 "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
1761 printer->Print(*vars,
1762 " return ::grpc::internal::ClientReaderWriterFactory< "
1763 "$Request$, $Response$>::Create("
1765 "rpcmethod_$Method$_, "
1771 "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
1772 "ClientContext* context, "
1773 "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* "
1775 printer->Print(*vars,
1776 " ::grpc::internal::ClientCallbackReaderWriterFactory< "
1777 "$Request$,$Response$>::Create("
1778 "stub_->channel_.get(), "
1779 "stub_->rpcmethod_$Method$_, "
1780 "context, reactor);\n"
1783 for (auto async_prefix : async_prefixes) {
1784 (*vars)["AsyncPrefix"] = async_prefix.prefix;
1785 (*vars)["AsyncStart"] = async_prefix.start;
1786 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
1787 (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
1788 printer->Print(*vars,
1789 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
1790 "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
1791 "ClientContext* context, "
1792 "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
1793 printer->Print(*vars,
1795 "::grpc::internal::ClientAsyncReaderWriterFactory< "
1796 "$Request$, $Response$>::Create("
1797 "channel_.get(), cq, "
1798 "rpcmethod_$Method$_, "
1799 "context, $AsyncStart$$AsyncCreateArgs$);\n"
1805 void PrintSourceServerMethod(grpc_generator::Printer* printer,
1806 const grpc_generator::Method* method,
1807 std::map<grpc::string, grpc::string>* vars) {
1808 (*vars)["Method"] = method->name();
1809 (*vars)["Request"] = method->input_type_name();
1810 (*vars)["Response"] = method->output_type_name();
1811 if (method->NoStreaming()) {
1812 printer->Print(*vars,
1813 "::grpc::Status $ns$$Service$::Service::$Method$("
1814 "::grpc::ServerContext* context, "
1815 "const $Request$* request, $Response$* response) {\n");
1816 printer->Print(" (void) context;\n");
1817 printer->Print(" (void) request;\n");
1818 printer->Print(" (void) response;\n");
1820 " return ::grpc::Status("
1821 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1822 printer->Print("}\n\n");
1823 } else if (ClientOnlyStreaming(method)) {
1824 printer->Print(*vars,
1825 "::grpc::Status $ns$$Service$::Service::$Method$("
1826 "::grpc::ServerContext* context, "
1827 "::grpc::ServerReader< $Request$>* reader, "
1828 "$Response$* response) {\n");
1829 printer->Print(" (void) context;\n");
1830 printer->Print(" (void) reader;\n");
1831 printer->Print(" (void) response;\n");
1833 " return ::grpc::Status("
1834 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1835 printer->Print("}\n\n");
1836 } else if (ServerOnlyStreaming(method)) {
1837 printer->Print(*vars,
1838 "::grpc::Status $ns$$Service$::Service::$Method$("
1839 "::grpc::ServerContext* context, "
1840 "const $Request$* request, "
1841 "::grpc::ServerWriter< $Response$>* writer) {\n");
1842 printer->Print(" (void) context;\n");
1843 printer->Print(" (void) request;\n");
1844 printer->Print(" (void) writer;\n");
1846 " return ::grpc::Status("
1847 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1848 printer->Print("}\n\n");
1849 } else if (method->BidiStreaming()) {
1850 printer->Print(*vars,
1851 "::grpc::Status $ns$$Service$::Service::$Method$("
1852 "::grpc::ServerContext* context, "
1853 "::grpc::ServerReaderWriter< $Response$, $Request$>* "
1855 printer->Print(" (void) context;\n");
1856 printer->Print(" (void) stream;\n");
1858 " return ::grpc::Status("
1859 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1860 printer->Print("}\n\n");
1864 void PrintSourceService(grpc_generator::Printer* printer,
1865 const grpc_generator::Service* service,
1866 std::map<grpc::string, grpc::string>* vars) {
1867 (*vars)["Service"] = service->name();
1869 if (service->method_count() > 0) {
1870 printer->Print(*vars,
1871 "static const char* $prefix$$Service$_method_names[] = {\n");
1872 for (int i = 0; i < service->method_count(); ++i) {
1873 (*vars)["Method"] = service->method(i)->name();
1874 printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
1876 printer->Print(*vars, "};\n\n");
1879 printer->Print(*vars,
1880 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
1881 "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
1882 "const ::grpc::StubOptions& options) {\n"
1884 " std::unique_ptr< $ns$$Service$::Stub> stub(new "
1885 "$ns$$Service$::Stub(channel));\n"
1888 printer->Print(*vars,
1889 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
1890 "::grpc::ChannelInterface>& channel)\n");
1892 printer->Print(": channel_(channel)");
1893 for (int i = 0; i < service->method_count(); ++i) {
1894 auto method = service->method(i);
1895 (*vars)["Method"] = method->name();
1896 (*vars)["Idx"] = as_string(i);
1897 if (method->NoStreaming()) {
1898 (*vars)["StreamingType"] = "NORMAL_RPC";
1899 // NOTE: There is no reason to consider streamed-unary as a separate
1900 // category here since this part is setting up the client-side stub
1901 // and this appears as a NORMAL_RPC from the client-side.
1902 } else if (ClientOnlyStreaming(method.get())) {
1903 (*vars)["StreamingType"] = "CLIENT_STREAMING";
1904 } else if (ServerOnlyStreaming(method.get())) {
1905 (*vars)["StreamingType"] = "SERVER_STREAMING";
1907 (*vars)["StreamingType"] = "BIDI_STREAMING";
1909 printer->Print(*vars,
1910 ", rpcmethod_$Method$_("
1911 "$prefix$$Service$_method_names[$Idx$], "
1912 "::grpc::internal::RpcMethod::$StreamingType$, "
1916 printer->Print("{}\n\n");
1919 for (int i = 0; i < service->method_count(); ++i) {
1920 (*vars)["Idx"] = as_string(i);
1921 PrintSourceClientMethod(printer, service->method(i).get(), vars);
1924 printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
1926 for (int i = 0; i < service->method_count(); ++i) {
1927 auto method = service->method(i);
1928 (*vars)["Idx"] = as_string(i);
1929 (*vars)["Method"] = method->name();
1930 (*vars)["Request"] = method->input_type_name();
1931 (*vars)["Response"] = method->output_type_name();
1932 if (method->NoStreaming()) {
1935 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
1936 " $prefix$$Service$_method_names[$Idx$],\n"
1937 " ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
1938 " new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
1941 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1942 } else if (ClientOnlyStreaming(method.get())) {
1945 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
1946 " $prefix$$Service$_method_names[$Idx$],\n"
1947 " ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
1948 " new ::grpc::internal::ClientStreamingHandler< "
1949 "$ns$$Service$::Service, $Request$, $Response$>(\n"
1950 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1951 } else if (ServerOnlyStreaming(method.get())) {
1954 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
1955 " $prefix$$Service$_method_names[$Idx$],\n"
1956 " ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
1957 " new ::grpc::internal::ServerStreamingHandler< "
1958 "$ns$$Service$::Service, $Request$, $Response$>(\n"
1959 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1960 } else if (method->BidiStreaming()) {
1963 "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
1964 " $prefix$$Service$_method_names[$Idx$],\n"
1965 " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
1966 " new ::grpc::internal::BidiStreamingHandler< "
1967 "$ns$$Service$::Service, $Request$, $Response$>(\n"
1968 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1972 printer->Print(*vars, "}\n\n");
1973 printer->Print(*vars,
1974 "$ns$$Service$::Service::~Service() {\n"
1976 for (int i = 0; i < service->method_count(); ++i) {
1977 (*vars)["Idx"] = as_string(i);
1978 PrintSourceServerMethod(printer, service->method(i).get(), vars);
1982 grpc::string GetSourceServices(grpc_generator::File* file,
1983 const Parameters& params) {
1984 grpc::string output;
1986 // Scope the output stream so it closes and finalizes output to the string.
1987 auto printer = file->CreatePrinter(&output);
1988 std::map<grpc::string, grpc::string> vars;
1989 // Package string is empty or ends with a dot. It is used to fully qualify
1991 vars["Package"] = file->package();
1992 if (!file->package().empty()) {
1993 vars["Package"].append(".");
1995 if (!params.services_namespace.empty()) {
1996 vars["ns"] = params.services_namespace + "::";
1997 vars["prefix"] = params.services_namespace;
2000 vars["prefix"] = "";
2003 for (int i = 0; i < file->service_count(); ++i) {
2004 PrintSourceService(printer.get(), file->service(i).get(), &vars);
2005 printer->Print("\n");
2011 grpc::string GetSourceEpilogue(grpc_generator::File* file,
2012 const Parameters& /*params*/) {
2015 if (!file->package().empty()) {
2016 std::vector<grpc::string> parts = file->package_parts();
2018 for (auto part = parts.begin(); part != parts.end(); part++) {
2019 temp.append("} // namespace ");
2029 // TODO(mmukhi): Make sure we need parameters or not.
2030 grpc::string GetMockPrologue(grpc_generator::File* file,
2031 const Parameters& /*params*/) {
2032 grpc::string output;
2034 // Scope the output stream so it closes and finalizes output to the string.
2035 auto printer = file->CreatePrinter(&output);
2036 std::map<grpc::string, grpc::string> vars;
2038 vars["filename"] = file->filename();
2039 vars["filename_base"] = file->filename_without_ext();
2040 vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
2041 vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
2043 printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
2044 printer->Print(vars,
2045 "// If you make any local change, they will be lost.\n");
2046 printer->Print(vars, "// source: $filename$\n\n");
2048 printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
2049 printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
2050 printer->Print(vars, file->additional_headers().c_str());
2051 printer->Print(vars, "\n");
2056 // TODO(mmukhi): Add client-stream and completion-queue headers.
2057 grpc::string GetMockIncludes(grpc_generator::File* file,
2058 const Parameters& params) {
2059 grpc::string output;
2061 // Scope the output stream so it closes and finalizes output to the string.
2062 auto printer = file->CreatePrinter(&output);
2063 std::map<grpc::string, grpc::string> vars;
2065 static const char* headers_strs[] = {
2066 "grpcpp/impl/codegen/async_stream.h",
2067 "grpcpp/impl/codegen/sync_stream.h",
2069 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
2070 PrintIncludes(printer.get(), headers, params.use_system_headers,
2071 params.grpc_search_path);
2073 std::vector<grpc::string> gmock_header;
2074 if (params.gmock_search_path.empty()) {
2075 gmock_header.push_back("gmock/gmock.h");
2076 PrintIncludes(printer.get(), gmock_header, params.use_system_headers,
2077 params.grpc_search_path);
2079 gmock_header.push_back("gmock.h");
2080 // We use local includes when a gmock_search_path is given
2081 PrintIncludes(printer.get(), gmock_header, false,
2082 params.gmock_search_path);
2085 if (!file->package().empty()) {
2086 std::vector<grpc::string> parts = file->package_parts();
2088 for (auto part = parts.begin(); part != parts.end(); part++) {
2089 vars["part"] = *part;
2090 printer->Print(vars, "namespace $part$ {\n");
2094 printer->Print(vars, "\n");
2099 void PrintMockClientMethods(grpc_generator::Printer* printer,
2100 const grpc_generator::Method* method,
2101 std::map<grpc::string, grpc::string>* vars) {
2102 (*vars)["Method"] = method->name();
2103 (*vars)["Request"] = method->input_type_name();
2104 (*vars)["Response"] = method->output_type_name();
2107 grpc::string prefix;
2108 grpc::string method_params; // extra arguments to method
2109 int extra_method_param_count;
2110 } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
2112 if (method->NoStreaming()) {
2115 "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
2116 "const $Request$& request, $Response$* response));\n");
2117 for (auto async_prefix : async_prefixes) {
2118 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2121 "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
2122 "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
2123 "(::grpc::ClientContext* context, const $Request$& request, "
2124 "::grpc::CompletionQueue* cq));\n");
2126 } else if (ClientOnlyStreaming(method)) {
2129 "MOCK_METHOD2($Method$Raw, "
2130 "::grpc::ClientWriterInterface< $Request$>*"
2131 "(::grpc::ClientContext* context, $Response$* response));\n");
2132 for (auto async_prefix : async_prefixes) {
2133 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2134 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2135 (*vars)["MockArgs"] =
2136 std::to_string(3 + async_prefix.extra_method_param_count);
2137 printer->Print(*vars,
2138 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2139 "::grpc::ClientAsyncWriterInterface< $Request$>*"
2140 "(::grpc::ClientContext* context, $Response$* response, "
2141 "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
2143 } else if (ServerOnlyStreaming(method)) {
2146 "MOCK_METHOD2($Method$Raw, "
2147 "::grpc::ClientReaderInterface< $Response$>*"
2148 "(::grpc::ClientContext* context, const $Request$& request));\n");
2149 for (auto async_prefix : async_prefixes) {
2150 (*vars)["AsyncPrefix"] = async_prefix.prefix;
2151 (*vars)["AsyncMethodParams"] = async_prefix.method_params;
2152 (*vars)["MockArgs"] =
2153 std::to_string(3 + async_prefix.extra_method_param_count);
2156 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2157 "::grpc::ClientAsyncReaderInterface< $Response$>*"
2158 "(::grpc::ClientContext* context, const $Request$& request, "
2159 "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
2161 } else if (method->BidiStreaming()) {
2164 "MOCK_METHOD1($Method$Raw, "
2165 "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
2166 "(::grpc::ClientContext* context));\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(2 + async_prefix.extra_method_param_count);
2174 "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2175 "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
2176 "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
2177 "$AsyncMethodParams$));\n");
2182 void PrintMockService(grpc_generator::Printer* printer,
2183 const grpc_generator::Service* service,
2184 std::map<grpc::string, grpc::string>* vars) {
2185 (*vars)["Service"] = service->name();
2187 printer->Print(*vars,
2188 "class Mock$Service$Stub : public $Service$::StubInterface {\n"
2191 for (int i = 0; i < service->method_count(); ++i) {
2192 PrintMockClientMethods(printer, service->method(i).get(), vars);
2195 printer->Print("};\n");
2198 grpc::string GetMockServices(grpc_generator::File* file,
2199 const Parameters& params) {
2200 grpc::string output;
2202 // Scope the output stream so it closes and finalizes output to the string.
2203 auto printer = file->CreatePrinter(&output);
2204 std::map<grpc::string, grpc::string> vars;
2205 // Package string is empty or ends with a dot. It is used to fully qualify
2207 vars["Package"] = file->package();
2208 if (!file->package().empty()) {
2209 vars["Package"].append(".");
2212 if (!params.services_namespace.empty()) {
2213 vars["services_namespace"] = params.services_namespace;
2214 printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
2217 for (int i = 0; i < file->service_count(); i++) {
2218 PrintMockService(printer.get(), file->service(i).get(), &vars);
2219 printer->Print("\n");
2222 if (!params.services_namespace.empty()) {
2223 printer->Print(vars, "} // namespace $services_namespace$\n\n");
2229 grpc::string GetMockEpilogue(grpc_generator::File* file,
2230 const Parameters& /*params*/) {
2233 if (!file->package().empty()) {
2234 std::vector<grpc::string> parts = file->package_parts();
2236 for (auto part = parts.begin(); part != parts.end(); part++) {
2237 temp.append("} // namespace ");
2247 } // namespace grpc_cpp_generator