|
|
|
@ -292,6 +292,35 @@ static void Message_setfield(upb_msg* msg, const upb_fielddef* f, VALUE val, |
|
|
|
|
upb_msg_set(msg, f, msgval, arena); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static VALUE Message_getfield(VALUE _self, const upb_fielddef* f) { |
|
|
|
|
Message* self = ruby_to_Message(_self); |
|
|
|
|
// This is a special-case: upb_msg_mutable() for map & array are logically
|
|
|
|
|
// const (they will not change what is serialized) but physically
|
|
|
|
|
// non-const, as they do allocate a repeated field or map. The logical
|
|
|
|
|
// constness means it's ok to do even if the message is frozen.
|
|
|
|
|
upb_msg *msg = (upb_msg*)self->msg; |
|
|
|
|
upb_arena *arena = Arena_get(self->arena); |
|
|
|
|
if (upb_fielddef_ismap(f)) { |
|
|
|
|
upb_map *map = upb_msg_mutable(msg, f, arena).map; |
|
|
|
|
const upb_fielddef *key_f = map_field_key(f); |
|
|
|
|
const upb_fielddef *val_f = map_field_value(f); |
|
|
|
|
upb_fieldtype_t key_type = upb_fielddef_type(key_f); |
|
|
|
|
TypeInfo value_type_info = TypeInfo_get(val_f); |
|
|
|
|
return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena); |
|
|
|
|
} else if (upb_fielddef_isseq(f)) { |
|
|
|
|
upb_array *arr = upb_msg_mutable(msg, f, arena).array; |
|
|
|
|
return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena); |
|
|
|
|
} else if (upb_fielddef_issubmsg(f)) { |
|
|
|
|
if (!upb_msg_has(self->msg, f)) return Qnil; |
|
|
|
|
upb_msg *submsg = upb_msg_mutable(msg, f, arena).msg; |
|
|
|
|
const upb_msgdef *m = upb_fielddef_msgsubdef(f); |
|
|
|
|
return Message_GetRubyWrapper(submsg, m, self->arena); |
|
|
|
|
} else { |
|
|
|
|
upb_msgval msgval = upb_msg_get(self->msg, f); |
|
|
|
|
return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static VALUE Message_field_accessor(VALUE _self, const upb_fielddef* f, |
|
|
|
|
int accessor_type, int argc, VALUE* argv) { |
|
|
|
|
upb_arena *arena = Arena_get(Message_GetArena(_self)); |
|
|
|
@ -350,37 +379,12 @@ static VALUE Message_field_accessor(VALUE _self, const upb_fielddef* f, |
|
|
|
|
return INT2NUM(msgval.int32_val); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
case METHOD_GETTER: { |
|
|
|
|
Message* self = ruby_to_Message(_self); |
|
|
|
|
// This is a special-case: upb_msg_mutable() for map & array are logically
|
|
|
|
|
// const (they will not change what is serialized) but physically
|
|
|
|
|
// non-const, as they do allocate a repeated field or map. The logical
|
|
|
|
|
// constness means it's ok to do even if the message is frozen.
|
|
|
|
|
upb_msg *msg = (upb_msg*)self->msg; |
|
|
|
|
if (upb_fielddef_ismap(f)) { |
|
|
|
|
upb_map *map = upb_msg_mutable(msg, f, arena).map; |
|
|
|
|
const upb_fielddef *key_f = map_field_key(f); |
|
|
|
|
const upb_fielddef *val_f = map_field_value(f); |
|
|
|
|
upb_fieldtype_t key_type = upb_fielddef_type(key_f); |
|
|
|
|
TypeInfo value_type_info = TypeInfo_get(val_f); |
|
|
|
|
return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena); |
|
|
|
|
} else if (upb_fielddef_isseq(f)) { |
|
|
|
|
upb_array *arr = upb_msg_mutable(msg, f, arena).array; |
|
|
|
|
return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena); |
|
|
|
|
} else if (upb_fielddef_issubmsg(f)) { |
|
|
|
|
if (!upb_msg_has(self->msg, f)) return Qnil; |
|
|
|
|
upb_msg *submsg = upb_msg_mutable(msg, f, arena).msg; |
|
|
|
|
const upb_msgdef *m = upb_fielddef_msgsubdef(f); |
|
|
|
|
return Message_GetRubyWrapper(submsg, m, self->arena); |
|
|
|
|
} else { |
|
|
|
|
upb_msgval msgval = upb_msg_get(self->msg, f); |
|
|
|
|
return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena); |
|
|
|
|
} |
|
|
|
|
case METHOD_GETTER: |
|
|
|
|
return Message_getfield(_self, f); |
|
|
|
|
default: |
|
|
|
|
rb_raise(rb_eRuntimeError, "Internal error, no such accessor: %d", |
|
|
|
|
accessor_type); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -866,7 +870,6 @@ static VALUE Message_freeze(VALUE _self) { |
|
|
|
|
static VALUE Message_index(VALUE _self, VALUE field_name) { |
|
|
|
|
Message* self = ruby_to_Message(_self); |
|
|
|
|
const upb_fielddef* field; |
|
|
|
|
upb_msgval val; |
|
|
|
|
|
|
|
|
|
Check_Type(field_name, T_STRING); |
|
|
|
|
field = upb_msgdef_ntofz(self->msgdef, RSTRING_PTR(field_name)); |
|
|
|
@ -875,8 +878,7 @@ static VALUE Message_index(VALUE _self, VALUE field_name) { |
|
|
|
|
return Qnil; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val = upb_msg_get(self->msg, field); |
|
|
|
|
return Convert_UpbToRuby(val, TypeInfo_get(field), self->arena); |
|
|
|
|
return Message_getfield(_self, field); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|