Imported Upstream version 1.18.0
[platform/upstream/grpc.git] / src / compiler / cpp_generator.cc
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 #include <map>
20
21 #include "src/compiler/cpp_generator.h"
22
23 #include <sstream>
24
25 namespace grpc_cpp_generator {
26 namespace {
27
28 template <class T>
29 grpc::string as_string(T x) {
30   std::ostringstream out;
31   out << x;
32   return out.str();
33 }
34
35 inline bool ClientOnlyStreaming(const grpc_generator::Method* method) {
36   return method->ClientStreaming() && !method->ServerStreaming();
37 }
38
39 inline bool ServerOnlyStreaming(const grpc_generator::Method* method) {
40   return !method->ClientStreaming() && method->ServerStreaming();
41 }
42
43 grpc::string FilenameIdentifier(const grpc::string& filename) {
44   grpc::string result;
45   for (unsigned i = 0; i < filename.size(); i++) {
46     char c = filename[i];
47     if (isalnum(c)) {
48       result.push_back(c);
49     } else {
50       static char hex[] = "0123456789abcdef";
51       result.push_back('_');
52       result.push_back(hex[(c >> 4) & 0xf]);
53       result.push_back(hex[c & 0xf]);
54     }
55   }
56   return result;
57 }
58 }  // namespace
59
60 template <class T, size_t N>
61 T* array_end(T (&array)[N]) {
62   return array + N;
63 }
64
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;
69
70   vars["l"] = use_system_headers ? '<' : '"';
71   vars["r"] = use_system_headers ? '>' : '"';
72
73   if (!search_path.empty()) {
74     vars["l"] += search_path;
75     if (search_path[search_path.size() - 1] != '/') {
76       vars["l"] += '/';
77     }
78   }
79
80   for (auto i = headers.begin(); i != headers.end(); i++) {
81     vars["h"] = *i;
82     printer->Print(vars, "#include $l$$h$$r$\n");
83   }
84 }
85
86 grpc::string GetHeaderPrologue(grpc_generator::File* file,
87                                const Parameters& /*params*/) {
88   grpc::string output;
89   {
90     // Scope the output stream so it closes and finalizes output to the string.
91     auto printer = file->CreatePrinter(&output);
92     std::map<grpc::string, grpc::string> vars;
93
94     vars["filename"] = file->filename();
95     vars["filename_identifier"] = FilenameIdentifier(file->filename());
96     vars["filename_base"] = file->filename_without_ext();
97     vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
98
99     printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
100     printer->Print(vars,
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());
107     }
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");
114   }
115   return output;
116 }
117
118 grpc::string GetHeaderIncludes(grpc_generator::File* file,
119                                const Parameters& params) {
120   grpc::string output;
121   {
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;
125
126     if (!params.additional_header_includes.empty()) {
127       PrintIncludes(printer.get(), params.additional_header_includes, false,
128                     "");
129     }
130     static const char* headers_strs[] = {
131         "functional",
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");
154
155     if (!file->package().empty()) {
156       std::vector<grpc::string> parts = file->package_parts();
157
158       for (auto part = parts.begin(); part != parts.end(); part++) {
159         vars["part"] = *part;
160         printer->Print(vars, "namespace $part$ {\n");
161       }
162       printer->Print(vars, "\n");
163     }
164   }
165   return output;
166 }
167
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();
174
175   struct {
176     grpc::string prefix;
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", "", ""}};
181
182   if (is_public) {
183     if (method->NoStreaming()) {
184       printer->Print(
185           *vars,
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;
190         printer->Print(
191             *vars,
192             "std::unique_ptr< "
193             "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
194             "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
195             "const $Request$& request, "
196             "::grpc::CompletionQueue* cq) {\n");
197         printer->Indent();
198         printer->Print(
199             *vars,
200             "return std::unique_ptr< "
201             "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
202             "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
203         printer->Outdent();
204         printer->Print("}\n");
205       }
206     } else if (ClientOnlyStreaming(method)) {
207       printer->Print(
208           *vars,
209           "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
210           " $Method$("
211           "::grpc::ClientContext* context, $Response$* response) {\n");
212       printer->Indent();
213       printer->Print(
214           *vars,
215           "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
216           "($Method$Raw(context, response));\n");
217       printer->Outdent();
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;
223         printer->Print(
224             *vars,
225             "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
226             " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
227             "$Response$* "
228             "response, "
229             "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
230         printer->Indent();
231         printer->Print(*vars,
232                        "return std::unique_ptr< "
233                        "::grpc::ClientAsyncWriterInterface< $Request$>>("
234                        "$AsyncPrefix$$Method$Raw(context, response, "
235                        "cq$AsyncRawArgs$));\n");
236         printer->Outdent();
237         printer->Print("}\n");
238       }
239     } else if (ServerOnlyStreaming(method)) {
240       printer->Print(
241           *vars,
242           "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
243           " $Method$(::grpc::ClientContext* context, const $Request$& request)"
244           " {\n");
245       printer->Indent();
246       printer->Print(
247           *vars,
248           "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
249           "($Method$Raw(context, request));\n");
250       printer->Outdent();
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;
256         printer->Print(
257             *vars,
258             "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
259             "$AsyncPrefix$$Method$("
260             "::grpc::ClientContext* context, const $Request$& request, "
261             "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
262         printer->Indent();
263         printer->Print(
264             *vars,
265             "return std::unique_ptr< "
266             "::grpc::ClientAsyncReaderInterface< $Response$>>("
267             "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
268         printer->Outdent();
269         printer->Print("}\n");
270       }
271     } else if (method->BidiStreaming()) {
272       printer->Print(*vars,
273                      "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
274                      "$Request$, $Response$>> "
275                      "$Method$(::grpc::ClientContext* context) {\n");
276       printer->Indent();
277       printer->Print(
278           *vars,
279           "return std::unique_ptr< "
280           "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
281           "$Method$Raw(context));\n");
282       printer->Outdent();
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;
288         printer->Print(
289             *vars,
290             "std::unique_ptr< "
291             "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
292             "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
293             "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
294         printer->Indent();
295         printer->Print(
296             *vars,
297             "return std::unique_ptr< "
298             "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
299             "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
300         printer->Outdent();
301         printer->Print("}\n");
302       }
303     }
304   } else {
305     if (method->NoStreaming()) {
306       for (auto async_prefix : async_prefixes) {
307         (*vars)["AsyncPrefix"] = async_prefix.prefix;
308         printer->Print(
309             *vars,
310             "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
311             "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
312             "const $Request$& request, "
313             "::grpc::CompletionQueue* cq) = 0;\n");
314       }
315     } else if (ClientOnlyStreaming(method)) {
316       printer->Print(
317           *vars,
318           "virtual ::grpc::ClientWriterInterface< $Request$>*"
319           " $Method$Raw("
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;
324         printer->Print(
325             *vars,
326             "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
327             " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
328             "$Response$* response, "
329             "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
330       }
331     } else if (ServerOnlyStreaming(method)) {
332       printer->Print(
333           *vars,
334           "virtual ::grpc::ClientReaderInterface< $Response$>* "
335           "$Method$Raw("
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;
340         printer->Print(
341             *vars,
342             "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
343             "$AsyncPrefix$$Method$Raw("
344             "::grpc::ClientContext* context, const $Request$& request, "
345             "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
346       }
347     } else if (method->BidiStreaming()) {
348       printer->Print(*vars,
349                      "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
350                      "$Response$>* "
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;
355         printer->Print(
356             *vars,
357             "virtual ::grpc::ClientAsyncReaderWriterInterface< "
358             "$Request$, $Response$>* "
359             "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
360             "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
361       }
362     }
363   }
364 }
365
366 void PrintHeaderClientMethod(grpc_generator::Printer* printer,
367                              const grpc_generator::Method* method,
368                              std::map<grpc::string, grpc::string>* vars,
369                              bool is_public) {
370   (*vars)["Method"] = method->name();
371   (*vars)["Request"] = method->input_type_name();
372   (*vars)["Response"] = method->output_type_name();
373   struct {
374     grpc::string prefix;
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", "", ""}};
379
380   if (is_public) {
381     if (method->NoStreaming()) {
382       printer->Print(
383           *vars,
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;
388         printer->Print(
389             *vars,
390             "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
391             "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
392             "const $Request$& request, "
393             "::grpc::CompletionQueue* cq) {\n");
394         printer->Indent();
395         printer->Print(*vars,
396                        "return std::unique_ptr< "
397                        "::grpc::ClientAsyncResponseReader< $Response$>>("
398                        "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
399         printer->Outdent();
400         printer->Print("}\n");
401       }
402     } else if (ClientOnlyStreaming(method)) {
403       printer->Print(
404           *vars,
405           "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
406           " $Method$("
407           "::grpc::ClientContext* context, $Response$* response) {\n");
408       printer->Indent();
409       printer->Print(*vars,
410                      "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
411                      "($Method$Raw(context, response));\n");
412       printer->Outdent();
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");
423         printer->Indent();
424         printer->Print(
425             *vars,
426             "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
427             "$AsyncPrefix$$Method$Raw(context, response, "
428             "cq$AsyncRawArgs$));\n");
429         printer->Outdent();
430         printer->Print("}\n");
431       }
432     } else if (ServerOnlyStreaming(method)) {
433       printer->Print(
434           *vars,
435           "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
436           " $Method$(::grpc::ClientContext* context, const $Request$& request)"
437           " {\n");
438       printer->Indent();
439       printer->Print(
440           *vars,
441           "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
442           "($Method$Raw(context, request));\n");
443       printer->Outdent();
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;
449         printer->Print(
450             *vars,
451             "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
452             "$AsyncPrefix$$Method$("
453             "::grpc::ClientContext* context, const $Request$& request, "
454             "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
455         printer->Indent();
456         printer->Print(
457             *vars,
458             "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
459             "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
460         printer->Outdent();
461         printer->Print("}\n");
462       }
463     } else if (method->BidiStreaming()) {
464       printer->Print(
465           *vars,
466           "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
467           " $Method$(::grpc::ClientContext* context) {\n");
468       printer->Indent();
469       printer->Print(*vars,
470                      "return std::unique_ptr< "
471                      "::grpc::ClientReaderWriter< $Request$, $Response$>>("
472                      "$Method$Raw(context));\n");
473       printer->Outdent();
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");
484         printer->Indent();
485         printer->Print(
486             *vars,
487             "return std::unique_ptr< "
488             "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
489             "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
490         printer->Outdent();
491         printer->Print("}\n");
492       }
493     }
494   } else {
495     if (method->NoStreaming()) {
496       for (auto async_prefix : async_prefixes) {
497         (*vars)["AsyncPrefix"] = async_prefix.prefix;
498         printer->Print(
499             *vars,
500             "::grpc::ClientAsyncResponseReader< $Response$>* "
501             "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
502             "const $Request$& request, "
503             "::grpc::CompletionQueue* cq) override;\n");
504       }
505     } else if (ClientOnlyStreaming(method)) {
506       printer->Print(*vars,
507                      "::grpc::ClientWriter< $Request$>* $Method$Raw("
508                      "::grpc::ClientContext* context, $Response$* response) "
509                      "override;\n");
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;
514         printer->Print(
515             *vars,
516             "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
517             "::grpc::ClientContext* context, $Response$* response, "
518             "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
519       }
520     } else if (ServerOnlyStreaming(method)) {
521       printer->Print(*vars,
522                      "::grpc::ClientReader< $Response$>* $Method$Raw("
523                      "::grpc::ClientContext* context, const $Request$& request)"
524                      " override;\n");
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;
529         printer->Print(
530             *vars,
531             "::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw("
532             "::grpc::ClientContext* context, const $Request$& request, "
533             "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
534       }
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;
543         printer->Print(
544             *vars,
545             "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
546             "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
547             "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
548       }
549     }
550   }
551 }
552
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");
564   printer->Indent();
565   printer->Print("virtual ~experimental_async_interface() {}\n");
566 }
567
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
572   assert(is_public);
573
574   (*vars)["Method"] = method->name();
575   (*vars)["Request"] = method->input_type_name();
576   (*vars)["Response"] = method->output_type_name();
577
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$>* "
588                    "reactor) = 0;\n");
589   } else if (ServerOnlyStreaming(method)) {
590     printer->Print(*vars,
591                    "virtual void $Method$(::grpc::ClientContext* context, "
592                    "$Request$* request, "
593                    "::grpc::experimental::ClientReadReactor< $Response$>* "
594                    "reactor) = 0;\n");
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");
600   }
601 }
602
603 void PrintHeaderClientMethodCallbackInterfacesEnd(
604     grpc_generator::Printer* printer,
605     std::map<grpc::string, grpc::string>* vars) {
606   printer->Outdent();
607   printer->Print("};\n");
608
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.
614   printer->Print(
615       "virtual class experimental_async_interface* experimental_async() { "
616       "return nullptr; }\n");
617 }
618
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");
626   printer->Indent();
627 }
628
629 void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
630                                      const grpc_generator::Method* method,
631                                      std::map<grpc::string, grpc::string>* vars,
632                                      bool is_public) {
633   // Reserve is_public for future expansion
634   assert(is_public);
635
636   (*vars)["Method"] = method->name();
637   (*vars)["Request"] = method->input_type_name();
638   (*vars)["Response"] = method->output_type_name();
639
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");
657
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");
663   }
664 }
665
666 void PrintHeaderClientMethodCallbackEnd(
667     grpc_generator::Printer* printer,
668     std::map<grpc::string, grpc::string>* vars) {
669   printer->Outdent();
670   printer->Print(" private:\n");
671   printer->Indent();
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");
678   printer->Outdent();
679   printer->Print("};\n");
680
681   printer->Print(
682       "class experimental_async_interface* experimental_async() override { "
683       "return &async_stub_; }\n");
684 }
685
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");
692 }
693
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()) {
718     printer->Print(
719         *vars,
720         "virtual ::grpc::Status $Method$("
721         "::grpc::ServerContext* context, "
722         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
723         "\n");
724   }
725   printer->Print(method->GetTrailingComments("//").c_str());
726 }
727
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()) {
735     printer->Print(
736         *vars,
737         "// disable synchronous version of this method\n"
738         "::grpc::Status $Method$("
739         "::grpc::ServerContext* context, const $Request$* request, "
740         "$Response$* response) override {\n"
741         "  abort();\n"
742         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
743         "}\n");
744     printer->Print(
745         *vars,
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)) {
756     printer->Print(
757         *vars,
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"
763         "  abort();\n"
764         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
765         "}\n");
766     printer->Print(
767         *vars,
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)) {
778     printer->Print(
779         *vars,
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 "
784         "{\n"
785         "  abort();\n"
786         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
787         "}\n");
788     printer->Print(
789         *vars,
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");
795     printer->Print(
796         *vars,
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()) {
801     printer->Print(
802         *vars,
803         "// disable synchronous version of this method\n"
804         "::grpc::Status $Method$("
805         "::grpc::ServerContext* context, "
806         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
807         " override {\n"
808         "  abort();\n"
809         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
810         "}\n");
811     printer->Print(
812         *vars,
813         "void Request$Method$("
814         "::grpc::ServerContext* context, "
815         "::grpc::ServerAsyncReaderWriter< $RealResponse$, $RealRequest$>* "
816         "stream, "
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");
823   }
824 }
825
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");
839   printer->Print(
840       " private:\n"
841       "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
842   printer->Print(" public:\n");
843   printer->Indent();
844   printer->Print(*vars,
845                  "WithAsyncMethod_$Method$() {\n"
846                  "  ::grpc::Service::MarkMethodAsync($Idx$);\n"
847                  "}\n");
848   printer->Print(*vars,
849                  "~WithAsyncMethod_$Method$() override {\n"
850                  "  BaseClassMustBeDerivedFromService(this);\n"
851                  "}\n");
852   PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
853   printer->Outdent();
854   printer->Print(*vars, "};\n");
855 }
856
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()) {
864     printer->Print(
865         *vars,
866         "// disable synchronous version of this method\n"
867         "::grpc::Status $Method$("
868         "::grpc::ServerContext* context, const $Request$* request, "
869         "$Response$* response) override {\n"
870         "  abort();\n"
871         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
872         "}\n");
873     printer->Print(
874         *vars,
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)) {
882     printer->Print(
883         *vars,
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"
889         "  abort();\n"
890         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
891         "}\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)) {
898     printer->Print(
899         *vars,
900         "// disable synchronous version of this method\n"
901         "::grpc::Status $Method$("
902         "::grpc::ServerContext* context, const $Request$* request, "
903         "::grpc::ServerWriter< $Response$>* writer) override "
904         "{\n"
905         "  abort();\n"
906         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
907         "}\n");
908     printer->Print(*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()) {
914     printer->Print(
915         *vars,
916         "// disable synchronous version of this method\n"
917         "::grpc::Status $Method$("
918         "::grpc::ServerContext* context, "
919         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
920         " override {\n"
921         "  abort();\n"
922         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
923         "}\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");
929   }
930 }
931
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");
943   printer->Print(
944       *vars,
945       "class ExperimentalWithCallbackMethod_$Method$ : public BaseClass {\n");
946   printer->Print(
947       " private:\n"
948       "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
949   printer->Print(" public:\n");
950   printer->Indent();
951   printer->Print(*vars, "ExperimentalWithCallbackMethod_$Method$() {\n");
952   if (method->NoStreaming()) {
953     printer->Print(
954         *vars,
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* "
962         "controller) {\n"
963         "               return this->$"
964         "Method$(context, request, response, controller);\n"
965         "             }));\n");
966   } else if (ClientOnlyStreaming(method)) {
967     printer->Print(
968         *vars,
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)) {
974     printer->Print(
975         *vars,
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()) {
981     printer->Print(
982         *vars,
983         "  ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
984         "    new ::grpc::internal::CallbackBidiHandler< "
985         "$RealRequest$, $RealResponse$>(\n"
986         "      [this] { return this->$Method$(); }));\n");
987   }
988   printer->Print(*vars, "}\n");
989   printer->Print(*vars,
990                  "~ExperimentalWithCallbackMethod_$Method$() override {\n"
991                  "  BaseClassMustBeDerivedFromService(this);\n"
992                  "}\n");
993   PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
994   printer->Outdent();
995   printer->Print(*vars, "};\n");
996 }
997
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 "
1011                  "BaseClass {\n");
1012   printer->Print(
1013       " private:\n"
1014       "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1015   printer->Print(" public:\n");
1016   printer->Indent();
1017   printer->Print(*vars, "ExperimentalWithRawCallbackMethod_$Method$() {\n");
1018   if (method->NoStreaming()) {
1019     printer->Print(
1020         *vars,
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* "
1028         "controller) {\n"
1029         "               this->$"
1030         "Method$(context, request, response, controller);\n"
1031         "             }));\n");
1032   } else if (ClientOnlyStreaming(method)) {
1033     printer->Print(
1034         *vars,
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)) {
1040     printer->Print(
1041         *vars,
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()) {
1047     printer->Print(
1048         *vars,
1049         "  ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
1050         "    new ::grpc::internal::CallbackBidiHandler< "
1051         "$RealRequest$, $RealResponse$>(\n"
1052         "      [this] { return this->$Method$(); }));\n");
1053   }
1054   printer->Print(*vars, "}\n");
1055   printer->Print(*vars,
1056                  "~ExperimentalWithRawCallbackMethod_$Method$() override {\n"
1057                  "  BaseClassMustBeDerivedFromService(this);\n"
1058                  "}\n");
1059   PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
1060   printer->Outdent();
1061   printer->Print(*vars, "};\n");
1062 }
1063
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");
1075     printer->Print(
1076         " private:\n"
1077         "  void BaseClassMustBeDerivedFromService(const Service *service) "
1078         "{}\n");
1079     printer->Print(" public:\n");
1080     printer->Indent();
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"
1089                    "}\n");
1090     printer->Print(*vars,
1091                    "~WithStreamedUnaryMethod_$Method$() override {\n"
1092                    "  BaseClassMustBeDerivedFromService(this);\n"
1093                    "}\n");
1094     printer->Print(
1095         *vars,
1096         "// disable regular version of this method\n"
1097         "::grpc::Status $Method$("
1098         "::grpc::ServerContext* context, const $Request$* request, "
1099         "$Response$* response) override {\n"
1100         "  abort();\n"
1101         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1102         "}\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)"
1109                    " = 0;\n");
1110     printer->Outdent();
1111     printer->Print(*vars, "};\n");
1112   }
1113 }
1114
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");
1126     printer->Print(
1127         " private:\n"
1128         "  void BaseClassMustBeDerivedFromService(const Service *service) "
1129         "{}\n");
1130     printer->Print(" public:\n");
1131     printer->Indent();
1132     printer->Print(
1133         *vars,
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"
1141         "}\n");
1142     printer->Print(*vars,
1143                    "~WithSplitStreamingMethod_$Method$() override {\n"
1144                    "  BaseClassMustBeDerivedFromService(this);\n"
1145                    "}\n");
1146     printer->Print(
1147         *vars,
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 "
1152         "{\n"
1153         "  abort();\n"
1154         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1155         "}\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)"
1162                    " = 0;\n");
1163     printer->Outdent();
1164     printer->Print(*vars, "};\n");
1165   }
1166 }
1167
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");
1177   printer->Print(
1178       " private:\n"
1179       "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1180   printer->Print(" public:\n");
1181   printer->Indent();
1182   printer->Print(*vars,
1183                  "WithGenericMethod_$Method$() {\n"
1184                  "  ::grpc::Service::MarkMethodGeneric($Idx$);\n"
1185                  "}\n");
1186   printer->Print(*vars,
1187                  "~WithGenericMethod_$Method$() override {\n"
1188                  "  BaseClassMustBeDerivedFromService(this);\n"
1189                  "}\n");
1190   if (method->NoStreaming()) {
1191     printer->Print(
1192         *vars,
1193         "// disable synchronous version of this method\n"
1194         "::grpc::Status $Method$("
1195         "::grpc::ServerContext* context, const $Request$* request, "
1196         "$Response$* response) override {\n"
1197         "  abort();\n"
1198         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1199         "}\n");
1200   } else if (ClientOnlyStreaming(method)) {
1201     printer->Print(
1202         *vars,
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"
1208         "  abort();\n"
1209         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1210         "}\n");
1211   } else if (ServerOnlyStreaming(method)) {
1212     printer->Print(
1213         *vars,
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 "
1218         "{\n"
1219         "  abort();\n"
1220         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1221         "}\n");
1222   } else if (method->BidiStreaming()) {
1223     printer->Print(
1224         *vars,
1225         "// disable synchronous version of this method\n"
1226         "::grpc::Status $Method$("
1227         "::grpc::ServerContext* context, "
1228         "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
1229         " override {\n"
1230         "  abort();\n"
1231         "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
1232         "}\n");
1233   }
1234   printer->Outdent();
1235   printer->Print(*vars, "};\n");
1236 }
1237
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");
1250   printer->Print(
1251       " private:\n"
1252       "  void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
1253   printer->Print(" public:\n");
1254   printer->Indent();
1255   printer->Print(*vars,
1256                  "WithRawMethod_$Method$() {\n"
1257                  "  ::grpc::Service::MarkMethodRaw($Idx$);\n"
1258                  "}\n");
1259   printer->Print(*vars,
1260                  "~WithRawMethod_$Method$() override {\n"
1261                  "  BaseClassMustBeDerivedFromService(this);\n"
1262                  "}\n");
1263   PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
1264   printer->Outdent();
1265   printer->Print(*vars, "};\n");
1266 }
1267
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();
1272
1273   printer->Print(service->GetLeadingComments("//").c_str());
1274   printer->Print(*vars,
1275                  "class $Service$ final {\n"
1276                  " public:\n");
1277   printer->Indent();
1278
1279   // Service metadata
1280   printer->Print(*vars,
1281                  "static constexpr char const* service_full_name() {\n"
1282                  "  return \"$Package$$Service$\";\n"
1283                  "}\n");
1284
1285   // Client side
1286   printer->Print(
1287       "class StubInterface {\n"
1288       " public:\n");
1289   printer->Indent();
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,
1294                                       true);
1295     printer->Print(service->method(i)->GetTrailingComments("//").c_str());
1296   }
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(),
1301                                               vars, true);
1302     printer->Print(service->method(i)->GetTrailingComments("//").c_str());
1303   }
1304   PrintHeaderClientMethodCallbackInterfacesEnd(printer, vars);
1305   printer->Outdent();
1306   printer->Print("private:\n");
1307   printer->Indent();
1308   for (int i = 0; i < service->method_count(); ++i) {
1309     PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
1310                                       false);
1311   }
1312   printer->Outdent();
1313   printer->Print("};\n");
1314   printer->Print(
1315       "class Stub final : public StubInterface"
1316       " {\n public:\n");
1317   printer->Indent();
1318   printer->Print(
1319       "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
1320       "channel);\n");
1321   for (int i = 0; i < service->method_count(); ++i) {
1322     PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
1323   }
1324   PrintHeaderClientMethodCallbackStart(printer, vars);
1325   for (int i = 0; i < service->method_count(); ++i) {
1326     PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars,
1327                                     true);
1328   }
1329   PrintHeaderClientMethodCallbackEnd(printer, vars);
1330   printer->Outdent();
1331   printer->Print("\n private:\n");
1332   printer->Indent();
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);
1337   }
1338   for (int i = 0; i < service->method_count(); ++i) {
1339     PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
1340   }
1341   printer->Outdent();
1342   printer->Print("};\n");
1343   printer->Print(
1344       "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
1345       "::grpc::ChannelInterface>& channel, "
1346       "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
1347
1348   printer->Print("\n");
1349
1350   // Server side - base
1351   printer->Print(
1352       "class Service : public ::grpc::Service {\n"
1353       " public:\n");
1354   printer->Indent();
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);
1359   }
1360   printer->Outdent();
1361   printer->Print("};\n");
1362
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);
1367   }
1368
1369   printer->Print("typedef ");
1370
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$<");
1374   }
1375   printer->Print("Service");
1376   for (int i = 0; i < service->method_count(); ++i) {
1377     printer->Print(" >");
1378   }
1379   printer->Print(" AsyncService;\n");
1380
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);
1385   }
1386
1387   printer->Print("typedef ");
1388
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$<");
1392   }
1393   printer->Print("Service");
1394   for (int i = 0; i < service->method_count(); ++i) {
1395     printer->Print(" >");
1396   }
1397   printer->Print(" ExperimentalCallbackService;\n");
1398
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);
1403   }
1404
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);
1409   }
1410
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);
1415   }
1416
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(),
1421                                          vars);
1422   }
1423
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$<");
1429     }
1430   }
1431   printer->Print("Service");
1432   for (int i = 0; i < service->method_count(); ++i) {
1433     if (service->method(i)->NoStreaming()) {
1434       printer->Print(" >");
1435     }
1436   }
1437   printer->Print(" StreamedUnaryService;\n");
1438
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(),
1443                                           vars);
1444   }
1445
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$<");
1452     }
1453   }
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(" >");
1459     }
1460   }
1461   printer->Print(" SplitStreamedService;\n");
1462
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$<");
1470     }
1471     if (service->method(i)->NoStreaming()) {
1472       printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
1473     }
1474   }
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(" >");
1481     }
1482   }
1483   printer->Print(" StreamedService;\n");
1484
1485   printer->Outdent();
1486   printer->Print("};\n");
1487   printer->Print(service->GetTrailingComments("//").c_str());
1488 }
1489
1490 grpc::string GetHeaderServices(grpc_generator::File* file,
1491                                const Parameters& params) {
1492   grpc::string output;
1493   {
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
1498     // method names.
1499     vars["Package"] = file->package();
1500     if (!file->package().empty()) {
1501       vars["Package"].append(".");
1502     }
1503
1504     if (!params.services_namespace.empty()) {
1505       vars["services_namespace"] = params.services_namespace;
1506       printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
1507     }
1508
1509     for (int i = 0; i < file->service_count(); ++i) {
1510       PrintHeaderService(printer.get(), file->service(i).get(), &vars);
1511       printer->Print("\n");
1512     }
1513
1514     if (!params.services_namespace.empty()) {
1515       printer->Print(vars, "}  // namespace $services_namespace$\n\n");
1516     }
1517   }
1518   return output;
1519 }
1520
1521 grpc::string GetHeaderEpilogue(grpc_generator::File* file,
1522                                const Parameters& /*params*/) {
1523   grpc::string output;
1524   {
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;
1528
1529     vars["filename"] = file->filename();
1530     vars["filename_identifier"] = FilenameIdentifier(file->filename());
1531
1532     if (!file->package().empty()) {
1533       std::vector<grpc::string> parts = file->package_parts();
1534
1535       for (auto part = parts.rbegin(); part != parts.rend(); part++) {
1536         vars["part"] = *part;
1537         printer->Print(vars, "}  // namespace $part$\n");
1538       }
1539       printer->Print(vars, "\n");
1540     }
1541
1542     printer->Print(vars, "\n");
1543     printer->Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
1544
1545     printer->Print(file->GetTrailingComments("//").c_str());
1546   }
1547   return output;
1548 }
1549
1550 grpc::string GetSourcePrologue(grpc_generator::File* file,
1551                                const Parameters& /*params*/) {
1552   grpc::string output;
1553   {
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;
1557
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;
1562
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");
1567
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");
1571   }
1572   return output;
1573 }
1574
1575 grpc::string GetSourceIncludes(grpc_generator::File* file,
1576                                const Parameters& params) {
1577   grpc::string output;
1578   {
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;
1582
1583     static const char* headers_strs[] = {
1584         "functional",
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);
1598
1599     if (!file->package().empty()) {
1600       std::vector<grpc::string> parts = file->package_parts();
1601
1602       for (auto part = parts.begin(); part != parts.end(); part++) {
1603         vars["part"] = *part;
1604         printer->Print(vars, "namespace $part$ {\n");
1605       }
1606     }
1607
1608     printer->Print(vars, "\n");
1609   }
1610   return output;
1611 }
1612
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();
1619   struct {
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");
1635
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");
1645
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");
1655       printer->Print(
1656           *vars,
1657           "  return "
1658           "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
1659           "::Create(channel_.get(), cq, "
1660           "rpcmethod_$Method$_, "
1661           "context, request, $AsyncStart$);\n"
1662           "}\n\n");
1663     }
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");
1669     printer->Print(
1670         *vars,
1671         "  return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
1672         "channel_.get(), "
1673         "rpcmethod_$Method$_, "
1674         "context, response);\n"
1675         "}\n\n");
1676
1677     printer->Print(
1678         *vars,
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"
1689                    "}\n\n");
1690
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");
1701       printer->Print(
1702           *vars,
1703           "  return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
1704           "::Create(channel_.get(), cq, "
1705           "rpcmethod_$Method$_, "
1706           "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
1707           "}\n\n");
1708     }
1709   } else if (ServerOnlyStreaming(method)) {
1710     printer->Print(
1711         *vars,
1712         "::grpc::ClientReader< $Response$>* "
1713         "$ns$$Service$::Stub::$Method$Raw("
1714         "::grpc::ClientContext* context, const $Request$& request) {\n");
1715     printer->Print(
1716         *vars,
1717         "  return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
1718         "channel_.get(), "
1719         "rpcmethod_$Method$_, "
1720         "context, request);\n"
1721         "}\n\n");
1722
1723     printer->Print(
1724         *vars,
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"
1735                    "}\n\n");
1736
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;
1742       printer->Print(
1743           *vars,
1744           "::grpc::ClientAsyncReader< $Response$>* "
1745           "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
1746           "::grpc::ClientContext* context, const $Request$& request, "
1747           "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
1748       printer->Print(
1749           *vars,
1750           "  return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
1751           "::Create(channel_.get(), cq, "
1752           "rpcmethod_$Method$_, "
1753           "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
1754           "}\n\n");
1755     }
1756   } else if (method->BidiStreaming()) {
1757     printer->Print(
1758         *vars,
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("
1764                    "channel_.get(), "
1765                    "rpcmethod_$Method$_, "
1766                    "context);\n"
1767                    "}\n\n");
1768
1769     printer->Print(
1770         *vars,
1771         "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
1772         "ClientContext* context, "
1773         "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* "
1774         "reactor) {\n");
1775     printer->Print(*vars,
1776                    "  ::grpc::internal::ClientCallbackReaderWriterFactory< "
1777                    "$Request$,$Response$>::Create("
1778                    "stub_->channel_.get(), "
1779                    "stub_->rpcmethod_$Method$_, "
1780                    "context, reactor);\n"
1781                    "}\n\n");
1782
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,
1794                      "  return "
1795                      "::grpc::internal::ClientAsyncReaderWriterFactory< "
1796                      "$Request$, $Response$>::Create("
1797                      "channel_.get(), cq, "
1798                      "rpcmethod_$Method$_, "
1799                      "context, $AsyncStart$$AsyncCreateArgs$);\n"
1800                      "}\n\n");
1801     }
1802   }
1803 }
1804
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");
1819     printer->Print(
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");
1832     printer->Print(
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");
1845     printer->Print(
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$>* "
1854                    "stream) {\n");
1855     printer->Print("  (void) context;\n");
1856     printer->Print("  (void) stream;\n");
1857     printer->Print(
1858         "  return ::grpc::Status("
1859         "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
1860     printer->Print("}\n\n");
1861   }
1862 }
1863
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();
1868
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");
1875     }
1876     printer->Print(*vars, "};\n\n");
1877   }
1878
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"
1883                  "  (void)options;\n"
1884                  "  std::unique_ptr< $ns$$Service$::Stub> stub(new "
1885                  "$ns$$Service$::Stub(channel));\n"
1886                  "  return stub;\n"
1887                  "}\n\n");
1888   printer->Print(*vars,
1889                  "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
1890                  "::grpc::ChannelInterface>& channel)\n");
1891   printer->Indent();
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";
1906     } else {
1907       (*vars)["StreamingType"] = "BIDI_STREAMING";
1908     }
1909     printer->Print(*vars,
1910                    ", rpcmethod_$Method$_("
1911                    "$prefix$$Service$_method_names[$Idx$], "
1912                    "::grpc::internal::RpcMethod::$StreamingType$, "
1913                    "channel"
1914                    ")\n");
1915   }
1916   printer->Print("{}\n\n");
1917   printer->Outdent();
1918
1919   for (int i = 0; i < service->method_count(); ++i) {
1920     (*vars)["Idx"] = as_string(i);
1921     PrintSourceClientMethod(printer, service->method(i).get(), vars);
1922   }
1923
1924   printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
1925   printer->Indent();
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()) {
1933       printer->Print(
1934           *vars,
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, "
1939           "$Request$, "
1940           "$Response$>(\n"
1941           "        std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
1942     } else if (ClientOnlyStreaming(method.get())) {
1943       printer->Print(
1944           *vars,
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())) {
1952       printer->Print(
1953           *vars,
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()) {
1961       printer->Print(
1962           *vars,
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");
1969     }
1970   }
1971   printer->Outdent();
1972   printer->Print(*vars, "}\n\n");
1973   printer->Print(*vars,
1974                  "$ns$$Service$::Service::~Service() {\n"
1975                  "}\n\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);
1979   }
1980 }
1981
1982 grpc::string GetSourceServices(grpc_generator::File* file,
1983                                const Parameters& params) {
1984   grpc::string output;
1985   {
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
1990     // method names.
1991     vars["Package"] = file->package();
1992     if (!file->package().empty()) {
1993       vars["Package"].append(".");
1994     }
1995     if (!params.services_namespace.empty()) {
1996       vars["ns"] = params.services_namespace + "::";
1997       vars["prefix"] = params.services_namespace;
1998     } else {
1999       vars["ns"] = "";
2000       vars["prefix"] = "";
2001     }
2002
2003     for (int i = 0; i < file->service_count(); ++i) {
2004       PrintSourceService(printer.get(), file->service(i).get(), &vars);
2005       printer->Print("\n");
2006     }
2007   }
2008   return output;
2009 }
2010
2011 grpc::string GetSourceEpilogue(grpc_generator::File* file,
2012                                const Parameters& /*params*/) {
2013   grpc::string temp;
2014
2015   if (!file->package().empty()) {
2016     std::vector<grpc::string> parts = file->package_parts();
2017
2018     for (auto part = parts.begin(); part != parts.end(); part++) {
2019       temp.append("}  // namespace ");
2020       temp.append(*part);
2021       temp.append("\n");
2022     }
2023     temp.append("\n");
2024   }
2025
2026   return temp;
2027 }
2028
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;
2033   {
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;
2037
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;
2042
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");
2047
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");
2052   }
2053   return output;
2054 }
2055
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;
2060   {
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;
2064
2065     static const char* headers_strs[] = {
2066         "grpcpp/impl/codegen/async_stream.h",
2067         "grpcpp/impl/codegen/sync_stream.h",
2068     };
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);
2072
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);
2078     } else {
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);
2083     }
2084
2085     if (!file->package().empty()) {
2086       std::vector<grpc::string> parts = file->package_parts();
2087
2088       for (auto part = parts.begin(); part != parts.end(); part++) {
2089         vars["part"] = *part;
2090         printer->Print(vars, "namespace $part$ {\n");
2091       }
2092     }
2093
2094     printer->Print(vars, "\n");
2095   }
2096   return output;
2097 }
2098
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();
2105
2106   struct {
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}};
2111
2112   if (method->NoStreaming()) {
2113     printer->Print(
2114         *vars,
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;
2119       printer->Print(
2120           *vars,
2121           "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
2122           "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
2123           "(::grpc::ClientContext* context, const $Request$& request, "
2124           "::grpc::CompletionQueue* cq));\n");
2125     }
2126   } else if (ClientOnlyStreaming(method)) {
2127     printer->Print(
2128         *vars,
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");
2142     }
2143   } else if (ServerOnlyStreaming(method)) {
2144     printer->Print(
2145         *vars,
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);
2154       printer->Print(
2155           *vars,
2156           "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2157           "::grpc::ClientAsyncReaderInterface< $Response$>*"
2158           "(::grpc::ClientContext* context, const $Request$& request, "
2159           "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
2160     }
2161   } else if (method->BidiStreaming()) {
2162     printer->Print(
2163         *vars,
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);
2172       printer->Print(
2173           *vars,
2174           "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
2175           "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
2176           "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
2177           "$AsyncMethodParams$));\n");
2178     }
2179   }
2180 }
2181
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();
2186
2187   printer->Print(*vars,
2188                  "class Mock$Service$Stub : public $Service$::StubInterface {\n"
2189                  " public:\n");
2190   printer->Indent();
2191   for (int i = 0; i < service->method_count(); ++i) {
2192     PrintMockClientMethods(printer, service->method(i).get(), vars);
2193   }
2194   printer->Outdent();
2195   printer->Print("};\n");
2196 }
2197
2198 grpc::string GetMockServices(grpc_generator::File* file,
2199                              const Parameters& params) {
2200   grpc::string output;
2201   {
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
2206     // method names.
2207     vars["Package"] = file->package();
2208     if (!file->package().empty()) {
2209       vars["Package"].append(".");
2210     }
2211
2212     if (!params.services_namespace.empty()) {
2213       vars["services_namespace"] = params.services_namespace;
2214       printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
2215     }
2216
2217     for (int i = 0; i < file->service_count(); i++) {
2218       PrintMockService(printer.get(), file->service(i).get(), &vars);
2219       printer->Print("\n");
2220     }
2221
2222     if (!params.services_namespace.empty()) {
2223       printer->Print(vars, "} // namespace $services_namespace$\n\n");
2224     }
2225   }
2226   return output;
2227 }
2228
2229 grpc::string GetMockEpilogue(grpc_generator::File* file,
2230                              const Parameters& /*params*/) {
2231   grpc::string temp;
2232
2233   if (!file->package().empty()) {
2234     std::vector<grpc::string> parts = file->package_parts();
2235
2236     for (auto part = parts.begin(); part != parts.end(); part++) {
2237       temp.append("} // namespace ");
2238       temp.append(*part);
2239       temp.append("\n");
2240     }
2241     temp.append("\n");
2242   }
2243
2244   return temp;
2245 }
2246
2247 }  // namespace grpc_cpp_generator