diff options
Diffstat (limited to 'src/compiler/cpp_generator.cc')
-rw-r--r-- | src/compiler/cpp_generator.cc | 355 |
1 files changed, 285 insertions, 70 deletions
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 2908b639f3..a1a0258c68 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -40,6 +40,9 @@ namespace grpc_cpp_generator { namespace { +grpc::string message_header_ext() { return ".pb.h"; } +grpc::string service_header_ext() { return ".grpc.pb.h"; } + template <class T> grpc::string as_string(T x) { std::ostringstream out; @@ -47,6 +50,14 @@ grpc::string as_string(T x) { return out.str(); } +inline bool ClientOnlyStreaming(const grpc_generator::Method *method) { + return method->ClientStreaming() && !method->ServerStreaming(); +} + +inline bool ServerOnlyStreaming(const grpc_generator::Method *method) { + return !method->ClientStreaming() && method->ServerStreaming(); +} + grpc::string FilenameIdentifier(const grpc::string &filename) { grpc::string result; for (unsigned i = 0; i < filename.size(); i++) { @@ -69,7 +80,8 @@ T *array_end(T (&array)[N]) { return array + N; } -void PrintIncludes(Printer *printer, const std::vector<grpc::string> &headers, +void PrintIncludes(grpc_generator::Printer *printer, + const std::vector<grpc::string> &headers, const Parameters ¶ms) { std::map<grpc::string, grpc::string> vars; @@ -90,7 +102,8 @@ void PrintIncludes(Printer *printer, const std::vector<grpc::string> &headers, } } -grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) { +grpc::string GetHeaderPrologue(grpc_generator::File *file, + const Parameters & /*params*/) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -100,13 +113,13 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) { vars["filename"] = file->filename(); vars["filename_identifier"] = FilenameIdentifier(file->filename()); vars["filename_base"] = file->filename_without_ext(); - vars["message_header_ext"] = file->message_header_ext(); + vars["message_header_ext"] = message_header_ext(); printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); printer->Print(vars, "// If you make any local change, they will be lost.\n"); printer->Print(vars, "// source: $filename$\n"); - grpc::string leading_comments = file->GetLeadingComments(); + grpc::string leading_comments = file->GetLeadingComments("//"); if (!leading_comments.empty()) { printer->Print(vars, "// Original file comments:\n"); printer->Print(leading_comments.c_str()); @@ -120,7 +133,8 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) { return output; } -grpc::string GetHeaderIncludes(File *file, const Parameters ¶ms) { +grpc::string GetHeaderIncludes(grpc_generator::File *file, + const Parameters ¶ms) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -162,7 +176,7 @@ grpc::string GetHeaderIncludes(File *file, const Parameters ¶ms) { } void PrintHeaderClientMethodInterfaces( - Printer *printer, const Method *method, + grpc_generator::Printer *printer, const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars, bool is_public) { (*vars)["Method"] = method->name(); (*vars)["Request"] = method->input_type_name(); @@ -187,7 +201,7 @@ void PrintHeaderClientMethodInterfaces( "Async$Method$Raw(context, request, cq));\n"); printer->Outdent(); printer->Print("}\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print( *vars, "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>" @@ -213,7 +227,7 @@ void PrintHeaderClientMethodInterfaces( "Async$Method$Raw(context, response, cq, tag));\n"); printer->Outdent(); printer->Print("}\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>" @@ -275,7 +289,7 @@ void PrintHeaderClientMethodInterfaces( "Async$Method$Raw(::grpc::ClientContext* context, " "const $Request$& request, " "::grpc::CompletionQueue* cq) = 0;\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print( *vars, "virtual ::grpc::ClientWriterInterface< $Request$>*" @@ -286,7 +300,7 @@ void PrintHeaderClientMethodInterfaces( " Async$Method$Raw(::grpc::ClientContext* context, " "$Response$* response, " "::grpc::CompletionQueue* cq, void* tag) = 0;\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw(" @@ -311,7 +325,8 @@ void PrintHeaderClientMethodInterfaces( } } -void PrintHeaderClientMethod(Printer *printer, const Method *method, +void PrintHeaderClientMethod(grpc_generator::Printer *printer, + const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars, bool is_public) { (*vars)["Method"] = method->name(); @@ -336,7 +351,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method, "Async$Method$Raw(context, request, cq));\n"); printer->Outdent(); printer->Print("}\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print( *vars, "std::unique_ptr< ::grpc::ClientWriter< $Request$>>" @@ -360,7 +375,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method, "Async$Method$Raw(context, response, cq, tag));\n"); printer->Outdent(); printer->Print("}\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, "std::unique_ptr< ::grpc::ClientReader< $Response$>>" @@ -418,7 +433,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method, "Async$Method$Raw(::grpc::ClientContext* context, " "const $Request$& request, " "::grpc::CompletionQueue* cq) override;\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "::grpc::ClientWriter< $Request$>* $Method$Raw(" "::grpc::ClientContext* context, $Response$* response) " @@ -427,7 +442,7 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method, "::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw(" "::grpc::ClientContext* context, $Response$* response, " "::grpc::CompletionQueue* cq, void* tag) override;\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print(*vars, "::grpc::ClientReader< $Response$>* $Method$Raw(" "::grpc::ClientContext* context, const $Request$& request)" @@ -449,30 +464,32 @@ void PrintHeaderClientMethod(Printer *printer, const Method *method, } } -void PrintHeaderClientMethodData(Printer *printer, const Method *method, +void PrintHeaderClientMethodData(grpc_generator::Printer *printer, + const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars) { (*vars)["Method"] = method->name(); printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n"); } -void PrintHeaderServerMethodSync(Printer *printer, const Method *method, +void PrintHeaderServerMethodSync(grpc_generator::Printer *printer, + const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars) { (*vars)["Method"] = method->name(); (*vars)["Request"] = method->input_type_name(); (*vars)["Response"] = method->output_type_name(); - printer->Print(method->GetLeadingComments().c_str()); + printer->Print(method->GetLeadingComments("//").c_str()); if (method->NoStreaming()) { printer->Print(*vars, "virtual ::grpc::Status $Method$(" "::grpc::ServerContext* context, const $Request$* request, " "$Response$* response);\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "virtual ::grpc::Status $Method$(" "::grpc::ServerContext* context, " "::grpc::ServerReader< $Request$>* reader, " "$Response$* response);\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print(*vars, "virtual ::grpc::Status $Method$(" "::grpc::ServerContext* context, const $Request$* request, " @@ -485,10 +502,11 @@ void PrintHeaderServerMethodSync(Printer *printer, const Method *method, "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);" "\n"); } - printer->Print(method->GetTrailingComments().c_str()); + printer->Print(method->GetTrailingComments("//").c_str()); } -void PrintHeaderServerMethodAsync(Printer *printer, const Method *method, +void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer, + const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars) { (*vars)["Method"] = method->name(); (*vars)["Request"] = method->input_type_name(); @@ -530,7 +548,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method, " ::grpc::Service::RequestAsyncUnary($Idx$, context, " "request, response, new_call_cq, notification_cq, tag);\n"); printer->Print("}\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print( *vars, "// disable synchronous version of this method\n" @@ -552,7 +570,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method, " ::grpc::Service::RequestAsyncClientStreaming($Idx$, " "context, reader, new_call_cq, notification_cq, tag);\n"); printer->Print("}\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, "// disable synchronous version of this method\n" @@ -603,7 +621,7 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method, } void PrintHeaderServerMethodStreamedUnary( - Printer *printer, const Method *method, + grpc_generator::Printer *printer, const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars) { (*vars)["Method"] = method->name(); (*vars)["Request"] = method->input_type_name(); @@ -654,12 +672,12 @@ void PrintHeaderServerMethodStreamedUnary( } void PrintHeaderServerMethodSplitStreaming( - Printer *printer, const Method *method, + grpc_generator::Printer *printer, const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars) { (*vars)["Method"] = method->name(); (*vars)["Request"] = method->input_type_name(); (*vars)["Response"] = method->output_type_name(); - if (method->ServerOnlyStreaming()) { + if (ServerOnlyStreaming(method)) { printer->Print(*vars, "template <class BaseClass>\n"); printer->Print(*vars, "class WithSplitStreamingMethod_$Method$ : " @@ -706,7 +724,7 @@ void PrintHeaderServerMethodSplitStreaming( } void PrintHeaderServerMethodGeneric( - Printer *printer, const Method *method, + grpc_generator::Printer *printer, const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars) { (*vars)["Method"] = method->name(); (*vars)["Request"] = method->input_type_name(); @@ -737,7 +755,7 @@ void PrintHeaderServerMethodGeneric( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print( *vars, "// disable synchronous version of this method\n" @@ -748,7 +766,7 @@ void PrintHeaderServerMethodGeneric( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, "// disable synchronous version of this method\n" @@ -775,16 +793,23 @@ void PrintHeaderServerMethodGeneric( printer->Print(*vars, "};\n"); } -void PrintHeaderService(Printer *printer, const Service *service, +void PrintHeaderService(grpc_generator::Printer *printer, + const grpc_generator::Service *service, std::map<grpc::string, grpc::string> *vars) { (*vars)["Service"] = service->name(); - printer->Print(service->GetLeadingComments().c_str()); + printer->Print(service->GetLeadingComments("//").c_str()); printer->Print(*vars, "class $Service$ final {\n" " public:\n"); printer->Indent(); + // Service metadata + printer->Print(*vars, + "static constexpr char const* service_full_name() {\n" + " return \"$Package$$Service$\";\n" + "}\n"); + // Client side printer->Print( "class StubInterface {\n" @@ -792,10 +817,10 @@ void PrintHeaderService(Printer *printer, const Service *service, printer->Indent(); printer->Print("virtual ~StubInterface() {}\n"); for (int i = 0; i < service->method_count(); ++i) { - printer->Print(service->method(i)->GetLeadingComments().c_str()); + printer->Print(service->method(i)->GetLeadingComments("//").c_str()); PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars, true); - printer->Print(service->method(i)->GetTrailingComments().c_str()); + printer->Print(service->method(i)->GetTrailingComments("//").c_str()); } printer->Outdent(); printer->Print("private:\n"); @@ -903,13 +928,15 @@ void PrintHeaderService(Printer *printer, const Service *service, printer->Print("typedef "); for (int i = 0; i < service->method_count(); ++i) { (*vars)["method_name"] = service->method(i).get()->name(); - if (service->method(i)->ServerOnlyStreaming()) { + auto method = service->method(i); + if (ServerOnlyStreaming(method.get())) { printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<"); } } printer->Print("Service"); for (int i = 0; i < service->method_count(); ++i) { - if (service->method(i)->ServerOnlyStreaming()) { + auto method = service->method(i); + if (ServerOnlyStreaming(method.get())) { printer->Print(" >"); } } @@ -919,7 +946,8 @@ void PrintHeaderService(Printer *printer, const Service *service, printer->Print("typedef "); for (int i = 0; i < service->method_count(); ++i) { (*vars)["method_name"] = service->method(i).get()->name(); - if (service->method(i)->ServerOnlyStreaming()) { + auto method = service->method(i); + if (ServerOnlyStreaming(method.get())) { printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<"); } if (service->method(i)->NoStreaming()) { @@ -928,8 +956,9 @@ void PrintHeaderService(Printer *printer, const Service *service, } printer->Print("Service"); for (int i = 0; i < service->method_count(); ++i) { + auto method = service->method(i); if (service->method(i)->NoStreaming() || - service->method(i)->ServerOnlyStreaming()) { + ServerOnlyStreaming(method.get())) { printer->Print(" >"); } } @@ -937,10 +966,11 @@ void PrintHeaderService(Printer *printer, const Service *service, printer->Outdent(); printer->Print("};\n"); - printer->Print(service->GetTrailingComments().c_str()); + printer->Print(service->GetTrailingComments("//").c_str()); } -grpc::string GetHeaderServices(File *file, const Parameters ¶ms) { +grpc::string GetHeaderServices(grpc_generator::File *file, + const Parameters ¶ms) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -970,7 +1000,8 @@ grpc::string GetHeaderServices(File *file, const Parameters ¶ms) { return output; } -grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) { +grpc::string GetHeaderEpilogue(grpc_generator::File *file, + const Parameters & /*params*/) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -993,12 +1024,13 @@ grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) { printer->Print(vars, "\n"); printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n"); - printer->Print(file->GetTrailingComments().c_str()); + printer->Print(file->GetTrailingComments("//").c_str()); } return output; } -grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) { +grpc::string GetSourcePrologue(grpc_generator::File *file, + const Parameters & /*params*/) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -1007,8 +1039,8 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) { vars["filename"] = file->filename(); vars["filename_base"] = file->filename_without_ext(); - vars["message_header_ext"] = file->message_header_ext(); - vars["service_header_ext"] = file->service_header_ext(); + vars["message_header_ext"] = message_header_ext(); + vars["service_header_ext"] = service_header_ext(); printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); printer->Print(vars, @@ -1023,7 +1055,8 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) { return output; } -grpc::string GetSourceIncludes(File *file, const Parameters ¶ms) { +grpc::string GetSourceIncludes(grpc_generator::File *file, + const Parameters ¶ms) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -1056,7 +1089,8 @@ grpc::string GetSourceIncludes(File *file, const Parameters ¶ms) { return output; } -void PrintSourceClientMethod(Printer *printer, const Method *method, +void PrintSourceClientMethod(grpc_generator::Printer *printer, + const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars) { (*vars)["Method"] = method->name(); (*vars)["Request"] = method->input_type_name(); @@ -1078,13 +1112,13 @@ void PrintSourceClientMethod(Printer *printer, const Method *method, "const $Request$& request, " "::grpc::CompletionQueue* cq) {\n"); printer->Print(*vars, - " return new " - "::grpc::ClientAsyncResponseReader< $Response$>(" + " return " + "::grpc::ClientAsyncResponseReader< $Response$>::Create(" "channel_.get(), cq, " "rpcmethod_$Method$_, " "context, request);\n" "}\n\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "::grpc::ClientWriter< $Request$>* " "$ns$$Service$::Stub::$Method$Raw(" @@ -1101,12 +1135,12 @@ void PrintSourceClientMethod(Printer *printer, const Method *method, "::grpc::ClientContext* context, $Response$* response, " "::grpc::CompletionQueue* cq, void* tag) {\n"); printer->Print(*vars, - " return new ::grpc::ClientAsyncWriter< $Request$>(" + " return ::grpc::ClientAsyncWriter< $Request$>::Create(" "channel_.get(), cq, " "rpcmethod_$Method$_, " "context, response, tag);\n" "}\n\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, "::grpc::ClientReader< $Response$>* " @@ -1124,7 +1158,7 @@ void PrintSourceClientMethod(Printer *printer, const Method *method, "::grpc::ClientContext* context, const $Request$& request, " "::grpc::CompletionQueue* cq, void* tag) {\n"); printer->Print(*vars, - " return new ::grpc::ClientAsyncReader< $Response$>(" + " return ::grpc::ClientAsyncReader< $Response$>::Create(" "channel_.get(), cq, " "rpcmethod_$Method$_, " "context, request, tag);\n" @@ -1146,17 +1180,19 @@ void PrintSourceClientMethod(Printer *printer, const Method *method, "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* " "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, " "::grpc::CompletionQueue* cq, void* tag) {\n"); - printer->Print(*vars, - " return new " - "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>(" - "channel_.get(), cq, " - "rpcmethod_$Method$_, " - "context, tag);\n" - "}\n\n"); + printer->Print( + *vars, + " return " + "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>::Create(" + "channel_.get(), cq, " + "rpcmethod_$Method$_, " + "context, tag);\n" + "}\n\n"); } } -void PrintSourceServerMethod(Printer *printer, const Method *method, +void PrintSourceServerMethod(grpc_generator::Printer *printer, + const grpc_generator::Method *method, std::map<grpc::string, grpc::string> *vars) { (*vars)["Method"] = method->name(); (*vars)["Request"] = method->input_type_name(); @@ -1173,7 +1209,7 @@ void PrintSourceServerMethod(Printer *printer, const Method *method, " return ::grpc::Status(" "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); printer->Print("}\n\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "::grpc::Status $ns$$Service$::Service::$Method$(" "::grpc::ServerContext* context, " @@ -1186,7 +1222,7 @@ void PrintSourceServerMethod(Printer *printer, const Method *method, " return ::grpc::Status(" "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); printer->Print("}\n\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method)) { printer->Print(*vars, "::grpc::Status $ns$$Service$::Service::$Method$(" "::grpc::ServerContext* context, " @@ -1214,7 +1250,8 @@ void PrintSourceServerMethod(Printer *printer, const Method *method, } } -void PrintSourceService(Printer *printer, const Service *service, +void PrintSourceService(grpc_generator::Printer *printer, + const grpc_generator::Service *service, std::map<grpc::string, grpc::string> *vars) { (*vars)["Service"] = service->name(); @@ -1250,9 +1287,9 @@ void PrintSourceService(Printer *printer, const Service *service, // NOTE: There is no reason to consider streamed-unary as a separate // category here since this part is setting up the client-side stub // and this appears as a NORMAL_RPC from the client-side. - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method.get())) { (*vars)["StreamingType"] = "CLIENT_STREAMING"; - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method.get())) { (*vars)["StreamingType"] = "SERVER_STREAMING"; } else { (*vars)["StreamingType"] = "BIDI_STREAMING"; @@ -1290,7 +1327,7 @@ void PrintSourceService(Printer *printer, const Service *service, "$Request$, " "$Response$>(\n" " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); - } else if (method->ClientOnlyStreaming()) { + } else if (ClientOnlyStreaming(method.get())) { printer->Print( *vars, "AddMethod(new ::grpc::RpcServiceMethod(\n" @@ -1299,7 +1336,7 @@ void PrintSourceService(Printer *printer, const Service *service, " new ::grpc::ClientStreamingHandler< " "$ns$$Service$::Service, $Request$, $Response$>(\n" " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); - } else if (method->ServerOnlyStreaming()) { + } else if (ServerOnlyStreaming(method.get())) { printer->Print( *vars, "AddMethod(new ::grpc::RpcServiceMethod(\n" @@ -1330,7 +1367,8 @@ void PrintSourceService(Printer *printer, const Service *service, } } -grpc::string GetSourceServices(File *file, const Parameters ¶ms) { +grpc::string GetSourceServices(grpc_generator::File *file, + const Parameters ¶ms) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -1358,7 +1396,8 @@ grpc::string GetSourceServices(File *file, const Parameters ¶ms) { return output; } -grpc::string GetSourceEpilogue(File *file, const Parameters & /*params*/) { +grpc::string GetSourceEpilogue(grpc_generator::File *file, + const Parameters & /*params*/) { grpc::string temp; if (!file->package().empty()) { @@ -1375,4 +1414,180 @@ grpc::string GetSourceEpilogue(File *file, const Parameters & /*params*/) { return temp; } +// TODO(mmukhi): Make sure we need parameters or not. +grpc::string GetMockPrologue(grpc_generator::File *file, + const Parameters & /*params*/) { + grpc::string output; + { + // Scope the output stream so it closes and finalizes output to the string. + auto printer = file->CreatePrinter(&output); + std::map<grpc::string, grpc::string> vars; + + vars["filename"] = file->filename(); + vars["filename_base"] = file->filename_without_ext(); + vars["message_header_ext"] = message_header_ext(); + vars["service_header_ext"] = service_header_ext(); + + printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); + printer->Print(vars, + "// If you make any local change, they will be lost.\n"); + printer->Print(vars, "// source: $filename$\n\n"); + + printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n"); + printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n"); + printer->Print(vars, file->additional_headers().c_str()); + printer->Print(vars, "\n"); + } + return output; +} + +// TODO(mmukhi): Add client-stream and completion-queue headers. +grpc::string GetMockIncludes(grpc_generator::File *file, + const Parameters ¶ms) { + grpc::string output; + { + // Scope the output stream so it closes and finalizes output to the string. + auto printer = file->CreatePrinter(&output); + std::map<grpc::string, grpc::string> vars; + + static const char *headers_strs[] = { + "grpc++/impl/codegen/async_stream.h", + "grpc++/impl/codegen/sync_stream.h", "gmock/gmock.h", + }; + std::vector<grpc::string> headers(headers_strs, array_end(headers_strs)); + PrintIncludes(printer.get(), headers, params); + + if (!file->package().empty()) { + std::vector<grpc::string> parts = file->package_parts(); + + for (auto part = parts.begin(); part != parts.end(); part++) { + vars["part"] = *part; + printer->Print(vars, "namespace $part$ {\n"); + } + } + + printer->Print(vars, "\n"); + } + return output; +} + +void PrintMockClientMethods(grpc_generator::Printer *printer, + const grpc_generator::Method *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["Method"] = method->name(); + (*vars)["Request"] = method->input_type_name(); + (*vars)["Response"] = method->output_type_name(); + + if (method->NoStreaming()) { + printer->Print( + *vars, + "MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, " + "const $Request$& request, $Response$* response));\n"); + printer->Print(*vars, + "MOCK_METHOD3(Async$Method$Raw, " + "::grpc::ClientAsyncResponseReaderInterface< $Response$>*" + "(::grpc::ClientContext* context, const $Request$& request, " + "::grpc::CompletionQueue* cq));\n"); + } else if (ClientOnlyStreaming(method)) { + printer->Print( + *vars, + "MOCK_METHOD2($Method$Raw, " + "::grpc::ClientWriterInterface< $Request$>*" + "(::grpc::ClientContext* context, $Response$* response));\n"); + printer->Print(*vars, + "MOCK_METHOD4(Async$Method$Raw, " + "::grpc::ClientAsyncWriterInterface< $Request$>*" + "(::grpc::ClientContext* context, $Response$* response, " + "::grpc::CompletionQueue* cq, void* tag));\n"); + } else if (ServerOnlyStreaming(method)) { + printer->Print( + *vars, + "MOCK_METHOD2($Method$Raw, " + "::grpc::ClientReaderInterface< $Response$>*" + "(::grpc::ClientContext* context, const $Request$& request));\n"); + printer->Print(*vars, + "MOCK_METHOD4(Async$Method$Raw, " + "::grpc::ClientAsyncReaderInterface< $Response$>*" + "(::grpc::ClientContext* context, const $Request$& request, " + "::grpc::CompletionQueue* cq, void* tag));\n"); + } else if (method->BidiStreaming()) { + printer->Print( + *vars, + "MOCK_METHOD1($Method$Raw, " + "::grpc::ClientReaderWriterInterface< $Request$, $Response$>*" + "(::grpc::ClientContext* context));\n"); + printer->Print( + *vars, + "MOCK_METHOD3(Async$Method$Raw, " + "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*" + "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, " + "void* tag));\n"); + } +} + +void PrintMockService(grpc_generator::Printer *printer, + const grpc_generator::Service *service, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["Service"] = service->name(); + + printer->Print(*vars, + "class Mock$Service$Stub : public $Service$::StubInterface {\n" + " public:\n"); + printer->Indent(); + for (int i = 0; i < service->method_count(); ++i) { + PrintMockClientMethods(printer, service->method(i).get(), vars); + } + printer->Outdent(); + printer->Print("};\n"); +} + +grpc::string GetMockServices(grpc_generator::File *file, + const Parameters ¶ms) { + grpc::string output; + { + // Scope the output stream so it closes and finalizes output to the string. + auto printer = file->CreatePrinter(&output); + std::map<grpc::string, grpc::string> vars; + // Package string is empty or ends with a dot. It is used to fully qualify + // method names. + vars["Package"] = file->package(); + if (!file->package().empty()) { + vars["Package"].append("."); + } + + if (!params.services_namespace.empty()) { + vars["services_namespace"] = params.services_namespace; + printer->Print(vars, "\nnamespace $services_namespace$ {\n\n"); + } + + for (int i = 0; i < file->service_count(); i++) { + PrintMockService(printer.get(), file->service(i).get(), &vars); + printer->Print("\n"); + } + + if (!params.services_namespace.empty()) { + printer->Print(vars, "} // namespace $services_namespace$\n\n"); + } + } + return output; +} + +grpc::string GetMockEpilogue(grpc_generator::File *file, + const Parameters & /*params*/) { + grpc::string temp; + + if (!file->package().empty()) { + std::vector<grpc::string> parts = file->package_parts(); + + for (auto part = parts.begin(); part != parts.end(); part++) { + temp.append("} // namespace "); + temp.append(*part); + temp.append("\n"); + } + temp.append("\n"); + } + + return temp; +} + } // namespace grpc_cpp_generator |