diff options
author | Brent Shaffer <betterbrent@google.com> | 2018-05-02 14:40:15 -0700 |
---|---|---|
committer | Paul Yang <TeBoring@users.noreply.github.com> | 2018-05-24 13:39:41 -0700 |
commit | f1911f37f817fb2dddbb07478bdcda526488fc55 (patch) | |
tree | 402d04901ea74eef1e161aca8a370439760bdb1e /src | |
parent | b625aabbe75f91bb4974b5c75106233ed2761dbb (diff) |
PHP array constructors for protobuf messages (#4530)
* PHP array constructors for protobuf messages
* removes Descriptor from error message
* allows mergeFrom to accept an array
* only use initWithDescriptor if instanceof MapEntry
* adds doc comments
* removes ability for constructors to take arrays for submessages
* Revert "allows mergeFrom to accept an array"
This reverts commit b7b72182d561634af12c5c5c56a7cda3b33241f9.
* makes mergeFromArray protected and fixes mergeFrom whitespace
* Separates merging from JSON and merging from PHP array
* removes well-known types and json keys from array construction
* Addresses PR review comments
* cleans up tests
* fixes exception messages
Diffstat (limited to 'src')
-rw-r--r-- | src/google/protobuf/compiler/php/php_generator.cc | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index a37380e3..34d0f9ef 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -94,6 +94,9 @@ void Indent(io::Printer* printer); void Outdent(io::Printer* printer); void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message, int is_descriptor); +void GenerateMessageConstructorDocComment(io::Printer* printer, + const Descriptor* message, + int is_descriptor); void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, int is_descriptor, int function_type); void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, @@ -1109,8 +1112,9 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, } printer.Print("\n"); + GenerateMessageConstructorDocComment(&printer, message, is_descriptor); printer.Print( - "public function __construct() {\n"); + "public function __construct($data = NULL) {\n"); Indent(&printer); std::string metadata_filename = @@ -1118,7 +1122,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, std::string metadata_fullname = FilenameToClassname(metadata_filename); printer.Print( "\\^fullname^::initOnce();\n" - "parent::__construct();\n", + "parent::__construct($data);\n", "fullname", metadata_fullname); Outdent(&printer); @@ -1271,7 +1275,8 @@ static string EscapePhpdoc(const string& input) { } static void GenerateDocCommentBodyForLocation( - io::Printer* printer, const SourceLocation& location) { + io::Printer* printer, const SourceLocation& location, bool trailingNewline, + int indentCount) { string comments = location.leading_comments.empty() ? location.trailing_comments : location.leading_comments; if (!comments.empty()) { @@ -1292,14 +1297,16 @@ static void GenerateDocCommentBodyForLocation( // Most lines should start with a space. Watch out for lines that start // with a /, since putting that right after the leading asterisk will // close the comment. - if (!lines[i].empty() && lines[i][0] == '/') { + if (indentCount == 0 && !lines[i].empty() && lines[i][0] == '/') { printer->Print(" * ^line^\n", "line", lines[i]); } else { - printer->Print(" *^line^\n", "line", lines[i]); + std::string indent = std::string(indentCount, ' '); + printer->Print(" *^ind^^line^\n", "ind", indent, "line", lines[i]); } } - printer->Print( - " *\n"); + if (trailingNewline) { + printer->Print(" *\n"); + } } } @@ -1308,7 +1315,7 @@ static void GenerateDocCommentBody( io::Printer* printer, const DescriptorType* descriptor) { SourceLocation location; if (descriptor->GetSourceLocation(&location)) { - GenerateDocCommentBodyForLocation(printer, location); + GenerateDocCommentBodyForLocation(printer, location, true, 0); } } @@ -1334,6 +1341,37 @@ void GenerateMessageDocComment(io::Printer* printer, "messagename", EscapePhpdoc(message->full_name())); } +void GenerateMessageConstructorDocComment(io::Printer* printer, + const Descriptor* message, + int is_descriptor) { + // In theory we should have slightly different comments for setters, getters, + // etc., but in practice everyone already knows the difference between these + // so it's redundant information. + + // We start the comment with the main body based on the comments from the + // .proto file (if present). We then end with the field declaration, e.g.: + // optional string foo = 5; + // If the field is a group, the debug string might end with {. + printer->Print("/**\n"); + printer->Print(" * Constructor.\n"); + printer->Print(" *\n"); + printer->Print(" * @param array $data {\n"); + printer->Print(" * Optional. Data for populating the Message object.\n"); + printer->Print(" *\n"); + for (int i = 0; i < message->field_count(); i++) { + const FieldDescriptor* field = message->field(i); + printer->Print(" * @type ^php_type^ $^var^\n", + "php_type", PhpSetterTypeName(field, is_descriptor), + "var", field->name()); + SourceLocation location; + if (field->GetSourceLocation(&location)) { + GenerateDocCommentBodyForLocation(printer, location, false, 10); + } + } + printer->Print(" * }\n"); + printer->Print(" */\n"); +} + void GenerateServiceDocComment(io::Printer* printer, const ServiceDescriptor* service) { printer->Print("/**\n"); |