blob: 08b1123a5121ae226fbe0b34db20d6682cba675b [file] [log] [blame]
nnobleebebb7e2014-12-10 16:31:01 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
nnobleebebb7e2014-12-10 16:31:01 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Nicolas "Pixel" Noble36f53232015-01-16 06:39:58 +010034#include <map>
35
nnobleebebb7e2014-12-10 16:31:01 -080036#include "src/compiler/cpp_generator.h"
nnobleebebb7e2014-12-10 16:31:01 -080037#include "src/compiler/cpp_generator_helpers.h"
Nicolas Nobled446eb82015-03-12 17:22:33 -070038
39#include "src/compiler/config.h"
40
Craig Tiller8c8d0aa2015-02-12 11:38:36 -080041#include <sstream>
nnobleebebb7e2014-12-10 16:31:01 -080042
43namespace grpc_cpp_generator {
44namespace {
45
Craig Tiller8c8d0aa2015-02-12 11:38:36 -080046template <class T>
Nicolas Nobled446eb82015-03-12 17:22:33 -070047grpc::string as_string(T x) {
Craig Tiller8c8d0aa2015-02-12 11:38:36 -080048 std::ostringstream out;
49 out << x;
50 return out.str();
51}
52
Nicolas Nobled446eb82015-03-12 17:22:33 -070053bool NoStreaming(const grpc::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080054 return !method->client_streaming() && !method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080055}
56
Nicolas Nobled446eb82015-03-12 17:22:33 -070057bool ClientOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080058 return method->client_streaming() && !method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080059}
60
Nicolas Nobled446eb82015-03-12 17:22:33 -070061bool ServerOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
yangg1b151092015-01-09 15:31:05 -080062 return !method->client_streaming() && method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080063}
64
Nicolas Nobled446eb82015-03-12 17:22:33 -070065bool BidiStreaming(const grpc::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080066 return method->client_streaming() && method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080067}
68
Craig Tiller277d3cf2015-04-14 14:04:51 -070069grpc::string FilenameIdentifier(const grpc::string &filename) {
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +020070 grpc::string result;
71 for (unsigned i = 0; i < filename.size(); i++) {
72 char c = filename[i];
73 if (isalnum(c)) {
74 result.push_back(c);
75 } else {
76 static char hex[] = "0123456789abcdef";
77 result.push_back('_');
78 result.push_back(hex[(c >> 4) & 0xf]);
79 result.push_back(hex[c & 0xf]);
80 }
81 }
82 return result;
83}
nnobleebebb7e2014-12-10 16:31:01 -080084} // namespace
85
Nicolas "Pixel" Noble1ba1f632016-03-17 19:57:54 +010086template<class T, size_t N>
87T *array_end(T (&array)[N]) { return array + N; }
88
89void PrintIncludes(grpc::protobuf::io::Printer *printer, const std::vector<grpc::string>& headers, const Parameters &params) {
90 std::map<grpc::string, grpc::string> vars;
91
92 vars["l"] = params.use_system_headers ? '<' : '"';
93 vars["r"] = params.use_system_headers ? '>' : '"';
94
95 if (!params.grpc_search_path.empty()) {
96 vars["l"] += params.grpc_search_path;
97 if (params.grpc_search_path.back() != '/') {
98 vars["l"] += '/';
99 }
100 }
101
102 for (auto i = headers.begin(); i != headers.end(); i++) {
103 vars["h"] = *i;
104 printer->Print(vars, "#include $l$$h$$r$\n");
105 }
106}
107
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200108grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
109 const Parameters &params) {
110 grpc::string output;
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700111 {
112 // Scope the output stream so it closes and finalizes output to the string.
113 grpc::protobuf::io::StringOutputStream output_stream(&output);
114 grpc::protobuf::io::Printer printer(&output_stream, '$');
115 std::map<grpc::string, grpc::string> vars;
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200116
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700117 vars["filename"] = file->name();
118 vars["filename_identifier"] = FilenameIdentifier(file->name());
119 vars["filename_base"] = grpc_generator::StripProto(file->name());
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200120
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700121 printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
Craig Tillerce40de52015-06-05 07:14:58 -0700122 printer.Print(vars,
123 "// If you make any local change, they will be lost.\n");
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700124 printer.Print(vars, "// source: $filename$\n");
125 printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
126 printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
127 printer.Print(vars, "\n");
128 printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
129 printer.Print(vars, "\n");
130 }
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200131 return output;
132}
133
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100134grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
135 const Parameters &params) {
Nicolas "Pixel" Noble931bdce2016-01-12 03:08:11 +0100136 grpc::string output;
137 {
138 // Scope the output stream so it closes and finalizes output to the string.
139 grpc::protobuf::io::StringOutputStream output_stream(&output);
140 grpc::protobuf::io::Printer printer(&output_stream, '$');
141 std::map<grpc::string, grpc::string> vars;
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200142
Nicolas "Pixel" Noble1ba1f632016-03-17 19:57:54 +0100143 static const char *headers_strs[] = {
144 "grpc++/impl/codegen/async_stream.h",
145 "grpc++/impl/codegen/async_unary_call.h",
146 "grpc++/impl/codegen/proto_utils.h",
147 "grpc++/impl/codegen/rpc_method.h",
148 "grpc++/impl/codegen/service_type.h",
149 "grpc++/impl/codegen/status.h",
150 "grpc++/impl/codegen/stub_options.h",
151 "grpc++/impl/codegen/sync_stream.h"
152 };
153 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
154 PrintIncludes(&printer, headers, params);
Nicolas "Pixel" Noble931bdce2016-01-12 03:08:11 +0100155 printer.Print(vars, "\n");
156 printer.Print(vars, "namespace grpc {\n");
157 printer.Print(vars, "class CompletionQueue;\n");
158 printer.Print(vars, "class Channel;\n");
159 printer.Print(vars, "class RpcService;\n");
160 printer.Print(vars, "class ServerCompletionQueue;\n");
161 printer.Print(vars, "class ServerContext;\n");
162 printer.Print(vars, "} // namespace grpc\n\n");
163
164 if (!file->package().empty()) {
165 std::vector<grpc::string> parts =
166 grpc_generator::tokenize(file->package(), ".");
167
168 for (auto part = parts.begin(); part != parts.end(); part++) {
169 vars["part"] = *part;
170 printer.Print(vars, "namespace $part$ {\n");
171 }
172 printer.Print(vars, "\n");
173 }
174 }
175 return output;
nnobleebebb7e2014-12-10 16:31:01 -0800176}
177
Craig Tillerce40de52015-06-05 07:14:58 -0700178void PrintHeaderClientMethodInterfaces(
179 grpc::protobuf::io::Printer *printer,
180 const grpc::protobuf::MethodDescriptor *method,
181 std::map<grpc::string, grpc::string> *vars, bool is_public) {
nnobleebebb7e2014-12-10 16:31:01 -0800182 (*vars)["Method"] = method->name();
183 (*vars)["Request"] =
184 grpc_cpp_generator::ClassName(method->input_type(), true);
185 (*vars)["Response"] =
186 grpc_cpp_generator::ClassName(method->output_type(), true);
Yang Gaoc6924c82015-05-05 10:42:51 -0700187
188 if (is_public) {
189 if (NoStreaming(method)) {
190 printer->Print(
191 *vars,
192 "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
193 "const $Request$& request, $Response$* response) = 0;\n");
Craig Tillerce40de52015-06-05 07:14:58 -0700194 printer->Print(*vars,
195 "std::unique_ptr< "
196 "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
197 "Async$Method$(::grpc::ClientContext* context, "
198 "const $Request$& request, "
199 "::grpc::CompletionQueue* cq) {\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700200 printer->Indent();
Craig Tillerce40de52015-06-05 07:14:58 -0700201 printer->Print(*vars,
202 "return std::unique_ptr< "
203 "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
204 "Async$Method$Raw(context, request, cq));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700205 printer->Outdent();
206 printer->Print("}\n");
207 } else if (ClientOnlyStreaming(method)) {
208 printer->Print(
209 *vars,
210 "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
211 " $Method$("
212 "::grpc::ClientContext* context, $Response$* response) {\n");
213 printer->Indent();
214 printer->Print(
215 *vars,
216 "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
217 "($Method$Raw(context, response));\n");
218 printer->Outdent();
219 printer->Print("}\n");
220 printer->Print(
221 *vars,
222 "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
Craig Tillerce40de52015-06-05 07:14:58 -0700223 " Async$Method$(::grpc::ClientContext* context, $Response$* "
224 "response, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700225 "::grpc::CompletionQueue* cq, void* tag) {\n");
226 printer->Indent();
Craig Tillerce40de52015-06-05 07:14:58 -0700227 printer->Print(*vars,
228 "return std::unique_ptr< "
229 "::grpc::ClientAsyncWriterInterface< $Request$>>("
230 "Async$Method$Raw(context, response, cq, tag));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700231 printer->Outdent();
232 printer->Print("}\n");
233 } else if (ServerOnlyStreaming(method)) {
234 printer->Print(
235 *vars,
236 "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
237 " $Method$(::grpc::ClientContext* context, const $Request$& request)"
238 " {\n");
239 printer->Indent();
240 printer->Print(
241 *vars,
242 "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
243 "($Method$Raw(context, request));\n");
244 printer->Outdent();
245 printer->Print("}\n");
246 printer->Print(
247 *vars,
248 "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
249 "Async$Method$("
250 "::grpc::ClientContext* context, const $Request$& request, "
251 "::grpc::CompletionQueue* cq, void* tag) {\n");
252 printer->Indent();
Craig Tillerce40de52015-06-05 07:14:58 -0700253 printer->Print(*vars,
254 "return std::unique_ptr< "
255 "::grpc::ClientAsyncReaderInterface< $Response$>>("
256 "Async$Method$Raw(context, request, cq, tag));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700257 printer->Outdent();
258 printer->Print("}\n");
259 } else if (BidiStreaming(method)) {
Craig Tillerce40de52015-06-05 07:14:58 -0700260 printer->Print(*vars,
261 "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
262 "$Request$, $Response$>> "
263 "$Method$(::grpc::ClientContext* context) {\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700264 printer->Indent();
265 printer->Print(
266 *vars,
267 "return std::unique_ptr< "
268 "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
269 "$Method$Raw(context));\n");
270 printer->Outdent();
271 printer->Print("}\n");
272 printer->Print(
273 *vars,
274 "std::unique_ptr< "
275 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
276 "Async$Method$(::grpc::ClientContext* context, "
277 "::grpc::CompletionQueue* cq, void* tag) {\n");
278 printer->Indent();
279 printer->Print(
280 *vars,
281 "return std::unique_ptr< "
282 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
283 "Async$Method$Raw(context, cq, tag));\n");
284 printer->Outdent();
285 printer->Print("}\n");
286 }
287 } else {
288 if (NoStreaming(method)) {
289 printer->Print(
290 *vars,
291 "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
292 "Async$Method$Raw(::grpc::ClientContext* context, "
293 "const $Request$& request, "
Craig Tiller5f871ac2015-05-08 13:05:51 -0700294 "::grpc::CompletionQueue* cq) = 0;\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700295 } else if (ClientOnlyStreaming(method)) {
296 printer->Print(
297 *vars,
298 "virtual ::grpc::ClientWriterInterface< $Request$>*"
299 " $Method$Raw("
300 "::grpc::ClientContext* context, $Response$* response) = 0;\n");
Craig Tillerce40de52015-06-05 07:14:58 -0700301 printer->Print(*vars,
302 "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
303 " Async$Method$Raw(::grpc::ClientContext* context, "
304 "$Response$* response, "
305 "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700306 } else if (ServerOnlyStreaming(method)) {
307 printer->Print(
308 *vars,
309 "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
310 "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
311 printer->Print(
312 *vars,
313 "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
314 "Async$Method$Raw("
315 "::grpc::ClientContext* context, const $Request$& request, "
316 "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
317 } else if (BidiStreaming(method)) {
Craig Tillerce40de52015-06-05 07:14:58 -0700318 printer->Print(*vars,
319 "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
320 "$Response$>* "
321 "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
322 printer->Print(*vars,
323 "virtual ::grpc::ClientAsyncReaderWriterInterface< "
324 "$Request$, $Response$>* "
325 "Async$Method$Raw(::grpc::ClientContext* context, "
326 "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700327 }
328 }
329}
330
331void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
332 const grpc::protobuf::MethodDescriptor *method,
333 std::map<grpc::string, grpc::string> *vars,
334 bool is_public) {
335 (*vars)["Method"] = method->name();
336 (*vars)["Request"] =
337 grpc_cpp_generator::ClassName(method->input_type(), true);
338 (*vars)["Response"] =
339 grpc_cpp_generator::ClassName(method->output_type(), true);
Yang Gaoc6924c82015-05-05 10:42:51 -0700340 if (is_public) {
341 if (NoStreaming(method)) {
342 printer->Print(
343 *vars,
344 "::grpc::Status $Method$(::grpc::ClientContext* context, "
345 "const $Request$& request, $Response$* response) GRPC_OVERRIDE;\n");
346 printer->Print(
347 *vars,
348 "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
349 "Async$Method$(::grpc::ClientContext* context, "
350 "const $Request$& request, "
Craig Tiller5f871ac2015-05-08 13:05:51 -0700351 "::grpc::CompletionQueue* cq) {\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700352 printer->Indent();
Craig Tillerce40de52015-06-05 07:14:58 -0700353 printer->Print(*vars,
354 "return std::unique_ptr< "
355 "::grpc::ClientAsyncResponseReader< $Response$>>("
356 "Async$Method$Raw(context, request, cq));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700357 printer->Outdent();
358 printer->Print("}\n");
359 } else if (ClientOnlyStreaming(method)) {
360 printer->Print(
361 *vars,
362 "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
363 " $Method$("
364 "::grpc::ClientContext* context, $Response$* response) {\n");
365 printer->Indent();
Craig Tillerce40de52015-06-05 07:14:58 -0700366 printer->Print(*vars,
367 "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
368 "($Method$Raw(context, response));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700369 printer->Outdent();
370 printer->Print("}\n");
Craig Tillerce40de52015-06-05 07:14:58 -0700371 printer->Print(*vars,
372 "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
373 " Async$Method$(::grpc::ClientContext* context, "
374 "$Response$* response, "
375 "::grpc::CompletionQueue* cq, void* tag) {\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700376 printer->Indent();
377 printer->Print(
378 *vars,
379 "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
380 "Async$Method$Raw(context, response, cq, tag));\n");
381 printer->Outdent();
382 printer->Print("}\n");
383 } else if (ServerOnlyStreaming(method)) {
384 printer->Print(
385 *vars,
386 "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
387 " $Method$(::grpc::ClientContext* context, const $Request$& request)"
388 " {\n");
389 printer->Indent();
390 printer->Print(
391 *vars,
392 "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
393 "($Method$Raw(context, request));\n");
394 printer->Outdent();
395 printer->Print("}\n");
396 printer->Print(
397 *vars,
398 "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
399 "Async$Method$("
400 "::grpc::ClientContext* context, const $Request$& request, "
401 "::grpc::CompletionQueue* cq, void* tag) {\n");
402 printer->Indent();
403 printer->Print(
404 *vars,
405 "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
406 "Async$Method$Raw(context, request, cq, tag));\n");
407 printer->Outdent();
408 printer->Print("}\n");
409 } else if (BidiStreaming(method)) {
410 printer->Print(
411 *vars,
412 "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
413 " $Method$(::grpc::ClientContext* context) {\n");
414 printer->Indent();
Craig Tillerce40de52015-06-05 07:14:58 -0700415 printer->Print(*vars,
416 "return std::unique_ptr< "
417 "::grpc::ClientReaderWriter< $Request$, $Response$>>("
418 "$Method$Raw(context));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700419 printer->Outdent();
420 printer->Print("}\n");
Craig Tillerce40de52015-06-05 07:14:58 -0700421 printer->Print(*vars,
422 "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
423 "$Request$, $Response$>> "
424 "Async$Method$(::grpc::ClientContext* context, "
425 "::grpc::CompletionQueue* cq, void* tag) {\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700426 printer->Indent();
Craig Tillerce40de52015-06-05 07:14:58 -0700427 printer->Print(*vars,
428 "return std::unique_ptr< "
429 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
430 "Async$Method$Raw(context, cq, tag));\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700431 printer->Outdent();
432 printer->Print("}\n");
433 }
434 } else {
435 if (NoStreaming(method)) {
Craig Tillerce40de52015-06-05 07:14:58 -0700436 printer->Print(*vars,
437 "::grpc::ClientAsyncResponseReader< $Response$>* "
438 "Async$Method$Raw(::grpc::ClientContext* context, "
439 "const $Request$& request, "
440 "::grpc::CompletionQueue* cq) GRPC_OVERRIDE;\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700441 } else if (ClientOnlyStreaming(method)) {
Craig Tillerce40de52015-06-05 07:14:58 -0700442 printer->Print(*vars,
443 "::grpc::ClientWriter< $Request$>* $Method$Raw("
444 "::grpc::ClientContext* context, $Response$* response) "
445 "GRPC_OVERRIDE;\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700446 printer->Print(
447 *vars,
448 "::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
449 "::grpc::ClientContext* context, $Response$* response, "
450 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
451 } else if (ServerOnlyStreaming(method)) {
Craig Tillerce40de52015-06-05 07:14:58 -0700452 printer->Print(*vars,
453 "::grpc::ClientReader< $Response$>* $Method$Raw("
454 "::grpc::ClientContext* context, const $Request$& request)"
455 " GRPC_OVERRIDE;\n");
Yang Gaoc6924c82015-05-05 10:42:51 -0700456 printer->Print(
457 *vars,
458 "::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw("
459 "::grpc::ClientContext* context, const $Request$& request, "
460 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
461 } else if (BidiStreaming(method)) {
462 printer->Print(
463 *vars,
464 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
465 "$Method$Raw(::grpc::ClientContext* context) GRPC_OVERRIDE;\n");
466 printer->Print(
467 *vars,
468 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
469 "Async$Method$Raw(::grpc::ClientContext* context, "
470 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
471 }
nnobleebebb7e2014-12-10 16:31:01 -0800472 }
473}
474
Craig Tillerbd6c6182015-04-10 17:08:15 -0700475void PrintHeaderClientMethodData(grpc::protobuf::io::Printer *printer,
476 const grpc::protobuf::MethodDescriptor *method,
477 std::map<grpc::string, grpc::string> *vars) {
478 (*vars)["Method"] = method->name();
479 printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
480}
481
Craig Tiller277d3cf2015-04-14 14:04:51 -0700482void PrintHeaderServerMethodSync(grpc::protobuf::io::Printer *printer,
483 const grpc::protobuf::MethodDescriptor *method,
484 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800485 (*vars)["Method"] = method->name();
486 (*vars)["Request"] =
487 grpc_cpp_generator::ClassName(method->input_type(), true);
488 (*vars)["Response"] =
489 grpc_cpp_generator::ClassName(method->output_type(), true);
490 if (NoStreaming(method)) {
491 printer->Print(*vars,
yangga4b6f5d2014-12-17 15:53:12 -0800492 "virtual ::grpc::Status $Method$("
493 "::grpc::ServerContext* context, const $Request$* request, "
nnobleebebb7e2014-12-10 16:31:01 -0800494 "$Response$* response);\n");
495 } else if (ClientOnlyStreaming(method)) {
496 printer->Print(*vars,
497 "virtual ::grpc::Status $Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800498 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800499 "::grpc::ServerReader< $Request$>* reader, "
nnobleebebb7e2014-12-10 16:31:01 -0800500 "$Response$* response);\n");
501 } else if (ServerOnlyStreaming(method)) {
502 printer->Print(*vars,
yangga4b6f5d2014-12-17 15:53:12 -0800503 "virtual ::grpc::Status $Method$("
504 "::grpc::ServerContext* context, const $Request$* request, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800505 "::grpc::ServerWriter< $Response$>* writer);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800506 } else if (BidiStreaming(method)) {
Yang Gao5680ff42015-01-14 12:14:21 -0800507 printer->Print(
508 *vars,
509 "virtual ::grpc::Status $Method$("
510 "::grpc::ServerContext* context, "
511 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
512 "\n");
nnobleebebb7e2014-12-10 16:31:01 -0800513 }
514}
515
Craig Tiller5ef5db12015-02-09 12:47:21 -0800516void PrintHeaderServerMethodAsync(
Nicolas Nobled446eb82015-03-12 17:22:33 -0700517 grpc::protobuf::io::Printer *printer,
518 const grpc::protobuf::MethodDescriptor *method,
519 std::map<grpc::string, grpc::string> *vars) {
Craig Tiller2dff17d2015-02-09 12:42:23 -0800520 (*vars)["Method"] = method->name();
521 (*vars)["Request"] =
522 grpc_cpp_generator::ClassName(method->input_type(), true);
523 (*vars)["Response"] =
524 grpc_cpp_generator::ClassName(method->output_type(), true);
Craig Tiller15f383c2016-01-07 12:45:32 -0800525 printer->Print(*vars, "template <class BaseClass>\n");
526 printer->Print(*vars,
527 "class WithAsyncMethod_$Method$ : public BaseClass {\n");
528 printer->Print(
529 " private:\n"
530 " void BaseClassMustBeDerivedFromService(Service *service) {}\n");
531 printer->Print(" public:\n");
532 printer->Indent();
533 printer->Print(*vars,
yang-gbef0d872016-01-13 15:27:33 -0800534 "WithAsyncMethod_$Method$() {\n"
yang-g0bbc87f2016-01-15 09:22:50 -0800535 " ::grpc::Service::MarkMethodAsync($Idx$);\n"
yang-gbef0d872016-01-13 15:27:33 -0800536 "}\n");
537 printer->Print(*vars,
538 "~WithAsyncMethod_$Method$() GRPC_OVERRIDE {\n"
Craig Tiller15f383c2016-01-07 12:45:32 -0800539 " BaseClassMustBeDerivedFromService(this);\n"
540 "}\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800541 if (NoStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700542 printer->Print(
543 *vars,
Craig Tiller15f383c2016-01-07 12:45:32 -0800544 "// disable synchronous version of this method\n"
545 "::grpc::Status $Method$("
546 "::grpc::ServerContext* context, const $Request$* request, "
547 "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
548 " abort();\n"
549 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
550 "}\n");
551 printer->Print(
552 *vars,
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700553 "void Request$Method$("
554 "::grpc::ServerContext* context, $Request$* request, "
555 "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
556 "::grpc::CompletionQueue* new_call_cq, "
Craig Tiller15f383c2016-01-07 12:45:32 -0800557 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
558 printer->Print(*vars,
559 " ::grpc::Service::RequestAsyncUnary($Idx$, context, "
560 "request, response, new_call_cq, notification_cq, tag);\n");
561 printer->Print("}\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800562 } else if (ClientOnlyStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700563 printer->Print(
564 *vars,
Craig Tiller15f383c2016-01-07 12:45:32 -0800565 "// disable synchronous version of this method\n"
566 "::grpc::Status $Method$("
567 "::grpc::ServerContext* context, "
568 "::grpc::ServerReader< $Request$>* reader, "
569 "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
570 " abort();\n"
571 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
572 "}\n");
573 printer->Print(
574 *vars,
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700575 "void Request$Method$("
576 "::grpc::ServerContext* context, "
577 "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
578 "::grpc::CompletionQueue* new_call_cq, "
Craig Tiller15f383c2016-01-07 12:45:32 -0800579 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
580 printer->Print(*vars,
581 " ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
582 "context, reader, new_call_cq, notification_cq, tag);\n");
583 printer->Print("}\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800584 } else if (ServerOnlyStreaming(method)) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700585 printer->Print(
586 *vars,
Craig Tiller15f383c2016-01-07 12:45:32 -0800587 "// disable synchronous version of this method\n"
588 "::grpc::Status $Method$("
589 "::grpc::ServerContext* context, const $Request$* request, "
590 "::grpc::ServerWriter< $Response$>* writer) GRPC_FINAL GRPC_OVERRIDE "
591 "{\n"
592 " abort();\n"
593 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
594 "}\n");
595 printer->Print(
596 *vars,
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700597 "void Request$Method$("
598 "::grpc::ServerContext* context, $Request$* request, "
599 "::grpc::ServerAsyncWriter< $Response$>* writer, "
600 "::grpc::CompletionQueue* new_call_cq, "
Craig Tiller15f383c2016-01-07 12:45:32 -0800601 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
602 printer->Print(
603 *vars,
604 " ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
605 "context, request, writer, new_call_cq, notification_cq, tag);\n");
606 printer->Print("}\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800607 } else if (BidiStreaming(method)) {
608 printer->Print(
609 *vars,
Craig Tiller15f383c2016-01-07 12:45:32 -0800610 "// disable synchronous version of this method\n"
611 "::grpc::Status $Method$("
612 "::grpc::ServerContext* context, "
613 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
614 "GRPC_FINAL GRPC_OVERRIDE {\n"
615 " abort();\n"
616 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
617 "}\n");
618 printer->Print(
619 *vars,
Yang Gaoca3cb3e2015-02-12 00:05:11 -0800620 "void Request$Method$("
Craig Tiller2dff17d2015-02-09 12:42:23 -0800621 "::grpc::ServerContext* context, "
Craig Tiller225f7be2015-02-09 22:32:37 -0800622 "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700623 "::grpc::CompletionQueue* new_call_cq, "
Craig Tiller15f383c2016-01-07 12:45:32 -0800624 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
625 printer->Print(*vars,
626 " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
627 "context, stream, new_call_cq, notification_cq, tag);\n");
628 printer->Print("}\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800629 }
Craig Tiller15f383c2016-01-07 12:45:32 -0800630 printer->Outdent();
631 printer->Print(*vars, "};\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800632}
633
yang-g0bbc87f2016-01-15 09:22:50 -0800634void PrintHeaderServerMethodGeneric(
635 grpc::protobuf::io::Printer *printer,
636 const grpc::protobuf::MethodDescriptor *method,
637 std::map<grpc::string, grpc::string> *vars) {
638 (*vars)["Method"] = method->name();
639 (*vars)["Request"] =
640 grpc_cpp_generator::ClassName(method->input_type(), true);
641 (*vars)["Response"] =
642 grpc_cpp_generator::ClassName(method->output_type(), true);
643 printer->Print(*vars, "template <class BaseClass>\n");
644 printer->Print(*vars,
645 "class WithGenericMethod_$Method$ : public BaseClass {\n");
646 printer->Print(
647 " private:\n"
648 " void BaseClassMustBeDerivedFromService(Service *service) {}\n");
649 printer->Print(" public:\n");
650 printer->Indent();
651 printer->Print(*vars,
652 "WithGenericMethod_$Method$() {\n"
653 " ::grpc::Service::MarkMethodGeneric($Idx$);\n"
654 "}\n");
655 printer->Print(*vars,
656 "~WithGenericMethod_$Method$() GRPC_OVERRIDE {\n"
657 " BaseClassMustBeDerivedFromService(this);\n"
658 "}\n");
659 if (NoStreaming(method)) {
660 printer->Print(
661 *vars,
662 "// disable synchronous version of this method\n"
663 "::grpc::Status $Method$("
664 "::grpc::ServerContext* context, const $Request$* request, "
665 "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
666 " abort();\n"
667 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
668 "}\n");
669 } else if (ClientOnlyStreaming(method)) {
670 printer->Print(
671 *vars,
672 "// disable synchronous version of this method\n"
673 "::grpc::Status $Method$("
674 "::grpc::ServerContext* context, "
675 "::grpc::ServerReader< $Request$>* reader, "
676 "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
677 " abort();\n"
678 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
679 "}\n");
680 } else if (ServerOnlyStreaming(method)) {
681 printer->Print(
682 *vars,
683 "// disable synchronous version of this method\n"
684 "::grpc::Status $Method$("
685 "::grpc::ServerContext* context, const $Request$* request, "
686 "::grpc::ServerWriter< $Response$>* writer) GRPC_FINAL GRPC_OVERRIDE "
687 "{\n"
688 " abort();\n"
689 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
690 "}\n");
691 } else if (BidiStreaming(method)) {
692 printer->Print(
693 *vars,
694 "// disable synchronous version of this method\n"
695 "::grpc::Status $Method$("
696 "::grpc::ServerContext* context, "
697 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
698 "GRPC_FINAL GRPC_OVERRIDE {\n"
699 " abort();\n"
700 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
701 "}\n");
702 }
703 printer->Outdent();
704 printer->Print(*vars, "};\n");
nnobleebebb7e2014-12-10 16:31:01 -0800705}
706
Nicolas Nobled446eb82015-03-12 17:22:33 -0700707void PrintHeaderService(grpc::protobuf::io::Printer *printer,
708 const grpc::protobuf::ServiceDescriptor *service,
709 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800710 (*vars)["Service"] = service->name();
711
712 printer->Print(*vars,
Craig Tillercf133f42015-02-26 14:05:56 -0800713 "class $Service$ GRPC_FINAL {\n"
nnobleebebb7e2014-12-10 16:31:01 -0800714 " public:\n");
715 printer->Indent();
716
717 // Client side
Craig Tillerb5dcec52015-01-13 11:13:42 -0800718 printer->Print(
Yang Gao72e0fb82015-05-01 16:24:07 -0700719 "class StubInterface {\n"
Craig Tillerb5dcec52015-01-13 11:13:42 -0800720 " public:\n");
nnobleebebb7e2014-12-10 16:31:01 -0800721 printer->Indent();
Yang Gao72e0fb82015-05-01 16:24:07 -0700722 printer->Print("virtual ~StubInterface() {}\n");
723 for (int i = 0; i < service->method_count(); ++i) {
Yang Gaoc6924c82015-05-05 10:42:51 -0700724 PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, true);
725 }
726 printer->Outdent();
727 printer->Print("private:\n");
728 printer->Indent();
729 for (int i = 0; i < service->method_count(); ++i) {
730 PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, false);
Yang Gao72e0fb82015-05-01 16:24:07 -0700731 }
732 printer->Outdent();
733 printer->Print("};\n");
734 printer->Print(
yang-gef003082015-08-20 11:40:51 -0700735 "class Stub GRPC_FINAL : public StubInterface"
736 " {\n public:\n");
Yang Gao72e0fb82015-05-01 16:24:07 -0700737 printer->Indent();
David Garcia Quintase50c6c22016-01-13 16:02:00 -0800738 printer->Print("Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800739 for (int i = 0; i < service->method_count(); ++i) {
Yang Gaoc6924c82015-05-05 10:42:51 -0700740 PrintHeaderClientMethod(printer, service->method(i), vars, true);
nnobleebebb7e2014-12-10 16:31:01 -0800741 }
742 printer->Outdent();
Yang Gaoc6924c82015-05-05 10:42:51 -0700743 printer->Print("\n private:\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -0700744 printer->Indent();
David Garcia Quintase50c6c22016-01-13 16:02:00 -0800745 printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -0700746 for (int i = 0; i < service->method_count(); ++i) {
Yang Gaoc6924c82015-05-05 10:42:51 -0700747 PrintHeaderClientMethod(printer, service->method(i), vars, false);
748 }
749 for (int i = 0; i < service->method_count(); ++i) {
Craig Tillerbd6c6182015-04-10 17:08:15 -0700750 PrintHeaderClientMethodData(printer, service->method(i), vars);
751 }
752 printer->Outdent();
nnobleebebb7e2014-12-10 16:31:01 -0800753 printer->Print("};\n");
754 printer->Print(
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800755 "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
David Garcia Quintase50c6c22016-01-13 16:02:00 -0800756 "::grpc::ChannelInterface>& channel, "
yang-g297a25b2015-08-03 16:43:46 -0700757 "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
nnobleebebb7e2014-12-10 16:31:01 -0800758
759 printer->Print("\n");
760
Craig Tiller15f383c2016-01-07 12:45:32 -0800761 // Server side - base
Craig Tillerb5dcec52015-01-13 11:13:42 -0800762 printer->Print(
Craig Tiller15f383c2016-01-07 12:45:32 -0800763 "class Service : public ::grpc::Service {\n"
Craig Tillerb5dcec52015-01-13 11:13:42 -0800764 " public:\n");
nnobleebebb7e2014-12-10 16:31:01 -0800765 printer->Indent();
Vijay Pai7f715702015-10-12 22:47:58 +0000766 printer->Print("Service();\n");
nnobleebebb7e2014-12-10 16:31:01 -0800767 printer->Print("virtual ~Service();\n");
768 for (int i = 0; i < service->method_count(); ++i) {
Craig Tiller2dff17d2015-02-09 12:42:23 -0800769 PrintHeaderServerMethodSync(printer, service->method(i), vars);
770 }
Craig Tiller2dff17d2015-02-09 12:42:23 -0800771 printer->Outdent();
Craig Tiller2dff17d2015-02-09 12:42:23 -0800772 printer->Print("};\n");
773
774 // Server side - Asynchronous
Craig Tiller2dff17d2015-02-09 12:42:23 -0800775 for (int i = 0; i < service->method_count(); ++i) {
Craig Tiller15f383c2016-01-07 12:45:32 -0800776 (*vars)["Idx"] = as_string(i);
Craig Tiller2dff17d2015-02-09 12:42:23 -0800777 PrintHeaderServerMethodAsync(printer, service->method(i), vars);
nnobleebebb7e2014-12-10 16:31:01 -0800778 }
Craig Tiller15f383c2016-01-07 12:45:32 -0800779
780 printer->Print("typedef ");
781
782 for (int i = 0; i < service->method_count(); ++i) {
783 (*vars)["method_name"] = service->method(i)->name();
784 printer->Print(*vars, "WithAsyncMethod_$method_name$<");
785 }
786 printer->Print("Service");
787 for (int i = 0; i < service->method_count(); ++i) {
788 printer->Print(" >");
789 }
790 printer->Print(" AsyncService;\n");
nnobleebebb7e2014-12-10 16:31:01 -0800791
yang-g0bbc87f2016-01-15 09:22:50 -0800792 // Server side - Generic
793 for (int i = 0; i < service->method_count(); ++i) {
794 (*vars)["Idx"] = as_string(i);
795 PrintHeaderServerMethodGeneric(printer, service->method(i), vars);
796 }
nnobleebebb7e2014-12-10 16:31:01 -0800797
798 printer->Outdent();
799 printer->Print("};\n");
800}
801
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100802grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
803 const Parameters &params) {
Nicolas Nobled446eb82015-03-12 17:22:33 -0700804 grpc::string output;
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700805 {
Craig Tillerce40de52015-06-05 07:14:58 -0700806 // Scope the output stream so it closes and finalizes output to the string.
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700807 grpc::protobuf::io::StringOutputStream output_stream(&output);
808 grpc::protobuf::io::Printer printer(&output_stream, '$');
809 std::map<grpc::string, grpc::string> vars;
yang-gbef0d872016-01-13 15:27:33 -0800810 // Package string is empty or ends with a dot. It is used to fully qualify
811 // method names.
812 vars["Package"] = file->package();
813 if (!file->package().empty()) {
814 vars["Package"].append(".");
815 }
nnobleebebb7e2014-12-10 16:31:01 -0800816
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700817 if (!params.services_namespace.empty()) {
818 vars["services_namespace"] = params.services_namespace;
819 printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
820 }
821
822 for (int i = 0; i < file->service_count(); ++i) {
823 PrintHeaderService(&printer, file->service(i), &vars);
824 printer.Print("\n");
825 }
826
827 if (!params.services_namespace.empty()) {
828 printer.Print(vars, "} // namespace $services_namespace$\n\n");
829 }
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100830 }
nnobleebebb7e2014-12-10 16:31:01 -0800831 return output;
832}
833
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200834grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
835 const Parameters &params) {
836 grpc::string output;
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700837 {
838 // Scope the output stream so it closes and finalizes output to the string.
839 grpc::protobuf::io::StringOutputStream output_stream(&output);
840 grpc::protobuf::io::Printer printer(&output_stream, '$');
841 std::map<grpc::string, grpc::string> vars;
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200842
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700843 vars["filename"] = file->name();
844 vars["filename_identifier"] = FilenameIdentifier(file->name());
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200845
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700846 if (!file->package().empty()) {
847 std::vector<grpc::string> parts =
848 grpc_generator::tokenize(file->package(), ".");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200849
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700850 for (auto part = parts.rbegin(); part != parts.rend(); part++) {
851 vars["part"] = *part;
852 printer.Print(vars, "} // namespace $part$\n");
853 }
854 printer.Print(vars, "\n");
Yang Gao1dc1a432015-04-10 13:53:11 -0700855 }
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700856
Yang Gao1dc1a432015-04-10 13:53:11 -0700857 printer.Print(vars, "\n");
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700858 printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200859 }
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200860 return output;
861}
862
863grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
864 const Parameters &params) {
865 grpc::string output;
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700866 {
867 // Scope the output stream so it closes and finalizes output to the string.
868 grpc::protobuf::io::StringOutputStream output_stream(&output);
869 grpc::protobuf::io::Printer printer(&output_stream, '$');
870 std::map<grpc::string, grpc::string> vars;
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200871
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700872 vars["filename"] = file->name();
873 vars["filename_base"] = grpc_generator::StripProto(file->name());
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200874
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700875 printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
Craig Tillerce40de52015-06-05 07:14:58 -0700876 printer.Print(vars,
877 "// If you make any local change, they will be lost.\n");
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700878 printer.Print(vars, "// source: $filename$\n\n");
879 printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
880 printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
881 printer.Print(vars, "\n");
882 }
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200883 return output;
884}
885
886grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
Nicolas "Pixel" Noble931bdce2016-01-12 03:08:11 +0100887 const Parameters &params) {
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200888 grpc::string output;
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700889 {
890 // Scope the output stream so it closes and finalizes output to the string.
891 grpc::protobuf::io::StringOutputStream output_stream(&output);
892 grpc::protobuf::io::Printer printer(&output_stream, '$');
893 std::map<grpc::string, grpc::string> vars;
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200894
Nicolas "Pixel" Noble1ba1f632016-03-17 19:57:54 +0100895 static const char *headers_strs[] = {
896 "grpc++/impl/codegen/async_stream.h",
897 "grpc++/impl/codegen/async_unary_call.h",
898 "grpc++/impl/codegen/channel_interface.h",
899 "grpc++/impl/codegen/client_unary_call.h",
900 "grpc++/impl/codegen/method_handler_impl.h",
901 "grpc++/impl/codegen/rpc_service_method.h",
902 "grpc++/impl/codegen/service_type.h",
903 "grpc++/impl/codegen/sync_stream.h"
904 };
905 std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
906 PrintIncludes(&printer, headers, params);
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200907
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700908 if (!file->package().empty()) {
909 std::vector<grpc::string> parts =
910 grpc_generator::tokenize(file->package(), ".");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200911
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700912 for (auto part = parts.begin(); part != parts.end(); part++) {
913 vars["part"] = *part;
914 printer.Print(vars, "namespace $part$ {\n");
915 }
Yang Gao1dc1a432015-04-10 13:53:11 -0700916 }
Jan Tattermusch5dcebd92015-05-27 15:30:59 -0700917
918 printer.Print(vars, "\n");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200919 }
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +0200920 return output;
921}
922
Nicolas Nobled446eb82015-03-12 17:22:33 -0700923void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
924 const grpc::protobuf::MethodDescriptor *method,
925 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800926 (*vars)["Method"] = method->name();
927 (*vars)["Request"] =
928 grpc_cpp_generator::ClassName(method->input_type(), true);
929 (*vars)["Response"] =
930 grpc_cpp_generator::ClassName(method->output_type(), true);
931 if (NoStreaming(method)) {
932 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +0100933 "::grpc::Status $ns$$Service$::Stub::$Method$("
nnobleebebb7e2014-12-10 16:31:01 -0800934 "::grpc::ClientContext* context, "
935 "const $Request$& request, $Response$* response) {\n");
936 printer->Print(*vars,
yang-gef003082015-08-20 11:40:51 -0700937 " return ::grpc::BlockingUnaryCall(channel_.get(), "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700938 "rpcmethod_$Method$_, "
nnobleebebb7e2014-12-10 16:31:01 -0800939 "context, request, response);\n"
940 "}\n\n");
Yang Gao5680ff42015-01-14 12:14:21 -0800941 printer->Print(
942 *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700943 "::grpc::ClientAsyncResponseReader< $Response$>* "
944 "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800945 "const $Request$& request, "
Craig Tiller3676b382015-05-06 13:01:05 -0700946 "::grpc::CompletionQueue* cq) {\n");
yangg5bcea0d2015-01-06 10:35:03 -0800947 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700948 " return new "
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800949 "::grpc::ClientAsyncResponseReader< $Response$>("
yang-gef003082015-08-20 11:40:51 -0700950 "channel_.get(), cq, "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700951 "rpcmethod_$Method$_, "
Craig Tiller5f871ac2015-05-08 13:05:51 -0700952 "context, request);\n"
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800953 "}\n\n");
954 } else if (ClientOnlyStreaming(method)) {
955 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700956 "::grpc::ClientWriter< $Request$>* "
957 "$ns$$Service$::Stub::$Method$Raw("
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800958 "::grpc::ClientContext* context, $Response$* response) {\n");
959 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700960 " return new ::grpc::ClientWriter< $Request$>("
yang-gef003082015-08-20 11:40:51 -0700961 "channel_.get(), "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700962 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700963 "context, response);\n"
yangg5bcea0d2015-01-06 10:35:03 -0800964 "}\n\n");
Yang Gao068c85b2015-02-12 15:21:24 -0800965 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700966 "::grpc::ClientAsyncWriter< $Request$>* "
967 "$ns$$Service$::Stub::Async$Method$Raw("
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800968 "::grpc::ClientContext* context, $Response$* response, "
969 "::grpc::CompletionQueue* cq, void* tag) {\n");
970 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700971 " return new ::grpc::ClientAsyncWriter< $Request$>("
yang-gef003082015-08-20 11:40:51 -0700972 "channel_.get(), cq, "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700973 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700974 "context, response, tag);\n"
Yang Gao068c85b2015-02-12 15:21:24 -0800975 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800976 } else if (ServerOnlyStreaming(method)) {
977 printer->Print(
978 *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700979 "::grpc::ClientReader< $Response$>* "
980 "$ns$$Service$::Stub::$Method$Raw("
Yang Gao07d83042015-02-13 14:11:31 -0800981 "::grpc::ClientContext* context, const $Request$& request) {\n");
yangg5bcea0d2015-01-06 10:35:03 -0800982 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700983 " return new ::grpc::ClientReader< $Response$>("
yang-gef003082015-08-20 11:40:51 -0700984 "channel_.get(), "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700985 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700986 "context, request);\n"
yangg5bcea0d2015-01-06 10:35:03 -0800987 "}\n\n");
Yang Gao068c85b2015-02-12 15:21:24 -0800988 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700989 "::grpc::ClientAsyncReader< $Response$>* "
990 "$ns$$Service$::Stub::Async$Method$Raw("
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800991 "::grpc::ClientContext* context, const $Request$& request, "
992 "::grpc::CompletionQueue* cq, void* tag) {\n");
993 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -0700994 " return new ::grpc::ClientAsyncReader< $Response$>("
yang-gef003082015-08-20 11:40:51 -0700995 "channel_.get(), cq, "
Craig Tillerbd6c6182015-04-10 17:08:15 -0700996 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -0700997 "context, request, tag);\n"
Yang Gao068c85b2015-02-12 15:21:24 -0800998 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800999 } else if (BidiStreaming(method)) {
1000 printer->Print(
1001 *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -07001002 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
1003 "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
Craig Tillerfd1b49b2015-02-23 12:53:39 -08001004 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -07001005 " return new ::grpc::ClientReaderWriter< "
Craig Tillerfd1b49b2015-02-23 12:53:39 -08001006 "$Request$, $Response$>("
yang-gef003082015-08-20 11:40:51 -07001007 "channel_.get(), "
Craig Tillerbd6c6182015-04-10 17:08:15 -07001008 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -07001009 "context);\n"
Craig Tillerfd1b49b2015-02-23 12:53:39 -08001010 "}\n\n");
Craig Tiller277d3cf2015-04-14 14:04:51 -07001011 printer->Print(
1012 *vars,
Yang Gaoc6924c82015-05-05 10:42:51 -07001013 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
1014 "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
Craig Tiller277d3cf2015-04-14 14:04:51 -07001015 "::grpc::CompletionQueue* cq, void* tag) {\n");
Craig Tillerfd1b49b2015-02-23 12:53:39 -08001016 printer->Print(*vars,
Yang Gaoc6924c82015-05-05 10:42:51 -07001017 " return new "
Craig Tillerfd1b49b2015-02-23 12:53:39 -08001018 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
yang-gef003082015-08-20 11:40:51 -07001019 "channel_.get(), cq, "
Craig Tillerbd6c6182015-04-10 17:08:15 -07001020 "rpcmethod_$Method$_, "
Yang Gaoc6924c82015-05-05 10:42:51 -07001021 "context, tag);\n"
Craig Tillerfd1b49b2015-02-23 12:53:39 -08001022 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -08001023 }
1024}
1025
Nicolas Nobled446eb82015-03-12 17:22:33 -07001026void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
1027 const grpc::protobuf::MethodDescriptor *method,
1028 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -08001029 (*vars)["Method"] = method->name();
1030 (*vars)["Request"] =
1031 grpc_cpp_generator::ClassName(method->input_type(), true);
1032 (*vars)["Response"] =
1033 grpc_cpp_generator::ClassName(method->output_type(), true);
1034 if (NoStreaming(method)) {
1035 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001036 "::grpc::Status $ns$$Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -08001037 "::grpc::ServerContext* context, "
nnobleebebb7e2014-12-10 16:31:01 -08001038 "const $Request$* request, $Response$* response) {\n");
Nicolas "Pixel" Nobleb14fbf72015-06-10 23:49:23 +02001039 printer->Print(" (void) context;\n");
1040 printer->Print(" (void) request;\n");
1041 printer->Print(" (void) response;\n");
nnobleebebb7e2014-12-10 16:31:01 -08001042 printer->Print(
1043 " return ::grpc::Status("
Yang Gaoc1a2c312015-06-16 10:59:46 -07001044 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
nnobleebebb7e2014-12-10 16:31:01 -08001045 printer->Print("}\n\n");
1046 } else if (ClientOnlyStreaming(method)) {
1047 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001048 "::grpc::Status $ns$$Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -08001049 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -08001050 "::grpc::ServerReader< $Request$>* reader, "
nnobleebebb7e2014-12-10 16:31:01 -08001051 "$Response$* response) {\n");
Nicolas "Pixel" Nobleb14fbf72015-06-10 23:49:23 +02001052 printer->Print(" (void) context;\n");
1053 printer->Print(" (void) reader;\n");
1054 printer->Print(" (void) response;\n");
nnobleebebb7e2014-12-10 16:31:01 -08001055 printer->Print(
1056 " return ::grpc::Status("
Yang Gaoc1a2c312015-06-16 10:59:46 -07001057 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
nnobleebebb7e2014-12-10 16:31:01 -08001058 printer->Print("}\n\n");
1059 } else if (ServerOnlyStreaming(method)) {
1060 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001061 "::grpc::Status $ns$$Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -08001062 "::grpc::ServerContext* context, "
nnobleebebb7e2014-12-10 16:31:01 -08001063 "const $Request$* request, "
Yang Gao1ff11f62015-01-14 11:45:32 -08001064 "::grpc::ServerWriter< $Response$>* writer) {\n");
Nicolas "Pixel" Nobleb14fbf72015-06-10 23:49:23 +02001065 printer->Print(" (void) context;\n");
1066 printer->Print(" (void) request;\n");
1067 printer->Print(" (void) writer;\n");
nnobleebebb7e2014-12-10 16:31:01 -08001068 printer->Print(
1069 " return ::grpc::Status("
Yang Gaoc1a2c312015-06-16 10:59:46 -07001070 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
nnobleebebb7e2014-12-10 16:31:01 -08001071 printer->Print("}\n\n");
1072 } else if (BidiStreaming(method)) {
1073 printer->Print(*vars,
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001074 "::grpc::Status $ns$$Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -08001075 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -08001076 "::grpc::ServerReaderWriter< $Response$, $Request$>* "
nnobleebebb7e2014-12-10 16:31:01 -08001077 "stream) {\n");
Nicolas "Pixel" Nobleb14fbf72015-06-10 23:49:23 +02001078 printer->Print(" (void) context;\n");
1079 printer->Print(" (void) stream;\n");
nnobleebebb7e2014-12-10 16:31:01 -08001080 printer->Print(
1081 " return ::grpc::Status("
Yang Gaoc1a2c312015-06-16 10:59:46 -07001082 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
nnobleebebb7e2014-12-10 16:31:01 -08001083 printer->Print("}\n\n");
1084 }
1085}
1086
Nicolas Nobled446eb82015-03-12 17:22:33 -07001087void PrintSourceService(grpc::protobuf::io::Printer *printer,
1088 const grpc::protobuf::ServiceDescriptor *service,
1089 std::map<grpc::string, grpc::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -08001090 (*vars)["Service"] = service->name();
Craig Tiller8c8d0aa2015-02-12 11:38:36 -08001091
Craig Tiller277d3cf2015-04-14 14:04:51 -07001092 printer->Print(*vars,
1093 "static const char* $prefix$$Service$_method_names[] = {\n");
Craig Tiller8c8d0aa2015-02-12 11:38:36 -08001094 for (int i = 0; i < service->method_count(); ++i) {
1095 (*vars)["Method"] = service->method(i)->name();
1096 printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
1097 }
1098 printer->Print(*vars, "};\n\n");
1099
yang-g8c2be9f2015-08-19 16:28:09 -07001100 printer->Print(*vars,
1101 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
David Garcia Quintase50c6c22016-01-13 16:02:00 -08001102 "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
yang-g8c2be9f2015-08-19 16:28:09 -07001103 "const ::grpc::StubOptions& options) {\n"
1104 " std::unique_ptr< $ns$$Service$::Stub> stub(new "
1105 "$ns$$Service$::Stub(channel));\n"
1106 " return stub;\n"
1107 "}\n\n");
Craig Tiller277d3cf2015-04-14 14:04:51 -07001108 printer->Print(*vars,
1109 "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
David Garcia Quintase50c6c22016-01-13 16:02:00 -08001110 "::grpc::ChannelInterface>& channel)\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -07001111 printer->Indent();
yang-gef003082015-08-20 11:40:51 -07001112 printer->Print(": channel_(channel)");
Craig Tillerbd6c6182015-04-10 17:08:15 -07001113 for (int i = 0; i < service->method_count(); ++i) {
1114 const grpc::protobuf::MethodDescriptor *method = service->method(i);
Craig Tillerbd6c6182015-04-10 17:08:15 -07001115 (*vars)["Method"] = method->name();
1116 (*vars)["Idx"] = as_string(i);
1117 if (NoStreaming(method)) {
1118 (*vars)["StreamingType"] = "NORMAL_RPC";
1119 } else if (ClientOnlyStreaming(method)) {
1120 (*vars)["StreamingType"] = "CLIENT_STREAMING";
1121 } else if (ServerOnlyStreaming(method)) {
1122 (*vars)["StreamingType"] = "SERVER_STREAMING";
1123 } else {
1124 (*vars)["StreamingType"] = "BIDI_STREAMING";
1125 }
yang-g431f8c22015-08-20 10:59:29 -07001126 printer->Print(*vars,
1127 ", rpcmethod_$Method$_("
1128 "$prefix$$Service$_method_names[$Idx$], "
1129 "::grpc::RpcMethod::$StreamingType$, "
1130 "channel"
1131 ")\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -07001132 }
Craig Tiller3beef682015-04-14 13:55:03 -07001133 printer->Print("{}\n\n");
Craig Tillerbd6c6182015-04-10 17:08:15 -07001134 printer->Outdent();
1135
nnobleebebb7e2014-12-10 16:31:01 -08001136 for (int i = 0; i < service->method_count(); ++i) {
Craig Tiller8c8d0aa2015-02-12 11:38:36 -08001137 (*vars)["Idx"] = as_string(i);
nnobleebebb7e2014-12-10 16:31:01 -08001138 PrintSourceClientMethod(printer, service->method(i), vars);
1139 }
1140
yang-gbef0d872016-01-13 15:27:33 -08001141 printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
nnobleebebb7e2014-12-10 16:31:01 -08001142 printer->Indent();
yang-ge39cb742016-02-10 23:50:08 -08001143 printer->Print(*vars, "(void)$prefix$$Service$_method_names;\n");
nnobleebebb7e2014-12-10 16:31:01 -08001144 for (int i = 0; i < service->method_count(); ++i) {
Nicolas Nobled446eb82015-03-12 17:22:33 -07001145 const grpc::protobuf::MethodDescriptor *method = service->method(i);
Craig Tiller8c8d0aa2015-02-12 11:38:36 -08001146 (*vars)["Idx"] = as_string(i);
nnobleebebb7e2014-12-10 16:31:01 -08001147 (*vars)["Method"] = method->name();
1148 (*vars)["Request"] =
1149 grpc_cpp_generator::ClassName(method->input_type(), true);
1150 (*vars)["Response"] =
1151 grpc_cpp_generator::ClassName(method->output_type(), true);
1152 if (NoStreaming(method)) {
1153 printer->Print(
1154 *vars,
yang-gbef0d872016-01-13 15:27:33 -08001155 "AddMethod(new ::grpc::RpcServiceMethod(\n"
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001156 " $prefix$$Service$_method_names[$Idx$],\n"
yangg5bcea0d2015-01-06 10:35:03 -08001157 " ::grpc::RpcMethod::NORMAL_RPC,\n"
Craig Tiller277d3cf2015-04-14 14:04:51 -07001158 " new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
1159 "$Request$, "
nnobleebebb7e2014-12-10 16:31:01 -08001160 "$Response$>(\n"
Craig Tiller50a7a682015-06-04 12:53:40 -07001161 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
nnobleebebb7e2014-12-10 16:31:01 -08001162 } else if (ClientOnlyStreaming(method)) {
1163 printer->Print(
1164 *vars,
yang-gbef0d872016-01-13 15:27:33 -08001165 "AddMethod(new ::grpc::RpcServiceMethod(\n"
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001166 " $prefix$$Service$_method_names[$Idx$],\n"
yangg5bcea0d2015-01-06 10:35:03 -08001167 " ::grpc::RpcMethod::CLIENT_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -08001168 " new ::grpc::ClientStreamingHandler< "
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001169 "$ns$$Service$::Service, $Request$, $Response$>(\n"
Craig Tiller50a7a682015-06-04 12:53:40 -07001170 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
nnobleebebb7e2014-12-10 16:31:01 -08001171 } else if (ServerOnlyStreaming(method)) {
1172 printer->Print(
1173 *vars,
yang-gbef0d872016-01-13 15:27:33 -08001174 "AddMethod(new ::grpc::RpcServiceMethod(\n"
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001175 " $prefix$$Service$_method_names[$Idx$],\n"
yangg5bcea0d2015-01-06 10:35:03 -08001176 " ::grpc::RpcMethod::SERVER_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -08001177 " new ::grpc::ServerStreamingHandler< "
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001178 "$ns$$Service$::Service, $Request$, $Response$>(\n"
Craig Tiller50a7a682015-06-04 12:53:40 -07001179 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
nnobleebebb7e2014-12-10 16:31:01 -08001180 } else if (BidiStreaming(method)) {
1181 printer->Print(
1182 *vars,
yang-gbef0d872016-01-13 15:27:33 -08001183 "AddMethod(new ::grpc::RpcServiceMethod(\n"
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001184 " $prefix$$Service$_method_names[$Idx$],\n"
yangg5bcea0d2015-01-06 10:35:03 -08001185 " ::grpc::RpcMethod::BIDI_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -08001186 " new ::grpc::BidiStreamingHandler< "
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001187 "$ns$$Service$::Service, $Request$, $Response$>(\n"
Craig Tiller50a7a682015-06-04 12:53:40 -07001188 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
nnobleebebb7e2014-12-10 16:31:01 -08001189 }
1190 }
nnobleebebb7e2014-12-10 16:31:01 -08001191 printer->Outdent();
yang-gbef0d872016-01-13 15:27:33 -08001192 printer->Print(*vars, "}\n\n");
1193 printer->Print(*vars,
1194 "$ns$$Service$::Service::~Service() {\n"
1195 "}\n\n");
1196 for (int i = 0; i < service->method_count(); ++i) {
1197 (*vars)["Idx"] = as_string(i);
1198 PrintSourceServerMethod(printer, service->method(i), vars);
1199 }
nnobleebebb7e2014-12-10 16:31:01 -08001200}
1201
Nicolas "Pixel" Noble375a82b2015-03-24 02:33:18 +01001202grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
1203 const Parameters &params) {
Nicolas Nobled446eb82015-03-12 17:22:33 -07001204 grpc::string output;
Jan Tattermusch5dcebd92015-05-27 15:30:59 -07001205 {
1206 // Scope the output stream so it closes and finalizes output to the string.
1207 grpc::protobuf::io::StringOutputStream output_stream(&output);
1208 grpc::protobuf::io::Printer printer(&output_stream, '$');
1209 std::map<grpc::string, grpc::string> vars;
1210 // Package string is empty or ends with a dot. It is used to fully qualify
1211 // method names.
1212 vars["Package"] = file->package();
1213 if (!file->package().empty()) {
1214 vars["Package"].append(".");
1215 }
1216 if (!params.services_namespace.empty()) {
1217 vars["ns"] = params.services_namespace + "::";
1218 vars["prefix"] = params.services_namespace;
1219 } else {
1220 vars["ns"] = "";
1221 vars["prefix"] = "";
1222 }
nnobleebebb7e2014-12-10 16:31:01 -08001223
Jan Tattermusch5dcebd92015-05-27 15:30:59 -07001224 for (int i = 0; i < file->service_count(); ++i) {
1225 PrintSourceService(&printer, file->service(i), &vars);
1226 printer.Print("\n");
1227 }
nnobleebebb7e2014-12-10 16:31:01 -08001228 }
1229 return output;
1230}
1231
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +02001232grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
1233 const Parameters &params) {
1234 grpc::string temp;
1235
Yang Gao1dc1a432015-04-10 13:53:11 -07001236 if (!file->package().empty()) {
1237 std::vector<grpc::string> parts =
1238 grpc_generator::tokenize(file->package(), ".");
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +02001239
Yang Gao1dc1a432015-04-10 13:53:11 -07001240 for (auto part = parts.begin(); part != parts.end(); part++) {
1241 temp.append("} // namespace ");
1242 temp.append(*part);
1243 temp.append("\n");
1244 }
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +02001245 temp.append("\n");
1246 }
1247
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +02001248 return temp;
1249}
1250
Craig Tiller190d3602015-02-18 09:23:38 -08001251} // namespace grpc_cpp_generator