cpp_generator.cc 89 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247
  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. bool use_system_headers, const grpc::string& search_path) {
  58. std::map<grpc::string, grpc::string> vars;
  59. vars["l"] = use_system_headers ? '<' : '"';
  60. vars["r"] = use_system_headers ? '>' : '"';
  61. if (!search_path.empty()) {
  62. vars["l"] += search_path;
  63. if (search_path[search_path.size() - 1] != '/') {
  64. vars["l"] += '/';
  65. }
  66. }
  67. for (auto i = headers.begin(); i != headers.end(); i++) {
  68. vars["h"] = *i;
  69. printer->Print(vars, "#include $l$$h$$r$\n");
  70. }
  71. }
  72. grpc::string GetHeaderPrologue(grpc_generator::File* file,
  73. const Parameters& /*params*/) {
  74. grpc::string output;
  75. {
  76. // Scope the output stream so it closes and finalizes output to the string.
  77. auto printer = file->CreatePrinter(&output);
  78. std::map<grpc::string, grpc::string> vars;
  79. vars["filename"] = file->filename();
  80. vars["filename_identifier"] = FilenameIdentifier(file->filename());
  81. vars["filename_base"] = file->filename_without_ext();
  82. vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
  83. printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
  84. printer->Print(vars,
  85. "// If you make any local change, they will be lost.\n");
  86. printer->Print(vars, "// source: $filename$\n");
  87. grpc::string leading_comments = file->GetLeadingComments("//");
  88. if (!leading_comments.empty()) {
  89. printer->Print(vars, "// Original file comments:\n");
  90. printer->PrintRaw(leading_comments.c_str());
  91. }
  92. printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
  93. printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
  94. printer->Print(vars, "\n");
  95. printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
  96. printer->Print(vars, file->additional_headers().c_str());
  97. printer->Print(vars, "\n");
  98. }
  99. return output;
  100. }
  101. grpc::string GetHeaderIncludes(grpc_generator::File* file,
  102. const Parameters& params) {
  103. grpc::string output;
  104. {
  105. // Scope the output stream so it closes and finalizes output to the string.
  106. auto printer = file->CreatePrinter(&output);
  107. std::map<grpc::string, grpc::string> vars;
  108. if (!params.additional_header_includes.empty()) {
  109. PrintIncludes(printer.get(), params.additional_header_includes, false,
  110. "");
  111. }
  112. static const char* headers_strs[] = {
  113. "functional",
  114. "grpcpp/impl/codegen/async_generic_service.h",
  115. "grpcpp/impl/codegen/async_stream.h",
  116. "grpcpp/impl/codegen/async_unary_call.h",
  117. "grpcpp/impl/codegen/client_callback.h",
  118. "grpcpp/impl/codegen/method_handler_impl.h",
  119. "grpcpp/impl/codegen/proto_utils.h",
  120. "grpcpp/impl/codegen/rpc_method.h",
  121. "grpcpp/impl/codegen/server_callback.h",
  122. "grpcpp/impl/codegen/service_type.h",
  123. "grpcpp/impl/codegen/status.h",
  124. "grpcpp/impl/codegen/stub_options.h",
  125. "grpcpp/impl/codegen/sync_stream.h"};
  126. std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
  127. PrintIncludes(printer.get(), headers, params.use_system_headers,
  128. params.grpc_search_path);
  129. printer->Print(vars, "\n");
  130. printer->Print(vars, "namespace grpc {\n");
  131. printer->Print(vars, "class CompletionQueue;\n");
  132. printer->Print(vars, "class Channel;\n");
  133. printer->Print(vars, "class ServerCompletionQueue;\n");
  134. printer->Print(vars, "class ServerContext;\n");
  135. printer->Print(vars, "} // namespace grpc\n\n");
  136. if (!file->package().empty()) {
  137. std::vector<grpc::string> parts = file->package_parts();
  138. for (auto part = parts.begin(); part != parts.end(); part++) {
  139. vars["part"] = *part;
  140. printer->Print(vars, "namespace $part$ {\n");
  141. }
  142. printer->Print(vars, "\n");
  143. }
  144. }
  145. return output;
  146. }
  147. void PrintHeaderClientMethodInterfaces(
  148. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  149. std::map<grpc::string, grpc::string>* vars, bool is_public) {
  150. (*vars)["Method"] = method->name();
  151. (*vars)["Request"] = method->input_type_name();
  152. (*vars)["Response"] = method->output_type_name();
  153. struct {
  154. grpc::string prefix;
  155. grpc::string method_params; // extra arguments to method
  156. grpc::string raw_args; // extra arguments to raw version of method
  157. } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
  158. {"PrepareAsync", "", ""}};
  159. if (is_public) {
  160. if (method->NoStreaming()) {
  161. printer->Print(
  162. *vars,
  163. "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
  164. "const $Request$& request, $Response$* response) = 0;\n");
  165. for (auto async_prefix : async_prefixes) {
  166. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  167. printer->Print(
  168. *vars,
  169. "std::unique_ptr< "
  170. "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
  171. "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  172. "const $Request$& request, "
  173. "::grpc::CompletionQueue* cq) {\n");
  174. printer->Indent();
  175. printer->Print(
  176. *vars,
  177. "return std::unique_ptr< "
  178. "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
  179. "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
  180. printer->Outdent();
  181. printer->Print("}\n");
  182. }
  183. } else if (ClientOnlyStreaming(method)) {
  184. printer->Print(
  185. *vars,
  186. "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
  187. " $Method$("
  188. "::grpc::ClientContext* context, $Response$* response) {\n");
  189. printer->Indent();
  190. printer->Print(
  191. *vars,
  192. "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
  193. "($Method$Raw(context, response));\n");
  194. printer->Outdent();
  195. printer->Print("}\n");
  196. for (auto async_prefix : async_prefixes) {
  197. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  198. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  199. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  200. printer->Print(
  201. *vars,
  202. "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
  203. " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  204. "$Response$* "
  205. "response, "
  206. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  207. printer->Indent();
  208. printer->Print(*vars,
  209. "return std::unique_ptr< "
  210. "::grpc::ClientAsyncWriterInterface< $Request$>>("
  211. "$AsyncPrefix$$Method$Raw(context, response, "
  212. "cq$AsyncRawArgs$));\n");
  213. printer->Outdent();
  214. printer->Print("}\n");
  215. }
  216. } else if (ServerOnlyStreaming(method)) {
  217. printer->Print(
  218. *vars,
  219. "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
  220. " $Method$(::grpc::ClientContext* context, const $Request$& request)"
  221. " {\n");
  222. printer->Indent();
  223. printer->Print(
  224. *vars,
  225. "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
  226. "($Method$Raw(context, request));\n");
  227. printer->Outdent();
  228. printer->Print("}\n");
  229. for (auto async_prefix : async_prefixes) {
  230. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  231. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  232. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  233. printer->Print(
  234. *vars,
  235. "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
  236. "$AsyncPrefix$$Method$("
  237. "::grpc::ClientContext* context, const $Request$& request, "
  238. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  239. printer->Indent();
  240. printer->Print(
  241. *vars,
  242. "return std::unique_ptr< "
  243. "::grpc::ClientAsyncReaderInterface< $Response$>>("
  244. "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
  245. printer->Outdent();
  246. printer->Print("}\n");
  247. }
  248. } else if (method->BidiStreaming()) {
  249. printer->Print(*vars,
  250. "std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
  251. "$Request$, $Response$>> "
  252. "$Method$(::grpc::ClientContext* context) {\n");
  253. printer->Indent();
  254. printer->Print(
  255. *vars,
  256. "return std::unique_ptr< "
  257. "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
  258. "$Method$Raw(context));\n");
  259. printer->Outdent();
  260. printer->Print("}\n");
  261. for (auto async_prefix : async_prefixes) {
  262. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  263. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  264. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  265. printer->Print(
  266. *vars,
  267. "std::unique_ptr< "
  268. "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
  269. "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  270. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  271. printer->Indent();
  272. printer->Print(
  273. *vars,
  274. "return std::unique_ptr< "
  275. "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
  276. "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
  277. printer->Outdent();
  278. printer->Print("}\n");
  279. }
  280. }
  281. } else {
  282. if (method->NoStreaming()) {
  283. for (auto async_prefix : async_prefixes) {
  284. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  285. printer->Print(
  286. *vars,
  287. "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
  288. "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  289. "const $Request$& request, "
  290. "::grpc::CompletionQueue* cq) = 0;\n");
  291. }
  292. } else if (ClientOnlyStreaming(method)) {
  293. printer->Print(
  294. *vars,
  295. "virtual ::grpc::ClientWriterInterface< $Request$>*"
  296. " $Method$Raw("
  297. "::grpc::ClientContext* context, $Response$* response) = 0;\n");
  298. for (auto async_prefix : async_prefixes) {
  299. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  300. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  301. printer->Print(
  302. *vars,
  303. "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
  304. " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  305. "$Response$* response, "
  306. "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
  307. }
  308. } else if (ServerOnlyStreaming(method)) {
  309. printer->Print(
  310. *vars,
  311. "virtual ::grpc::ClientReaderInterface< $Response$>* "
  312. "$Method$Raw("
  313. "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
  314. for (auto async_prefix : async_prefixes) {
  315. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  316. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  317. printer->Print(
  318. *vars,
  319. "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
  320. "$AsyncPrefix$$Method$Raw("
  321. "::grpc::ClientContext* context, const $Request$& request, "
  322. "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
  323. }
  324. } else if (method->BidiStreaming()) {
  325. printer->Print(*vars,
  326. "virtual ::grpc::ClientReaderWriterInterface< $Request$, "
  327. "$Response$>* "
  328. "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
  329. for (auto async_prefix : async_prefixes) {
  330. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  331. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  332. printer->Print(
  333. *vars,
  334. "virtual ::grpc::ClientAsyncReaderWriterInterface< "
  335. "$Request$, $Response$>* "
  336. "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  337. "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
  338. }
  339. }
  340. }
  341. }
  342. void PrintHeaderClientMethod(grpc_generator::Printer* printer,
  343. const grpc_generator::Method* method,
  344. std::map<grpc::string, grpc::string>* vars,
  345. bool is_public) {
  346. (*vars)["Method"] = method->name();
  347. (*vars)["Request"] = method->input_type_name();
  348. (*vars)["Response"] = method->output_type_name();
  349. struct {
  350. grpc::string prefix;
  351. grpc::string method_params; // extra arguments to method
  352. grpc::string raw_args; // extra arguments to raw version of method
  353. } async_prefixes[] = {{"Async", ", void* tag", ", tag"},
  354. {"PrepareAsync", "", ""}};
  355. if (is_public) {
  356. if (method->NoStreaming()) {
  357. printer->Print(
  358. *vars,
  359. "::grpc::Status $Method$(::grpc::ClientContext* context, "
  360. "const $Request$& request, $Response$* response) override;\n");
  361. for (auto async_prefix : async_prefixes) {
  362. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  363. printer->Print(
  364. *vars,
  365. "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
  366. "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  367. "const $Request$& request, "
  368. "::grpc::CompletionQueue* cq) {\n");
  369. printer->Indent();
  370. printer->Print(*vars,
  371. "return std::unique_ptr< "
  372. "::grpc::ClientAsyncResponseReader< $Response$>>("
  373. "$AsyncPrefix$$Method$Raw(context, request, cq));\n");
  374. printer->Outdent();
  375. printer->Print("}\n");
  376. }
  377. } else if (ClientOnlyStreaming(method)) {
  378. printer->Print(
  379. *vars,
  380. "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
  381. " $Method$("
  382. "::grpc::ClientContext* context, $Response$* response) {\n");
  383. printer->Indent();
  384. printer->Print(*vars,
  385. "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
  386. "($Method$Raw(context, response));\n");
  387. printer->Outdent();
  388. printer->Print("}\n");
  389. for (auto async_prefix : async_prefixes) {
  390. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  391. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  392. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  393. printer->Print(*vars,
  394. "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
  395. " $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  396. "$Response$* response, "
  397. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  398. printer->Indent();
  399. printer->Print(
  400. *vars,
  401. "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
  402. "$AsyncPrefix$$Method$Raw(context, response, "
  403. "cq$AsyncRawArgs$));\n");
  404. printer->Outdent();
  405. printer->Print("}\n");
  406. }
  407. } else if (ServerOnlyStreaming(method)) {
  408. printer->Print(
  409. *vars,
  410. "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
  411. " $Method$(::grpc::ClientContext* context, const $Request$& request)"
  412. " {\n");
  413. printer->Indent();
  414. printer->Print(
  415. *vars,
  416. "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
  417. "($Method$Raw(context, request));\n");
  418. printer->Outdent();
  419. printer->Print("}\n");
  420. for (auto async_prefix : async_prefixes) {
  421. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  422. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  423. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  424. printer->Print(
  425. *vars,
  426. "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
  427. "$AsyncPrefix$$Method$("
  428. "::grpc::ClientContext* context, const $Request$& request, "
  429. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  430. printer->Indent();
  431. printer->Print(
  432. *vars,
  433. "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
  434. "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
  435. printer->Outdent();
  436. printer->Print("}\n");
  437. }
  438. } else if (method->BidiStreaming()) {
  439. printer->Print(
  440. *vars,
  441. "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
  442. " $Method$(::grpc::ClientContext* context) {\n");
  443. printer->Indent();
  444. printer->Print(*vars,
  445. "return std::unique_ptr< "
  446. "::grpc::ClientReaderWriter< $Request$, $Response$>>("
  447. "$Method$Raw(context));\n");
  448. printer->Outdent();
  449. printer->Print("}\n");
  450. for (auto async_prefix : async_prefixes) {
  451. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  452. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  453. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  454. printer->Print(*vars,
  455. "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
  456. "$Request$, $Response$>> "
  457. "$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
  458. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  459. printer->Indent();
  460. printer->Print(
  461. *vars,
  462. "return std::unique_ptr< "
  463. "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
  464. "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
  465. printer->Outdent();
  466. printer->Print("}\n");
  467. }
  468. }
  469. } else {
  470. if (method->NoStreaming()) {
  471. for (auto async_prefix : async_prefixes) {
  472. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  473. printer->Print(
  474. *vars,
  475. "::grpc::ClientAsyncResponseReader< $Response$>* "
  476. "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  477. "const $Request$& request, "
  478. "::grpc::CompletionQueue* cq) override;\n");
  479. }
  480. } else if (ClientOnlyStreaming(method)) {
  481. printer->Print(*vars,
  482. "::grpc::ClientWriter< $Request$>* $Method$Raw("
  483. "::grpc::ClientContext* context, $Response$* response) "
  484. "override;\n");
  485. for (auto async_prefix : async_prefixes) {
  486. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  487. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  488. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  489. printer->Print(
  490. *vars,
  491. "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
  492. "::grpc::ClientContext* context, $Response$* response, "
  493. "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
  494. }
  495. } else if (ServerOnlyStreaming(method)) {
  496. printer->Print(*vars,
  497. "::grpc::ClientReader< $Response$>* $Method$Raw("
  498. "::grpc::ClientContext* context, const $Request$& request)"
  499. " override;\n");
  500. for (auto async_prefix : async_prefixes) {
  501. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  502. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  503. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  504. printer->Print(
  505. *vars,
  506. "::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw("
  507. "::grpc::ClientContext* context, const $Request$& request, "
  508. "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
  509. }
  510. } else if (method->BidiStreaming()) {
  511. printer->Print(*vars,
  512. "::grpc::ClientReaderWriter< $Request$, $Response$>* "
  513. "$Method$Raw(::grpc::ClientContext* context) override;\n");
  514. for (auto async_prefix : async_prefixes) {
  515. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  516. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  517. (*vars)["AsyncRawArgs"] = async_prefix.raw_args;
  518. printer->Print(
  519. *vars,
  520. "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
  521. "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
  522. "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
  523. }
  524. }
  525. }
  526. }
  527. void PrintHeaderClientMethodCallbackInterfacesStart(
  528. grpc_generator::Printer* printer,
  529. std::map<grpc::string, grpc::string>* vars) {
  530. // This declares the interface for the callback-based API. The components
  531. // are pure; even though this is new (post-1.0) API, it can be pure because
  532. // it is an entirely new interface that happens to be scoped within
  533. // StubInterface, not new additions to StubInterface itself
  534. printer->Print("class experimental_async_interface {\n");
  535. // All methods in this new interface are public. There is no need for private
  536. // "Raw" methods since the callback-based API returns unowned raw pointers
  537. printer->Print(" public:\n");
  538. printer->Indent();
  539. printer->Print("virtual ~experimental_async_interface() {}\n");
  540. }
  541. void PrintHeaderClientMethodCallbackInterfaces(
  542. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  543. std::map<grpc::string, grpc::string>* vars, bool is_public) {
  544. // Reserve is_public for future expansion
  545. assert(is_public);
  546. (*vars)["Method"] = method->name();
  547. (*vars)["Request"] = method->input_type_name();
  548. (*vars)["Response"] = method->output_type_name();
  549. if (method->NoStreaming()) {
  550. printer->Print(*vars,
  551. "virtual void $Method$(::grpc::ClientContext* context, "
  552. "const $Request$* request, $Response$* response, "
  553. "std::function<void(::grpc::Status)>) = 0;\n");
  554. } else if (ClientOnlyStreaming(method)) {
  555. printer->Print(*vars,
  556. "virtual void $Method$(::grpc::ClientContext* context, "
  557. "$Response$* response, "
  558. "::grpc::experimental::ClientWriteReactor< $Request$>* "
  559. "reactor) = 0;\n");
  560. } else if (ServerOnlyStreaming(method)) {
  561. printer->Print(*vars,
  562. "virtual void $Method$(::grpc::ClientContext* context, "
  563. "$Request$* request, "
  564. "::grpc::experimental::ClientReadReactor< $Response$>* "
  565. "reactor) = 0;\n");
  566. } else if (method->BidiStreaming()) {
  567. printer->Print(*vars,
  568. "virtual void $Method$(::grpc::ClientContext* context, "
  569. "::grpc::experimental::ClientBidiReactor< "
  570. "$Request$,$Response$>* reactor) = 0;\n");
  571. }
  572. }
  573. void PrintHeaderClientMethodCallbackInterfacesEnd(
  574. grpc_generator::Printer* printer,
  575. std::map<grpc::string, grpc::string>* vars) {
  576. printer->Outdent();
  577. printer->Print("};\n");
  578. // Declare a function to give the async stub contents. It can't be pure
  579. // since this is a new API in StubInterface, but it is meaningless by default
  580. // (since any stub that wants to use it must have its own implementation of
  581. // the callback functions therein), so make the default return value nullptr.
  582. // Intentionally include the word "class" to avoid possible shadowing.
  583. printer->Print(
  584. "virtual class experimental_async_interface* experimental_async() { "
  585. "return nullptr; }\n");
  586. }
  587. void PrintHeaderClientMethodCallbackStart(
  588. grpc_generator::Printer* printer,
  589. std::map<grpc::string, grpc::string>* vars) {
  590. // This declares the stub entry for the callback-based API.
  591. printer->Print("class experimental_async final :\n");
  592. printer->Print(" public StubInterface::experimental_async_interface {\n");
  593. printer->Print(" public:\n");
  594. printer->Indent();
  595. }
  596. void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
  597. const grpc_generator::Method* method,
  598. std::map<grpc::string, grpc::string>* vars,
  599. bool is_public) {
  600. // Reserve is_public for future expansion
  601. assert(is_public);
  602. (*vars)["Method"] = method->name();
  603. (*vars)["Request"] = method->input_type_name();
  604. (*vars)["Response"] = method->output_type_name();
  605. if (method->NoStreaming()) {
  606. printer->Print(*vars,
  607. "void $Method$(::grpc::ClientContext* context, "
  608. "const $Request$* request, $Response$* response, "
  609. "std::function<void(::grpc::Status)>) override;\n");
  610. } else if (ClientOnlyStreaming(method)) {
  611. printer->Print(*vars,
  612. "void $Method$(::grpc::ClientContext* context, "
  613. "$Response$* response, "
  614. "::grpc::experimental::ClientWriteReactor< $Request$>* "
  615. "reactor) override;\n");
  616. } else if (ServerOnlyStreaming(method)) {
  617. printer->Print(*vars,
  618. "void $Method$(::grpc::ClientContext* context, "
  619. "$Request$* request, "
  620. "::grpc::experimental::ClientReadReactor< $Response$>* "
  621. "reactor) override;\n");
  622. } else if (method->BidiStreaming()) {
  623. printer->Print(*vars,
  624. "void $Method$(::grpc::ClientContext* context, "
  625. "::grpc::experimental::ClientBidiReactor< "
  626. "$Request$,$Response$>* reactor) override;\n");
  627. }
  628. }
  629. void PrintHeaderClientMethodCallbackEnd(
  630. grpc_generator::Printer* printer,
  631. std::map<grpc::string, grpc::string>* vars) {
  632. printer->Outdent();
  633. printer->Print(" private:\n");
  634. printer->Indent();
  635. printer->Print("friend class Stub;\n");
  636. printer->Print("explicit experimental_async(Stub* stub): stub_(stub) { }\n");
  637. // include a function with a dummy use of stub_ to avoid an unused
  638. // private member warning for service with no methods
  639. printer->Print("Stub* stub() { return stub_; }\n");
  640. printer->Print("Stub* stub_;\n");
  641. printer->Outdent();
  642. printer->Print("};\n");
  643. printer->Print(
  644. "class experimental_async_interface* experimental_async() override { "
  645. "return &async_stub_; }\n");
  646. }
  647. void PrintHeaderClientMethodData(grpc_generator::Printer* printer,
  648. const grpc_generator::Method* method,
  649. std::map<grpc::string, grpc::string>* vars) {
  650. (*vars)["Method"] = method->name();
  651. printer->Print(*vars,
  652. "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
  653. }
  654. void PrintHeaderServerMethodSync(grpc_generator::Printer* printer,
  655. const grpc_generator::Method* method,
  656. std::map<grpc::string, grpc::string>* vars) {
  657. (*vars)["Method"] = method->name();
  658. (*vars)["Request"] = method->input_type_name();
  659. (*vars)["Response"] = method->output_type_name();
  660. printer->Print(method->GetLeadingComments("//").c_str());
  661. if (method->NoStreaming()) {
  662. printer->Print(*vars,
  663. "virtual ::grpc::Status $Method$("
  664. "::grpc::ServerContext* context, const $Request$* request, "
  665. "$Response$* response);\n");
  666. } else if (ClientOnlyStreaming(method)) {
  667. printer->Print(*vars,
  668. "virtual ::grpc::Status $Method$("
  669. "::grpc::ServerContext* context, "
  670. "::grpc::ServerReader< $Request$>* reader, "
  671. "$Response$* response);\n");
  672. } else if (ServerOnlyStreaming(method)) {
  673. printer->Print(*vars,
  674. "virtual ::grpc::Status $Method$("
  675. "::grpc::ServerContext* context, const $Request$* request, "
  676. "::grpc::ServerWriter< $Response$>* writer);\n");
  677. } else if (method->BidiStreaming()) {
  678. printer->Print(
  679. *vars,
  680. "virtual ::grpc::Status $Method$("
  681. "::grpc::ServerContext* context, "
  682. "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
  683. "\n");
  684. }
  685. printer->Print(method->GetTrailingComments("//").c_str());
  686. }
  687. // Helper generator. Disables the sync API for Request and Response, then adds
  688. // in an async API for RealRequest and RealResponse types. This is to be used
  689. // to generate async and raw async APIs.
  690. void PrintHeaderServerAsyncMethodsHelper(
  691. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  692. std::map<grpc::string, grpc::string>* vars) {
  693. if (method->NoStreaming()) {
  694. printer->Print(
  695. *vars,
  696. "// disable synchronous version of this method\n"
  697. "::grpc::Status $Method$("
  698. "::grpc::ServerContext* context, const $Request$* request, "
  699. "$Response$* response) override {\n"
  700. " abort();\n"
  701. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  702. "}\n");
  703. printer->Print(
  704. *vars,
  705. "void Request$Method$("
  706. "::grpc::ServerContext* context, $RealRequest$* request, "
  707. "::grpc::ServerAsyncResponseWriter< $RealResponse$>* response, "
  708. "::grpc::CompletionQueue* new_call_cq, "
  709. "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
  710. printer->Print(*vars,
  711. " ::grpc::Service::RequestAsyncUnary($Idx$, context, "
  712. "request, response, new_call_cq, notification_cq, tag);\n");
  713. printer->Print("}\n");
  714. } else if (ClientOnlyStreaming(method)) {
  715. printer->Print(
  716. *vars,
  717. "// disable synchronous version of this method\n"
  718. "::grpc::Status $Method$("
  719. "::grpc::ServerContext* context, "
  720. "::grpc::ServerReader< $Request$>* reader, "
  721. "$Response$* response) override {\n"
  722. " abort();\n"
  723. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  724. "}\n");
  725. printer->Print(
  726. *vars,
  727. "void Request$Method$("
  728. "::grpc::ServerContext* context, "
  729. "::grpc::ServerAsyncReader< $RealResponse$, $RealRequest$>* reader, "
  730. "::grpc::CompletionQueue* new_call_cq, "
  731. "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
  732. printer->Print(*vars,
  733. " ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
  734. "context, reader, new_call_cq, notification_cq, tag);\n");
  735. printer->Print("}\n");
  736. } else if (ServerOnlyStreaming(method)) {
  737. printer->Print(
  738. *vars,
  739. "// disable synchronous version of this method\n"
  740. "::grpc::Status $Method$("
  741. "::grpc::ServerContext* context, const $Request$* request, "
  742. "::grpc::ServerWriter< $Response$>* writer) override "
  743. "{\n"
  744. " abort();\n"
  745. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  746. "}\n");
  747. printer->Print(
  748. *vars,
  749. "void Request$Method$("
  750. "::grpc::ServerContext* context, $RealRequest$* request, "
  751. "::grpc::ServerAsyncWriter< $RealResponse$>* writer, "
  752. "::grpc::CompletionQueue* new_call_cq, "
  753. "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
  754. printer->Print(
  755. *vars,
  756. " ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
  757. "context, request, writer, new_call_cq, notification_cq, tag);\n");
  758. printer->Print("}\n");
  759. } else if (method->BidiStreaming()) {
  760. printer->Print(
  761. *vars,
  762. "// disable synchronous version of this method\n"
  763. "::grpc::Status $Method$("
  764. "::grpc::ServerContext* context, "
  765. "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
  766. " override {\n"
  767. " abort();\n"
  768. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  769. "}\n");
  770. printer->Print(
  771. *vars,
  772. "void Request$Method$("
  773. "::grpc::ServerContext* context, "
  774. "::grpc::ServerAsyncReaderWriter< $RealResponse$, $RealRequest$>* "
  775. "stream, "
  776. "::grpc::CompletionQueue* new_call_cq, "
  777. "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
  778. printer->Print(*vars,
  779. " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
  780. "context, stream, new_call_cq, notification_cq, tag);\n");
  781. printer->Print("}\n");
  782. }
  783. }
  784. void PrintHeaderServerMethodAsync(grpc_generator::Printer* printer,
  785. const grpc_generator::Method* method,
  786. std::map<grpc::string, grpc::string>* vars) {
  787. (*vars)["Method"] = method->name();
  788. // These will be disabled
  789. (*vars)["Request"] = method->input_type_name();
  790. (*vars)["Response"] = method->output_type_name();
  791. // These will be used for the async API
  792. (*vars)["RealRequest"] = method->input_type_name();
  793. (*vars)["RealResponse"] = method->output_type_name();
  794. printer->Print(*vars, "template <class BaseClass>\n");
  795. printer->Print(*vars,
  796. "class WithAsyncMethod_$Method$ : public BaseClass {\n");
  797. printer->Print(
  798. " private:\n"
  799. " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  800. printer->Print(" public:\n");
  801. printer->Indent();
  802. printer->Print(*vars,
  803. "WithAsyncMethod_$Method$() {\n"
  804. " ::grpc::Service::MarkMethodAsync($Idx$);\n"
  805. "}\n");
  806. printer->Print(*vars,
  807. "~WithAsyncMethod_$Method$() override {\n"
  808. " BaseClassMustBeDerivedFromService(this);\n"
  809. "}\n");
  810. PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
  811. printer->Outdent();
  812. printer->Print(*vars, "};\n");
  813. }
  814. // Helper generator. Disables the sync API for Request and Response, then adds
  815. // in a callback API for RealRequest and RealResponse types. This is to be used
  816. // to generate callback and raw callback APIs.
  817. void PrintHeaderServerCallbackMethodsHelper(
  818. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  819. std::map<grpc::string, grpc::string>* vars) {
  820. if (method->NoStreaming()) {
  821. printer->Print(
  822. *vars,
  823. "// disable synchronous version of this method\n"
  824. "::grpc::Status $Method$("
  825. "::grpc::ServerContext* context, const $Request$* request, "
  826. "$Response$* response) override {\n"
  827. " abort();\n"
  828. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  829. "}\n");
  830. printer->Print(
  831. *vars,
  832. "virtual void $Method$("
  833. "::grpc::ServerContext* context, const $RealRequest$* request, "
  834. "$RealResponse$* response, "
  835. "::grpc::experimental::ServerCallbackRpcController* "
  836. "controller) { controller->Finish(::grpc::Status("
  837. "::grpc::StatusCode::UNIMPLEMENTED, \"\")); }\n");
  838. } else if (ClientOnlyStreaming(method)) {
  839. printer->Print(
  840. *vars,
  841. "// disable synchronous version of this method\n"
  842. "::grpc::Status $Method$("
  843. "::grpc::ServerContext* context, "
  844. "::grpc::ServerReader< $Request$>* reader, "
  845. "$Response$* response) override {\n"
  846. " abort();\n"
  847. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  848. "}\n");
  849. printer->Print(*vars,
  850. "virtual ::grpc::experimental::ServerReadReactor< "
  851. "$RealRequest$, $RealResponse$>* $Method$() {\n"
  852. " return new ::grpc::internal::UnimplementedReadReactor<\n"
  853. " $RealRequest$, $RealResponse$>;}\n");
  854. } else if (ServerOnlyStreaming(method)) {
  855. printer->Print(
  856. *vars,
  857. "// disable synchronous version of this method\n"
  858. "::grpc::Status $Method$("
  859. "::grpc::ServerContext* context, const $Request$* request, "
  860. "::grpc::ServerWriter< $Response$>* writer) override "
  861. "{\n"
  862. " abort();\n"
  863. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  864. "}\n");
  865. printer->Print(*vars,
  866. "virtual ::grpc::experimental::ServerWriteReactor< "
  867. "$RealRequest$, $RealResponse$>* $Method$() {\n"
  868. " return new ::grpc::internal::UnimplementedWriteReactor<\n"
  869. " $RealRequest$, $RealResponse$>;}\n");
  870. } else if (method->BidiStreaming()) {
  871. printer->Print(
  872. *vars,
  873. "// disable synchronous version of this method\n"
  874. "::grpc::Status $Method$("
  875. "::grpc::ServerContext* context, "
  876. "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
  877. " override {\n"
  878. " abort();\n"
  879. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  880. "}\n");
  881. printer->Print(*vars,
  882. "virtual ::grpc::experimental::ServerBidiReactor< "
  883. "$RealRequest$, $RealResponse$>* $Method$() {\n"
  884. " return new ::grpc::internal::UnimplementedBidiReactor<\n"
  885. " $RealRequest$, $RealResponse$>;}\n");
  886. }
  887. }
  888. void PrintHeaderServerMethodCallback(
  889. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  890. std::map<grpc::string, grpc::string>* vars) {
  891. (*vars)["Method"] = method->name();
  892. // These will be disabled
  893. (*vars)["Request"] = method->input_type_name();
  894. (*vars)["Response"] = method->output_type_name();
  895. // These will be used for the callback API
  896. (*vars)["RealRequest"] = method->input_type_name();
  897. (*vars)["RealResponse"] = method->output_type_name();
  898. printer->Print(*vars, "template <class BaseClass>\n");
  899. printer->Print(
  900. *vars,
  901. "class ExperimentalWithCallbackMethod_$Method$ : public BaseClass {\n");
  902. printer->Print(
  903. " private:\n"
  904. " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  905. printer->Print(" public:\n");
  906. printer->Indent();
  907. printer->Print(*vars, "ExperimentalWithCallbackMethod_$Method$() {\n");
  908. if (method->NoStreaming()) {
  909. printer->Print(
  910. *vars,
  911. " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
  912. " new ::grpc::internal::CallbackUnaryHandler< "
  913. "$RealRequest$, $RealResponse$>(\n"
  914. " [this](::grpc::ServerContext* context,\n"
  915. " const $RealRequest$* request,\n"
  916. " $RealResponse$* response,\n"
  917. " ::grpc::experimental::ServerCallbackRpcController* "
  918. "controller) {\n"
  919. " return this->$"
  920. "Method$(context, request, response, controller);\n"
  921. " }));\n");
  922. } else if (ClientOnlyStreaming(method)) {
  923. printer->Print(
  924. *vars,
  925. " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
  926. " new ::grpc::internal::CallbackClientStreamingHandler< "
  927. "$RealRequest$, $RealResponse$>(\n"
  928. " [this] { return this->$Method$(); }));\n");
  929. } else if (ServerOnlyStreaming(method)) {
  930. printer->Print(
  931. *vars,
  932. " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
  933. " new ::grpc::internal::CallbackServerStreamingHandler< "
  934. "$RealRequest$, $RealResponse$>(\n"
  935. " [this] { return this->$Method$(); }));\n");
  936. } else if (method->BidiStreaming()) {
  937. printer->Print(
  938. *vars,
  939. " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
  940. " new ::grpc::internal::CallbackBidiHandler< "
  941. "$RealRequest$, $RealResponse$>(\n"
  942. " [this] { return this->$Method$(); }));\n");
  943. }
  944. printer->Print(*vars, "}\n");
  945. printer->Print(*vars,
  946. "~ExperimentalWithCallbackMethod_$Method$() override {\n"
  947. " BaseClassMustBeDerivedFromService(this);\n"
  948. "}\n");
  949. PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
  950. printer->Outdent();
  951. printer->Print(*vars, "};\n");
  952. }
  953. void PrintHeaderServerMethodRawCallback(
  954. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  955. std::map<grpc::string, grpc::string>* vars) {
  956. (*vars)["Method"] = method->name();
  957. // These will be disabled
  958. (*vars)["Request"] = method->input_type_name();
  959. (*vars)["Response"] = method->output_type_name();
  960. // These will be used for raw API
  961. (*vars)["RealRequest"] = "::grpc::ByteBuffer";
  962. (*vars)["RealResponse"] = "::grpc::ByteBuffer";
  963. printer->Print(*vars, "template <class BaseClass>\n");
  964. printer->Print(*vars,
  965. "class ExperimentalWithRawCallbackMethod_$Method$ : public "
  966. "BaseClass {\n");
  967. printer->Print(
  968. " private:\n"
  969. " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  970. printer->Print(" public:\n");
  971. printer->Indent();
  972. printer->Print(*vars, "ExperimentalWithRawCallbackMethod_$Method$() {\n");
  973. if (method->NoStreaming()) {
  974. printer->Print(
  975. *vars,
  976. " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
  977. " new ::grpc::internal::CallbackUnaryHandler< "
  978. "$RealRequest$, $RealResponse$>(\n"
  979. " [this](::grpc::ServerContext* context,\n"
  980. " const $RealRequest$* request,\n"
  981. " $RealResponse$* response,\n"
  982. " ::grpc::experimental::ServerCallbackRpcController* "
  983. "controller) {\n"
  984. " this->$"
  985. "Method$(context, request, response, controller);\n"
  986. " }));\n");
  987. } else if (ClientOnlyStreaming(method)) {
  988. printer->Print(
  989. *vars,
  990. " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
  991. " new ::grpc::internal::CallbackClientStreamingHandler< "
  992. "$RealRequest$, $RealResponse$>(\n"
  993. " [this] { return this->$Method$(); }));\n");
  994. } else if (ServerOnlyStreaming(method)) {
  995. printer->Print(
  996. *vars,
  997. " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
  998. " new ::grpc::internal::CallbackServerStreamingHandler< "
  999. "$RealRequest$, $RealResponse$>(\n"
  1000. " [this] { return this->$Method$(); }));\n");
  1001. } else if (method->BidiStreaming()) {
  1002. printer->Print(
  1003. *vars,
  1004. " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
  1005. " new ::grpc::internal::CallbackBidiHandler< "
  1006. "$RealRequest$, $RealResponse$>(\n"
  1007. " [this] { return this->$Method$(); }));\n");
  1008. }
  1009. printer->Print(*vars, "}\n");
  1010. printer->Print(*vars,
  1011. "~ExperimentalWithRawCallbackMethod_$Method$() override {\n"
  1012. " BaseClassMustBeDerivedFromService(this);\n"
  1013. "}\n");
  1014. PrintHeaderServerCallbackMethodsHelper(printer, method, vars);
  1015. printer->Outdent();
  1016. printer->Print(*vars, "};\n");
  1017. }
  1018. void PrintHeaderServerMethodStreamedUnary(
  1019. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  1020. std::map<grpc::string, grpc::string>* vars) {
  1021. (*vars)["Method"] = method->name();
  1022. (*vars)["Request"] = method->input_type_name();
  1023. (*vars)["Response"] = method->output_type_name();
  1024. if (method->NoStreaming()) {
  1025. printer->Print(*vars, "template <class BaseClass>\n");
  1026. printer->Print(*vars,
  1027. "class WithStreamedUnaryMethod_$Method$ : "
  1028. "public BaseClass {\n");
  1029. printer->Print(
  1030. " private:\n"
  1031. " void BaseClassMustBeDerivedFromService(const Service *service) "
  1032. "{}\n");
  1033. printer->Print(" public:\n");
  1034. printer->Indent();
  1035. printer->Print(*vars,
  1036. "WithStreamedUnaryMethod_$Method$() {\n"
  1037. " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
  1038. " new ::grpc::internal::StreamedUnaryHandler< $Request$, "
  1039. "$Response$>(std::bind"
  1040. "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
  1041. "Streamed$Method$, this, std::placeholders::_1, "
  1042. "std::placeholders::_2)));\n"
  1043. "}\n");
  1044. printer->Print(*vars,
  1045. "~WithStreamedUnaryMethod_$Method$() override {\n"
  1046. " BaseClassMustBeDerivedFromService(this);\n"
  1047. "}\n");
  1048. printer->Print(
  1049. *vars,
  1050. "// disable regular version of this method\n"
  1051. "::grpc::Status $Method$("
  1052. "::grpc::ServerContext* context, const $Request$* request, "
  1053. "$Response$* response) override {\n"
  1054. " abort();\n"
  1055. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  1056. "}\n");
  1057. printer->Print(*vars,
  1058. "// replace default version of method with streamed unary\n"
  1059. "virtual ::grpc::Status Streamed$Method$("
  1060. "::grpc::ServerContext* context, "
  1061. "::grpc::ServerUnaryStreamer< "
  1062. "$Request$,$Response$>* server_unary_streamer)"
  1063. " = 0;\n");
  1064. printer->Outdent();
  1065. printer->Print(*vars, "};\n");
  1066. }
  1067. }
  1068. void PrintHeaderServerMethodSplitStreaming(
  1069. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  1070. std::map<grpc::string, grpc::string>* vars) {
  1071. (*vars)["Method"] = method->name();
  1072. (*vars)["Request"] = method->input_type_name();
  1073. (*vars)["Response"] = method->output_type_name();
  1074. if (ServerOnlyStreaming(method)) {
  1075. printer->Print(*vars, "template <class BaseClass>\n");
  1076. printer->Print(*vars,
  1077. "class WithSplitStreamingMethod_$Method$ : "
  1078. "public BaseClass {\n");
  1079. printer->Print(
  1080. " private:\n"
  1081. " void BaseClassMustBeDerivedFromService(const Service *service) "
  1082. "{}\n");
  1083. printer->Print(" public:\n");
  1084. printer->Indent();
  1085. printer->Print(
  1086. *vars,
  1087. "WithSplitStreamingMethod_$Method$() {\n"
  1088. " ::grpc::Service::MarkMethodStreamed($Idx$,\n"
  1089. " new ::grpc::internal::SplitServerStreamingHandler< $Request$, "
  1090. "$Response$>(std::bind"
  1091. "(&WithSplitStreamingMethod_$Method$<BaseClass>::"
  1092. "Streamed$Method$, this, std::placeholders::_1, "
  1093. "std::placeholders::_2)));\n"
  1094. "}\n");
  1095. printer->Print(*vars,
  1096. "~WithSplitStreamingMethod_$Method$() override {\n"
  1097. " BaseClassMustBeDerivedFromService(this);\n"
  1098. "}\n");
  1099. printer->Print(
  1100. *vars,
  1101. "// disable regular version of this method\n"
  1102. "::grpc::Status $Method$("
  1103. "::grpc::ServerContext* context, const $Request$* request, "
  1104. "::grpc::ServerWriter< $Response$>* writer) override "
  1105. "{\n"
  1106. " abort();\n"
  1107. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  1108. "}\n");
  1109. printer->Print(*vars,
  1110. "// replace default version of method with split streamed\n"
  1111. "virtual ::grpc::Status Streamed$Method$("
  1112. "::grpc::ServerContext* context, "
  1113. "::grpc::ServerSplitStreamer< "
  1114. "$Request$,$Response$>* server_split_streamer)"
  1115. " = 0;\n");
  1116. printer->Outdent();
  1117. printer->Print(*vars, "};\n");
  1118. }
  1119. }
  1120. void PrintHeaderServerMethodGeneric(
  1121. grpc_generator::Printer* printer, const grpc_generator::Method* method,
  1122. std::map<grpc::string, grpc::string>* vars) {
  1123. (*vars)["Method"] = method->name();
  1124. (*vars)["Request"] = method->input_type_name();
  1125. (*vars)["Response"] = method->output_type_name();
  1126. printer->Print(*vars, "template <class BaseClass>\n");
  1127. printer->Print(*vars,
  1128. "class WithGenericMethod_$Method$ : public BaseClass {\n");
  1129. printer->Print(
  1130. " private:\n"
  1131. " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  1132. printer->Print(" public:\n");
  1133. printer->Indent();
  1134. printer->Print(*vars,
  1135. "WithGenericMethod_$Method$() {\n"
  1136. " ::grpc::Service::MarkMethodGeneric($Idx$);\n"
  1137. "}\n");
  1138. printer->Print(*vars,
  1139. "~WithGenericMethod_$Method$() override {\n"
  1140. " BaseClassMustBeDerivedFromService(this);\n"
  1141. "}\n");
  1142. if (method->NoStreaming()) {
  1143. printer->Print(
  1144. *vars,
  1145. "// disable synchronous version of this method\n"
  1146. "::grpc::Status $Method$("
  1147. "::grpc::ServerContext* context, const $Request$* request, "
  1148. "$Response$* response) override {\n"
  1149. " abort();\n"
  1150. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  1151. "}\n");
  1152. } else if (ClientOnlyStreaming(method)) {
  1153. printer->Print(
  1154. *vars,
  1155. "// disable synchronous version of this method\n"
  1156. "::grpc::Status $Method$("
  1157. "::grpc::ServerContext* context, "
  1158. "::grpc::ServerReader< $Request$>* reader, "
  1159. "$Response$* response) override {\n"
  1160. " abort();\n"
  1161. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  1162. "}\n");
  1163. } else if (ServerOnlyStreaming(method)) {
  1164. printer->Print(
  1165. *vars,
  1166. "// disable synchronous version of this method\n"
  1167. "::grpc::Status $Method$("
  1168. "::grpc::ServerContext* context, const $Request$* request, "
  1169. "::grpc::ServerWriter< $Response$>* writer) override "
  1170. "{\n"
  1171. " abort();\n"
  1172. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  1173. "}\n");
  1174. } else if (method->BidiStreaming()) {
  1175. printer->Print(
  1176. *vars,
  1177. "// disable synchronous version of this method\n"
  1178. "::grpc::Status $Method$("
  1179. "::grpc::ServerContext* context, "
  1180. "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
  1181. " override {\n"
  1182. " abort();\n"
  1183. " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
  1184. "}\n");
  1185. }
  1186. printer->Outdent();
  1187. printer->Print(*vars, "};\n");
  1188. }
  1189. void PrintHeaderServerMethodRaw(grpc_generator::Printer* printer,
  1190. const grpc_generator::Method* method,
  1191. std::map<grpc::string, grpc::string>* vars) {
  1192. (*vars)["Method"] = method->name();
  1193. // These will be disabled
  1194. (*vars)["Request"] = method->input_type_name();
  1195. (*vars)["Response"] = method->output_type_name();
  1196. // These will be used for raw API
  1197. (*vars)["RealRequest"] = "::grpc::ByteBuffer";
  1198. (*vars)["RealResponse"] = "::grpc::ByteBuffer";
  1199. printer->Print(*vars, "template <class BaseClass>\n");
  1200. printer->Print(*vars, "class WithRawMethod_$Method$ : public BaseClass {\n");
  1201. printer->Print(
  1202. " private:\n"
  1203. " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
  1204. printer->Print(" public:\n");
  1205. printer->Indent();
  1206. printer->Print(*vars,
  1207. "WithRawMethod_$Method$() {\n"
  1208. " ::grpc::Service::MarkMethodRaw($Idx$);\n"
  1209. "}\n");
  1210. printer->Print(*vars,
  1211. "~WithRawMethod_$Method$() override {\n"
  1212. " BaseClassMustBeDerivedFromService(this);\n"
  1213. "}\n");
  1214. PrintHeaderServerAsyncMethodsHelper(printer, method, vars);
  1215. printer->Outdent();
  1216. printer->Print(*vars, "};\n");
  1217. }
  1218. void PrintHeaderService(grpc_generator::Printer* printer,
  1219. const grpc_generator::Service* service,
  1220. std::map<grpc::string, grpc::string>* vars) {
  1221. (*vars)["Service"] = service->name();
  1222. printer->Print(service->GetLeadingComments("//").c_str());
  1223. printer->Print(*vars,
  1224. "class $Service$ final {\n"
  1225. " public:\n");
  1226. printer->Indent();
  1227. // Service metadata
  1228. printer->Print(*vars,
  1229. "static constexpr char const* service_full_name() {\n"
  1230. " return \"$Package$$Service$\";\n"
  1231. "}\n");
  1232. // Client side
  1233. printer->Print(
  1234. "class StubInterface {\n"
  1235. " public:\n");
  1236. printer->Indent();
  1237. printer->Print("virtual ~StubInterface() {}\n");
  1238. for (int i = 0; i < service->method_count(); ++i) {
  1239. printer->Print(service->method(i)->GetLeadingComments("//").c_str());
  1240. PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
  1241. true);
  1242. printer->Print(service->method(i)->GetTrailingComments("//").c_str());
  1243. }
  1244. PrintHeaderClientMethodCallbackInterfacesStart(printer, vars);
  1245. for (int i = 0; i < service->method_count(); ++i) {
  1246. printer->Print(service->method(i)->GetLeadingComments("//").c_str());
  1247. PrintHeaderClientMethodCallbackInterfaces(printer, service->method(i).get(),
  1248. vars, true);
  1249. printer->Print(service->method(i)->GetTrailingComments("//").c_str());
  1250. }
  1251. PrintHeaderClientMethodCallbackInterfacesEnd(printer, vars);
  1252. printer->Outdent();
  1253. printer->Print("private:\n");
  1254. printer->Indent();
  1255. for (int i = 0; i < service->method_count(); ++i) {
  1256. PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars,
  1257. false);
  1258. }
  1259. printer->Outdent();
  1260. printer->Print("};\n");
  1261. printer->Print(
  1262. "class Stub final : public StubInterface"
  1263. " {\n public:\n");
  1264. printer->Indent();
  1265. printer->Print(
  1266. "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
  1267. "channel);\n");
  1268. for (int i = 0; i < service->method_count(); ++i) {
  1269. PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
  1270. }
  1271. PrintHeaderClientMethodCallbackStart(printer, vars);
  1272. for (int i = 0; i < service->method_count(); ++i) {
  1273. PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars,
  1274. true);
  1275. }
  1276. PrintHeaderClientMethodCallbackEnd(printer, vars);
  1277. printer->Outdent();
  1278. printer->Print("\n private:\n");
  1279. printer->Indent();
  1280. printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
  1281. printer->Print("class experimental_async async_stub_{this};\n");
  1282. for (int i = 0; i < service->method_count(); ++i) {
  1283. PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
  1284. }
  1285. for (int i = 0; i < service->method_count(); ++i) {
  1286. PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
  1287. }
  1288. printer->Outdent();
  1289. printer->Print("};\n");
  1290. printer->Print(
  1291. "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
  1292. "::grpc::ChannelInterface>& channel, "
  1293. "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
  1294. printer->Print("\n");
  1295. // Server side - base
  1296. printer->Print(
  1297. "class Service : public ::grpc::Service {\n"
  1298. " public:\n");
  1299. printer->Indent();
  1300. printer->Print("Service();\n");
  1301. printer->Print("virtual ~Service();\n");
  1302. for (int i = 0; i < service->method_count(); ++i) {
  1303. PrintHeaderServerMethodSync(printer, service->method(i).get(), vars);
  1304. }
  1305. printer->Outdent();
  1306. printer->Print("};\n");
  1307. // Server side - Asynchronous
  1308. for (int i = 0; i < service->method_count(); ++i) {
  1309. (*vars)["Idx"] = as_string(i);
  1310. PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars);
  1311. }
  1312. printer->Print("typedef ");
  1313. for (int i = 0; i < service->method_count(); ++i) {
  1314. (*vars)["method_name"] = service->method(i)->name();
  1315. printer->Print(*vars, "WithAsyncMethod_$method_name$<");
  1316. }
  1317. printer->Print("Service");
  1318. for (int i = 0; i < service->method_count(); ++i) {
  1319. printer->Print(" >");
  1320. }
  1321. printer->Print(" AsyncService;\n");
  1322. // Server side - Callback
  1323. for (int i = 0; i < service->method_count(); ++i) {
  1324. (*vars)["Idx"] = as_string(i);
  1325. PrintHeaderServerMethodCallback(printer, service->method(i).get(), vars);
  1326. }
  1327. printer->Print("typedef ");
  1328. for (int i = 0; i < service->method_count(); ++i) {
  1329. (*vars)["method_name"] = service->method(i)->name();
  1330. printer->Print(*vars, "ExperimentalWithCallbackMethod_$method_name$<");
  1331. }
  1332. printer->Print("Service");
  1333. for (int i = 0; i < service->method_count(); ++i) {
  1334. printer->Print(" >");
  1335. }
  1336. printer->Print(" ExperimentalCallbackService;\n");
  1337. // Server side - Generic
  1338. for (int i = 0; i < service->method_count(); ++i) {
  1339. (*vars)["Idx"] = as_string(i);
  1340. PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
  1341. }
  1342. // Server side - Raw
  1343. for (int i = 0; i < service->method_count(); ++i) {
  1344. (*vars)["Idx"] = as_string(i);
  1345. PrintHeaderServerMethodRaw(printer, service->method(i).get(), vars);
  1346. }
  1347. // Server side - Raw Callback
  1348. for (int i = 0; i < service->method_count(); ++i) {
  1349. (*vars)["Idx"] = as_string(i);
  1350. PrintHeaderServerMethodRawCallback(printer, service->method(i).get(), vars);
  1351. }
  1352. // Server side - Streamed Unary
  1353. for (int i = 0; i < service->method_count(); ++i) {
  1354. (*vars)["Idx"] = as_string(i);
  1355. PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
  1356. vars);
  1357. }
  1358. printer->Print("typedef ");
  1359. for (int i = 0; i < service->method_count(); ++i) {
  1360. (*vars)["method_name"] = service->method(i)->name();
  1361. if (service->method(i)->NoStreaming()) {
  1362. printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
  1363. }
  1364. }
  1365. printer->Print("Service");
  1366. for (int i = 0; i < service->method_count(); ++i) {
  1367. if (service->method(i)->NoStreaming()) {
  1368. printer->Print(" >");
  1369. }
  1370. }
  1371. printer->Print(" StreamedUnaryService;\n");
  1372. // Server side - controlled server-side streaming
  1373. for (int i = 0; i < service->method_count(); ++i) {
  1374. (*vars)["Idx"] = as_string(i);
  1375. PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(),
  1376. vars);
  1377. }
  1378. printer->Print("typedef ");
  1379. for (int i = 0; i < service->method_count(); ++i) {
  1380. (*vars)["method_name"] = service->method(i)->name();
  1381. auto method = service->method(i);
  1382. if (ServerOnlyStreaming(method.get())) {
  1383. printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
  1384. }
  1385. }
  1386. printer->Print("Service");
  1387. for (int i = 0; i < service->method_count(); ++i) {
  1388. auto method = service->method(i);
  1389. if (ServerOnlyStreaming(method.get())) {
  1390. printer->Print(" >");
  1391. }
  1392. }
  1393. printer->Print(" SplitStreamedService;\n");
  1394. // Server side - typedef for controlled both unary and server-side streaming
  1395. printer->Print("typedef ");
  1396. for (int i = 0; i < service->method_count(); ++i) {
  1397. (*vars)["method_name"] = service->method(i)->name();
  1398. auto method = service->method(i);
  1399. if (ServerOnlyStreaming(method.get())) {
  1400. printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<");
  1401. }
  1402. if (service->method(i)->NoStreaming()) {
  1403. printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
  1404. }
  1405. }
  1406. printer->Print("Service");
  1407. for (int i = 0; i < service->method_count(); ++i) {
  1408. auto method = service->method(i);
  1409. if (service->method(i)->NoStreaming() ||
  1410. ServerOnlyStreaming(method.get())) {
  1411. printer->Print(" >");
  1412. }
  1413. }
  1414. printer->Print(" StreamedService;\n");
  1415. printer->Outdent();
  1416. printer->Print("};\n");
  1417. printer->Print(service->GetTrailingComments("//").c_str());
  1418. }
  1419. grpc::string GetHeaderServices(grpc_generator::File* file,
  1420. const Parameters& params) {
  1421. grpc::string output;
  1422. {
  1423. // Scope the output stream so it closes and finalizes output to the string.
  1424. auto printer = file->CreatePrinter(&output);
  1425. std::map<grpc::string, grpc::string> vars;
  1426. // Package string is empty or ends with a dot. It is used to fully qualify
  1427. // method names.
  1428. vars["Package"] = file->package();
  1429. if (!file->package().empty()) {
  1430. vars["Package"].append(".");
  1431. }
  1432. if (!params.services_namespace.empty()) {
  1433. vars["services_namespace"] = params.services_namespace;
  1434. printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
  1435. }
  1436. for (int i = 0; i < file->service_count(); ++i) {
  1437. PrintHeaderService(printer.get(), file->service(i).get(), &vars);
  1438. printer->Print("\n");
  1439. }
  1440. if (!params.services_namespace.empty()) {
  1441. printer->Print(vars, "} // namespace $services_namespace$\n\n");
  1442. }
  1443. }
  1444. return output;
  1445. }
  1446. grpc::string GetHeaderEpilogue(grpc_generator::File* file,
  1447. const Parameters& /*params*/) {
  1448. grpc::string output;
  1449. {
  1450. // Scope the output stream so it closes and finalizes output to the string.
  1451. auto printer = file->CreatePrinter(&output);
  1452. std::map<grpc::string, grpc::string> vars;
  1453. vars["filename"] = file->filename();
  1454. vars["filename_identifier"] = FilenameIdentifier(file->filename());
  1455. if (!file->package().empty()) {
  1456. std::vector<grpc::string> parts = file->package_parts();
  1457. for (auto part = parts.rbegin(); part != parts.rend(); part++) {
  1458. vars["part"] = *part;
  1459. printer->Print(vars, "} // namespace $part$\n");
  1460. }
  1461. printer->Print(vars, "\n");
  1462. }
  1463. printer->Print(vars, "\n");
  1464. printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
  1465. printer->Print(file->GetTrailingComments("//").c_str());
  1466. }
  1467. return output;
  1468. }
  1469. grpc::string GetSourcePrologue(grpc_generator::File* file,
  1470. const Parameters& /*params*/) {
  1471. grpc::string output;
  1472. {
  1473. // Scope the output stream so it closes and finalizes output to the string.
  1474. auto printer = file->CreatePrinter(&output);
  1475. std::map<grpc::string, grpc::string> vars;
  1476. vars["filename"] = file->filename();
  1477. vars["filename_base"] = file->filename_without_ext();
  1478. vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
  1479. vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
  1480. printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
  1481. printer->Print(vars,
  1482. "// If you make any local change, they will be lost.\n");
  1483. printer->Print(vars, "// source: $filename$\n\n");
  1484. printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
  1485. printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
  1486. printer->Print(vars, "\n");
  1487. }
  1488. return output;
  1489. }
  1490. grpc::string GetSourceIncludes(grpc_generator::File* file,
  1491. const Parameters& params) {
  1492. grpc::string output;
  1493. {
  1494. // Scope the output stream so it closes and finalizes output to the string.
  1495. auto printer = file->CreatePrinter(&output);
  1496. std::map<grpc::string, grpc::string> vars;
  1497. static const char* headers_strs[] = {
  1498. "functional",
  1499. "grpcpp/impl/codegen/async_stream.h",
  1500. "grpcpp/impl/codegen/async_unary_call.h",
  1501. "grpcpp/impl/codegen/channel_interface.h",
  1502. "grpcpp/impl/codegen/client_unary_call.h",
  1503. "grpcpp/impl/codegen/client_callback.h",
  1504. "grpcpp/impl/codegen/method_handler_impl.h",
  1505. "grpcpp/impl/codegen/rpc_service_method.h",
  1506. "grpcpp/impl/codegen/server_callback.h",
  1507. "grpcpp/impl/codegen/service_type.h",
  1508. "grpcpp/impl/codegen/sync_stream.h"};
  1509. std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
  1510. PrintIncludes(printer.get(), headers, params.use_system_headers,
  1511. params.grpc_search_path);
  1512. if (!file->package().empty()) {
  1513. std::vector<grpc::string> parts = file->package_parts();
  1514. for (auto part = parts.begin(); part != parts.end(); part++) {
  1515. vars["part"] = *part;
  1516. printer->Print(vars, "namespace $part$ {\n");
  1517. }
  1518. }
  1519. printer->Print(vars, "\n");
  1520. }
  1521. return output;
  1522. }
  1523. void PrintSourceClientMethod(grpc_generator::Printer* printer,
  1524. const grpc_generator::Method* method,
  1525. std::map<grpc::string, grpc::string>* vars) {
  1526. (*vars)["Method"] = method->name();
  1527. (*vars)["Request"] = method->input_type_name();
  1528. (*vars)["Response"] = method->output_type_name();
  1529. struct {
  1530. grpc::string prefix;
  1531. grpc::string start; // bool literal expressed as string
  1532. grpc::string method_params; // extra arguments to method
  1533. grpc::string create_args; // extra arguments to creator
  1534. } async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
  1535. {"PrepareAsync", "false", "", ", nullptr"}};
  1536. if (method->NoStreaming()) {
  1537. printer->Print(*vars,
  1538. "::grpc::Status $ns$$Service$::Stub::$Method$("
  1539. "::grpc::ClientContext* context, "
  1540. "const $Request$& request, $Response$* response) {\n");
  1541. printer->Print(*vars,
  1542. " return ::grpc::internal::BlockingUnaryCall"
  1543. "(channel_.get(), rpcmethod_$Method$_, "
  1544. "context, request, response);\n}\n\n");
  1545. printer->Print(*vars,
  1546. "void $ns$$Service$::Stub::experimental_async::$Method$("
  1547. "::grpc::ClientContext* context, "
  1548. "const $Request$* request, $Response$* response, "
  1549. "std::function<void(::grpc::Status)> f) {\n");
  1550. printer->Print(*vars,
  1551. " return ::grpc::internal::CallbackUnaryCall"
  1552. "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
  1553. "context, request, response, std::move(f));\n}\n\n");
  1554. for (auto async_prefix : async_prefixes) {
  1555. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1556. (*vars)["AsyncStart"] = async_prefix.start;
  1557. printer->Print(*vars,
  1558. "::grpc::ClientAsyncResponseReader< $Response$>* "
  1559. "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
  1560. "ClientContext* context, "
  1561. "const $Request$& request, "
  1562. "::grpc::CompletionQueue* cq) {\n");
  1563. printer->Print(
  1564. *vars,
  1565. " return "
  1566. "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
  1567. "::Create(channel_.get(), cq, "
  1568. "rpcmethod_$Method$_, "
  1569. "context, request, $AsyncStart$);\n"
  1570. "}\n\n");
  1571. }
  1572. } else if (ClientOnlyStreaming(method)) {
  1573. printer->Print(*vars,
  1574. "::grpc::ClientWriter< $Request$>* "
  1575. "$ns$$Service$::Stub::$Method$Raw("
  1576. "::grpc::ClientContext* context, $Response$* response) {\n");
  1577. printer->Print(
  1578. *vars,
  1579. " return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
  1580. "channel_.get(), "
  1581. "rpcmethod_$Method$_, "
  1582. "context, response);\n"
  1583. "}\n\n");
  1584. printer->Print(
  1585. *vars,
  1586. "void $ns$$Service$::"
  1587. "Stub::experimental_async::$Method$(::grpc::ClientContext* context, "
  1588. "$Response$* response, "
  1589. "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n");
  1590. printer->Print(*vars,
  1591. " ::grpc::internal::ClientCallbackWriterFactory< "
  1592. "$Request$>::Create("
  1593. "stub_->channel_.get(), "
  1594. "stub_->rpcmethod_$Method$_, "
  1595. "context, response, reactor);\n"
  1596. "}\n\n");
  1597. for (auto async_prefix : async_prefixes) {
  1598. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1599. (*vars)["AsyncStart"] = async_prefix.start;
  1600. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1601. (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
  1602. printer->Print(*vars,
  1603. "::grpc::ClientAsyncWriter< $Request$>* "
  1604. "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
  1605. "::grpc::ClientContext* context, $Response$* response, "
  1606. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  1607. printer->Print(
  1608. *vars,
  1609. " return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
  1610. "::Create(channel_.get(), cq, "
  1611. "rpcmethod_$Method$_, "
  1612. "context, response, $AsyncStart$$AsyncCreateArgs$);\n"
  1613. "}\n\n");
  1614. }
  1615. } else if (ServerOnlyStreaming(method)) {
  1616. printer->Print(
  1617. *vars,
  1618. "::grpc::ClientReader< $Response$>* "
  1619. "$ns$$Service$::Stub::$Method$Raw("
  1620. "::grpc::ClientContext* context, const $Request$& request) {\n");
  1621. printer->Print(
  1622. *vars,
  1623. " return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
  1624. "channel_.get(), "
  1625. "rpcmethod_$Method$_, "
  1626. "context, request);\n"
  1627. "}\n\n");
  1628. printer->Print(
  1629. *vars,
  1630. "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
  1631. "ClientContext* context, "
  1632. "$Request$* request, "
  1633. "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n");
  1634. printer->Print(*vars,
  1635. " ::grpc::internal::ClientCallbackReaderFactory< "
  1636. "$Response$>::Create("
  1637. "stub_->channel_.get(), "
  1638. "stub_->rpcmethod_$Method$_, "
  1639. "context, request, reactor);\n"
  1640. "}\n\n");
  1641. for (auto async_prefix : async_prefixes) {
  1642. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1643. (*vars)["AsyncStart"] = async_prefix.start;
  1644. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1645. (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
  1646. printer->Print(
  1647. *vars,
  1648. "::grpc::ClientAsyncReader< $Response$>* "
  1649. "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
  1650. "::grpc::ClientContext* context, const $Request$& request, "
  1651. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  1652. printer->Print(
  1653. *vars,
  1654. " return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
  1655. "::Create(channel_.get(), cq, "
  1656. "rpcmethod_$Method$_, "
  1657. "context, request, $AsyncStart$$AsyncCreateArgs$);\n"
  1658. "}\n\n");
  1659. }
  1660. } else if (method->BidiStreaming()) {
  1661. printer->Print(
  1662. *vars,
  1663. "::grpc::ClientReaderWriter< $Request$, $Response$>* "
  1664. "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
  1665. printer->Print(*vars,
  1666. " return ::grpc::internal::ClientReaderWriterFactory< "
  1667. "$Request$, $Response$>::Create("
  1668. "channel_.get(), "
  1669. "rpcmethod_$Method$_, "
  1670. "context);\n"
  1671. "}\n\n");
  1672. printer->Print(
  1673. *vars,
  1674. "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
  1675. "ClientContext* context, "
  1676. "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* "
  1677. "reactor) {\n");
  1678. printer->Print(*vars,
  1679. " ::grpc::internal::ClientCallbackReaderWriterFactory< "
  1680. "$Request$,$Response$>::Create("
  1681. "stub_->channel_.get(), "
  1682. "stub_->rpcmethod_$Method$_, "
  1683. "context, reactor);\n"
  1684. "}\n\n");
  1685. for (auto async_prefix : async_prefixes) {
  1686. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1687. (*vars)["AsyncStart"] = async_prefix.start;
  1688. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  1689. (*vars)["AsyncCreateArgs"] = async_prefix.create_args;
  1690. printer->Print(*vars,
  1691. "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
  1692. "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
  1693. "ClientContext* context, "
  1694. "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
  1695. printer->Print(*vars,
  1696. " return "
  1697. "::grpc::internal::ClientAsyncReaderWriterFactory< "
  1698. "$Request$, $Response$>::Create("
  1699. "channel_.get(), cq, "
  1700. "rpcmethod_$Method$_, "
  1701. "context, $AsyncStart$$AsyncCreateArgs$);\n"
  1702. "}\n\n");
  1703. }
  1704. }
  1705. }
  1706. void PrintSourceServerMethod(grpc_generator::Printer* printer,
  1707. const grpc_generator::Method* method,
  1708. std::map<grpc::string, grpc::string>* vars) {
  1709. (*vars)["Method"] = method->name();
  1710. (*vars)["Request"] = method->input_type_name();
  1711. (*vars)["Response"] = method->output_type_name();
  1712. if (method->NoStreaming()) {
  1713. printer->Print(*vars,
  1714. "::grpc::Status $ns$$Service$::Service::$Method$("
  1715. "::grpc::ServerContext* context, "
  1716. "const $Request$* request, $Response$* response) {\n");
  1717. printer->Print(" (void) context;\n");
  1718. printer->Print(" (void) request;\n");
  1719. printer->Print(" (void) response;\n");
  1720. printer->Print(
  1721. " return ::grpc::Status("
  1722. "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
  1723. printer->Print("}\n\n");
  1724. } else if (ClientOnlyStreaming(method)) {
  1725. printer->Print(*vars,
  1726. "::grpc::Status $ns$$Service$::Service::$Method$("
  1727. "::grpc::ServerContext* context, "
  1728. "::grpc::ServerReader< $Request$>* reader, "
  1729. "$Response$* response) {\n");
  1730. printer->Print(" (void) context;\n");
  1731. printer->Print(" (void) reader;\n");
  1732. printer->Print(" (void) response;\n");
  1733. printer->Print(
  1734. " return ::grpc::Status("
  1735. "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
  1736. printer->Print("}\n\n");
  1737. } else if (ServerOnlyStreaming(method)) {
  1738. printer->Print(*vars,
  1739. "::grpc::Status $ns$$Service$::Service::$Method$("
  1740. "::grpc::ServerContext* context, "
  1741. "const $Request$* request, "
  1742. "::grpc::ServerWriter< $Response$>* writer) {\n");
  1743. printer->Print(" (void) context;\n");
  1744. printer->Print(" (void) request;\n");
  1745. printer->Print(" (void) writer;\n");
  1746. printer->Print(
  1747. " return ::grpc::Status("
  1748. "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
  1749. printer->Print("}\n\n");
  1750. } else if (method->BidiStreaming()) {
  1751. printer->Print(*vars,
  1752. "::grpc::Status $ns$$Service$::Service::$Method$("
  1753. "::grpc::ServerContext* context, "
  1754. "::grpc::ServerReaderWriter< $Response$, $Request$>* "
  1755. "stream) {\n");
  1756. printer->Print(" (void) context;\n");
  1757. printer->Print(" (void) stream;\n");
  1758. printer->Print(
  1759. " return ::grpc::Status("
  1760. "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
  1761. printer->Print("}\n\n");
  1762. }
  1763. }
  1764. void PrintSourceService(grpc_generator::Printer* printer,
  1765. const grpc_generator::Service* service,
  1766. std::map<grpc::string, grpc::string>* vars) {
  1767. (*vars)["Service"] = service->name();
  1768. if (service->method_count() > 0) {
  1769. printer->Print(*vars,
  1770. "static const char* $prefix$$Service$_method_names[] = {\n");
  1771. for (int i = 0; i < service->method_count(); ++i) {
  1772. (*vars)["Method"] = service->method(i)->name();
  1773. printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
  1774. }
  1775. printer->Print(*vars, "};\n\n");
  1776. }
  1777. printer->Print(*vars,
  1778. "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
  1779. "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
  1780. "const ::grpc::StubOptions& options) {\n"
  1781. " (void)options;\n"
  1782. " std::unique_ptr< $ns$$Service$::Stub> stub(new "
  1783. "$ns$$Service$::Stub(channel));\n"
  1784. " return stub;\n"
  1785. "}\n\n");
  1786. printer->Print(*vars,
  1787. "$ns$$Service$::Stub::Stub(const std::shared_ptr< "
  1788. "::grpc::ChannelInterface>& channel)\n");
  1789. printer->Indent();
  1790. printer->Print(": channel_(channel)");
  1791. for (int i = 0; i < service->method_count(); ++i) {
  1792. auto method = service->method(i);
  1793. (*vars)["Method"] = method->name();
  1794. (*vars)["Idx"] = as_string(i);
  1795. if (method->NoStreaming()) {
  1796. (*vars)["StreamingType"] = "NORMAL_RPC";
  1797. // NOTE: There is no reason to consider streamed-unary as a separate
  1798. // category here since this part is setting up the client-side stub
  1799. // and this appears as a NORMAL_RPC from the client-side.
  1800. } else if (ClientOnlyStreaming(method.get())) {
  1801. (*vars)["StreamingType"] = "CLIENT_STREAMING";
  1802. } else if (ServerOnlyStreaming(method.get())) {
  1803. (*vars)["StreamingType"] = "SERVER_STREAMING";
  1804. } else {
  1805. (*vars)["StreamingType"] = "BIDI_STREAMING";
  1806. }
  1807. printer->Print(*vars,
  1808. ", rpcmethod_$Method$_("
  1809. "$prefix$$Service$_method_names[$Idx$], "
  1810. "::grpc::internal::RpcMethod::$StreamingType$, "
  1811. "channel"
  1812. ")\n");
  1813. }
  1814. printer->Print("{}\n\n");
  1815. printer->Outdent();
  1816. for (int i = 0; i < service->method_count(); ++i) {
  1817. (*vars)["Idx"] = as_string(i);
  1818. PrintSourceClientMethod(printer, service->method(i).get(), vars);
  1819. }
  1820. printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
  1821. printer->Indent();
  1822. for (int i = 0; i < service->method_count(); ++i) {
  1823. auto method = service->method(i);
  1824. (*vars)["Idx"] = as_string(i);
  1825. (*vars)["Method"] = method->name();
  1826. (*vars)["Request"] = method->input_type_name();
  1827. (*vars)["Response"] = method->output_type_name();
  1828. if (method->NoStreaming()) {
  1829. printer->Print(
  1830. *vars,
  1831. "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
  1832. " $prefix$$Service$_method_names[$Idx$],\n"
  1833. " ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
  1834. " new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
  1835. "$Request$, "
  1836. "$Response$>(\n"
  1837. " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
  1838. } else if (ClientOnlyStreaming(method.get())) {
  1839. printer->Print(
  1840. *vars,
  1841. "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
  1842. " $prefix$$Service$_method_names[$Idx$],\n"
  1843. " ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
  1844. " new ::grpc::internal::ClientStreamingHandler< "
  1845. "$ns$$Service$::Service, $Request$, $Response$>(\n"
  1846. " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
  1847. } else if (ServerOnlyStreaming(method.get())) {
  1848. printer->Print(
  1849. *vars,
  1850. "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
  1851. " $prefix$$Service$_method_names[$Idx$],\n"
  1852. " ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
  1853. " new ::grpc::internal::ServerStreamingHandler< "
  1854. "$ns$$Service$::Service, $Request$, $Response$>(\n"
  1855. " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
  1856. } else if (method->BidiStreaming()) {
  1857. printer->Print(
  1858. *vars,
  1859. "AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
  1860. " $prefix$$Service$_method_names[$Idx$],\n"
  1861. " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
  1862. " new ::grpc::internal::BidiStreamingHandler< "
  1863. "$ns$$Service$::Service, $Request$, $Response$>(\n"
  1864. " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
  1865. }
  1866. }
  1867. printer->Outdent();
  1868. printer->Print(*vars, "}\n\n");
  1869. printer->Print(*vars,
  1870. "$ns$$Service$::Service::~Service() {\n"
  1871. "}\n\n");
  1872. for (int i = 0; i < service->method_count(); ++i) {
  1873. (*vars)["Idx"] = as_string(i);
  1874. PrintSourceServerMethod(printer, service->method(i).get(), vars);
  1875. }
  1876. }
  1877. grpc::string GetSourceServices(grpc_generator::File* file,
  1878. const Parameters& params) {
  1879. grpc::string output;
  1880. {
  1881. // Scope the output stream so it closes and finalizes output to the string.
  1882. auto printer = file->CreatePrinter(&output);
  1883. std::map<grpc::string, grpc::string> vars;
  1884. // Package string is empty or ends with a dot. It is used to fully qualify
  1885. // method names.
  1886. vars["Package"] = file->package();
  1887. if (!file->package().empty()) {
  1888. vars["Package"].append(".");
  1889. }
  1890. if (!params.services_namespace.empty()) {
  1891. vars["ns"] = params.services_namespace + "::";
  1892. vars["prefix"] = params.services_namespace;
  1893. } else {
  1894. vars["ns"] = "";
  1895. vars["prefix"] = "";
  1896. }
  1897. for (int i = 0; i < file->service_count(); ++i) {
  1898. PrintSourceService(printer.get(), file->service(i).get(), &vars);
  1899. printer->Print("\n");
  1900. }
  1901. }
  1902. return output;
  1903. }
  1904. grpc::string GetSourceEpilogue(grpc_generator::File* file,
  1905. const Parameters& /*params*/) {
  1906. grpc::string temp;
  1907. if (!file->package().empty()) {
  1908. std::vector<grpc::string> parts = file->package_parts();
  1909. for (auto part = parts.begin(); part != parts.end(); part++) {
  1910. temp.append("} // namespace ");
  1911. temp.append(*part);
  1912. temp.append("\n");
  1913. }
  1914. temp.append("\n");
  1915. }
  1916. return temp;
  1917. }
  1918. // TODO(mmukhi): Make sure we need parameters or not.
  1919. grpc::string GetMockPrologue(grpc_generator::File* file,
  1920. const Parameters& /*params*/) {
  1921. grpc::string output;
  1922. {
  1923. // Scope the output stream so it closes and finalizes output to the string.
  1924. auto printer = file->CreatePrinter(&output);
  1925. std::map<grpc::string, grpc::string> vars;
  1926. vars["filename"] = file->filename();
  1927. vars["filename_base"] = file->filename_without_ext();
  1928. vars["message_header_ext"] = kCppGeneratorMessageHeaderExt;
  1929. vars["service_header_ext"] = kCppGeneratorServiceHeaderExt;
  1930. printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
  1931. printer->Print(vars,
  1932. "// If you make any local change, they will be lost.\n");
  1933. printer->Print(vars, "// source: $filename$\n\n");
  1934. printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
  1935. printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
  1936. printer->Print(vars, file->additional_headers().c_str());
  1937. printer->Print(vars, "\n");
  1938. }
  1939. return output;
  1940. }
  1941. // TODO(mmukhi): Add client-stream and completion-queue headers.
  1942. grpc::string GetMockIncludes(grpc_generator::File* file,
  1943. const Parameters& params) {
  1944. grpc::string output;
  1945. {
  1946. // Scope the output stream so it closes and finalizes output to the string.
  1947. auto printer = file->CreatePrinter(&output);
  1948. std::map<grpc::string, grpc::string> vars;
  1949. static const char* headers_strs[] = {
  1950. "grpcpp/impl/codegen/async_stream.h",
  1951. "grpcpp/impl/codegen/sync_stream.h",
  1952. };
  1953. std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
  1954. PrintIncludes(printer.get(), headers, params.use_system_headers,
  1955. params.grpc_search_path);
  1956. std::vector<grpc::string> gmock_header;
  1957. if (params.gmock_search_path.empty()) {
  1958. gmock_header.push_back("gmock/gmock.h");
  1959. PrintIncludes(printer.get(), gmock_header, params.use_system_headers,
  1960. params.grpc_search_path);
  1961. } else {
  1962. gmock_header.push_back("gmock.h");
  1963. // We use local includes when a gmock_search_path is given
  1964. PrintIncludes(printer.get(), gmock_header, false,
  1965. params.gmock_search_path);
  1966. }
  1967. if (!file->package().empty()) {
  1968. std::vector<grpc::string> parts = file->package_parts();
  1969. for (auto part = parts.begin(); part != parts.end(); part++) {
  1970. vars["part"] = *part;
  1971. printer->Print(vars, "namespace $part$ {\n");
  1972. }
  1973. }
  1974. printer->Print(vars, "\n");
  1975. }
  1976. return output;
  1977. }
  1978. void PrintMockClientMethods(grpc_generator::Printer* printer,
  1979. const grpc_generator::Method* method,
  1980. std::map<grpc::string, grpc::string>* vars) {
  1981. (*vars)["Method"] = method->name();
  1982. (*vars)["Request"] = method->input_type_name();
  1983. (*vars)["Response"] = method->output_type_name();
  1984. struct {
  1985. grpc::string prefix;
  1986. grpc::string method_params; // extra arguments to method
  1987. int extra_method_param_count;
  1988. } async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
  1989. if (method->NoStreaming()) {
  1990. printer->Print(
  1991. *vars,
  1992. "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
  1993. "const $Request$& request, $Response$* response));\n");
  1994. for (auto async_prefix : async_prefixes) {
  1995. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  1996. printer->Print(
  1997. *vars,
  1998. "MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
  1999. "::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
  2000. "(::grpc::ClientContext* context, const $Request$& request, "
  2001. "::grpc::CompletionQueue* cq));\n");
  2002. }
  2003. } else if (ClientOnlyStreaming(method)) {
  2004. printer->Print(
  2005. *vars,
  2006. "MOCK_METHOD2($Method$Raw, "
  2007. "::grpc::ClientWriterInterface< $Request$>*"
  2008. "(::grpc::ClientContext* context, $Response$* response));\n");
  2009. for (auto async_prefix : async_prefixes) {
  2010. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  2011. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  2012. (*vars)["MockArgs"] =
  2013. std::to_string(3 + async_prefix.extra_method_param_count);
  2014. printer->Print(*vars,
  2015. "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
  2016. "::grpc::ClientAsyncWriterInterface< $Request$>*"
  2017. "(::grpc::ClientContext* context, $Response$* response, "
  2018. "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
  2019. }
  2020. } else if (ServerOnlyStreaming(method)) {
  2021. printer->Print(
  2022. *vars,
  2023. "MOCK_METHOD2($Method$Raw, "
  2024. "::grpc::ClientReaderInterface< $Response$>*"
  2025. "(::grpc::ClientContext* context, const $Request$& request));\n");
  2026. for (auto async_prefix : async_prefixes) {
  2027. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  2028. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  2029. (*vars)["MockArgs"] =
  2030. std::to_string(3 + async_prefix.extra_method_param_count);
  2031. printer->Print(
  2032. *vars,
  2033. "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
  2034. "::grpc::ClientAsyncReaderInterface< $Response$>*"
  2035. "(::grpc::ClientContext* context, const $Request$& request, "
  2036. "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
  2037. }
  2038. } else if (method->BidiStreaming()) {
  2039. printer->Print(
  2040. *vars,
  2041. "MOCK_METHOD1($Method$Raw, "
  2042. "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
  2043. "(::grpc::ClientContext* context));\n");
  2044. for (auto async_prefix : async_prefixes) {
  2045. (*vars)["AsyncPrefix"] = async_prefix.prefix;
  2046. (*vars)["AsyncMethodParams"] = async_prefix.method_params;
  2047. (*vars)["MockArgs"] =
  2048. std::to_string(2 + async_prefix.extra_method_param_count);
  2049. printer->Print(
  2050. *vars,
  2051. "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
  2052. "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
  2053. "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
  2054. "$AsyncMethodParams$));\n");
  2055. }
  2056. }
  2057. }
  2058. void PrintMockService(grpc_generator::Printer* printer,
  2059. const grpc_generator::Service* service,
  2060. std::map<grpc::string, grpc::string>* vars) {
  2061. (*vars)["Service"] = service->name();
  2062. printer->Print(*vars,
  2063. "class Mock$Service$Stub : public $Service$::StubInterface {\n"
  2064. " public:\n");
  2065. printer->Indent();
  2066. for (int i = 0; i < service->method_count(); ++i) {
  2067. PrintMockClientMethods(printer, service->method(i).get(), vars);
  2068. }
  2069. printer->Outdent();
  2070. printer->Print("};\n");
  2071. }
  2072. grpc::string GetMockServices(grpc_generator::File* file,
  2073. const Parameters& params) {
  2074. grpc::string output;
  2075. {
  2076. // Scope the output stream so it closes and finalizes output to the string.
  2077. auto printer = file->CreatePrinter(&output);
  2078. std::map<grpc::string, grpc::string> vars;
  2079. // Package string is empty or ends with a dot. It is used to fully qualify
  2080. // method names.
  2081. vars["Package"] = file->package();
  2082. if (!file->package().empty()) {
  2083. vars["Package"].append(".");
  2084. }
  2085. if (!params.services_namespace.empty()) {
  2086. vars["services_namespace"] = params.services_namespace;
  2087. printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
  2088. }
  2089. for (int i = 0; i < file->service_count(); i++) {
  2090. PrintMockService(printer.get(), file->service(i).get(), &vars);
  2091. printer->Print("\n");
  2092. }
  2093. if (!params.services_namespace.empty()) {
  2094. printer->Print(vars, "} // namespace $services_namespace$\n\n");
  2095. }
  2096. }
  2097. return output;
  2098. }
  2099. grpc::string GetMockEpilogue(grpc_generator::File* file,
  2100. const Parameters& /*params*/) {
  2101. grpc::string temp;
  2102. if (!file->package().empty()) {
  2103. std::vector<grpc::string> parts = file->package_parts();
  2104. for (auto part = parts.begin(); part != parts.end(); part++) {
  2105. temp.append("} // namespace ");
  2106. temp.append(*part);
  2107. temp.append("\n");
  2108. }
  2109. temp.append("\n");
  2110. }
  2111. return temp;
  2112. }
  2113. } // namespace grpc_cpp_generator