From 3bb52151dd4ca829ae827517af3a0fd44e9b0bfb Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Tue, 17 Mar 2015 21:52:52 -0700 Subject: Make Python package spec indirect This is part of a change to ease internal usage of GRPC. --- src/compiler/python_generator.cc | 69 ++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 9 deletions(-) (limited to 'src/compiler/python_generator.cc') diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index e4f85450f5..1ec3772f9f 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -36,13 +36,18 @@ #include #include #include +#include #include #include +#include +#include #include #include "src/compiler/generator_helpers.h" #include "src/compiler/python_generator.h" +#include #include +#include #include #include #include @@ -53,8 +58,11 @@ using google::protobuf::Descriptor; using google::protobuf::FileDescriptor; using google::protobuf::MethodDescriptor; using google::protobuf::ServiceDescriptor; +using google::protobuf::compiler::GeneratorContext; +using google::protobuf::io::CodedOutputStream; using google::protobuf::io::Printer; using google::protobuf::io::StringOutputStream; +using google::protobuf::io::ZeroCopyOutputStream; using std::initializer_list; using std::make_pair; using std::map; @@ -63,6 +71,41 @@ using std::replace; using std::vector; namespace grpc_python_generator { + +PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config) + : config_(config) {} + +PythonGrpcGenerator::~PythonGrpcGenerator() {} + +bool PythonGrpcGenerator::Generate( + const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const { + // Get output file name. + std::string file_name; + static const int proto_suffix_length = strlen(".proto"); + if (file->name().size() > static_cast(proto_suffix_length) && + file->name().find_last_of(".proto") == file->name().size() - 1) { + file_name = file->name().substr( + 0, file->name().size() - proto_suffix_length) + "_pb2.py"; + } else { + *error = "Invalid proto file name. Proto file must end with .proto"; + return false; + } + + std::unique_ptr output( + context->OpenForInsert(file_name, "module_scope")); + CodedOutputStream coded_out(output.get()); + bool success = false; + std::string code = ""; + tie(success, code) = grpc_python_generator::GetServices(file, config_); + if (success) { + coded_out.WriteRaw(code.data(), code.size()); + return true; + } else { + return false; + } +} + namespace { ////////////////////////////////// // BEGIN FORMATTING BOILERPLATE // @@ -70,7 +113,8 @@ namespace { // Converts an initializer list of the form { key0, value0, key1, value1, ... } // into a map of key* to value*. Is merely a readability helper for later code. -map ListToDict(const initializer_list& values) { +map ListToDict( + const initializer_list& values) { assert(values.size() % 2 == 0); map value_map; auto value_iter = values.begin(); @@ -237,8 +281,10 @@ bool PrintServerFactory(const std::string& package_qualified_service_name, { IndentScope raii_create_server_indent(out); map method_description_constructors; - map> input_message_modules_and_classes; - map> output_message_modules_and_classes; + map> + input_message_modules_and_classes; + map> + output_message_modules_and_classes; for (int i = 0; i < service->method_count(); ++i) { const MethodDescriptor* method = service->method(i); const std::string method_description_constructor = @@ -313,8 +359,10 @@ bool PrintStubFactory(const std::string& package_qualified_service_name, { IndentScope raii_create_server_indent(out); map method_description_constructors; - map> input_message_modules_and_classes; - map> output_message_modules_and_classes; + map> + input_message_modules_and_classes; + map> + output_message_modules_and_classes; for (int i = 0; i < service->method_count(); ++i) { const MethodDescriptor* method = service->method(i); const std::string method_description_constructor = @@ -378,22 +426,25 @@ bool PrintStubFactory(const std::string& package_qualified_service_name, return true; } -bool PrintPreamble(const FileDescriptor* file, Printer* out) { +bool PrintPreamble(const FileDescriptor* file, + const GeneratorConfiguration& config, Printer* out) { out->Print("import abc\n"); - out->Print("from grpc.early_adopter import implementations\n"); + out->Print("from $Package$ import implementations\n", + "Package", config.implementations_package_root); out->Print("from grpc.framework.alpha import utilities\n"); return true; } } // namespace -pair GetServices(const FileDescriptor* file) { +pair GetServices(const FileDescriptor* file, + const GeneratorConfiguration& config) { std::string output; { // Scope the output stream so it closes and finalizes output to the string. StringOutputStream output_stream(&output); Printer out(&output_stream, '$'); - if (!PrintPreamble(file, &out)) { + if (!PrintPreamble(file, config, &out)) { return make_pair(false, ""); } auto package = file->package(); -- cgit v1.2.3