Commit 9cfb12bf authored by Joshua Haberman's avatar Joshua Haberman

Tests pass for all common operations.

A few things that don't work or aren't tested yet:
- wrappers at the top level
- equality checking for not-yet-expanded wrappers.
parent 969d245b
...@@ -1440,8 +1440,14 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc, ...@@ -1440,8 +1440,14 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
putstr(str, f, sink); putstr(str, f, sink);
} }
} else if (upb_fielddef_issubmsg(f)) { } else if (upb_fielddef_issubmsg(f)) {
putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth, VALUE val = DEREF(msg, offset, VALUE);
emit_defaults, is_json); int type = TYPE(val);
if (type != T_DATA && type != T_NIL && is_wrapper_type_field(f)) {
// OPT: could try to avoid expanding the wrapper here.
val = ruby_wrapper_type(desc->layout, f, val);
DEREF(msg, offset, VALUE) = val;
}
putsubmsg(val, f, sink, depth, emit_defaults, is_json);
} else { } else {
upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
...@@ -1475,7 +1481,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc, ...@@ -1475,7 +1481,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
} }
#undef T #undef T
} }
} }
......
...@@ -108,8 +108,12 @@ enum { ...@@ -108,8 +108,12 @@ enum {
}; };
// Check if the field is a well known wrapper type // Check if the field is a well known wrapper type
static bool is_wrapper_type_field(const upb_fielddef* field) { bool is_wrapper_type_field(const upb_fielddef* field) {
const upb_msgdef *m = upb_fielddef_msgsubdef(field); const upb_msgdef *m;
if (upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
return false;
}
m = upb_fielddef_msgsubdef(field);
switch (upb_msgdef_wellknowntype(m)) { switch (upb_msgdef_wellknowntype(m)) {
case UPB_WELLKNOWN_DOUBLEVALUE: case UPB_WELLKNOWN_DOUBLEVALUE:
case UPB_WELLKNOWN_FLOATVALUE: case UPB_WELLKNOWN_FLOATVALUE:
...@@ -127,8 +131,8 @@ static bool is_wrapper_type_field(const upb_fielddef* field) { ...@@ -127,8 +131,8 @@ static bool is_wrapper_type_field(const upb_fielddef* field) {
} }
// Get a new Ruby wrapper type and set the initial value // Get a new Ruby wrapper type and set the initial value
static VALUE ruby_wrapper_type(const MessageLayout* layout, VALUE ruby_wrapper_type(const MessageLayout* layout, const upb_fielddef* field,
const upb_fielddef* field, const VALUE value) { const VALUE value) {
if (is_wrapper_type_field(field) && value != Qnil) { if (is_wrapper_type_field(field) && value != Qnil) {
VALUE hash = rb_hash_new(); VALUE hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("value"), value); rb_hash_aset(hash, rb_str_new2("value"), value);
...@@ -195,7 +199,6 @@ static int extract_method_call(VALUE method_name, MessageHeader* self, ...@@ -195,7 +199,6 @@ static int extract_method_call(VALUE method_name, MessageHeader* self,
// Check if field exists and is a wrapper type // Check if field exists and is a wrapper type
if (upb_msgdef_lookupname(self->descriptor->msgdef, wrapper_field_name, if (upb_msgdef_lookupname(self->descriptor->msgdef, wrapper_field_name,
name_len - 9, &test_f_wrapper, &test_o_wrapper) && name_len - 9, &test_f_wrapper, &test_o_wrapper) &&
upb_fielddef_type(test_f_wrapper) == UPB_TYPE_MESSAGE &&
is_wrapper_type_field(test_f_wrapper)) { is_wrapper_type_field(test_f_wrapper)) {
// It does exist! // It does exist!
has_field = true; has_field = true;
......
...@@ -556,6 +556,10 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2); ...@@ -556,6 +556,10 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2);
VALUE layout_hash(MessageLayout* layout, void* storage); VALUE layout_hash(MessageLayout* layout, void* storage);
VALUE layout_inspect(MessageLayout* layout, void* storage); VALUE layout_inspect(MessageLayout* layout, void* storage);
bool is_wrapper_type_field(const upb_fielddef* field);
VALUE ruby_wrapper_type(const MessageLayout* layout, const upb_fielddef* field,
const VALUE value);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Message class creation. // Message class creation.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -843,8 +843,15 @@ VALUE layout_get(MessageLayout* layout, ...@@ -843,8 +843,15 @@ VALUE layout_get(MessageLayout* layout,
} else if (!field_set) { } else if (!field_set) {
return layout_get_default(field); return layout_get_default(field);
} else { } else {
return native_slot_get(upb_fielddef_type(field), VALUE type_class = field_type_class(layout, field);
field_type_class(layout, field), memory); VALUE val = native_slot_get(upb_fielddef_type(field), type_class, memory);
int type = TYPE(val);
if (type != T_DATA && type != T_NIL && is_wrapper_type_field(field)) {
val = ruby_wrapper_type(layout, field, val);
native_slot_set(upb_fielddef_name(field), upb_fielddef_type(field),
type_class, memory, val);
}
return val;
} }
} }
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment