aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ruby/ext/google/protobuf_c/storage.c13
-rw-r--r--ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java12
-rw-r--r--ruby/tests/basic.rb10
3 files changed, 24 insertions, 11 deletions
diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c
index 5dae5aec..1c839781 100644
--- a/ruby/ext/google/protobuf_c/storage.c
+++ b/ruby/ext/google/protobuf_c/storage.c
@@ -57,14 +57,23 @@ size_t native_slot_size(upb_fieldtype_t type) {
}
}
-VALUE value_from_default(const upb_fielddef *field) {
+static VALUE value_from_default(const upb_fielddef *field) {
switch (upb_fielddef_type(field)) {
case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
case UPB_TYPE_BOOL:
return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
case UPB_TYPE_MESSAGE: return Qnil;
- case UPB_TYPE_ENUM: return INT2NUM(upb_fielddef_defaultint32(field));
+ case UPB_TYPE_ENUM: {
+ const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
+ int32_t num = upb_fielddef_defaultint32(field);
+ const char *label = upb_enumdef_iton(enumdef, num);
+ if (label) {
+ return ID2SYM(rb_intern(label));
+ } else {
+ return INT2NUM(num);
+ }
+ }
case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
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 39213c4d..12893f73 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
@@ -592,13 +592,17 @@ public class RubyMessage extends RubyObject {
protected IRubyObject getField(ThreadContext context, Descriptors.FieldDescriptor fieldDescriptor) {
Descriptors.OneofDescriptor oneofDescriptor = fieldDescriptor.getContainingOneof();
if (oneofDescriptor != null) {
- if (oneofCases.containsKey(oneofDescriptor)) {
- if (oneofCases.get(oneofDescriptor) != fieldDescriptor)
- return context.runtime.getNil();
+ if (oneofCases.get(oneofDescriptor) == fieldDescriptor) {
return fields.get(fieldDescriptor);
} else {
Descriptors.FieldDescriptor oneofCase = builder.getOneofFieldDescriptor(oneofDescriptor);
- if (oneofCase != fieldDescriptor) return context.runtime.getNil();
+ if (oneofCase != fieldDescriptor) {
+ if (fieldDescriptor.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
+ return context.runtime.getNil();
+ } else {
+ return wrapField(context, fieldDescriptor, fieldDescriptor.getDefaultValue());
+ }
+ }
IRubyObject value = wrapField(context, oneofCase, builder.getField(oneofCase));
fields.put(fieldDescriptor, value);
return value;
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index db6a3c75..fee07e33 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -706,28 +706,28 @@ module BasicTest
assert d.a == ""
assert d.b == 0
assert d.c == nil
- assert d.d == 0
+ assert d.d == :Default
assert d.my_oneof == nil
d.a = "hi"
assert d.a == "hi"
assert d.b == 0
assert d.c == nil
- assert d.d == 0
+ assert d.d == :Default
assert d.my_oneof == :a
d.b = 42
assert d.a == ""
assert d.b == 42
assert d.c == nil
- assert d.d == 0
+ assert d.d == :Default
assert d.my_oneof == :b
d.c = TestMessage2.new(:foo => 100)
assert d.a == ""
assert d.b == 0
assert d.c.foo == 100
- assert d.d == 0
+ assert d.d == :Default
assert d.my_oneof == :c
d.d = :C
@@ -759,7 +759,7 @@ module BasicTest
assert d4.a == ""
assert d4.b == 0
assert d4.c.foo == 1
- assert d4.d == 0
+ assert d4.d == :Default
d5 = OneofMessage.new(:a => "hello")
assert d5.a == "hello"