diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/csharp_generator.cc | 62 | ||||
-rw-r--r-- | src/compiler/csharp_generator.h | 2 | ||||
-rw-r--r-- | src/compiler/python_generator.cc | 314 | ||||
-rw-r--r-- | src/compiler/python_generator.h | 3 | ||||
-rw-r--r-- | src/compiler/python_plugin.cc | 3 |
5 files changed, 321 insertions, 63 deletions
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 9432bdda96..7b497df7f4 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -33,12 +33,18 @@ #include <cctype> #include <map> +#include <sstream> #include <vector> +#include "src/compiler/csharp_generator.h" #include "src/compiler/config.h" #include "src/compiler/csharp_generator_helpers.h" #include "src/compiler/csharp_generator.h" + +using google::protobuf::compiler::csharp::GetFileNamespace; +using google::protobuf::compiler::csharp::GetClassName; +using google::protobuf::compiler::csharp::GetUmbrellaClassName; using grpc::protobuf::FileDescriptor; using grpc::protobuf::Descriptor; using grpc::protobuf::ServiceDescriptor; @@ -55,47 +61,10 @@ using grpc_generator::StringReplace; using std::map; using std::vector; + namespace grpc_csharp_generator { namespace { -// TODO(jtattermusch): make GetFileNamespace part of libprotoc public API. -// NOTE: Implementation needs to match exactly to GetFileNamespace -// defined in csharp_helpers.h in protoc csharp plugin. -// We cannot reference it directly because google3 protobufs -// don't have a csharp protoc plugin. -std::string GetFileNamespace(const FileDescriptor* file) { - if (file->options().has_csharp_namespace()) { - return file->options().csharp_namespace(); - } - return file->package(); -} - -std::string ToCSharpName(const std::string& name, const FileDescriptor* file) { - std::string result = GetFileNamespace(file); - if (result != "") { - result += '.'; - } - std::string classname; - if (file->package().empty()) { - classname = name; - } else { - // Strip the proto package from full_name since we've replaced it with - // the C# namespace. - classname = name.substr(file->package().size() + 1); - } - result += StringReplace(classname, ".", ".Types.", false); - return "global::" + result; -} - -// TODO(jtattermusch): make GetClassName part of libprotoc public API. -// NOTE: Implementation needs to match exactly to GetClassName -// defined in csharp_helpers.h in protoc csharp plugin. -// We cannot reference it directly because google3 protobufs -// don't have a csharp protoc plugin. -std::string GetClassName(const Descriptor* message) { - return ToCSharpName(message->full_name(), message->file()); -} - std::string GetServiceClassName(const ServiceDescriptor* service) { return service->name(); } @@ -229,7 +198,7 @@ void GenerateMarshallerFields(Printer* out, const ServiceDescriptor *service) { for (size_t i = 0; i < used_messages.size(); i++) { const Descriptor *message = used_messages[i]; out->Print( - "static readonly Marshaller<$type$> $fieldname$ = Marshallers.Create((arg) => arg.ToByteArray(), $type$.ParseFrom);\n", + "static readonly Marshaller<$type$> $fieldname$ = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), $type$.Parser.ParseFrom);\n", "fieldname", GetMarshallerFieldName(message), "type", GetClassName(message)); } @@ -258,6 +227,19 @@ void GenerateStaticMethodField(Printer* out, const MethodDescriptor *method) { out->Outdent(); } +void GenerateServiceDescriptorProperty(Printer* out, const ServiceDescriptor *service) { + std::ostringstream index; + index << service->index(); + out->Print("// service descriptor\n"); + out->Print("public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor\n"); + out->Print("{\n"); + out->Print(" get { return $umbrella$.Descriptor.Services[$index$]; }\n", + "umbrella", GetUmbrellaClassName(service->file()), "index", + index.str()); + out->Print("}\n"); + out->Print("\n"); +} + void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) { out->Print("// client interface\n"); out->Print("public interface $name$\n", "name", @@ -504,6 +486,7 @@ void GenerateService(Printer* out, const ServiceDescriptor *service) { for (int i = 0; i < service->method_count(); i++) { GenerateStaticMethodField(out, service->method(i)); } + GenerateServiceDescriptorProperty(out, service); GenerateClientInterface(out, service); GenerateServerInterface(out, service); GenerateClientStub(out, service); @@ -539,7 +522,6 @@ grpc::string GetServices(const FileDescriptor *file) { out.Print("using System.Threading;\n"); out.Print("using System.Threading.Tasks;\n"); out.Print("using Grpc.Core;\n"); - // TODO(jtattermusch): add using for protobuf message classes out.Print("\n"); out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file)); diff --git a/src/compiler/csharp_generator.h b/src/compiler/csharp_generator.h index ec537d3f1d..90eb7e2984 100644 --- a/src/compiler/csharp_generator.h +++ b/src/compiler/csharp_generator.h @@ -36,6 +36,8 @@ #include "src/compiler/config.h" +#include <google/protobuf/compiler/csharp/csharp_names.h> + namespace grpc_csharp_generator { grpc::string GetServices(const grpc::protobuf::FileDescriptor *file); diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index 72c457ac6b..83133f2b6e 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -148,8 +148,8 @@ class IndentScope { // END FORMATTING BOILERPLATE // //////////////////////////////// -bool PrintServicer(const ServiceDescriptor* service, - Printer* out) { +bool PrintAlphaServicer(const ServiceDescriptor* service, + Printer* out) { grpc::string doc = "<fill me in later!>"; map<grpc::string, grpc::string> dict = ListToDict({ "Service", service->name(), @@ -176,7 +176,7 @@ bool PrintServicer(const ServiceDescriptor* service, return true; } -bool PrintServer(const ServiceDescriptor* service, Printer* out) { +bool PrintAlphaServer(const ServiceDescriptor* service, Printer* out) { grpc::string doc = "<fill me in later!>"; map<grpc::string, grpc::string> dict = ListToDict({ "Service", service->name(), @@ -204,8 +204,8 @@ bool PrintServer(const ServiceDescriptor* service, Printer* out) { return true; } -bool PrintStub(const ServiceDescriptor* service, - Printer* out) { +bool PrintAlphaStub(const ServiceDescriptor* service, + Printer* out) { grpc::string doc = "<fill me in later!>"; map<grpc::string, grpc::string> dict = ListToDict({ "Service", service->name(), @@ -268,8 +268,8 @@ bool GetModuleAndMessagePath(const Descriptor* type, return true; } -bool PrintServerFactory(const grpc::string& package_qualified_service_name, - const ServiceDescriptor* service, Printer* out) { +bool PrintAlphaServerFactory(const grpc::string& package_qualified_service_name, + const ServiceDescriptor* service, Printer* out) { out->Print("def early_adopter_create_$Service$_server(servicer, port, " "private_key=None, certificate_chain=None):\n", "Service", service->name()); @@ -320,7 +320,7 @@ bool PrintServerFactory(const grpc::string& package_qualified_service_name, input_message_modules_and_classes.find(method_name); auto output_message_module_and_class = output_message_modules_and_classes.find(method_name); - out->Print("\"$Method$\": utilities.$Constructor$(\n", "Method", + out->Print("\"$Method$\": alpha_utilities.$Constructor$(\n", "Method", method_name, "Constructor", name_and_description_constructor->second); { @@ -339,7 +339,7 @@ bool PrintServerFactory(const grpc::string& package_qualified_service_name, } out->Print("}\n"); out->Print( - "return implementations.server(" + "return early_adopter_implementations.server(" "\"$PackageQualifiedServiceName$\"," " method_service_descriptions, port, private_key=private_key," " certificate_chain=certificate_chain)\n", @@ -348,8 +348,8 @@ bool PrintServerFactory(const grpc::string& package_qualified_service_name, return true; } -bool PrintStubFactory(const grpc::string& package_qualified_service_name, - const ServiceDescriptor* service, Printer* out) { +bool PrintAlphaStubFactory(const grpc::string& package_qualified_service_name, + const ServiceDescriptor* service, Printer* out) { map<grpc::string, grpc::string> dict = ListToDict({ "Service", service->name(), }); @@ -404,7 +404,7 @@ bool PrintStubFactory(const grpc::string& package_qualified_service_name, input_message_modules_and_classes.find(method_name); auto output_message_module_and_class = output_message_modules_and_classes.find(method_name); - out->Print("\"$Method$\": utilities.$Constructor$(\n", "Method", + out->Print("\"$Method$\": alpha_utilities.$Constructor$(\n", "Method", method_name, "Constructor", name_and_description_constructor->second); { @@ -422,7 +422,7 @@ bool PrintStubFactory(const grpc::string& package_qualified_service_name, } out->Print("}\n"); out->Print( - "return implementations.stub(" + "return early_adopter_implementations.stub(" "\"$PackageQualifiedServiceName$\"," " method_invocation_descriptions, host, port," " metadata_transformer=metadata_transformer, secure=secure," @@ -434,12 +434,280 @@ bool PrintStubFactory(const grpc::string& package_qualified_service_name, return true; } +bool PrintBetaServicer(const ServiceDescriptor* service, + Printer* out) { + grpc::string doc = "<fill me in later!>"; + map<grpc::string, grpc::string> dict = ListToDict({ + "Service", service->name(), + "Documentation", doc, + }); + out->Print("\n"); + out->Print(dict, "class Beta$Service$Servicer(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() ? + "request_iterator" : "request"; + out->Print("@abc.abstractmethod\n"); + out->Print("def $Method$(self, $ArgName$, context):\n", + "Method", meth->name(), "ArgName", arg_name); + { + IndentScope raii_method_indent(out); + out->Print("raise NotImplementedError()\n"); + } + } + } + return true; +} + +bool PrintBetaStub(const ServiceDescriptor* service, + Printer* out) { + grpc::string doc = "The interface to which stubs will conform."; + map<grpc::string, grpc::string> dict = ListToDict({ + "Service", service->name(), + "Documentation", doc, + }); + out->Print("\n"); + out->Print(dict, "class Beta$Service$Stub(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() ? + "request_iterator" : "request"; + auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name}); + out->Print("@abc.abstractmethod\n"); + out->Print(methdict, "def $Method$(self, $ArgName$, timeout):\n"); + { + IndentScope raii_method_indent(out); + out->Print("raise NotImplementedError()\n"); + } + if (!meth->server_streaming()) { + out->Print(methdict, "$Method$.future = None\n"); + } + } + } + return true; +} + +bool PrintBetaServerFactory(const grpc::string& package_qualified_service_name, + const ServiceDescriptor* service, Printer* out) { + out->Print("\n"); + out->Print("def beta_create_$Service$_server(servicer, pool=None, " + "pool_size=None, default_timeout=None, maximum_timeout=None):\n", + "Service", service->name()); + { + IndentScope raii_create_server_indent(out); + map<grpc::string, grpc::string> method_implementation_constructors; + map<grpc::string, pair<grpc::string, grpc::string>> + input_message_modules_and_classes; + map<grpc::string, pair<grpc::string, grpc::string>> + output_message_modules_and_classes; + for (int i = 0; i < service->method_count(); ++i) { + const MethodDescriptor* method = service->method(i); + const grpc::string method_implementation_constructor = + grpc::string(method->client_streaming() ? "stream_" : "unary_") + + grpc::string(method->server_streaming() ? "stream_" : "unary_") + + "inline"; + pair<grpc::string, grpc::string> input_message_module_and_class; + if (!GetModuleAndMessagePath(method->input_type(), + &input_message_module_and_class)) { + return false; + } + pair<grpc::string, grpc::string> output_message_module_and_class; + if (!GetModuleAndMessagePath(method->output_type(), + &output_message_module_and_class)) { + return false; + } + // Import the modules that define the messages used in RPCs. + out->Print("import $Module$\n", "Module", + input_message_module_and_class.first); + out->Print("import $Module$\n", "Module", + output_message_module_and_class.first); + method_implementation_constructors.insert( + make_pair(method->name(), method_implementation_constructor)); + input_message_modules_and_classes.insert( + make_pair(method->name(), input_message_module_and_class)); + output_message_modules_and_classes.insert( + make_pair(method->name(), output_message_module_and_class)); + } + out->Print("request_deserializers = {\n"); + for (auto name_and_input_module_class_pair = + input_message_modules_and_classes.begin(); + name_and_input_module_class_pair != + input_message_modules_and_classes.end(); + name_and_input_module_class_pair++) { + IndentScope raii_indent(out); + out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): " + "$InputTypeModule$.$InputTypeClass$.FromString,\n", + "PackageQualifiedServiceName", package_qualified_service_name, + "MethodName", name_and_input_module_class_pair->first, + "InputTypeModule", + name_and_input_module_class_pair->second.first, + "InputTypeClass", + name_and_input_module_class_pair->second.second); + } + out->Print("}\n"); + out->Print("response_serializers = {\n"); + for (auto name_and_output_module_class_pair = + output_message_modules_and_classes.begin(); + name_and_output_module_class_pair != + output_message_modules_and_classes.end(); + name_and_output_module_class_pair++) { + IndentScope raii_indent(out); + out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): " + "$OutputTypeModule$.$OutputTypeClass$.SerializeToString,\n", + "PackageQualifiedServiceName", package_qualified_service_name, + "MethodName", name_and_output_module_class_pair->first, + "OutputTypeModule", + name_and_output_module_class_pair->second.first, + "OutputTypeClass", + name_and_output_module_class_pair->second.second); + } + out->Print("}\n"); + out->Print("method_implementations = {\n"); + for (auto name_and_implementation_constructor = + method_implementation_constructors.begin(); + name_and_implementation_constructor != + method_implementation_constructors.end(); + name_and_implementation_constructor++) { + IndentScope raii_descriptions_indent(out); + const grpc::string method_name = + name_and_implementation_constructor->first; + out->Print("(\'$PackageQualifiedServiceName$\', \'$Method$\'): " + "face_utilities.$Constructor$(servicer.$Method$),\n", + "PackageQualifiedServiceName", package_qualified_service_name, + "Method", name_and_implementation_constructor->first, + "Constructor", name_and_implementation_constructor->second); + } + out->Print("}\n"); + out->Print("server_options = beta_implementations.server_options(" + "request_deserializers=request_deserializers, " + "response_serializers=response_serializers, " + "thread_pool=pool, thread_pool_size=pool_size, " + "default_timeout=default_timeout, " + "maximum_timeout=maximum_timeout)\n"); + out->Print("return beta_implementations.server(method_implementations, " + "options=server_options)\n"); + } + return true; +} + +bool PrintBetaStubFactory(const grpc::string& package_qualified_service_name, + const ServiceDescriptor* service, Printer* out) { + map<grpc::string, grpc::string> dict = ListToDict({ + "Service", service->name(), + }); + out->Print("\n"); + out->Print(dict, "def beta_create_$Service$_stub(channel, host=None," + " metadata_transformer=None, pool=None, pool_size=None):\n"); + { + IndentScope raii_create_server_indent(out); + map<grpc::string, grpc::string> method_cardinalities; + map<grpc::string, pair<grpc::string, grpc::string>> + input_message_modules_and_classes; + map<grpc::string, pair<grpc::string, grpc::string>> + output_message_modules_and_classes; + for (int i = 0; i < service->method_count(); ++i) { + const MethodDescriptor* method = service->method(i); + const grpc::string method_cardinality = + grpc::string(method->client_streaming() ? "STREAM" : "UNARY") + + "_" + + grpc::string(method->server_streaming() ? "STREAM" : "UNARY"); + pair<grpc::string, grpc::string> input_message_module_and_class; + if (!GetModuleAndMessagePath(method->input_type(), + &input_message_module_and_class)) { + return false; + } + pair<grpc::string, grpc::string> output_message_module_and_class; + if (!GetModuleAndMessagePath(method->output_type(), + &output_message_module_and_class)) { + return false; + } + // Import the modules that define the messages used in RPCs. + out->Print("import $Module$\n", "Module", + input_message_module_and_class.first); + out->Print("import $Module$\n", "Module", + output_message_module_and_class.first); + method_cardinalities.insert( + make_pair(method->name(), method_cardinality)); + input_message_modules_and_classes.insert( + make_pair(method->name(), input_message_module_and_class)); + output_message_modules_and_classes.insert( + make_pair(method->name(), output_message_module_and_class)); + } + out->Print("request_serializers = {\n"); + for (auto name_and_input_module_class_pair = + input_message_modules_and_classes.begin(); + name_and_input_module_class_pair != + input_message_modules_and_classes.end(); + name_and_input_module_class_pair++) { + IndentScope raii_indent(out); + out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): " + "$InputTypeModule$.$InputTypeClass$.SerializeToString,\n", + "PackageQualifiedServiceName", package_qualified_service_name, + "MethodName", name_and_input_module_class_pair->first, + "InputTypeModule", + name_and_input_module_class_pair->second.first, + "InputTypeClass", + name_and_input_module_class_pair->second.second); + } + out->Print("}\n"); + out->Print("response_deserializers = {\n"); + for (auto name_and_output_module_class_pair = + output_message_modules_and_classes.begin(); + name_and_output_module_class_pair != + output_message_modules_and_classes.end(); + name_and_output_module_class_pair++) { + IndentScope raii_indent(out); + out->Print("(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): " + "$OutputTypeModule$.$OutputTypeClass$.FromString,\n", + "PackageQualifiedServiceName", package_qualified_service_name, + "MethodName", name_and_output_module_class_pair->first, + "OutputTypeModule", + name_and_output_module_class_pair->second.first, + "OutputTypeClass", + name_and_output_module_class_pair->second.second); + } + out->Print("}\n"); + out->Print("cardinalities = {\n"); + for (auto name_and_cardinality = method_cardinalities.begin(); + name_and_cardinality != method_cardinalities.end(); + name_and_cardinality++) { + IndentScope raii_descriptions_indent(out); + out->Print("\'$Method$\': cardinality.Cardinality.$Cardinality$,\n", + "Method", name_and_cardinality->first, + "Cardinality", name_and_cardinality->second); + } + out->Print("}\n"); + out->Print("stub_options = beta_implementations.stub_options(" + "host=host, metadata_transformer=metadata_transformer, " + "request_serializers=request_serializers, " + "response_deserializers=response_deserializers, " + "thread_pool=pool, thread_pool_size=pool_size)\n"); + out->Print( + "return beta_implementations.dynamic_stub(channel, \'$PackageQualifiedServiceName$\', " + "cardinalities, options=stub_options)\n", + "PackageQualifiedServiceName", package_qualified_service_name); + } + return true; +} + bool PrintPreamble(const FileDescriptor* file, const GeneratorConfiguration& config, Printer* out) { out->Print("import abc\n"); - out->Print("from $Package$ import implementations\n", - "Package", config.implementations_package_root); - out->Print("from grpc.framework.alpha import utilities\n"); + out->Print("from $Package$ import implementations as beta_implementations\n", + "Package", config.beta_package_root); + out->Print("from $Package$ import implementations as early_adopter_implementations\n", + "Package", config.early_adopter_package_root); + out->Print("from grpc.framework.alpha import utilities as alpha_utilities\n"); + out->Print("from grpc.framework.common import cardinality\n"); + out->Print("from grpc.framework.interfaces.face import utilities as face_utilities\n"); return true; } @@ -462,11 +730,15 @@ pair<bool, grpc::string> GetServices(const FileDescriptor* file, for (int i = 0; i < file->service_count(); ++i) { auto service = file->service(i); auto package_qualified_service_name = package + service->name(); - if (!(PrintServicer(service, &out) && - PrintServer(service, &out) && - PrintStub(service, &out) && - PrintServerFactory(package_qualified_service_name, service, &out) && - PrintStubFactory(package_qualified_service_name, service, &out))) { + if (!(PrintAlphaServicer(service, &out) && + PrintAlphaServer(service, &out) && + PrintAlphaStub(service, &out) && + PrintAlphaServerFactory(package_qualified_service_name, service, &out) && + PrintAlphaStubFactory(package_qualified_service_name, service, &out) && + PrintBetaServicer(service, &out) && + PrintBetaStub(service, &out) && + PrintBetaServerFactory(package_qualified_service_name, service, &out) && + PrintBetaStubFactory(package_qualified_service_name, service, &out))) { return make_pair(false, ""); } } diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h index b47f3c1243..44ed4b3f98 100644 --- a/src/compiler/python_generator.h +++ b/src/compiler/python_generator.h @@ -43,7 +43,8 @@ namespace grpc_python_generator { // Data pertaining to configuration of the generator with respect to anything // that may be used internally at Google. struct GeneratorConfiguration { - grpc::string implementations_package_root; + grpc::string early_adopter_package_root; + grpc::string beta_package_root; }; class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc index d1f49442da..c7cef54900 100644 --- a/src/compiler/python_plugin.cc +++ b/src/compiler/python_plugin.cc @@ -38,7 +38,8 @@ int main(int argc, char* argv[]) { grpc_python_generator::GeneratorConfiguration config; - config.implementations_package_root = "grpc.early_adopter"; + config.early_adopter_package_root = "grpc.early_adopter"; + config.beta_package_root = "grpc.beta"; grpc_python_generator::PythonGrpcGenerator generator(config); return grpc::protobuf::compiler::PluginMain(argc, argv, &generator); } |