Updated to new upb APIs.

pull/9436/head
Joshua Haberman 3 years ago
parent f41049a0f0
commit c153dd9bf7
  1. 8
      ruby/Rakefile
  2. 229
      ruby/ext/google/protobuf_c/convert.c
  3. 21
      ruby/ext/google/protobuf_c/convert.h
  4. 397
      ruby/ext/google/protobuf_c/defs.c
  5. 38
      ruby/ext/google/protobuf_c/defs.h
  6. 210
      ruby/ext/google/protobuf_c/map.c
  7. 15
      ruby/ext/google/protobuf_c/map.h
  8. 626
      ruby/ext/google/protobuf_c/message.c
  9. 41
      ruby/ext/google/protobuf_c/message.h
  10. 115
      ruby/ext/google/protobuf_c/protobuf.c
  11. 23
      ruby/ext/google/protobuf_c/protobuf.h
  12. 166
      ruby/ext/google/protobuf_c/repeated_field.c
  13. 12
      ruby/ext/google/protobuf_c/repeated_field.h
  14. 2
      ruby/ext/google/protobuf_c/ruby-upb.c
  15. 4
      ruby/ext/google/protobuf_c/ruby-upb.h
  16. 7
      ruby/ext/google/protobuf_c/wrap_memcpy.c
  17. 8
      ruby/tests/common_tests.rb

@ -80,6 +80,14 @@ if RUBY_PLATFORM == "java"
end end
else else
unless ENV['IN_DOCKER'] == 'true'
# We need utf8_range in-tree.
FileUtils.mkdir_p("ext/google/protobuf_c/third_party/utf8_range")
FileUtils.cp("../third_party/utf8_range/utf8_range.h", "ext/google/protobuf_c/third_party/utf8_range")
FileUtils.cp("../third_party/utf8_range/utf8_range.c", "ext/google/protobuf_c/third_party/utf8_range")
FileUtils.cp("../third_party/utf8_range/LICENSE", "ext/google/protobuf_c/third_party/utf8_range")
end
Rake::ExtensionTask.new("protobuf_c", spec) do |ext| Rake::ExtensionTask.new("protobuf_c", spec) do |ext|
unless RUBY_PLATFORM =~ /darwin/ unless RUBY_PLATFORM =~ /darwin/
# TODO: also set "no_native to true" for mac if possible. As is, # TODO: also set "no_native to true" for mac if possible. As is,

@ -31,7 +31,7 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Ruby <-> upb data conversion functions. // Ruby <-> upb data conversion functions.
// //
// This file Also contains a few other assorted algorithms on upb_msgval. // This file Also contains a few other assorted algorithms on upb_MessageValue.
// //
// None of the algorithms in this file require any access to the internal // None of the algorithms in this file require any access to the internal
// representation of Ruby or upb objects. // representation of Ruby or upb objects.
@ -42,10 +42,10 @@
#include "message.h" #include "message.h"
#include "protobuf.h" #include "protobuf.h"
static upb_strview Convert_StringData(VALUE str, upb_arena *arena) { static upb_StringView Convert_StringData(VALUE str, upb_Arena* arena) {
upb_strview ret; upb_StringView ret;
if (arena) { if (arena) {
char *ptr = upb_arena_malloc(arena, RSTRING_LEN(str)); char* ptr = upb_Arena_Malloc(arena, RSTRING_LEN(str));
memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str)); memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str));
ret.data = ptr; ret.data = ptr;
} else { } else {
@ -57,13 +57,11 @@ static upb_strview Convert_StringData(VALUE str, upb_arena *arena) {
} }
static bool is_ruby_num(VALUE value) { static bool is_ruby_num(VALUE value) {
return (TYPE(value) == T_FLOAT || return (TYPE(value) == T_FLOAT || TYPE(value) == T_FIXNUM ||
TYPE(value) == T_FIXNUM ||
TYPE(value) == T_BIGNUM); TYPE(value) == T_BIGNUM);
} }
static void Convert_CheckInt(const char* name, upb_fieldtype_t type, static void Convert_CheckInt(const char* name, upb_CType type, VALUE val) {
VALUE val) {
if (!is_ruby_num(val)) { if (!is_ruby_num(val)) {
rb_raise(cTypeError, rb_raise(cTypeError,
"Expected number type for integral field '%s' (given %s).", name, "Expected number type for integral field '%s' (given %s).", name,
@ -82,7 +80,7 @@ static void Convert_CheckInt(const char* name, upb_fieldtype_t type,
name, rb_class2name(CLASS_OF(val))); name, rb_class2name(CLASS_OF(val)));
} }
} }
if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) { if (type == kUpb_CType_UInt32 || type == kUpb_CType_UInt64) {
if (NUM2DBL(val) < 0) { if (NUM2DBL(val) < 0) {
rb_raise( rb_raise(
rb_eRangeError, rb_eRangeError,
@ -93,26 +91,31 @@ static void Convert_CheckInt(const char* name, upb_fieldtype_t type,
} }
static int32_t Convert_ToEnum(VALUE value, const char* name, static int32_t Convert_ToEnum(VALUE value, const char* name,
const upb_enumdef* e) { const upb_EnumDef* e) {
int32_t val; int32_t val;
switch (TYPE(value)) { switch (TYPE(value)) {
case T_FLOAT: case T_FLOAT:
case T_FIXNUM: case T_FIXNUM:
case T_BIGNUM: case T_BIGNUM:
Convert_CheckInt(name, UPB_TYPE_INT32, value); Convert_CheckInt(name, kUpb_CType_Int32, value);
val = NUM2INT(value); val = NUM2INT(value);
break; break;
case T_STRING: case T_STRING: {
if (!upb_enumdef_ntoi(e, RSTRING_PTR(value), RSTRING_LEN(value), &val)) { const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize(
goto unknownval; e, RSTRING_PTR(value), RSTRING_LEN(value));
} if (!ev) goto unknownval;
val = upb_EnumValueDef_Number(ev);
break; break;
case T_SYMBOL: }
if (!upb_enumdef_ntoiz(e, rb_id2name(SYM2ID(value)), &val)) { case T_SYMBOL: {
const upb_EnumValueDef* ev =
upb_EnumDef_FindValueByName(e, rb_id2name(SYM2ID(value)));
if (!ev)
goto unknownval; goto unknownval;
} val = upb_EnumValueDef_Number(ev);
break; break;
}
default: default:
rb_raise(cTypeError, rb_raise(cTypeError,
"Expected number or symbol type for enum field '%s'.", name); "Expected number or symbol type for enum field '%s'.", name);
@ -124,47 +127,52 @@ unknownval:
rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name); rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
} }
upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info, upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
upb_arena* arena) { TypeInfo type_info, upb_Arena* arena) {
upb_msgval ret; upb_MessageValue ret;
switch (type_info.type) { switch (type_info.type) {
case UPB_TYPE_FLOAT: case kUpb_CType_Float:
if (!is_ruby_num(value)) { if (!is_ruby_num(value)) {
rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).", rb_raise(cTypeError,
name, rb_class2name(CLASS_OF(value))); "Expected number type for float field '%s' (given %s).", name,
rb_class2name(CLASS_OF(value)));
} }
ret.float_val = NUM2DBL(value); ret.float_val = NUM2DBL(value);
break; break;
case UPB_TYPE_DOUBLE: case kUpb_CType_Double:
if (!is_ruby_num(value)) { if (!is_ruby_num(value)) {
rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).", rb_raise(cTypeError,
name, rb_class2name(CLASS_OF(value))); "Expected number type for double field '%s' (given %s).", name,
rb_class2name(CLASS_OF(value)));
} }
ret.double_val = NUM2DBL(value); ret.double_val = NUM2DBL(value);
break; break;
case UPB_TYPE_BOOL: { case kUpb_CType_Bool: {
if (value == Qtrue) { if (value == Qtrue) {
ret.bool_val = 1; ret.bool_val = 1;
} else if (value == Qfalse) { } else if (value == Qfalse) {
ret.bool_val = 0; ret.bool_val = 0;
} else { } else {
rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).", rb_raise(cTypeError,
name, rb_class2name(CLASS_OF(value))); "Invalid argument for boolean field '%s' (given %s).", name,
rb_class2name(CLASS_OF(value)));
} }
break; break;
} }
case UPB_TYPE_STRING: { case kUpb_CType_String: {
VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding()); VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
if (CLASS_OF(value) == rb_cSymbol) { if (CLASS_OF(value) == rb_cSymbol) {
value = rb_funcall(value, rb_intern("to_s"), 0); value = rb_funcall(value, rb_intern("to_s"), 0);
} else if (CLASS_OF(value) != rb_cString) { } else if (CLASS_OF(value) != rb_cString) {
rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).", rb_raise(cTypeError,
name, rb_class2name(CLASS_OF(value))); "Invalid argument for string field '%s' (given %s).", name,
rb_class2name(CLASS_OF(value)));
} }
if (rb_obj_encoding(value) != utf8) { if (rb_obj_encoding(value) != utf8) {
// Note: this will not duplicate underlying string data unless necessary. // Note: this will not duplicate underlying string data unless
// necessary.
value = rb_str_encode(value, utf8, 0, Qnil); value = rb_str_encode(value, utf8, 0, Qnil);
if (rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) { if (rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
@ -175,15 +183,17 @@ upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info,
ret.str_val = Convert_StringData(value, arena); ret.str_val = Convert_StringData(value, arena);
break; break;
} }
case UPB_TYPE_BYTES: { case kUpb_CType_Bytes: {
VALUE bytes = rb_enc_from_encoding(rb_ascii8bit_encoding()); VALUE bytes = rb_enc_from_encoding(rb_ascii8bit_encoding());
if (CLASS_OF(value) != rb_cString) { if (CLASS_OF(value) != rb_cString) {
rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).", rb_raise(cTypeError,
name, rb_class2name(CLASS_OF(value))); "Invalid argument for bytes field '%s' (given %s).", name,
rb_class2name(CLASS_OF(value)));
} }
if (rb_obj_encoding(value) != bytes) { if (rb_obj_encoding(value) != bytes) {
// Note: this will not duplicate underlying string data unless necessary. // Note: this will not duplicate underlying string data unless
// necessary.
// TODO(haberman): is this really necessary to get raw bytes? // TODO(haberman): is this really necessary to get raw bytes?
value = rb_str_encode(value, bytes, 0, Qnil); value = rb_str_encode(value, bytes, 0, Qnil);
} }
@ -191,33 +201,33 @@ upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info,
ret.str_val = Convert_StringData(value, arena); ret.str_val = Convert_StringData(value, arena);
break; break;
} }
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
ret.msg_val = ret.msg_val =
Message_GetUpbMessage(value, type_info.def.msgdef, name, arena); Message_GetUpbMessage(value, type_info.def.msgdef, name, arena);
break; break;
case UPB_TYPE_ENUM: case kUpb_CType_Enum:
ret.int32_val = Convert_ToEnum(value, name, type_info.def.enumdef); ret.int32_val = Convert_ToEnum(value, name, type_info.def.enumdef);
break; break;
case UPB_TYPE_INT32: case kUpb_CType_Int32:
case UPB_TYPE_INT64: case kUpb_CType_Int64:
case UPB_TYPE_UINT32: case kUpb_CType_UInt32:
case UPB_TYPE_UINT64: case kUpb_CType_UInt64:
Convert_CheckInt(name, type_info.type, value); Convert_CheckInt(name, type_info.type, value);
switch (type_info.type) { switch (type_info.type) {
case UPB_TYPE_INT32: case kUpb_CType_Int32:
ret.int32_val = NUM2INT(value); ret.int32_val = NUM2INT(value);
break; break;
case UPB_TYPE_INT64: case kUpb_CType_Int64:
ret.int64_val = NUM2LL(value); ret.int64_val = NUM2LL(value);
break; break;
case UPB_TYPE_UINT32: case kUpb_CType_UInt32:
ret.uint32_val = NUM2UINT(value); ret.uint32_val = NUM2UINT(value);
break; break;
case UPB_TYPE_UINT64: case kUpb_CType_UInt64:
ret.uint64_val = NUM2ULL(value); ret.uint64_val = NUM2ULL(value);
break; break;
default: default:
break; break;
} }
break; break;
default: default:
@ -227,45 +237,46 @@ upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info,
return ret; return ret;
} }
VALUE Convert_UpbToRuby(upb_msgval upb_val, TypeInfo type_info, VALUE arena) { VALUE Convert_UpbToRuby(upb_MessageValue upb_val, TypeInfo type_info,
VALUE arena) {
switch (type_info.type) { switch (type_info.type) {
case UPB_TYPE_FLOAT: case kUpb_CType_Float:
return DBL2NUM(upb_val.float_val); return DBL2NUM(upb_val.float_val);
case UPB_TYPE_DOUBLE: case kUpb_CType_Double:
return DBL2NUM(upb_val.double_val); return DBL2NUM(upb_val.double_val);
case UPB_TYPE_BOOL: case kUpb_CType_Bool:
return upb_val.bool_val ? Qtrue : Qfalse; return upb_val.bool_val ? Qtrue : Qfalse;
case UPB_TYPE_INT32: case kUpb_CType_Int32:
return INT2NUM(upb_val.int32_val); return INT2NUM(upb_val.int32_val);
case UPB_TYPE_INT64: case kUpb_CType_Int64:
return LL2NUM(upb_val.int64_val); return LL2NUM(upb_val.int64_val);
case UPB_TYPE_UINT32: case kUpb_CType_UInt32:
return UINT2NUM(upb_val.uint32_val); return UINT2NUM(upb_val.uint32_val);
case UPB_TYPE_UINT64: case kUpb_CType_UInt64:
return ULL2NUM(upb_val.int64_val); return ULL2NUM(upb_val.int64_val);
case UPB_TYPE_ENUM: { case kUpb_CType_Enum: {
const char* name = const upb_EnumValueDef *ev = upb_EnumDef_FindValueByNumber(
upb_enumdef_iton(type_info.def.enumdef, upb_val.int32_val); type_info.def.enumdef, upb_val.int32_val);
if (name) { if (ev) {
return ID2SYM(rb_intern(name)); return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
} else { } else {
return INT2NUM(upb_val.int32_val); return INT2NUM(upb_val.int32_val);
} }
} }
case UPB_TYPE_STRING: { case kUpb_CType_String: {
VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size); VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size);
rb_enc_associate(str_rb, rb_utf8_encoding()); rb_enc_associate(str_rb, rb_utf8_encoding());
rb_obj_freeze(str_rb); rb_obj_freeze(str_rb);
return str_rb; return str_rb;
} }
case UPB_TYPE_BYTES: { case kUpb_CType_Bytes: {
VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size); VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size);
rb_enc_associate(str_rb, rb_ascii8bit_encoding()); rb_enc_associate(str_rb, rb_ascii8bit_encoding());
rb_obj_freeze(str_rb); rb_obj_freeze(str_rb);
return str_rb; return str_rb;
} }
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
return Message_GetRubyWrapper((upb_msg*)upb_val.msg_val, return Message_GetRubyWrapper((upb_Message*)upb_val.msg_val,
type_info.def.msgdef, arena); type_info.def.msgdef, arena);
default: default:
rb_raise(rb_eRuntimeError, "Convert_UpbToRuby(): Unexpected type %d", rb_raise(rb_eRuntimeError, "Convert_UpbToRuby(): Unexpected type %d",
@ -273,24 +284,24 @@ VALUE Convert_UpbToRuby(upb_msgval upb_val, TypeInfo type_info, VALUE arena) {
} }
} }
upb_msgval Msgval_DeepCopy(upb_msgval msgval, TypeInfo type_info, upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info,
upb_arena* arena) { upb_Arena* arena) {
upb_msgval new_msgval; upb_MessageValue new_msgval;
switch (type_info.type) { switch (type_info.type) {
default: default:
memcpy(&new_msgval, &msgval, sizeof(msgval)); memcpy(&new_msgval, &msgval, sizeof(msgval));
break; break;
case UPB_TYPE_STRING: case kUpb_CType_String:
case UPB_TYPE_BYTES: { case kUpb_CType_Bytes: {
size_t n = msgval.str_val.size; size_t n = msgval.str_val.size;
char *mem = upb_arena_malloc(arena, n); char* mem = upb_Arena_Malloc(arena, n);
new_msgval.str_val.data = mem; new_msgval.str_val.data = mem;
new_msgval.str_val.size = n; new_msgval.str_val.size = n;
memcpy(mem, msgval.str_val.data, n); memcpy(mem, msgval.str_val.data, n);
break; break;
} }
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
new_msgval.msg_val = new_msgval.msg_val =
Message_deep_copy(msgval.msg_val, type_info.def.msgdef, arena); Message_deep_copy(msgval.msg_val, type_info.def.msgdef, arena);
break; break;
@ -299,48 +310,50 @@ upb_msgval Msgval_DeepCopy(upb_msgval msgval, TypeInfo type_info,
return new_msgval; return new_msgval;
} }
bool Msgval_IsEqual(upb_msgval val1, upb_msgval val2, TypeInfo type_info) { bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2,
TypeInfo type_info) {
switch (type_info.type) { switch (type_info.type) {
case UPB_TYPE_BOOL: case kUpb_CType_Bool:
return memcmp(&val1, &val2, 1) == 0; return memcmp(&val1, &val2, 1) == 0;
case UPB_TYPE_FLOAT: case kUpb_CType_Float:
case UPB_TYPE_INT32: case kUpb_CType_Int32:
case UPB_TYPE_UINT32: case kUpb_CType_UInt32:
case UPB_TYPE_ENUM: case kUpb_CType_Enum:
return memcmp(&val1, &val2, 4) == 0; return memcmp(&val1, &val2, 4) == 0;
case UPB_TYPE_DOUBLE: case kUpb_CType_Double:
case UPB_TYPE_INT64: case kUpb_CType_Int64:
case UPB_TYPE_UINT64: case kUpb_CType_UInt64:
return memcmp(&val1, &val2, 8) == 0; return memcmp(&val1, &val2, 8) == 0;
case UPB_TYPE_STRING: case kUpb_CType_String:
case UPB_TYPE_BYTES: case kUpb_CType_Bytes:
return val1.str_val.size == val2.str_val.size && return val1.str_val.size == val2.str_val.size &&
memcmp(val1.str_val.data, val2.str_val.data, memcmp(val1.str_val.data, val2.str_val.data, val1.str_val.size) ==
val1.str_val.size) == 0; 0;
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
return Message_Equal(val1.msg_val, val2.msg_val, type_info.def.msgdef); return Message_Equal(val1.msg_val, val2.msg_val, type_info.def.msgdef);
default: default:
rb_raise(rb_eRuntimeError, "Internal error, unexpected type"); rb_raise(rb_eRuntimeError, "Internal error, unexpected type");
} }
} }
uint64_t Msgval_GetHash(upb_msgval val, TypeInfo type_info, uint64_t seed) { uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info,
uint64_t seed) {
switch (type_info.type) { switch (type_info.type) {
case UPB_TYPE_BOOL: case kUpb_CType_Bool:
return Wyhash(&val, 1, seed, kWyhashSalt); return Wyhash(&val, 1, seed, kWyhashSalt);
case UPB_TYPE_FLOAT: case kUpb_CType_Float:
case UPB_TYPE_INT32: case kUpb_CType_Int32:
case UPB_TYPE_UINT32: case kUpb_CType_UInt32:
case UPB_TYPE_ENUM: case kUpb_CType_Enum:
return Wyhash(&val, 4, seed, kWyhashSalt); return Wyhash(&val, 4, seed, kWyhashSalt);
case UPB_TYPE_DOUBLE: case kUpb_CType_Double:
case UPB_TYPE_INT64: case kUpb_CType_Int64:
case UPB_TYPE_UINT64: case kUpb_CType_UInt64:
return Wyhash(&val, 8, seed, kWyhashSalt); return Wyhash(&val, 8, seed, kWyhashSalt);
case UPB_TYPE_STRING: case kUpb_CType_String:
case UPB_TYPE_BYTES: case kUpb_CType_Bytes:
return Wyhash(val.str_val.data, val.str_val.size, seed, kWyhashSalt); return Wyhash(val.str_val.data, val.str_val.size, seed, kWyhashSalt);
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
return Message_Hash(val.msg_val, type_info.def.msgdef, seed); return Message_Hash(val.msg_val, type_info.def.msgdef, seed);
default: default:
rb_raise(rb_eRuntimeError, "Internal error, unexpected type"); rb_raise(rb_eRuntimeError, "Internal error, unexpected type");

@ -36,7 +36,7 @@
#include "protobuf.h" #include "protobuf.h"
#include "ruby-upb.h" #include "ruby-upb.h"
// Converts |ruby_val| to a upb_msgval according to |type_info|. // Converts |ruby_val| to a upb_MessageValue according to |type_info|.
// //
// The |arena| parameter indicates the lifetime of the container where this // The |arena| parameter indicates the lifetime of the container where this
// value will be assigned. It is used as follows: // value will be assigned. It is used as follows:
@ -47,8 +47,8 @@
// - If type is message and the Ruby value is a message instance, we will fuse // - If type is message and the Ruby value is a message instance, we will fuse
// the message's arena into |arena|, to ensure that this message outlives the // the message's arena into |arena|, to ensure that this message outlives the
// container. // container.
upb_msgval Convert_RubyToUpb(VALUE ruby_val, const char *name, upb_MessageValue Convert_RubyToUpb(VALUE ruby_val, const char *name,
TypeInfo type_info, upb_arena *arena); TypeInfo type_info, upb_Arena *arena);
// Converts |upb_val| to a Ruby VALUE according to |type_info|. This may involve // Converts |upb_val| to a Ruby VALUE according to |type_info|. This may involve
// creating a Ruby wrapper object. // creating a Ruby wrapper object.
@ -56,17 +56,20 @@ upb_msgval Convert_RubyToUpb(VALUE ruby_val, const char *name,
// The |arena| parameter indicates the arena that owns the lifetime of // The |arena| parameter indicates the arena that owns the lifetime of
// |upb_val|. Any Ruby wrapper object that is created will reference |arena| // |upb_val|. Any Ruby wrapper object that is created will reference |arena|
// and ensure it outlives the wrapper. // and ensure it outlives the wrapper.
VALUE Convert_UpbToRuby(upb_msgval upb_val, TypeInfo type_info, VALUE arena); VALUE Convert_UpbToRuby(upb_MessageValue upb_val, TypeInfo type_info,
VALUE arena);
// Creates a deep copy of |msgval| in |arena|. // Creates a deep copy of |msgval| in |arena|.
upb_msgval Msgval_DeepCopy(upb_msgval msgval, TypeInfo type_info, upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info,
upb_arena *arena); upb_Arena *arena);
// Returns true if |val1| and |val2| are equal. Their type is given by // Returns true if |val1| and |val2| are equal. Their type is given by
// |type_info|. // |type_info|.
bool Msgval_IsEqual(upb_msgval val1, upb_msgval val2, TypeInfo type_info); bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2,
TypeInfo type_info);
// Returns a hash value for the given upb_msgval. // Returns a hash value for the given upb_MessageValue.
uint64_t Msgval_GetHash(upb_msgval val, TypeInfo type_info, uint64_t seed); uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info,
uint64_t seed);
#endif // RUBY_PROTOBUF_CONVERT_H_ #endif // RUBY_PROTOBUF_CONVERT_H_

@ -41,11 +41,11 @@
// instances. // instances.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def); static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def);
static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def); static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def);
static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def); static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def);
static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def); static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def);
static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def); static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def);
// A distinct object that is not accessible from Ruby. We use this as a // A distinct object that is not accessible from Ruby. We use this as a
// constructor argument to enforce that certain objects cannot be created from // constructor argument to enforce that certain objects cannot be created from
@ -74,7 +74,7 @@ static VALUE rb_str_maybe_null(const char* s) {
typedef struct { typedef struct {
VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor. VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor.
upb_symtab* symtab; upb_DefPool* symtab;
} DescriptorPool; } DescriptorPool;
VALUE cDescriptorPool = Qnil; VALUE cDescriptorPool = Qnil;
@ -90,14 +90,14 @@ static void DescriptorPool_mark(void* _self) {
static void DescriptorPool_free(void* _self) { static void DescriptorPool_free(void* _self) {
DescriptorPool* self = _self; DescriptorPool* self = _self;
upb_symtab_free(self->symtab); upb_DefPool_Free(self->symtab);
xfree(self); xfree(self);
} }
static const rb_data_type_t DescriptorPool_type = { static const rb_data_type_t DescriptorPool_type = {
"Google::Protobuf::DescriptorPool", "Google::Protobuf::DescriptorPool",
{DescriptorPool_mark, DescriptorPool_free, NULL}, {DescriptorPool_mark, DescriptorPool_free, NULL},
.flags = RUBY_TYPED_FREE_IMMEDIATELY, .flags = RUBY_TYPED_FREE_IMMEDIATELY,
}; };
static DescriptorPool* ruby_to_DescriptorPool(VALUE val) { static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
@ -107,8 +107,8 @@ static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
} }
// Exposed to other modules in defs.h. // Exposed to other modules in defs.h.
const upb_symtab *DescriptorPool_GetSymtab(VALUE desc_pool_rb) { const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb) {
DescriptorPool *pool = ruby_to_DescriptorPool(desc_pool_rb); DescriptorPool* pool = ruby_to_DescriptorPool(desc_pool_rb);
return pool->symtab; return pool->symtab;
} }
@ -126,7 +126,7 @@ static VALUE DescriptorPool_alloc(VALUE klass) {
ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self); ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self);
self->def_to_descriptor = rb_hash_new(); self->def_to_descriptor = rb_hash_new();
self->symtab = upb_symtab_new(); self->symtab = upb_DefPool_New();
ObjectCache_Add(self->symtab, ret); ObjectCache_Add(self->symtab, ret);
return ret; return ret;
@ -143,7 +143,7 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
DescriptorPool* self = ruby_to_DescriptorPool(_self); DescriptorPool* self = ruby_to_DescriptorPool(_self);
Check_Type(serialized_file_proto, T_STRING); Check_Type(serialized_file_proto, T_STRING);
VALUE arena_rb = Arena_new(); VALUE arena_rb = Arena_new();
upb_arena *arena = Arena_get(arena_rb); upb_Arena* arena = Arena_get(arena_rb);
google_protobuf_FileDescriptorProto* file_proto = google_protobuf_FileDescriptorProto* file_proto =
google_protobuf_FileDescriptorProto_parse( google_protobuf_FileDescriptorProto_parse(
RSTRING_PTR(serialized_file_proto), RSTRING_PTR(serialized_file_proto),
@ -151,13 +151,13 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
if (!file_proto) { if (!file_proto) {
rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto"); rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto");
} }
upb_status status; upb_Status status;
upb_status_clear(&status); upb_Status_Clear(&status);
const upb_filedef* filedef = const upb_FileDef* filedef =
upb_symtab_addfile(self->symtab, file_proto, &status); upb_DefPool_AddFile(self->symtab, file_proto, &status);
if (!filedef) { if (!filedef) {
rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s", rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s",
upb_status_errmsg(&status)); upb_Status_ErrorMessage(&status));
} }
return get_filedef_obj(_self, filedef); return get_filedef_obj(_self, filedef);
} }
@ -172,15 +172,15 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) { static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
DescriptorPool* self = ruby_to_DescriptorPool(_self); DescriptorPool* self = ruby_to_DescriptorPool(_self);
const char* name_str = get_str(name); const char* name_str = get_str(name);
const upb_msgdef* msgdef; const upb_MessageDef* msgdef;
const upb_enumdef* enumdef; const upb_EnumDef* enumdef;
msgdef = upb_symtab_lookupmsg(self->symtab, name_str); msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
if (msgdef) { if (msgdef) {
return get_msgdef_obj(_self, msgdef); return get_msgdef_obj(_self, msgdef);
} }
enumdef = upb_symtab_lookupenum(self->symtab, name_str); enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str);
if (enumdef) { if (enumdef) {
return get_enumdef_obj(_self, enumdef); return get_enumdef_obj(_self, enumdef);
} }
@ -202,8 +202,7 @@ static VALUE DescriptorPool_generated_pool(VALUE _self) {
} }
static void DescriptorPool_register(VALUE module) { static void DescriptorPool_register(VALUE module) {
VALUE klass = rb_define_class_under( VALUE klass = rb_define_class_under(module, "DescriptorPool", rb_cObject);
module, "DescriptorPool", rb_cObject);
rb_define_alloc_func(klass, DescriptorPool_alloc); rb_define_alloc_func(klass, DescriptorPool_alloc);
rb_define_method(klass, "add_serialized_file", rb_define_method(klass, "add_serialized_file",
DescriptorPool_add_serialized_file, 1); DescriptorPool_add_serialized_file, 1);
@ -222,7 +221,7 @@ static void DescriptorPool_register(VALUE module) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef struct { typedef struct {
const upb_msgdef* msgdef; const upb_MessageDef* msgdef;
VALUE klass; VALUE klass;
VALUE descriptor_pool; VALUE descriptor_pool;
} Descriptor; } Descriptor;
@ -236,9 +235,9 @@ static void Descriptor_mark(void* _self) {
} }
static const rb_data_type_t Descriptor_type = { static const rb_data_type_t Descriptor_type = {
"Google::Protobuf::Descriptor", "Google::Protobuf::Descriptor",
{Descriptor_mark, RUBY_DEFAULT_FREE, NULL}, {Descriptor_mark, RUBY_DEFAULT_FREE, NULL},
.flags = RUBY_TYPED_FREE_IMMEDIATELY, .flags = RUBY_TYPED_FREE_IMMEDIATELY,
}; };
static Descriptor* ruby_to_Descriptor(VALUE val) { static Descriptor* ruby_to_Descriptor(VALUE val) {
@ -281,7 +280,7 @@ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
} }
self->descriptor_pool = descriptor_pool; self->descriptor_pool = descriptor_pool;
self->msgdef = (const upb_msgdef*)NUM2ULL(ptr); self->msgdef = (const upb_MessageDef*)NUM2ULL(ptr);
return Qnil; return Qnil;
} }
@ -294,7 +293,8 @@ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
*/ */
static VALUE Descriptor_file_descriptor(VALUE _self) { static VALUE Descriptor_file_descriptor(VALUE _self) {
Descriptor* self = ruby_to_Descriptor(_self); Descriptor* self = ruby_to_Descriptor(_self);
return get_filedef_obj(self->descriptor_pool, upb_msgdef_file(self->msgdef)); return get_filedef_obj(self->descriptor_pool,
upb_MessageDef_File(self->msgdef));
} }
/* /*
@ -306,7 +306,7 @@ static VALUE Descriptor_file_descriptor(VALUE _self) {
*/ */
static VALUE Descriptor_name(VALUE _self) { static VALUE Descriptor_name(VALUE _self) {
Descriptor* self = ruby_to_Descriptor(_self); Descriptor* self = ruby_to_Descriptor(_self);
return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef)); return rb_str_maybe_null(upb_MessageDef_FullName(self->msgdef));
} }
/* /*
@ -318,11 +318,9 @@ static VALUE Descriptor_name(VALUE _self) {
static VALUE Descriptor_each(VALUE _self) { static VALUE Descriptor_each(VALUE _self) {
Descriptor* self = ruby_to_Descriptor(_self); Descriptor* self = ruby_to_Descriptor(_self);
upb_msg_field_iter it; int n = upb_MessageDef_FieldCount(self->msgdef);
for (upb_msg_field_begin(&it, self->msgdef); for (int i = 0; i < n; i++) {
!upb_msg_field_done(&it); const upb_FieldDef* field = upb_MessageDef_Field(self->msgdef, i);
upb_msg_field_next(&it)) {
const upb_fielddef* field = upb_msg_iter_field(&it);
VALUE obj = get_fielddef_obj(self->descriptor_pool, field); VALUE obj = get_fielddef_obj(self->descriptor_pool, field);
rb_yield(obj); rb_yield(obj);
} }
@ -339,7 +337,7 @@ static VALUE Descriptor_each(VALUE _self) {
static VALUE Descriptor_lookup(VALUE _self, VALUE name) { static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
Descriptor* self = ruby_to_Descriptor(_self); Descriptor* self = ruby_to_Descriptor(_self);
const char* s = get_str(name); const char* s = get_str(name);
const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s); const upb_FieldDef* field = upb_MessageDef_FindFieldByName(self->msgdef, s);
if (field == NULL) { if (field == NULL) {
return Qnil; return Qnil;
} }
@ -356,11 +354,9 @@ static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
static VALUE Descriptor_each_oneof(VALUE _self) { static VALUE Descriptor_each_oneof(VALUE _self) {
Descriptor* self = ruby_to_Descriptor(_self); Descriptor* self = ruby_to_Descriptor(_self);
upb_msg_oneof_iter it; int n = upb_MessageDef_OneofCount(self->msgdef);
for (upb_msg_oneof_begin(&it, self->msgdef); for (int i = 0; i < n; i++) {
!upb_msg_oneof_done(&it); const upb_OneofDef* oneof = upb_MessageDef_Oneof(self->msgdef, i);
upb_msg_oneof_next(&it)) {
const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof); VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof);
rb_yield(obj); rb_yield(obj);
} }
@ -377,7 +373,7 @@ static VALUE Descriptor_each_oneof(VALUE _self) {
static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) { static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
Descriptor* self = ruby_to_Descriptor(_self); Descriptor* self = ruby_to_Descriptor(_self);
const char* s = get_str(name); const char* s = get_str(name);
const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s); const upb_OneofDef* oneof = upb_MessageDef_FindOneofByName(self->msgdef, s);
if (oneof == NULL) { if (oneof == NULL) {
return Qnil; return Qnil;
} }
@ -399,8 +395,7 @@ static VALUE Descriptor_msgclass(VALUE _self) {
} }
static void Descriptor_register(VALUE module) { static void Descriptor_register(VALUE module) {
VALUE klass = rb_define_class_under( VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
module, "Descriptor", rb_cObject);
rb_define_alloc_func(klass, Descriptor_alloc); rb_define_alloc_func(klass, Descriptor_alloc);
rb_define_method(klass, "initialize", Descriptor_initialize, 3); rb_define_method(klass, "initialize", Descriptor_initialize, 3);
rb_define_method(klass, "each", Descriptor_each, 0); rb_define_method(klass, "each", Descriptor_each, 0);
@ -420,8 +415,8 @@ static void Descriptor_register(VALUE module) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef struct { typedef struct {
const upb_filedef* filedef; const upb_FileDef* filedef;
VALUE descriptor_pool; // Owns the upb_filedef. VALUE descriptor_pool; // Owns the upb_FileDef.
} FileDescriptor; } FileDescriptor;
static VALUE cFileDescriptor = Qnil; static VALUE cFileDescriptor = Qnil;
@ -432,9 +427,9 @@ static void FileDescriptor_mark(void* _self) {
} }
static const rb_data_type_t FileDescriptor_type = { static const rb_data_type_t FileDescriptor_type = {
"Google::Protobuf::FileDescriptor", "Google::Protobuf::FileDescriptor",
{FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
.flags = RUBY_TYPED_FREE_IMMEDIATELY, .flags = RUBY_TYPED_FREE_IMMEDIATELY,
}; };
static FileDescriptor* ruby_to_FileDescriptor(VALUE val) { static FileDescriptor* ruby_to_FileDescriptor(VALUE val) {
@ -459,7 +454,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
* to a builder. * to a builder.
*/ */
static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie, static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
VALUE descriptor_pool, VALUE ptr) { VALUE descriptor_pool, VALUE ptr) {
FileDescriptor* self = ruby_to_FileDescriptor(_self); FileDescriptor* self = ruby_to_FileDescriptor(_self);
if (cookie != c_only_cookie) { if (cookie != c_only_cookie) {
@ -468,7 +463,7 @@ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
} }
self->descriptor_pool = descriptor_pool; self->descriptor_pool = descriptor_pool;
self->filedef = (const upb_filedef*)NUM2ULL(ptr); self->filedef = (const upb_FileDef*)NUM2ULL(ptr);
return Qnil; return Qnil;
} }
@ -481,7 +476,7 @@ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
*/ */
static VALUE FileDescriptor_name(VALUE _self) { static VALUE FileDescriptor_name(VALUE _self) {
FileDescriptor* self = ruby_to_FileDescriptor(_self); FileDescriptor* self = ruby_to_FileDescriptor(_self);
const char* name = upb_filedef_name(self->filedef); const char* name = upb_FileDef_Name(self->filedef);
return name == NULL ? Qnil : rb_str_new2(name); return name == NULL ? Qnil : rb_str_new2(name);
} }
@ -497,16 +492,18 @@ static VALUE FileDescriptor_name(VALUE _self) {
static VALUE FileDescriptor_syntax(VALUE _self) { static VALUE FileDescriptor_syntax(VALUE _self) {
FileDescriptor* self = ruby_to_FileDescriptor(_self); FileDescriptor* self = ruby_to_FileDescriptor(_self);
switch (upb_filedef_syntax(self->filedef)) { switch (upb_FileDef_Syntax(self->filedef)) {
case UPB_SYNTAX_PROTO3: return ID2SYM(rb_intern("proto3")); case kUpb_Syntax_Proto3:
case UPB_SYNTAX_PROTO2: return ID2SYM(rb_intern("proto2")); return ID2SYM(rb_intern("proto3"));
default: return Qnil; case kUpb_Syntax_Proto2:
return ID2SYM(rb_intern("proto2"));
default:
return Qnil;
} }
} }
static void FileDescriptor_register(VALUE module) { static void FileDescriptor_register(VALUE module) {
VALUE klass = rb_define_class_under( VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject);
module, "FileDescriptor", rb_cObject);
rb_define_alloc_func(klass, FileDescriptor_alloc); rb_define_alloc_func(klass, FileDescriptor_alloc);
rb_define_method(klass, "initialize", FileDescriptor_initialize, 3); rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
rb_define_method(klass, "name", FileDescriptor_name, 0); rb_define_method(klass, "name", FileDescriptor_name, 0);
@ -520,8 +517,8 @@ static void FileDescriptor_register(VALUE module) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef struct { typedef struct {
const upb_fielddef* fielddef; const upb_FieldDef* fielddef;
VALUE descriptor_pool; // Owns the upb_fielddef. VALUE descriptor_pool; // Owns the upb_FieldDef.
} FieldDescriptor; } FieldDescriptor;
static VALUE cFieldDescriptor = Qnil; static VALUE cFieldDescriptor = Qnil;
@ -532,9 +529,9 @@ static void FieldDescriptor_mark(void* _self) {
} }
static const rb_data_type_t FieldDescriptor_type = { static const rb_data_type_t FieldDescriptor_type = {
"Google::Protobuf::FieldDescriptor", "Google::Protobuf::FieldDescriptor",
{FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
.flags = RUBY_TYPED_FREE_IMMEDIATELY, .flags = RUBY_TYPED_FREE_IMMEDIATELY,
}; };
static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) { static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) {
@ -573,7 +570,7 @@ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
} }
self->descriptor_pool = descriptor_pool; self->descriptor_pool = descriptor_pool;
self->fielddef = (const upb_fielddef*)NUM2ULL(ptr); self->fielddef = (const upb_FieldDef*)NUM2ULL(ptr);
return Qnil; return Qnil;
} }
@ -586,31 +583,31 @@ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
*/ */
static VALUE FieldDescriptor_name(VALUE _self) { static VALUE FieldDescriptor_name(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
return rb_str_maybe_null(upb_fielddef_name(self->fielddef)); return rb_str_maybe_null(upb_FieldDef_Name(self->fielddef));
} }
// Non-static, exposed to other .c files. // Non-static, exposed to other .c files.
upb_fieldtype_t ruby_to_fieldtype(VALUE type) { upb_CType ruby_to_fieldtype(VALUE type) {
if (TYPE(type) != T_SYMBOL) { if (TYPE(type) != T_SYMBOL) {
rb_raise(rb_eArgError, "Expected symbol for field type."); rb_raise(rb_eArgError, "Expected symbol for field type.");
} }
#define CONVERT(upb, ruby) \ #define CONVERT(upb, ruby) \
if (SYM2ID(type) == rb_intern( # ruby )) { \ if (SYM2ID(type) == rb_intern(#ruby)) { \
return UPB_TYPE_ ## upb; \ return kUpb_CType_##upb; \
} }
CONVERT(FLOAT, float); CONVERT(Float, float);
CONVERT(DOUBLE, double); CONVERT(Double, double);
CONVERT(BOOL, bool); CONVERT(Bool, bool);
CONVERT(STRING, string); CONVERT(String, string);
CONVERT(BYTES, bytes); CONVERT(Bytes, bytes);
CONVERT(MESSAGE, message); CONVERT(Message, message);
CONVERT(ENUM, enum); CONVERT(Enum, enum);
CONVERT(INT32, int32); CONVERT(Int32, int32);
CONVERT(INT64, int64); CONVERT(Int64, int64);
CONVERT(UINT32, uint32); CONVERT(UInt32, uint32);
CONVERT(UINT64, uint64); CONVERT(UInt64, uint64);
#undef CONVERT #undef CONVERT
@ -618,28 +615,29 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
return 0; return 0;
} }
static VALUE descriptortype_to_ruby(upb_descriptortype_t type) { static VALUE descriptortype_to_ruby(upb_FieldType type) {
switch (type) { switch (type) {
#define CONVERT(upb, ruby) \ #define CONVERT(upb, ruby) \
case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby )); case kUpb_FieldType_##upb: \
CONVERT(FLOAT, float); return ID2SYM(rb_intern(#ruby));
CONVERT(DOUBLE, double); CONVERT(Float, float);
CONVERT(BOOL, bool); CONVERT(Double, double);
CONVERT(STRING, string); CONVERT(Bool, bool);
CONVERT(BYTES, bytes); CONVERT(String, string);
CONVERT(MESSAGE, message); CONVERT(Bytes, bytes);
CONVERT(GROUP, group); CONVERT(Message, message);
CONVERT(ENUM, enum); CONVERT(Group, group);
CONVERT(INT32, int32); CONVERT(Enum, enum);
CONVERT(INT64, int64); CONVERT(Int32, int32);
CONVERT(UINT32, uint32); CONVERT(Int64, int64);
CONVERT(UINT64, uint64); CONVERT(UInt32, uint32);
CONVERT(SINT32, sint32); CONVERT(UInt64, uint64);
CONVERT(SINT64, sint64); CONVERT(SInt32, sint32);
CONVERT(FIXED32, fixed32); CONVERT(SInt64, sint64);
CONVERT(FIXED64, fixed64); CONVERT(Fixed32, fixed32);
CONVERT(SFIXED32, sfixed32); CONVERT(Fixed64, fixed64);
CONVERT(SFIXED64, sfixed64); CONVERT(SFixed32, sfixed32);
CONVERT(SFixed64, sfixed64);
#undef CONVERT #undef CONVERT
} }
return Qnil; return Qnil;
@ -657,7 +655,7 @@ static VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
*/ */
static VALUE FieldDescriptor__type(VALUE _self) { static VALUE FieldDescriptor__type(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef)); return descriptortype_to_ruby(upb_FieldDef_Type(self->fielddef));
} }
/* /*
@ -668,17 +666,16 @@ static VALUE FieldDescriptor__type(VALUE _self) {
*/ */
static VALUE FieldDescriptor_default(VALUE _self) { static VALUE FieldDescriptor_default(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_fielddef *f = self->fielddef; const upb_FieldDef* f = self->fielddef;
upb_msgval default_val = {0}; upb_MessageValue default_val = {0};
if (upb_fielddef_issubmsg(f)) { if (upb_FieldDef_IsSubMessage(f)) {
return Qnil; return Qnil;
} else if (!upb_fielddef_isseq(f)) { } else if (!upb_FieldDef_IsRepeated(f)) {
default_val = upb_fielddef_default(f); default_val = upb_FieldDef_Default(f);
} }
return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil); return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
} }
/* /*
* call-seq: * call-seq:
* FieldDescriptor.json_name => json_name * FieldDescriptor.json_name => json_name
@ -687,8 +684,8 @@ static VALUE FieldDescriptor_default(VALUE _self) {
*/ */
static VALUE FieldDescriptor_json_name(VALUE _self) { static VALUE FieldDescriptor_json_name(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_fielddef *f = self->fielddef; const upb_FieldDef* f = self->fielddef;
const char *json_name = upb_fielddef_jsonname(f); const char* json_name = upb_FieldDef_JsonName(f);
return rb_str_new2(json_name); return rb_str_new2(json_name);
} }
@ -703,13 +700,14 @@ static VALUE FieldDescriptor_json_name(VALUE _self) {
*/ */
static VALUE FieldDescriptor_label(VALUE _self) { static VALUE FieldDescriptor_label(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
switch (upb_fielddef_label(self->fielddef)) { switch (upb_FieldDef_Label(self->fielddef)) {
#define CONVERT(upb, ruby) \ #define CONVERT(upb, ruby) \
case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby )); case kUpb_Label_##upb: \
return ID2SYM(rb_intern(#ruby));
CONVERT(OPTIONAL, optional); CONVERT(Optional, optional);
CONVERT(REQUIRED, required); CONVERT(Required, required);
CONVERT(REPEATED, repeated); CONVERT(Repeated, repeated);
#undef CONVERT #undef CONVERT
} }
@ -725,7 +723,7 @@ static VALUE FieldDescriptor_label(VALUE _self) {
*/ */
static VALUE FieldDescriptor_number(VALUE _self) { static VALUE FieldDescriptor_number(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
return INT2NUM(upb_fielddef_number(self->fielddef)); return INT2NUM(upb_FieldDef_Number(self->fielddef));
} }
/* /*
@ -739,13 +737,13 @@ static VALUE FieldDescriptor_number(VALUE _self) {
*/ */
static VALUE FieldDescriptor_submsg_name(VALUE _self) { static VALUE FieldDescriptor_submsg_name(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
switch (upb_fielddef_type(self->fielddef)) { switch (upb_FieldDef_CType(self->fielddef)) {
case UPB_TYPE_ENUM: case kUpb_CType_Enum:
return rb_str_new2( return rb_str_new2(
upb_enumdef_fullname(upb_fielddef_enumsubdef(self->fielddef))); upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(self->fielddef)));
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
return rb_str_new2( return rb_str_new2(
upb_msgdef_fullname(upb_fielddef_msgsubdef(self->fielddef))); upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(self->fielddef)));
default: default:
return Qnil; return Qnil;
} }
@ -762,13 +760,13 @@ static VALUE FieldDescriptor_submsg_name(VALUE _self) {
*/ */
static VALUE FieldDescriptor_subtype(VALUE _self) { static VALUE FieldDescriptor_subtype(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
switch (upb_fielddef_type(self->fielddef)) { switch (upb_FieldDef_CType(self->fielddef)) {
case UPB_TYPE_ENUM: case kUpb_CType_Enum:
return get_enumdef_obj(self->descriptor_pool, return get_enumdef_obj(self->descriptor_pool,
upb_fielddef_enumsubdef(self->fielddef)); upb_FieldDef_EnumSubDef(self->fielddef));
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
return get_msgdef_obj(self->descriptor_pool, return get_msgdef_obj(self->descriptor_pool,
upb_fielddef_msgsubdef(self->fielddef)); upb_FieldDef_MessageSubDef(self->fielddef));
default: default:
return Qnil; return Qnil;
} }
@ -783,11 +781,11 @@ static VALUE FieldDescriptor_subtype(VALUE _self) {
*/ */
static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) { static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_msgdef *m; const upb_MessageDef* m;
Message_Get(msg_rb, &m); Message_Get(msg_rb, &m);
if (m != upb_fielddef_containingtype(self->fielddef)) { if (m != upb_FieldDef_ContainingType(self->fielddef)) {
rb_raise(cTypeError, "get method called on wrong message type"); rb_raise(cTypeError, "get method called on wrong message type");
} }
@ -803,16 +801,16 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
*/ */
static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) { static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_msgdef *m; const upb_MessageDef* m;
const upb_msgdef *msg = Message_Get(msg_rb, &m); const upb_MessageDef* msg = Message_Get(msg_rb, &m);
if (m != upb_fielddef_containingtype(self->fielddef)) { if (m != upb_FieldDef_ContainingType(self->fielddef)) {
rb_raise(cTypeError, "has method called on wrong message type"); rb_raise(cTypeError, "has method called on wrong message type");
} else if (!upb_fielddef_haspresence(self->fielddef)) { } else if (!upb_FieldDef_HasPresence(self->fielddef)) {
rb_raise(rb_eArgError, "does not track presence"); rb_raise(rb_eArgError, "does not track presence");
} }
return upb_msg_has(msg, self->fielddef) ? Qtrue : Qfalse; return upb_Message_Has(msg, self->fielddef) ? Qtrue : Qfalse;
} }
/* /*
@ -823,14 +821,14 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
*/ */
static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) { static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_msgdef *m; const upb_MessageDef* m;
upb_msgdef *msg = Message_GetMutable(msg_rb, &m); upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
if (m != upb_fielddef_containingtype(self->fielddef)) { if (m != upb_FieldDef_ContainingType(self->fielddef)) {
rb_raise(cTypeError, "has method called on wrong message type"); rb_raise(cTypeError, "has method called on wrong message type");
} }
upb_msg_clearfield(msg, self->fielddef); upb_Message_ClearField(msg, self->fielddef);
return Qnil; return Qnil;
} }
@ -844,24 +842,23 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
*/ */
static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) { static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self); FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_msgdef *m; const upb_MessageDef* m;
upb_msgdef *msg = Message_GetMutable(msg_rb, &m); upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
upb_arena *arena = Arena_get(Message_GetArena(msg_rb)); upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
upb_msgval msgval; upb_MessageValue msgval;
if (m != upb_fielddef_containingtype(self->fielddef)) { if (m != upb_FieldDef_ContainingType(self->fielddef)) {
rb_raise(cTypeError, "set method called on wrong message type"); rb_raise(cTypeError, "set method called on wrong message type");
} }
msgval = Convert_RubyToUpb(value, upb_fielddef_name(self->fielddef), msgval = Convert_RubyToUpb(value, upb_FieldDef_Name(self->fielddef),
TypeInfo_get(self->fielddef), arena); TypeInfo_get(self->fielddef), arena);
upb_msg_set(msg, self->fielddef, msgval, arena); upb_Message_Set(msg, self->fielddef, msgval, arena);
return Qnil; return Qnil;
} }
static void FieldDescriptor_register(VALUE module) { static void FieldDescriptor_register(VALUE module) {
VALUE klass = rb_define_class_under( VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
module, "FieldDescriptor", rb_cObject);
rb_define_alloc_func(klass, FieldDescriptor_alloc); rb_define_alloc_func(klass, FieldDescriptor_alloc);
rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3); rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
rb_define_method(klass, "name", FieldDescriptor_name, 0); rb_define_method(klass, "name", FieldDescriptor_name, 0);
@ -885,8 +882,8 @@ static void FieldDescriptor_register(VALUE module) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef struct { typedef struct {
const upb_oneofdef* oneofdef; const upb_OneofDef* oneofdef;
VALUE descriptor_pool; // Owns the upb_oneofdef. VALUE descriptor_pool; // Owns the upb_OneofDef.
} OneofDescriptor; } OneofDescriptor;
static VALUE cOneofDescriptor = Qnil; static VALUE cOneofDescriptor = Qnil;
@ -930,7 +927,7 @@ static VALUE OneofDescriptor_alloc(VALUE klass) {
* Creates a descriptor wrapper object. May only be called from C. * Creates a descriptor wrapper object. May only be called from C.
*/ */
static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie, static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
VALUE descriptor_pool, VALUE ptr) { VALUE descriptor_pool, VALUE ptr) {
OneofDescriptor* self = ruby_to_OneofDescriptor(_self); OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
if (cookie != c_only_cookie) { if (cookie != c_only_cookie) {
@ -939,7 +936,7 @@ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
} }
self->descriptor_pool = descriptor_pool; self->descriptor_pool = descriptor_pool;
self->oneofdef = (const upb_oneofdef*)NUM2ULL(ptr); self->oneofdef = (const upb_OneofDef*)NUM2ULL(ptr);
return Qnil; return Qnil;
} }
@ -952,7 +949,7 @@ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
*/ */
static VALUE OneofDescriptor_name(VALUE _self) { static VALUE OneofDescriptor_name(VALUE _self) {
OneofDescriptor* self = ruby_to_OneofDescriptor(_self); OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef)); return rb_str_maybe_null(upb_OneofDef_Name(self->oneofdef));
} }
/* /*
@ -963,11 +960,10 @@ static VALUE OneofDescriptor_name(VALUE _self) {
*/ */
static VALUE OneofDescriptor_each(VALUE _self) { static VALUE OneofDescriptor_each(VALUE _self) {
OneofDescriptor* self = ruby_to_OneofDescriptor(_self); OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
upb_oneof_iter it;
for (upb_oneof_begin(&it, self->oneofdef); int n = upb_OneofDef_FieldCount(self->oneofdef);
!upb_oneof_done(&it); for (int i = 0; i < n; i++) {
upb_oneof_next(&it)) { const upb_FieldDef* f = upb_OneofDef_Field(self->oneofdef, i);
const upb_fielddef* f = upb_oneof_iter_field(&it);
VALUE obj = get_fielddef_obj(self->descriptor_pool, f); VALUE obj = get_fielddef_obj(self->descriptor_pool, f);
rb_yield(obj); rb_yield(obj);
} }
@ -975,8 +971,7 @@ static VALUE OneofDescriptor_each(VALUE _self) {
} }
static void OneofDescriptor_register(VALUE module) { static void OneofDescriptor_register(VALUE module) {
VALUE klass = rb_define_class_under( VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
module, "OneofDescriptor", rb_cObject);
rb_define_alloc_func(klass, OneofDescriptor_alloc); rb_define_alloc_func(klass, OneofDescriptor_alloc);
rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3); rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
rb_define_method(klass, "name", OneofDescriptor_name, 0); rb_define_method(klass, "name", OneofDescriptor_name, 0);
@ -991,9 +986,9 @@ static void OneofDescriptor_register(VALUE module) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef struct { typedef struct {
const upb_enumdef* enumdef; const upb_EnumDef* enumdef;
VALUE module; // begins as nil VALUE module; // begins as nil
VALUE descriptor_pool; // Owns the upb_enumdef. VALUE descriptor_pool; // Owns the upb_EnumDef.
} EnumDescriptor; } EnumDescriptor;
static VALUE cEnumDescriptor = Qnil; static VALUE cEnumDescriptor = Qnil;
@ -1005,9 +1000,9 @@ static void EnumDescriptor_mark(void* _self) {
} }
static const rb_data_type_t EnumDescriptor_type = { static const rb_data_type_t EnumDescriptor_type = {
"Google::Protobuf::EnumDescriptor", "Google::Protobuf::EnumDescriptor",
{EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
.flags = RUBY_TYPED_FREE_IMMEDIATELY, .flags = RUBY_TYPED_FREE_IMMEDIATELY,
}; };
static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) { static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) {
@ -1026,8 +1021,8 @@ static VALUE EnumDescriptor_alloc(VALUE klass) {
} }
// Exposed to other modules in defs.h. // Exposed to other modules in defs.h.
const upb_enumdef *EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) { const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) {
EnumDescriptor *desc = ruby_to_EnumDescriptor(enum_desc_rb); EnumDescriptor* desc = ruby_to_EnumDescriptor(enum_desc_rb);
return desc->enumdef; return desc->enumdef;
} }
@ -1047,7 +1042,7 @@ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
} }
self->descriptor_pool = descriptor_pool; self->descriptor_pool = descriptor_pool;
self->enumdef = (const upb_enumdef*)NUM2ULL(ptr); self->enumdef = (const upb_EnumDef*)NUM2ULL(ptr);
return Qnil; return Qnil;
} }
@ -1061,7 +1056,7 @@ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
static VALUE EnumDescriptor_file_descriptor(VALUE _self) { static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
EnumDescriptor* self = ruby_to_EnumDescriptor(_self); EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
return get_filedef_obj(self->descriptor_pool, return get_filedef_obj(self->descriptor_pool,
upb_enumdef_file(self->enumdef)); upb_EnumDef_File(self->enumdef));
} }
/* /*
@ -1072,7 +1067,7 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
*/ */
static VALUE EnumDescriptor_name(VALUE _self) { static VALUE EnumDescriptor_name(VALUE _self) {
EnumDescriptor* self = ruby_to_EnumDescriptor(_self); EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef)); return rb_str_maybe_null(upb_EnumDef_FullName(self->enumdef));
} }
/* /*
@ -1084,10 +1079,11 @@ static VALUE EnumDescriptor_name(VALUE _self) {
*/ */
static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) { static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
EnumDescriptor* self = ruby_to_EnumDescriptor(_self); EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
const char* name_str= rb_id2name(SYM2ID(name)); const char* name_str = rb_id2name(SYM2ID(name));
int32_t val = 0; const upb_EnumValueDef *ev =
if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) { upb_EnumDef_FindValueByName(self->enumdef, name_str);
return INT2NUM(val); if (ev) {
return INT2NUM(upb_EnumValueDef_Number(ev));
} else { } else {
return Qnil; return Qnil;
} }
@ -1103,9 +1099,9 @@ static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) { static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
EnumDescriptor* self = ruby_to_EnumDescriptor(_self); EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
int32_t val = NUM2INT(number); int32_t val = NUM2INT(number);
const char* name = upb_enumdef_iton(self->enumdef, val); const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(self->enumdef, val);
if (name != NULL) { if (ev) {
return ID2SYM(rb_intern(name)); return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
} else { } else {
return Qnil; return Qnil;
} }
@ -1121,12 +1117,11 @@ static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
static VALUE EnumDescriptor_each(VALUE _self) { static VALUE EnumDescriptor_each(VALUE _self) {
EnumDescriptor* self = ruby_to_EnumDescriptor(_self); EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
upb_enum_iter it; int n = upb_EnumDef_ValueCount(self->enumdef);
for (upb_enum_begin(&it, self->enumdef); for (int i = 0; i < n; i++) {
!upb_enum_done(&it); const upb_EnumValueDef* ev = upb_EnumDef_Value(self->enumdef, i);
upb_enum_next(&it)) { VALUE key = ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it))); VALUE number = INT2NUM(upb_EnumValueDef_Number(ev));
VALUE number = INT2NUM(upb_enum_iter_number(&it));
rb_yield_values(2, key, number); rb_yield_values(2, key, number);
} }
@ -1148,8 +1143,7 @@ static VALUE EnumDescriptor_enummodule(VALUE _self) {
} }
static void EnumDescriptor_register(VALUE module) { static void EnumDescriptor_register(VALUE module) {
VALUE klass = rb_define_class_under( VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
module, "EnumDescriptor", rb_cObject);
rb_define_alloc_func(klass, EnumDescriptor_alloc); rb_define_alloc_func(klass, EnumDescriptor_alloc);
rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3); rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
rb_define_method(klass, "name", EnumDescriptor_name, 0); rb_define_method(klass, "name", EnumDescriptor_name, 0);
@ -1176,7 +1170,7 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
if (def == Qnil) { if (def == Qnil) {
// Lazily create wrapper object. // Lazily create wrapper object.
VALUE args[3] = { c_only_cookie, _descriptor_pool, key }; VALUE args[3] = {c_only_cookie, _descriptor_pool, key};
def = rb_class_new_instance(3, args, klass); def = rb_class_new_instance(3, args, klass);
rb_hash_aset(descriptor_pool->def_to_descriptor, key, def); rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
} }
@ -1184,23 +1178,23 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
return def; return def;
} }
static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) { static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def) {
return get_def_obj(descriptor_pool, def, cDescriptor); return get_def_obj(descriptor_pool, def, cDescriptor);
} }
static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) { static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def) {
return get_def_obj(descriptor_pool, def, cEnumDescriptor); return get_def_obj(descriptor_pool, def, cEnumDescriptor);
} }
static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) { static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def) {
return get_def_obj(descriptor_pool, def, cFieldDescriptor); return get_def_obj(descriptor_pool, def, cFieldDescriptor);
} }
static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) { static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def) {
return get_def_obj(descriptor_pool, def, cFileDescriptor); return get_def_obj(descriptor_pool, def, cFileDescriptor);
} }
static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) { static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
return get_def_obj(descriptor_pool, def, cOneofDescriptor); return get_def_obj(descriptor_pool, def, cOneofDescriptor);
} }
@ -1210,8 +1204,8 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
// Functions exposed to other modules in defs.h. // Functions exposed to other modules in defs.h.
VALUE Descriptor_DefToClass(const upb_msgdef *m) { VALUE Descriptor_DefToClass(const upb_MessageDef* m) {
const upb_symtab *symtab = upb_filedef_symtab(upb_msgdef_file(m)); const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m));
VALUE pool = ObjectCache_Get(symtab); VALUE pool = ObjectCache_Get(symtab);
PBRUBY_ASSERT(pool != Qnil); PBRUBY_ASSERT(pool != Qnil);
VALUE desc_rb = get_msgdef_obj(pool, m); VALUE desc_rb = get_msgdef_obj(pool, m);
@ -1219,15 +1213,16 @@ VALUE Descriptor_DefToClass(const upb_msgdef *m) {
return desc->klass; return desc->klass;
} }
const upb_msgdef *Descriptor_GetMsgDef(VALUE desc_rb) { const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb) {
const Descriptor* desc = ruby_to_Descriptor(desc_rb); const Descriptor* desc = ruby_to_Descriptor(desc_rb);
return desc->msgdef; return desc->msgdef;
} }
VALUE TypeInfo_InitArg(int argc, VALUE *argv, int skip_arg) { VALUE TypeInfo_InitArg(int argc, VALUE* argv, int skip_arg) {
if (argc > skip_arg) { if (argc > skip_arg) {
if (argc > 1 + skip_arg) { if (argc > 1 + skip_arg) {
rb_raise(rb_eArgError, "Expected a maximum of %d arguments.", skip_arg + 1); rb_raise(rb_eArgError, "Expected a maximum of %d arguments.",
skip_arg + 1);
} }
return argv[skip_arg]; return argv[skip_arg];
} else { } else {
@ -1239,7 +1234,7 @@ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
VALUE* type_class, VALUE* init_arg) { VALUE* type_class, VALUE* init_arg) {
TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])}; TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])};
if (ret.type == UPB_TYPE_MESSAGE || ret.type == UPB_TYPE_ENUM) { if (ret.type == kUpb_CType_Message || ret.type == kUpb_CType_Enum) {
*init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2); *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2);
if (argc < 2 + skip_arg) { if (argc < 2 + skip_arg) {
@ -1257,11 +1252,11 @@ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
"class or enum as returned by the DescriptorPool."); "class or enum as returned by the DescriptorPool.");
} }
if (ret.type == UPB_TYPE_MESSAGE) { if (ret.type == kUpb_CType_Message) {
ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef; ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef;
Message_CheckClass(klass); Message_CheckClass(klass);
} else { } else {
PBRUBY_ASSERT(ret.type == UPB_TYPE_ENUM); PBRUBY_ASSERT(ret.type == kUpb_CType_Enum);
ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef; ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef;
} }
} else { } else {

@ -40,9 +40,9 @@
// TypeInfo // TypeInfo
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// This bundles a upb_fieldtype_t and msgdef/enumdef when appropriate. This is // This bundles a upb_CType and msgdef/enumdef when appropriate. This is
// convenient for functions that need type information but cannot necessarily // convenient for functions that need type information but cannot necessarily
// assume a upb_fielddef will be available. // assume a upb_FieldDef will be available.
// //
// For example, Google::Protobuf::Map and Google::Protobuf::RepeatedField can // For example, Google::Protobuf::Map and Google::Protobuf::RepeatedField can
// be constructed with type information alone: // be constructed with type information alone:
@ -51,21 +51,21 @@
// Google::Protobuf::RepeatedField.new(:message, FooMessage) // Google::Protobuf::RepeatedField.new(:message, FooMessage)
typedef struct { typedef struct {
upb_fieldtype_t type; upb_CType type;
union { union {
const upb_msgdef* msgdef; // When type == UPB_TYPE_MESSAGE const upb_MessageDef* msgdef; // When type == kUpb_CType_Message
const upb_enumdef* enumdef; // When type == UPB_TYPE_ENUM const upb_EnumDef* enumdef; // When type == kUpb_CType_Enum
} def; } def;
} TypeInfo; } TypeInfo;
static inline TypeInfo TypeInfo_get(const upb_fielddef *f) { static inline TypeInfo TypeInfo_get(const upb_FieldDef* f) {
TypeInfo ret = {upb_fielddef_type(f), {NULL}}; TypeInfo ret = {upb_FieldDef_CType(f), {NULL}};
switch (ret.type) { switch (ret.type) {
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
ret.def.msgdef = upb_fielddef_msgsubdef(f); ret.def.msgdef = upb_FieldDef_MessageSubDef(f);
break; break;
case UPB_TYPE_ENUM: case kUpb_CType_Enum:
ret.def.enumdef = upb_fielddef_enumsubdef(f); ret.def.enumdef = upb_FieldDef_EnumSubDef(f);
break; break;
default: default:
break; break;
@ -76,9 +76,9 @@ static inline TypeInfo TypeInfo_get(const upb_fielddef *f) {
TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg, TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
VALUE* type_class, VALUE* init_arg); VALUE* type_class, VALUE* init_arg);
static inline TypeInfo TypeInfo_from_type(upb_fieldtype_t type) { static inline TypeInfo TypeInfo_from_type(upb_CType type) {
TypeInfo ret = {type}; TypeInfo ret = {type};
assert(type != UPB_TYPE_MESSAGE && type != UPB_TYPE_ENUM); assert(type != kUpb_CType_Message && type != kUpb_CType_Enum);
return ret; return ret;
} }
@ -86,17 +86,17 @@ static inline TypeInfo TypeInfo_from_type(upb_fieldtype_t type) {
// Other utilities // Other utilities
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
VALUE Descriptor_DefToClass(const upb_msgdef *m); VALUE Descriptor_DefToClass(const upb_MessageDef* m);
// Returns the underlying msgdef, enumdef, or symtab (respectively) for the // Returns the underlying msgdef, enumdef, or symtab (respectively) for the
// given Descriptor, EnumDescriptor, or DescriptorPool Ruby object. // given Descriptor, EnumDescriptor, or DescriptorPool Ruby object.
const upb_enumdef *EnumDescriptor_GetEnumDef(VALUE enum_desc_rb); const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb);
const upb_symtab *DescriptorPool_GetSymtab(VALUE desc_pool_rb); const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb);
const upb_msgdef *Descriptor_GetMsgDef(VALUE desc_rb); const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb);
// Returns a upb field type for the given Ruby symbol // Returns a upb field type for the given Ruby symbol
// (eg. :float => UPB_TYPE_FLOAT). // (eg. :float => kUpb_CType_Float).
upb_fieldtype_t ruby_to_fieldtype(VALUE type); upb_CType ruby_to_fieldtype(VALUE type);
// The singleton generated pool (a DescriptorPool object). // The singleton generated pool (a DescriptorPool object).
extern VALUE generated_pool; extern VALUE generated_pool;

@ -34,7 +34,7 @@
#include "protobuf.h" #include "protobuf.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Basic map operations on top of upb_map. // Basic map operations on top of upb_Map.
// //
// Note that we roll our own `Map` container here because, as for // Note that we roll our own `Map` container here because, as for
// `RepeatedField`, we want a strongly-typed container. This is so that any user // `RepeatedField`, we want a strongly-typed container. This is so that any user
@ -48,8 +48,8 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef struct { typedef struct {
const upb_map *map; // Can convert to mutable when non-frozen. const upb_Map* map; // Can convert to mutable when non-frozen.
upb_fieldtype_t key_type; upb_CType key_type;
TypeInfo value_type_info; TypeInfo value_type_info;
VALUE value_type_class; VALUE value_type_class;
VALUE arena; VALUE arena;
@ -62,9 +62,9 @@ static void Map_mark(void* _self) {
} }
const rb_data_type_t Map_type = { const rb_data_type_t Map_type = {
"Google::Protobuf::Map", "Google::Protobuf::Map",
{ Map_mark, RUBY_DEFAULT_FREE, NULL }, {Map_mark, RUBY_DEFAULT_FREE, NULL},
.flags = RUBY_TYPED_FREE_IMMEDIATELY, .flags = RUBY_TYPED_FREE_IMMEDIATELY,
}; };
VALUE cMap; VALUE cMap;
@ -84,8 +84,8 @@ static VALUE Map_alloc(VALUE klass) {
return TypedData_Wrap_Struct(klass, &Map_type, self); return TypedData_Wrap_Struct(klass, &Map_type, self);
} }
VALUE Map_GetRubyWrapper(upb_map* map, upb_fieldtype_t key_type, VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type, TypeInfo value_type,
TypeInfo value_type, VALUE arena) { VALUE arena) {
PBRUBY_ASSERT(map); PBRUBY_ASSERT(map);
VALUE val = ObjectCache_Get(map); VALUE val = ObjectCache_Get(map);
@ -99,8 +99,8 @@ VALUE Map_GetRubyWrapper(upb_map* map, upb_fieldtype_t key_type,
self->arena = arena; self->arena = arena;
self->key_type = key_type; self->key_type = key_type;
self->value_type_info = value_type; self->value_type_info = value_type;
if (self->value_type_info.type == UPB_TYPE_MESSAGE) { if (self->value_type_info.type == kUpb_CType_Message) {
const upb_msgdef *val_m = self->value_type_info.def.msgdef; const upb_MessageDef* val_m = self->value_type_info.def.msgdef;
self->value_type_class = Descriptor_DefToClass(val_m); self->value_type_class = Descriptor_DefToClass(val_m);
} }
} }
@ -108,9 +108,9 @@ VALUE Map_GetRubyWrapper(upb_map* map, upb_fieldtype_t key_type,
return val; return val;
} }
static VALUE Map_new_this_type(Map *from) { static VALUE Map_new_this_type(Map* from) {
VALUE arena_rb = Arena_new(); VALUE arena_rb = Arena_new();
upb_map* map = upb_map_new(Arena_get(arena_rb), from->key_type, upb_Map* map = upb_Map_New(Arena_get(arena_rb), from->key_type,
from->value_type_info.type); from->value_type_info.type);
VALUE ret = VALUE ret =
Map_GetRubyWrapper(map, from->key_type, from->value_type_info, arena_rb); Map_GetRubyWrapper(map, from->key_type, from->value_type_info, arena_rb);
@ -125,22 +125,22 @@ static TypeInfo Map_keyinfo(Map* self) {
return ret; return ret;
} }
static upb_map *Map_GetMutable(VALUE _self) { static upb_Map* Map_GetMutable(VALUE _self) {
rb_check_frozen(_self); rb_check_frozen(_self);
return (upb_map*)ruby_to_Map(_self)->map; return (upb_Map*)ruby_to_Map(_self)->map;
} }
VALUE Map_CreateHash(const upb_map* map, upb_fieldtype_t key_type, VALUE Map_CreateHash(const upb_Map* map, upb_CType key_type,
TypeInfo val_info) { TypeInfo val_info) {
VALUE hash = rb_hash_new(); VALUE hash = rb_hash_new();
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
TypeInfo key_info = TypeInfo_from_type(key_type); TypeInfo key_info = TypeInfo_from_type(key_type);
if (!map) return hash; if (!map) return hash;
while (upb_mapiter_next(map, &iter)) { while (upb_MapIterator_Next(map, &iter)) {
upb_msgval key = upb_mapiter_key(map, iter); upb_MessageValue key = upb_MapIterator_Key(map, iter);
upb_msgval val = upb_mapiter_value(map, iter); upb_MessageValue val = upb_MapIterator_Value(map, iter);
VALUE key_val = Convert_UpbToRuby(key, key_info, Qnil); VALUE key_val = Convert_UpbToRuby(key, key_info, Qnil);
VALUE val_val = Scalar_CreateHash(val, val_info); VALUE val_val = Scalar_CreateHash(val, val_info);
rb_hash_aset(hash, key_val, val_val); rb_hash_aset(hash, key_val, val_val);
@ -152,25 +152,26 @@ VALUE Map_CreateHash(const upb_map* map, upb_fieldtype_t key_type,
VALUE Map_deep_copy(VALUE obj) { VALUE Map_deep_copy(VALUE obj) {
Map* self = ruby_to_Map(obj); Map* self = ruby_to_Map(obj);
VALUE new_arena_rb = Arena_new(); VALUE new_arena_rb = Arena_new();
upb_arena *arena = Arena_get(new_arena_rb); upb_Arena* arena = Arena_get(new_arena_rb);
upb_map* new_map = upb_Map* new_map =
upb_map_new(arena, self->key_type, self->value_type_info.type); upb_Map_New(arena, self->key_type, self->value_type_info.type);
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
while (upb_mapiter_next(self->map, &iter)) { while (upb_MapIterator_Next(self->map, &iter)) {
upb_msgval key = upb_mapiter_key(self->map, iter); upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
upb_msgval val = upb_mapiter_value(self->map, iter); upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
upb_msgval val_copy = Msgval_DeepCopy(val, self->value_type_info, arena); upb_MessageValue val_copy =
upb_map_set(new_map, key, val_copy, arena); Msgval_DeepCopy(val, self->value_type_info, arena);
upb_Map_Set(new_map, key, val_copy, arena);
} }
return Map_GetRubyWrapper(new_map, self->key_type, self->value_type_info, return Map_GetRubyWrapper(new_map, self->key_type, self->value_type_info,
new_arena_rb); new_arena_rb);
} }
const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field, const upb_Map* Map_GetUpbMap(VALUE val, const upb_FieldDef* field,
upb_arena* arena) { upb_Arena* arena) {
const upb_fielddef* key_field = map_field_key(field); const upb_FieldDef* key_field = map_field_key(field);
const upb_fielddef* value_field = map_field_value(field); const upb_FieldDef* value_field = map_field_value(field);
TypeInfo value_type_info = TypeInfo_get(value_field); TypeInfo value_type_info = TypeInfo_get(value_field);
Map* self; Map* self;
@ -180,7 +181,7 @@ const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field,
} }
self = ruby_to_Map(val); self = ruby_to_Map(val);
if (self->key_type != upb_fielddef_type(key_field)) { if (self->key_type != upb_FieldDef_CType(key_field)) {
rb_raise(cTypeError, "Map key type does not match field's key type"); rb_raise(cTypeError, "Map key type does not match field's key type");
} }
if (self->value_type_info.type != value_type_info.type) { if (self->value_type_info.type != value_type_info.type) {
@ -194,16 +195,16 @@ const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field,
return self->map; return self->map;
} }
void Map_Inspect(StringBuilder* b, const upb_map* map, upb_fieldtype_t key_type, void Map_Inspect(StringBuilder* b, const upb_Map* map, upb_CType key_type,
TypeInfo val_type) { TypeInfo val_type) {
bool first = true; bool first = true;
TypeInfo key_type_info = {key_type}; TypeInfo key_type_info = {key_type};
StringBuilder_Printf(b, "{"); StringBuilder_Printf(b, "{");
if (map) { if (map) {
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
while (upb_mapiter_next(map, &iter)) { while (upb_MapIterator_Next(map, &iter)) {
upb_msgval key = upb_mapiter_key(map, iter); upb_MessageValue key = upb_MapIterator_Key(map, iter);
upb_msgval val = upb_mapiter_value(map, iter); upb_MessageValue val = upb_MapIterator_Value(map, iter);
if (first) { if (first) {
first = false; first = false;
} else { } else {
@ -219,10 +220,12 @@ void Map_Inspect(StringBuilder* b, const upb_map* map, upb_fieldtype_t key_type,
static int merge_into_self_callback(VALUE key, VALUE val, VALUE _self) { static int merge_into_self_callback(VALUE key, VALUE val, VALUE _self) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
upb_arena *arena = Arena_get(self->arena); upb_Arena* arena = Arena_get(self->arena);
upb_msgval key_val = Convert_RubyToUpb(key, "", Map_keyinfo(self), arena); upb_MessageValue key_val =
upb_msgval val_val = Convert_RubyToUpb(val, "", self->value_type_info, arena); Convert_RubyToUpb(key, "", Map_keyinfo(self), arena);
upb_map_set(Map_GetMutable(_self), key_val, val_val, arena); upb_MessageValue val_val =
Convert_RubyToUpb(val, "", self->value_type_info, arena);
upb_Map_Set(Map_GetMutable(_self), key_val, val_val, arena);
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -234,9 +237,9 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
RTYPEDDATA_TYPE(hashmap) == &Map_type) { RTYPEDDATA_TYPE(hashmap) == &Map_type) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
Map* other = ruby_to_Map(hashmap); Map* other = ruby_to_Map(hashmap);
upb_arena *arena = Arena_get(self->arena); upb_Arena* arena = Arena_get(self->arena);
upb_msg *self_msg = Map_GetMutable(_self); upb_Message* self_msg = Map_GetMutable(_self);
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
Arena_fuse(other->arena, arena); Arena_fuse(other->arena, arena);
@ -246,10 +249,10 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types"); rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types");
} }
while (upb_mapiter_next(other->map, &iter)) { while (upb_MapIterator_Next(other->map, &iter)) {
upb_msgval key = upb_mapiter_key(other->map, iter); upb_MessageValue key = upb_MapIterator_Key(other->map, iter);
upb_msgval val = upb_mapiter_value(other->map, iter); upb_MessageValue val = upb_MapIterator_Value(other->map, iter);
upb_map_set(self_msg, key, val, arena); upb_Map_Set(self_msg, key, val, arena);
} }
} else { } else {
rb_raise(rb_eArgError, "Unknown type merging into Map"); rb_raise(rb_eArgError, "Unknown type merging into Map");
@ -305,20 +308,20 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
// Check that the key type is an allowed type. // Check that the key type is an allowed type.
switch (self->key_type) { switch (self->key_type) {
case UPB_TYPE_INT32: case kUpb_CType_Int32:
case UPB_TYPE_INT64: case kUpb_CType_Int64:
case UPB_TYPE_UINT32: case kUpb_CType_UInt32:
case UPB_TYPE_UINT64: case kUpb_CType_UInt64:
case UPB_TYPE_BOOL: case kUpb_CType_Bool:
case UPB_TYPE_STRING: case kUpb_CType_String:
case UPB_TYPE_BYTES: case kUpb_CType_Bytes:
// These are OK. // These are OK.
break; break;
default: default:
rb_raise(rb_eArgError, "Invalid key type for map."); rb_raise(rb_eArgError, "Invalid key type for map.");
} }
self->map = upb_map_new(Arena_get(self->arena), self->key_type, self->map = upb_Map_New(Arena_get(self->arena), self->key_type,
self->value_type_info.type); self->value_type_info.type);
ObjectCache_Add(self->map, _self); ObjectCache_Add(self->map, _self);
@ -339,11 +342,11 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
*/ */
static VALUE Map_each(VALUE _self) { static VALUE Map_each(VALUE _self) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
while (upb_mapiter_next(self->map, &iter)) { while (upb_MapIterator_Next(self->map, &iter)) {
upb_msgval key = upb_mapiter_key(self->map, iter); upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
upb_msgval val = upb_mapiter_value(self->map, iter); upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena); VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena); VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
rb_yield_values(2, key_val, val_val); rb_yield_values(2, key_val, val_val);
@ -360,11 +363,11 @@ static VALUE Map_each(VALUE _self) {
*/ */
static VALUE Map_keys(VALUE _self) { static VALUE Map_keys(VALUE _self) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
VALUE ret = rb_ary_new(); VALUE ret = rb_ary_new();
while (upb_mapiter_next(self->map, &iter)) { while (upb_MapIterator_Next(self->map, &iter)) {
upb_msgval key = upb_mapiter_key(self->map, iter); upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena); VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
rb_ary_push(ret, key_val); rb_ary_push(ret, key_val);
} }
@ -380,11 +383,11 @@ static VALUE Map_keys(VALUE _self) {
*/ */
static VALUE Map_values(VALUE _self) { static VALUE Map_values(VALUE _self) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
VALUE ret = rb_ary_new(); VALUE ret = rb_ary_new();
while (upb_mapiter_next(self->map, &iter)) { while (upb_MapIterator_Next(self->map, &iter)) {
upb_msgval val = upb_mapiter_value(self->map, iter); upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena); VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
rb_ary_push(ret, val_val); rb_ary_push(ret, val_val);
} }
@ -401,10 +404,11 @@ static VALUE Map_values(VALUE _self) {
*/ */
static VALUE Map_index(VALUE _self, VALUE key) { static VALUE Map_index(VALUE _self, VALUE key) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); upb_MessageValue key_upb =
upb_msgval val; Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
upb_MessageValue val;
if (upb_map_get(self->map, key_upb, &val)) { if (upb_Map_Get(self->map, key_upb, &val)) {
return Convert_UpbToRuby(val, self->value_type_info, self->arena); return Convert_UpbToRuby(val, self->value_type_info, self->arena);
} else { } else {
return Qnil; return Qnil;
@ -421,11 +425,13 @@ static VALUE Map_index(VALUE _self, VALUE key) {
*/ */
static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) { static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
upb_arena *arena = Arena_get(self->arena); upb_Arena* arena = Arena_get(self->arena);
upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); upb_MessageValue key_upb =
upb_msgval val_upb = Convert_RubyToUpb(val, "", self->value_type_info, arena); Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
upb_MessageValue val_upb =
Convert_RubyToUpb(val, "", self->value_type_info, arena);
upb_map_set(Map_GetMutable(_self), key_upb, val_upb, arena); upb_Map_Set(Map_GetMutable(_self), key_upb, val_upb, arena);
return val; return val;
} }
@ -439,9 +445,10 @@ static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) {
*/ */
static VALUE Map_has_key(VALUE _self, VALUE key) { static VALUE Map_has_key(VALUE _self, VALUE key) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); upb_MessageValue key_upb =
Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
if (upb_map_get(self->map, key_upb, NULL)) { if (upb_Map_Get(self->map, key_upb, NULL)) {
return Qtrue; return Qtrue;
} else { } else {
return Qfalse; return Qfalse;
@ -457,21 +464,22 @@ static VALUE Map_has_key(VALUE _self, VALUE key) {
*/ */
static VALUE Map_delete(VALUE _self, VALUE key) { static VALUE Map_delete(VALUE _self, VALUE key) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); upb_MessageValue key_upb =
upb_msgval val_upb; Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
upb_MessageValue val_upb;
VALUE ret; VALUE ret;
rb_check_frozen(_self); rb_check_frozen(_self);
// TODO(haberman): make upb_map_delete() also capable of returning the deleted // TODO(haberman): make upb_Map_Delete() also capable of returning the deleted
// value. // value.
if (upb_map_get(self->map, key_upb, &val_upb)) { if (upb_Map_Get(self->map, key_upb, &val_upb)) {
ret = Convert_UpbToRuby(val_upb, self->value_type_info, self->arena); ret = Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
} else { } else {
ret = Qnil; ret = Qnil;
} }
upb_map_delete(Map_GetMutable(_self), key_upb); upb_Map_Delete(Map_GetMutable(_self), key_upb);
return ret; return ret;
} }
@ -483,7 +491,7 @@ static VALUE Map_delete(VALUE _self, VALUE key) {
* Removes all entries from the map. * Removes all entries from the map.
*/ */
static VALUE Map_clear(VALUE _self) { static VALUE Map_clear(VALUE _self) {
upb_map_clear(Map_GetMutable(_self)); upb_Map_Clear(Map_GetMutable(_self));
return Qnil; return Qnil;
} }
@ -495,7 +503,7 @@ static VALUE Map_clear(VALUE _self) {
*/ */
static VALUE Map_length(VALUE _self) { static VALUE Map_length(VALUE _self) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
return ULL2NUM(upb_map_size(self->map)); return ULL2NUM(upb_Map_Size(self->map));
} }
/* /*
@ -509,16 +517,16 @@ static VALUE Map_dup(VALUE _self) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
VALUE new_map_rb = Map_new_this_type(self); VALUE new_map_rb = Map_new_this_type(self);
Map* new_self = ruby_to_Map(new_map_rb); Map* new_self = ruby_to_Map(new_map_rb);
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
upb_arena *arena = Arena_get(new_self->arena); upb_Arena* arena = Arena_get(new_self->arena);
upb_map *new_map = Map_GetMutable(new_map_rb); upb_Map* new_map = Map_GetMutable(new_map_rb);
Arena_fuse(self->arena, arena); Arena_fuse(self->arena, arena);
while (upb_mapiter_next(self->map, &iter)) { while (upb_MapIterator_Next(self->map, &iter)) {
upb_msgval key = upb_mapiter_key(self->map, iter); upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
upb_msgval val = upb_mapiter_value(self->map, iter); upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
upb_map_set(new_map, key, val, arena); upb_Map_Set(new_map, key, val, arena);
} }
return new_map_rb; return new_map_rb;
@ -559,18 +567,18 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
self->value_type_class != other->value_type_class) { self->value_type_class != other->value_type_class) {
return Qfalse; return Qfalse;
} }
if (upb_map_size(self->map) != upb_map_size(other->map)) { if (upb_Map_Size(self->map) != upb_Map_Size(other->map)) {
return Qfalse; return Qfalse;
} }
// For each member of self, check that an equal member exists at the same key // For each member of self, check that an equal member exists at the same key
// in other. // in other.
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
while (upb_mapiter_next(self->map, &iter)) { while (upb_MapIterator_Next(self->map, &iter)) {
upb_msgval key = upb_mapiter_key(self->map, iter); upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
upb_msgval val = upb_mapiter_value(self->map, iter); upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
upb_msgval other_val; upb_MessageValue other_val;
if (!upb_map_get(other->map, key, &other_val)) { if (!upb_Map_Get(other->map, key, &other_val)) {
// Not present in other map. // Not present in other map.
return Qfalse; return Qfalse;
} }
@ -609,11 +617,11 @@ VALUE Map_hash(VALUE _self) {
Map* self = ruby_to_Map(_self); Map* self = ruby_to_Map(_self);
uint64_t hash = 0; uint64_t hash = 0;
size_t iter = UPB_MAP_BEGIN; size_t iter = kUpb_Map_Begin;
TypeInfo key_info = {self->key_type}; TypeInfo key_info = {self->key_type};
while (upb_mapiter_next(self->map, &iter)) { while (upb_MapIterator_Next(self->map, &iter)) {
upb_msgval key = upb_mapiter_key(self->map, iter); upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
upb_msgval val = upb_mapiter_value(self->map, iter); upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
hash = Msgval_GetHash(key, key_info, hash); hash = Msgval_GetHash(key, key_info, hash);
hash = Msgval_GetHash(val, self->value_type_info, hash); hash = Msgval_GetHash(val, self->value_type_info, hash);
} }

@ -38,22 +38,21 @@
// Returns a Ruby wrapper object for the given map, which will be created if // Returns a Ruby wrapper object for the given map, which will be created if
// one does not exist already. // one does not exist already.
VALUE Map_GetRubyWrapper(upb_map *map, upb_fieldtype_t key_type, VALUE Map_GetRubyWrapper(upb_Map *map, upb_CType key_type, TypeInfo value_type,
TypeInfo value_type, VALUE arena); VALUE arena);
// Gets the underlying upb_map for this Ruby map object, which must have // Gets the underlying upb_Map for this Ruby map object, which must have
// key/value type that match |field|. If this is not a map or the type doesn't // key/value type that match |field|. If this is not a map or the type doesn't
// match, raises an exception. // match, raises an exception.
const upb_map *Map_GetUpbMap(VALUE val, const upb_fielddef *field, const upb_Map *Map_GetUpbMap(VALUE val, const upb_FieldDef *field,
upb_arena *arena); upb_Arena *arena);
// Implements #inspect for this map by appending its contents to |b|. // Implements #inspect for this map by appending its contents to |b|.
void Map_Inspect(StringBuilder *b, const upb_map *map, upb_fieldtype_t key_type, void Map_Inspect(StringBuilder *b, const upb_Map *map, upb_CType key_type,
TypeInfo val_type); TypeInfo val_type);
// Returns a new Hash object containing the contents of this Map. // Returns a new Hash object containing the contents of this Map.
VALUE Map_CreateHash(const upb_map* map, upb_fieldtype_t key_type, VALUE Map_CreateHash(const upb_Map *map, upb_CType key_type, TypeInfo val_info);
TypeInfo val_info);
// Returns a deep copy of this Map object. // Returns a deep copy of this Map object.
VALUE Map_deep_copy(VALUE obj); VALUE Map_deep_copy(VALUE obj);

File diff suppressed because it is too large Load Diff

@ -36,55 +36,58 @@
#include "protobuf.h" #include "protobuf.h"
#include "ruby-upb.h" #include "ruby-upb.h"
// Gets the underlying upb_msg* and upb_msgdef for the given Ruby message // Gets the underlying upb_Message* and upb_MessageDef for the given Ruby
// wrapper. Requires that |value| is indeed a message object. // message wrapper. Requires that |value| is indeed a message object.
const upb_msg *Message_Get(VALUE value, const upb_msgdef **m); const upb_Message* Message_Get(VALUE value, const upb_MessageDef** m);
// Like Message_Get(), but checks that the object is not frozen and returns a // Like Message_Get(), but checks that the object is not frozen and returns a
// mutable pointer. // mutable pointer.
upb_msg *Message_GetMutable(VALUE value, const upb_msgdef **m); upb_Message* Message_GetMutable(VALUE value, const upb_MessageDef** m);
// Returns the Arena object for this message. // Returns the Arena object for this message.
VALUE Message_GetArena(VALUE value); VALUE Message_GetArena(VALUE value);
// Converts |value| into a upb_msg value of the expected upb_msgdef type, // Converts |value| into a upb_Message value of the expected upb_MessageDef
// raising an error if this is not possible. Used when assigning |value| to a // type, raising an error if this is not possible. Used when assigning |value|
// field of another message, which means the message must be of a particular // to a field of another message, which means the message must be of a
// type. // particular type.
// //
// This will perform automatic conversions in some cases (for example, Time -> // This will perform automatic conversions in some cases (for example, Time ->
// Google::Protobuf::Timestamp). If any new message is created, it will be // Google::Protobuf::Timestamp). If any new message is created, it will be
// created on |arena|, and any existing message will have its arena fused with // created on |arena|, and any existing message will have its arena fused with
// |arena|. // |arena|.
const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m, const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
const char* name, upb_arena* arena); const char* name, upb_Arena* arena);
// Gets or constructs a Ruby wrapper object for the given message. The wrapper // Gets or constructs a Ruby wrapper object for the given message. The wrapper
// object will reference |arena| and ensure that it outlives this object. // object will reference |arena| and ensure that it outlives this object.
VALUE Message_GetRubyWrapper(upb_msg* msg, const upb_msgdef* m, VALUE arena); VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m,
VALUE arena);
// Gets the given field from this message. // Gets the given field from this message.
VALUE Message_getfield(VALUE _self, const upb_fielddef* f); VALUE Message_getfield(VALUE _self, const upb_FieldDef* f);
// Implements #inspect for this message, printing the text to |b|. // Implements #inspect for this message, printing the text to |b|.
void Message_PrintMessage(StringBuilder* b, const upb_msg* msg, void Message_PrintMessage(StringBuilder* b, const upb_Message* msg,
const upb_msgdef* m); const upb_MessageDef* m);
// Returns a hash value for the given message. // Returns a hash value for the given message.
uint64_t Message_Hash(const upb_msg *msg, const upb_msgdef *m, uint64_t seed); uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
uint64_t seed);
// Returns a deep copy of the given message. // Returns a deep copy of the given message.
upb_msg* Message_deep_copy(const upb_msg* msg, const upb_msgdef* m, upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
upb_arena *arena); upb_Arena* arena);
// Returns true if these two messages are equal. // Returns true if these two messages are equal.
bool Message_Equal(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m); bool Message_Equal(const upb_Message* m1, const upb_Message* m2,
const upb_MessageDef* m);
// Checks that this Ruby object is a message, and raises an exception if not. // Checks that this Ruby object is a message, and raises an exception if not.
void Message_CheckClass(VALUE klass); void Message_CheckClass(VALUE klass);
// Returns a new Hash object containing the contents of this message. // Returns a new Hash object containing the contents of this message.
VALUE Scalar_CreateHash(upb_msgval val, TypeInfo type_info); VALUE Scalar_CreateHash(upb_MessageValue val, TypeInfo type_info);
// Creates a message class or enum module for this descriptor, respectively. // Creates a message class or enum module for this descriptor, respectively.
VALUE build_class_from_descriptor(VALUE descriptor); VALUE build_class_from_descriptor(VALUE descriptor);

@ -40,14 +40,14 @@
VALUE cParseError; VALUE cParseError;
VALUE cTypeError; VALUE cTypeError;
const upb_fielddef* map_field_key(const upb_fielddef* field) { const upb_FieldDef *map_field_key(const upb_FieldDef *field) {
const upb_msgdef *entry = upb_fielddef_msgsubdef(field); const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field);
return upb_msgdef_itof(entry, 1); return upb_MessageDef_FindFieldByNumberWithSize(entry, 1);
} }
const upb_fielddef* map_field_value(const upb_fielddef* field) { const upb_FieldDef *map_field_value(const upb_FieldDef *field) {
const upb_msgdef *entry = upb_fielddef_msgsubdef(field); const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field);
return upb_msgdef_itof(entry, 2); return upb_MessageDef_FindFieldByNumberWithSize(entry, 2);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -66,21 +66,21 @@ static size_t StringBuilder_SizeOf(size_t cap) {
return sizeof(StringBuilder) + cap; return sizeof(StringBuilder) + cap;
} }
StringBuilder* StringBuilder_New() { StringBuilder *StringBuilder_New() {
const size_t cap = 128; const size_t cap = 128;
StringBuilder* builder = malloc(sizeof(*builder)); StringBuilder *builder = malloc(sizeof(*builder));
builder->size = 0; builder->size = 0;
builder->cap = cap; builder->cap = cap;
builder->data = malloc(builder->cap); builder->data = malloc(builder->cap);
return builder; return builder;
} }
void StringBuilder_Free(StringBuilder* b) { void StringBuilder_Free(StringBuilder *b) {
free(b->data); free(b->data);
free(b); free(b);
} }
void StringBuilder_Printf(StringBuilder* b, const char *fmt, ...) { void StringBuilder_Printf(StringBuilder *b, const char *fmt, ...) {
size_t have = b->cap - b->size; size_t have = b->cap - b->size;
size_t n; size_t n;
va_list args; va_list args;
@ -104,60 +104,62 @@ void StringBuilder_Printf(StringBuilder* b, const char *fmt, ...) {
b->size += n; b->size += n;
} }
VALUE StringBuilder_ToRubyString(StringBuilder* b) { VALUE StringBuilder_ToRubyString(StringBuilder *b) {
VALUE ret = rb_str_new(b->data, b->size); VALUE ret = rb_str_new(b->data, b->size);
rb_enc_associate(ret, rb_utf8_encoding()); rb_enc_associate(ret, rb_utf8_encoding());
return ret; return ret;
} }
static void StringBuilder_PrintEnum(StringBuilder* b, int32_t val, static void StringBuilder_PrintEnum(StringBuilder *b, int32_t val,
const upb_enumdef* e) { const upb_EnumDef *e) {
const char *name = upb_enumdef_iton(e, val); const upb_EnumValueDef *ev = upb_EnumDef_FindValueByNumber(e, val);
if (name) { if (ev) {
StringBuilder_Printf(b, ":%s", name); StringBuilder_Printf(b, ":%s", upb_EnumValueDef_Name(ev));
} else { } else {
StringBuilder_Printf(b, "%" PRId32, val); StringBuilder_Printf(b, "%" PRId32, val);
} }
} }
void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val, void StringBuilder_PrintMsgval(StringBuilder *b, upb_MessageValue val,
TypeInfo info) { TypeInfo info) {
switch (info.type) { switch (info.type) {
case UPB_TYPE_BOOL: case kUpb_CType_Bool:
StringBuilder_Printf(b, "%s", val.bool_val ? "true" : "false"); StringBuilder_Printf(b, "%s", val.bool_val ? "true" : "false");
break; break;
case UPB_TYPE_FLOAT: { case kUpb_CType_Float: {
VALUE str = rb_inspect(DBL2NUM(val.float_val)); VALUE str = rb_inspect(DBL2NUM(val.float_val));
StringBuilder_Printf(b, "%s", RSTRING_PTR(str)); StringBuilder_Printf(b, "%s", RSTRING_PTR(str));
break; break;
} }
case UPB_TYPE_DOUBLE: { case kUpb_CType_Double: {
VALUE str = rb_inspect(DBL2NUM(val.double_val)); VALUE str = rb_inspect(DBL2NUM(val.double_val));
StringBuilder_Printf(b, "%s", RSTRING_PTR(str)); StringBuilder_Printf(b, "%s", RSTRING_PTR(str));
break; break;
} }
case UPB_TYPE_INT32: case kUpb_CType_Int32:
StringBuilder_Printf(b, "%" PRId32, val.int32_val); StringBuilder_Printf(b, "%" PRId32, val.int32_val);
break; break;
case UPB_TYPE_UINT32: case kUpb_CType_UInt32:
StringBuilder_Printf(b, "%" PRIu32, val.uint32_val); StringBuilder_Printf(b, "%" PRIu32, val.uint32_val);
break; break;
case UPB_TYPE_INT64: case kUpb_CType_Int64:
StringBuilder_Printf(b, "%" PRId64, val.int64_val); StringBuilder_Printf(b, "%" PRId64, val.int64_val);
break; break;
case UPB_TYPE_UINT64: case kUpb_CType_UInt64:
StringBuilder_Printf(b, "%" PRIu64, val.uint64_val); StringBuilder_Printf(b, "%" PRIu64, val.uint64_val);
break; break;
case UPB_TYPE_STRING: case kUpb_CType_String:
StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, val.str_val.data); StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size,
val.str_val.data);
break; break;
case UPB_TYPE_BYTES: case kUpb_CType_Bytes:
StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, val.str_val.data); StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size,
val.str_val.data);
break; break;
case UPB_TYPE_ENUM: case kUpb_CType_Enum:
StringBuilder_PrintEnum(b, val.int32_val, info.def.enumdef); StringBuilder_PrintEnum(b, val.int32_val, info.def.enumdef);
break; break;
case UPB_TYPE_MESSAGE: case kUpb_CType_Message:
Message_PrintMessage(b, val.msg_val, info.def.msgdef); Message_PrintMessage(b, val.msg_val, info.def.msgdef);
break; break;
} }
@ -168,7 +170,7 @@ void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val,
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef struct { typedef struct {
upb_arena *arena; upb_Arena *arena;
VALUE pinned_objs; VALUE pinned_objs;
} Arena; } Arena;
@ -179,44 +181,42 @@ static void Arena_mark(void *data) {
static void Arena_free(void *data) { static void Arena_free(void *data) {
Arena *arena = data; Arena *arena = data;
upb_arena_free(arena->arena); upb_Arena_Free(arena->arena);
xfree(arena); xfree(arena);
} }
static VALUE cArena; static VALUE cArena;
const rb_data_type_t Arena_type = { const rb_data_type_t Arena_type = {
"Google::Protobuf::Internal::Arena", "Google::Protobuf::Internal::Arena",
{ Arena_mark, Arena_free, NULL }, {Arena_mark, Arena_free, NULL},
.flags = RUBY_TYPED_FREE_IMMEDIATELY, .flags = RUBY_TYPED_FREE_IMMEDIATELY,
}; };
static VALUE Arena_alloc(VALUE klass) { static VALUE Arena_alloc(VALUE klass) {
Arena *arena = ALLOC(Arena); Arena *arena = ALLOC(Arena);
arena->arena = upb_arena_new(); arena->arena = upb_Arena_New();
arena->pinned_objs = Qnil; arena->pinned_objs = Qnil;
return TypedData_Wrap_Struct(klass, &Arena_type, arena); return TypedData_Wrap_Struct(klass, &Arena_type, arena);
} }
upb_arena *Arena_get(VALUE _arena) { upb_Arena *Arena_get(VALUE _arena) {
Arena *arena; Arena *arena;
TypedData_Get_Struct(_arena, Arena, &Arena_type, arena); TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
return arena->arena; return arena->arena;
} }
void Arena_fuse(VALUE _arena, upb_arena *other) { void Arena_fuse(VALUE _arena, upb_Arena *other) {
Arena *arena; Arena *arena;
TypedData_Get_Struct(_arena, Arena, &Arena_type, arena); TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
if (!upb_arena_fuse(arena->arena, other)) { if (!upb_Arena_Fuse(arena->arena, other)) {
rb_raise(rb_eRuntimeError, rb_raise(rb_eRuntimeError,
"Unable to fuse arenas. This should never happen since Ruby does " "Unable to fuse arenas. This should never happen since Ruby does "
"not use initial blocks"); "not use initial blocks");
} }
} }
VALUE Arena_new() { VALUE Arena_new() { return Arena_alloc(cArena); }
return Arena_alloc(cArena);
}
void Arena_Pin(VALUE _arena, VALUE obj) { void Arena_Pin(VALUE _arena, VALUE obj) {
Arena *arena; Arena *arena;
@ -333,8 +333,8 @@ static void SecondaryMap_MaybeGC() {
// avoid O(N^2) CPU costs. // avoid O(N^2) CPU costs.
size_t threshold = PBRUBY_MAX(secondary_len * 0.2, 2000); size_t threshold = PBRUBY_MAX(secondary_len * 0.2, 2000);
if (waste > threshold) { if (waste > threshold) {
rb_funcall(gc_secondary_map_lambda, rb_intern("call"), 2, rb_funcall(gc_secondary_map_lambda, rb_intern("call"), 2, secondary_map,
secondary_map, weak_obj_cache); weak_obj_cache);
} }
} }
@ -353,7 +353,7 @@ static VALUE SecondaryMap_Get(VALUE key, bool create) {
#endif #endif
// Requires: secondary_map_mutex is held by this thread iff create == true. // Requires: secondary_map_mutex is held by this thread iff create == true.
static VALUE ObjectCache_GetKey(const void* key, bool create) { static VALUE ObjectCache_GetKey(const void *key, bool create) {
VALUE key_val = (VALUE)key; VALUE key_val = (VALUE)key;
PBRUBY_ASSERT((key_val & 3) == 0); PBRUBY_ASSERT((key_val & 3) == 0);
VALUE ret = LL2NUM(key_val >> 2); VALUE ret = LL2NUM(key_val >> 2);
@ -380,7 +380,7 @@ static void ObjectCache_Init() {
#endif #endif
} }
void ObjectCache_Add(const void* key, VALUE val) { void ObjectCache_Add(const void *key, VALUE val) {
PBRUBY_ASSERT(ObjectCache_Get(key) == Qnil); PBRUBY_ASSERT(ObjectCache_Get(key) == Qnil);
#if USE_SECONDARY_MAP #if USE_SECONDARY_MAP
rb_mutex_lock(secondary_map_mutex); rb_mutex_lock(secondary_map_mutex);
@ -394,7 +394,7 @@ void ObjectCache_Add(const void* key, VALUE val) {
} }
// Returns the cached object for this key, if any. Otherwise returns Qnil. // Returns the cached object for this key, if any. Otherwise returns Qnil.
VALUE ObjectCache_Get(const void* key) { VALUE ObjectCache_Get(const void *key) {
VALUE key_rb = ObjectCache_GetKey(key, false); VALUE key_rb = ObjectCache_GetKey(key, false);
return rb_funcall(weak_obj_cache, item_get, 1, key_rb); return rb_funcall(weak_obj_cache, item_get, 1, key_rb);
} }
@ -407,9 +407,9 @@ VALUE ObjectCache_Get(const void* key) {
* unknown fields in submessages. * unknown fields in submessages.
*/ */
static VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) { static VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) {
const upb_msgdef *m; const upb_MessageDef *m;
upb_msg *msg = Message_GetMutable(msg_rb, &m); upb_Message *msg = Message_GetMutable(msg_rb, &m);
if (!upb_msg_discardunknown(msg, m, 128)) { if (!upb_Message_DiscardUnknown(msg, m, 128)) {
rb_raise(rb_eRuntimeError, "Messages nested too deeply."); rb_raise(rb_eRuntimeError, "Messages nested too deeply.");
} }
@ -431,10 +431,10 @@ VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
return Map_deep_copy(obj); return Map_deep_copy(obj);
} else { } else {
VALUE new_arena_rb = Arena_new(); VALUE new_arena_rb = Arena_new();
upb_arena *new_arena = Arena_get(new_arena_rb); upb_Arena *new_arena = Arena_get(new_arena_rb);
const upb_msgdef *m; const upb_MessageDef *m;
const upb_msg *msg = Message_Get(obj, &m); const upb_Message *msg = Message_Get(obj, &m);
upb_msg* new_msg = Message_deep_copy(msg, m, new_arena); upb_Message *new_msg = Message_deep_copy(msg, m, new_arena);
return Message_GetRubyWrapper(new_msg, m, new_arena_rb); return Message_GetRubyWrapper(new_msg, m, new_arena_rb);
} }
} }
@ -445,8 +445,7 @@ VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
// This must be named "Init_protobuf_c" because the Ruby module is named // This must be named "Init_protobuf_c" because the Ruby module is named
// "protobuf_c" -- the VM looks for this symbol in our .so. // "protobuf_c" -- the VM looks for this symbol in our .so.
__attribute__ ((visibility ("default"))) __attribute__((visibility("default"))) void Init_protobuf_c() {
void Init_protobuf_c() {
ObjectCache_Init(); ObjectCache_Init();
VALUE google = rb_define_module("Google"); VALUE google = rb_define_module("Google");
@ -465,6 +464,6 @@ void Init_protobuf_c() {
rb_define_singleton_method(protobuf, "discard_unknown", rb_define_singleton_method(protobuf, "discard_unknown",
Google_Protobuf_discard_unknown, 1); Google_Protobuf_discard_unknown, 1);
rb_define_singleton_method(protobuf, "deep_copy", rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy,
Google_Protobuf_deep_copy, 1); 1);
} }

@ -31,33 +31,33 @@
#ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ #ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
#define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ #define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
#include <ruby/encoding.h>
#include <ruby/ruby.h> #include <ruby/ruby.h>
#include <ruby/vm.h> #include <ruby/vm.h>
#include <ruby/encoding.h>
#include "ruby-upb.h"
#include "defs.h" #include "defs.h"
#include "ruby-upb.h"
// These operate on a map field (i.e., a repeated field of submessages whose // These operate on a map field (i.e., a repeated field of submessages whose
// submessage type is a map-entry msgdef). // submessage type is a map-entry msgdef).
const upb_fielddef* map_field_key(const upb_fielddef* field); const upb_FieldDef* map_field_key(const upb_FieldDef* field);
const upb_fielddef* map_field_value(const upb_fielddef* field); const upb_FieldDef* map_field_value(const upb_FieldDef* field);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Arena // Arena
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// A Ruby object that wraps an underlying upb_arena. Any objects that are // A Ruby object that wraps an underlying upb_Arena. Any objects that are
// allocated from this arena should reference the Arena in rb_gc_mark(), to // allocated from this arena should reference the Arena in rb_gc_mark(), to
// ensure that the object's underlying memory outlives any Ruby object that can // ensure that the object's underlying memory outlives any Ruby object that can
// reach it. // reach it.
VALUE Arena_new(); VALUE Arena_new();
upb_arena *Arena_get(VALUE arena); upb_Arena* Arena_get(VALUE arena);
// Fuses this arena to another, throwing a Ruby exception if this is not // Fuses this arena to another, throwing a Ruby exception if this is not
// possible. // possible.
void Arena_fuse(VALUE arena, upb_arena *other); void Arena_fuse(VALUE arena, upb_Arena* other);
// Pins this Ruby object to the lifetime of this arena, so that as long as the // Pins this Ruby object to the lifetime of this arena, so that as long as the
// arena is alive this object will not be collected. // arena is alive this object will not be collected.
@ -93,10 +93,11 @@ typedef struct StringBuilder StringBuilder;
StringBuilder* StringBuilder_New(); StringBuilder* StringBuilder_New();
void StringBuilder_Free(StringBuilder* b); void StringBuilder_Free(StringBuilder* b);
void StringBuilder_Printf(StringBuilder* b, const char *fmt, ...); void StringBuilder_Printf(StringBuilder* b, const char* fmt, ...);
VALUE StringBuilder_ToRubyString(StringBuilder* b); VALUE StringBuilder_ToRubyString(StringBuilder* b);
void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val, TypeInfo info); void StringBuilder_PrintMsgval(StringBuilder* b, upb_MessageValue val,
TypeInfo info);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Utilities. // Utilities.
@ -105,7 +106,9 @@ void StringBuilder_PrintMsgval(StringBuilder* b, upb_msgval val, TypeInfo info);
extern VALUE cTypeError; extern VALUE cTypeError;
#ifdef NDEBUG #ifdef NDEBUG
#define PBRUBY_ASSERT(expr) do {} while (false && (expr)) #define PBRUBY_ASSERT(expr) \
do { \
} while (false && (expr))
#else #else
#define PBRUBY_ASSERT(expr) assert(expr) #define PBRUBY_ASSERT(expr) assert(expr)
#endif #endif

@ -40,10 +40,10 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
typedef struct { typedef struct {
const upb_array *array; // Can get as mutable when non-frozen. const upb_Array* array; // Can get as mutable when non-frozen.
TypeInfo type_info; TypeInfo type_info;
VALUE type_class; // To GC-root the msgdef/enumdef in type_info. VALUE type_class; // To GC-root the msgdef/enumdef in type_info.
VALUE arena; // To GC-root the upb_array. VALUE arena; // To GC-root the upb_Array.
} RepeatedField; } RepeatedField;
VALUE cRepeatedField; VALUE cRepeatedField;
@ -55,9 +55,9 @@ static void RepeatedField_mark(void* _self) {
} }
const rb_data_type_t RepeatedField_type = { const rb_data_type_t RepeatedField_type = {
"Google::Protobuf::RepeatedField", "Google::Protobuf::RepeatedField",
{ RepeatedField_mark, RUBY_DEFAULT_FREE, NULL }, {RepeatedField_mark, RUBY_DEFAULT_FREE, NULL},
.flags = RUBY_TYPED_FREE_IMMEDIATELY, .flags = RUBY_TYPED_FREE_IMMEDIATELY,
}; };
static RepeatedField* ruby_to_RepeatedField(VALUE _self) { static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
@ -66,9 +66,9 @@ static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
return self; return self;
} }
static upb_array *RepeatedField_GetMutable(VALUE _self) { static upb_Array* RepeatedField_GetMutable(VALUE _self) {
rb_check_frozen(_self); rb_check_frozen(_self);
return (upb_array*)ruby_to_RepeatedField(_self)->array; return (upb_Array*)ruby_to_RepeatedField(_self)->array;
} }
VALUE RepeatedField_alloc(VALUE klass) { VALUE RepeatedField_alloc(VALUE klass) {
@ -79,7 +79,7 @@ VALUE RepeatedField_alloc(VALUE klass) {
return TypedData_Wrap_Struct(klass, &RepeatedField_type, self); return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
} }
VALUE RepeatedField_GetRubyWrapper(upb_array* array, TypeInfo type_info, VALUE RepeatedField_GetRubyWrapper(upb_Array* array, TypeInfo type_info,
VALUE arena) { VALUE arena) {
PBRUBY_ASSERT(array); PBRUBY_ASSERT(array);
VALUE val = ObjectCache_Get(array); VALUE val = ObjectCache_Get(array);
@ -92,7 +92,7 @@ VALUE RepeatedField_GetRubyWrapper(upb_array* array, TypeInfo type_info,
self->array = array; self->array = array;
self->arena = arena; self->arena = arena;
self->type_info = type_info; self->type_info = type_info;
if (self->type_info.type == UPB_TYPE_MESSAGE) { if (self->type_info.type == kUpb_CType_Message) {
self->type_class = Descriptor_DefToClass(type_info.def.msgdef); self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
} }
} }
@ -105,24 +105,24 @@ VALUE RepeatedField_GetRubyWrapper(upb_array* array, TypeInfo type_info,
static VALUE RepeatedField_new_this_type(RepeatedField* from) { static VALUE RepeatedField_new_this_type(RepeatedField* from) {
VALUE arena_rb = Arena_new(); VALUE arena_rb = Arena_new();
upb_array *array = upb_array_new(Arena_get(arena_rb), from->type_info.type); upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type);
VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb); VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb);
PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class); PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class);
return ret; return ret;
} }
void RepeatedField_Inspect(StringBuilder* b, const upb_array* array, void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
TypeInfo info) { TypeInfo info) {
bool first = true; bool first = true;
StringBuilder_Printf(b, "["); StringBuilder_Printf(b, "[");
size_t n = array ? upb_array_size(array) : 0; size_t n = array ? upb_Array_Size(array) : 0;
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
if (first) { if (first) {
first = false; first = false;
} else { } else {
StringBuilder_Printf(b, ", "); StringBuilder_Printf(b, ", ");
} }
StringBuilder_PrintMsgval(b, upb_array_get(array, i), info); StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info);
} }
StringBuilder_Printf(b, "]"); StringBuilder_Printf(b, "]");
} }
@ -132,24 +132,24 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
VALUE new_rptfield = RepeatedField_new_this_type(self); VALUE new_rptfield = RepeatedField_new_this_type(self);
RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield); RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield);
VALUE arena_rb = new_self->arena; VALUE arena_rb = new_self->arena;
upb_array *new_array = RepeatedField_GetMutable(new_rptfield); upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
upb_arena *arena = Arena_get(arena_rb); upb_Arena* arena = Arena_get(arena_rb);
size_t elements = upb_array_size(self->array); size_t elements = upb_Array_Size(self->array);
upb_array_resize(new_array, elements, arena); upb_Array_Resize(new_array, elements, arena);
size_t size = upb_array_size(self->array); size_t size = upb_Array_Size(self->array);
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
upb_msgval msgval = upb_array_get(self->array, i); upb_MessageValue msgval = upb_Array_Get(self->array, i);
upb_msgval copy = Msgval_DeepCopy(msgval, self->type_info, arena); upb_MessageValue copy = Msgval_DeepCopy(msgval, self->type_info, arena);
upb_array_set(new_array, i, copy); upb_Array_Set(new_array, i, copy);
} }
return new_rptfield; return new_rptfield;
} }
const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef* field, const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field,
upb_arena* arena) { upb_Arena* arena) {
RepeatedField* self; RepeatedField* self;
TypeInfo type_info = TypeInfo_get(field); TypeInfo type_info = TypeInfo_get(field);
@ -173,17 +173,17 @@ const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef* field,
static int index_position(VALUE _index, RepeatedField* repeated_field) { static int index_position(VALUE _index, RepeatedField* repeated_field) {
int index = NUM2INT(_index); int index = NUM2INT(_index);
if (index < 0) index += upb_array_size(repeated_field->array); if (index < 0) index += upb_Array_Size(repeated_field->array);
return index; return index;
} }
static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) { static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
size_t size = upb_array_size(self->array); size_t size = upb_Array_Size(self->array);
VALUE ary = rb_ary_new2(size); VALUE ary = rb_ary_new2(size);
long i; long i;
for (i = beg; i < beg + len; i++) { for (i = beg; i < beg + len; i++) {
upb_msgval msgval = upb_array_get(self->array, i); upb_MessageValue msgval = upb_Array_Get(self->array, i);
VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena); VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena);
rb_ary_push(ary, elem); rb_ary_push(ary, elem);
} }
@ -200,18 +200,17 @@ static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
*/ */
static VALUE RepeatedField_each(VALUE _self) { static VALUE RepeatedField_each(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
int size = upb_array_size(self->array); int size = upb_Array_Size(self->array);
int i; int i;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
upb_msgval msgval = upb_array_get(self->array, i); upb_MessageValue msgval = upb_Array_Get(self->array, i);
VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
rb_yield(val); rb_yield(val);
} }
return _self; return _self;
} }
/* /*
* call-seq: * call-seq:
* RepeatedField.[](index) => value * RepeatedField.[](index) => value
@ -220,20 +219,20 @@ static VALUE RepeatedField_each(VALUE _self) {
*/ */
static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) { static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
long size = upb_array_size(self->array); long size = upb_Array_Size(self->array);
VALUE arg = argv[0]; VALUE arg = argv[0];
long beg, len; long beg, len;
if (argc == 1){ if (argc == 1) {
if (FIXNUM_P(arg)) { if (FIXNUM_P(arg)) {
/* standard case */ /* standard case */
upb_msgval msgval; upb_MessageValue msgval;
int index = index_position(argv[0], self); int index = index_position(argv[0], self);
if (index < 0 || (size_t)index >= upb_array_size(self->array)) { if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) {
return Qnil; return Qnil;
} }
msgval = upb_array_get(self->array, index); msgval = upb_Array_Get(self->array, index);
return Convert_UpbToRuby(msgval, self->type_info, self->arena); return Convert_UpbToRuby(msgval, self->type_info, self->arena);
} else { } else {
/* check if idx is Range */ /* check if idx is Range */
@ -269,10 +268,10 @@ static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
*/ */
static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) { static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
int size = upb_array_size(self->array); int size = upb_Array_Size(self->array);
upb_array *array = RepeatedField_GetMutable(_self); upb_Array* array = RepeatedField_GetMutable(_self);
upb_arena *arena = Arena_get(self->arena); upb_Arena* arena = Arena_get(self->arena);
upb_msgval msgval = Convert_RubyToUpb(val, "", self->type_info, arena); upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
int index = index_position(_index, self); int index = index_position(_index, self);
if (index < 0 || index >= (INT_MAX - 1)) { if (index < 0 || index >= (INT_MAX - 1)) {
@ -280,17 +279,17 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
} }
if (index >= size) { if (index >= size) {
upb_array_resize(array, index + 1, arena); upb_Array_Resize(array, index + 1, arena);
upb_msgval fill; upb_MessageValue fill;
memset(&fill, 0, sizeof(fill)); memset(&fill, 0, sizeof(fill));
for (int i = size; i < index; i++) { for (int i = size; i < index; i++) {
// Fill default values. // Fill default values.
// TODO(haberman): should this happen at the upb level? // TODO(haberman): should this happen at the upb level?
upb_array_set(array, i, fill); upb_Array_Set(array, i, fill);
} }
} }
upb_array_set(array, index, msgval); upb_Array_Set(array, index, msgval);
return Qnil; return Qnil;
} }
@ -302,13 +301,14 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
*/ */
static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) { static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
upb_arena *arena = Arena_get(self->arena); upb_Arena* arena = Arena_get(self->arena);
upb_array *array = RepeatedField_GetMutable(_self); upb_Array* array = RepeatedField_GetMutable(_self);
int i; int i;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
upb_msgval msgval = Convert_RubyToUpb(argv[i], "", self->type_info, arena); upb_MessageValue msgval =
upb_array_append(array, msgval, arena); Convert_RubyToUpb(argv[i], "", self->type_info, arena);
upb_Array_Append(array, msgval, arena);
} }
return _self; return _self;
@ -322,11 +322,11 @@ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
*/ */
static VALUE RepeatedField_push(VALUE _self, VALUE val) { static VALUE RepeatedField_push(VALUE _self, VALUE val) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
upb_arena *arena = Arena_get(self->arena); upb_Arena* arena = Arena_get(self->arena);
upb_array *array = RepeatedField_GetMutable(_self); upb_Array* array = RepeatedField_GetMutable(_self);
upb_msgval msgval = Convert_RubyToUpb(val, "", self->type_info, arena); upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
upb_array_append(array, msgval, arena); upb_Array_Append(array, msgval, arena);
return _self; return _self;
} }
@ -336,19 +336,19 @@ static VALUE RepeatedField_push(VALUE _self, VALUE val) {
*/ */
static VALUE RepeatedField_pop_one(VALUE _self) { static VALUE RepeatedField_pop_one(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
size_t size = upb_array_size(self->array); size_t size = upb_Array_Size(self->array);
upb_array *array = RepeatedField_GetMutable(_self); upb_Array* array = RepeatedField_GetMutable(_self);
upb_msgval last; upb_MessageValue last;
VALUE ret; VALUE ret;
if (size == 0) { if (size == 0) {
return Qnil; return Qnil;
} }
last = upb_array_get(self->array, size - 1); last = upb_Array_Get(self->array, size - 1);
ret = Convert_UpbToRuby(last, self->type_info, self->arena); ret = Convert_UpbToRuby(last, self->type_info, self->arena);
upb_array_resize(array, size - 1, Arena_get(self->arena)); upb_Array_Resize(array, size - 1, Arena_get(self->arena));
return ret; return ret;
} }
@ -360,11 +360,11 @@ static VALUE RepeatedField_pop_one(VALUE _self) {
*/ */
static VALUE RepeatedField_replace(VALUE _self, VALUE list) { static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
upb_array *array = RepeatedField_GetMutable(_self); upb_Array* array = RepeatedField_GetMutable(_self);
int i; int i;
Check_Type(list, T_ARRAY); Check_Type(list, T_ARRAY);
upb_array_resize(array, 0, Arena_get(self->arena)); upb_Array_Resize(array, 0, Arena_get(self->arena));
for (i = 0; i < RARRAY_LEN(list); i++) { for (i = 0; i < RARRAY_LEN(list); i++) {
RepeatedField_push(_self, rb_ary_entry(list, i)); RepeatedField_push(_self, rb_ary_entry(list, i));
@ -381,8 +381,8 @@ static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
*/ */
static VALUE RepeatedField_clear(VALUE _self) { static VALUE RepeatedField_clear(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
upb_array *array = RepeatedField_GetMutable(_self); upb_Array* array = RepeatedField_GetMutable(_self);
upb_array_resize(array, 0, Arena_get(self->arena)); upb_Array_Resize(array, 0, Arena_get(self->arena));
return _self; return _self;
} }
@ -394,7 +394,7 @@ static VALUE RepeatedField_clear(VALUE _self) {
*/ */
static VALUE RepeatedField_length(VALUE _self) { static VALUE RepeatedField_length(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
return INT2NUM(upb_array_size(self->array)); return INT2NUM(upb_Array_Size(self->array));
} }
/* /*
@ -408,16 +408,16 @@ static VALUE RepeatedField_dup(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
VALUE new_rptfield = RepeatedField_new_this_type(self); VALUE new_rptfield = RepeatedField_new_this_type(self);
RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield); RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
upb_array *new_array = RepeatedField_GetMutable(new_rptfield); upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
upb_arena* arena = Arena_get(new_rptfield_self->arena); upb_Arena* arena = Arena_get(new_rptfield_self->arena);
int size = upb_array_size(self->array); int size = upb_Array_Size(self->array);
int i; int i;
Arena_fuse(self->arena, arena); Arena_fuse(self->arena, arena);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
upb_msgval msgval = upb_array_get(self->array, i); upb_MessageValue msgval = upb_Array_Get(self->array, i);
upb_array_append(new_array, msgval, arena); upb_Array_Append(new_array, msgval, arena);
} }
return new_rptfield; return new_rptfield;
@ -432,12 +432,12 @@ static VALUE RepeatedField_dup(VALUE _self) {
*/ */
VALUE RepeatedField_to_ary(VALUE _self) { VALUE RepeatedField_to_ary(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
int size = upb_array_size(self->array); int size = upb_Array_Size(self->array);
VALUE ary = rb_ary_new2(size); VALUE ary = rb_ary_new2(size);
int i; int i;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
upb_msgval msgval = upb_array_get(self->array, i); upb_MessageValue msgval = upb_Array_Get(self->array, i);
VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
rb_ary_push(ary, val); rb_ary_push(ary, val);
} }
@ -473,17 +473,17 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
self = ruby_to_RepeatedField(_self); self = ruby_to_RepeatedField(_self);
other = ruby_to_RepeatedField(_other); other = ruby_to_RepeatedField(_other);
size_t n = upb_array_size(self->array); size_t n = upb_Array_Size(self->array);
if (self->type_info.type != other->type_info.type || if (self->type_info.type != other->type_info.type ||
self->type_class != other->type_class || self->type_class != other->type_class ||
upb_array_size(other->array) != n) { upb_Array_Size(other->array) != n) {
return Qfalse; return Qfalse;
} }
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
upb_msgval val1 = upb_array_get(self->array, i); upb_MessageValue val1 = upb_Array_Get(self->array, i);
upb_msgval val2 = upb_array_get(other->array, i); upb_MessageValue val2 = upb_Array_Get(other->array, i);
if (!Msgval_IsEqual(val1, val2, self->type_info)) { if (!Msgval_IsEqual(val1, val2, self->type_info)) {
return Qfalse; return Qfalse;
} }
@ -517,10 +517,10 @@ static VALUE RepeatedField_freeze(VALUE _self) {
VALUE RepeatedField_hash(VALUE _self) { VALUE RepeatedField_hash(VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
uint64_t hash = 0; uint64_t hash = 0;
size_t n = upb_array_size(self->array); size_t n = upb_Array_Size(self->array);
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
upb_msgval val = upb_array_get(self->array, i); upb_MessageValue val = upb_Array_Get(self->array, i);
hash = Msgval_GetHash(val, self->type_info, hash); hash = Msgval_GetHash(val, self->type_info, hash);
} }
@ -549,10 +549,10 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
RepeatedField* list_rptfield = ruby_to_RepeatedField(list); RepeatedField* list_rptfield = ruby_to_RepeatedField(list);
RepeatedField* dupped = ruby_to_RepeatedField(dupped_); RepeatedField* dupped = ruby_to_RepeatedField(dupped_);
upb_array *dupped_array = RepeatedField_GetMutable(dupped_); upb_Array* dupped_array = RepeatedField_GetMutable(dupped_);
upb_arena* arena = Arena_get(dupped->arena); upb_Arena* arena = Arena_get(dupped->arena);
Arena_fuse(list_rptfield->arena, arena); Arena_fuse(list_rptfield->arena, arena);
int size = upb_array_size(list_rptfield->array); int size = upb_Array_Size(list_rptfield->array);
int i; int i;
if (self->type_info.type != list_rptfield->type_info.type || if (self->type_info.type != list_rptfield->type_info.type ||
@ -562,8 +562,8 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
} }
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
upb_msgval msgval = upb_array_get(list_rptfield->array, i); upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i);
upb_array_append(dupped_array, msgval, arena); upb_Array_Append(dupped_array, msgval, arena);
} }
} else { } else {
rb_raise(rb_eArgError, "Unknown type appending to RepeatedField"); rb_raise(rb_eArgError, "Unknown type appending to RepeatedField");
@ -601,7 +601,7 @@ VALUE RepeatedField_concat(VALUE _self, VALUE list) {
*/ */
VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) { VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
RepeatedField* self = ruby_to_RepeatedField(_self); RepeatedField* self = ruby_to_RepeatedField(_self);
upb_arena *arena; upb_Arena* arena;
VALUE ary = Qnil; VALUE ary = Qnil;
self->arena = Arena_new(); self->arena = Arena_new();
@ -612,7 +612,7 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
} }
self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary); self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary);
self->array = upb_array_new(arena, self->type_info.type); self->array = upb_Array_New(arena, self->type_info.type);
ObjectCache_Add(self->array, _self); ObjectCache_Add(self->array, _self);
if (ary != Qnil) { if (ary != Qnil) {
@ -627,14 +627,12 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
} }
void RepeatedField_register(VALUE module) { void RepeatedField_register(VALUE module) {
VALUE klass = rb_define_class_under( VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject);
module, "RepeatedField", rb_cObject);
rb_define_alloc_func(klass, RepeatedField_alloc); rb_define_alloc_func(klass, RepeatedField_alloc);
rb_gc_register_address(&cRepeatedField); rb_gc_register_address(&cRepeatedField);
cRepeatedField = klass; cRepeatedField = klass;
rb_define_method(klass, "initialize", rb_define_method(klass, "initialize", RepeatedField_init, -1);
RepeatedField_init, -1);
rb_define_method(klass, "each", RepeatedField_each, 0); rb_define_method(klass, "each", RepeatedField_each, 0);
rb_define_method(klass, "[]", RepeatedField_index, -1); rb_define_method(klass, "[]", RepeatedField_index, -1);
rb_define_method(klass, "at", RepeatedField_index, -1); rb_define_method(klass, "at", RepeatedField_index, -1);

@ -36,19 +36,19 @@
#include "protobuf.h" #include "protobuf.h"
#include "ruby-upb.h" #include "ruby-upb.h"
// Returns a Ruby wrapper object for the given upb_array, which will be created // Returns a Ruby wrapper object for the given upb_Array, which will be created
// if one does not exist already. // if one does not exist already.
VALUE RepeatedField_GetRubyWrapper(upb_array* msg, TypeInfo type_info, VALUE RepeatedField_GetRubyWrapper(upb_Array* msg, TypeInfo type_info,
VALUE arena); VALUE arena);
// Gets the underlying upb_array for this Ruby RepeatedField object, which must // Gets the underlying upb_Array for this Ruby RepeatedField object, which must
// have a type that matches |f|. If this is not a repeated field or the type // have a type that matches |f|. If this is not a repeated field or the type
// doesn't match, raises an exception. // doesn't match, raises an exception.
const upb_array* RepeatedField_GetUpbArray(VALUE value, const upb_fielddef* f, const upb_Array* RepeatedField_GetUpbArray(VALUE value, const upb_FieldDef* f,
upb_arena* arena); upb_Arena* arena);
// Implements #inspect for this repeated field by appending its contents to |b|. // Implements #inspect for this repeated field by appending its contents to |b|.
void RepeatedField_Inspect(StringBuilder* b, const upb_array* array, void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
TypeInfo info); TypeInfo info);
// Returns a deep copy of this RepeatedField object. // Returns a deep copy of this RepeatedField object.

@ -2624,7 +2624,7 @@ static uint64_t WyhashMix(uint64_t v0, uint64_t v1) {
return low ^ high; return low ^ high;
} }
static uint64_t Wyhash(const void* data, size_t len, uint64_t seed, uint64_t Wyhash(const void* data, size_t len, uint64_t seed,
const uint64_t salt[]) { const uint64_t salt[]) {
const uint8_t* ptr = (const uint8_t*)data; const uint8_t* ptr = (const uint8_t*)data;
uint64_t starting_length = (uint64_t)len; uint64_t starting_length = (uint64_t)len;

@ -786,6 +786,10 @@ upb_DecodeStatus upb_Decode(const char* buf, size_t size, upb_Message* msg,
extern "C" { extern "C" {
#endif #endif
uint64_t Wyhash(const void* data, size_t len, uint64_t seed,
const uint64_t salt[]);
extern const uint64_t kWyhashSalt[5];
/* upb_value ******************************************************************/ /* upb_value ******************************************************************/
typedef struct { typedef struct {

@ -33,7 +33,8 @@
// On x86-64 Linux with glibc, we link against the 2.2.5 version of memcpy so // On x86-64 Linux with glibc, we link against the 2.2.5 version of memcpy so
// that we avoid depending on the 2.14 version of the symbol. This way, // that we avoid depending on the 2.14 version of the symbol. This way,
// distributions that are using pre-2.14 versions of glibc can successfully use // distributions that are using pre-2.14 versions of glibc can successfully use
// the gem we distribute (https://github.com/protocolbuffers/protobuf/issues/2783). // the gem we distribute
// (https://github.com/protocolbuffers/protobuf/issues/2783).
// //
// This wrapper is enabled by passing the linker flags -Wl,-wrap,memcpy in // This wrapper is enabled by passing the linker flags -Wl,-wrap,memcpy in
// extconf.rb. // extconf.rb.
@ -41,11 +42,11 @@
#if defined(__x86_64__) && defined(__GNU_LIBRARY__) #if defined(__x86_64__) && defined(__GNU_LIBRARY__)
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); __asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n) { void *__wrap_memcpy(void *dest, const void *src, size_t n) {
return memcpy(dest, src, n); return memcpy(dest, src, n);
} }
#else #else
void *__wrap_memcpy(void *dest, const void *src, size_t n) { void *__wrap_memcpy(void *dest, const void *src, size_t n) {
return memmove(dest, src, n); return memmove(dest, src, n);
} }
#endif #endif
#endif #endif

@ -816,11 +816,17 @@ module CommonTests
:optional_enum => :B, :optional_enum => :B,
:repeated_string => ["a", "b", "c"], :repeated_string => ["a", "b", "c"],
:repeated_int32 => [42, 43, 44], :repeated_int32 => [42, 43, 44],
:repeated_enum => [:A, :B, :C, 100], :repeated_enum => [:A, :B, :C],
:repeated_msg => [proto_module::TestMessage2.new(:foo => 1), :repeated_msg => [proto_module::TestMessage2.new(:foo => 1),
proto_module::TestMessage2.new(:foo => 2)]) proto_module::TestMessage2.new(:foo => 2)])
if proto_module == ::BasicTest
# For proto3 we can add an unknown enum value safely.
m.repeated_enum << 100
end
data = proto_module::TestMessage.encode m data = proto_module::TestMessage.encode m
m2 = proto_module::TestMessage.decode data m2 = proto_module::TestMessage.decode data
assert_equal m, m2 assert_equal m, m2
data = Google::Protobuf.encode m data = Google::Protobuf.encode m

Loading…
Cancel
Save