cpp_generator.cc 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <map>
  19. #include "src/compiler/cpp_generator.h"
  20. #include <sstream>
  21. namespace grpc_cpp_generator {
  22. namespace {
  23. template <class T>
  24. grpc::string as_string(T x) {
  25. std::ostringstream out;
  26. out << x;
  27. return out.str();
  28. }
  29. inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
  30. return method->ClientStreaming() && !method->ServerStreaming();
  31. }
  32. inline bool ServerOnlyStreaming(const grpc_generator::Method *method) {
  33. return !method->ClientStreaming() && method->ServerStreaming();
  34. }
  35. grpc::string FilenameIdentifier(const grpc::string &filename) {
  36. grpc::string result;
  37. for (unsigned i = 0; i < filename.size(); i++) {
  38. char c = filename[i];
  39. if (isalnum(c)) {
  40. result.push_back(c);
  41. } else {
  42. static char hex[] = "0123456789abcdef";
  43. result.push_back('_');
  44. result.push_back(hex[(c >> 4) & 0xf]);
  45. result.push_back(hex[c & 0xf]);
  46. }
  47. }
  48. return result;
  49. }
  50. } // namespace
  51. template <class T, size_t N>
  52. T *array_end(T (&array)[N]) {
  53. return array + N;
  54. }
  55. void PrintIncludes(grpc_generator::Printer *printer,
  56. const std::vector<grpc::string> &headers,
  57. const Parameters &params) {
  58. std::map<grpc::string, grpc::string> vars;
  59. vars["l"] = params.use_system_headers ? '<' : '"';
  60. vars["r"] = params.use_system_headers ? '>' : '"';
  61. auto &s = params.grpc_search_path;
  62. if (!s.empty()) {
  63. vars["l"] += s;
  64. if (s[s.size() - 1] != '/') {
  65. vars["l"] += '/';
  66. }
  67. }
  68. for (auto i = headers.begin(); i != headers.end(); i++) {
  69. vars["h"] = *i;
  70. printer->Print(vars, "#include $l$$h$$r$\n");
  71. }
  72. }
  73. grpc::string GetHeaderPrologue(grpc_generator::File *file,
  74. const Parameters & /*params*/) {
  75. grpc::string output;
  76. {
  77. // Scope the output stream so it closes and finalizes output to the string.
  78. auto printer = file->CreatePrinter(&output);
  79. std::map<grpc::string, grpc::string> vars;
  80. vars["filename"] = file->filename();
  81. vars["filename_identifier"] = FilenameIdentifier(file->filename());
  82. vars["filename_base"] = file->filename_without_ext();
  83. vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
  84. printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
  85. printer->Print(vars,
  86. "// If you make any local change, they will be lost.\n");
  87. printer->Print(vars, "// source: $filename$\n");
  88. grpc::string leading_comments = file->GetLeadingComments("//");
  89. if (!leading_comments.empty()) {
  90. printer->Print(vars, "// Original file comments:\n");
  91. printer->Print(leading_comments.c_str());
  92. }
  93. printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
  94. printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
  95. printer->Print(vars, "\n");
  96. printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
  97. printer->Print(vars, file->additional_headers().c_str());
  98. printer->Print(vars, "\n");
  99. }
  100. return output;
  101. }
  102. grpc::string GetHeaderIncludes(grpc_generator::File *file,
  103. const Parameters &params) {
  104. grpc::string output;
  105. {
  106. // Scope the output stream so it closes and finalizes output to the string.
  107. auto printer = file->CreatePrinter(&output);
  108. std::map<grpc::string, grpc::string> vars;
  109. static const char *headers_strs[] = {
  110. "grpc++/impl/codegen/async_stream.h",
  111. "grpc++/impl/codegen/async_unary_call.h",
  112. "grpc++/impl/codegen/method_handler_impl.h",
  113. "grpc++/impl/codegen/proto_utils.h",
  114. "grpc++/impl/codegen/rpc_method.h",
  115. "grpc++/impl/codegen/service_type.h",
  116. "grpc++/impl/codegen/status.h",
  117. "grpc++/impl/codegen/stub_options.h",
  118. "grpc++/impl/codegen/sync_stream.h"};
  119. std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
  120. PrintIncludes(printer.get(), headers, params);
  121. printer->Print(vars, "\n");
  122. printer->Print(vars, "namespace grpc {\n");
  123. printer->Print(vars, "class CompletionQueue;\n");
  124. printer->Print(vars, "class Channel;\n");
  125. printer->Print(vars, "class RpcService;\n");
  126. printer->Print(vars, "class ServerCompletionQueue;\n");
  127. printer->Print(vars, "class ServerContext;\n");
  128. printer->Print(vars, "} // namespace grpc\n\n");
  129. if (!file->package().empty()) {
  130. std::vector<grpc::string> parts = file->package_parts();
  131. for (auto part = parts.begin(); part != parts.end(); part++) {
  132. vars["part"] = *part;
  133. printer->Print(vars, "namespace $part$ {\n");
  134. }
  135. printer->Print(vars, "\n");
  136. }
  137. }
  138. return output;
  139. }
  140. void PrintHeaderClientMethodInterfaces(
  141. grpc_generator::Printer *printer, const grpc_generator::Method *method,
  142. std::map<grpc::string, grpc::string> *vars, bool is_public) {
  143. (*vars)["Method"] = method->name();
  144. (*vars)["Request"] = method->input_type_name();
  145. (*vars)["Response"] = method->output_type_name();
  146. struct {
  147. grpc::string prefix;
  148. grpc::string method_params; // extra arguments to method
  149. grpc::string raw_args; // extra arguments to raw version of method
  150. } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
  151. {"PrepareAsync", "", ""}};
  152. if (is_public) {
  153. if (method->NoStreaming()) {
  154. printer->Print(
  155. *vars,
  156. "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
  157. "const $Request$& request, $Response$* response) = 0;\n");
  158. for (auto async_prefix : async_prefixes) {
  159. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  160. printer->Print(
  161. *vars,
  162. "std::unique_ptr< "
  163. "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
  164. "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  165. "const $Request$& request, "
  166. "::grpc::CompletionQueue* cq) {\n");
  167. printer->Indent();
  168. printer->Print(
  169. *vars,
  170. "return std::unique_ptr< "
  171. "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
  172. "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
  173. printer->Outdent();
  174. printer->Print("}\n");
  175. }
  176. } else if (ClientOnlyStreaming(method)) {
  177. printer->Print(
  178. *vars,
  179. "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
  180. " $Method$("
  181. "::grpc::ClientContext* context, $Response$* response) {\n");
  182. printer->Indent();
  183. printer->Print(
  184. *vars,
  185. "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
  186. "($Method$Raw(context, response));\n");
  187. printer->Outdent();
  188. printer->Print("}\n");
  189. for (auto async_prefix : async_prefixes) {
  190. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  191. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  192. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  193. printer->Print(
  194. *vars,
  195. "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
  196. " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  197. "$Response$* "
  198. "response, "
  199. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  200. printer->Indent();
  201. printer->Print(*vars,
  202. "return std::unique_ptr< "
  203. "::grpc::ClientAsyncWriterInterface< $Request$>>("
  204. "$AsyncPrefix$$Method$Raw(context, response, "
  205. "cq$AsyncRawArgs$));\n");
  206. printer->Outdent();
  207. printer->Print("}\n");
  208. }
  209. } else if (ServerOnlyStreaming(method)) {
  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. for (auto async_prefix : async_prefixes) {
  223. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  224. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  225. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  226. printer->Print(
  227. *vars,
  228. "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
  229. "$AsyncPrefix$$Method$("
  230. "::grpc::ClientContext* context, const $Request$& request, "
  231. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  232. printer->Indent();
  233. printer->Print(
  234. *vars,
  235. "return std::unique_ptr< "
  236. "::grpc::ClientAsyncReaderInterface< $Response$>>("
  237. "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
  238. printer->Outdent();
  239. printer->Print("}\n");
  240. }
  241. } else if (method->BidiStreaming()) {
  242. printer->Print(*vars,
  243. "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
  244. "$Request$, $Response$>> "
  245. "$Method$(::grpc::ClientContext* context) {\n");
  246. printer->Indent();
  247. printer->Print(
  248. *vars,
  249. "return std::unique_ptr< "
  250. "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
  251. "$Method$Raw(context));\n");
  252. printer->Outdent();
  253. printer->Print("}\n");
  254. for (auto async_prefix : async_prefixes) {
  255. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  256. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  257. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  258. printer->Print(
  259. *vars,
  260. "std::unique_ptr< "
  261. "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
  262. "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  263. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  264. printer->Indent();
  265. printer->Print(
  266. *vars,
  267. "return std::unique_ptr< "
  268. "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
  269. "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
  270. printer->Outdent();
  271. printer->Print("}\n");
  272. }
  273. }
  274. } else {
  275. if (method->NoStreaming()) {
  276. for (auto async_prefix : async_prefixes) {
  277. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  278. printer->Print(
  279. *vars,
  280. "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
  281. "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  282. "const $Request$& request, "
  283. "::grpc::CompletionQueue* cq) = 0;\n");
  284. }
  285. } else if (ClientOnlyStreaming(method)) {
  286. printer->Print(
  287. *vars,
  288. "virtual ::grpc::ClientWriterInterface< $Request$>*"
  289. " $Method$Raw("
  290. "::grpc::ClientContext* context, $Response$* response) = 0;\n");
  291. for (auto async_prefix : async_prefixes) {
  292. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  293. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  294. printer->Print(
  295. *vars,
  296. "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
  297. " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  298. "$Response$* response, "
  299. "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
  300. }
  301. } else if (ServerOnlyStreaming(method)) {
  302. printer->Print(
  303. *vars,
  304. "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
  305. "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
  306. for (auto async_prefix : async_prefixes) {
  307. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  308. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  309. printer->Print(
  310. *vars,
  311. "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
  312. "$AsyncPrefix$$Method$Raw("
  313. "::grpc::ClientContext* context, const $Request$& request, "
  314. "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
  315. }
  316. } else if (method->BidiStreaming()) {
  317. printer->Print(*vars,
  318. "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
  319. "$Response$>* "
  320. "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
  321. for (auto async_prefix : async_prefixes) {
  322. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  323. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  324. printer->Print(
  325. *vars,
  326. "virtual ::grpc::ClientAsyncReaderWriterInterface< "
  327. "$Request$, $Response$>* "
  328. "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  329. "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
  330. }
  331. }
  332. }
  333. }
  334. void PrintHeaderClientMethod(grpc_generator::Printer *printer,
  335. const grpc_generator::Method *method,
  336. std::map<grpc::string, grpc::string> *vars,
  337. bool is_public) {
  338. (*vars)["Method"] = method->name();
  339. (*vars)["Request"] = method->input_type_name();
  340. (*vars)["Response"] = method->output_type_name();
  341. struct {
  342. grpc::string prefix;
  343. grpc::string method_params; // extra arguments to method
  344. grpc::string raw_args; // extra arguments to raw version of method
  345. } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
  346. {"PrepareAsync", "", ""}};
  347. if (is_public) {
  348. if (method->NoStreaming()) {
  349. printer->Print(
  350. *vars,
  351. "::grpc::Status $Method$(::grpc::ClientContext* context, "
  352. "const $Request$& request, $Response$* response) override;\n");
  353. for (auto async_prefix : async_prefixes) {
  354. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  355. printer->Print(
  356. *vars,
  357. "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
  358. "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  359. "const $Request$& request, "
  360. "::grpc::CompletionQueue* cq) {\n");
  361. printer->Indent();
  362. printer->Print(*vars,
  363. "return std::unique_ptr< "
  364. "::grpc::ClientAsyncResponseReader< $Response$>>("
  365. "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
  366. printer->Outdent();
  367. printer->Print("}\n");
  368. }
  369. } else if (ClientOnlyStreaming(method)) {
  370. printer->Print(
  371. *vars,
  372. "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
  373. " $Method$("
  374. "::grpc::ClientContext* context, $Response$* response) {\n");
  375. printer->Indent();
  376. printer->Print(*vars,
  377. "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
  378. "($Method$Raw(context, response));\n");
  379. printer->Outdent();
  380. printer->Print("}\n");
  381. for (auto async_prefix : async_prefixes) {
  382. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  383. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  384. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  385. printer->Print(*vars,
  386. "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
  387. " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  388. "$Response$* response, "
  389. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  390. printer->Indent();
  391. printer->Print(
  392. *vars,
  393. "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
  394. "$AsyncPrefix$$Method$Raw(context, response, "
  395. "cq$AsyncRawArgs$));\n");
  396. printer->Outdent();
  397. printer->Print("}\n");
  398. }
  399. } else if (ServerOnlyStreaming(method)) {
  400. printer->Print(
  401. *vars,
  402. "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
  403. " $Method$(::grpc::ClientContext* context, const $Request$& request)"
  404. " {\n");
  405. printer->Indent();
  406. printer->Print(
  407. *vars,
  408. "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
  409. "($Method$Raw(context, request));\n");
  410. printer->Outdent();
  411. printer->Print("}\n");
  412. for (auto async_prefix : async_prefixes) {
  413. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  414. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  415. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  416. printer->Print(
  417. *vars,
  418. "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
  419. "$AsyncPrefix$$Method$("
  420. "::grpc::ClientContext* context, const $Request$& request, "
  421. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  422. printer->Indent();
  423. printer->Print(
  424. *vars,
  425. "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
  426. "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
  427. printer->Outdent();
  428. printer->Print("}\n");
  429. }
  430. } else if (method->BidiStreaming()) {
  431. printer->Print(
  432. *vars,
  433. "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
  434. " $Method$(::grpc::ClientContext* context) {\n");
  435. printer->Indent();
  436. printer->Print(*vars,
  437. "return std::unique_ptr< "
  438. "::grpc::ClientReaderWriter< $Request$, $Response$>>("
  439. "$Method$Raw(context));\n");
  440. printer->Outdent();
  441. printer->Print("}\n");
  442. for (auto async_prefix : async_prefixes) {
  443. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  444. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  445. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  446. printer->Print(*vars,
  447. "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
  448. "$Request$, $Response$>> "
  449. "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  450. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  451. printer->Indent();
  452. printer->Print(
  453. *vars,
  454. "return std::unique_ptr< "
  455. "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
  456. "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
  457. printer->Outdent();
  458. printer->Print("}\n");
  459. }
  460. }
  461. } else {
  462. if (method->NoStreaming()) {
  463. for (auto async_prefix : async_prefixes) {
  464. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  465. printer->Print(
  466. *vars,
  467. "::grpc::ClientAsyncResponseReader< $Response$>* "
  468. "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  469. "const $Request$& request, "
  470. "::grpc::CompletionQueue* cq) override;\n");
  471. }
  472. } else if (ClientOnlyStreaming(method)) {
  473. printer->Print(*vars,
  474. "::grpc::ClientWriter< $Request$>* $Method$Raw("
  475. "::grpc::ClientContext* context, $Response$* response) "
  476. "override;\n");
  477. for (auto async_prefix : async_prefixes) {
  478. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  479. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  480. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  481. printer->Print(
  482. *vars,
  483. "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
  484. "::grpc::ClientContext* context, $Response$* response, "
  485. "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
  486. }
  487. } else if (ServerOnlyStreaming(method)) {
  488. printer->Print(*vars,
  489. "::grpc::ClientReader< $Response$>* $Method$Raw("
  490. "::grpc::ClientContext* context, const $Request$& request)"
  491. " override;\n");
  492. for (auto async_prefix : async_prefixes) {
  493. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  494. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  495. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  496. printer->Print(
  497. *vars,
  498. "::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw("
  499. "::grpc::ClientContext* context, const $Request$& request, "
  500. "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
  501. }
  502. } else if (method->BidiStreaming()) {
  503. printer->Print(*vars,
  504. "::grpc::ClientReaderWriter< $Request$, $Response$>* "
  505. "$Method$Raw(::grpc::ClientContext* context) override;\n");
  506. for (auto async_prefix : async_prefixes) {
  507. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  508. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  509. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  510. printer->Print(
  511. *vars,
  512. "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
  513. "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  514. "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
  515. }
  516. }
  517. }
  518. }
  519. void PrintHeaderClientMethodData(grpc_generator::Printer *printer,
  520. const grpc_generator::Method *method,
  521. std::map<grpc::string, grpc::string> *vars) {
  522. (*vars)["Method"] = method->name();
  523. printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
  524. }
  525. void PrintHeaderServerMethodSync(grpc_generator::Printer *printer,
  526. const grpc_generator::Method *method,
  527. std::map<grpc::string, grpc::string> *vars) {
  528. (*vars)["Method"] = method->name();
  529. (*vars)["Request"] = method->input_type_name();
  530. (*vars)["Response"] = method->output_type_name();
  531. printer->Print(method->GetLeadingComments("//").c_str());
  532. if (method->NoStreaming()) {
  533. printer->Print(*vars,
  534. "virtual ::grpc::Status $Method$("
  535. "::grpc::ServerContext* context, const $Request$* request, "
  536. "$Response$* response);\n");
  537. } else if (ClientOnlyStreaming(method)) {
  538. printer->Print(*vars,
  539. "virtual ::grpc::Status $Method$("
  540. "::grpc::ServerContext* context, "
  541. "::grpc::ServerReader< $Request$>* reader, "
  542. "$Response$* response);\n");
  543. } else if (ServerOnlyStreaming(method)) {
  544. printer->Print(*vars,
  545. "virtual ::grpc::Status $Method$("
  546. "::grpc::ServerContext* context, const $Request$* request, "
  547. "::grpc::ServerWriter< $Response$>* writer);\n");
  548. } else if (method->BidiStreaming()) {
  549. printer->Print(
  550. *vars,
  551. "virtual ::grpc::Status $Method$("
  552. "::grpc::ServerContext* context, "
  553. "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
  554. "\n");
  555. }
  556. printer->Print(method->GetTrailingComments("//").c_str());
  557. }
  558. void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer,
  559. const grpc_generator::Method *method,
  560. std::map<grpc::string, grpc::string> *vars) {
  561. (*vars)["Method"] = method->name();
  562. (*vars)["Request"] = method->input_type_name();
  563. (*vars)["Response"] = method->output_type_name();
  564. printer->Print(*vars, "template <class BaseClass>\n");
  565. printer->Print(*vars,
  566. "class WithAsyncMethod_$Method$ : public BaseClass {\n");
  567. printer->Print(
  568. " private:\n"
  569. " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  570. printer->Print(" public:\n");
  571. printer->Indent();
  572. printer->Print(*vars,
  573. "WithAsyncMethod_$Method$() {\n"
  574. " ::grpc::Service::MarkMethodAsync($Idx$);\n"
  575. "}\n");
  576. printer->Print(*vars,
  577. "~WithAsyncMethod_$Method$() override {\n"
  578. " BaseClassMustBeDerivedFromService(this);\n"
  579. "}\n");
  580. if (method->NoStreaming()) {
  581. printer->Print(
  582. *vars,
  583. "// disable synchronous version of this method\n"
  584. "::grpc::Status $Method$("
  585. "::grpc::ServerContext* context, const $Request$* request, "
  586. "$Response$* response) final override {\n"
  587. " abort();\n"
  588. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  589. "}\n");
  590. printer->Print(
  591. *vars,
  592. "void Request$Method$("
  593. "::grpc::ServerContext* context, $Request$* request, "
  594. "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
  595. "::grpc::CompletionQueue* new_call_cq, "
  596. "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
  597. printer->Print(*vars,
  598. " ::grpc::Service::RequestAsyncUnary($Idx$, context, "
  599. "request, response, new_call_cq, notification_cq, tag);\n");
  600. printer->Print("}\n");
  601. } else if (ClientOnlyStreaming(method)) {
  602. printer->Print(
  603. *vars,
  604. "// disable synchronous version of this method\n"
  605. "::grpc::Status $Method$("
  606. "::grpc::ServerContext* context, "
  607. "::grpc::ServerReader< $Request$>* reader, "
  608. "$Response$* response) final override {\n"
  609. " abort();\n"
  610. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  611. "}\n");
  612. printer->Print(
  613. *vars,
  614. "void Request$Method$("
  615. "::grpc::ServerContext* context, "
  616. "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
  617. "::grpc::CompletionQueue* new_call_cq, "
  618. "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
  619. printer->Print(*vars,
  620. " ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
  621. "context, reader, new_call_cq, notification_cq, tag);\n");
  622. printer->Print("}\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) final override "
  630. "{\n"
  631. " abort();\n"
  632. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  633. "}\n");
  634. printer->Print(
  635. *vars,
  636. "void Request$Method$("
  637. "::grpc::ServerContext* context, $Request$* request, "
  638. "::grpc::ServerAsyncWriter< $Response$>* writer, "
  639. "::grpc::CompletionQueue* new_call_cq, "
  640. "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
  641. printer->Print(
  642. *vars,
  643. " ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
  644. "context, request, writer, new_call_cq, notification_cq, tag);\n");
  645. printer->Print("}\n");
  646. } else if (method->BidiStreaming()) {
  647. printer->Print(
  648. *vars,
  649. "// disable synchronous version of this method\n"
  650. "::grpc::Status $Method$("
  651. "::grpc::ServerContext* context, "
  652. "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
  653. "final override {\n"
  654. " abort();\n"
  655. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  656. "}\n");
  657. printer->Print(
  658. *vars,
  659. "void Request$Method$("
  660. "::grpc::ServerContext* context, "
  661. "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
  662. "::grpc::CompletionQueue* new_call_cq, "
  663. "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
  664. printer->Print(*vars,
  665. " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
  666. "context, stream, new_call_cq, notification_cq, tag);\n");
  667. printer->Print("}\n");
  668. }
  669. printer->Outdent();
  670. printer->Print(*vars, "};\n");
  671. }
  672. void PrintHeaderServerMethodStreamedUnary(
  673. grpc_generator::Printer *printer, const grpc_generator::Method *method,
  674. std::map<grpc::string, grpc::string> *vars) {
  675. (*vars)["Method"] = method->name();
  676. (*vars)["Request"] = method->input_type_name();
  677. (*vars)["Response"] = method->output_type_name();
  678. if (method->NoStreaming()) {
  679. printer->Print(*vars, "template <class BaseClass>\n");
  680. printer->Print(*vars,
  681. "class WithStreamedUnaryMethod_$Method$ : "
  682. "public BaseClass {\n");
  683. printer->Print(
  684. " private:\n"
  685. " void BaseClassMustBeDerivedFromService(const Service *service) "
  686. "{}\n");
  687. printer->Print(" public:\n");
  688. printer->Indent();
  689. printer->Print(*vars,
  690. "WithStreamedUnaryMethod_$Method$() {\n"
  691. " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
  692. " new ::grpc::StreamedUnaryHandler< $Request$, "
  693. "$Response$>(std::bind"
  694. "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
  695. "Streamed$Method$, this, std::placeholders::_1, "
  696. "std::placeholders::_2)));\n"
  697. "}\n");
  698. printer->Print(*vars,
  699. "~WithStreamedUnaryMethod_$Method$() override {\n"
  700. " BaseClassMustBeDerivedFromService(this);\n"
  701. "}\n");
  702. printer->Print(
  703. *vars,
  704. "// disable regular version of this method\n"
  705. "::grpc::Status $Method$("
  706. "::grpc::ServerContext* context, const $Request$* request, "
  707. "$Response$* response) final override {\n"
  708. " abort();\n"
  709. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  710. "}\n");
  711. printer->Print(*vars,
  712. "// replace default version of method with streamed unary\n"
  713. "virtual ::grpc::Status Streamed$Method$("
  714. "::grpc::ServerContext* context, "
  715. "::grpc::ServerUnaryStreamer< "
  716. "$Request$,$Response$>* server_unary_streamer)"
  717. " = 0;\n");
  718. printer->Outdent();
  719. printer->Print(*vars, "};\n");
  720. }
  721. }
  722. void PrintHeaderServerMethodSplitStreaming(
  723. grpc_generator::Printer *printer, const grpc_generator::Method *method,
  724. std::map<grpc::string, grpc::string> *vars) {
  725. (*vars)["Method"] = method->name();
  726. (*vars)["Request"] = method->input_type_name();
  727. (*vars)["Response"] = method->output_type_name();
  728. if (ServerOnlyStreaming(method)) {
  729. printer->Print(*vars, "template <class BaseClass>\n");
  730. printer->Print(*vars,
  731. "class WithSplitStreamingMethod_$Method$ : "
  732. "public BaseClass {\n");
  733. printer->Print(
  734. " private:\n"
  735. " void BaseClassMustBeDerivedFromService(const Service *service) "
  736. "{}\n");
  737. printer->Print(" public:\n");
  738. printer->Indent();
  739. printer->Print(*vars,
  740. "WithSplitStreamingMethod_$Method$() {\n"
  741. " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
  742. " new ::grpc::SplitServerStreamingHandler< $Request$, "
  743. "$Response$>(std::bind"
  744. "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
  745. "Streamed$Method$, this, std::placeholders::_1, "
  746. "std::placeholders::_2)));\n"
  747. "}\n");
  748. printer->Print(*vars,
  749. "~WithSplitStreamingMethod_$Method$() override {\n"
  750. " BaseClassMustBeDerivedFromService(this);\n"
  751. "}\n");
  752. printer->Print(
  753. *vars,
  754. "// disable regular version of this method\n"
  755. "::grpc::Status $Method$("
  756. "::grpc::ServerContext* context, const $Request$* request, "
  757. "::grpc::ServerWriter< $Response$>* writer) final override "
  758. "{\n"
  759. " abort();\n"
  760. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  761. "}\n");
  762. printer->Print(*vars,
  763. "// replace default version of method with split streamed\n"
  764. "virtual ::grpc::Status Streamed$Method$("
  765. "::grpc::ServerContext* context, "
  766. "::grpc::ServerSplitStreamer< "
  767. "$Request$,$Response$>* server_split_streamer)"
  768. " = 0;\n");
  769. printer->Outdent();
  770. printer->Print(*vars, "};\n");
  771. }
  772. }
  773. void PrintHeaderServerMethodGeneric(
  774. grpc_generator::Printer *printer, const grpc_generator::Method *method,
  775. std::map<grpc::string, grpc::string> *vars) {
  776. (*vars)["Method"] = method->name();
  777. (*vars)["Request"] = method->input_type_name();
  778. (*vars)["Response"] = method->output_type_name();
  779. printer->Print(*vars, "template <class BaseClass>\n");
  780. printer->Print(*vars,
  781. "class WithGenericMethod_$Method$ : public BaseClass {\n");
  782. printer->Print(
  783. " private:\n"
  784. " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  785. printer->Print(" public:\n");
  786. printer->Indent();
  787. printer->Print(*vars,
  788. "WithGenericMethod_$Method$() {\n"
  789. " ::grpc::Service::MarkMethodGeneric($Idx$);\n"
  790. "}\n");
  791. printer->Print(*vars,
  792. "~WithGenericMethod_$Method$() override {\n"
  793. " BaseClassMustBeDerivedFromService(this);\n"
  794. "}\n");
  795. if (method->NoStreaming()) {
  796. printer->Print(
  797. *vars,
  798. "// disable synchronous version of this method\n"
  799. "::grpc::Status $Method$("
  800. "::grpc::ServerContext* context, const $Request$* request, "
  801. "$Response$* response) final override {\n"
  802. " abort();\n"
  803. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  804. "}\n");
  805. } else if (ClientOnlyStreaming(method)) {
  806. printer->Print(
  807. *vars,
  808. "// disable synchronous version of this method\n"
  809. "::grpc::Status $Method$("
  810. "::grpc::ServerContext* context, "
  811. "::grpc::ServerReader< $Request$>* reader, "
  812. "$Response$* response) final override {\n"
  813. " abort();\n"
  814. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  815. "}\n");
  816. } else if (ServerOnlyStreaming(method)) {
  817. printer->Print(
  818. *vars,
  819. "// disable synchronous version of this method\n"
  820. "::grpc::Status $Method$("
  821. "::grpc::ServerContext* context, const $Request$* request, "
  822. "::grpc::ServerWriter< $Response$>* writer) final override "
  823. "{\n"
  824. " abort();\n"
  825. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  826. "}\n");
  827. } else if (method->BidiStreaming()) {
  828. printer->Print(
  829. *vars,
  830. "// disable synchronous version of this method\n"
  831. "::grpc::Status $Method$("
  832. "::grpc::ServerContext* context, "
  833. "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
  834. "final override {\n"
  835. " abort();\n"
  836. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  837. "}\n");
  838. }
  839. printer->Outdent();
  840. printer->Print(*vars, "};\n");
  841. }
  842. void PrintHeaderService(grpc_generator::Printer *printer,
  843. const grpc_generator::Service *service,
  844. std::map<grpc::string, grpc::string> *vars) {
  845. (*vars)["Service"] = service->name();
  846. printer->Print(service->GetLeadingComments("//").c_str());
  847. printer->Print(*vars,
  848. "class $Service$ final {\n"
  849. " public:\n");
  850. printer->Indent();
  851. // Service metadata
  852. printer->Print(*vars,
  853. "static constexpr char const* service_full_name() {\n"
  854. " return \"$Package$$Service$\";\n"
  855. "}\n");
  856. // Client side
  857. printer->Print(
  858. "class StubInterface {\n"
  859. " public:\n");
  860. printer->Indent();
  861. printer->Print("virtual ~StubInterface() {}\n");
  862. for (int i = 0; i < service->method_count(); ++i) {
  863. printer->Print(service->method(i)->GetLeadingComments("//").c_str());
  864. PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
  865. true);
  866. printer->Print(service->method(i)->GetTrailingComments("//").c_str());
  867. }
  868. printer->Outdent();
  869. printer->Print("private:\n");
  870. printer->Indent();
  871. for (int i = 0; i < service->method_count(); ++i) {
  872. PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
  873. false);
  874. }
  875. printer->Outdent();
  876. printer->Print("};\n");
  877. printer->Print(
  878. "class Stub final : public StubInterface"
  879. " {\n public:\n");
  880. printer->Indent();
  881. printer->Print(
  882. "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
  883. for (int i = 0; i < service->method_count(); ++i) {
  884. PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
  885. }
  886. printer->Outdent();
  887. printer->Print("\n private:\n");
  888. printer->Indent();
  889. printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
  890. for (int i = 0; i < service->method_count(); ++i) {
  891. PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
  892. }
  893. for (int i = 0; i < service->method_count(); ++i) {
  894. PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
  895. }
  896. printer->Outdent();
  897. printer->Print("};\n");
  898. printer->Print(
  899. "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
  900. "::grpc::ChannelInterface>& channel, "
  901. "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
  902. printer->Print("\n");
  903. // Server side - base
  904. printer->Print(
  905. "class Service : public ::grpc::Service {\n"
  906. " public:\n");
  907. printer->Indent();
  908. printer->Print("Service();\n");
  909. printer->Print("virtual ~Service();\n");
  910. for (int i = 0; i < service->method_count(); ++i) {
  911. PrintHeaderServerMethodSync(printer, service->method(i).get(), vars);
  912. }
  913. printer->Outdent();
  914. printer->Print("};\n");
  915. // Server side - Asynchronous
  916. for (int i = 0; i < service->method_count(); ++i) {
  917. (*vars)["Idx"] = as_string(i);
  918. PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars);
  919. }
  920. printer->Print("typedef ");
  921. for (int i = 0; i < service->method_count(); ++i) {
  922. (*vars)["method_name"] = service->method(i).get()->name();
  923. printer->Print(*vars, "WithAsyncMethod_$method_name$<");
  924. }
  925. printer->Print("Service");
  926. for (int i = 0; i < service->method_count(); ++i) {
  927. printer->Print(" >");
  928. }
  929. printer->Print(" AsyncService;\n");
  930. // Server side - Generic
  931. for (int i = 0; i < service->method_count(); ++i) {
  932. (*vars)["Idx"] = as_string(i);
  933. PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
  934. }
  935. // Server side - Streamed Unary
  936. for (int i = 0; i < service->method_count(); ++i) {
  937. (*vars)["Idx"] = as_string(i);
  938. PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
  939. vars);
  940. }
  941. printer->Print("typedef ");
  942. for (int i = 0; i < service->method_count(); ++i) {
  943. (*vars)["method_name"] = service->method(i).get()->name();
  944. if (service->method(i)->NoStreaming()) {
  945. printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
  946. }
  947. }
  948. printer->Print("Service");
  949. for (int i = 0; i < service->method_count(); ++i) {
  950. if (service->method(i)->NoStreaming()) {
  951. printer->Print(" >");
  952. }
  953. }
  954. printer->Print(" StreamedUnaryService;\n");
  955. // Server side - controlled server-side streaming
  956. for (int i = 0; i < service->method_count(); ++i) {
  957. (*vars)["Idx"] = as_string(i);
  958. PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(),
  959. vars);
  960. }
  961. printer->Print("typedef ");
  962. for (int i = 0; i < service->method_count(); ++i) {
  963. (*vars)["method_name"] = service->method(i).get()->name();
  964. auto method = service->method(i);
  965. if (ServerOnlyStreaming(method.get())) {
  966. printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
  967. }
  968. }
  969. printer->Print("Service");
  970. for (int i = 0; i < service->method_count(); ++i) {
  971. auto method = service->method(i);
  972. if (ServerOnlyStreaming(method.get())) {
  973. printer->Print(" >");
  974. }
  975. }
  976. printer->Print(" SplitStreamedService;\n");
  977. // Server side - typedef for controlled both unary and server-side streaming
  978. printer->Print("typedef ");
  979. for (int i = 0; i < service->method_count(); ++i) {
  980. (*vars)["method_name"] = service->method(i).get()->name();
  981. auto method = service->method(i);
  982. if (ServerOnlyStreaming(method.get())) {
  983. printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
  984. }
  985. if (service->method(i)->NoStreaming()) {
  986. printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
  987. }
  988. }
  989. printer->Print("Service");
  990. for (int i = 0; i < service->method_count(); ++i) {
  991. auto method = service->method(i);
  992. if (service->method(i)->NoStreaming() ||
  993. ServerOnlyStreaming(method.get())) {
  994. printer->Print(" >");
  995. }
  996. }
  997. printer->Print(" StreamedService;\n");
  998. printer->Outdent();
  999. printer->Print("};\n");
  1000. printer->Print(service->GetTrailingComments("//").c_str());
  1001. }
  1002. grpc::string GetHeaderServices(grpc_generator::File *file,
  1003. const Parameters &params) {
  1004. grpc::string output;
  1005. {
  1006. // Scope the output stream so it closes and finalizes output to the string.
  1007. auto printer = file->CreatePrinter(&output);
  1008. std::map<grpc::string, grpc::string> vars;
  1009. // Package string is empty or ends with a dot. It is used to fully qualify
  1010. // method names.
  1011. vars["Package"] = file->package();
  1012. if (!file->package().empty()) {
  1013. vars["Package"].append(".");
  1014. }
  1015. if (!params.services_namespace.empty()) {
  1016. vars["services_namespace"] = params.services_namespace;
  1017. printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
  1018. }
  1019. for (int i = 0; i < file->service_count(); ++i) {
  1020. PrintHeaderService(printer.get(), file->service(i).get(), &vars);
  1021. printer->Print("\n");
  1022. }
  1023. if (!params.services_namespace.empty()) {
  1024. printer->Print(vars, "} // namespace $services_namespace$\n\n");
  1025. }
  1026. }
  1027. return output;
  1028. }
  1029. grpc::string GetHeaderEpilogue(grpc_generator::File *file,
  1030. const Parameters & /*params*/) {
  1031. grpc::string output;
  1032. {
  1033. // Scope the output stream so it closes and finalizes output to the string.
  1034. auto printer = file->CreatePrinter(&output);
  1035. std::map<grpc::string, grpc::string> vars;
  1036. vars["filename"] = file->filename();
  1037. vars["filename_identifier"] = FilenameIdentifier(file->filename());
  1038. if (!file->package().empty()) {
  1039. std::vector<grpc::string> parts = file->package_parts();
  1040. for (auto part = parts.rbegin(); part != parts.rend(); part++) {
  1041. vars["part"] = *part;
  1042. printer->Print(vars, "} // namespace $part$\n");
  1043. }
  1044. printer->Print(vars, "\n");
  1045. }
  1046. printer->Print(vars, "\n");
  1047. printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
  1048. printer->Print(file->GetTrailingComments("//").c_str());
  1049. }
  1050. return output;
  1051. }
  1052. grpc::string GetSourcePrologue(grpc_generator::File *file,
  1053. const Parameters & /*params*/) {
  1054. grpc::string output;
  1055. {
  1056. // Scope the output stream so it closes and finalizes output to the string.
  1057. auto printer = file->CreatePrinter(&output);
  1058. std::map<grpc::string, grpc::string> vars;
  1059. vars["filename"] = file->filename();
  1060. vars["filename_base"] = file->filename_without_ext();
  1061. vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
  1062. vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
  1063. printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
  1064. printer->Print(vars,
  1065. "// If you make any local change, they will be lost.\n");
  1066. printer->Print(vars, "// source: $filename$\n\n");
  1067. printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
  1068. printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
  1069. printer->Print(vars, "\n");
  1070. }
  1071. return output;
  1072. }
  1073. grpc::string GetSourceIncludes(grpc_generator::File *file,
  1074. const Parameters &params) {
  1075. grpc::string output;
  1076. {
  1077. // Scope the output stream so it closes and finalizes output to the string.
  1078. auto printer = file->CreatePrinter(&output);
  1079. std::map<grpc::string, grpc::string> vars;
  1080. static const char *headers_strs[] = {
  1081. "grpc++/impl/codegen/async_stream.h",
  1082. "grpc++/impl/codegen/async_unary_call.h",
  1083. "grpc++/impl/codegen/channel_interface.h",
  1084. "grpc++/impl/codegen/client_unary_call.h",
  1085. "grpc++/impl/codegen/method_handler_impl.h",
  1086. "grpc++/impl/codegen/rpc_service_method.h",
  1087. "grpc++/impl/codegen/service_type.h",
  1088. "grpc++/impl/codegen/sync_stream.h"};
  1089. std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
  1090. PrintIncludes(printer.get(), headers, params);
  1091. if (!file->package().empty()) {
  1092. std::vector<grpc::string> parts = file->package_parts();
  1093. for (auto part = parts.begin(); part != parts.end(); part++) {
  1094. vars["part"] = *part;
  1095. printer->Print(vars, "namespace $part$ {\n");
  1096. }
  1097. }
  1098. printer->Print(vars, "\n");
  1099. }
  1100. return output;
  1101. }
  1102. void PrintSourceClientMethod(grpc_generator::Printer *printer,
  1103. const grpc_generator::Method *method,
  1104. std::map<grpc::string, grpc::string> *vars) {
  1105. (*vars)["Method"] = method->name();
  1106. (*vars)["Request"] = method->input_type_name();
  1107. (*vars)["Response"] = method->output_type_name();
  1108. struct {
  1109. grpc::string prefix;
  1110. grpc::string start; // bool literal expressed as string
  1111. grpc::string method_params; // extra arguments to method
  1112. grpc::string create_args; // extra arguments to creator
  1113. } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
  1114. {"PrepareAsync", "false", "", ", nullptr"}};
  1115. if (method->NoStreaming()) {
  1116. printer->Print(*vars,
  1117. "::grpc::Status $ns$$Service$::Stub::$Method$("
  1118. "::grpc::ClientContext* context, "
  1119. "const $Request$& request, $Response$* response) {\n");
  1120. printer->Print(*vars,
  1121. " return ::grpc::BlockingUnaryCall(channel_.get(), "
  1122. "rpcmethod_$Method$_, "
  1123. "context, request, response);\n"
  1124. "}\n\n");
  1125. for (auto async_prefix : async_prefixes) {
  1126. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1127. (*vars)["AsyncStart"] = async_prefix.start;
  1128. printer->Print(*vars,
  1129. "::grpc::ClientAsyncResponseReader< $Response$>* "
  1130. "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
  1131. "ClientContext* context, "
  1132. "const $Request$& request, "
  1133. "::grpc::CompletionQueue* cq) {\n");
  1134. printer->Print(*vars,
  1135. " return "
  1136. "::grpc::ClientAsyncResponseReader< $Response$>::Create("
  1137. "channel_.get(), cq, "
  1138. "rpcmethod_$Method$_, "
  1139. "context, request, $AsyncStart$);\n"
  1140. "}\n\n");
  1141. }
  1142. } else if (ClientOnlyStreaming(method)) {
  1143. printer->Print(*vars,
  1144. "::grpc::ClientWriter< $Request$>* "
  1145. "$ns$$Service$::Stub::$Method$Raw("
  1146. "::grpc::ClientContext* context, $Response$* response) {\n");
  1147. printer->Print(*vars,
  1148. " return new ::grpc::ClientWriter< $Request$>("
  1149. "channel_.get(), "
  1150. "rpcmethod_$Method$_, "
  1151. "context, response);\n"
  1152. "}\n\n");
  1153. for (auto async_prefix : async_prefixes) {
  1154. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1155. (*vars)["AsyncStart"] = async_prefix.start;
  1156. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1157. (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
  1158. printer->Print(*vars,
  1159. "::grpc::ClientAsyncWriter< $Request$>* "
  1160. "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
  1161. "::grpc::ClientContext* context, $Response$* response, "
  1162. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  1163. printer->Print(*vars,
  1164. " return ::grpc::ClientAsyncWriter< $Request$>::Create("
  1165. "channel_.get(), cq, "
  1166. "rpcmethod_$Method$_, "
  1167. "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
  1168. "}\n\n");
  1169. }
  1170. } else if (ServerOnlyStreaming(method)) {
  1171. printer->Print(
  1172. *vars,
  1173. "::grpc::ClientReader< $Response$>* "
  1174. "$ns$$Service$::Stub::$Method$Raw("
  1175. "::grpc::ClientContext* context, const $Request$& request) {\n");
  1176. printer->Print(*vars,
  1177. " return new ::grpc::ClientReader< $Response$>("
  1178. "channel_.get(), "
  1179. "rpcmethod_$Method$_, "
  1180. "context, request);\n"
  1181. "}\n\n");
  1182. for (auto async_prefix : async_prefixes) {
  1183. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1184. (*vars)["AsyncStart"] = async_prefix.start;
  1185. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1186. (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
  1187. printer->Print(
  1188. *vars,
  1189. "::grpc::ClientAsyncReader< $Response$>* "
  1190. "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
  1191. "::grpc::ClientContext* context, const $Request$& request, "
  1192. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  1193. printer->Print(*vars,
  1194. " return ::grpc::ClientAsyncReader< $Response$>::Create("
  1195. "channel_.get(), cq, "
  1196. "rpcmethod_$Method$_, "
  1197. "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
  1198. "}\n\n");
  1199. }
  1200. } else if (method->BidiStreaming()) {
  1201. printer->Print(
  1202. *vars,
  1203. "::grpc::ClientReaderWriter< $Request$, $Response$>* "
  1204. "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
  1205. printer->Print(*vars,
  1206. " return new ::grpc::ClientReaderWriter< "
  1207. "$Request$, $Response$>("
  1208. "channel_.get(), "
  1209. "rpcmethod_$Method$_, "
  1210. "context);\n"
  1211. "}\n\n");
  1212. for (auto async_prefix : async_prefixes) {
  1213. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1214. (*vars)["AsyncStart"] = async_prefix.start;
  1215. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1216. (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
  1217. printer->Print(*vars,
  1218. "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
  1219. "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
  1220. "ClientContext* context, "
  1221. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  1222. printer->Print(
  1223. *vars,
  1224. " return "
  1225. "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>::Create("
  1226. "channel_.get(), cq, "
  1227. "rpcmethod_$Method$_, "
  1228. "context, $AsyncStart$$AsyncCreateArgs$);\n"
  1229. "}\n\n");
  1230. }
  1231. }
  1232. }
  1233. void PrintSourceServerMethod(grpc_generator::Printer *printer,
  1234. const grpc_generator::Method *method,
  1235. std::map<grpc::string, grpc::string> *vars) {
  1236. (*vars)["Method"] = method->name();
  1237. (*vars)["Request"] = method->input_type_name();
  1238. (*vars)["Response"] = method->output_type_name();
  1239. if (method->NoStreaming()) {
  1240. printer->Print(*vars,
  1241. "::grpc::Status $ns$$Service$::Service::$Method$("
  1242. "::grpc::ServerContext* context, "
  1243. "const $Request$* request, $Response$* response) {\n");
  1244. printer->Print(" (void) context;\n");
  1245. printer->Print(" (void) request;\n");
  1246. printer->Print(" (void) response;\n");
  1247. printer->Print(
  1248. " return ::grpc::Status("
  1249. "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
  1250. printer->Print("}\n\n");
  1251. } else if (ClientOnlyStreaming(method)) {
  1252. printer->Print(*vars,
  1253. "::grpc::Status $ns$$Service$::Service::$Method$("
  1254. "::grpc::ServerContext* context, "
  1255. "::grpc::ServerReader< $Request$>* reader, "
  1256. "$Response$* response) {\n");
  1257. printer->Print(" (void) context;\n");
  1258. printer->Print(" (void) reader;\n");
  1259. printer->Print(" (void) response;\n");
  1260. printer->Print(
  1261. " return ::grpc::Status("
  1262. "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
  1263. printer->Print("}\n\n");
  1264. } else if (ServerOnlyStreaming(method)) {
  1265. printer->Print(*vars,
  1266. "::grpc::Status $ns$$Service$::Service::$Method$("
  1267. "::grpc::ServerContext* context, "
  1268. "const $Request$* request, "
  1269. "::grpc::ServerWriter< $Response$>* writer) {\n");
  1270. printer->Print(" (void) context;\n");
  1271. printer->Print(" (void) request;\n");
  1272. printer->Print(" (void) writer;\n");
  1273. printer->Print(
  1274. " return ::grpc::Status("
  1275. "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
  1276. printer->Print("}\n\n");
  1277. } else if (method->BidiStreaming()) {
  1278. printer->Print(*vars,
  1279. "::grpc::Status $ns$$Service$::Service::$Method$("
  1280. "::grpc::ServerContext* context, "
  1281. "::grpc::ServerReaderWriter< $Response$, $Request$>* "
  1282. "stream) {\n");
  1283. printer->Print(" (void) context;\n");
  1284. printer->Print(" (void) stream;\n");
  1285. printer->Print(
  1286. " return ::grpc::Status("
  1287. "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
  1288. printer->Print("}\n\n");
  1289. }
  1290. }
  1291. void PrintSourceService(grpc_generator::Printer *printer,
  1292. const grpc_generator::Service *service,
  1293. std::map<grpc::string, grpc::string> *vars) {
  1294. (*vars)["Service"] = service->name();
  1295. if (service->method_count() > 0) {
  1296. printer->Print(*vars,
  1297. "static const char* $prefix$$Service$_method_names[] = {\n");
  1298. for (int i = 0; i < service->method_count(); ++i) {
  1299. (*vars)["Method"] = service->method(i).get()->name();
  1300. printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
  1301. }
  1302. printer->Print(*vars, "};\n\n");
  1303. }
  1304. printer->Print(*vars,
  1305. "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
  1306. "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
  1307. "const ::grpc::StubOptions& options) {\n"
  1308. " std::unique_ptr< $ns$$Service$::Stub> stub(new "
  1309. "$ns$$Service$::Stub(channel));\n"
  1310. " return stub;\n"
  1311. "}\n\n");
  1312. printer->Print(*vars,
  1313. "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
  1314. "::grpc::ChannelInterface>& channel)\n");
  1315. printer->Indent();
  1316. printer->Print(": channel_(channel)");
  1317. for (int i = 0; i < service->method_count(); ++i) {
  1318. auto method = service->method(i);
  1319. (*vars)["Method"] = method->name();
  1320. (*vars)["Idx"] = as_string(i);
  1321. if (method->NoStreaming()) {
  1322. (*vars)["StreamingType"] = "NORMAL_RPC";
  1323. // NOTE: There is no reason to consider streamed-unary as a separate
  1324. // category here since this part is setting up the client-side stub
  1325. // and this appears as a NORMAL_RPC from the client-side.
  1326. } else if (ClientOnlyStreaming(method.get())) {
  1327. (*vars)["StreamingType"] = "CLIENT_STREAMING";
  1328. } else if (ServerOnlyStreaming(method.get())) {
  1329. (*vars)["StreamingType"] = "SERVER_STREAMING";
  1330. } else {
  1331. (*vars)["StreamingType"] = "BIDI_STREAMING";
  1332. }
  1333. printer->Print(*vars,
  1334. ", rpcmethod_$Method$_("
  1335. "$prefix$$Service$_method_names[$Idx$], "
  1336. "::grpc::RpcMethod::$StreamingType$, "
  1337. "channel"
  1338. ")\n");
  1339. }
  1340. printer->Print("{}\n\n");
  1341. printer->Outdent();
  1342. for (int i = 0; i < service->method_count(); ++i) {
  1343. (*vars)["Idx"] = as_string(i);
  1344. PrintSourceClientMethod(printer, service->method(i).get(), vars);
  1345. }
  1346. printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
  1347. printer->Indent();
  1348. for (int i = 0; i < service->method_count(); ++i) {
  1349. auto method = service->method(i);
  1350. (*vars)["Idx"] = as_string(i);
  1351. (*vars)["Method"] = method->name();
  1352. (*vars)["Request"] = method->input_type_name();
  1353. (*vars)["Response"] = method->output_type_name();
  1354. if (method->NoStreaming()) {
  1355. printer->Print(
  1356. *vars,
  1357. "AddMethod(new ::grpc::RpcServiceMethod(\n"
  1358. " $prefix$$Service$_method_names[$Idx$],\n"
  1359. " ::grpc::RpcMethod::NORMAL_RPC,\n"
  1360. " new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
  1361. "$Request$, "
  1362. "$Response$>(\n"
  1363. " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
  1364. } else if (ClientOnlyStreaming(method.get())) {
  1365. printer->Print(
  1366. *vars,
  1367. "AddMethod(new ::grpc::RpcServiceMethod(\n"
  1368. " $prefix$$Service$_method_names[$Idx$],\n"
  1369. " ::grpc::RpcMethod::CLIENT_STREAMING,\n"
  1370. " new ::grpc::ClientStreamingHandler< "
  1371. "$ns$$Service$::Service, $Request$, $Response$>(\n"
  1372. " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
  1373. } else if (ServerOnlyStreaming(method.get())) {
  1374. printer->Print(
  1375. *vars,
  1376. "AddMethod(new ::grpc::RpcServiceMethod(\n"
  1377. " $prefix$$Service$_method_names[$Idx$],\n"
  1378. " ::grpc::RpcMethod::SERVER_STREAMING,\n"
  1379. " new ::grpc::ServerStreamingHandler< "
  1380. "$ns$$Service$::Service, $Request$, $Response$>(\n"
  1381. " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
  1382. } else if (method->BidiStreaming()) {
  1383. printer->Print(
  1384. *vars,
  1385. "AddMethod(new ::grpc::RpcServiceMethod(\n"
  1386. " $prefix$$Service$_method_names[$Idx$],\n"
  1387. " ::grpc::RpcMethod::BIDI_STREAMING,\n"
  1388. " new ::grpc::BidiStreamingHandler< "
  1389. "$ns$$Service$::Service, $Request$, $Response$>(\n"
  1390. " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
  1391. }
  1392. }
  1393. printer->Outdent();
  1394. printer->Print(*vars, "}\n\n");
  1395. printer->Print(*vars,
  1396. "$ns$$Service$::Service::~Service() {\n"
  1397. "}\n\n");
  1398. for (int i = 0; i < service->method_count(); ++i) {
  1399. (*vars)["Idx"] = as_string(i);
  1400. PrintSourceServerMethod(printer, service->method(i).get(), vars);
  1401. }
  1402. }
  1403. grpc::string GetSourceServices(grpc_generator::File *file,
  1404. const Parameters &params) {
  1405. grpc::string output;
  1406. {
  1407. // Scope the output stream so it closes and finalizes output to the string.
  1408. auto printer = file->CreatePrinter(&output);
  1409. std::map<grpc::string, grpc::string> vars;
  1410. // Package string is empty or ends with a dot. It is used to fully qualify
  1411. // method names.
  1412. vars["Package"] = file->package();
  1413. if (!file->package().empty()) {
  1414. vars["Package"].append(".");
  1415. }
  1416. if (!params.services_namespace.empty()) {
  1417. vars["ns"] = params.services_namespace + "::";
  1418. vars["prefix"] = params.services_namespace;
  1419. } else {
  1420. vars["ns"] = "";
  1421. vars["prefix"] = "";
  1422. }
  1423. for (int i = 0; i < file->service_count(); ++i) {
  1424. PrintSourceService(printer.get(), file->service(i).get(), &vars);
  1425. printer->Print("\n");
  1426. }
  1427. }
  1428. return output;
  1429. }
  1430. grpc::string GetSourceEpilogue(grpc_generator::File *file,
  1431. const Parameters & /*params*/) {
  1432. grpc::string temp;
  1433. if (!file->package().empty()) {
  1434. std::vector<grpc::string> parts = file->package_parts();
  1435. for (auto part = parts.begin(); part != parts.end(); part++) {
  1436. temp.append("} // namespace ");
  1437. temp.append(*part);
  1438. temp.append("\n");
  1439. }
  1440. temp.append("\n");
  1441. }
  1442. return temp;
  1443. }
  1444. // TODO(mmukhi): Make sure we need parameters or not.
  1445. grpc::string GetMockPrologue(grpc_generator::File *file,
  1446. const Parameters & /*params*/) {
  1447. grpc::string output;
  1448. {
  1449. // Scope the output stream so it closes and finalizes output to the string.
  1450. auto printer = file->CreatePrinter(&output);
  1451. std::map<grpc::string, grpc::string> vars;
  1452. vars["filename"] = file->filename();
  1453. vars["filename_base"] = file->filename_without_ext();
  1454. vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
  1455. vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
  1456. printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
  1457. printer->Print(vars,
  1458. "// If you make any local change, they will be lost.\n");
  1459. printer->Print(vars, "// source: $filename$\n\n");
  1460. printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
  1461. printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
  1462. printer->Print(vars, file->additional_headers().c_str());
  1463. printer->Print(vars, "\n");
  1464. }
  1465. return output;
  1466. }
  1467. // TODO(mmukhi): Add client-stream and completion-queue headers.
  1468. grpc::string GetMockIncludes(grpc_generator::File *file,
  1469. const Parameters &params) {
  1470. grpc::string output;
  1471. {
  1472. // Scope the output stream so it closes and finalizes output to the string.
  1473. auto printer = file->CreatePrinter(&output);
  1474. std::map<grpc::string, grpc::string> vars;
  1475. static const char *headers_strs[] = {
  1476. "grpc++/impl/codegen/async_stream.h",
  1477. "grpc++/impl/codegen/sync_stream.h", "gmock/gmock.h",
  1478. };
  1479. std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
  1480. PrintIncludes(printer.get(), headers, params);
  1481. if (!file->package().empty()) {
  1482. std::vector<grpc::string> parts = file->package_parts();
  1483. for (auto part = parts.begin(); part != parts.end(); part++) {
  1484. vars["part"] = *part;
  1485. printer->Print(vars, "namespace $part$ {\n");
  1486. }
  1487. }
  1488. printer->Print(vars, "\n");
  1489. }
  1490. return output;
  1491. }
  1492. void PrintMockClientMethods(grpc_generator::Printer *printer,
  1493. const grpc_generator::Method *method,
  1494. std::map<grpc::string, grpc::string> *vars) {
  1495. (*vars)["Method"] = method->name();
  1496. (*vars)["Request"] = method->input_type_name();
  1497. (*vars)["Response"] = method->output_type_name();
  1498. struct {
  1499. grpc::string prefix;
  1500. grpc::string method_params; // extra arguments to method
  1501. int extra_method_param_count;
  1502. } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
  1503. if (method->NoStreaming()) {
  1504. printer->Print(
  1505. *vars,
  1506. "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
  1507. "const $Request$& request, $Response$* response));\n");
  1508. for (auto async_prefix : async_prefixes) {
  1509. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1510. printer->Print(
  1511. *vars,
  1512. "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
  1513. "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
  1514. "(::grpc::ClientContext* context, const $Request$& request, "
  1515. "::grpc::CompletionQueue* cq));\n");
  1516. }
  1517. } else if (ClientOnlyStreaming(method)) {
  1518. printer->Print(
  1519. *vars,
  1520. "MOCK_METHOD2($Method$Raw, "
  1521. "::grpc::ClientWriterInterface< $Request$>*"
  1522. "(::grpc::ClientContext* context, $Response$* response));\n");
  1523. for (auto async_prefix : async_prefixes) {
  1524. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1525. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1526. (*vars)["MockArgs"] =
  1527. std::to_string(3 + async_prefix.extra_method_param_count);
  1528. printer->Print(*vars,
  1529. "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
  1530. "::grpc::ClientAsyncWriterInterface< $Request$>*"
  1531. "(::grpc::ClientContext* context, $Response$* response, "
  1532. "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
  1533. }
  1534. } else if (ServerOnlyStreaming(method)) {
  1535. printer->Print(
  1536. *vars,
  1537. "MOCK_METHOD2($Method$Raw, "
  1538. "::grpc::ClientReaderInterface< $Response$>*"
  1539. "(::grpc::ClientContext* context, const $Request$& request));\n");
  1540. for (auto async_prefix : async_prefixes) {
  1541. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1542. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1543. (*vars)["MockArgs"] =
  1544. std::to_string(3 + async_prefix.extra_method_param_count);
  1545. printer->Print(
  1546. *vars,
  1547. "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
  1548. "::grpc::ClientAsyncReaderInterface< $Response$>*"
  1549. "(::grpc::ClientContext* context, const $Request$& request, "
  1550. "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
  1551. }
  1552. } else if (method->BidiStreaming()) {
  1553. printer->Print(
  1554. *vars,
  1555. "MOCK_METHOD1($Method$Raw, "
  1556. "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
  1557. "(::grpc::ClientContext* context));\n");
  1558. for (auto async_prefix : async_prefixes) {
  1559. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1560. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1561. (*vars)["MockArgs"] =
  1562. std::to_string(2 + async_prefix.extra_method_param_count);
  1563. printer->Print(
  1564. *vars,
  1565. "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
  1566. "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
  1567. "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
  1568. "$AsyncMethodParams$));\n");
  1569. }
  1570. }
  1571. }
  1572. void PrintMockService(grpc_generator::Printer *printer,
  1573. const grpc_generator::Service *service,
  1574. std::map<grpc::string, grpc::string> *vars) {
  1575. (*vars)["Service"] = service->name();
  1576. printer->Print(*vars,
  1577. "class Mock$Service$Stub : public $Service$::StubInterface {\n"
  1578. " public:\n");
  1579. printer->Indent();
  1580. for (int i = 0; i < service->method_count(); ++i) {
  1581. PrintMockClientMethods(printer, service->method(i).get(), vars);
  1582. }
  1583. printer->Outdent();
  1584. printer->Print("};\n");
  1585. }
  1586. grpc::string GetMockServices(grpc_generator::File *file,
  1587. const Parameters &params) {
  1588. grpc::string output;
  1589. {
  1590. // Scope the output stream so it closes and finalizes output to the string.
  1591. auto printer = file->CreatePrinter(&output);
  1592. std::map<grpc::string, grpc::string> vars;
  1593. // Package string is empty or ends with a dot. It is used to fully qualify
  1594. // method names.
  1595. vars["Package"] = file->package();
  1596. if (!file->package().empty()) {
  1597. vars["Package"].append(".");
  1598. }
  1599. if (!params.services_namespace.empty()) {
  1600. vars["services_namespace"] = params.services_namespace;
  1601. printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
  1602. }
  1603. for (int i = 0; i < file->service_count(); i++) {
  1604. PrintMockService(printer.get(), file->service(i).get(), &vars);
  1605. printer->Print("\n");
  1606. }
  1607. if (!params.services_namespace.empty()) {
  1608. printer->Print(vars, "} // namespace $services_namespace$\n\n");
  1609. }
  1610. }
  1611. return output;
  1612. }
  1613. grpc::string GetMockEpilogue(grpc_generator::File *file,
  1614. const Parameters & /*params*/) {
  1615. grpc::string temp;
  1616. if (!file->package().empty()) {
  1617. std::vector<grpc::string> parts = file->package_parts();
  1618. for (auto part = parts.begin(); part != parts.end(); part++) {
  1619. temp.append("} // namespace ");
  1620. temp.append(*part);
  1621. temp.append("\n");
  1622. }
  1623. temp.append("\n");
  1624. }
  1625. return temp;
  1626. }
  1627. } // namespace grpc_cpp_generator