blob: 413cbb4941828627259cfead4d6e70fd06d43640 [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
34#include "src/compiler/cpp_generator.h"
35
36#include "src/compiler/cpp_generator_helpers.h"
37#include <google/protobuf/descriptor.h>
38#include <google/protobuf/descriptor.pb.h>
39#include <google/protobuf/io/printer.h>
40#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
41
42namespace grpc_cpp_generator {
43namespace {
44
45bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080046 return !method->client_streaming() && !method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080047}
48
49bool ClientOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
Craig Tillerb5dcec52015-01-13 11:13:42 -080050 return method->client_streaming() && !method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080051}
52
53bool ServerOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
yangg1b151092015-01-09 15:31:05 -080054 return !method->client_streaming() && method->server_streaming();
nnobleebebb7e2014-12-10 16:31:01 -080055}
56
57bool BidiStreaming(const google::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
61bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor* file) {
62 for (int i = 0; i < file->service_count(); i++) {
63 for (int j = 0; j < file->service(i)->method_count(); j++) {
64 if (ClientOnlyStreaming(file->service(i)->method(j))) {
65 return true;
66 }
67 }
68 }
69 return false;
70}
71
72bool HasServerOnlyStreaming(const google::protobuf::FileDescriptor* file) {
73 for (int i = 0; i < file->service_count(); i++) {
74 for (int j = 0; j < file->service(i)->method_count(); j++) {
75 if (ServerOnlyStreaming(file->service(i)->method(j))) {
76 return true;
77 }
78 }
79 }
80 return false;
81}
82
83bool HasBidiStreaming(const google::protobuf::FileDescriptor* file) {
84 for (int i = 0; i < file->service_count(); i++) {
85 for (int j = 0; j < file->service(i)->method_count(); j++) {
86 if (BidiStreaming(file->service(i)->method(j))) {
87 return true;
88 }
89 }
90 }
91 return false;
92}
93} // namespace
94
Nicolas Noblef5c5d802015-01-15 16:36:13 -080095std::string GetHeaderIncludes(const google::protobuf::FileDescriptor* file) {
96 std::string temp =
yangg1b151092015-01-09 15:31:05 -080097 "#include \"grpc++/impl/internal_stub.h\"\n"
temiola33a21682014-12-11 15:13:40 -080098 "#include \"grpc++/status.h\"\n"
nnobleebebb7e2014-12-10 16:31:01 -080099 "\n"
100 "namespace grpc {\n"
101 "class ChannelInterface;\n"
yangga4b6f5d2014-12-17 15:53:12 -0800102 "class RpcService;\n"
103 "class ServerContext;\n";
nnobleebebb7e2014-12-10 16:31:01 -0800104 if (HasClientOnlyStreaming(file)) {
105 temp.append("template <class OutMessage> class ClientWriter;\n");
106 temp.append("template <class InMessage> class ServerReader;\n");
107 }
108 if (HasServerOnlyStreaming(file)) {
109 temp.append("template <class InMessage> class ClientReader;\n");
110 temp.append("template <class OutMessage> class ServerWriter;\n");
111 }
112 if (HasBidiStreaming(file)) {
113 temp.append(
114 "template <class OutMessage, class InMessage>\n"
115 "class ClientReaderWriter;\n");
116 temp.append(
117 "template <class OutMessage, class InMessage>\n"
118 "class ServerReaderWriter;\n");
119 }
120 temp.append("} // namespace grpc\n");
121 return temp;
122}
123
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800124std::string GetSourceIncludes() {
yangg1b151092015-01-09 15:31:05 -0800125 return "#include \"grpc++/channel_interface.h\"\n"
126 "#include \"grpc++/impl/rpc_method.h\"\n"
127 "#include \"grpc++/impl/rpc_service_method.h\"\n"
temiola33a21682014-12-11 15:13:40 -0800128 "#include \"grpc++/stream.h\"\n";
nnobleebebb7e2014-12-10 16:31:01 -0800129}
130
131void PrintHeaderClientMethod(google::protobuf::io::Printer* printer,
Craig Tillerb5dcec52015-01-13 11:13:42 -0800132 const google::protobuf::MethodDescriptor* method,
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800133 std::map<std::string, std::string>* vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800134 (*vars)["Method"] = method->name();
135 (*vars)["Request"] =
136 grpc_cpp_generator::ClassName(method->input_type(), true);
137 (*vars)["Response"] =
138 grpc_cpp_generator::ClassName(method->output_type(), true);
139 if (NoStreaming(method)) {
140 printer->Print(*vars,
141 "::grpc::Status $Method$(::grpc::ClientContext* context, "
142 "const $Request$& request, $Response$* response);\n\n");
143 } else if (ClientOnlyStreaming(method)) {
144 printer->Print(
145 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800146 "::grpc::ClientWriter< $Request$>* $Method$("
nnobleebebb7e2014-12-10 16:31:01 -0800147 "::grpc::ClientContext* context, $Response$* response);\n\n");
148 } else if (ServerOnlyStreaming(method)) {
149 printer->Print(
150 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800151 "::grpc::ClientReader< $Response$>* $Method$("
nnobleebebb7e2014-12-10 16:31:01 -0800152 "::grpc::ClientContext* context, const $Request$* request);\n\n");
153 } else if (BidiStreaming(method)) {
154 printer->Print(*vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800155 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
nnobleebebb7e2014-12-10 16:31:01 -0800156 "$Method$(::grpc::ClientContext* context);\n\n");
157 }
158}
159
160void PrintHeaderServerMethod(google::protobuf::io::Printer* printer,
161 const google::protobuf::MethodDescriptor* method,
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800162 std::map<std::string, std::string>* vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800163 (*vars)["Method"] = method->name();
164 (*vars)["Request"] =
165 grpc_cpp_generator::ClassName(method->input_type(), true);
166 (*vars)["Response"] =
167 grpc_cpp_generator::ClassName(method->output_type(), true);
168 if (NoStreaming(method)) {
169 printer->Print(*vars,
yangga4b6f5d2014-12-17 15:53:12 -0800170 "virtual ::grpc::Status $Method$("
171 "::grpc::ServerContext* context, const $Request$* request, "
nnobleebebb7e2014-12-10 16:31:01 -0800172 "$Response$* response);\n");
173 } else if (ClientOnlyStreaming(method)) {
174 printer->Print(*vars,
175 "virtual ::grpc::Status $Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800176 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800177 "::grpc::ServerReader< $Request$>* reader, "
nnobleebebb7e2014-12-10 16:31:01 -0800178 "$Response$* response);\n");
179 } else if (ServerOnlyStreaming(method)) {
180 printer->Print(*vars,
yangga4b6f5d2014-12-17 15:53:12 -0800181 "virtual ::grpc::Status $Method$("
182 "::grpc::ServerContext* context, const $Request$* request, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800183 "::grpc::ServerWriter< $Response$>* writer);\n");
nnobleebebb7e2014-12-10 16:31:01 -0800184 } else if (BidiStreaming(method)) {
Yang Gao5680ff42015-01-14 12:14:21 -0800185 printer->Print(
186 *vars,
187 "virtual ::grpc::Status $Method$("
188 "::grpc::ServerContext* context, "
189 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
190 "\n");
nnobleebebb7e2014-12-10 16:31:01 -0800191 }
192}
193
194void PrintHeaderService(google::protobuf::io::Printer* printer,
195 const google::protobuf::ServiceDescriptor* service,
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800196 std::map<std::string, std::string>* vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800197 (*vars)["Service"] = service->name();
198
199 printer->Print(*vars,
200 "class $Service$ {\n"
201 " public:\n");
202 printer->Indent();
203
204 // Client side
Craig Tillerb5dcec52015-01-13 11:13:42 -0800205 printer->Print(
206 "class Stub : public ::grpc::InternalStub {\n"
207 " public:\n");
nnobleebebb7e2014-12-10 16:31:01 -0800208 printer->Indent();
209 for (int i = 0; i < service->method_count(); ++i) {
210 PrintHeaderClientMethod(printer, service->method(i), vars);
211 }
212 printer->Outdent();
213 printer->Print("};\n");
214 printer->Print(
Yang Gao1ff11f62015-01-14 11:45:32 -0800215 "static Stub* NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& "
nnobleebebb7e2014-12-10 16:31:01 -0800216 "channel);\n");
217
218 printer->Print("\n");
219
220 // Server side
Craig Tillerb5dcec52015-01-13 11:13:42 -0800221 printer->Print(
222 "class Service {\n"
223 " public:\n");
nnobleebebb7e2014-12-10 16:31:01 -0800224 printer->Indent();
225 printer->Print("Service() : service_(nullptr) {}\n");
226 printer->Print("virtual ~Service();\n");
227 for (int i = 0; i < service->method_count(); ++i) {
228 PrintHeaderServerMethod(printer, service->method(i), vars);
229 }
230 printer->Print("::grpc::RpcService* service();\n");
231 printer->Outdent();
Craig Tillerb5dcec52015-01-13 11:13:42 -0800232 printer->Print(
233 " private:\n"
234 " ::grpc::RpcService* service_;\n");
nnobleebebb7e2014-12-10 16:31:01 -0800235 printer->Print("};\n");
236
237 printer->Outdent();
238 printer->Print("};\n");
239}
240
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800241std::string GetHeaderServices(const google::protobuf::FileDescriptor* file) {
242 std::string output;
nnobleebebb7e2014-12-10 16:31:01 -0800243 google::protobuf::io::StringOutputStream output_stream(&output);
244 google::protobuf::io::Printer printer(&output_stream, '$');
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800245 std::map<std::string, std::string> vars;
nnobleebebb7e2014-12-10 16:31:01 -0800246
247 for (int i = 0; i < file->service_count(); ++i) {
samuelwca9f3592014-12-15 14:22:04 -0800248 PrintHeaderService(&printer, file->service(i), &vars);
nnobleebebb7e2014-12-10 16:31:01 -0800249 printer.Print("\n");
250 }
251 return output;
252}
253
254void PrintSourceClientMethod(google::protobuf::io::Printer* printer,
Craig Tillerb5dcec52015-01-13 11:13:42 -0800255 const google::protobuf::MethodDescriptor* method,
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800256 std::map<std::string, std::string>* vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800257 (*vars)["Method"] = method->name();
258 (*vars)["Request"] =
259 grpc_cpp_generator::ClassName(method->input_type(), true);
260 (*vars)["Response"] =
261 grpc_cpp_generator::ClassName(method->output_type(), true);
262 if (NoStreaming(method)) {
263 printer->Print(*vars,
264 "::grpc::Status $Service$::Stub::$Method$("
265 "::grpc::ClientContext* context, "
266 "const $Request$& request, $Response$* response) {\n");
267 printer->Print(*vars,
268 " return channel()->StartBlockingRpc("
yangg5bcea0d2015-01-06 10:35:03 -0800269 "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\"), "
nnobleebebb7e2014-12-10 16:31:01 -0800270 "context, request, response);\n"
271 "}\n\n");
272 } else if (ClientOnlyStreaming(method)) {
Yang Gao5680ff42015-01-14 12:14:21 -0800273 printer->Print(
274 *vars,
275 "::grpc::ClientWriter< $Request$>* $Service$::Stub::$Method$("
276 "::grpc::ClientContext* context, $Response$* response) {\n");
yangg5bcea0d2015-01-06 10:35:03 -0800277 printer->Print(*vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800278 " return new ::grpc::ClientWriter< $Request$>("
yangg5bcea0d2015-01-06 10:35:03 -0800279 "channel()->CreateStream("
280 "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
281 "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
282 "context, nullptr, response));\n"
283 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800284 } else if (ServerOnlyStreaming(method)) {
285 printer->Print(
286 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800287 "::grpc::ClientReader< $Response$>* $Service$::Stub::$Method$("
nnobleebebb7e2014-12-10 16:31:01 -0800288 "::grpc::ClientContext* context, const $Request$* request) {\n");
yangg5bcea0d2015-01-06 10:35:03 -0800289 printer->Print(*vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800290 " return new ::grpc::ClientReader< $Response$>("
yangg5bcea0d2015-01-06 10:35:03 -0800291 "channel()->CreateStream("
292 "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
293 "::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
294 "context, request, nullptr));\n"
295 "}\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800296 } else if (BidiStreaming(method)) {
297 printer->Print(
298 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800299 "::grpc::ClientReaderWriter< $Request$, $Response$>* "
nnobleebebb7e2014-12-10 16:31:01 -0800300 "$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n");
301 printer->Print(
302 *vars,
Yang Gao1ff11f62015-01-14 11:45:32 -0800303 " return new ::grpc::ClientReaderWriter< $Request$, $Response$>("
yangg5bcea0d2015-01-06 10:35:03 -0800304 "channel()->CreateStream("
305 "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
nnobleebebb7e2014-12-10 16:31:01 -0800306 "::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
307 "context, nullptr, nullptr));\n"
308 "}\n\n");
309 }
310}
311
312void PrintSourceServerMethod(google::protobuf::io::Printer* printer,
Craig Tillerb5dcec52015-01-13 11:13:42 -0800313 const google::protobuf::MethodDescriptor* method,
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800314 std::map<std::string, std::string>* vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800315 (*vars)["Method"] = method->name();
316 (*vars)["Request"] =
317 grpc_cpp_generator::ClassName(method->input_type(), true);
318 (*vars)["Response"] =
319 grpc_cpp_generator::ClassName(method->output_type(), true);
320 if (NoStreaming(method)) {
321 printer->Print(*vars,
322 "::grpc::Status $Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800323 "::grpc::ServerContext* context, "
nnobleebebb7e2014-12-10 16:31:01 -0800324 "const $Request$* request, $Response$* response) {\n");
325 printer->Print(
326 " return ::grpc::Status("
327 "::grpc::StatusCode::UNIMPLEMENTED);\n");
328 printer->Print("}\n\n");
329 } else if (ClientOnlyStreaming(method)) {
330 printer->Print(*vars,
331 "::grpc::Status $Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800332 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800333 "::grpc::ServerReader< $Request$>* reader, "
nnobleebebb7e2014-12-10 16:31:01 -0800334 "$Response$* response) {\n");
335 printer->Print(
336 " return ::grpc::Status("
337 "::grpc::StatusCode::UNIMPLEMENTED);\n");
338 printer->Print("}\n\n");
339 } else if (ServerOnlyStreaming(method)) {
340 printer->Print(*vars,
341 "::grpc::Status $Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800342 "::grpc::ServerContext* context, "
nnobleebebb7e2014-12-10 16:31:01 -0800343 "const $Request$* request, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800344 "::grpc::ServerWriter< $Response$>* writer) {\n");
nnobleebebb7e2014-12-10 16:31:01 -0800345 printer->Print(
346 " return ::grpc::Status("
347 "::grpc::StatusCode::UNIMPLEMENTED);\n");
348 printer->Print("}\n\n");
349 } else if (BidiStreaming(method)) {
350 printer->Print(*vars,
351 "::grpc::Status $Service$::Service::$Method$("
yangga4b6f5d2014-12-17 15:53:12 -0800352 "::grpc::ServerContext* context, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800353 "::grpc::ServerReaderWriter< $Response$, $Request$>* "
nnobleebebb7e2014-12-10 16:31:01 -0800354 "stream) {\n");
355 printer->Print(
356 " return ::grpc::Status("
357 "::grpc::StatusCode::UNIMPLEMENTED);\n");
358 printer->Print("}\n\n");
359 }
360}
361
362void PrintSourceService(google::protobuf::io::Printer* printer,
363 const google::protobuf::ServiceDescriptor* service,
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800364 std::map<std::string, std::string>* vars) {
nnobleebebb7e2014-12-10 16:31:01 -0800365 (*vars)["Service"] = service->name();
Yang Gao5680ff42015-01-14 12:14:21 -0800366 printer->Print(
367 *vars,
368 "$Service$::Stub* $Service$::NewStub("
369 "const std::shared_ptr< ::grpc::ChannelInterface>& channel) {\n"
370 " $Service$::Stub* stub = new $Service$::Stub();\n"
371 " stub->set_channel(channel);\n"
372 " return stub;\n"
373 "};\n\n");
nnobleebebb7e2014-12-10 16:31:01 -0800374 for (int i = 0; i < service->method_count(); ++i) {
375 PrintSourceClientMethod(printer, service->method(i), vars);
376 }
377
378 printer->Print(*vars,
379 "$Service$::Service::~Service() {\n"
380 " delete service_;\n"
381 "}\n\n");
382 for (int i = 0; i < service->method_count(); ++i) {
383 PrintSourceServerMethod(printer, service->method(i), vars);
384 }
385 printer->Print(*vars,
Craig Tillerb5dcec52015-01-13 11:13:42 -0800386 "::grpc::RpcService* $Service$::Service::service() {\n");
nnobleebebb7e2014-12-10 16:31:01 -0800387 printer->Indent();
Craig Tillerb5dcec52015-01-13 11:13:42 -0800388 printer->Print(
389 "if (service_ != nullptr) {\n"
390 " return service_;\n"
391 "}\n");
nnobleebebb7e2014-12-10 16:31:01 -0800392 printer->Print("service_ = new ::grpc::RpcService();\n");
393 for (int i = 0; i < service->method_count(); ++i) {
394 const google::protobuf::MethodDescriptor* method = service->method(i);
395 (*vars)["Method"] = method->name();
396 (*vars)["Request"] =
397 grpc_cpp_generator::ClassName(method->input_type(), true);
398 (*vars)["Response"] =
399 grpc_cpp_generator::ClassName(method->output_type(), true);
400 if (NoStreaming(method)) {
401 printer->Print(
402 *vars,
403 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
yangg5bcea0d2015-01-06 10:35:03 -0800404 " \"/$Package$$Service$/$Method$\",\n"
405 " ::grpc::RpcMethod::NORMAL_RPC,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800406 " new ::grpc::RpcMethodHandler< $Service$::Service, $Request$, "
nnobleebebb7e2014-12-10 16:31:01 -0800407 "$Response$>(\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800408 " std::function< ::grpc::Status($Service$::Service*, "
yangga4b6f5d2014-12-17 15:53:12 -0800409 "::grpc::ServerContext*, const $Request$*, $Response$*)>("
nnobleebebb7e2014-12-10 16:31:01 -0800410 "&$Service$::Service::$Method$), this),\n"
411 " new $Request$, new $Response$));\n");
412 } else if (ClientOnlyStreaming(method)) {
413 printer->Print(
414 *vars,
415 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
yangg5bcea0d2015-01-06 10:35:03 -0800416 " \"/$Package$$Service$/$Method$\",\n"
417 " ::grpc::RpcMethod::CLIENT_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800418 " new ::grpc::ClientStreamingHandler< "
nnobleebebb7e2014-12-10 16:31:01 -0800419 "$Service$::Service, $Request$, $Response$>(\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800420 " std::function< ::grpc::Status($Service$::Service*, "
yangga4b6f5d2014-12-17 15:53:12 -0800421 "::grpc::ServerContext*, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800422 "::grpc::ServerReader< $Request$>*, $Response$*)>("
nnobleebebb7e2014-12-10 16:31:01 -0800423 "&$Service$::Service::$Method$), this),\n"
424 " new $Request$, new $Response$));\n");
425 } else if (ServerOnlyStreaming(method)) {
426 printer->Print(
427 *vars,
428 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
yangg5bcea0d2015-01-06 10:35:03 -0800429 " \"/$Package$$Service$/$Method$\",\n"
430 " ::grpc::RpcMethod::SERVER_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800431 " new ::grpc::ServerStreamingHandler< "
nnobleebebb7e2014-12-10 16:31:01 -0800432 "$Service$::Service, $Request$, $Response$>(\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800433 " std::function< ::grpc::Status($Service$::Service*, "
yangga4b6f5d2014-12-17 15:53:12 -0800434 "::grpc::ServerContext*, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800435 "const $Request$*, ::grpc::ServerWriter< $Response$>*)>("
nnobleebebb7e2014-12-10 16:31:01 -0800436 "&$Service$::Service::$Method$), this),\n"
437 " new $Request$, new $Response$));\n");
438 } else if (BidiStreaming(method)) {
439 printer->Print(
440 *vars,
441 "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
yangg5bcea0d2015-01-06 10:35:03 -0800442 " \"/$Package$$Service$/$Method$\",\n"
443 " ::grpc::RpcMethod::BIDI_STREAMING,\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800444 " new ::grpc::BidiStreamingHandler< "
nnobleebebb7e2014-12-10 16:31:01 -0800445 "$Service$::Service, $Request$, $Response$>(\n"
Yang Gao1ff11f62015-01-14 11:45:32 -0800446 " std::function< ::grpc::Status($Service$::Service*, "
yangga4b6f5d2014-12-17 15:53:12 -0800447 "::grpc::ServerContext*, "
Yang Gao1ff11f62015-01-14 11:45:32 -0800448 "::grpc::ServerReaderWriter< $Response$, $Request$>*)>("
nnobleebebb7e2014-12-10 16:31:01 -0800449 "&$Service$::Service::$Method$), this),\n"
450 " new $Request$, new $Response$));\n");
451 }
452 }
453 printer->Print("return service_;\n");
454 printer->Outdent();
455 printer->Print("}\n\n");
456}
457
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800458std::string GetSourceServices(const google::protobuf::FileDescriptor* file) {
459 std::string output;
nnobleebebb7e2014-12-10 16:31:01 -0800460 google::protobuf::io::StringOutputStream output_stream(&output);
461 google::protobuf::io::Printer printer(&output_stream, '$');
Nicolas Noblef5c5d802015-01-15 16:36:13 -0800462 std::map<std::string, std::string> vars;
yangg5bcea0d2015-01-06 10:35:03 -0800463 // Package string is empty or ends with a dot. It is used to fully qualify
464 // method names.
465 vars["Package"] = file->package();
466 if (!file->package().empty()) {
467 vars["Package"].append(".");
468 }
nnobleebebb7e2014-12-10 16:31:01 -0800469
470 for (int i = 0; i < file->service_count(); ++i) {
samuelwca9f3592014-12-15 14:22:04 -0800471 PrintSourceService(&printer, file->service(i), &vars);
nnobleebebb7e2014-12-10 16:31:01 -0800472 printer.Print("\n");
473 }
474 return output;
475}
476
477} // namespace grpc_cpp_generator