aboutsummaryrefslogtreecommitdiffhomepage
path: root/ruby/src
diff options
context:
space:
mode:
authorGravatar Zachary Anker <zanker@squareup.com>2017-09-12 12:52:15 -0700
committerGravatar Zachary Anker <zanker@squareup.com>2017-09-20 11:39:46 -0700
commit87714836e328ca3f98c93a451be26bfd35e804b7 (patch)
treed2c626e4851ab2eb99d1c54dddf16a2de5bb17f5 /ruby/src
parent06aa8dc9e730cc39c67d0ff9c0c95e645ccf03c9 (diff)
Allow initializing a chain of protos using only a hash
Diffstat (limited to 'ruby/src')
-rw-r--r--ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java43
1 files changed, 27 insertions, 16 deletions
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
index 733ccfbc..59040394 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
@@ -82,8 +82,8 @@ public class RubyMessage extends RubyObject {
hash.visitAll(new RubyHash.Visitor() {
@Override
public void visit(IRubyObject key, IRubyObject value) {
- if (!(key instanceof RubySymbol))
- throw runtime.newTypeError("Expected symbols as hash keys in initialization map.");
+ if (!(key instanceof RubySymbol) && !(key instanceof RubyString))
+ throw runtime.newTypeError("Expected string or symbols as hash keys in initialization map.");
final Descriptors.FieldDescriptor fieldDescriptor = findField(context, key);
if (Utils.isMapEntry(fieldDescriptor)) {
@@ -103,9 +103,15 @@ public class RubyMessage extends RubyObject {
if (oneof != null) {
oneofCases.put(oneof, fieldDescriptor);
}
+
+ if (value instanceof RubyHash && fieldDescriptor.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
+ RubyDescriptor descriptor = (RubyDescriptor) getDescriptorForField(context, fieldDescriptor);
+ RubyClass typeClass = (RubyClass) descriptor.msgclass(context);
+ value = (IRubyObject) typeClass.newInstance(context, value, Block.NULL_BLOCK);
+ }
+
fields.put(fieldDescriptor, value);
}
-
}
});
}
@@ -518,19 +524,12 @@ public class RubyMessage extends RubyObject {
val = value.isTrue();
break;
case BYTES:
+ Utils.validateStringEncoding(context, fieldDescriptor.getType(), value);
+ val = ByteString.copyFrom(((RubyString) value).getBytes());
+ break;
case STRING:
Utils.validateStringEncoding(context, fieldDescriptor.getType(), value);
- RubyString str = (RubyString) value;
- switch (fieldDescriptor.getType()) {
- case BYTES:
- val = ByteString.copyFrom(str.getBytes());
- break;
- case STRING:
- val = str.asJavaString();
- break;
- default:
- break;
- }
+ val = ((RubyString) value).asJavaString();
break;
case MESSAGE:
RubyClass typeClass = (RubyClass) ((RubyDescriptor) getDescriptorForField(context, fieldDescriptor)).msgclass(context);
@@ -543,7 +542,7 @@ public class RubyMessage extends RubyObject {
if (Utils.isRubyNum(value)) {
val = enumDescriptor.findValueByNumberCreatingIfUnknown(RubyNumeric.num2int(value));
- } else if (value instanceof RubySymbol) {
+ } else if (value instanceof RubySymbol || value instanceof RubyString) {
val = enumDescriptor.findValueByName(value.asJavaString());
} else {
throw runtime.newTypeError("Expected number or symbol type for enum field.");
@@ -741,8 +740,20 @@ public class RubyMessage extends RubyObject {
Descriptors.FieldDescriptor fieldDescriptor, IRubyObject value) {
RubyArray arr = value.convertToArray();
RubyRepeatedField repeatedField = repeatedFieldForFieldDescriptor(context, fieldDescriptor);
+
+ RubyClass typeClass = null;
+ if (fieldDescriptor.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
+ RubyDescriptor descriptor = (RubyDescriptor) getDescriptorForField(context, fieldDescriptor);
+ typeClass = (RubyClass) descriptor.msgclass(context);
+ }
+
for (int i = 0; i < arr.size(); i++) {
- repeatedField.push(context, arr.eltInternal(i));
+ IRubyObject row = arr.eltInternal(i);
+ if (row instanceof RubyHash && typeClass != null) {
+ row = (IRubyObject) typeClass.newInstance(context, row, Block.NULL_BLOCK);
+ }
+
+ repeatedField.push(context, row);
}
return repeatedField;
}