diff options
author | Matt A <matthew.james.allan@gmail.com> | 2017-07-18 10:45:18 -0400 |
---|---|---|
committer | Paul Yang <TeBoring@users.noreply.github.com> | 2017-07-18 07:45:18 -0700 |
commit | 9e745f771b2a0cde271b8283753c19014124ac95 (patch) | |
tree | fdbeb728029877de7d65f4b8d467e6b7970741db /src/google/protobuf/compiler/php/php_generator.cc | |
parent | 33545583286a31940b6a732b1888e639cdf2e3c4 (diff) |
Support PHP generic services (#3269)
* Add php_generic_services option
* Generate PHP generic services
* Respect namespaces for generated PHP services
* Test PHP generated services
* Rename PHP generator service method doc comment function
* Correct phpdoc service method case
* Test namespaced PHP generic services
* Always use the FQCN for PHP generic service input/output
* Add generated_service_test to php test.sh
* Add php service test protos to CI
* Add php service files to php_EXTRA_DIST
* Use Interface suffix for php generic services
Diffstat (limited to 'src/google/protobuf/compiler/php/php_generator.cc')
-rw-r--r-- | src/google/protobuf/compiler/php/php_generator.cc | 140 |
1 files changed, 130 insertions, 10 deletions
diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 17d8ebad..60e6fce9 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -82,6 +82,10 @@ void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, int is_descriptor); void GenerateEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value); +void GenerateServiceDocComment(io::Printer* printer, + const ServiceDescriptor* service); +void GenerateServiceMethodDocComment(io::Printer* printer, + const MethodDescriptor* method); std::string RenameEmpty(const std::string& name) { if (name == "Empty") { @@ -139,17 +143,9 @@ std::string ClassNamePrefix(const string& classname, return ""; } - template <typename DescriptorType> -std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { - string classname = desc->name(); - const Descriptor* containing = desc->containing_type(); - while (containing != NULL) { - classname = containing->name() + '_' + classname; - containing = containing->containing_type(); - } - classname = ClassNamePrefix(classname, desc) + classname; - +std::string NamespacedName(const string& classname, + const DescriptorType* desc, bool is_descriptor) { if (desc->file()->options().has_php_namespace()) { const string& php_namespace = desc->file()->options().php_namespace(); if (php_namespace != "") { @@ -167,6 +163,24 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { } } +template <typename DescriptorType> +std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { + string classname = desc->name(); + const Descriptor* containing = desc->containing_type(); + while (containing != NULL) { + classname = containing->name() + '_' + classname; + containing = containing->containing_type(); + } + classname = ClassNamePrefix(classname, desc) + classname; + return NamespacedName(classname, desc, is_descriptor); +} + +std::string FullClassName(const ServiceDescriptor* desc, bool is_descriptor) { + string classname = desc->name(); + classname = ClassNamePrefix(classname, desc) + classname; + return NamespacedName(classname, desc, is_descriptor); +} + std::string PhpName(const std::string& full_name, bool is_descriptor) { if (is_descriptor) { return kDescriptorPackageName; @@ -272,6 +286,17 @@ std::string GeneratedEnumFileName(const EnumDescriptor* en, return result + ".php"; } +std::string GeneratedServiceFileName(const ServiceDescriptor* service, + bool is_descriptor) { + std::string result = FullClassName(service, is_descriptor) + "Interface"; + for (int i = 0; i < result.size(); i++) { + if (result[i] == '\\') { + result[i] = '/'; + } + } + return result + ".php"; +} + std::string IntToString(int32 value) { std::ostringstream os; os << value; @@ -660,6 +685,16 @@ void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) { Outdent(printer); } +void GenerateServiceMethod(const MethodDescriptor* method, + io::Printer* printer) { + printer->Print( + "public function ^camel_name^(\\^request_name^ $request);\n\n", + "camel_name", UnderscoresToCamelCase(method->name(), false), + "request_name", FullClassName( + method->input_type(), false) + ); +} + void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, io::Printer* printer) { // Don't generate MapEntry messages -- we use the PHP extension's native @@ -1061,6 +1096,58 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, } } +void GenerateServiceFile(const FileDescriptor* file, + const ServiceDescriptor* service, bool is_descriptor, + GeneratorContext* generator_context) { + std::string filename = GeneratedServiceFileName(service, is_descriptor); + scoped_ptr<io::ZeroCopyOutputStream> output( + generator_context->Open(filename)); + io::Printer printer(output.get(), '^'); + + GenerateHead(file, &printer); + + std::string fullname = FilenameToClassname(filename); + int lastindex = fullname.find_last_of("\\"); + + if (file->options().has_php_namespace()) { + const string& php_namespace = file->options().php_namespace(); + if (!php_namespace.empty()) { + printer.Print( + "namespace ^name^;\n\n", + "name", php_namespace); + } + } else if (!file->package().empty()) { + printer.Print( + "namespace ^name^;\n\n", + "name", fullname.substr(0, lastindex)); + } + + GenerateServiceDocComment(&printer, service); + + if (lastindex != string::npos) { + printer.Print( + "interface ^name^\n" + "{\n", + "name", fullname.substr(lastindex + 1)); + } else { + printer.Print( + "interface ^name^\n" + "{\n", + "name", fullname); + } + + Indent(&printer); + + for (int i = 0; i < service->method_count(); i++) { + const MethodDescriptor* method = service->method(i); + GenerateServiceMethodDocComment(&printer, method); + GenerateServiceMethod(method, &printer); + } + + Outdent(&printer); + printer.Print("}\n\n"); +} + void GenerateFile(const FileDescriptor* file, bool is_descriptor, GeneratorContext* generator_context) { GenerateMetadataFile(file, is_descriptor, generator_context); @@ -1072,6 +1159,12 @@ void GenerateFile(const FileDescriptor* file, bool is_descriptor, GenerateEnumFile(file, file->enum_type(i), is_descriptor, generator_context); } + if (file->options().php_generic_services()) { + for (int i = 0; i < file->service_count(); i++) { + GenerateServiceFile(file, file->service(i), is_descriptor, + generator_context); + } + } } static string EscapePhpdoc(const string& input) { @@ -1180,6 +1273,16 @@ void GenerateMessageDocComment(io::Printer* printer, "messagename", EscapePhpdoc(message->full_name())); } +void GenerateServiceDocComment(io::Printer* printer, + const ServiceDescriptor* service) { + printer->Print("/**\n"); + GenerateDocCommentBody(printer, service); + printer->Print( + " * Protobuf type <code>^fullname^</code>\n" + " */\n", + "fullname", EscapePhpdoc(service->full_name())); +} + void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, int is_descriptor, int function_type) { // In theory we should have slightly different comments for setters, getters, @@ -1226,6 +1329,23 @@ void GenerateEnumValueDocComment(io::Printer* printer, "def", EscapePhpdoc(FirstLineOf(value->DebugString()))); } +void GenerateServiceMethodDocComment(io::Printer* printer, + const MethodDescriptor* method) { + printer->Print("/**\n"); + GenerateDocCommentBody(printer, method); + printer->Print( + " * Method <code>^method_name^</code>\n" + " *\n", + "method_name", EscapePhpdoc(UnderscoresToCamelCase(method->name(), false))); + printer->Print( + " * @param \\^input_type^ $request\n", + "input_type", EscapePhpdoc(FullClassName(method->input_type(), false))); + printer->Print( + " * @return \\^return_type^\n" + " */\n", + "return_type", EscapePhpdoc(FullClassName(method->output_type(), false))); +} + bool Generator::Generate(const FileDescriptor* file, const string& parameter, GeneratorContext* generator_context, string* error) const { |