cpp_generator.cc 48 KB

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