Index: third_party/protobuf/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java |
diff --git a/third_party/protobuf/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/third_party/protobuf/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java |
index 547ab22cb2d6c3dbf819691e32707c54b368849b..39213c4d1670adb97676bfa4155a6298ac8c81fb 100644 |
--- a/third_party/protobuf/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java |
+++ b/third_party/protobuf/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java |
@@ -86,14 +86,14 @@ public class RubyMessage extends RubyObject { |
if (Utils.isMapEntry(fieldDescriptor)) { |
if (!(value instanceof RubyHash)) |
- throw runtime.newArgumentError("Expected Hash object as initializer value for map field."); |
+ throw runtime.newArgumentError("Expected Hash object as initializer value for map field '" + key.asJavaString() + "'."); |
final RubyMap map = newMapForField(context, fieldDescriptor); |
map.mergeIntoSelf(context, value); |
maps.put(fieldDescriptor, map); |
} else if (fieldDescriptor.isRepeated()) { |
if (!(value instanceof RubyArray)) |
- throw runtime.newTypeError("Expected array as initializer var for repeated field."); |
+ throw runtime.newArgumentError("Expected array as initializer value for repeated field '" + key.asJavaString() + "'."); |
RubyRepeatedField repeatedField = rubyToRepeatedField(context, fieldDescriptor, value); |
addRepeatedField(fieldDescriptor, repeatedField); |
} else { |
@@ -217,6 +217,9 @@ public class RubyMessage extends RubyObject { |
RubyDescriptor rubyDescriptor = (RubyDescriptor) getDescriptor(context, metaClass); |
IRubyObject oneofDescriptor = rubyDescriptor.lookupOneof(context, args[0]); |
if (oneofDescriptor.isNil()) { |
+ if (!hasField(args[0])) { |
+ return Helpers.invokeSuper(context, this, metaClass, "method_missing", args, Block.NULL_BLOCK); |
+ } |
return index(context, args[0]); |
} |
RubyOneofDescriptor rubyOneofDescriptor = (RubyOneofDescriptor) oneofDescriptor; |
@@ -233,6 +236,10 @@ public class RubyMessage extends RubyObject { |
if (field.end_with_p(context, equalSign).isTrue()) { |
field.chomp_bang(context, equalSign); |
} |
+ |
+ if (!hasField(field)) { |
+ return Helpers.invokeSuper(context, this, metaClass, "method_missing", args, Block.NULL_BLOCK); |
+ } |
return indexSet(context, field, args[1]); |
} |
} |
@@ -435,6 +442,11 @@ public class RubyMessage extends RubyObject { |
return ret; |
} |
+ private boolean hasField(IRubyObject fieldName) { |
+ String nameStr = fieldName.asJavaString(); |
+ return this.descriptor.findFieldByName(Utils.escapeIdentifier(nameStr)) != null; |
+ } |
+ |
private void checkRepeatedFieldType(ThreadContext context, IRubyObject value, |
Descriptors.FieldDescriptor fieldDescriptor) { |
Ruby runtime = context.runtime; |