Browse Source

Fixed oneof behavior for enums and fixed JRuby.

Josh Haberman 9 years ago
parent
commit
2d514ce2d8

+ 11 - 2
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));

+ 8 - 4
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;

+ 5 - 5
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"