diff options
author | Chris Fallin <cfallin@google.com> | 2015-02-12 16:08:01 -0800 |
---|---|---|
committer | Chris Fallin <cfallin@google.com> | 2015-02-12 16:08:01 -0800 |
commit | a2bea0a0012b4adbc50c47246d968a85cb88cec2 (patch) | |
tree | 6ed5b7445bc098091fadf094b2ccbeb124d3569e /src | |
parent | 43beb6268bd3989154991bccb831e2bc951402d8 (diff) | |
download | protobuf-a2bea0a0012b4adbc50c47246d968a85cb88cec2.tar.gz protobuf-a2bea0a0012b4adbc50c47246d968a85cb88cec2.tar.bz2 protobuf-a2bea0a0012b4adbc50c47246d968a85cb88cec2.zip |
Properly support maps in Ruby protoc and another bugfix.
Previously, we supported map fields in the Ruby DSL. However, we never
connected the final link in the chain and generated `map` DSL commands
for map fields in `.proto` files. My apologies -- I had been testing
with the DSL directly so I missed this.
Also fixed a handlerdata-setup-infinite-loop when a map value field's
type is its containing message.
Diffstat (limited to 'src')
-rw-r--r-- | src/google/protobuf/compiler/ruby/ruby_generator.cc | 75 |
1 files changed, 59 insertions, 16 deletions
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index be59fafd..88292891 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -102,24 +102,53 @@ std::string TypeName(const google::protobuf::FieldDescriptor* field) { void GenerateField(const google::protobuf::FieldDescriptor* field, google::protobuf::io::Printer* printer) { - printer->Print( - "$label$ :$name$, ", - "label", LabelForField(field), - "name", field->name()); - printer->Print( - ":$type$, $number$", - "type", TypeName(field), - "number", IntToString(field->number())); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - ", \"$subtype$\"\n", - "subtype", field->message_type()->full_name()); - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + + if (field->is_map()) { + const FieldDescriptor* key_field = + field->message_type()->FindFieldByNumber(1); + const FieldDescriptor* value_field = + field->message_type()->FindFieldByNumber(2); + printer->Print( - ", \"$subtype$\"\n", - "subtype", field->enum_type()->full_name()); + "map :$name$, :$key_type$, :$value_type$, $number$", + "name", field->name(), + "key_type", TypeName(key_field), + "value_type", TypeName(value_field), + "number", IntToString(field->number())); + + if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + ", \"$subtype$\"\n", + "subtype", value_field->message_type()->full_name()); + } else if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + printer->Print( + ", \"$subtype$\"\n", + "subtype", value_field->enum_type()->full_name()); + } else { + printer->Print("\n"); + } } else { - printer->Print("\n"); + + printer->Print( + "$label$ :$name$, ", + "label", LabelForField(field), + "name", field->name()); + printer->Print( + ":$type$, $number$", + "type", TypeName(field), + "number", IntToString(field->number())); + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + ", \"$subtype$\"\n", + "subtype", field->message_type()->full_name()); + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + printer->Print( + ", \"$subtype$\"\n", + "subtype", field->enum_type()->full_name()); + } else { + printer->Print("\n"); + } } } @@ -141,6 +170,13 @@ void GenerateOneof(const google::protobuf::OneofDescriptor* oneof, void GenerateMessage(const google::protobuf::Descriptor* message, google::protobuf::io::Printer* printer) { + + // Don't generate MapEntry messages -- we use the Ruby extension's native + // support for map fields instead. + if (message->options().map_entry()) { + return; + } + printer->Print( "add_message \"$name$\" do\n", "name", message->full_name()); @@ -213,6 +249,13 @@ void GenerateMessageAssignment( const std::string& prefix, const google::protobuf::Descriptor* message, google::protobuf::io::Printer* printer) { + + // Don't generate MapEntry messages -- we use the Ruby extension's native + // support for map fields instead. + if (message->options().map_entry()) { + return; + } + printer->Print( "$prefix$$name$ = ", "prefix", prefix, |