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