Index: third_party/protobuf/ruby/ext/google/protobuf_c/message.c |
diff --git a/third_party/protobuf/ruby/ext/google/protobuf_c/message.c b/third_party/protobuf/ruby/ext/google/protobuf_c/message.c |
index ebe2f1ab49684f7a0a40793455f89378a20124f5..e16250f3b07eddfce44d176fb941e49efef95c25 100644 |
--- a/third_party/protobuf/ruby/ext/google/protobuf_c/message.c |
+++ b/third_party/protobuf/ruby/ext/google/protobuf_c/message.c |
@@ -151,32 +151,30 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { |
name_len--; |
} |
- // Check for a oneof name first. |
- o = upb_msgdef_ntoo(self->descriptor->msgdef, |
- name, name_len); |
+ // See if this name corresponds to either a oneof or field in this message. |
+ if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len, &f, |
+ &o)) { |
+ return rb_call_super(argc, argv); |
+ } |
+ |
if (o != NULL) { |
+ // This is a oneof -- return which field inside the oneof is set. |
if (setter) { |
rb_raise(rb_eRuntimeError, "Oneof accessors are read-only."); |
} |
return which_oneof_field(self, o); |
- } |
- |
- // Otherwise, check for a field with that name. |
- f = upb_msgdef_ntof(self->descriptor->msgdef, |
- name, name_len); |
- |
- if (f == NULL) { |
- rb_raise(rb_eArgError, "Unknown field"); |
- } |
- |
- if (setter) { |
- if (argc < 2) { |
- rb_raise(rb_eArgError, "No value provided to setter."); |
- } |
- layout_set(self->descriptor->layout, Message_data(self), f, argv[1]); |
- return Qnil; |
} else { |
- return layout_get(self->descriptor->layout, Message_data(self), f); |
+ // This is a field -- get or set the field's value. |
+ assert(f); |
+ if (setter) { |
+ if (argc < 2) { |
+ rb_raise(rb_eArgError, "No value provided to setter."); |
+ } |
+ layout_set(self->descriptor->layout, Message_data(self), f, argv[1]); |
+ return Qnil; |
+ } else { |
+ return layout_get(self->descriptor->layout, Message_data(self), f); |
+ } |
} |
} |
@@ -197,7 +195,7 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { |
f = upb_msgdef_ntofz(self->descriptor->msgdef, name); |
if (f == NULL) { |
rb_raise(rb_eArgError, |
- "Unknown field name in initialization map entry."); |
+ "Unknown field name '%s' in initialization map entry.", name); |
} |
if (is_map_field(f)) { |
@@ -205,7 +203,7 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { |
if (TYPE(val) != T_HASH) { |
rb_raise(rb_eArgError, |
- "Expected Hash object as initializer value for map field."); |
+ "Expected Hash object as initializer value for map field '%s'.", name); |
} |
map = layout_get(self->descriptor->layout, Message_data(self), f); |
Map_merge_into_self(map, val); |
@@ -214,7 +212,7 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { |
if (TYPE(val) != T_ARRAY) { |
rb_raise(rb_eArgError, |
- "Expected array as initializer value for repeated field."); |
+ "Expected array as initializer value for repeated field '%s'.", name); |
} |
ary = layout_get(self->descriptor->layout, Message_data(self), f); |
for (int i = 0; i < RARRAY_LEN(val); i++) { |
@@ -475,7 +473,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) { |
rb_define_singleton_method(klass, "decode", Message_decode, 1); |
rb_define_singleton_method(klass, "encode", Message_encode, 1); |
rb_define_singleton_method(klass, "decode_json", Message_decode_json, 1); |
- rb_define_singleton_method(klass, "encode_json", Message_encode_json, 1); |
+ rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1); |
rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0); |
return klass; |