OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * |
| 3 * Copyright 2015-2016, 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 <map> |
| 35 |
| 36 #include "src/compiler/cpp_generator.h" |
| 37 #include "src/compiler/cpp_generator_helpers.h" |
| 38 |
| 39 #include "src/compiler/config.h" |
| 40 |
| 41 #include <sstream> |
| 42 |
| 43 namespace grpc_cpp_generator { |
| 44 namespace { |
| 45 |
| 46 template <class T> |
| 47 grpc::string as_string(T x) { |
| 48 std::ostringstream out; |
| 49 out << x; |
| 50 return out.str(); |
| 51 } |
| 52 |
| 53 bool NoStreaming(const grpc::protobuf::MethodDescriptor *method) { |
| 54 return !method->client_streaming() && !method->server_streaming(); |
| 55 } |
| 56 |
| 57 bool ClientOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) { |
| 58 return method->client_streaming() && !method->server_streaming(); |
| 59 } |
| 60 |
| 61 bool ServerOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) { |
| 62 return !method->client_streaming() && method->server_streaming(); |
| 63 } |
| 64 |
| 65 bool BidiStreaming(const grpc::protobuf::MethodDescriptor *method) { |
| 66 return method->client_streaming() && method->server_streaming(); |
| 67 } |
| 68 |
| 69 grpc::string FilenameIdentifier(const grpc::string &filename) { |
| 70 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 } |
| 84 } // namespace |
| 85 |
| 86 grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file, |
| 87 const Parameters ¶ms) { |
| 88 grpc::string output; |
| 89 { |
| 90 // Scope the output stream so it closes and finalizes output to the string. |
| 91 grpc::protobuf::io::StringOutputStream output_stream(&output); |
| 92 grpc::protobuf::io::Printer printer(&output_stream, '$'); |
| 93 std::map<grpc::string, grpc::string> vars; |
| 94 |
| 95 vars["filename"] = file->name(); |
| 96 vars["filename_identifier"] = FilenameIdentifier(file->name()); |
| 97 vars["filename_base"] = grpc_generator::StripProto(file->name()); |
| 98 |
| 99 printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n"); |
| 100 printer.Print(vars, |
| 101 "// If you make any local change, they will be lost.\n"); |
| 102 printer.Print(vars, "// source: $filename$\n"); |
| 103 printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n"); |
| 104 printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n"); |
| 105 printer.Print(vars, "\n"); |
| 106 printer.Print(vars, "#include \"$filename_base$.pb.h\"\n"); |
| 107 printer.Print(vars, "\n"); |
| 108 } |
| 109 return output; |
| 110 } |
| 111 |
| 112 grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, |
| 113 const Parameters ¶ms) { |
| 114 grpc::string temp = |
| 115 "#include <grpc++/impl/codegen/async_stream.h>\n" |
| 116 "#include <grpc++/impl/codegen/async_unary_call.h>\n" |
| 117 "#include <grpc++/impl/codegen/proto_utils.h>\n" |
| 118 "#include <grpc++/impl/codegen/rpc_method.h>\n" |
| 119 "#include <grpc++/impl/codegen/service_type.h>\n" |
| 120 "#include <grpc++/impl/codegen/status.h>\n" |
| 121 "#include <grpc++/impl/codegen/stub_options.h>\n" |
| 122 "#include <grpc++/impl/codegen/sync_stream.h>\n" |
| 123 "\n" |
| 124 "namespace grpc {\n" |
| 125 "class CompletionQueue;\n" |
| 126 "class RpcService;\n" |
| 127 "class ServerCompletionQueue;\n" |
| 128 "class ServerContext;\n" |
| 129 "} // namespace grpc\n\n"; |
| 130 |
| 131 if (!file->package().empty()) { |
| 132 std::vector<grpc::string> parts = |
| 133 grpc_generator::tokenize(file->package(), "."); |
| 134 |
| 135 for (auto part = parts.begin(); part != parts.end(); part++) { |
| 136 temp.append("namespace "); |
| 137 temp.append(*part); |
| 138 temp.append(" {\n"); |
| 139 } |
| 140 temp.append("\n"); |
| 141 } |
| 142 |
| 143 return temp; |
| 144 } |
| 145 |
| 146 void PrintHeaderClientMethodInterfaces( |
| 147 grpc::protobuf::io::Printer *printer, |
| 148 const grpc::protobuf::MethodDescriptor *method, |
| 149 std::map<grpc::string, grpc::string> *vars, bool is_public) { |
| 150 (*vars)["Method"] = method->name(); |
| 151 (*vars)["Request"] = |
| 152 grpc_cpp_generator::ClassName(method->input_type(), true); |
| 153 (*vars)["Response"] = |
| 154 grpc_cpp_generator::ClassName(method->output_type(), true); |
| 155 |
| 156 if (is_public) { |
| 157 if (NoStreaming(method)) { |
| 158 printer->Print( |
| 159 *vars, |
| 160 "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, " |
| 161 "const $Request$& request, $Response$* response) = 0;\n"); |
| 162 printer->Print(*vars, |
| 163 "std::unique_ptr< " |
| 164 "::grpc::ClientAsyncResponseReaderInterface< $Response$>> " |
| 165 "Async$Method$(::grpc::ClientContext* context, " |
| 166 "const $Request$& request, " |
| 167 "::grpc::CompletionQueue* cq) {\n"); |
| 168 printer->Indent(); |
| 169 printer->Print(*vars, |
| 170 "return std::unique_ptr< " |
| 171 "::grpc::ClientAsyncResponseReaderInterface< $Response$>>(" |
| 172 "Async$Method$Raw(context, request, cq));\n"); |
| 173 printer->Outdent(); |
| 174 printer->Print("}\n"); |
| 175 } else if (ClientOnlyStreaming(method)) { |
| 176 printer->Print( |
| 177 *vars, |
| 178 "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>" |
| 179 " $Method$(" |
| 180 "::grpc::ClientContext* context, $Response$* response) {\n"); |
| 181 printer->Indent(); |
| 182 printer->Print( |
| 183 *vars, |
| 184 "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>" |
| 185 "($Method$Raw(context, response));\n"); |
| 186 printer->Outdent(); |
| 187 printer->Print("}\n"); |
| 188 printer->Print( |
| 189 *vars, |
| 190 "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>" |
| 191 " Async$Method$(::grpc::ClientContext* context, $Response$* " |
| 192 "response, " |
| 193 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 194 printer->Indent(); |
| 195 printer->Print(*vars, |
| 196 "return std::unique_ptr< " |
| 197 "::grpc::ClientAsyncWriterInterface< $Request$>>(" |
| 198 "Async$Method$Raw(context, response, cq, tag));\n"); |
| 199 printer->Outdent(); |
| 200 printer->Print("}\n"); |
| 201 } else if (ServerOnlyStreaming(method)) { |
| 202 printer->Print( |
| 203 *vars, |
| 204 "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>" |
| 205 " $Method$(::grpc::ClientContext* context, const $Request$& request)" |
| 206 " {\n"); |
| 207 printer->Indent(); |
| 208 printer->Print( |
| 209 *vars, |
| 210 "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>" |
| 211 "($Method$Raw(context, request));\n"); |
| 212 printer->Outdent(); |
| 213 printer->Print("}\n"); |
| 214 printer->Print( |
| 215 *vars, |
| 216 "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> " |
| 217 "Async$Method$(" |
| 218 "::grpc::ClientContext* context, const $Request$& request, " |
| 219 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 220 printer->Indent(); |
| 221 printer->Print(*vars, |
| 222 "return std::unique_ptr< " |
| 223 "::grpc::ClientAsyncReaderInterface< $Response$>>(" |
| 224 "Async$Method$Raw(context, request, cq, tag));\n"); |
| 225 printer->Outdent(); |
| 226 printer->Print("}\n"); |
| 227 } else if (BidiStreaming(method)) { |
| 228 printer->Print(*vars, |
| 229 "std::unique_ptr< ::grpc::ClientReaderWriterInterface< " |
| 230 "$Request$, $Response$>> " |
| 231 "$Method$(::grpc::ClientContext* context) {\n"); |
| 232 printer->Indent(); |
| 233 printer->Print( |
| 234 *vars, |
| 235 "return std::unique_ptr< " |
| 236 "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>(" |
| 237 "$Method$Raw(context));\n"); |
| 238 printer->Outdent(); |
| 239 printer->Print("}\n"); |
| 240 printer->Print( |
| 241 *vars, |
| 242 "std::unique_ptr< " |
| 243 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> " |
| 244 "Async$Method$(::grpc::ClientContext* context, " |
| 245 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 246 printer->Indent(); |
| 247 printer->Print( |
| 248 *vars, |
| 249 "return std::unique_ptr< " |
| 250 "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>(" |
| 251 "Async$Method$Raw(context, cq, tag));\n"); |
| 252 printer->Outdent(); |
| 253 printer->Print("}\n"); |
| 254 } |
| 255 } else { |
| 256 if (NoStreaming(method)) { |
| 257 printer->Print( |
| 258 *vars, |
| 259 "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* " |
| 260 "Async$Method$Raw(::grpc::ClientContext* context, " |
| 261 "const $Request$& request, " |
| 262 "::grpc::CompletionQueue* cq) = 0;\n"); |
| 263 } else if (ClientOnlyStreaming(method)) { |
| 264 printer->Print( |
| 265 *vars, |
| 266 "virtual ::grpc::ClientWriterInterface< $Request$>*" |
| 267 " $Method$Raw(" |
| 268 "::grpc::ClientContext* context, $Response$* response) = 0;\n"); |
| 269 printer->Print(*vars, |
| 270 "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*" |
| 271 " Async$Method$Raw(::grpc::ClientContext* context, " |
| 272 "$Response$* response, " |
| 273 "::grpc::CompletionQueue* cq, void* tag) = 0;\n"); |
| 274 } else if (ServerOnlyStreaming(method)) { |
| 275 printer->Print( |
| 276 *vars, |
| 277 "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw(" |
| 278 "::grpc::ClientContext* context, const $Request$& request) = 0;\n"); |
| 279 printer->Print( |
| 280 *vars, |
| 281 "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* " |
| 282 "Async$Method$Raw(" |
| 283 "::grpc::ClientContext* context, const $Request$& request, " |
| 284 "::grpc::CompletionQueue* cq, void* tag) = 0;\n"); |
| 285 } else if (BidiStreaming(method)) { |
| 286 printer->Print(*vars, |
| 287 "virtual ::grpc::ClientReaderWriterInterface< $Request$, " |
| 288 "$Response$>* " |
| 289 "$Method$Raw(::grpc::ClientContext* context) = 0;\n"); |
| 290 printer->Print(*vars, |
| 291 "virtual ::grpc::ClientAsyncReaderWriterInterface< " |
| 292 "$Request$, $Response$>* " |
| 293 "Async$Method$Raw(::grpc::ClientContext* context, " |
| 294 "::grpc::CompletionQueue* cq, void* tag) = 0;\n"); |
| 295 } |
| 296 } |
| 297 } |
| 298 |
| 299 void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer, |
| 300 const grpc::protobuf::MethodDescriptor *method, |
| 301 std::map<grpc::string, grpc::string> *vars, |
| 302 bool is_public) { |
| 303 (*vars)["Method"] = method->name(); |
| 304 (*vars)["Request"] = |
| 305 grpc_cpp_generator::ClassName(method->input_type(), true); |
| 306 (*vars)["Response"] = |
| 307 grpc_cpp_generator::ClassName(method->output_type(), true); |
| 308 if (is_public) { |
| 309 if (NoStreaming(method)) { |
| 310 printer->Print( |
| 311 *vars, |
| 312 "::grpc::Status $Method$(::grpc::ClientContext* context, " |
| 313 "const $Request$& request, $Response$* response) GRPC_OVERRIDE;\n"); |
| 314 printer->Print( |
| 315 *vars, |
| 316 "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> " |
| 317 "Async$Method$(::grpc::ClientContext* context, " |
| 318 "const $Request$& request, " |
| 319 "::grpc::CompletionQueue* cq) {\n"); |
| 320 printer->Indent(); |
| 321 printer->Print(*vars, |
| 322 "return std::unique_ptr< " |
| 323 "::grpc::ClientAsyncResponseReader< $Response$>>(" |
| 324 "Async$Method$Raw(context, request, cq));\n"); |
| 325 printer->Outdent(); |
| 326 printer->Print("}\n"); |
| 327 } else if (ClientOnlyStreaming(method)) { |
| 328 printer->Print( |
| 329 *vars, |
| 330 "std::unique_ptr< ::grpc::ClientWriter< $Request$>>" |
| 331 " $Method$(" |
| 332 "::grpc::ClientContext* context, $Response$* response) {\n"); |
| 333 printer->Indent(); |
| 334 printer->Print(*vars, |
| 335 "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>" |
| 336 "($Method$Raw(context, response));\n"); |
| 337 printer->Outdent(); |
| 338 printer->Print("}\n"); |
| 339 printer->Print(*vars, |
| 340 "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>" |
| 341 " Async$Method$(::grpc::ClientContext* context, " |
| 342 "$Response$* response, " |
| 343 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 344 printer->Indent(); |
| 345 printer->Print( |
| 346 *vars, |
| 347 "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>(" |
| 348 "Async$Method$Raw(context, response, cq, tag));\n"); |
| 349 printer->Outdent(); |
| 350 printer->Print("}\n"); |
| 351 } else if (ServerOnlyStreaming(method)) { |
| 352 printer->Print( |
| 353 *vars, |
| 354 "std::unique_ptr< ::grpc::ClientReader< $Response$>>" |
| 355 " $Method$(::grpc::ClientContext* context, const $Request$& request)" |
| 356 " {\n"); |
| 357 printer->Indent(); |
| 358 printer->Print( |
| 359 *vars, |
| 360 "return std::unique_ptr< ::grpc::ClientReader< $Response$>>" |
| 361 "($Method$Raw(context, request));\n"); |
| 362 printer->Outdent(); |
| 363 printer->Print("}\n"); |
| 364 printer->Print( |
| 365 *vars, |
| 366 "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> " |
| 367 "Async$Method$(" |
| 368 "::grpc::ClientContext* context, const $Request$& request, " |
| 369 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 370 printer->Indent(); |
| 371 printer->Print( |
| 372 *vars, |
| 373 "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>(" |
| 374 "Async$Method$Raw(context, request, cq, tag));\n"); |
| 375 printer->Outdent(); |
| 376 printer->Print("}\n"); |
| 377 } else if (BidiStreaming(method)) { |
| 378 printer->Print( |
| 379 *vars, |
| 380 "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>" |
| 381 " $Method$(::grpc::ClientContext* context) {\n"); |
| 382 printer->Indent(); |
| 383 printer->Print(*vars, |
| 384 "return std::unique_ptr< " |
| 385 "::grpc::ClientReaderWriter< $Request$, $Response$>>(" |
| 386 "$Method$Raw(context));\n"); |
| 387 printer->Outdent(); |
| 388 printer->Print("}\n"); |
| 389 printer->Print(*vars, |
| 390 "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< " |
| 391 "$Request$, $Response$>> " |
| 392 "Async$Method$(::grpc::ClientContext* context, " |
| 393 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 394 printer->Indent(); |
| 395 printer->Print(*vars, |
| 396 "return std::unique_ptr< " |
| 397 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>(" |
| 398 "Async$Method$Raw(context, cq, tag));\n"); |
| 399 printer->Outdent(); |
| 400 printer->Print("}\n"); |
| 401 } |
| 402 } else { |
| 403 if (NoStreaming(method)) { |
| 404 printer->Print(*vars, |
| 405 "::grpc::ClientAsyncResponseReader< $Response$>* " |
| 406 "Async$Method$Raw(::grpc::ClientContext* context, " |
| 407 "const $Request$& request, " |
| 408 "::grpc::CompletionQueue* cq) GRPC_OVERRIDE;\n"); |
| 409 } else if (ClientOnlyStreaming(method)) { |
| 410 printer->Print(*vars, |
| 411 "::grpc::ClientWriter< $Request$>* $Method$Raw(" |
| 412 "::grpc::ClientContext* context, $Response$* response) " |
| 413 "GRPC_OVERRIDE;\n"); |
| 414 printer->Print( |
| 415 *vars, |
| 416 "::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw(" |
| 417 "::grpc::ClientContext* context, $Response$* response, " |
| 418 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n"); |
| 419 } else if (ServerOnlyStreaming(method)) { |
| 420 printer->Print(*vars, |
| 421 "::grpc::ClientReader< $Response$>* $Method$Raw(" |
| 422 "::grpc::ClientContext* context, const $Request$& request)" |
| 423 " GRPC_OVERRIDE;\n"); |
| 424 printer->Print( |
| 425 *vars, |
| 426 "::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw(" |
| 427 "::grpc::ClientContext* context, const $Request$& request, " |
| 428 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n"); |
| 429 } else if (BidiStreaming(method)) { |
| 430 printer->Print( |
| 431 *vars, |
| 432 "::grpc::ClientReaderWriter< $Request$, $Response$>* " |
| 433 "$Method$Raw(::grpc::ClientContext* context) GRPC_OVERRIDE;\n"); |
| 434 printer->Print( |
| 435 *vars, |
| 436 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* " |
| 437 "Async$Method$Raw(::grpc::ClientContext* context, " |
| 438 "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n"); |
| 439 } |
| 440 } |
| 441 } |
| 442 |
| 443 void PrintHeaderClientMethodData(grpc::protobuf::io::Printer *printer, |
| 444 const grpc::protobuf::MethodDescriptor *method, |
| 445 std::map<grpc::string, grpc::string> *vars) { |
| 446 (*vars)["Method"] = method->name(); |
| 447 printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n"); |
| 448 } |
| 449 |
| 450 void PrintHeaderServerMethodSync(grpc::protobuf::io::Printer *printer, |
| 451 const grpc::protobuf::MethodDescriptor *method, |
| 452 std::map<grpc::string, grpc::string> *vars) { |
| 453 (*vars)["Method"] = method->name(); |
| 454 (*vars)["Request"] = |
| 455 grpc_cpp_generator::ClassName(method->input_type(), true); |
| 456 (*vars)["Response"] = |
| 457 grpc_cpp_generator::ClassName(method->output_type(), true); |
| 458 if (NoStreaming(method)) { |
| 459 printer->Print(*vars, |
| 460 "virtual ::grpc::Status $Method$(" |
| 461 "::grpc::ServerContext* context, const $Request$* request, " |
| 462 "$Response$* response);\n"); |
| 463 } else if (ClientOnlyStreaming(method)) { |
| 464 printer->Print(*vars, |
| 465 "virtual ::grpc::Status $Method$(" |
| 466 "::grpc::ServerContext* context, " |
| 467 "::grpc::ServerReader< $Request$>* reader, " |
| 468 "$Response$* response);\n"); |
| 469 } else if (ServerOnlyStreaming(method)) { |
| 470 printer->Print(*vars, |
| 471 "virtual ::grpc::Status $Method$(" |
| 472 "::grpc::ServerContext* context, const $Request$* request, " |
| 473 "::grpc::ServerWriter< $Response$>* writer);\n"); |
| 474 } else if (BidiStreaming(method)) { |
| 475 printer->Print( |
| 476 *vars, |
| 477 "virtual ::grpc::Status $Method$(" |
| 478 "::grpc::ServerContext* context, " |
| 479 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);" |
| 480 "\n"); |
| 481 } |
| 482 } |
| 483 |
| 484 void PrintHeaderServerMethodAsync( |
| 485 grpc::protobuf::io::Printer *printer, |
| 486 const grpc::protobuf::MethodDescriptor *method, |
| 487 std::map<grpc::string, grpc::string> *vars) { |
| 488 (*vars)["Method"] = method->name(); |
| 489 (*vars)["Request"] = |
| 490 grpc_cpp_generator::ClassName(method->input_type(), true); |
| 491 (*vars)["Response"] = |
| 492 grpc_cpp_generator::ClassName(method->output_type(), true); |
| 493 printer->Print(*vars, "template <class BaseClass>\n"); |
| 494 printer->Print(*vars, |
| 495 "class WithAsyncMethod_$Method$ : public BaseClass {\n"); |
| 496 printer->Print( |
| 497 " private:\n" |
| 498 " void BaseClassMustBeDerivedFromService(Service *service) {}\n"); |
| 499 printer->Print(" public:\n"); |
| 500 printer->Indent(); |
| 501 printer->Print(*vars, |
| 502 "WithAsyncMethod_$Method$() {\n" |
| 503 " ::grpc::Service::MarkMethodAsync($Idx$);\n" |
| 504 "}\n"); |
| 505 printer->Print(*vars, |
| 506 "~WithAsyncMethod_$Method$() GRPC_OVERRIDE {\n" |
| 507 " BaseClassMustBeDerivedFromService(this);\n" |
| 508 "}\n"); |
| 509 if (NoStreaming(method)) { |
| 510 printer->Print( |
| 511 *vars, |
| 512 "// disable synchronous version of this method\n" |
| 513 "::grpc::Status $Method$(" |
| 514 "::grpc::ServerContext* context, const $Request$* request, " |
| 515 "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n" |
| 516 " abort();\n" |
| 517 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" |
| 518 "}\n"); |
| 519 printer->Print( |
| 520 *vars, |
| 521 "void Request$Method$(" |
| 522 "::grpc::ServerContext* context, $Request$* request, " |
| 523 "::grpc::ServerAsyncResponseWriter< $Response$>* response, " |
| 524 "::grpc::CompletionQueue* new_call_cq, " |
| 525 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n"); |
| 526 printer->Print(*vars, |
| 527 " ::grpc::Service::RequestAsyncUnary($Idx$, context, " |
| 528 "request, response, new_call_cq, notification_cq, tag);\n"); |
| 529 printer->Print("}\n"); |
| 530 } else if (ClientOnlyStreaming(method)) { |
| 531 printer->Print( |
| 532 *vars, |
| 533 "// disable synchronous version of this method\n" |
| 534 "::grpc::Status $Method$(" |
| 535 "::grpc::ServerContext* context, " |
| 536 "::grpc::ServerReader< $Request$>* reader, " |
| 537 "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n" |
| 538 " abort();\n" |
| 539 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" |
| 540 "}\n"); |
| 541 printer->Print( |
| 542 *vars, |
| 543 "void Request$Method$(" |
| 544 "::grpc::ServerContext* context, " |
| 545 "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, " |
| 546 "::grpc::CompletionQueue* new_call_cq, " |
| 547 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n"); |
| 548 printer->Print(*vars, |
| 549 " ::grpc::Service::RequestAsyncClientStreaming($Idx$, " |
| 550 "context, reader, new_call_cq, notification_cq, tag);\n"); |
| 551 printer->Print("}\n"); |
| 552 } else if (ServerOnlyStreaming(method)) { |
| 553 printer->Print( |
| 554 *vars, |
| 555 "// disable synchronous version of this method\n" |
| 556 "::grpc::Status $Method$(" |
| 557 "::grpc::ServerContext* context, const $Request$* request, " |
| 558 "::grpc::ServerWriter< $Response$>* writer) GRPC_FINAL GRPC_OVERRIDE " |
| 559 "{\n" |
| 560 " abort();\n" |
| 561 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" |
| 562 "}\n"); |
| 563 printer->Print( |
| 564 *vars, |
| 565 "void Request$Method$(" |
| 566 "::grpc::ServerContext* context, $Request$* request, " |
| 567 "::grpc::ServerAsyncWriter< $Response$>* writer, " |
| 568 "::grpc::CompletionQueue* new_call_cq, " |
| 569 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n"); |
| 570 printer->Print( |
| 571 *vars, |
| 572 " ::grpc::Service::RequestAsyncServerStreaming($Idx$, " |
| 573 "context, request, writer, new_call_cq, notification_cq, tag);\n"); |
| 574 printer->Print("}\n"); |
| 575 } else if (BidiStreaming(method)) { |
| 576 printer->Print( |
| 577 *vars, |
| 578 "// disable synchronous version of this method\n" |
| 579 "::grpc::Status $Method$(" |
| 580 "::grpc::ServerContext* context, " |
| 581 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) " |
| 582 "GRPC_FINAL GRPC_OVERRIDE {\n" |
| 583 " abort();\n" |
| 584 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" |
| 585 "}\n"); |
| 586 printer->Print( |
| 587 *vars, |
| 588 "void Request$Method$(" |
| 589 "::grpc::ServerContext* context, " |
| 590 "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, " |
| 591 "::grpc::CompletionQueue* new_call_cq, " |
| 592 "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n"); |
| 593 printer->Print(*vars, |
| 594 " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, " |
| 595 "context, stream, new_call_cq, notification_cq, tag);\n"); |
| 596 printer->Print("}\n"); |
| 597 } |
| 598 printer->Outdent(); |
| 599 printer->Print(*vars, "};\n"); |
| 600 } |
| 601 |
| 602 void PrintHeaderServerMethodGeneric( |
| 603 grpc::protobuf::io::Printer *printer, |
| 604 const grpc::protobuf::MethodDescriptor *method, |
| 605 std::map<grpc::string, grpc::string> *vars) { |
| 606 (*vars)["Method"] = method->name(); |
| 607 (*vars)["Request"] = |
| 608 grpc_cpp_generator::ClassName(method->input_type(), true); |
| 609 (*vars)["Response"] = |
| 610 grpc_cpp_generator::ClassName(method->output_type(), true); |
| 611 printer->Print(*vars, "template <class BaseClass>\n"); |
| 612 printer->Print(*vars, |
| 613 "class WithGenericMethod_$Method$ : public BaseClass {\n"); |
| 614 printer->Print( |
| 615 " private:\n" |
| 616 " void BaseClassMustBeDerivedFromService(Service *service) {}\n"); |
| 617 printer->Print(" public:\n"); |
| 618 printer->Indent(); |
| 619 printer->Print(*vars, |
| 620 "WithGenericMethod_$Method$() {\n" |
| 621 " ::grpc::Service::MarkMethodGeneric($Idx$);\n" |
| 622 "}\n"); |
| 623 printer->Print(*vars, |
| 624 "~WithGenericMethod_$Method$() GRPC_OVERRIDE {\n" |
| 625 " BaseClassMustBeDerivedFromService(this);\n" |
| 626 "}\n"); |
| 627 if (NoStreaming(method)) { |
| 628 printer->Print( |
| 629 *vars, |
| 630 "// disable synchronous version of this method\n" |
| 631 "::grpc::Status $Method$(" |
| 632 "::grpc::ServerContext* context, const $Request$* request, " |
| 633 "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n" |
| 634 " abort();\n" |
| 635 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" |
| 636 "}\n"); |
| 637 } else if (ClientOnlyStreaming(method)) { |
| 638 printer->Print( |
| 639 *vars, |
| 640 "// disable synchronous version of this method\n" |
| 641 "::grpc::Status $Method$(" |
| 642 "::grpc::ServerContext* context, " |
| 643 "::grpc::ServerReader< $Request$>* reader, " |
| 644 "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n" |
| 645 " abort();\n" |
| 646 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" |
| 647 "}\n"); |
| 648 } else if (ServerOnlyStreaming(method)) { |
| 649 printer->Print( |
| 650 *vars, |
| 651 "// disable synchronous version of this method\n" |
| 652 "::grpc::Status $Method$(" |
| 653 "::grpc::ServerContext* context, const $Request$* request, " |
| 654 "::grpc::ServerWriter< $Response$>* writer) GRPC_FINAL GRPC_OVERRIDE " |
| 655 "{\n" |
| 656 " abort();\n" |
| 657 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" |
| 658 "}\n"); |
| 659 } else if (BidiStreaming(method)) { |
| 660 printer->Print( |
| 661 *vars, |
| 662 "// disable synchronous version of this method\n" |
| 663 "::grpc::Status $Method$(" |
| 664 "::grpc::ServerContext* context, " |
| 665 "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) " |
| 666 "GRPC_FINAL GRPC_OVERRIDE {\n" |
| 667 " abort();\n" |
| 668 " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" |
| 669 "}\n"); |
| 670 } |
| 671 printer->Outdent(); |
| 672 printer->Print(*vars, "};\n"); |
| 673 } |
| 674 |
| 675 void PrintHeaderService(grpc::protobuf::io::Printer *printer, |
| 676 const grpc::protobuf::ServiceDescriptor *service, |
| 677 std::map<grpc::string, grpc::string> *vars) { |
| 678 (*vars)["Service"] = service->name(); |
| 679 |
| 680 printer->Print(*vars, |
| 681 "class $Service$ GRPC_FINAL {\n" |
| 682 " public:\n"); |
| 683 printer->Indent(); |
| 684 |
| 685 // Client side |
| 686 printer->Print( |
| 687 "class StubInterface {\n" |
| 688 " public:\n"); |
| 689 printer->Indent(); |
| 690 printer->Print("virtual ~StubInterface() {}\n"); |
| 691 for (int i = 0; i < service->method_count(); ++i) { |
| 692 PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, true); |
| 693 } |
| 694 printer->Outdent(); |
| 695 printer->Print("private:\n"); |
| 696 printer->Indent(); |
| 697 for (int i = 0; i < service->method_count(); ++i) { |
| 698 PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, false); |
| 699 } |
| 700 printer->Outdent(); |
| 701 printer->Print("};\n"); |
| 702 printer->Print( |
| 703 "class Stub GRPC_FINAL : public StubInterface" |
| 704 " {\n public:\n"); |
| 705 printer->Indent(); |
| 706 printer->Print("Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel
);\n"); |
| 707 for (int i = 0; i < service->method_count(); ++i) { |
| 708 PrintHeaderClientMethod(printer, service->method(i), vars, true); |
| 709 } |
| 710 printer->Outdent(); |
| 711 printer->Print("\n private:\n"); |
| 712 printer->Indent(); |
| 713 printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n"); |
| 714 for (int i = 0; i < service->method_count(); ++i) { |
| 715 PrintHeaderClientMethod(printer, service->method(i), vars, false); |
| 716 } |
| 717 for (int i = 0; i < service->method_count(); ++i) { |
| 718 PrintHeaderClientMethodData(printer, service->method(i), vars); |
| 719 } |
| 720 printer->Outdent(); |
| 721 printer->Print("};\n"); |
| 722 printer->Print( |
| 723 "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< " |
| 724 "::grpc::ChannelInterface>& channel, " |
| 725 "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n"); |
| 726 |
| 727 printer->Print("\n"); |
| 728 |
| 729 // Server side - base |
| 730 printer->Print( |
| 731 "class Service : public ::grpc::Service {\n" |
| 732 " public:\n"); |
| 733 printer->Indent(); |
| 734 printer->Print("Service();\n"); |
| 735 printer->Print("virtual ~Service();\n"); |
| 736 for (int i = 0; i < service->method_count(); ++i) { |
| 737 PrintHeaderServerMethodSync(printer, service->method(i), vars); |
| 738 } |
| 739 printer->Outdent(); |
| 740 printer->Print("};\n"); |
| 741 |
| 742 // Server side - Asynchronous |
| 743 for (int i = 0; i < service->method_count(); ++i) { |
| 744 (*vars)["Idx"] = as_string(i); |
| 745 PrintHeaderServerMethodAsync(printer, service->method(i), vars); |
| 746 } |
| 747 |
| 748 printer->Print("typedef "); |
| 749 |
| 750 for (int i = 0; i < service->method_count(); ++i) { |
| 751 (*vars)["method_name"] = service->method(i)->name(); |
| 752 printer->Print(*vars, "WithAsyncMethod_$method_name$<"); |
| 753 } |
| 754 printer->Print("Service"); |
| 755 for (int i = 0; i < service->method_count(); ++i) { |
| 756 printer->Print(" >"); |
| 757 } |
| 758 printer->Print(" AsyncService;\n"); |
| 759 |
| 760 // Server side - Generic |
| 761 for (int i = 0; i < service->method_count(); ++i) { |
| 762 (*vars)["Idx"] = as_string(i); |
| 763 PrintHeaderServerMethodGeneric(printer, service->method(i), vars); |
| 764 } |
| 765 |
| 766 printer->Outdent(); |
| 767 printer->Print("};\n"); |
| 768 } |
| 769 |
| 770 grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file, |
| 771 const Parameters ¶ms) { |
| 772 grpc::string output; |
| 773 { |
| 774 // Scope the output stream so it closes and finalizes output to the string. |
| 775 grpc::protobuf::io::StringOutputStream output_stream(&output); |
| 776 grpc::protobuf::io::Printer printer(&output_stream, '$'); |
| 777 std::map<grpc::string, grpc::string> vars; |
| 778 // Package string is empty or ends with a dot. It is used to fully qualify |
| 779 // method names. |
| 780 vars["Package"] = file->package(); |
| 781 if (!file->package().empty()) { |
| 782 vars["Package"].append("."); |
| 783 } |
| 784 |
| 785 if (!params.services_namespace.empty()) { |
| 786 vars["services_namespace"] = params.services_namespace; |
| 787 printer.Print(vars, "\nnamespace $services_namespace$ {\n\n"); |
| 788 } |
| 789 |
| 790 for (int i = 0; i < file->service_count(); ++i) { |
| 791 PrintHeaderService(&printer, file->service(i), &vars); |
| 792 printer.Print("\n"); |
| 793 } |
| 794 |
| 795 if (!params.services_namespace.empty()) { |
| 796 printer.Print(vars, "} // namespace $services_namespace$\n\n"); |
| 797 } |
| 798 } |
| 799 return output; |
| 800 } |
| 801 |
| 802 grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file, |
| 803 const Parameters ¶ms) { |
| 804 grpc::string output; |
| 805 { |
| 806 // Scope the output stream so it closes and finalizes output to the string. |
| 807 grpc::protobuf::io::StringOutputStream output_stream(&output); |
| 808 grpc::protobuf::io::Printer printer(&output_stream, '$'); |
| 809 std::map<grpc::string, grpc::string> vars; |
| 810 |
| 811 vars["filename"] = file->name(); |
| 812 vars["filename_identifier"] = FilenameIdentifier(file->name()); |
| 813 |
| 814 if (!file->package().empty()) { |
| 815 std::vector<grpc::string> parts = |
| 816 grpc_generator::tokenize(file->package(), "."); |
| 817 |
| 818 for (auto part = parts.rbegin(); part != parts.rend(); part++) { |
| 819 vars["part"] = *part; |
| 820 printer.Print(vars, "} // namespace $part$\n"); |
| 821 } |
| 822 printer.Print(vars, "\n"); |
| 823 } |
| 824 |
| 825 printer.Print(vars, "\n"); |
| 826 printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n"); |
| 827 } |
| 828 return output; |
| 829 } |
| 830 |
| 831 grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file, |
| 832 const Parameters ¶ms) { |
| 833 grpc::string output; |
| 834 { |
| 835 // Scope the output stream so it closes and finalizes output to the string. |
| 836 grpc::protobuf::io::StringOutputStream output_stream(&output); |
| 837 grpc::protobuf::io::Printer printer(&output_stream, '$'); |
| 838 std::map<grpc::string, grpc::string> vars; |
| 839 |
| 840 vars["filename"] = file->name(); |
| 841 vars["filename_base"] = grpc_generator::StripProto(file->name()); |
| 842 |
| 843 printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n"); |
| 844 printer.Print(vars, |
| 845 "// If you make any local change, they will be lost.\n"); |
| 846 printer.Print(vars, "// source: $filename$\n\n"); |
| 847 printer.Print(vars, "#include \"$filename_base$.pb.h\"\n"); |
| 848 printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n"); |
| 849 printer.Print(vars, "\n"); |
| 850 } |
| 851 return output; |
| 852 } |
| 853 |
| 854 grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file, |
| 855 const Parameters ¶m) { |
| 856 grpc::string output; |
| 857 { |
| 858 // Scope the output stream so it closes and finalizes output to the string. |
| 859 grpc::protobuf::io::StringOutputStream output_stream(&output); |
| 860 grpc::protobuf::io::Printer printer(&output_stream, '$'); |
| 861 std::map<grpc::string, grpc::string> vars; |
| 862 |
| 863 printer.Print(vars, "#include <grpc++/impl/codegen/async_stream.h>\n"); |
| 864 printer.Print(vars, "#include <grpc++/impl/codegen/async_unary_call.h>\n"); |
| 865 printer.Print(vars, "#include <grpc++/impl/codegen/channel_interface.h>\n"); |
| 866 printer.Print(vars, "#include <grpc++/impl/codegen/client_unary_call.h>\n"); |
| 867 printer.Print(vars, |
| 868 "#include <grpc++/impl/codegen/method_handler_impl.h>\n"); |
| 869 printer.Print(vars, |
| 870 "#include <grpc++/impl/codegen/rpc_service_method.h>\n"); |
| 871 printer.Print(vars, "#include <grpc++/impl/codegen/service_type.h>\n"); |
| 872 printer.Print(vars, "#include <grpc++/impl/codegen/sync_stream.h>\n"); |
| 873 |
| 874 if (!file->package().empty()) { |
| 875 std::vector<grpc::string> parts = |
| 876 grpc_generator::tokenize(file->package(), "."); |
| 877 |
| 878 for (auto part = parts.begin(); part != parts.end(); part++) { |
| 879 vars["part"] = *part; |
| 880 printer.Print(vars, "namespace $part$ {\n"); |
| 881 } |
| 882 } |
| 883 |
| 884 printer.Print(vars, "\n"); |
| 885 } |
| 886 return output; |
| 887 } |
| 888 |
| 889 void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer, |
| 890 const grpc::protobuf::MethodDescriptor *method, |
| 891 std::map<grpc::string, grpc::string> *vars) { |
| 892 (*vars)["Method"] = method->name(); |
| 893 (*vars)["Request"] = |
| 894 grpc_cpp_generator::ClassName(method->input_type(), true); |
| 895 (*vars)["Response"] = |
| 896 grpc_cpp_generator::ClassName(method->output_type(), true); |
| 897 if (NoStreaming(method)) { |
| 898 printer->Print(*vars, |
| 899 "::grpc::Status $ns$$Service$::Stub::$Method$(" |
| 900 "::grpc::ClientContext* context, " |
| 901 "const $Request$& request, $Response$* response) {\n"); |
| 902 printer->Print(*vars, |
| 903 " return ::grpc::BlockingUnaryCall(channel_.get(), " |
| 904 "rpcmethod_$Method$_, " |
| 905 "context, request, response);\n" |
| 906 "}\n\n"); |
| 907 printer->Print( |
| 908 *vars, |
| 909 "::grpc::ClientAsyncResponseReader< $Response$>* " |
| 910 "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, " |
| 911 "const $Request$& request, " |
| 912 "::grpc::CompletionQueue* cq) {\n"); |
| 913 printer->Print(*vars, |
| 914 " return new " |
| 915 "::grpc::ClientAsyncResponseReader< $Response$>(" |
| 916 "channel_.get(), cq, " |
| 917 "rpcmethod_$Method$_, " |
| 918 "context, request);\n" |
| 919 "}\n\n"); |
| 920 } else if (ClientOnlyStreaming(method)) { |
| 921 printer->Print(*vars, |
| 922 "::grpc::ClientWriter< $Request$>* " |
| 923 "$ns$$Service$::Stub::$Method$Raw(" |
| 924 "::grpc::ClientContext* context, $Response$* response) {\n"); |
| 925 printer->Print(*vars, |
| 926 " return new ::grpc::ClientWriter< $Request$>(" |
| 927 "channel_.get(), " |
| 928 "rpcmethod_$Method$_, " |
| 929 "context, response);\n" |
| 930 "}\n\n"); |
| 931 printer->Print(*vars, |
| 932 "::grpc::ClientAsyncWriter< $Request$>* " |
| 933 "$ns$$Service$::Stub::Async$Method$Raw(" |
| 934 "::grpc::ClientContext* context, $Response$* response, " |
| 935 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 936 printer->Print(*vars, |
| 937 " return new ::grpc::ClientAsyncWriter< $Request$>(" |
| 938 "channel_.get(), cq, " |
| 939 "rpcmethod_$Method$_, " |
| 940 "context, response, tag);\n" |
| 941 "}\n\n"); |
| 942 } else if (ServerOnlyStreaming(method)) { |
| 943 printer->Print( |
| 944 *vars, |
| 945 "::grpc::ClientReader< $Response$>* " |
| 946 "$ns$$Service$::Stub::$Method$Raw(" |
| 947 "::grpc::ClientContext* context, const $Request$& request) {\n"); |
| 948 printer->Print(*vars, |
| 949 " return new ::grpc::ClientReader< $Response$>(" |
| 950 "channel_.get(), " |
| 951 "rpcmethod_$Method$_, " |
| 952 "context, request);\n" |
| 953 "}\n\n"); |
| 954 printer->Print(*vars, |
| 955 "::grpc::ClientAsyncReader< $Response$>* " |
| 956 "$ns$$Service$::Stub::Async$Method$Raw(" |
| 957 "::grpc::ClientContext* context, const $Request$& request, " |
| 958 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 959 printer->Print(*vars, |
| 960 " return new ::grpc::ClientAsyncReader< $Response$>(" |
| 961 "channel_.get(), cq, " |
| 962 "rpcmethod_$Method$_, " |
| 963 "context, request, tag);\n" |
| 964 "}\n\n"); |
| 965 } else if (BidiStreaming(method)) { |
| 966 printer->Print( |
| 967 *vars, |
| 968 "::grpc::ClientReaderWriter< $Request$, $Response$>* " |
| 969 "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n"); |
| 970 printer->Print(*vars, |
| 971 " return new ::grpc::ClientReaderWriter< " |
| 972 "$Request$, $Response$>(" |
| 973 "channel_.get(), " |
| 974 "rpcmethod_$Method$_, " |
| 975 "context);\n" |
| 976 "}\n\n"); |
| 977 printer->Print( |
| 978 *vars, |
| 979 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* " |
| 980 "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, " |
| 981 "::grpc::CompletionQueue* cq, void* tag) {\n"); |
| 982 printer->Print(*vars, |
| 983 " return new " |
| 984 "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>(" |
| 985 "channel_.get(), cq, " |
| 986 "rpcmethod_$Method$_, " |
| 987 "context, tag);\n" |
| 988 "}\n\n"); |
| 989 } |
| 990 } |
| 991 |
| 992 void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer, |
| 993 const grpc::protobuf::MethodDescriptor *method, |
| 994 std::map<grpc::string, grpc::string> *vars) { |
| 995 (*vars)["Method"] = method->name(); |
| 996 (*vars)["Request"] = |
| 997 grpc_cpp_generator::ClassName(method->input_type(), true); |
| 998 (*vars)["Response"] = |
| 999 grpc_cpp_generator::ClassName(method->output_type(), true); |
| 1000 if (NoStreaming(method)) { |
| 1001 printer->Print(*vars, |
| 1002 "::grpc::Status $ns$$Service$::Service::$Method$(" |
| 1003 "::grpc::ServerContext* context, " |
| 1004 "const $Request$* request, $Response$* response) {\n"); |
| 1005 printer->Print(" (void) context;\n"); |
| 1006 printer->Print(" (void) request;\n"); |
| 1007 printer->Print(" (void) response;\n"); |
| 1008 printer->Print( |
| 1009 " return ::grpc::Status(" |
| 1010 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); |
| 1011 printer->Print("}\n\n"); |
| 1012 } else if (ClientOnlyStreaming(method)) { |
| 1013 printer->Print(*vars, |
| 1014 "::grpc::Status $ns$$Service$::Service::$Method$(" |
| 1015 "::grpc::ServerContext* context, " |
| 1016 "::grpc::ServerReader< $Request$>* reader, " |
| 1017 "$Response$* response) {\n"); |
| 1018 printer->Print(" (void) context;\n"); |
| 1019 printer->Print(" (void) reader;\n"); |
| 1020 printer->Print(" (void) response;\n"); |
| 1021 printer->Print( |
| 1022 " return ::grpc::Status(" |
| 1023 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); |
| 1024 printer->Print("}\n\n"); |
| 1025 } else if (ServerOnlyStreaming(method)) { |
| 1026 printer->Print(*vars, |
| 1027 "::grpc::Status $ns$$Service$::Service::$Method$(" |
| 1028 "::grpc::ServerContext* context, " |
| 1029 "const $Request$* request, " |
| 1030 "::grpc::ServerWriter< $Response$>* writer) {\n"); |
| 1031 printer->Print(" (void) context;\n"); |
| 1032 printer->Print(" (void) request;\n"); |
| 1033 printer->Print(" (void) writer;\n"); |
| 1034 printer->Print( |
| 1035 " return ::grpc::Status(" |
| 1036 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); |
| 1037 printer->Print("}\n\n"); |
| 1038 } else if (BidiStreaming(method)) { |
| 1039 printer->Print(*vars, |
| 1040 "::grpc::Status $ns$$Service$::Service::$Method$(" |
| 1041 "::grpc::ServerContext* context, " |
| 1042 "::grpc::ServerReaderWriter< $Response$, $Request$>* " |
| 1043 "stream) {\n"); |
| 1044 printer->Print(" (void) context;\n"); |
| 1045 printer->Print(" (void) stream;\n"); |
| 1046 printer->Print( |
| 1047 " return ::grpc::Status(" |
| 1048 "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); |
| 1049 printer->Print("}\n\n"); |
| 1050 } |
| 1051 } |
| 1052 |
| 1053 void PrintSourceService(grpc::protobuf::io::Printer *printer, |
| 1054 const grpc::protobuf::ServiceDescriptor *service, |
| 1055 std::map<grpc::string, grpc::string> *vars) { |
| 1056 (*vars)["Service"] = service->name(); |
| 1057 |
| 1058 printer->Print(*vars, |
| 1059 "static const char* $prefix$$Service$_method_names[] = {\n"); |
| 1060 for (int i = 0; i < service->method_count(); ++i) { |
| 1061 (*vars)["Method"] = service->method(i)->name(); |
| 1062 printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n"); |
| 1063 } |
| 1064 printer->Print(*vars, "};\n\n"); |
| 1065 |
| 1066 printer->Print(*vars, |
| 1067 "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub(" |
| 1068 "const std::shared_ptr< ::grpc::ChannelInterface>& channel, " |
| 1069 "const ::grpc::StubOptions& options) {\n" |
| 1070 " std::unique_ptr< $ns$$Service$::Stub> stub(new " |
| 1071 "$ns$$Service$::Stub(channel));\n" |
| 1072 " return stub;\n" |
| 1073 "}\n\n"); |
| 1074 printer->Print(*vars, |
| 1075 "$ns$$Service$::Stub::Stub(const std::shared_ptr< " |
| 1076 "::grpc::ChannelInterface>& channel)\n"); |
| 1077 printer->Indent(); |
| 1078 printer->Print(": channel_(channel)"); |
| 1079 for (int i = 0; i < service->method_count(); ++i) { |
| 1080 const grpc::protobuf::MethodDescriptor *method = service->method(i); |
| 1081 (*vars)["Method"] = method->name(); |
| 1082 (*vars)["Idx"] = as_string(i); |
| 1083 if (NoStreaming(method)) { |
| 1084 (*vars)["StreamingType"] = "NORMAL_RPC"; |
| 1085 } else if (ClientOnlyStreaming(method)) { |
| 1086 (*vars)["StreamingType"] = "CLIENT_STREAMING"; |
| 1087 } else if (ServerOnlyStreaming(method)) { |
| 1088 (*vars)["StreamingType"] = "SERVER_STREAMING"; |
| 1089 } else { |
| 1090 (*vars)["StreamingType"] = "BIDI_STREAMING"; |
| 1091 } |
| 1092 printer->Print(*vars, |
| 1093 ", rpcmethod_$Method$_(" |
| 1094 "$prefix$$Service$_method_names[$Idx$], " |
| 1095 "::grpc::RpcMethod::$StreamingType$, " |
| 1096 "channel" |
| 1097 ")\n"); |
| 1098 } |
| 1099 printer->Print("{}\n\n"); |
| 1100 printer->Outdent(); |
| 1101 |
| 1102 for (int i = 0; i < service->method_count(); ++i) { |
| 1103 (*vars)["Idx"] = as_string(i); |
| 1104 PrintSourceClientMethod(printer, service->method(i), vars); |
| 1105 } |
| 1106 |
| 1107 printer->Print(*vars, "$ns$$Service$::Service::Service() {\n"); |
| 1108 printer->Indent(); |
| 1109 printer->Print(*vars, "(void)$prefix$$Service$_method_names;\n"); |
| 1110 for (int i = 0; i < service->method_count(); ++i) { |
| 1111 const grpc::protobuf::MethodDescriptor *method = service->method(i); |
| 1112 (*vars)["Idx"] = as_string(i); |
| 1113 (*vars)["Method"] = method->name(); |
| 1114 (*vars)["Request"] = |
| 1115 grpc_cpp_generator::ClassName(method->input_type(), true); |
| 1116 (*vars)["Response"] = |
| 1117 grpc_cpp_generator::ClassName(method->output_type(), true); |
| 1118 if (NoStreaming(method)) { |
| 1119 printer->Print( |
| 1120 *vars, |
| 1121 "AddMethod(new ::grpc::RpcServiceMethod(\n" |
| 1122 " $prefix$$Service$_method_names[$Idx$],\n" |
| 1123 " ::grpc::RpcMethod::NORMAL_RPC,\n" |
| 1124 " new ::grpc::RpcMethodHandler< $ns$$Service$::Service, " |
| 1125 "$Request$, " |
| 1126 "$Response$>(\n" |
| 1127 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); |
| 1128 } else if (ClientOnlyStreaming(method)) { |
| 1129 printer->Print( |
| 1130 *vars, |
| 1131 "AddMethod(new ::grpc::RpcServiceMethod(\n" |
| 1132 " $prefix$$Service$_method_names[$Idx$],\n" |
| 1133 " ::grpc::RpcMethod::CLIENT_STREAMING,\n" |
| 1134 " new ::grpc::ClientStreamingHandler< " |
| 1135 "$ns$$Service$::Service, $Request$, $Response$>(\n" |
| 1136 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); |
| 1137 } else if (ServerOnlyStreaming(method)) { |
| 1138 printer->Print( |
| 1139 *vars, |
| 1140 "AddMethod(new ::grpc::RpcServiceMethod(\n" |
| 1141 " $prefix$$Service$_method_names[$Idx$],\n" |
| 1142 " ::grpc::RpcMethod::SERVER_STREAMING,\n" |
| 1143 " new ::grpc::ServerStreamingHandler< " |
| 1144 "$ns$$Service$::Service, $Request$, $Response$>(\n" |
| 1145 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); |
| 1146 } else if (BidiStreaming(method)) { |
| 1147 printer->Print( |
| 1148 *vars, |
| 1149 "AddMethod(new ::grpc::RpcServiceMethod(\n" |
| 1150 " $prefix$$Service$_method_names[$Idx$],\n" |
| 1151 " ::grpc::RpcMethod::BIDI_STREAMING,\n" |
| 1152 " new ::grpc::BidiStreamingHandler< " |
| 1153 "$ns$$Service$::Service, $Request$, $Response$>(\n" |
| 1154 " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); |
| 1155 } |
| 1156 } |
| 1157 printer->Outdent(); |
| 1158 printer->Print(*vars, "}\n\n"); |
| 1159 printer->Print(*vars, |
| 1160 "$ns$$Service$::Service::~Service() {\n" |
| 1161 "}\n\n"); |
| 1162 for (int i = 0; i < service->method_count(); ++i) { |
| 1163 (*vars)["Idx"] = as_string(i); |
| 1164 PrintSourceServerMethod(printer, service->method(i), vars); |
| 1165 } |
| 1166 } |
| 1167 |
| 1168 grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file, |
| 1169 const Parameters ¶ms) { |
| 1170 grpc::string output; |
| 1171 { |
| 1172 // Scope the output stream so it closes and finalizes output to the string. |
| 1173 grpc::protobuf::io::StringOutputStream output_stream(&output); |
| 1174 grpc::protobuf::io::Printer printer(&output_stream, '$'); |
| 1175 std::map<grpc::string, grpc::string> vars; |
| 1176 // Package string is empty or ends with a dot. It is used to fully qualify |
| 1177 // method names. |
| 1178 vars["Package"] = file->package(); |
| 1179 if (!file->package().empty()) { |
| 1180 vars["Package"].append("."); |
| 1181 } |
| 1182 if (!params.services_namespace.empty()) { |
| 1183 vars["ns"] = params.services_namespace + "::"; |
| 1184 vars["prefix"] = params.services_namespace; |
| 1185 } else { |
| 1186 vars["ns"] = ""; |
| 1187 vars["prefix"] = ""; |
| 1188 } |
| 1189 |
| 1190 for (int i = 0; i < file->service_count(); ++i) { |
| 1191 PrintSourceService(&printer, file->service(i), &vars); |
| 1192 printer.Print("\n"); |
| 1193 } |
| 1194 } |
| 1195 return output; |
| 1196 } |
| 1197 |
| 1198 grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file, |
| 1199 const Parameters ¶ms) { |
| 1200 grpc::string temp; |
| 1201 |
| 1202 if (!file->package().empty()) { |
| 1203 std::vector<grpc::string> parts = |
| 1204 grpc_generator::tokenize(file->package(), "."); |
| 1205 |
| 1206 for (auto part = parts.begin(); part != parts.end(); part++) { |
| 1207 temp.append("} // namespace "); |
| 1208 temp.append(*part); |
| 1209 temp.append("\n"); |
| 1210 } |
| 1211 temp.append("\n"); |
| 1212 } |
| 1213 |
| 1214 return temp; |
| 1215 } |
| 1216 |
| 1217 } // namespace grpc_cpp_generator |
OLD | NEW |