aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/compiler
diff options
context:
space:
mode:
authorGravatar murgatroid99 <mlumish@google.com>2016-04-19 10:56:01 -0700
committerGravatar murgatroid99 <mlumish@google.com>2016-04-19 10:56:01 -0700
commite264e3984f6a5d8b730760d59930191a3a7c31e8 (patch)
tree7c3de6d924ae0e57cfcdab3bfee167e23ea8a546 /src/compiler
parent7d69ea63c8af9c7be43434993c82f93033343dce (diff)
parent279681311f61b079a720b7aef424cbe9000d08e8 (diff)
Merged from master
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/cpp_generator.cc440
-rw-r--r--src/compiler/cpp_generator.h97
-rw-r--r--src/compiler/cpp_plugin.cc129
-rw-r--r--src/compiler/csharp_generator.cc159
-rw-r--r--src/compiler/python_generator.cc9
-rw-r--r--src/compiler/python_generator.h2
-rw-r--r--src/compiler/python_plugin.cc2
-rw-r--r--src/compiler/ruby_generator.cc4
-rw-r--r--src/compiler/ruby_generator_string-inl.h1
9 files changed, 528 insertions, 315 deletions
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 97295bed45..b133699306 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,9 +34,6 @@
#include <map>
#include "src/compiler/cpp_generator.h"
-#include "src/compiler/cpp_generator_helpers.h"
-
-#include "src/compiler/config.h"
#include <sstream>
@@ -50,22 +47,6 @@ grpc::string as_string(T x) {
return out.str();
}
-bool NoStreaming(const grpc::protobuf::MethodDescriptor *method) {
- return !method->client_streaming() && !method->server_streaming();
-}
-
-bool ClientOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
- return method->client_streaming() && !method->server_streaming();
-}
-
-bool ServerOnlyStreaming(const grpc::protobuf::MethodDescriptor *method) {
- return !method->client_streaming() && method->server_streaming();
-}
-
-bool BidiStreaming(const grpc::protobuf::MethodDescriptor *method) {
- return method->client_streaming() && method->server_streaming();
-}
-
grpc::string FilenameIdentifier(const grpc::string &filename) {
grpc::string result;
for (unsigned i = 0; i < filename.size(); i++) {
@@ -83,78 +64,103 @@ grpc::string FilenameIdentifier(const grpc::string &filename) {
}
} // namespace
-grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params) {
+template<class T, size_t N>
+T *array_end(T (&array)[N]) { return array + N; }
+
+void PrintIncludes(Printer *printer, const std::vector<grpc::string>& headers, const Parameters &params) {
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["l"] = params.use_system_headers ? '<' : '"';
+ vars["r"] = params.use_system_headers ? '>' : '"';
+
+ if (!params.grpc_search_path.empty()) {
+ vars["l"] += params.grpc_search_path;
+ if (params.grpc_search_path.back() != '/') {
+ vars["l"] += '/';
+ }
+ }
+
+ for (auto i = headers.begin(); i != headers.end(); i++) {
+ vars["h"] = *i;
+ printer->Print(vars, "#include $l$$h$$r$\n");
+ }
+}
+
+grpc::string GetHeaderPrologue(File *file, const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
+ auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
- vars["filename"] = file->name();
- vars["filename_identifier"] = FilenameIdentifier(file->name());
- vars["filename_base"] = grpc_generator::StripProto(file->name());
+ vars["filename"] = file->filename();
+ vars["filename_identifier"] = FilenameIdentifier(file->filename());
+ vars["filename_base"] = file->filename_without_ext();
- printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
- printer.Print(vars,
+ printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+ printer->Print(vars,
"// If you make any local change, they will be lost.\n");
- printer.Print(vars, "// source: $filename$\n");
- printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
- printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
- printer.Print(vars, "\n");
- printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
- printer.Print(vars, "\n");
+ printer->Print(vars, "// source: $filename$\n");
+ printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
+ printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
+ printer->Print(vars, "\n");
+ printer->Print(vars, "#include \"$filename_base$.pb.h\"\n");
+ printer->Print(vars, "\n");
}
return output;
}
-grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
+grpc::string GetHeaderIncludes(File *file,
const Parameters &params) {
- grpc::string temp =
- "#include <grpc++/impl/codegen/async_stream.h>\n"
- "#include <grpc++/impl/codegen/async_unary_call.h>\n"
- "#include <grpc++/impl/codegen/proto_utils.h>\n"
- "#include <grpc++/impl/codegen/rpc_method.h>\n"
- "#include <grpc++/impl/codegen/service_type.h>\n"
- "#include <grpc++/impl/codegen/status.h>\n"
- "#include <grpc++/impl/codegen/stub_options.h>\n"
- "#include <grpc++/impl/codegen/sync_stream.h>\n"
- "\n"
- "namespace grpc {\n"
- "class CompletionQueue;\n"
- "class RpcService;\n"
- "class ServerCompletionQueue;\n"
- "class ServerContext;\n"
- "} // namespace grpc\n\n";
+ 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;
- if (!file->package().empty()) {
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
+ static const char *headers_strs[] = {
+ "grpc++/impl/codegen/async_stream.h",
+ "grpc++/impl/codegen/async_unary_call.h",
+ "grpc++/impl/codegen/proto_utils.h",
+ "grpc++/impl/codegen/rpc_method.h",
+ "grpc++/impl/codegen/service_type.h",
+ "grpc++/impl/codegen/status.h",
+ "grpc++/impl/codegen/stub_options.h",
+ "grpc++/impl/codegen/sync_stream.h"
+ };
+ std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
+ PrintIncludes(printer.get(), headers, params);
+ printer->Print(vars, "\n");
+ printer->Print(vars, "namespace grpc {\n");
+ printer->Print(vars, "class CompletionQueue;\n");
+ printer->Print(vars, "class Channel;\n");
+ printer->Print(vars, "class RpcService;\n");
+ printer->Print(vars, "class ServerCompletionQueue;\n");
+ printer->Print(vars, "class ServerContext;\n");
+ printer->Print(vars, "} // namespace grpc\n\n");
- for (auto part = parts.begin(); part != parts.end(); part++) {
- temp.append("namespace ");
- temp.append(*part);
- temp.append(" {\n");
+ 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");
}
- temp.append("\n");
}
-
- return temp;
+ return output;
}
void PrintHeaderClientMethodInterfaces(
- grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
+ Printer *printer, const Method *method,
std::map<grpc::string, grpc::string> *vars, bool is_public) {
(*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
if (is_public) {
- if (NoStreaming(method)) {
+ if (method->NoStreaming()) {
printer->Print(
*vars,
"virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
@@ -172,7 +178,7 @@ void PrintHeaderClientMethodInterfaces(
"Async$Method$Raw(context, request, cq));\n");
printer->Outdent();
printer->Print("}\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
@@ -198,7 +204,7 @@ void PrintHeaderClientMethodInterfaces(
"Async$Method$Raw(context, response, cq, tag));\n");
printer->Outdent();
printer->Print("}\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
@@ -224,7 +230,7 @@ void PrintHeaderClientMethodInterfaces(
"Async$Method$Raw(context, request, cq, tag));\n");
printer->Outdent();
printer->Print("}\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(*vars,
"std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
"$Request$, $Response$>> "
@@ -253,14 +259,14 @@ void PrintHeaderClientMethodInterfaces(
printer->Print("}\n");
}
} else {
- if (NoStreaming(method)) {
+ if (method->NoStreaming()) {
printer->Print(
*vars,
"virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
"Async$Method$Raw(::grpc::ClientContext* context, "
"const $Request$& request, "
"::grpc::CompletionQueue* cq) = 0;\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(
*vars,
"virtual ::grpc::ClientWriterInterface< $Request$>*"
@@ -271,7 +277,7 @@ void PrintHeaderClientMethodInterfaces(
" Async$Method$Raw(::grpc::ClientContext* context, "
"$Response$* response, "
"::grpc::CompletionQueue* cq, void* tag) = 0;\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(
*vars,
"virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
@@ -282,7 +288,7 @@ void PrintHeaderClientMethodInterfaces(
"Async$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request, "
"::grpc::CompletionQueue* cq, void* tag) = 0;\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(*vars,
"virtual ::grpc::ClientReaderWriterInterface< $Request$, "
"$Response$>* "
@@ -296,17 +302,15 @@ void PrintHeaderClientMethodInterfaces(
}
}
-void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
+void PrintHeaderClientMethod(Printer *printer,
+ const Method *method,
std::map<grpc::string, grpc::string> *vars,
bool is_public) {
(*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
if (is_public) {
- if (NoStreaming(method)) {
+ if (method->NoStreaming()) {
printer->Print(
*vars,
"::grpc::Status $Method$(::grpc::ClientContext* context, "
@@ -324,7 +328,7 @@ void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
"Async$Method$Raw(context, request, cq));\n");
printer->Outdent();
printer->Print("}\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
@@ -348,7 +352,7 @@ void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
"Async$Method$Raw(context, response, cq, tag));\n");
printer->Outdent();
printer->Print("}\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientReader< $Response$>>"
@@ -374,7 +378,7 @@ void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
"Async$Method$Raw(context, request, cq, tag));\n");
printer->Outdent();
printer->Print("}\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
@@ -400,13 +404,13 @@ void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
printer->Print("}\n");
}
} else {
- if (NoStreaming(method)) {
+ if (method->NoStreaming()) {
printer->Print(*vars,
"::grpc::ClientAsyncResponseReader< $Response$>* "
"Async$Method$Raw(::grpc::ClientContext* context, "
"const $Request$& request, "
"::grpc::CompletionQueue* cq) GRPC_OVERRIDE;\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(*vars,
"::grpc::ClientWriter< $Request$>* $Method$Raw("
"::grpc::ClientContext* context, $Response$* response) "
@@ -416,7 +420,7 @@ void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
"::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
"::grpc::ClientContext* context, $Response$* response, "
"::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(*vars,
"::grpc::ClientReader< $Response$>* $Method$Raw("
"::grpc::ClientContext* context, const $Request$& request)"
@@ -426,7 +430,7 @@ void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
"::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request, "
"::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(
*vars,
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
@@ -440,38 +444,34 @@ void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
}
}
-void PrintHeaderClientMethodData(grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
+void PrintHeaderClientMethodData(Printer *printer, const Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
}
-void PrintHeaderServerMethodSync(grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
+void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
- if (NoStreaming(method)) {
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
+ if (method->NoStreaming()) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
"::grpc::ServerContext* context, const $Request$* request, "
"$Response$* response);\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerReader< $Request$>* reader, "
"$Response$* response);\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
"::grpc::ServerContext* context, const $Request$* request, "
"::grpc::ServerWriter< $Response$>* writer);\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(
*vars,
"virtual ::grpc::Status $Method$("
@@ -482,20 +482,18 @@ void PrintHeaderServerMethodSync(grpc::protobuf::io::Printer *printer,
}
void PrintHeaderServerMethodAsync(
- grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
+ Printer *printer,
+ const Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
printer->Print(*vars, "template <class BaseClass>\n");
printer->Print(*vars,
"class WithAsyncMethod_$Method$ : public BaseClass {\n");
printer->Print(
" private:\n"
- " void BaseClassMustBeDerivedFromService(Service *service) {}\n");
+ " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
printer->Print(" public:\n");
printer->Indent();
printer->Print(*vars,
@@ -506,7 +504,7 @@ void PrintHeaderServerMethodAsync(
"~WithAsyncMethod_$Method$() GRPC_OVERRIDE {\n"
" BaseClassMustBeDerivedFromService(this);\n"
"}\n");
- if (NoStreaming(method)) {
+ if (method->NoStreaming()) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@@ -527,7 +525,7 @@ void PrintHeaderServerMethodAsync(
" ::grpc::Service::RequestAsyncUnary($Idx$, context, "
"request, response, new_call_cq, notification_cq, tag);\n");
printer->Print("}\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@@ -549,7 +547,7 @@ void PrintHeaderServerMethodAsync(
" ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
"context, reader, new_call_cq, notification_cq, tag);\n");
printer->Print("}\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@@ -572,7 +570,7 @@ void PrintHeaderServerMethodAsync(
" ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
"context, request, writer, new_call_cq, notification_cq, tag);\n");
printer->Print("}\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@@ -600,20 +598,18 @@ void PrintHeaderServerMethodAsync(
}
void PrintHeaderServerMethodGeneric(
- grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
+ Printer *printer,
+ const Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
printer->Print(*vars, "template <class BaseClass>\n");
printer->Print(*vars,
"class WithGenericMethod_$Method$ : public BaseClass {\n");
printer->Print(
" private:\n"
- " void BaseClassMustBeDerivedFromService(Service *service) {}\n");
+ " void BaseClassMustBeDerivedFromService(const Service *service) {}\n");
printer->Print(" public:\n");
printer->Indent();
printer->Print(*vars,
@@ -624,7 +620,7 @@ void PrintHeaderServerMethodGeneric(
"~WithGenericMethod_$Method$() GRPC_OVERRIDE {\n"
" BaseClassMustBeDerivedFromService(this);\n"
"}\n");
- if (NoStreaming(method)) {
+ if (method->NoStreaming()) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@@ -634,7 +630,7 @@ void PrintHeaderServerMethodGeneric(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@@ -645,7 +641,7 @@ void PrintHeaderServerMethodGeneric(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@@ -656,7 +652,7 @@ void PrintHeaderServerMethodGeneric(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(
*vars,
"// disable synchronous version of this method\n"
@@ -672,8 +668,8 @@ void PrintHeaderServerMethodGeneric(
printer->Print(*vars, "};\n");
}
-void PrintHeaderService(grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::ServiceDescriptor *service,
+void PrintHeaderService(Printer *printer,
+ const Service *service,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name();
@@ -689,13 +685,13 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
printer->Indent();
printer->Print("virtual ~StubInterface() {}\n");
for (int i = 0; i < service->method_count(); ++i) {
- PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, true);
+ PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars, true);
}
printer->Outdent();
printer->Print("private:\n");
printer->Indent();
for (int i = 0; i < service->method_count(); ++i) {
- PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, false);
+ PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars, false);
}
printer->Outdent();
printer->Print("};\n");
@@ -705,17 +701,17 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
printer->Indent();
printer->Print("Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
for (int i = 0; i < service->method_count(); ++i) {
- PrintHeaderClientMethod(printer, service->method(i), vars, true);
+ PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
}
printer->Outdent();
printer->Print("\n private:\n");
printer->Indent();
printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
for (int i = 0; i < service->method_count(); ++i) {
- PrintHeaderClientMethod(printer, service->method(i), vars, false);
+ PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
}
for (int i = 0; i < service->method_count(); ++i) {
- PrintHeaderClientMethodData(printer, service->method(i), vars);
+ PrintHeaderClientMethodData(printer, service->method(i).get(), vars);
}
printer->Outdent();
printer->Print("};\n");
@@ -734,7 +730,7 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
printer->Print("Service();\n");
printer->Print("virtual ~Service();\n");
for (int i = 0; i < service->method_count(); ++i) {
- PrintHeaderServerMethodSync(printer, service->method(i), vars);
+ PrintHeaderServerMethodSync(printer, service->method(i).get(), vars);
}
printer->Outdent();
printer->Print("};\n");
@@ -742,13 +738,13 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
// Server side - Asynchronous
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["Idx"] = as_string(i);
- PrintHeaderServerMethodAsync(printer, service->method(i), vars);
+ PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars);
}
printer->Print("typedef ");
for (int i = 0; i < service->method_count(); ++i) {
- (*vars)["method_name"] = service->method(i)->name();
+ (*vars)["method_name"] = service->method(i).get()->name();
printer->Print(*vars, "WithAsyncMethod_$method_name$<");
}
printer->Print("Service");
@@ -760,20 +756,19 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
// Server side - Generic
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["Idx"] = as_string(i);
- PrintHeaderServerMethodGeneric(printer, service->method(i), vars);
+ PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
}
printer->Outdent();
printer->Print("};\n");
}
-grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
+grpc::string GetHeaderServices(File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
+ 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.
@@ -784,117 +779,112 @@ grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
if (!params.services_namespace.empty()) {
vars["services_namespace"] = params.services_namespace;
- printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
+ printer->Print(vars, "\nnamespace $services_namespace$ {\n\n");
}
for (int i = 0; i < file->service_count(); ++i) {
- PrintHeaderService(&printer, file->service(i), &vars);
- printer.Print("\n");
+ PrintHeaderService(printer.get(), file->service(i).get(), &vars);
+ printer->Print("\n");
}
if (!params.services_namespace.empty()) {
- printer.Print(vars, "} // namespace $services_namespace$\n\n");
+ printer->Print(vars, "} // namespace $services_namespace$\n\n");
}
}
return output;
}
-grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
+grpc::string GetHeaderEpilogue(File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
+ auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
- vars["filename"] = file->name();
- vars["filename_identifier"] = FilenameIdentifier(file->name());
+ vars["filename"] = file->filename();
+ vars["filename_identifier"] = FilenameIdentifier(file->filename());
if (!file->package().empty()) {
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
+ std::vector<grpc::string> parts = file->package_parts();
for (auto part = parts.rbegin(); part != parts.rend(); part++) {
vars["part"] = *part;
- printer.Print(vars, "} // namespace $part$\n");
+ printer->Print(vars, "} // namespace $part$\n");
}
- printer.Print(vars, "\n");
+ printer->Print(vars, "\n");
}
- printer.Print(vars, "\n");
- printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
+ printer->Print(vars, "\n");
+ printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
}
return output;
}
-grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
+grpc::string GetSourcePrologue(File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
+ auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
- vars["filename"] = file->name();
- vars["filename_base"] = grpc_generator::StripProto(file->name());
+ vars["filename"] = file->filename();
+ vars["filename_base"] = file->filename_without_ext();
- printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
- printer.Print(vars,
+ printer->Print(vars, "// Generated by the gRPC protobuf 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$.pb.h\"\n");
- printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
- printer.Print(vars, "\n");
+ printer->Print(vars, "// source: $filename$\n\n");
+ printer->Print(vars, "#include \"$filename_base$.pb.h\"\n");
+ printer->Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
+ printer->Print(vars, "\n");
}
return output;
}
-grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
- const Parameters &param) {
+grpc::string GetSourceIncludes(File *file,
+ const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
+ auto printer = file->CreatePrinter(&output);
std::map<grpc::string, grpc::string> vars;
- printer.Print(vars, "#include <grpc++/impl/codegen/async_stream.h>\n");
- printer.Print(vars, "#include <grpc++/impl/codegen/async_unary_call.h>\n");
- printer.Print(vars, "#include <grpc++/impl/codegen/channel_interface.h>\n");
- printer.Print(vars, "#include <grpc++/impl/codegen/client_unary_call.h>\n");
- printer.Print(vars,
- "#include <grpc++/impl/codegen/method_handler_impl.h>\n");
- printer.Print(vars,
- "#include <grpc++/impl/codegen/rpc_service_method.h>\n");
- printer.Print(vars, "#include <grpc++/impl/codegen/service_type.h>\n");
- printer.Print(vars, "#include <grpc++/impl/codegen/sync_stream.h>\n");
+ static const char *headers_strs[] = {
+ "grpc++/impl/codegen/async_stream.h",
+ "grpc++/impl/codegen/async_unary_call.h",
+ "grpc++/impl/codegen/channel_interface.h",
+ "grpc++/impl/codegen/client_unary_call.h",
+ "grpc++/impl/codegen/method_handler_impl.h",
+ "grpc++/impl/codegen/rpc_service_method.h",
+ "grpc++/impl/codegen/service_type.h",
+ "grpc++/impl/codegen/sync_stream.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 =
- grpc_generator::tokenize(file->package(), ".");
+ 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, "namespace $part$ {\n");
}
}
- printer.Print(vars, "\n");
+ printer->Print(vars, "\n");
}
return output;
}
-void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
+void PrintSourceClientMethod(Printer *printer,
+ const Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
- if (NoStreaming(method)) {
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
+ if (method->NoStreaming()) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Stub::$Method$("
"::grpc::ClientContext* context, "
@@ -917,7 +907,7 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
"rpcmethod_$Method$_, "
"context, request);\n"
"}\n\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(*vars,
"::grpc::ClientWriter< $Request$>* "
"$ns$$Service$::Stub::$Method$Raw("
@@ -939,7 +929,7 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
"rpcmethod_$Method$_, "
"context, response, tag);\n"
"}\n\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(
*vars,
"::grpc::ClientReader< $Response$>* "
@@ -962,7 +952,7 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
"rpcmethod_$Method$_, "
"context, request, tag);\n"
"}\n\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(
*vars,
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
@@ -989,15 +979,13 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
}
}
-void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
+void PrintSourceServerMethod(Printer *printer,
+ const Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
- if (NoStreaming(method)) {
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
+ if (method->NoStreaming()) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
@@ -1009,7 +997,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
printer->Print("}\n\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
@@ -1022,7 +1010,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
printer->Print("}\n\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
@@ -1035,7 +1023,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
printer->Print("}\n\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
@@ -1050,15 +1038,15 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
}
}
-void PrintSourceService(grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::ServiceDescriptor *service,
+void PrintSourceService(Printer *printer,
+ const Service *service,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name();
printer->Print(*vars,
"static const char* $prefix$$Service$_method_names[] = {\n");
for (int i = 0; i < service->method_count(); ++i) {
- (*vars)["Method"] = service->method(i)->name();
+ (*vars)["Method"] = service->method(i).get()->name();
printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
}
printer->Print(*vars, "};\n\n");
@@ -1077,14 +1065,14 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
printer->Indent();
printer->Print(": channel_(channel)");
for (int i = 0; i < service->method_count(); ++i) {
- const grpc::protobuf::MethodDescriptor *method = service->method(i);
+ auto method = service->method(i);
(*vars)["Method"] = method->name();
(*vars)["Idx"] = as_string(i);
- if (NoStreaming(method)) {
+ if (method->NoStreaming()) {
(*vars)["StreamingType"] = "NORMAL_RPC";
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
(*vars)["StreamingType"] = "CLIENT_STREAMING";
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
(*vars)["StreamingType"] = "SERVER_STREAMING";
} else {
(*vars)["StreamingType"] = "BIDI_STREAMING";
@@ -1101,21 +1089,19 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["Idx"] = as_string(i);
- PrintSourceClientMethod(printer, service->method(i), vars);
+ PrintSourceClientMethod(printer, service->method(i).get(), vars);
}
printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
printer->Indent();
printer->Print(*vars, "(void)$prefix$$Service$_method_names;\n");
for (int i = 0; i < service->method_count(); ++i) {
- const grpc::protobuf::MethodDescriptor *method = service->method(i);
+ auto method = service->method(i);
(*vars)["Idx"] = as_string(i);
(*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
- if (NoStreaming(method)) {
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
+ if (method->NoStreaming()) {
printer->Print(
*vars,
"AddMethod(new ::grpc::RpcServiceMethod(\n"
@@ -1125,7 +1111,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
"$Request$, "
"$Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
- } else if (ClientOnlyStreaming(method)) {
+ } else if (method->ClientOnlyStreaming()) {
printer->Print(
*vars,
"AddMethod(new ::grpc::RpcServiceMethod(\n"
@@ -1134,7 +1120,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
" new ::grpc::ClientStreamingHandler< "
"$ns$$Service$::Service, $Request$, $Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
- } else if (ServerOnlyStreaming(method)) {
+ } else if (method->ServerOnlyStreaming()) {
printer->Print(
*vars,
"AddMethod(new ::grpc::RpcServiceMethod(\n"
@@ -1143,7 +1129,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
" new ::grpc::ServerStreamingHandler< "
"$ns$$Service$::Service, $Request$, $Response$>(\n"
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
- } else if (BidiStreaming(method)) {
+ } else if (method->BidiStreaming()) {
printer->Print(
*vars,
"AddMethod(new ::grpc::RpcServiceMethod(\n"
@@ -1161,17 +1147,16 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
"}\n\n");
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["Idx"] = as_string(i);
- PrintSourceServerMethod(printer, service->method(i), vars);
+ PrintSourceServerMethod(printer, service->method(i).get(), vars);
}
}
-grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
+grpc::string GetSourceServices(File *file,
const Parameters &params) {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
+ 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.
@@ -1188,20 +1173,19 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
}
for (int i = 0; i < file->service_count(); ++i) {
- PrintSourceService(&printer, file->service(i), &vars);
- printer.Print("\n");
+ PrintSourceService(printer.get(), file->service(i).get(), &vars);
+ printer->Print("\n");
}
}
return output;
}
-grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
+grpc::string GetSourceEpilogue(File *file,
const Parameters &params) {
grpc::string temp;
if (!file->package().empty()) {
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
+ std::vector<grpc::string> parts = file->package_parts();
for (auto part = parts.begin(); part != parts.end(); part++) {
temp.append("} // namespace ");
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index 70c2e985f6..99a60a2eae 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -34,7 +34,23 @@
#ifndef GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
-#include "src/compiler/config.h"
+// cpp_generator.h/.cc do not directly depend on GRPC/ProtoBuf, such that they
+// can be used to generate code for other serialization systems, such as
+// FlatBuffers.
+
+#include <memory>
+#include <vector>
+
+#ifndef GRPC_CUSTOM_STRING
+#include <string>
+#define GRPC_CUSTOM_STRING std::string
+#endif
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+} // namespace grpc
namespace grpc_cpp_generator {
@@ -42,39 +58,86 @@ namespace grpc_cpp_generator {
struct Parameters {
// Puts the service into a namespace
grpc::string services_namespace;
+ // Use system includes (<>) or local includes ("")
+ bool use_system_headers;
+ // Prefix to any grpc include
+ grpc::string grpc_search_path;
+};
+
+// An abstract interface representing a method.
+struct Method {
+ virtual ~Method() {}
+
+ virtual grpc::string name() const = 0;
+
+ virtual grpc::string input_type_name() const = 0;
+ virtual grpc::string output_type_name() const = 0;
+
+ virtual bool NoStreaming() const = 0;
+ virtual bool ClientOnlyStreaming() const = 0;
+ virtual bool ServerOnlyStreaming() const = 0;
+ virtual bool BidiStreaming() const = 0;
+};
+
+// An abstract interface representing a service.
+struct Service {
+ virtual ~Service() {}
+
+ virtual grpc::string name() const = 0;
+
+ virtual int method_count() const = 0;
+ virtual std::unique_ptr<const Method> method(int i) const = 0;
+};
+
+struct Printer {
+ virtual ~Printer() {}
+
+ virtual void Print(const std::map<grpc::string, grpc::string> &vars,
+ const char *template_string) = 0;
+ virtual void Print(const char *string) = 0;
+ virtual void Indent() = 0;
+ virtual void Outdent() = 0;
+};
+
+// An interface that allows the source generated to be output using various
+// libraries/idls/serializers.
+struct File {
+ virtual ~File() {}
+
+ virtual grpc::string filename() const = 0;
+ virtual grpc::string filename_without_ext() const = 0;
+ virtual grpc::string package() const = 0;
+ virtual std::vector<grpc::string> package_parts() const = 0;
+
+ virtual int service_count() const = 0;
+ virtual std::unique_ptr<const Service> service(int i) const = 0;
+
+ virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
};
// Return the prologue of the generated header file.
-grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params);
+grpc::string GetHeaderPrologue(File *file, const Parameters &params);
// Return the includes needed for generated header file.
-grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params);
+grpc::string GetHeaderIncludes(File *file, const Parameters &params);
// Return the includes needed for generated source file.
-grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params);
+grpc::string GetSourceIncludes(File *file, const Parameters &params);
// Return the epilogue of the generated header file.
-grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params);
+grpc::string GetHeaderEpilogue(File *file, const Parameters &params);
// Return the prologue of the generated source file.
-grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params);
+grpc::string GetSourcePrologue(File *file, const Parameters &params);
// Return the services for generated header file.
-grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params);
+grpc::string GetHeaderServices(File *file, const Parameters &params);
// Return the services for generated source file.
-grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params);
+grpc::string GetSourceServices(File *file, const Parameters &params);
// Return the epilogue of the generated source file.
-grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
- const Parameters &params);
+grpc::string GetSourceEpilogue(File *file, const Parameters &params);
} // namespace grpc_cpp_generator
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index 88c704948e..f703c6453d 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -41,6 +41,105 @@
#include "src/compiler/cpp_generator.h"
#include "src/compiler/cpp_generator_helpers.h"
+class ProtoBufMethod : public grpc_cpp_generator::Method {
+ public:
+ ProtoBufMethod(const grpc::protobuf::MethodDescriptor *method)
+ : method_(method) {}
+
+ grpc::string name() const { return method_->name(); }
+
+ grpc::string input_type_name() const {
+ return grpc_cpp_generator::ClassName(method_->input_type(), true);
+ }
+ grpc::string output_type_name() const {
+ return grpc_cpp_generator::ClassName(method_->output_type(), true);
+ }
+
+ bool NoStreaming() const {
+ return !method_->client_streaming() && !method_->server_streaming();
+ }
+
+ bool ClientOnlyStreaming() const {
+ return method_->client_streaming() && !method_->server_streaming();
+ }
+
+ bool ServerOnlyStreaming() const {
+ return !method_->client_streaming() && method_->server_streaming();
+ }
+
+ bool BidiStreaming() const {
+ return method_->client_streaming() && method_->server_streaming();
+ }
+
+ private:
+ const grpc::protobuf::MethodDescriptor *method_;
+};
+
+class ProtoBufService : public grpc_cpp_generator::Service {
+ public:
+ ProtoBufService(const grpc::protobuf::ServiceDescriptor *service)
+ : service_(service) {}
+
+ grpc::string name() const { return service_->name(); }
+
+ int method_count() const { return service_->method_count(); };
+ std::unique_ptr<const grpc_cpp_generator::Method> method(int i) const {
+ return std::unique_ptr<const grpc_cpp_generator::Method>(
+ new ProtoBufMethod(service_->method(i)));
+ };
+
+ private:
+ const grpc::protobuf::ServiceDescriptor *service_;
+};
+
+class ProtoBufPrinter : public grpc_cpp_generator::Printer {
+ public:
+ ProtoBufPrinter(grpc::string *str)
+ : output_stream_(str), printer_(&output_stream_, '$') {}
+
+ void Print(const std::map<grpc::string, grpc::string> &vars,
+ const char *string_template) {
+ printer_.Print(vars, string_template);
+ }
+
+ void Print(const char *string) { printer_.Print(string); }
+ void Indent() { printer_.Indent(); }
+ void Outdent() { printer_.Outdent(); }
+
+ private:
+ grpc::protobuf::io::StringOutputStream output_stream_;
+ grpc::protobuf::io::Printer printer_;
+};
+
+class ProtoBufFile : public grpc_cpp_generator::File {
+ public:
+ ProtoBufFile(const grpc::protobuf::FileDescriptor *file) : file_(file) {}
+
+ grpc::string filename() const { return file_->name(); }
+ grpc::string filename_without_ext() const {
+ return grpc_generator::StripProto(filename());
+ }
+
+ grpc::string package() const { return file_->package(); }
+ std::vector<grpc::string> package_parts() const {
+ return grpc_generator::tokenize(package(), ".");
+ }
+
+ int service_count() const { return file_->service_count(); };
+ std::unique_ptr<const grpc_cpp_generator::Service> service(int i) const {
+ return std::unique_ptr<const grpc_cpp_generator::Service> (
+ new ProtoBufService(file_->service(i)));
+ }
+
+ std::unique_ptr<grpc_cpp_generator::Printer> CreatePrinter(grpc::string *str) const {
+ return std::unique_ptr<grpc_cpp_generator::Printer>(
+ new ProtoBufPrinter(str));
+ }
+
+ private:
+ const grpc::protobuf::FileDescriptor *file_;
+};
+
class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
public:
CppGrpcGenerator() {}
@@ -59,6 +158,9 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
}
grpc_cpp_generator::Parameters generator_parameters;
+ generator_parameters.use_system_headers = true;
+
+ ProtoBufFile pbfile(file);
if (!parameter.empty()) {
std::vector<grpc::string> parameters_list =
@@ -70,6 +172,17 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc_generator::tokenize(*parameter_string, "=");
if (param[0] == "services_namespace") {
generator_parameters.services_namespace = param[1];
+ } else if (param[0] == "use_system_headers") {
+ if (param[1] == "true") {
+ generator_parameters.use_system_headers = true;
+ } else if (param[1] == "false") {
+ generator_parameters.use_system_headers = false;
+ } else {
+ *error = grpc::string("Invalid parameter: ") + *parameter_string;
+ return false;
+ }
+ } else if (param[0] == "grpc_search_path") {
+ generator_parameters.grpc_search_path = param[1];
} else {
*error = grpc::string("Unknown parameter: ") + *parameter_string;
return false;
@@ -80,10 +193,10 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc::string file_name = grpc_generator::StripProto(file->name());
grpc::string header_code =
- grpc_cpp_generator::GetHeaderPrologue(file, generator_parameters) +
- grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters) +
- grpc_cpp_generator::GetHeaderServices(file, generator_parameters) +
- grpc_cpp_generator::GetHeaderEpilogue(file, generator_parameters);
+ grpc_cpp_generator::GetHeaderPrologue(&pbfile, generator_parameters) +
+ grpc_cpp_generator::GetHeaderIncludes(&pbfile, generator_parameters) +
+ grpc_cpp_generator::GetHeaderServices(&pbfile, generator_parameters) +
+ grpc_cpp_generator::GetHeaderEpilogue(&pbfile, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
context->Open(file_name + ".grpc.pb.h"));
grpc::protobuf::io::CodedOutputStream header_coded_out(
@@ -91,10 +204,10 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
header_coded_out.WriteRaw(header_code.data(), header_code.size());
grpc::string source_code =
- grpc_cpp_generator::GetSourcePrologue(file, generator_parameters) +
- grpc_cpp_generator::GetSourceIncludes(file, generator_parameters) +
- grpc_cpp_generator::GetSourceServices(file, generator_parameters) +
- grpc_cpp_generator::GetSourceEpilogue(file, generator_parameters);
+ grpc_cpp_generator::GetSourcePrologue(&pbfile, generator_parameters) +
+ grpc_cpp_generator::GetSourceIncludes(&pbfile, generator_parameters) +
+ grpc_cpp_generator::GetSourceServices(&pbfile, generator_parameters) +
+ grpc_cpp_generator::GetSourceEpilogue(&pbfile, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
context->Open(file_name + ".grpc.pb.cc"));
grpc::protobuf::io::CodedOutputStream source_coded_out(
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index f6079bdc05..69e2738d53 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -81,6 +81,10 @@ std::string GetServerInterfaceName(const ServiceDescriptor* service) {
return "I" + service->name();
}
+std::string GetServerClassName(const ServiceDescriptor* service) {
+ return service->name() + "Base";
+}
+
std::string GetCSharpMethodType(MethodType method_type) {
switch (method_type) {
case METHODTYPE_NO_STREAMING:
@@ -108,10 +112,14 @@ std::string GetMethodFieldName(const MethodDescriptor *method) {
return "__Method_" + method->name();
}
-std::string GetMethodRequestParamMaybe(const MethodDescriptor *method) {
+std::string GetMethodRequestParamMaybe(const MethodDescriptor *method,
+ bool invocation_param=false) {
if (method->client_streaming()) {
return "";
}
+ if (invocation_param) {
+ return "request, ";
+ }
return GetClassName(method->input_type()) + " request, ";
}
@@ -242,6 +250,8 @@ void GenerateServiceDescriptorProperty(Printer* out, const ServiceDescriptor *se
void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
out->Print("// client interface\n");
+ out->Print("[System.Obsolete(\"Client side interfaced will be removed "
+ "in the next release. Use client class directly.\")]\n");
out->Print("public interface $name$\n", "name",
GetClientInterfaceName(service));
out->Print("{\n");
@@ -290,6 +300,8 @@ void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
void GenerateServerInterface(Printer* out, const ServiceDescriptor *service) {
out->Print("// server-side interface\n");
+ out->Print("[System.Obsolete(\"Service implementations should inherit"
+ " from the generated abstract base class instead.\")]\n");
out->Print("public interface $name$\n", "name",
GetServerInterfaceName(service));
out->Print("{\n");
@@ -309,21 +321,64 @@ void GenerateServerInterface(Printer* out, const ServiceDescriptor *service) {
out->Print("\n");
}
+void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
+ out->Print("// server-side abstract class\n");
+ out->Print("public abstract class $name$\n", "name",
+ GetServerClassName(service));
+ out->Print("{\n");
+ out->Indent();
+ for (int i = 0; i < service->method_count(); i++) {
+ const MethodDescriptor *method = service->method(i);
+ out->Print(
+ "public virtual $returntype$ $methodname$($request$$response_stream_maybe$, "
+ "ServerCallContext context)\n",
+ "methodname", method->name(), "returntype",
+ GetMethodReturnTypeServer(method), "request",
+ GetMethodRequestParamServer(method), "response_stream_maybe",
+ GetMethodResponseStreamMaybe(method));
+ out->Print("{\n");
+ out->Indent();
+ out->Print("throw new RpcException("
+ "new Status(StatusCode.Unimplemented, \"\"));\n");
+ out->Outdent();
+ out->Print("}\n\n");
+ }
+ out->Outdent();
+ out->Print("}\n");
+ out->Print("\n");
+}
+
void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
out->Print("// client stub\n");
out->Print(
- "public class $name$ : ClientBase, $interface$\n",
- "name", GetClientClassName(service), "interface",
- GetClientInterfaceName(service));
+ "public class $name$ : ClientBase<$name$>, $interface$\n",
+ "name", GetClientClassName(service),
+ "interface", GetClientInterfaceName(service));
out->Print("{\n");
out->Indent();
// constructors
- out->Print(
- "public $name$(Channel channel) : base(channel)\n",
- "name", GetClientClassName(service));
+ out->Print("public $name$(Channel channel) : base(channel)\n",
+ "name", GetClientClassName(service));
+ out->Print("{\n");
+ out->Print("}\n");
+ out->Print("public $name$(CallInvoker callInvoker) : base(callInvoker)\n",
+ "name", GetClientClassName(service));
out->Print("{\n");
out->Print("}\n");
+ out->Print("///<summary>Protected parameterless constructor to allow creation"
+ " of test doubles.</summary>\n");
+ out->Print("protected $name$() : base()\n",
+ "name", GetClientClassName(service));
+ out->Print("{\n");
+ out->Print("}\n");
+ out->Print("///<summary>Protected constructor to allow creation of configured"
+ " clients.</summary>\n");
+ out->Print("protected $name$(ClientBaseConfiguration configuration)"
+ " : base(configuration)\n",
+ "name", GetClientClassName(service));
+ out->Print("{\n");
+ out->Print("}\n\n");
for (int i = 0; i < service->method_count(); i++) {
const MethodDescriptor *method = service->method(i);
@@ -331,30 +386,26 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
if (method_type == METHODTYPE_NO_STREAMING) {
// unary calls have an extra synchronous stub method
- out->Print(
- "public $response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
+ out->Print("public virtual $response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
"methodname", method->name(), "request",
GetClassName(method->input_type()), "response",
GetClassName(method->output_type()));
out->Print("{\n");
out->Indent();
- out->Print("var call = CreateCall($methodfield$, new CallOptions(headers, deadline, cancellationToken));\n",
- "methodfield", GetMethodFieldName(method));
- out->Print("return Calls.BlockingUnaryCall(call, request);\n");
+ out->Print("return $methodname$(request, new CallOptions(headers, deadline, cancellationToken));\n",
+ "methodname", method->name());
out->Outdent();
out->Print("}\n");
// overload taking CallOptions as a param
- out->Print(
- "public $response$ $methodname$($request$ request, CallOptions options)\n",
- "methodname", method->name(), "request",
- GetClassName(method->input_type()), "response",
- GetClassName(method->output_type()));
+ out->Print("public virtual $response$ $methodname$($request$ request, CallOptions options)\n",
+ "methodname", method->name(), "request",
+ GetClassName(method->input_type()), "response",
+ GetClassName(method->output_type()));
out->Print("{\n");
out->Indent();
- out->Print("var call = CreateCall($methodfield$, options);\n",
+ out->Print("return CallInvoker.BlockingUnaryCall($methodfield$, null, options, request);\n",
"methodfield", GetMethodFieldName(method));
- out->Print("return Calls.BlockingUnaryCall(call, request);\n");
out->Outdent();
out->Print("}\n");
}
@@ -364,57 +415,44 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
method_name += "Async"; // prevent name clash with synchronous method.
}
out->Print(
- "public $returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
- "methodname", method_name, "request_maybe",
- GetMethodRequestParamMaybe(method), "returntype",
- GetMethodReturnTypeClient(method));
+ "public virtual $returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
+ "methodname", method_name, "request_maybe",
+ GetMethodRequestParamMaybe(method), "returntype",
+ GetMethodReturnTypeClient(method));
out->Print("{\n");
out->Indent();
- out->Print("var call = CreateCall($methodfield$, new CallOptions(headers, deadline, cancellationToken));\n",
- "methodfield", GetMethodFieldName(method));
- switch (GetMethodType(method)) {
- case METHODTYPE_NO_STREAMING:
- out->Print("return Calls.AsyncUnaryCall(call, request);\n");
- break;
- case METHODTYPE_CLIENT_STREAMING:
- out->Print("return Calls.AsyncClientStreamingCall(call);\n");
- break;
- case METHODTYPE_SERVER_STREAMING:
- out->Print(
- "return Calls.AsyncServerStreamingCall(call, request);\n");
- break;
- case METHODTYPE_BIDI_STREAMING:
- out->Print("return Calls.AsyncDuplexStreamingCall(call);\n");
- break;
- default:
- GOOGLE_LOG(FATAL)<< "Can't get here.";
- }
+
+ out->Print("return $methodname$($request_maybe$new CallOptions(headers, deadline, cancellationToken));\n",
+ "methodname", method_name,
+ "request_maybe", GetMethodRequestParamMaybe(method, true));
out->Outdent();
out->Print("}\n");
// overload taking CallOptions as a param
out->Print(
- "public $returntype$ $methodname$($request_maybe$CallOptions options)\n",
+ "public virtual $returntype$ $methodname$($request_maybe$CallOptions options)\n",
"methodname", method_name, "request_maybe",
GetMethodRequestParamMaybe(method), "returntype",
GetMethodReturnTypeClient(method));
out->Print("{\n");
out->Indent();
- out->Print("var call = CreateCall($methodfield$, options);\n",
- "methodfield", GetMethodFieldName(method));
switch (GetMethodType(method)) {
case METHODTYPE_NO_STREAMING:
- out->Print("return Calls.AsyncUnaryCall(call, request);\n");
+ out->Print("return CallInvoker.AsyncUnaryCall($methodfield$, null, options, request);\n",
+ "methodfield", GetMethodFieldName(method));
break;
case METHODTYPE_CLIENT_STREAMING:
- out->Print("return Calls.AsyncClientStreamingCall(call);\n");
+ out->Print("return CallInvoker.AsyncClientStreamingCall($methodfield$, null, options);\n",
+ "methodfield", GetMethodFieldName(method));
break;
case METHODTYPE_SERVER_STREAMING:
out->Print(
- "return Calls.AsyncServerStreamingCall(call, request);\n");
+ "return CallInvoker.AsyncServerStreamingCall($methodfield$, null, options, request);\n",
+ "methodfield", GetMethodFieldName(method));
break;
case METHODTYPE_BIDI_STREAMING:
- out->Print("return Calls.AsyncDuplexStreamingCall(call);\n");
+ out->Print("return CallInvoker.AsyncDuplexStreamingCall($methodfield$, null, options);\n",
+ "methodfield", GetMethodFieldName(method));
break;
default:
GOOGLE_LOG(FATAL)<< "Can't get here.";
@@ -422,17 +460,30 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
out->Outdent();
out->Print("}\n");
}
+
+ // override NewInstance method
+ out->Print("protected override $name$ NewInstance(ClientBaseConfiguration configuration)\n",
+ "name", GetClientClassName(service));
+ out->Print("{\n");
+ out->Indent();
+ out->Print("return new $name$(configuration);\n",
+ "name", GetClientClassName(service));
+ out->Outdent();
+ out->Print("}\n");
+
out->Outdent();
out->Print("}\n");
out->Print("\n");
}
-void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service) {
+void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service,
+ bool use_server_class) {
out->Print(
"// creates service definition that can be registered with a server\n");
out->Print(
"public static ServerServiceDefinition BindService($interface$ serviceImpl)\n",
- "interface", GetServerInterfaceName(service));
+ "interface", use_server_class ? GetServerClassName(service) :
+ GetServerInterfaceName(service));
out->Print("{\n");
out->Indent();
@@ -489,8 +540,10 @@ void GenerateService(Printer* out, const ServiceDescriptor *service) {
GenerateServiceDescriptorProperty(out, service);
GenerateClientInterface(out, service);
GenerateServerInterface(out, service);
+ GenerateServerClass(out, service);
GenerateClientStub(out, service);
- GenerateBindServiceMethod(out, service);
+ GenerateBindServiceMethod(out, service, false);
+ GenerateBindServiceMethod(out, service, true);
GenerateNewStubMethods(out, service);
out->Outdent();
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index 4fd5dfbecb..02c032800b 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -190,11 +190,10 @@ bool PrintBetaServicer(const ServiceDescriptor* service,
"Documentation", doc,
});
out->Print("\n");
- out->Print(dict, "class Beta$Service$Servicer(object):\n");
+ out->Print(dict, "class Beta$Service$Servicer(six.with_metaclass(abc.ABCMeta, object)):\n");
{
IndentScope raii_class_indent(out);
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
- out->Print("__metaclass__ = abc.ABCMeta\n");
for (int i = 0; i < service->method_count(); ++i) {
auto meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ?
@@ -219,11 +218,10 @@ bool PrintBetaStub(const ServiceDescriptor* service,
"Documentation", doc,
});
out->Print("\n");
- out->Print(dict, "class Beta$Service$Stub(object):\n");
+ out->Print(dict, "class Beta$Service$Stub(six.with_metaclass(abc.ABCMeta, object)):\n");
{
IndentScope raii_class_indent(out);
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
- out->Print("__metaclass__ = abc.ABCMeta\n");
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ?
@@ -449,6 +447,7 @@ bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
bool PrintPreamble(const FileDescriptor* file,
const GeneratorConfiguration& config, Printer* out) {
out->Print("import abc\n");
+ out->Print("import six\n");
out->Print("from $Package$ import implementations as beta_implementations\n",
"Package", config.beta_package_root);
out->Print("from grpc.framework.common import cardinality\n");
diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h
index 68da18f9ba..e56b6790ef 100644
--- a/src/compiler/python_generator.h
+++ b/src/compiler/python_generator.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc
index d781ddbee5..92a07b2f80 100644
--- a/src/compiler/python_plugin.cc
+++ b/src/compiler/python_plugin.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index 299137519f..5ac56ad289 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -55,11 +55,11 @@ namespace {
// Prints out the method using the ruby gRPC DSL.
void PrintMethod(const MethodDescriptor *method, const grpc::string &package,
Printer *out) {
- grpc::string input_type = RubyTypeOf(method->input_type()->name(), package);
+ grpc::string input_type = RubyTypeOf(method->input_type()->full_name(), package);
if (method->client_streaming()) {
input_type = "stream(" + input_type + ")";
}
- grpc::string output_type = RubyTypeOf(method->output_type()->name(), package);
+ grpc::string output_type = RubyTypeOf(method->output_type()->full_name(), package);
if (method->server_streaming()) {
output_type = "stream(" + output_type + ")";
}
diff --git a/src/compiler/ruby_generator_string-inl.h b/src/compiler/ruby_generator_string-inl.h
index 8da3a88da2..d1ad871c1a 100644
--- a/src/compiler/ruby_generator_string-inl.h
+++ b/src/compiler/ruby_generator_string-inl.h
@@ -115,6 +115,7 @@ inline grpc::string RubyTypeOf(const grpc::string &a_type,
return res;
} else {
std::vector<grpc::string> prefixes_and_type = Split(res, '.');
+ res.clear();
for (unsigned int i = 0; i < prefixes_and_type.size(); ++i) {
if (i != 0) {
res += "::"; // switch '.' to the ruby module delim