blob: ecae429af50d14fa9bd7f37a1cb0c73a6aa49392 [file] [log] [blame]
nnobleebebb7e2014-12-10 16:31:01 -08001/*
2 *
3 * Copyright 2014, Google Inc.
4 * 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 <string>
35#include <map>
36
nnobleebebb7e2014-12-10 16:31:01 -080037#include "src/compiler/cpp_generator.h"
38
39#include "src/compiler/cpp_generator_helpers.h"
40#include <google/protobuf/descriptor.h>
41#include <google/protobuf/descriptor.pb.h>
42#include <google/protobuf/io/printer.h>
43#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
44
45namespace grpc_cpp_generator {
46namespace {
47
Craig Tillerecd49342015-01-18 14:36:47 -080048bool NoStreaming(const google::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080049 return !method->client_streaming() && !method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080050}
51
Craig Tillerecd49342015-01-18 14:36:47 -080052bool ClientOnlyStreaming(const google::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080053 return method->client_streaming() && !method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080054}
55
Craig Tillerecd49342015-01-18 14:36:47 -080056bool ServerOnlyStreaming(const google::protobuf::MethodDescriptor *method) {
yangg1b151092015-01-09 15:31:05 -080057 return !method->client_streaming() && method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080058}
59
Craig Tillerecd49342015-01-18 14:36:47 -080060bool BidiStreaming(const google::protobuf::MethodDescriptor *method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080061 return method->client_streaming() && method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080062}
63
Craig Tiller2dff17d2015-02-09 12:42:23 -080064bool HasUnaryCalls(const google::protobuf::FileDescriptor *file) {
65 for (int i = 0; i < file->service_count(); i++) {
66 for (int j = 0; j < file->service(i)->method_count(); j++) {
67 if (NoStreaming(file->service(i)->method(j))) {
68 return true;
69 }
70 }
71 }
72 return false;
73}
74
Craig Tillerecd49342015-01-18 14:36:47 -080075bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor *file) {
nnobleebebb7e2014-12-10 16:31:01 -080076 for (int i = 0; i < file->service_count(); i++) {
77 for (int j = 0; j < file->service(i)->method_count(); j++) {
78 if (ClientOnlyStreaming(file->service(i)->method(j))) {
79 return true;
80 }
81 }
82 }
83 return false;
84}
85
Craig Tillerecd49342015-01-18 14:36:47 -080086bool HasServerOnlyStreaming(const google::protobuf::FileDescriptor *file) {
nnobleebebb7e2014-12-10 16:31:01 -080087 for (int i = 0; i < file->service_count(); i++) {
88 for (int j = 0; j < file->service(i)->method_count(); j++) {
89 if (ServerOnlyStreaming(file->service(i)->method(j))) {
90 return true;
91 }
92 }
93 }
94 return false;
95}
96
Craig Tillerecd49342015-01-18 14:36:47 -080097bool HasBidiStreaming(const google::protobuf::FileDescriptor *file) {
nnobleebebb7e2014-12-10 16:31:01 -080098 for (int i = 0; i < file->service_count(); i++) {
99 for (int j = 0; j < file->service(i)->method_count(); j++) {
100 if (BidiStreaming(file->service(i)->method(j))) {
101 return true;
102 }
103 }
104 }
105 return false;
106}
107} // namespace
108
Craig Tillerecd49342015-01-18 14:36:47 -0800109std::string GetHeaderIncludes(const google::protobuf::FileDescriptor *file) {
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800110 std::string temp =
Craig Tiller14a65f92015-02-09 13:13:14 -0800111 "#include <grpc++/impl/internal_stub.h>\n"
112 "#include <grpc++/impl/service_type.h>\n"
113 "#include <grpc++/status.h>\n"
nnobleebebb7e2014-12-10 16:31:01 -0800114 "\n"
115 "namespace grpc {\n"
116 "class ChannelInterface;\n"
yangga4b6f5d2014-12-17 15:53:12 -0800117 "class RpcService;\n"
118 "class ServerContext;\n";
Craig Tiller2dff17d2015-02-09 12:42:23 -0800119 if (HasUnaryCalls(file)) {
Craig Tiller5ef5db12015-02-09 12:47:21 -0800120 temp.append(
121 "template <class OutMessage> class ServerAsyncResponseWriter;\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800122 }
nnobleebebb7e2014-12-10 16:31:01 -0800123 if (HasClientOnlyStreaming(file)) {
124 temp.append("template <class OutMessage> class ClientWriter;\n");
125 temp.append("template <class InMessage> class ServerReader;\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800126 temp.append("template <class OutMessage> class ClientAsyncWriter;\n");
127 temp.append("template <class InMessage> class ServerAsyncReader;\n");
nnobleebebb7e2014-12-10 16:31:01 -0800128 }
129 if (HasServerOnlyStreaming(file)) {
130 temp.append("template <class InMessage> class ClientReader;\n");
131 temp.append("template <class OutMessage> class ServerWriter;\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800132 temp.append("template <class OutMessage> class ClientAsyncReader;\n");
133 temp.append("template <class InMessage> class ServerAsyncWriter;\n");
nnobleebebb7e2014-12-10 16:31:01 -0800134 }
135 if (HasBidiStreaming(file)) {
136 temp.append(
137 "template <class OutMessage, class InMessage>\n"
138 "class ClientReaderWriter;\n");
139 temp.append(
140 "template <class OutMessage, class InMessage>\n"
141 "class ServerReaderWriter;\n");
142 }
143 temp.append("} // namespace grpc\n");
144 return temp;
145}
146
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800147std::string GetSourceIncludes() {
Craig Tiller2dff17d2015-02-09 12:42:23 -0800148 return "#include <grpc++/channel_interface.h>\n"
149 "#include <grpc++/impl/rpc_method.h>\n"
150 "#include <grpc++/impl/rpc_service_method.h>\n"
Craig Tiller14a65f92015-02-09 13:13:14 -0800151 "#include <grpc++/impl/service_type.h>\n"
Craig Tiller2dff17d2015-02-09 12:42:23 -0800152 "#include <grpc++/stream.h>\n";
nnobleebebb7e2014-12-10 16:31:01 -0800153}
154
Craig Tillerecd49342015-01-18 14:36:47 -0800155void PrintHeaderClientMethod(google::protobuf::io::Printer *printer,
156 const google::protobuf::MethodDescriptor *method,
157 std::map<std::string, std::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800158 (*vars)["Method"] = method->name();
159 (*vars)["Request"] =
160 grpc_cpp_generator::ClassName(method->input_type(), true);
161 (*vars)["Response"] =
162 grpc_cpp_generator::ClassName(method->output_type(), true);
163 if (NoStreaming(method)) {
164 printer->Print(*vars,
165 "::grpc::Status $Method$(::grpc::ClientContext* context, "
Craig Tiller5ef5db12015-02-09 12:47:21 -0800166 "const $Request$& request, $Response$* response);\n");
167 printer->Print(*vars,
168 "void $Method$(::grpc::ClientContext* context, "
169 "const $Request$& request, $Response$* response, "
Craig Tiller14a65f92015-02-09 13:13:14 -0800170 "::grpc::Status *status, "
171 "::grpc::CompletionQueue *cq, void *tag);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800172 } else if (ClientOnlyStreaming(method)) {
Craig Tiller5ef5db12015-02-09 12:47:21 -0800173 printer->Print(*vars,
174 "::grpc::ClientWriter< $Request$>* $Method$("
175 "::grpc::ClientContext* context, $Response$* response);\n");
176 printer->Print(*vars,
177 "::grpc::ClientWriter< $Request$>* $Method$("
178 "::grpc::ClientContext* context, $Response$* response, "
Craig Tiller14a65f92015-02-09 13:13:14 -0800179 "::grpc::Status *status, "
180 "::grpc::CompletionQueue *cq, void *tag);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800181 } else if (ServerOnlyStreaming(method)) {
182 printer->Print(
183 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800184 "::grpc::ClientReader< $Response$>* $Method$("
Craig Tiller5ef5db12015-02-09 12:47:21 -0800185 "::grpc::ClientContext* context, const $Request$* request);\n");
186 printer->Print(*vars,
187 "::grpc::ClientReader< $Response$>* $Method$("
188 "::grpc::ClientContext* context, const $Request$* request, "
Craig Tiller14a65f92015-02-09 13:13:14 -0800189 "::grpc::CompletionQueue *cq, void *tag);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800190 } else if (BidiStreaming(method)) {
191 printer->Print(*vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800192 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
Craig Tiller5ef5db12015-02-09 12:47:21 -0800193 "$Method$(::grpc::ClientContext* context);\n");
194 printer->Print(*vars,
195 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
196 "$Method$(::grpc::ClientContext* context, "
Craig Tiller14a65f92015-02-09 13:13:14 -0800197 "::grpc::CompletionQueue *cq, void *tag);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800198 }
199}
200
Craig Tiller5ef5db12015-02-09 12:47:21 -0800201void PrintHeaderServerMethodSync(
202 google::protobuf::io::Printer *printer,
203 const google::protobuf::MethodDescriptor *method,
204 std::map<std::string, std::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800205 (*vars)["Method"] = method->name();
206 (*vars)["Request"] =
207 grpc_cpp_generator::ClassName(method->input_type(), true);
208 (*vars)["Response"] =
209 grpc_cpp_generator::ClassName(method->output_type(), true);
210 if (NoStreaming(method)) {
211 printer->Print(*vars,
yangga4b6f5d2014-12-17 15:53:12 -0800212 "virtual ::grpc::Status $Method$("
213 "::grpc::ServerContext* context, const $Request$* request, "
nnobleebebb7e2014-12-10 16:31:01 -0800214 "$Response$* response);\n");
215 } else if (ClientOnlyStreaming(method)) {
216 printer->Print(*vars,
217 "virtual ::grpc::Status $Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800218 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800219 "::grpc::ServerReader< $Request$>* reader, "
nnobleebebb7e2014-12-10 16:31:01 -0800220 "$Response$* response);\n");
221 } else if (ServerOnlyStreaming(method)) {
222 printer->Print(*vars,
yangga4b6f5d2014-12-17 15:53:12 -0800223 "virtual ::grpc::Status $Method$("
224 "::grpc::ServerContext* context, const $Request$* request, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800225 "::grpc::ServerWriter< $Response$>* writer);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800226 } else if (BidiStreaming(method)) {
Yang Gao5680ff42015-01-14 12:14:21 -0800227 printer->Print(
228 *vars,
229 "virtual ::grpc::Status $Method$("
230 "::grpc::ServerContext* context, "
231 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
232 "\n");
nnobleebebb7e2014-12-10 16:31:01 -0800233 }
234}
235
Craig Tiller5ef5db12015-02-09 12:47:21 -0800236void PrintHeaderServerMethodAsync(
237 google::protobuf::io::Printer *printer,
238 const google::protobuf::MethodDescriptor *method,
239 std::map<std::string, std::string> *vars) {
Craig Tiller2dff17d2015-02-09 12:42:23 -0800240 (*vars)["Method"] = method->name();
241 (*vars)["Request"] =
242 grpc_cpp_generator::ClassName(method->input_type(), true);
243 (*vars)["Response"] =
244 grpc_cpp_generator::ClassName(method->output_type(), true);
245 if (NoStreaming(method)) {
246 printer->Print(*vars,
247 "void $Method$("
248 "::grpc::ServerContext* context, $Request$* request, "
249 "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
250 "::grpc::CompletionQueue* cq, void *tag);\n");
251 } else if (ClientOnlyStreaming(method)) {
252 printer->Print(*vars,
253 "void $Method$("
254 "::grpc::ServerContext* context, "
255 "::grpc::ServerAsyncReader< $Request$>* reader, "
256 "$Response$* response, "
257 "::grpc::CompletionQueue* cq, void *tag);\n");
258 } else if (ServerOnlyStreaming(method)) {
259 printer->Print(*vars,
260 "void $Method$("
261 "::grpc::ServerContext* context, $Request$* request, "
262 "::grpc::ServerAsyncWriter< $Response$>* writer, "
263 "::grpc::CompletionQueue* cq, void *tag);\n");
264 } else if (BidiStreaming(method)) {
265 printer->Print(
266 *vars,
267 "void $Method$("
268 "::grpc::ServerContext* context, "
269 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream, "
Craig Tiller5ef5db12015-02-09 12:47:21 -0800270 "::grpc::CompletionQueue* cq, void *tag);\n");
Craig Tiller2dff17d2015-02-09 12:42:23 -0800271 }
272}
273
Craig Tillerecd49342015-01-18 14:36:47 -0800274void PrintHeaderService(google::protobuf::io::Printer *printer,
275 const google::protobuf::ServiceDescriptor *service,
276 std::map<std::string, std::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800277 (*vars)["Service"] = service->name();
278
279 printer->Print(*vars,
Craig Tiller2dff17d2015-02-09 12:42:23 -0800280 "class $Service$ final {\n"
nnobleebebb7e2014-12-10 16:31:01 -0800281 " public:\n");
282 printer->Indent();
283
284 // Client side
Craig Tillerb5dcec52015-01-13 11:13:42 -0800285 printer->Print(
Craig Tiller2dff17d2015-02-09 12:42:23 -0800286 "class Stub final : public ::grpc::InternalStub {\n"
Craig Tillerb5dcec52015-01-13 11:13:42 -0800287 " public:\n");
nnobleebebb7e2014-12-10 16:31:01 -0800288 printer->Indent();
289 for (int i = 0; i < service->method_count(); ++i) {
290 PrintHeaderClientMethod(printer, service->method(i), vars);
291 }
292 printer->Outdent();
293 printer->Print("};\n");
294 printer->Print(
Yang Gao1ff11f62015-01-14 11:45:32 -0800295 "static Stub* NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& "
nnobleebebb7e2014-12-10 16:31:01 -0800296 "channel);\n");
297
298 printer->Print("\n");
299
Craig Tiller2dff17d2015-02-09 12:42:23 -0800300 // Server side - Synchronous
Craig Tillerb5dcec52015-01-13 11:13:42 -0800301 printer->Print(
Craig Tiller14a65f92015-02-09 13:13:14 -0800302 "class Service : public ::grpc::SynchronousService {\n"
Craig Tillerb5dcec52015-01-13 11:13:42 -0800303 " public:\n");
nnobleebebb7e2014-12-10 16:31:01 -0800304 printer->Indent();
305 printer->Print("Service() : service_(nullptr) {}\n");
306 printer->Print("virtual ~Service();\n");
307 for (int i = 0; i < service->method_count(); ++i) {
Craig Tiller2dff17d2015-02-09 12:42:23 -0800308 PrintHeaderServerMethodSync(printer, service->method(i), vars);
309 }
310 printer->Print("::grpc::RpcService* service();\n");
311 printer->Outdent();
312 printer->Print(
313 " private:\n"
314 " ::grpc::RpcService* service_;\n");
315 printer->Print("};\n");
316
317 // Server side - Asynchronous
318 printer->Print(
Craig Tiller14a65f92015-02-09 13:13:14 -0800319 "class AsyncService final : public ::grpc::AsynchronousService {\n"
Craig Tiller2dff17d2015-02-09 12:42:23 -0800320 " public:\n");
321 printer->Indent();
322 printer->Print("AsyncService() : service_(nullptr) {}\n");
323 printer->Print("~AsyncService();\n");
324 for (int i = 0; i < service->method_count(); ++i) {
325 PrintHeaderServerMethodAsync(printer, service->method(i), vars);
nnobleebebb7e2014-12-10 16:31:01 -0800326 }
327 printer->Print("::grpc::RpcService* service();\n");
328 printer->Outdent();
Craig Tillerb5dcec52015-01-13 11:13:42 -0800329 printer->Print(
330 " private:\n"
331 " ::grpc::RpcService* service_;\n");
nnobleebebb7e2014-12-10 16:31:01 -0800332 printer->Print("};\n");
333
334 printer->Outdent();
335 printer->Print("};\n");
336}
337
Craig Tillerecd49342015-01-18 14:36:47 -0800338std::string GetHeaderServices(const google::protobuf::FileDescriptor *file) {
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800339 std::string output;
nnobleebebb7e2014-12-10 16:31:01 -0800340 google::protobuf::io::StringOutputStream output_stream(&output);
341 google::protobuf::io::Printer printer(&output_stream, '$');
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800342 std::map<std::string, std::string> vars;
nnobleebebb7e2014-12-10 16:31:01 -0800343
344 for (int i = 0; i < file->service_count(); ++i) {
samuelwca9f3592014-12-15 14:22:04 -0800345 PrintHeaderService(&printer, file->service(i), &vars);
nnobleebebb7e2014-12-10 16:31:01 -0800346 printer.Print("\n");
347 }
348 return output;
349}
350
Craig Tillerecd49342015-01-18 14:36:47 -0800351void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
352 const google::protobuf::MethodDescriptor *method,
353 std::map<std::string, std::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800354 (*vars)["Method"] = method->name();
355 (*vars)["Request"] =
356 grpc_cpp_generator::ClassName(method->input_type(), true);
357 (*vars)["Response"] =
358 grpc_cpp_generator::ClassName(method->output_type(), true);
359 if (NoStreaming(method)) {
360 printer->Print(*vars,
361 "::grpc::Status $Service$::Stub::$Method$("
362 "::grpc::ClientContext* context, "
363 "const $Request$& request, $Response$* response) {\n");
364 printer->Print(*vars,
Craig Tillerc4965752015-02-09 09:51:00 -0800365 "return ::grpc::BlockingUnaryCall(channel(),"
yangg5bcea0d2015-01-06 10:35:03 -0800366 "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\"), "
nnobleebebb7e2014-12-10 16:31:01 -0800367 "context, request, response);\n"
368 "}\n\n");
369 } else if (ClientOnlyStreaming(method)) {
Yang Gao5680ff42015-01-14 12:14:21 -0800370 printer->Print(
371 *vars,
372 "::grpc::ClientWriter< $Request$>* $Service$::Stub::$Method$("
373 "::grpc::ClientContext* context, $Response$* response) {\n");
yangg5bcea0d2015-01-06 10:35:03 -0800374 printer->Print(*vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800375 " return new ::grpc::ClientWriter< $Request$>("
Craig Tillerc4965752015-02-09 09:51:00 -0800376 "channel(),"
yangg5bcea0d2015-01-06 10:35:03 -0800377 "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
378 "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
Craig Tillerc4965752015-02-09 09:51:00 -0800379 "context, response);\n"
yangg5bcea0d2015-01-06 10:35:03 -0800380 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800381 } else if (ServerOnlyStreaming(method)) {
382 printer->Print(
383 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800384 "::grpc::ClientReader< $Response$>* $Service$::Stub::$Method$("
nnobleebebb7e2014-12-10 16:31:01 -0800385 "::grpc::ClientContext* context, const $Request$* request) {\n");
yangg5bcea0d2015-01-06 10:35:03 -0800386 printer->Print(*vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800387 " return new ::grpc::ClientReader< $Response$>("
Craig Tillerc4965752015-02-09 09:51:00 -0800388 "channel(),"
yangg5bcea0d2015-01-06 10:35:03 -0800389 "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
390 "::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
Craig Tillerc4965752015-02-09 09:51:00 -0800391 "context, *request);\n"
yangg5bcea0d2015-01-06 10:35:03 -0800392 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800393 } else if (BidiStreaming(method)) {
394 printer->Print(
395 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800396 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
nnobleebebb7e2014-12-10 16:31:01 -0800397 "$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n");
398 printer->Print(
399 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800400 " return new ::grpc::ClientReaderWriter< $Request$, $Response$>("
Craig Tillerc4965752015-02-09 09:51:00 -0800401 "channel(),"
yangg5bcea0d2015-01-06 10:35:03 -0800402 "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
nnobleebebb7e2014-12-10 16:31:01 -0800403 "::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
Craig Tillerc4965752015-02-09 09:51:00 -0800404 "context);\n"
nnobleebebb7e2014-12-10 16:31:01 -0800405 "}\n\n");
406 }
407}
408
Craig Tillerecd49342015-01-18 14:36:47 -0800409void PrintSourceServerMethod(google::protobuf::io::Printer *printer,
410 const google::protobuf::MethodDescriptor *method,
411 std::map<std::string, std::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800412 (*vars)["Method"] = method->name();
413 (*vars)["Request"] =
414 grpc_cpp_generator::ClassName(method->input_type(), true);
415 (*vars)["Response"] =
416 grpc_cpp_generator::ClassName(method->output_type(), true);
417 if (NoStreaming(method)) {
418 printer->Print(*vars,
419 "::grpc::Status $Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800420 "::grpc::ServerContext* context, "
nnobleebebb7e2014-12-10 16:31:01 -0800421 "const $Request$* request, $Response$* response) {\n");
422 printer->Print(
423 " return ::grpc::Status("
424 "::grpc::StatusCode::UNIMPLEMENTED);\n");
425 printer->Print("}\n\n");
426 } else if (ClientOnlyStreaming(method)) {
427 printer->Print(*vars,
428 "::grpc::Status $Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800429 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800430 "::grpc::ServerReader< $Request$>* reader, "
nnobleebebb7e2014-12-10 16:31:01 -0800431 "$Response$* response) {\n");
432 printer->Print(
433 " return ::grpc::Status("
434 "::grpc::StatusCode::UNIMPLEMENTED);\n");
435 printer->Print("}\n\n");
436 } else if (ServerOnlyStreaming(method)) {
437 printer->Print(*vars,
438 "::grpc::Status $Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800439 "::grpc::ServerContext* context, "
nnobleebebb7e2014-12-10 16:31:01 -0800440 "const $Request$* request, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800441 "::grpc::ServerWriter< $Response$>* writer) {\n");
nnobleebebb7e2014-12-10 16:31:01 -0800442 printer->Print(
443 " return ::grpc::Status("
444 "::grpc::StatusCode::UNIMPLEMENTED);\n");
445 printer->Print("}\n\n");
446 } else if (BidiStreaming(method)) {
447 printer->Print(*vars,
448 "::grpc::Status $Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800449 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800450 "::grpc::ServerReaderWriter< $Response$, $Request$>* "
nnobleebebb7e2014-12-10 16:31:01 -0800451 "stream) {\n");
452 printer->Print(
453 " return ::grpc::Status("
454 "::grpc::StatusCode::UNIMPLEMENTED);\n");
455 printer->Print("}\n\n");
456 }
457}
458
Craig Tillerecd49342015-01-18 14:36:47 -0800459void PrintSourceService(google::protobuf::io::Printer *printer,
460 const google::protobuf::ServiceDescriptor *service,
461 std::map<std::string, std::string> *vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800462 (*vars)["Service"] = service->name();
Yang Gao5680ff42015-01-14 12:14:21 -0800463 printer->Print(
464 *vars,
465 "$Service$::Stub* $Service$::NewStub("
466 "const std::shared_ptr< ::grpc::ChannelInterface>& channel) {\n"
467 " $Service$::Stub* stub = new $Service$::Stub();\n"
468 " stub->set_channel(channel);\n"
469 " return stub;\n"
470 "};\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800471 for (int i = 0; i < service->method_count(); ++i) {
472 PrintSourceClientMethod(printer, service->method(i), vars);
473 }
474
475 printer->Print(*vars,
476 "$Service$::Service::~Service() {\n"
477 " delete service_;\n"
478 "}\n\n");
479 for (int i = 0; i < service->method_count(); ++i) {
480 PrintSourceServerMethod(printer, service->method(i), vars);
481 }
482 printer->Print(*vars,
Craig Tillerb5dcec52015-01-13 11:13:42 -0800483 "::grpc::RpcService* $Service$::Service::service() {\n");
nnobleebebb7e2014-12-10 16:31:01 -0800484 printer->Indent();
Craig Tillerb5dcec52015-01-13 11:13:42 -0800485 printer->Print(
486 "if (service_ != nullptr) {\n"
487 " return service_;\n"
488 "}\n");
nnobleebebb7e2014-12-10 16:31:01 -0800489 printer->Print("service_ = new ::grpc::RpcService();\n");
490 for (int i = 0; i < service->method_count(); ++i) {
Craig Tillerecd49342015-01-18 14:36:47 -0800491 const google::protobuf::MethodDescriptor *method = service->method(i);
nnobleebebb7e2014-12-10 16:31:01 -0800492 (*vars)["Method"] = method->name();
493 (*vars)["Request"] =
494 grpc_cpp_generator::ClassName(method->input_type(), true);
495 (*vars)["Response"] =
496 grpc_cpp_generator::ClassName(method->output_type(), true);
497 if (NoStreaming(method)) {
498 printer->Print(
499 *vars,
500 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
yangg5bcea0d2015-01-06 10:35:03 -0800501 " \"/$Package$$Service$/$Method$\",\n"
502 " ::grpc::RpcMethod::NORMAL_RPC,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800503 " new ::grpc::RpcMethodHandler< $Service$::Service, $Request$, "
nnobleebebb7e2014-12-10 16:31:01 -0800504 "$Response$>(\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800505 " std::function< ::grpc::Status($Service$::Service*, "
yangga4b6f5d2014-12-17 15:53:12 -0800506 "::grpc::ServerContext*, const $Request$*, $Response$*)>("
nnobleebebb7e2014-12-10 16:31:01 -0800507 "&$Service$::Service::$Method$), this),\n"
508 " new $Request$, new $Response$));\n");
509 } else if (ClientOnlyStreaming(method)) {
510 printer->Print(
511 *vars,
512 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
yangg5bcea0d2015-01-06 10:35:03 -0800513 " \"/$Package$$Service$/$Method$\",\n"
514 " ::grpc::RpcMethod::CLIENT_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800515 " new ::grpc::ClientStreamingHandler< "
nnobleebebb7e2014-12-10 16:31:01 -0800516 "$Service$::Service, $Request$, $Response$>(\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800517 " std::function< ::grpc::Status($Service$::Service*, "
yangga4b6f5d2014-12-17 15:53:12 -0800518 "::grpc::ServerContext*, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800519 "::grpc::ServerReader< $Request$>*, $Response$*)>("
nnobleebebb7e2014-12-10 16:31:01 -0800520 "&$Service$::Service::$Method$), this),\n"
521 " new $Request$, new $Response$));\n");
522 } else if (ServerOnlyStreaming(method)) {
523 printer->Print(
524 *vars,
525 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
yangg5bcea0d2015-01-06 10:35:03 -0800526 " \"/$Package$$Service$/$Method$\",\n"
527 " ::grpc::RpcMethod::SERVER_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800528 " new ::grpc::ServerStreamingHandler< "
nnobleebebb7e2014-12-10 16:31:01 -0800529 "$Service$::Service, $Request$, $Response$>(\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800530 " std::function< ::grpc::Status($Service$::Service*, "
yangga4b6f5d2014-12-17 15:53:12 -0800531 "::grpc::ServerContext*, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800532 "const $Request$*, ::grpc::ServerWriter< $Response$>*)>("
nnobleebebb7e2014-12-10 16:31:01 -0800533 "&$Service$::Service::$Method$), this),\n"
534 " new $Request$, new $Response$));\n");
535 } else if (BidiStreaming(method)) {
536 printer->Print(
537 *vars,
538 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
yangg5bcea0d2015-01-06 10:35:03 -0800539 " \"/$Package$$Service$/$Method$\",\n"
540 " ::grpc::RpcMethod::BIDI_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800541 " new ::grpc::BidiStreamingHandler< "
nnobleebebb7e2014-12-10 16:31:01 -0800542 "$Service$::Service, $Request$, $Response$>(\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800543 " std::function< ::grpc::Status($Service$::Service*, "
yangga4b6f5d2014-12-17 15:53:12 -0800544 "::grpc::ServerContext*, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800545 "::grpc::ServerReaderWriter< $Response$, $Request$>*)>("
nnobleebebb7e2014-12-10 16:31:01 -0800546 "&$Service$::Service::$Method$), this),\n"
547 " new $Request$, new $Response$));\n");
548 }
549 }
550 printer->Print("return service_;\n");
551 printer->Outdent();
552 printer->Print("}\n\n");
553}
554
Craig Tillerecd49342015-01-18 14:36:47 -0800555std::string GetSourceServices(const google::protobuf::FileDescriptor *file) {
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800556 std::string output;
nnobleebebb7e2014-12-10 16:31:01 -0800557 google::protobuf::io::StringOutputStream output_stream(&output);
558 google::protobuf::io::Printer printer(&output_stream, '$');
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800559 std::map<std::string, std::string> vars;
yangg5bcea0d2015-01-06 10:35:03 -0800560 // Package string is empty or ends with a dot. It is used to fully qualify
561 // method names.
562 vars["Package"] = file->package();
563 if (!file->package().empty()) {
564 vars["Package"].append(".");
565 }
nnobleebebb7e2014-12-10 16:31:01 -0800566
567 for (int i = 0; i < file->service_count(); ++i) {
samuelwca9f3592014-12-15 14:22:04 -0800568 PrintSourceService(&printer, file->service(i), &vars);
nnobleebebb7e2014-12-10 16:31:01 -0800569 printer.Print("\n");
570 }
571 return output;
572}
573
574} // namespace grpc_cpp_generator