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,
putstr(str, f, sink);
}
} else if (upb_fielddef_issubmsg(f)) {
putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth,
emit_defaults, is_json);
VALUE val = DEREF(msg, offset, VALUE);
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 {
upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
......@@ -1475,7 +1481,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
}
#undef T
}
}
......
......@@ -108,8 +108,12 @@ enum {
};
// Check if the field is a well known wrapper type
static bool is_wrapper_type_field(const upb_fielddef* field) {
const upb_msgdef *m = upb_fielddef_msgsubdef(field);
bool is_wrapper_type_field(const upb_fielddef* 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)) {
case UPB_WELLKNOWN_DOUBLEVALUE:
case UPB_WELLKNOWN_FLOATVALUE:
......@@ -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
static VALUE ruby_wrapper_type(const MessageLayout* layout,
const upb_fielddef* field, const VALUE value) {
VALUE ruby_wrapper_type(const MessageLayout* layout, const upb_fielddef* field,
const VALUE value) {
if (is_wrapper_type_field(field) && value != Qnil) {
VALUE hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("value"), value);
......@@ -195,7 +199,6 @@ static int extract_method_call(VALUE method_name, MessageHeader* self,
// Check if field exists and is a wrapper type
if (upb_msgdef_lookupname(self->descriptor->msgdef, wrapper_field_name,
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)) {
// It does exist!
has_field = true;
......
......@@ -556,6 +556,10 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2);
VALUE layout_hash(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.
// -----------------------------------------------------------------------------
......
......@@ -843,8 +843,15 @@ VALUE layout_get(MessageLayout* layout,
} else if (!field_set) {
return layout_get_default(field);
} else {
return native_slot_get(upb_fielddef_type(field),
field_type_class(layout, field), memory);
VALUE type_class = field_type_class(layout, field);
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