1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_HELPERS_H 20 #define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_HELPERS_H 21 22 #include <cstring> 23 #include <fstream> 24 #include <iostream> 25 #include <vector> 26 27 #include "src/compiler/config.h" 28 #include "src/compiler/generator_helpers.h" 29 #include "src/compiler/python_generator.h" 30 #include "src/compiler/python_private_generator.h" 31 32 using grpc::protobuf::Descriptor; 33 using grpc::protobuf::FileDescriptor; 34 using grpc::protobuf::MethodDescriptor; 35 using grpc::protobuf::ServiceDescriptor; 36 using grpc::protobuf::compiler::GeneratorContext; 37 using grpc::protobuf::io::CodedOutputStream; 38 using grpc::protobuf::io::Printer; 39 using grpc::protobuf::io::StringOutputStream; 40 using grpc::protobuf::io::ZeroCopyOutputStream; 41 using grpc_generator::StringReplace; 42 using grpc_generator::StripProto; 43 using std::vector; 44 45 namespace grpc_python_generator { 46 47 namespace { 48 49 typedef vector<const Descriptor*> DescriptorVector; 50 typedef vector<grpc::string> StringVector; 51 52 // TODO(https://github.com/google/protobuf/issues/888): 53 // Export `ModuleName` from protobuf's 54 // `src/google/protobuf/compiler/python/python_generator.cc` file. 55 grpc::string ModuleName(const grpc::string& filename, 56 const grpc::string& import_prefix) { 57 grpc::string basename = StripProto(filename); 58 basename = StringReplace(basename, "-", "_"); 59 basename = StringReplace(basename, "/", "."); 60 return import_prefix + basename + "_pb2"; 61 } 62 63 // TODO(https://github.com/google/protobuf/issues/888): 64 // Export `ModuleAlias` from protobuf's 65 // `src/google/protobuf/compiler/python/python_generator.cc` file. 66 grpc::string ModuleAlias(const grpc::string& filename, 67 const grpc::string& import_prefix) { 68 grpc::string module_name = ModuleName(filename, import_prefix); 69 // We can't have dots in the module name, so we replace each with _dot_. 70 // But that could lead to a collision between a.b and a_dot_b, so we also 71 // duplicate each underscore. 72 module_name = StringReplace(module_name, "_", "__"); 73 module_name = StringReplace(module_name, ".", "_dot_"); 74 return module_name; 75 } 76 77 bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out, 78 grpc::string generator_file_name, 79 bool generate_in_pb2_grpc, 80 grpc::string& import_prefix) { 81 const Descriptor* path_elem_type = type; 82 DescriptorVector message_path; 83 do { 84 message_path.push_back(path_elem_type); 85 path_elem_type = path_elem_type->containing_type(); 86 } while (path_elem_type); // implicit nullptr comparison; don't be explicit 87 grpc::string file_name = type->file()->name(); 88 static const int proto_suffix_length = strlen(".proto"); 89 if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) && 90 file_name.find_last_of(".proto") == file_name.size() - 1)) { 91 return false; 92 } 93 94 grpc::string module; 95 if (generator_file_name != file_name || generate_in_pb2_grpc) { 96 module = ModuleAlias(file_name, import_prefix) + "."; 97 } else { 98 module = ""; 99 } 100 grpc::string message_type; 101 for (DescriptorVector::reverse_iterator path_iter = message_path.rbegin(); 102 path_iter != message_path.rend(); ++path_iter) { 103 message_type += (*path_iter)->name() + "."; 104 } 105 // no pop_back prior to C++11 106 message_type.resize(message_type.size() - 1); 107 *out = module + message_type; 108 return true; 109 } 110 111 template <typename DescriptorType> 112 StringVector get_all_comments(const DescriptorType* descriptor) { 113 StringVector comments; 114 grpc_generator::GetComment( 115 descriptor, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &comments); 116 grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_LEADING, 117 &comments); 118 grpc_generator::GetComment(descriptor, grpc_generator::COMMENTTYPE_TRAILING, 119 &comments); 120 return comments; 121 } 122 123 } // namespace 124 125 } // namespace grpc_python_generator 126 127 #endif // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_HELPERS_H 128