google-protobuf 3.17.2 → 3.23.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/convert.c +128 -116
  3. data/ext/google/protobuf_c/convert.h +12 -9
  4. data/ext/google/protobuf_c/defs.c +235 -1529
  5. data/ext/google/protobuf_c/defs.h +19 -19
  6. data/ext/google/protobuf_c/extconf.rb +12 -6
  7. data/ext/google/protobuf_c/map.c +105 -109
  8. data/ext/google/protobuf_c/map.h +7 -8
  9. data/ext/google/protobuf_c/message.c +447 -342
  10. data/ext/google/protobuf_c/message.h +22 -19
  11. data/ext/google/protobuf_c/protobuf.c +71 -59
  12. data/ext/google/protobuf_c/protobuf.h +13 -10
  13. data/ext/google/protobuf_c/repeated_field.c +83 -85
  14. data/ext/google/protobuf_c/repeated_field.h +6 -6
  15. data/ext/google/protobuf_c/ruby-upb.c +11760 -6644
  16. data/ext/google/protobuf_c/ruby-upb.h +10765 -3396
  17. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  18. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +92 -0
  19. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +157 -0
  20. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +170 -0
  21. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +21 -0
  22. data/ext/google/protobuf_c/wrap_memcpy.c +4 -3
  23. data/lib/google/protobuf/any_pb.rb +24 -5
  24. data/lib/google/protobuf/api_pb.rb +27 -23
  25. data/lib/google/protobuf/descriptor_dsl.rb +465 -0
  26. data/lib/google/protobuf/descriptor_pb.rb +75 -0
  27. data/lib/google/protobuf/duration_pb.rb +24 -5
  28. data/lib/google/protobuf/empty_pb.rb +24 -3
  29. data/lib/google/protobuf/field_mask_pb.rb +24 -4
  30. data/lib/google/protobuf/message_exts.rb +7 -2
  31. data/lib/google/protobuf/plugin_pb.rb +47 -0
  32. data/lib/google/protobuf/repeated_field.rb +15 -2
  33. data/lib/google/protobuf/source_context_pb.rb +24 -4
  34. data/lib/google/protobuf/struct_pb.rb +24 -20
  35. data/lib/google/protobuf/timestamp_pb.rb +24 -5
  36. data/lib/google/protobuf/type_pb.rb +27 -68
  37. data/lib/google/protobuf/well_known_types.rb +12 -2
  38. data/lib/google/protobuf/wrappers_pb.rb +24 -28
  39. data/lib/google/protobuf.rb +5 -73
  40. metadata +17 -36
  41. data/ext/google/protobuf_c/third_party/wyhash/wyhash.h +0 -145
  42. data/tests/basic.rb +0 -611
  43. data/tests/generated_code_test.rb +0 -23
  44. data/tests/stress.rb +0 -38
@@ -35,13 +35,13 @@
35
35
  #include "map.h"
36
36
  #include "protobuf.h"
37
37
  #include "repeated_field.h"
38
- #include "third_party/wyhash/wyhash.h"
39
38
 
40
39
  static VALUE cParseError = Qnil;
40
+ static VALUE cAbstractMessage = Qnil;
41
41
  static ID descriptor_instancevar_interned;
42
42
 
43
43
  static VALUE initialize_rb_class_with_no_args(VALUE klass) {
44
- return rb_funcall(klass, rb_intern("new"), 0);
44
+ return rb_funcall(klass, rb_intern("new"), 0);
45
45
  }
46
46
 
47
47
  VALUE MessageOrEnum_GetDescriptor(VALUE klass) {
@@ -53,20 +53,23 @@ VALUE MessageOrEnum_GetDescriptor(VALUE klass) {
53
53
  // -----------------------------------------------------------------------------
54
54
 
55
55
  typedef struct {
56
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
57
+ // macro to update VALUE references, as to trigger write barriers.
56
58
  VALUE arena;
57
- const upb_msg* msg; // Can get as mutable when non-frozen.
58
- const upb_msgdef* msgdef; // kept alive by self.class.descriptor reference.
59
+ const upb_Message* msg; // Can get as mutable when non-frozen.
60
+ const upb_MessageDef*
61
+ msgdef; // kept alive by self.class.descriptor reference.
59
62
  } Message;
60
63
 
61
64
  static void Message_mark(void* _self) {
62
- Message* self = (Message *)_self;
65
+ Message* self = (Message*)_self;
63
66
  rb_gc_mark(self->arena);
64
67
  }
65
68
 
66
69
  static rb_data_type_t Message_type = {
67
- "Message",
68
- { Message_mark, RUBY_DEFAULT_FREE, NULL },
69
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
70
+ "Google::Protobuf::Message",
71
+ {Message_mark, RUBY_DEFAULT_FREE, NULL},
72
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
70
73
  };
71
74
 
72
75
  static Message* ruby_to_Message(VALUE msg_rb) {
@@ -90,21 +93,21 @@ static VALUE Message_alloc(VALUE klass) {
90
93
  return ret;
91
94
  }
92
95
 
93
- const upb_msg *Message_Get(VALUE msg_rb, const upb_msgdef **m) {
96
+ const upb_Message* Message_Get(VALUE msg_rb, const upb_MessageDef** m) {
94
97
  Message* msg = ruby_to_Message(msg_rb);
95
98
  if (m) *m = msg->msgdef;
96
99
  return msg->msg;
97
100
  }
98
101
 
99
- upb_msg *Message_GetMutable(VALUE msg_rb, const upb_msgdef **m) {
102
+ upb_Message* Message_GetMutable(VALUE msg_rb, const upb_MessageDef** m) {
100
103
  rb_check_frozen(msg_rb);
101
- return (upb_msg*)Message_Get(msg_rb, m);
104
+ return (upb_Message*)Message_Get(msg_rb, m);
102
105
  }
103
106
 
104
- void Message_InitPtr(VALUE self_, upb_msg *msg, VALUE arena) {
107
+ void Message_InitPtr(VALUE self_, upb_Message* msg, VALUE arena) {
105
108
  Message* self = ruby_to_Message(self_);
106
109
  self->msg = msg;
107
- self->arena = arena;
110
+ RB_OBJ_WRITE(self_, &self->arena, arena);
108
111
  ObjectCache_Add(msg, self_);
109
112
  }
110
113
 
@@ -120,7 +123,8 @@ void Message_CheckClass(VALUE klass) {
120
123
  }
121
124
  }
122
125
 
123
- VALUE Message_GetRubyWrapper(upb_msg* msg, const upb_msgdef* m, VALUE arena) {
126
+ VALUE Message_GetRubyWrapper(upb_Message* msg, const upb_MessageDef* m,
127
+ VALUE arena) {
124
128
  if (msg == NULL) return Qnil;
125
129
 
126
130
  VALUE val = ObjectCache_Get(msg);
@@ -134,17 +138,18 @@ VALUE Message_GetRubyWrapper(upb_msg* msg, const upb_msgdef* m, VALUE arena) {
134
138
  return val;
135
139
  }
136
140
 
137
- void Message_PrintMessage(StringBuilder* b, const upb_msg* msg,
138
- const upb_msgdef* m) {
141
+ void Message_PrintMessage(StringBuilder* b, const upb_Message* msg,
142
+ const upb_MessageDef* m) {
139
143
  bool first = true;
140
- int n = upb_msgdef_fieldcount(m);
144
+ int n = upb_MessageDef_FieldCount(m);
141
145
  VALUE klass = Descriptor_DefToClass(m);
142
146
  StringBuilder_Printf(b, "<%s: ", rb_class2name(klass));
143
147
 
144
148
  for (int i = 0; i < n; i++) {
145
- const upb_fielddef* field = upb_msgdef_field(m, i);
149
+ const upb_FieldDef* field = upb_MessageDef_Field(m, i);
146
150
 
147
- if (upb_fielddef_haspresence(field) && !upb_msg_has(msg, field)) {
151
+ if (upb_FieldDef_HasPresence(field) &&
152
+ !upb_Message_HasFieldByDef(msg, field)) {
148
153
  continue;
149
154
  }
150
155
 
@@ -154,17 +159,17 @@ void Message_PrintMessage(StringBuilder* b, const upb_msg* msg,
154
159
  first = false;
155
160
  }
156
161
 
157
- upb_msgval msgval = upb_msg_get(msg, field);
162
+ upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, field);
158
163
 
159
- StringBuilder_Printf(b, "%s: ", upb_fielddef_name(field));
164
+ StringBuilder_Printf(b, "%s: ", upb_FieldDef_Name(field));
160
165
 
161
- if (upb_fielddef_ismap(field)) {
162
- const upb_msgdef* entry_m = upb_fielddef_msgsubdef(field);
163
- const upb_fielddef* key_f = upb_msgdef_itof(entry_m, 1);
164
- const upb_fielddef* val_f = upb_msgdef_itof(entry_m, 2);
166
+ if (upb_FieldDef_IsMap(field)) {
167
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field);
168
+ const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1);
169
+ const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
165
170
  TypeInfo val_info = TypeInfo_get(val_f);
166
- Map_Inspect(b, msgval.map_val, upb_fielddef_type(key_f), val_info);
167
- } else if (upb_fielddef_isseq(field)) {
171
+ Map_Inspect(b, msgval.map_val, upb_FieldDef_CType(key_f), val_info);
172
+ } else if (upb_FieldDef_IsRepeated(field)) {
168
173
  RepeatedField_Inspect(b, msgval.array_val, TypeInfo_get(field));
169
174
  } else {
170
175
  StringBuilder_PrintMsgval(b, msgval, TypeInfo_get(field));
@@ -188,14 +193,31 @@ enum {
188
193
  };
189
194
 
190
195
  // Check if the field is a well known wrapper type
191
- static bool IsWrapper(const upb_fielddef* f) {
192
- return upb_fielddef_issubmsg(f) &&
193
- upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f));
196
+ static bool IsWrapper(const upb_MessageDef* m) {
197
+ if (!m) return false;
198
+ switch (upb_MessageDef_WellKnownType(m)) {
199
+ case kUpb_WellKnown_DoubleValue:
200
+ case kUpb_WellKnown_FloatValue:
201
+ case kUpb_WellKnown_Int64Value:
202
+ case kUpb_WellKnown_UInt64Value:
203
+ case kUpb_WellKnown_Int32Value:
204
+ case kUpb_WellKnown_UInt32Value:
205
+ case kUpb_WellKnown_StringValue:
206
+ case kUpb_WellKnown_BytesValue:
207
+ case kUpb_WellKnown_BoolValue:
208
+ return true;
209
+ default:
210
+ return false;
211
+ }
212
+ }
213
+
214
+ static bool IsFieldWrapper(const upb_FieldDef* f) {
215
+ return IsWrapper(upb_FieldDef_MessageSubDef(f));
194
216
  }
195
217
 
196
- static bool Match(const upb_msgdef* m, const char* name, const upb_fielddef** f,
197
- const upb_oneofdef** o, const char* prefix,
198
- const char* suffix) {
218
+ static bool Match(const upb_MessageDef* m, const char* name,
219
+ const upb_FieldDef** f, const upb_OneofDef** o,
220
+ const char* prefix, const char* suffix) {
199
221
  size_t sp = strlen(prefix);
200
222
  size_t ss = strlen(suffix);
201
223
  size_t sn = strlen(name);
@@ -207,12 +229,12 @@ static bool Match(const upb_msgdef* m, const char* name, const upb_fielddef** f,
207
229
  return false;
208
230
  }
209
231
 
210
- return upb_msgdef_lookupname(m, name + sp, sn - sp - ss, f, o);
232
+ return upb_MessageDef_FindByNameWithSize(m, name + sp, sn - sp - ss, f, o);
211
233
  }
212
234
 
213
235
  static int extract_method_call(VALUE method_name, Message* self,
214
- const upb_fielddef** f, const upb_oneofdef** o) {
215
- const upb_msgdef* m = self->msgdef;
236
+ const upb_FieldDef** f, const upb_OneofDef** o) {
237
+ const upb_MessageDef* m = self->msgdef;
216
238
  const char* name;
217
239
 
218
240
  Check_Type(method_name, T_SYMBOL);
@@ -222,156 +244,153 @@ static int extract_method_call(VALUE method_name, Message* self,
222
244
  if (Match(m, name, f, o, "", "=")) return METHOD_SETTER;
223
245
  if (Match(m, name, f, o, "clear_", "")) return METHOD_CLEAR;
224
246
  if (Match(m, name, f, o, "has_", "?") &&
225
- (*o || (*f && upb_fielddef_haspresence(*f)))) {
226
- // Disallow oneof hazzers for proto3.
227
- // TODO(haberman): remove this test when we are enabling oneof hazzers for
228
- // proto3.
229
- if (*f && !upb_fielddef_issubmsg(*f) &&
230
- upb_fielddef_realcontainingoneof(*f) &&
231
- upb_msgdef_syntax(upb_fielddef_containingtype(*f)) !=
232
- UPB_SYNTAX_PROTO2) {
233
- return METHOD_UNKNOWN;
234
- }
247
+ (*o || (*f && upb_FieldDef_HasPresence(*f)))) {
235
248
  return METHOD_PRESENCE;
236
249
  }
237
- if (Match(m, name, f, o, "", "_as_value") && *f && !upb_fielddef_isseq(*f) &&
238
- IsWrapper(*f)) {
250
+ if (Match(m, name, f, o, "", "_as_value") && *f &&
251
+ !upb_FieldDef_IsRepeated(*f) && IsFieldWrapper(*f)) {
239
252
  return METHOD_WRAPPER_GETTER;
240
253
  }
241
- if (Match(m, name, f, o, "", "_as_value=") && *f && !upb_fielddef_isseq(*f) &&
242
- IsWrapper(*f)) {
254
+ if (Match(m, name, f, o, "", "_as_value=") && *f &&
255
+ !upb_FieldDef_IsRepeated(*f) && IsFieldWrapper(*f)) {
243
256
  return METHOD_WRAPPER_SETTER;
244
257
  }
245
258
  if (Match(m, name, f, o, "", "_const") && *f &&
246
- upb_fielddef_type(*f) == UPB_TYPE_ENUM) {
259
+ upb_FieldDef_CType(*f) == kUpb_CType_Enum) {
247
260
  return METHOD_ENUM_GETTER;
248
261
  }
249
262
 
250
263
  return METHOD_UNKNOWN;
251
264
  }
252
265
 
253
- static VALUE Message_oneof_accessor(VALUE _self, const upb_oneofdef* o,
266
+ static VALUE Message_oneof_accessor(VALUE _self, const upb_OneofDef* o,
254
267
  int accessor_type) {
255
268
  Message* self = ruby_to_Message(_self);
256
- const upb_fielddef* oneof_field = upb_msg_whichoneof(self->msg, o);
269
+ const upb_FieldDef* oneof_field = upb_Message_WhichOneof(self->msg, o);
257
270
 
258
271
  switch (accessor_type) {
259
272
  case METHOD_PRESENCE:
260
273
  return oneof_field == NULL ? Qfalse : Qtrue;
261
274
  case METHOD_CLEAR:
262
275
  if (oneof_field != NULL) {
263
- upb_msg_clearfield(Message_GetMutable(_self, NULL), oneof_field);
276
+ upb_Message_ClearFieldByDef(Message_GetMutable(_self, NULL),
277
+ oneof_field);
264
278
  }
265
279
  return Qnil;
266
280
  case METHOD_GETTER:
267
281
  return oneof_field == NULL
268
282
  ? Qnil
269
- : ID2SYM(rb_intern(upb_fielddef_name(oneof_field)));
283
+ : ID2SYM(rb_intern(upb_FieldDef_Name(oneof_field)));
270
284
  case METHOD_SETTER:
271
285
  rb_raise(rb_eRuntimeError, "Oneof accessors are read-only.");
272
286
  }
273
287
  rb_raise(rb_eRuntimeError, "Invalid access of oneof field.");
274
288
  }
275
289
 
276
- static void Message_setfield(upb_msg* msg, const upb_fielddef* f, VALUE val,
277
- upb_arena* arena) {
278
- upb_msgval msgval;
279
- if (upb_fielddef_ismap(f)) {
290
+ static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val,
291
+ upb_Arena* arena) {
292
+ upb_MessageValue msgval;
293
+ if (upb_FieldDef_IsMap(f)) {
280
294
  msgval.map_val = Map_GetUpbMap(val, f, arena);
281
- } else if (upb_fielddef_isseq(f)) {
295
+ } else if (upb_FieldDef_IsRepeated(f)) {
282
296
  msgval.array_val = RepeatedField_GetUpbArray(val, f, arena);
283
297
  } else {
284
298
  if (val == Qnil &&
285
- (upb_fielddef_issubmsg(f) || upb_fielddef_realcontainingoneof(f))) {
286
- upb_msg_clearfield(msg, f);
299
+ (upb_FieldDef_IsSubMessage(f) || upb_FieldDef_RealContainingOneof(f))) {
300
+ upb_Message_ClearFieldByDef(msg, f);
287
301
  return;
288
302
  }
289
303
  msgval =
290
- Convert_RubyToUpb(val, upb_fielddef_name(f), TypeInfo_get(f), arena);
304
+ Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
291
305
  }
292
- upb_msg_set(msg, f, msgval, arena);
306
+ upb_Message_SetFieldByDef(msg, f, msgval, arena);
293
307
  }
294
308
 
295
- VALUE Message_getfield(VALUE _self, const upb_fielddef* f) {
309
+ VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) {
296
310
  Message* self = ruby_to_Message(_self);
297
- // This is a special-case: upb_msg_mutable() for map & array are logically
311
+ // This is a special-case: upb_Message_Mutable() for map & array are logically
298
312
  // const (they will not change what is serialized) but physically
299
313
  // non-const, as they do allocate a repeated field or map. The logical
300
314
  // constness means it's ok to do even if the message is frozen.
301
- upb_msg *msg = (upb_msg*)self->msg;
302
- upb_arena *arena = Arena_get(self->arena);
303
- if (upb_fielddef_ismap(f)) {
304
- upb_map *map = upb_msg_mutable(msg, f, arena).map;
305
- const upb_fielddef *key_f = map_field_key(f);
306
- const upb_fielddef *val_f = map_field_value(f);
307
- upb_fieldtype_t key_type = upb_fielddef_type(key_f);
315
+ upb_Message* msg = (upb_Message*)self->msg;
316
+ upb_Arena* arena = Arena_get(self->arena);
317
+ if (upb_FieldDef_IsMap(f)) {
318
+ upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
319
+ const upb_FieldDef* key_f = map_field_key(f);
320
+ const upb_FieldDef* val_f = map_field_value(f);
321
+ upb_CType key_type = upb_FieldDef_CType(key_f);
308
322
  TypeInfo value_type_info = TypeInfo_get(val_f);
309
323
  return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena);
310
- } else if (upb_fielddef_isseq(f)) {
311
- upb_array *arr = upb_msg_mutable(msg, f, arena).array;
324
+ } else if (upb_FieldDef_IsRepeated(f)) {
325
+ upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
312
326
  return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena);
313
- } else if (upb_fielddef_issubmsg(f)) {
314
- if (!upb_msg_has(self->msg, f)) return Qnil;
315
- upb_msg *submsg = upb_msg_mutable(msg, f, arena).msg;
316
- const upb_msgdef *m = upb_fielddef_msgsubdef(f);
327
+ } else if (upb_FieldDef_IsSubMessage(f)) {
328
+ if (!upb_Message_HasFieldByDef(self->msg, f)) return Qnil;
329
+ upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg;
330
+ const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f);
317
331
  return Message_GetRubyWrapper(submsg, m, self->arena);
318
332
  } else {
319
- upb_msgval msgval = upb_msg_get(self->msg, f);
333
+ upb_MessageValue msgval = upb_Message_GetFieldByDef(self->msg, f);
320
334
  return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena);
321
335
  }
322
336
  }
323
337
 
324
- static VALUE Message_field_accessor(VALUE _self, const upb_fielddef* f,
338
+ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f,
325
339
  int accessor_type, int argc, VALUE* argv) {
326
- upb_arena *arena = Arena_get(Message_GetArena(_self));
340
+ upb_Arena* arena = Arena_get(Message_GetArena(_self));
327
341
 
328
342
  switch (accessor_type) {
329
343
  case METHOD_SETTER:
330
344
  Message_setfield(Message_GetMutable(_self, NULL), f, argv[1], arena);
331
345
  return Qnil;
332
346
  case METHOD_CLEAR:
333
- upb_msg_clearfield(Message_GetMutable(_self, NULL), f);
347
+ upb_Message_ClearFieldByDef(Message_GetMutable(_self, NULL), f);
334
348
  return Qnil;
335
349
  case METHOD_PRESENCE:
336
- if (!upb_fielddef_haspresence(f)) {
350
+ if (!upb_FieldDef_HasPresence(f)) {
337
351
  rb_raise(rb_eRuntimeError, "Field does not have presence.");
338
352
  }
339
- return upb_msg_has(Message_Get(_self, NULL), f);
353
+ return upb_Message_HasFieldByDef(Message_Get(_self, NULL), f);
340
354
  case METHOD_WRAPPER_GETTER: {
341
355
  Message* self = ruby_to_Message(_self);
342
- if (upb_msg_has(self->msg, f)) {
343
- PBRUBY_ASSERT(upb_fielddef_issubmsg(f) && !upb_fielddef_isseq(f));
344
- upb_msgval wrapper = upb_msg_get(self->msg, f);
345
- const upb_msgdef *wrapper_m = upb_fielddef_msgsubdef(f);
346
- const upb_fielddef *value_f = upb_msgdef_itof(wrapper_m, 1);
347
- upb_msgval value = upb_msg_get(wrapper.msg_val, value_f);
356
+ if (upb_Message_HasFieldByDef(self->msg, f)) {
357
+ PBRUBY_ASSERT(upb_FieldDef_IsSubMessage(f) &&
358
+ !upb_FieldDef_IsRepeated(f));
359
+ upb_MessageValue wrapper = upb_Message_GetFieldByDef(self->msg, f);
360
+ const upb_MessageDef* wrapper_m = upb_FieldDef_MessageSubDef(f);
361
+ const upb_FieldDef* value_f =
362
+ upb_MessageDef_FindFieldByNumber(wrapper_m, 1);
363
+ upb_MessageValue value =
364
+ upb_Message_GetFieldByDef(wrapper.msg_val, value_f);
348
365
  return Convert_UpbToRuby(value, TypeInfo_get(value_f), self->arena);
349
366
  } else {
350
367
  return Qnil;
351
368
  }
352
369
  }
353
370
  case METHOD_WRAPPER_SETTER: {
354
- upb_msg *msg = Message_GetMutable(_self, NULL);
371
+ upb_Message* msg = Message_GetMutable(_self, NULL);
355
372
  if (argv[1] == Qnil) {
356
- upb_msg_clearfield(msg, f);
373
+ upb_Message_ClearFieldByDef(msg, f);
357
374
  } else {
358
- const upb_fielddef *val_f = upb_msgdef_itof(upb_fielddef_msgsubdef(f), 1);
359
- upb_msgval msgval = Convert_RubyToUpb(argv[1], upb_fielddef_name(f),
360
- TypeInfo_get(val_f), arena);
361
- upb_msg *wrapper = upb_msg_mutable(msg, f, arena).msg;
362
- upb_msg_set(wrapper, val_f, msgval, arena);
375
+ const upb_FieldDef* val_f =
376
+ upb_MessageDef_FindFieldByNumber(upb_FieldDef_MessageSubDef(f), 1);
377
+ upb_MessageValue msgval = Convert_RubyToUpb(
378
+ argv[1], upb_FieldDef_Name(f), TypeInfo_get(val_f), arena);
379
+ upb_Message* wrapper = upb_Message_Mutable(msg, f, arena).msg;
380
+ upb_Message_SetFieldByDef(wrapper, val_f, msgval, arena);
363
381
  }
364
382
  return Qnil;
365
383
  }
366
384
  case METHOD_ENUM_GETTER: {
367
- upb_msgval msgval = upb_msg_get(Message_Get(_self, NULL), f);
385
+ upb_MessageValue msgval =
386
+ upb_Message_GetFieldByDef(Message_Get(_self, NULL), f);
368
387
 
369
- if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
388
+ if (upb_FieldDef_Label(f) == kUpb_Label_Repeated) {
370
389
  // Map repeated fields to a new type with ints
371
390
  VALUE arr = rb_ary_new();
372
- size_t i, n = upb_array_size(msgval.array_val);
391
+ size_t i, n = upb_Array_Size(msgval.array_val);
373
392
  for (i = 0; i < n; i++) {
374
- upb_msgval elem = upb_array_get(msgval.array_val, i);
393
+ upb_MessageValue elem = upb_Array_Get(msgval.array_val, i);
375
394
  rb_ary_push(arr, INT2NUM(elem.int32_val));
376
395
  }
377
396
  return arr;
@@ -416,8 +435,8 @@ static VALUE Message_field_accessor(VALUE _self, const upb_fielddef* f,
416
435
  */
417
436
  static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
418
437
  Message* self = ruby_to_Message(_self);
419
- const upb_oneofdef* o;
420
- const upb_fielddef* f;
438
+ const upb_OneofDef* o;
439
+ const upb_FieldDef* f;
421
440
  int accessor_type;
422
441
 
423
442
  if (argc < 1) {
@@ -454,8 +473,8 @@ static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
454
473
 
455
474
  static VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) {
456
475
  Message* self = ruby_to_Message(_self);
457
- const upb_oneofdef* o;
458
- const upb_fielddef* f;
476
+ const upb_OneofDef* o;
477
+ const upb_FieldDef* f;
459
478
  int accessor_type;
460
479
 
461
480
  if (argc < 1) {
@@ -473,53 +492,55 @@ static VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) {
473
492
  }
474
493
  }
475
494
 
476
- void Message_InitFromValue(upb_msg* msg, const upb_msgdef* m, VALUE val,
477
- upb_arena* arena);
495
+ void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val,
496
+ upb_Arena* arena);
478
497
 
479
498
  typedef struct {
480
- upb_map *map;
499
+ upb_Map* map;
481
500
  TypeInfo key_type;
482
501
  TypeInfo val_type;
483
- upb_arena *arena;
502
+ upb_Arena* arena;
484
503
  } MapInit;
485
504
 
486
505
  static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
487
- MapInit *map_init = (MapInit*)_self;
488
- upb_msgval k, v;
506
+ MapInit* map_init = (MapInit*)_self;
507
+ upb_MessageValue k, v;
489
508
  k = Convert_RubyToUpb(key, "", map_init->key_type, NULL);
490
509
 
491
- if (map_init->val_type.type == UPB_TYPE_MESSAGE && TYPE(val) == T_HASH) {
492
- upb_msg *msg = upb_msg_new(map_init->val_type.def.msgdef, map_init->arena);
510
+ if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) {
511
+ upb_MiniTable* t = upb_MessageDef_MiniTable(map_init->val_type.def.msgdef);
512
+ upb_Message* msg = upb_Message_New(t, map_init->arena);
493
513
  Message_InitFromValue(msg, map_init->val_type.def.msgdef, val,
494
514
  map_init->arena);
495
515
  v.msg_val = msg;
496
516
  } else {
497
517
  v = Convert_RubyToUpb(val, "", map_init->val_type, map_init->arena);
498
518
  }
499
- upb_map_set(map_init->map, k, v, map_init->arena);
519
+ upb_Map_Set(map_init->map, k, v, map_init->arena);
500
520
  return ST_CONTINUE;
501
521
  }
502
522
 
503
- static void Map_InitFromValue(upb_map* map, const upb_fielddef* f, VALUE val,
504
- upb_arena* arena) {
505
- const upb_msgdef* entry_m = upb_fielddef_msgsubdef(f);
506
- const upb_fielddef* key_f = upb_msgdef_itof(entry_m, 1);
507
- const upb_fielddef* val_f = upb_msgdef_itof(entry_m, 2);
523
+ static void Map_InitFromValue(upb_Map* map, const upb_FieldDef* f, VALUE val,
524
+ upb_Arena* arena) {
525
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
526
+ const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1);
527
+ const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
508
528
  if (TYPE(val) != T_HASH) {
509
529
  rb_raise(rb_eArgError,
510
530
  "Expected Hash object as initializer value for map field '%s' "
511
531
  "(given %s).",
512
- upb_fielddef_name(f), rb_class2name(CLASS_OF(val)));
532
+ upb_FieldDef_Name(f), rb_class2name(CLASS_OF(val)));
513
533
  }
514
534
  MapInit map_init = {map, TypeInfo_get(key_f), TypeInfo_get(val_f), arena};
515
535
  rb_hash_foreach(val, Map_initialize_kwarg, (VALUE)&map_init);
516
536
  }
517
537
 
518
- static upb_msgval MessageValue_FromValue(VALUE val, TypeInfo info,
519
- upb_arena* arena) {
520
- if (info.type == UPB_TYPE_MESSAGE) {
521
- upb_msgval msgval;
522
- upb_msg* msg = upb_msg_new(info.def.msgdef, arena);
538
+ static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info,
539
+ upb_Arena* arena) {
540
+ if (info.type == kUpb_CType_Message) {
541
+ upb_MessageValue msgval;
542
+ upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef);
543
+ upb_Message* msg = upb_Message_New(t, arena);
523
544
  Message_InitFromValue(msg, info.def.msgdef, val, arena);
524
545
  msgval.msg_val = msg;
525
546
  return msgval;
@@ -528,61 +549,62 @@ static upb_msgval MessageValue_FromValue(VALUE val, TypeInfo info,
528
549
  }
529
550
  }
530
551
 
531
- static void RepeatedField_InitFromValue(upb_array* arr, const upb_fielddef* f,
532
- VALUE val, upb_arena* arena) {
552
+ static void RepeatedField_InitFromValue(upb_Array* arr, const upb_FieldDef* f,
553
+ VALUE val, upb_Arena* arena) {
533
554
  TypeInfo type_info = TypeInfo_get(f);
534
555
 
535
556
  if (TYPE(val) != T_ARRAY) {
536
557
  rb_raise(rb_eArgError,
537
- "Expected array as initializer value for repeated field '%s' (given %s).",
538
- upb_fielddef_name(f), rb_class2name(CLASS_OF(val)));
558
+ "Expected array as initializer value for repeated field '%s' "
559
+ "(given %s).",
560
+ upb_FieldDef_Name(f), rb_class2name(CLASS_OF(val)));
539
561
  }
540
562
 
541
563
  for (int i = 0; i < RARRAY_LEN(val); i++) {
542
564
  VALUE entry = rb_ary_entry(val, i);
543
- upb_msgval msgval;
544
- if (upb_fielddef_issubmsg(f) && TYPE(entry) == T_HASH) {
565
+ upb_MessageValue msgval;
566
+ if (upb_FieldDef_IsSubMessage(f) && TYPE(entry) == T_HASH) {
545
567
  msgval = MessageValue_FromValue(entry, type_info, arena);
546
568
  } else {
547
- msgval = Convert_RubyToUpb(entry, upb_fielddef_name(f), type_info, arena);
569
+ msgval = Convert_RubyToUpb(entry, upb_FieldDef_Name(f), type_info, arena);
548
570
  }
549
- upb_array_append(arr, msgval, arena);
571
+ upb_Array_Append(arr, msgval, arena);
550
572
  }
551
573
  }
552
574
 
553
- static void Message_InitFieldFromValue(upb_msg* msg, const upb_fielddef* f,
554
- VALUE val, upb_arena* arena) {
575
+ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f,
576
+ VALUE val, upb_Arena* arena) {
555
577
  if (TYPE(val) == T_NIL) return;
556
578
 
557
- if (upb_fielddef_ismap(f)) {
558
- upb_map *map = upb_msg_mutable(msg, f, arena).map;
579
+ if (upb_FieldDef_IsMap(f)) {
580
+ upb_Map* map = upb_Message_Mutable(msg, f, arena).map;
559
581
  Map_InitFromValue(map, f, val, arena);
560
- } else if (upb_fielddef_label(f) == UPB_LABEL_REPEATED) {
561
- upb_array *arr = upb_msg_mutable(msg, f, arena).array;
582
+ } else if (upb_FieldDef_Label(f) == kUpb_Label_Repeated) {
583
+ upb_Array* arr = upb_Message_Mutable(msg, f, arena).array;
562
584
  RepeatedField_InitFromValue(arr, f, val, arena);
563
- } else if (upb_fielddef_issubmsg(f)) {
585
+ } else if (upb_FieldDef_IsSubMessage(f)) {
564
586
  if (TYPE(val) == T_HASH) {
565
- upb_msg *submsg = upb_msg_mutable(msg, f, arena).msg;
566
- Message_InitFromValue(submsg, upb_fielddef_msgsubdef(f), val, arena);
587
+ upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg;
588
+ Message_InitFromValue(submsg, upb_FieldDef_MessageSubDef(f), val, arena);
567
589
  } else {
568
590
  Message_setfield(msg, f, val, arena);
569
591
  }
570
592
  } else {
571
- upb_msgval msgval =
572
- Convert_RubyToUpb(val, upb_fielddef_name(f), TypeInfo_get(f), arena);
573
- upb_msg_set(msg, f, msgval, arena);
593
+ upb_MessageValue msgval =
594
+ Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
595
+ upb_Message_SetFieldByDef(msg, f, msgval, arena);
574
596
  }
575
597
  }
576
598
 
577
599
  typedef struct {
578
- upb_msg *msg;
579
- const upb_msgdef *msgdef;
580
- upb_arena *arena;
600
+ upb_Message* msg;
601
+ const upb_MessageDef* msgdef;
602
+ upb_Arena* arena;
581
603
  } MsgInit;
582
604
 
583
605
  static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
584
- MsgInit *msg_init = (MsgInit*)_self;
585
- const char *name;
606
+ MsgInit* msg_init = (MsgInit*)_self;
607
+ const char* name;
586
608
 
587
609
  if (TYPE(key) == T_STRING) {
588
610
  name = RSTRING_PTR(key);
@@ -590,10 +612,12 @@ static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
590
612
  name = RSTRING_PTR(rb_id2str(SYM2ID(key)));
591
613
  } else {
592
614
  rb_raise(rb_eArgError,
593
- "Expected string or symbols as hash keys when initializing proto from hash.");
615
+ "Expected string or symbols as hash keys when initializing proto "
616
+ "from hash.");
594
617
  }
595
618
 
596
- const upb_fielddef* f = upb_msgdef_ntofz(msg_init->msgdef, name);
619
+ const upb_FieldDef* f =
620
+ upb_MessageDef_FindFieldByName(msg_init->msgdef, name);
597
621
 
598
622
  if (f == NULL) {
599
623
  rb_raise(rb_eArgError,
@@ -604,8 +628,8 @@ static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
604
628
  return ST_CONTINUE;
605
629
  }
606
630
 
607
- void Message_InitFromValue(upb_msg* msg, const upb_msgdef* m, VALUE val,
608
- upb_arena* arena) {
631
+ void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val,
632
+ upb_Arena* arena) {
609
633
  MsgInit msg_init = {msg, m, arena};
610
634
  if (TYPE(val) == T_HASH) {
611
635
  rb_hash_foreach(val, Message_initialize_kwarg, (VALUE)&msg_init);
@@ -630,8 +654,9 @@ void Message_InitFromValue(upb_msg* msg, const upb_msgdef* m, VALUE val,
630
654
  static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
631
655
  Message* self = ruby_to_Message(_self);
632
656
  VALUE arena_rb = Arena_new();
633
- upb_arena *arena = Arena_get(arena_rb);
634
- upb_msg *msg = upb_msg_new(self->msgdef, arena);
657
+ upb_Arena* arena = Arena_get(arena_rb);
658
+ upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef);
659
+ upb_Message* msg = upb_Message_New(t, arena);
635
660
 
636
661
  Message_InitPtr(_self, msg, arena_rb);
637
662
 
@@ -641,7 +666,7 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
641
666
  if (argc != 1) {
642
667
  rb_raise(rb_eArgError, "Expected 0 or 1 arguments.");
643
668
  }
644
- Message_InitFromValue((upb_msg*)self->msg, self->msgdef, argv[0], arena);
669
+ Message_InitFromValue((upb_Message*)self->msg, self->msgdef, argv[0], arena);
645
670
  return Qnil;
646
671
  }
647
672
 
@@ -655,34 +680,40 @@ static VALUE Message_dup(VALUE _self) {
655
680
  Message* self = ruby_to_Message(_self);
656
681
  VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
657
682
  Message* new_msg_self = ruby_to_Message(new_msg);
658
- size_t size = upb_msgdef_layout(self->msgdef)->size;
683
+ size_t size = upb_MessageDef_MiniTable(self->msgdef)->size;
659
684
 
660
685
  // TODO(copy unknown fields?)
661
686
  // TODO(use official upb msg copy function)
662
- memcpy((upb_msg*)new_msg_self->msg, self->msg, size);
687
+ memcpy((upb_Message*)new_msg_self->msg, self->msg, size);
663
688
  Arena_fuse(self->arena, Arena_get(new_msg_self->arena));
664
689
  return new_msg;
665
690
  }
666
691
 
667
692
  // Support function for Message_eq, and also used by other #eq functions.
668
- bool Message_Equal(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m) {
693
+ bool Message_Equal(const upb_Message* m1, const upb_Message* m2,
694
+ const upb_MessageDef* m) {
669
695
  if (m1 == m2) return true;
670
696
 
671
697
  size_t size1, size2;
672
- int encode_opts = UPB_ENCODE_SKIPUNKNOWN | UPB_ENCODE_DETERMINISTIC;
673
- upb_arena *arena_tmp = upb_arena_new();
674
- const upb_msglayout *layout = upb_msgdef_layout(m);
698
+ int encode_opts =
699
+ kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_Deterministic;
700
+ upb_Arena* arena_tmp = upb_Arena_New();
701
+ const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
675
702
 
676
703
  // Compare deterministically serialized payloads with no unknown fields.
677
- char *data1 = upb_encode_ex(m1, layout, encode_opts, arena_tmp, &size1);
678
- char *data2 = upb_encode_ex(m2, layout, encode_opts, arena_tmp, &size2);
679
-
680
- if (data1 && data2) {
704
+ char* data1;
705
+ char* data2;
706
+ upb_EncodeStatus status1 =
707
+ upb_Encode(m1, layout, encode_opts, arena_tmp, &data1, &size1);
708
+ upb_EncodeStatus status2 =
709
+ upb_Encode(m2, layout, encode_opts, arena_tmp, &data2, &size2);
710
+
711
+ if (status1 == kUpb_EncodeStatus_Ok && status2 == kUpb_EncodeStatus_Ok) {
681
712
  bool ret = (size1 == size2) && (memcmp(data1, data2, size1) == 0);
682
- upb_arena_free(arena_tmp);
713
+ upb_Arena_Free(arena_tmp);
683
714
  return ret;
684
715
  } else {
685
- upb_arena_free(arena_tmp);
716
+ upb_Arena_Free(arena_tmp);
686
717
  rb_raise(cParseError, "Error comparing messages");
687
718
  }
688
719
  }
@@ -706,22 +737,24 @@ static VALUE Message_eq(VALUE _self, VALUE _other) {
706
737
  return Message_Equal(self->msg, other->msg, self->msgdef) ? Qtrue : Qfalse;
707
738
  }
708
739
 
709
- uint64_t Message_Hash(const upb_msg* msg, const upb_msgdef* m, uint64_t seed) {
710
- upb_arena *arena = upb_arena_new();
711
- const char *data;
740
+ uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
741
+ uint64_t seed) {
742
+ upb_Arena* arena = upb_Arena_New();
743
+ char* data;
712
744
  size_t size;
713
745
 
714
746
  // Hash a deterministically serialized payloads with no unknown fields.
715
- data = upb_encode_ex(msg, upb_msgdef_layout(m),
716
- UPB_ENCODE_SKIPUNKNOWN | UPB_ENCODE_DETERMINISTIC, arena,
717
- &size);
718
-
719
- if (data) {
720
- uint64_t ret = wyhash(data, size, seed, _wyp);
721
- upb_arena_free(arena);
747
+ upb_EncodeStatus status = upb_Encode(
748
+ msg, upb_MessageDef_MiniTable(m),
749
+ kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_Deterministic, arena,
750
+ &data, &size);
751
+
752
+ if (status == kUpb_EncodeStatus_Ok) {
753
+ uint64_t ret = _upb_Hash(data, size, seed);
754
+ upb_Arena_Free(arena);
722
755
  return ret;
723
756
  } else {
724
- upb_arena_free(arena);
757
+ upb_Arena_Free(arena);
725
758
  rb_raise(cParseError, "Error calculating hash");
726
759
  }
727
760
  }
@@ -760,13 +793,13 @@ static VALUE Message_inspect(VALUE _self) {
760
793
 
761
794
  // Support functions for Message_to_h //////////////////////////////////////////
762
795
 
763
- static VALUE RepeatedField_CreateArray(const upb_array* arr,
796
+ static VALUE RepeatedField_CreateArray(const upb_Array* arr,
764
797
  TypeInfo type_info) {
765
- int size = arr ? upb_array_size(arr) : 0;
798
+ int size = arr ? upb_Array_Size(arr) : 0;
766
799
  VALUE ary = rb_ary_new2(size);
767
800
 
768
801
  for (int i = 0; i < size; i++) {
769
- upb_msgval msgval = upb_array_get(arr, i);
802
+ upb_MessageValue msgval = upb_Array_Get(arr, i);
770
803
  VALUE val = Scalar_CreateHash(msgval, type_info);
771
804
  rb_ary_push(ary, val);
772
805
  }
@@ -774,54 +807,56 @@ static VALUE RepeatedField_CreateArray(const upb_array* arr,
774
807
  return ary;
775
808
  }
776
809
 
777
- static VALUE Message_CreateHash(const upb_msg *msg, const upb_msgdef *m) {
810
+ static VALUE Message_CreateHash(const upb_Message* msg,
811
+ const upb_MessageDef* m) {
778
812
  if (!msg) return Qnil;
779
813
 
780
814
  VALUE hash = rb_hash_new();
781
- int n = upb_msgdef_fieldcount(m);
815
+ int n = upb_MessageDef_FieldCount(m);
782
816
  bool is_proto2;
783
817
 
784
818
  // We currently have a few behaviors that are specific to proto2.
785
819
  // This is unfortunate, we should key behaviors off field attributes (like
786
820
  // whether a field has presence), not proto2 vs. proto3. We should see if we
787
821
  // can change this without breaking users.
788
- is_proto2 = upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2;
822
+ is_proto2 = upb_MessageDef_Syntax(m) == kUpb_Syntax_Proto2;
789
823
 
790
824
  for (int i = 0; i < n; i++) {
791
- const upb_fielddef* field = upb_msgdef_field(m, i);
825
+ const upb_FieldDef* field = upb_MessageDef_Field(m, i);
792
826
  TypeInfo type_info = TypeInfo_get(field);
793
- upb_msgval msgval;
827
+ upb_MessageValue msgval;
794
828
  VALUE msg_value;
795
829
  VALUE msg_key;
796
830
 
797
- if (!is_proto2 && upb_fielddef_issubmsg(field) &&
798
- !upb_fielddef_isseq(field) && !upb_msg_has(msg, field)) {
831
+ if (!is_proto2 && upb_FieldDef_IsSubMessage(field) &&
832
+ !upb_FieldDef_IsRepeated(field) &&
833
+ !upb_Message_HasFieldByDef(msg, field)) {
799
834
  // TODO: Legacy behavior, remove when we fix the is_proto2 differences.
800
- msg_key = ID2SYM(rb_intern(upb_fielddef_name(field)));
835
+ msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
801
836
  rb_hash_aset(hash, msg_key, Qnil);
802
837
  continue;
803
838
  }
804
839
 
805
840
  // Do not include fields that are not present (oneof or optional fields).
806
- if (is_proto2 && upb_fielddef_haspresence(field) &&
807
- !upb_msg_has(msg, field)) {
841
+ if (is_proto2 && upb_FieldDef_HasPresence(field) &&
842
+ !upb_Message_HasFieldByDef(msg, field)) {
808
843
  continue;
809
844
  }
810
845
 
811
- msg_key = ID2SYM(rb_intern(upb_fielddef_name(field)));
812
- msgval = upb_msg_get(msg, field);
846
+ msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
847
+ msgval = upb_Message_GetFieldByDef(msg, field);
813
848
 
814
849
  // Proto2 omits empty map/repeated filds also.
815
850
 
816
- if (upb_fielddef_ismap(field)) {
817
- const upb_msgdef *entry_m = upb_fielddef_msgsubdef(field);
818
- const upb_fielddef *key_f = upb_msgdef_itof(entry_m, 1);
819
- const upb_fielddef *val_f = upb_msgdef_itof(entry_m, 2);
820
- upb_fieldtype_t key_type = upb_fielddef_type(key_f);
851
+ if (upb_FieldDef_IsMap(field)) {
852
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field);
853
+ const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1);
854
+ const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
855
+ upb_CType key_type = upb_FieldDef_CType(key_f);
821
856
  msg_value = Map_CreateHash(msgval.map_val, key_type, TypeInfo_get(val_f));
822
- } else if (upb_fielddef_isseq(field)) {
857
+ } else if (upb_FieldDef_IsRepeated(field)) {
823
858
  if (is_proto2 &&
824
- (!msgval.array_val || upb_array_size(msgval.array_val) == 0)) {
859
+ (!msgval.array_val || upb_Array_Size(msgval.array_val) == 0)) {
825
860
  continue;
826
861
  }
827
862
  msg_value = RepeatedField_CreateArray(msgval.array_val, type_info);
@@ -835,8 +870,8 @@ static VALUE Message_CreateHash(const upb_msg *msg, const upb_msgdef *m) {
835
870
  return hash;
836
871
  }
837
872
 
838
- VALUE Scalar_CreateHash(upb_msgval msgval, TypeInfo type_info) {
839
- if (type_info.type == UPB_TYPE_MESSAGE) {
873
+ VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info) {
874
+ if (type_info.type == kUpb_CType_Message) {
840
875
  return Message_CreateHash(msgval.msg_val, type_info.def.msgdef);
841
876
  } else {
842
877
  return Convert_UpbToRuby(msgval, type_info, Qnil);
@@ -879,10 +914,10 @@ static VALUE Message_freeze(VALUE _self) {
879
914
  */
880
915
  static VALUE Message_index(VALUE _self, VALUE field_name) {
881
916
  Message* self = ruby_to_Message(_self);
882
- const upb_fielddef* field;
917
+ const upb_FieldDef* field;
883
918
 
884
919
  Check_Type(field_name, T_STRING);
885
- field = upb_msgdef_ntofz(self->msgdef, RSTRING_PTR(field_name));
920
+ field = upb_MessageDef_FindFieldByName(self->msgdef, RSTRING_PTR(field_name));
886
921
 
887
922
  if (field == NULL) {
888
923
  return Qnil;
@@ -900,32 +935,55 @@ static VALUE Message_index(VALUE _self, VALUE field_name) {
900
935
  */
901
936
  static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
902
937
  Message* self = ruby_to_Message(_self);
903
- const upb_fielddef* f;
904
- upb_msgval val;
905
- upb_arena *arena = Arena_get(self->arena);
938
+ const upb_FieldDef* f;
939
+ upb_MessageValue val;
940
+ upb_Arena* arena = Arena_get(self->arena);
906
941
 
907
942
  Check_Type(field_name, T_STRING);
908
- f = upb_msgdef_ntofz(self->msgdef, RSTRING_PTR(field_name));
943
+ f = upb_MessageDef_FindFieldByName(self->msgdef, RSTRING_PTR(field_name));
909
944
 
910
945
  if (f == NULL) {
911
946
  rb_raise(rb_eArgError, "Unknown field: %s", RSTRING_PTR(field_name));
912
947
  }
913
948
 
914
- val = Convert_RubyToUpb(value, upb_fielddef_name(f), TypeInfo_get(f), arena);
915
- upb_msg_set(Message_GetMutable(_self, NULL), f, val, arena);
949
+ val = Convert_RubyToUpb(value, upb_FieldDef_Name(f), TypeInfo_get(f), arena);
950
+ upb_Message_SetFieldByDef(Message_GetMutable(_self, NULL), f, val, arena);
916
951
 
917
952
  return Qnil;
918
953
  }
919
954
 
920
955
  /*
921
956
  * call-seq:
922
- * MessageClass.decode(data) => message
957
+ * MessageClass.decode(data, options) => message
923
958
  *
924
959
  * Decodes the given data (as a string containing bytes in protocol buffers wire
925
960
  * format) under the interpretration given by this message class's definition
926
961
  * and returns a message object with the corresponding field values.
962
+ * @param options [Hash] options for the decoder
963
+ * recursion_limit: set to maximum decoding depth for message (default is 64)
927
964
  */
928
- static VALUE Message_decode(VALUE klass, VALUE data) {
965
+ static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
966
+ VALUE data = argv[0];
967
+ int options = 0;
968
+
969
+ if (argc < 1 || argc > 2) {
970
+ rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
971
+ }
972
+
973
+ if (argc == 2) {
974
+ VALUE hash_args = argv[1];
975
+ if (TYPE(hash_args) != T_HASH) {
976
+ rb_raise(rb_eArgError, "Expected hash arguments.");
977
+ }
978
+
979
+ VALUE depth =
980
+ rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit")));
981
+
982
+ if (depth != Qnil && TYPE(depth) == T_FIXNUM) {
983
+ options |= upb_DecodeOptions_MaxDepth(FIX2INT(depth));
984
+ }
985
+ }
986
+
929
987
  if (TYPE(data) != T_STRING) {
930
988
  rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
931
989
  }
@@ -933,9 +991,12 @@ static VALUE Message_decode(VALUE klass, VALUE data) {
933
991
  VALUE msg_rb = initialize_rb_class_with_no_args(klass);
934
992
  Message* msg = ruby_to_Message(msg_rb);
935
993
 
936
- if (!upb_decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_msg*)msg->msg,
937
- upb_msgdef_layout(msg->msgdef),
938
- Arena_get(msg->arena))) {
994
+ upb_DecodeStatus status =
995
+ upb_Decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_Message*)msg->msg,
996
+ upb_MessageDef_MiniTable(msg->msgdef), NULL, options,
997
+ Arena_get(msg->arena));
998
+
999
+ if (status != kUpb_DecodeStatus_Ok) {
939
1000
  rb_raise(cParseError, "Error occurred during parsing");
940
1001
  }
941
1002
 
@@ -957,10 +1018,10 @@ static VALUE Message_decode(VALUE klass, VALUE data) {
957
1018
  static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
958
1019
  VALUE data = argv[0];
959
1020
  int options = 0;
960
- upb_status status;
1021
+ upb_Status status;
961
1022
 
962
1023
  // TODO(haberman): use this message's pool instead.
963
- const upb_symtab *symtab = DescriptorPool_GetSymtab(generated_pool);
1024
+ const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool);
964
1025
 
965
1026
  if (argc < 1 || argc > 2) {
966
1027
  rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
@@ -972,8 +1033,9 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
972
1033
  rb_raise(rb_eArgError, "Expected hash arguments.");
973
1034
  }
974
1035
 
975
- if (RTEST(rb_hash_lookup2( hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse))) {
976
- options |= UPB_JSONDEC_IGNOREUNKNOWN;
1036
+ if (RTEST(rb_hash_lookup2(
1037
+ hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse))) {
1038
+ options |= upb_JsonDecode_IgnoreUnknown;
977
1039
  }
978
1040
  }
979
1041
 
@@ -989,16 +1051,16 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
989
1051
  Message* msg = ruby_to_Message(msg_rb);
990
1052
 
991
1053
  // We don't allow users to decode a wrapper type directly.
992
- if (upb_msgdef_iswrapper(msg->msgdef)) {
1054
+ if (IsWrapper(msg->msgdef)) {
993
1055
  rb_raise(rb_eRuntimeError, "Cannot parse a wrapper directly.");
994
1056
  }
995
1057
 
996
- upb_status_clear(&status);
997
- if (!upb_json_decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_msg*)msg->msg,
998
- msg->msgdef, symtab, options,
999
- Arena_get(msg->arena), &status)) {
1058
+ upb_Status_Clear(&status);
1059
+ if (!upb_JsonDecode(RSTRING_PTR(data), RSTRING_LEN(data),
1060
+ (upb_Message*)msg->msg, msg->msgdef, symtab, options,
1061
+ Arena_get(msg->arena), &status)) {
1000
1062
  rb_raise(cParseError, "Error occurred during parsing: %s",
1001
- upb_status_errmsg(&status));
1063
+ upb_Status_ErrorMessage(&status));
1002
1064
  }
1003
1065
 
1004
1066
  return msg_rb;
@@ -1006,31 +1068,53 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
1006
1068
 
1007
1069
  /*
1008
1070
  * call-seq:
1009
- * MessageClass.encode(msg) => bytes
1071
+ * MessageClass.encode(msg, options) => bytes
1010
1072
  *
1011
1073
  * Encodes the given message object to its serialized form in protocol buffers
1012
1074
  * wire format.
1075
+ * @param options [Hash] options for the encoder
1076
+ * recursion_limit: set to maximum encoding depth for message (default is 64)
1013
1077
  */
1014
- static VALUE Message_encode(VALUE klass, VALUE msg_rb) {
1015
- Message* msg = ruby_to_Message(msg_rb);
1016
- upb_arena *arena = upb_arena_new();
1017
- const char *data;
1078
+ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) {
1079
+ Message* msg = ruby_to_Message(argv[0]);
1080
+ int options = 0;
1081
+ char* data;
1018
1082
  size_t size;
1019
1083
 
1020
- if (CLASS_OF(msg_rb) != klass) {
1084
+ if (CLASS_OF(argv[0]) != klass) {
1021
1085
  rb_raise(rb_eArgError, "Message of wrong type.");
1022
1086
  }
1023
1087
 
1024
- data = upb_encode(msg->msg, upb_msgdef_layout(msg->msgdef), arena,
1025
- &size);
1088
+ if (argc < 1 || argc > 2) {
1089
+ rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
1090
+ }
1091
+
1092
+ if (argc == 2) {
1093
+ VALUE hash_args = argv[1];
1094
+ if (TYPE(hash_args) != T_HASH) {
1095
+ rb_raise(rb_eArgError, "Expected hash arguments.");
1096
+ }
1097
+ VALUE depth =
1098
+ rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit")));
1099
+
1100
+ if (depth != Qnil && TYPE(depth) == T_FIXNUM) {
1101
+ options |= upb_DecodeOptions_MaxDepth(FIX2INT(depth));
1102
+ }
1103
+ }
1104
+
1105
+ upb_Arena* arena = upb_Arena_New();
1026
1106
 
1027
- if (data) {
1107
+ upb_EncodeStatus status =
1108
+ upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->msgdef), options,
1109
+ arena, &data, &size);
1110
+
1111
+ if (status == kUpb_EncodeStatus_Ok) {
1028
1112
  VALUE ret = rb_str_new(data, size);
1029
1113
  rb_enc_associate(ret, rb_ascii8bit_encoding());
1030
- upb_arena_free(arena);
1114
+ upb_Arena_Free(arena);
1031
1115
  return ret;
1032
1116
  } else {
1033
- upb_arena_free(arena);
1117
+ upb_Arena_Free(arena);
1034
1118
  rb_raise(rb_eRuntimeError, "Exceeded maximum depth (possibly cycle)");
1035
1119
  }
1036
1120
  }
@@ -1041,18 +1125,19 @@ static VALUE Message_encode(VALUE klass, VALUE msg_rb) {
1041
1125
  *
1042
1126
  * Encodes the given message object into its serialized JSON representation.
1043
1127
  * @param options [Hash] options for the decoder
1044
- * preserve_proto_fieldnames: set true to use original fieldnames (default is to camelCase)
1045
- * emit_defaults: set true to emit 0/false values (default is to omit them)
1128
+ * preserve_proto_fieldnames: set true to use original fieldnames (default is
1129
+ * to camelCase) emit_defaults: set true to emit 0/false values (default is to
1130
+ * omit them)
1046
1131
  */
1047
1132
  static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1048
1133
  Message* msg = ruby_to_Message(argv[0]);
1049
1134
  int options = 0;
1050
1135
  char buf[1024];
1051
1136
  size_t size;
1052
- upb_status status;
1137
+ upb_Status status;
1053
1138
 
1054
1139
  // TODO(haberman): use this message's pool instead.
1055
- const upb_symtab *symtab = DescriptorPool_GetSymtab(generated_pool);
1140
+ const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool);
1056
1141
 
1057
1142
  if (argc < 1 || argc > 2) {
1058
1143
  rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
@@ -1061,35 +1146,46 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1061
1146
  if (argc == 2) {
1062
1147
  VALUE hash_args = argv[1];
1063
1148
  if (TYPE(hash_args) != T_HASH) {
1064
- rb_raise(rb_eArgError, "Expected hash arguments.");
1149
+ if (RTEST(rb_funcall(hash_args, rb_intern("respond_to?"), 1,
1150
+ rb_str_new2("to_h")))) {
1151
+ hash_args = rb_funcall(hash_args, rb_intern("to_h"), 0);
1152
+ } else {
1153
+ rb_raise(rb_eArgError, "Expected hash arguments.");
1154
+ }
1065
1155
  }
1066
1156
 
1067
1157
  if (RTEST(rb_hash_lookup2(hash_args,
1068
1158
  ID2SYM(rb_intern("preserve_proto_fieldnames")),
1069
1159
  Qfalse))) {
1070
- options |= UPB_JSONENC_PROTONAMES;
1160
+ options |= upb_JsonEncode_UseProtoNames;
1071
1161
  }
1072
1162
 
1073
1163
  if (RTEST(rb_hash_lookup2(hash_args, ID2SYM(rb_intern("emit_defaults")),
1074
1164
  Qfalse))) {
1075
- options |= UPB_JSONENC_EMITDEFAULTS;
1165
+ options |= upb_JsonEncode_EmitDefaults;
1166
+ }
1167
+
1168
+ if (RTEST(rb_hash_lookup2(hash_args,
1169
+ ID2SYM(rb_intern("format_enums_as_integers")),
1170
+ Qfalse))) {
1171
+ options |= upb_JsonEncode_FormatEnumsAsIntegers;
1076
1172
  }
1077
1173
  }
1078
1174
 
1079
- upb_status_clear(&status);
1080
- size = upb_json_encode(msg->msg, msg->msgdef, symtab, options, buf,
1081
- sizeof(buf), &status);
1175
+ upb_Status_Clear(&status);
1176
+ size = upb_JsonEncode(msg->msg, msg->msgdef, symtab, options, buf,
1177
+ sizeof(buf), &status);
1082
1178
 
1083
- if (!upb_ok(&status)) {
1179
+ if (!upb_Status_IsOk(&status)) {
1084
1180
  rb_raise(cParseError, "Error occurred during encoding: %s",
1085
- upb_status_errmsg(&status));
1181
+ upb_Status_ErrorMessage(&status));
1086
1182
  }
1087
1183
 
1088
1184
  VALUE ret;
1089
1185
  if (size >= sizeof(buf)) {
1090
1186
  char* buf2 = malloc(size + 1);
1091
- upb_json_encode(msg->msg, msg->msgdef, symtab, options, buf2, size + 1,
1092
- &status);
1187
+ upb_JsonEncode(msg->msg, msg->msgdef, symtab, options, buf2, size + 1,
1188
+ &status);
1093
1189
  ret = rb_str_new(buf2, size);
1094
1190
  free(buf2);
1095
1191
  } else {
@@ -1112,10 +1208,10 @@ static VALUE Message_descriptor(VALUE klass) {
1112
1208
  }
1113
1209
 
1114
1210
  VALUE build_class_from_descriptor(VALUE descriptor) {
1115
- const char *name;
1211
+ const char* name;
1116
1212
  VALUE klass;
1117
1213
 
1118
- name = upb_msgdef_fullname(Descriptor_GetMsgDef(descriptor));
1214
+ name = upb_MessageDef_FullName(Descriptor_GetMsgDef(descriptor));
1119
1215
  if (name == NULL) {
1120
1216
  rb_raise(rb_eRuntimeError, "Descriptor does not have assigned name.");
1121
1217
  }
@@ -1123,38 +1219,8 @@ VALUE build_class_from_descriptor(VALUE descriptor) {
1123
1219
  klass = rb_define_class_id(
1124
1220
  // Docs say this parameter is ignored. User will assign return value to
1125
1221
  // their own toplevel constant class name.
1126
- rb_intern("Message"),
1127
- rb_cObject);
1222
+ rb_intern("Message"), cAbstractMessage);
1128
1223
  rb_ivar_set(klass, descriptor_instancevar_interned, descriptor);
1129
- rb_define_alloc_func(klass, Message_alloc);
1130
- rb_require("google/protobuf/message_exts");
1131
- rb_include_module(klass, rb_eval_string("::Google::Protobuf::MessageExts"));
1132
- rb_extend_object(
1133
- klass, rb_eval_string("::Google::Protobuf::MessageExts::ClassMethods"));
1134
-
1135
- rb_define_method(klass, "method_missing",
1136
- Message_method_missing, -1);
1137
- rb_define_method(klass, "respond_to_missing?",
1138
- Message_respond_to_missing, -1);
1139
- rb_define_method(klass, "initialize", Message_initialize, -1);
1140
- rb_define_method(klass, "dup", Message_dup, 0);
1141
- // Also define #clone so that we don't inherit Object#clone.
1142
- rb_define_method(klass, "clone", Message_dup, 0);
1143
- rb_define_method(klass, "==", Message_eq, 1);
1144
- rb_define_method(klass, "eql?", Message_eq, 1);
1145
- rb_define_method(klass, "freeze", Message_freeze, 0);
1146
- rb_define_method(klass, "hash", Message_hash, 0);
1147
- rb_define_method(klass, "to_h", Message_to_h, 0);
1148
- rb_define_method(klass, "inspect", Message_inspect, 0);
1149
- rb_define_method(klass, "to_s", Message_inspect, 0);
1150
- rb_define_method(klass, "[]", Message_index, 1);
1151
- rb_define_method(klass, "[]=", Message_index_set, 2);
1152
- rb_define_singleton_method(klass, "decode", Message_decode, 1);
1153
- rb_define_singleton_method(klass, "encode", Message_encode, 1);
1154
- rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
1155
- rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
1156
- rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
1157
-
1158
1224
  return klass;
1159
1225
  }
1160
1226
 
@@ -1168,13 +1234,12 @@ VALUE build_class_from_descriptor(VALUE descriptor) {
1168
1234
  static VALUE enum_lookup(VALUE self, VALUE number) {
1169
1235
  int32_t num = NUM2INT(number);
1170
1236
  VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned);
1171
- const upb_enumdef *e = EnumDescriptor_GetEnumDef(desc);
1172
-
1173
- const char* name = upb_enumdef_iton(e, num);
1174
- if (name == NULL) {
1175
- return Qnil;
1237
+ const upb_EnumDef* e = EnumDescriptor_GetEnumDef(desc);
1238
+ const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e, num);
1239
+ if (ev) {
1240
+ return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
1176
1241
  } else {
1177
- return ID2SYM(rb_intern(name));
1242
+ return Qnil;
1178
1243
  }
1179
1244
  }
1180
1245
 
@@ -1188,14 +1253,12 @@ static VALUE enum_lookup(VALUE self, VALUE number) {
1188
1253
  static VALUE enum_resolve(VALUE self, VALUE sym) {
1189
1254
  const char* name = rb_id2name(SYM2ID(sym));
1190
1255
  VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned);
1191
- const upb_enumdef *e = EnumDescriptor_GetEnumDef(desc);
1192
-
1193
- int32_t num = 0;
1194
- bool found = upb_enumdef_ntoiz(e, name, &num);
1195
- if (!found) {
1196
- return Qnil;
1256
+ const upb_EnumDef* e = EnumDescriptor_GetEnumDef(desc);
1257
+ const upb_EnumValueDef* ev = upb_EnumDef_FindValueByName(e, name);
1258
+ if (ev) {
1259
+ return INT2NUM(upb_EnumValueDef_Number(ev));
1197
1260
  } else {
1198
- return INT2NUM(num);
1261
+ return Qnil;
1199
1262
  }
1200
1263
  }
1201
1264
 
@@ -1211,21 +1274,28 @@ static VALUE enum_descriptor(VALUE self) {
1211
1274
  }
1212
1275
 
1213
1276
  VALUE build_module_from_enumdesc(VALUE _enumdesc) {
1214
- const upb_enumdef *e = EnumDescriptor_GetEnumDef(_enumdesc);
1215
- VALUE mod = rb_define_module_id(rb_intern(upb_enumdef_fullname(e)));
1216
-
1217
- upb_enum_iter it;
1218
- for (upb_enum_begin(&it, e);
1219
- !upb_enum_done(&it);
1220
- upb_enum_next(&it)) {
1221
- const char* name = upb_enum_iter_name(&it);
1222
- int32_t value = upb_enum_iter_number(&it);
1277
+ const upb_EnumDef* e = EnumDescriptor_GetEnumDef(_enumdesc);
1278
+ VALUE mod = rb_define_module_id(rb_intern(upb_EnumDef_FullName(e)));
1279
+
1280
+ int n = upb_EnumDef_ValueCount(e);
1281
+ for (int i = 0; i < n; i++) {
1282
+ const upb_EnumValueDef* ev = upb_EnumDef_Value(e, i);
1283
+ upb_Arena* arena = upb_Arena_New();
1284
+ const char* src_name = upb_EnumValueDef_Name(ev);
1285
+ char* name = upb_strdup2(src_name, strlen(src_name), arena);
1286
+ int32_t value = upb_EnumValueDef_Number(ev);
1223
1287
  if (name[0] < 'A' || name[0] > 'Z') {
1224
- rb_warn("Enum value '%s' does not start with an uppercase letter "
1225
- "as is required for Ruby constants.",
1226
- name);
1288
+ if (name[0] >= 'a' && name[0] <= 'z') {
1289
+ name[0] -= 32; // auto capitalize
1290
+ } else {
1291
+ rb_warn(
1292
+ "Enum value '%s' does not start with an uppercase letter "
1293
+ "as is required for Ruby constants.",
1294
+ name);
1295
+ }
1227
1296
  }
1228
1297
  rb_define_const(mod, name, INT2NUM(value));
1298
+ upb_Arena_Free(arena);
1229
1299
  }
1230
1300
 
1231
1301
  rb_define_singleton_method(mod, "lookup", enum_lookup, 1);
@@ -1236,81 +1306,85 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc) {
1236
1306
  return mod;
1237
1307
  }
1238
1308
 
1239
- // Internal only; used by Google::Protobuf.deep_copy.
1240
- upb_msg* Message_deep_copy(const upb_msg* msg, const upb_msgdef* m,
1241
- upb_arena *arena) {
1309
+ // Internal to the library; used by Google::Protobuf.deep_copy.
1310
+ upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
1311
+ upb_Arena* arena) {
1242
1312
  // Serialize and parse.
1243
- upb_arena *tmp_arena = upb_arena_new();
1244
- const upb_msglayout *layout = upb_msgdef_layout(m);
1313
+ upb_Arena* tmp_arena = upb_Arena_New();
1314
+ const upb_MiniTable* layout = upb_MessageDef_MiniTable(m);
1245
1315
  size_t size;
1246
1316
 
1247
- char* data = upb_encode_ex(msg, layout, 0, tmp_arena, &size);
1248
- upb_msg* new_msg = upb_msg_new(m, arena);
1317
+ upb_Message* new_msg = upb_Message_New(layout, arena);
1318
+ char* data;
1249
1319
 
1250
- if (!data || !upb_decode(data, size, new_msg, layout, arena)) {
1251
- upb_arena_free(tmp_arena);
1320
+ if (upb_Encode(msg, layout, 0, tmp_arena, &data, &size) !=
1321
+ kUpb_EncodeStatus_Ok ||
1322
+ upb_Decode(data, size, new_msg, layout, NULL, 0, arena) !=
1323
+ kUpb_DecodeStatus_Ok) {
1324
+ upb_Arena_Free(tmp_arena);
1252
1325
  rb_raise(cParseError, "Error occurred copying proto");
1253
1326
  }
1254
1327
 
1255
- upb_arena_free(tmp_arena);
1328
+ upb_Arena_Free(tmp_arena);
1256
1329
  return new_msg;
1257
1330
  }
1258
1331
 
1259
- const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m,
1260
- const char* name, upb_arena* arena) {
1332
+ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
1333
+ const char* name, upb_Arena* arena) {
1261
1334
  if (value == Qnil) {
1262
1335
  rb_raise(cTypeError, "nil message not allowed here.");
1263
1336
  }
1264
1337
 
1265
1338
  VALUE klass = CLASS_OF(value);
1266
1339
  VALUE desc_rb = rb_ivar_get(klass, descriptor_instancevar_interned);
1267
- const upb_msgdef* val_m =
1340
+ const upb_MessageDef* val_m =
1268
1341
  desc_rb == Qnil ? NULL : Descriptor_GetMsgDef(desc_rb);
1269
1342
 
1270
1343
  if (val_m != m) {
1271
1344
  // Check for possible implicit conversions
1272
1345
  // TODO: hash conversion?
1273
1346
 
1274
- switch (upb_msgdef_wellknowntype(m)) {
1275
- case UPB_WELLKNOWN_TIMESTAMP: {
1347
+ switch (upb_MessageDef_WellKnownType(m)) {
1348
+ case kUpb_WellKnown_Timestamp: {
1276
1349
  // Time -> Google::Protobuf::Timestamp
1277
- upb_msg *msg = upb_msg_new(m, arena);
1278
- upb_msgval sec, nsec;
1350
+ const upb_MiniTable* t = upb_MessageDef_MiniTable(m);
1351
+ upb_Message* msg = upb_Message_New(t, arena);
1352
+ upb_MessageValue sec, nsec;
1279
1353
  struct timespec time;
1280
- const upb_fielddef *sec_f = upb_msgdef_itof(m, 1);
1281
- const upb_fielddef *nsec_f = upb_msgdef_itof(m, 2);
1354
+ const upb_FieldDef* sec_f = upb_MessageDef_FindFieldByNumber(m, 1);
1355
+ const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(m, 2);
1282
1356
 
1283
1357
  if (!rb_obj_is_kind_of(value, rb_cTime)) goto badtype;
1284
1358
 
1285
1359
  time = rb_time_timespec(value);
1286
1360
  sec.int64_val = time.tv_sec;
1287
1361
  nsec.int32_val = time.tv_nsec;
1288
- upb_msg_set(msg, sec_f, sec, arena);
1289
- upb_msg_set(msg, nsec_f, nsec, arena);
1362
+ upb_Message_SetFieldByDef(msg, sec_f, sec, arena);
1363
+ upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena);
1290
1364
  return msg;
1291
1365
  }
1292
- case UPB_WELLKNOWN_DURATION: {
1366
+ case kUpb_WellKnown_Duration: {
1293
1367
  // Numeric -> Google::Protobuf::Duration
1294
- upb_msg *msg = upb_msg_new(m, arena);
1295
- upb_msgval sec, nsec;
1296
- const upb_fielddef *sec_f = upb_msgdef_itof(m, 1);
1297
- const upb_fielddef *nsec_f = upb_msgdef_itof(m, 2);
1368
+ const upb_MiniTable* t = upb_MessageDef_MiniTable(m);
1369
+ upb_Message* msg = upb_Message_New(t, arena);
1370
+ upb_MessageValue sec, nsec;
1371
+ const upb_FieldDef* sec_f = upb_MessageDef_FindFieldByNumber(m, 1);
1372
+ const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(m, 2);
1298
1373
 
1299
1374
  if (!rb_obj_is_kind_of(value, rb_cNumeric)) goto badtype;
1300
1375
 
1301
1376
  sec.int64_val = NUM2LL(value);
1302
1377
  nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000);
1303
- upb_msg_set(msg, sec_f, sec, arena);
1304
- upb_msg_set(msg, nsec_f, nsec, arena);
1378
+ upb_Message_SetFieldByDef(msg, sec_f, sec, arena);
1379
+ upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena);
1305
1380
  return msg;
1306
1381
  }
1307
1382
  default:
1308
1383
  badtype:
1309
1384
  rb_raise(cTypeError,
1310
1385
  "Invalid type %s to assign to submessage field '%s'.",
1311
- rb_class2name(CLASS_OF(value)), name);
1386
+ rb_class2name(CLASS_OF(value)), name);
1312
1387
  }
1313
-
1314
1388
  }
1315
1389
 
1316
1390
  Message* self = ruby_to_Message(value);
@@ -1319,11 +1393,42 @@ const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m,
1319
1393
  return self->msg;
1320
1394
  }
1321
1395
 
1396
+ static void Message_define_class(VALUE klass) {
1397
+ rb_define_alloc_func(klass, Message_alloc);
1398
+
1399
+ rb_require("google/protobuf/message_exts");
1400
+ rb_define_method(klass, "method_missing", Message_method_missing, -1);
1401
+ rb_define_method(klass, "respond_to_missing?", Message_respond_to_missing,
1402
+ -1);
1403
+ rb_define_method(klass, "initialize", Message_initialize, -1);
1404
+ rb_define_method(klass, "dup", Message_dup, 0);
1405
+ // Also define #clone so that we don't inherit Object#clone.
1406
+ rb_define_method(klass, "clone", Message_dup, 0);
1407
+ rb_define_method(klass, "==", Message_eq, 1);
1408
+ rb_define_method(klass, "eql?", Message_eq, 1);
1409
+ rb_define_method(klass, "freeze", Message_freeze, 0);
1410
+ rb_define_method(klass, "hash", Message_hash, 0);
1411
+ rb_define_method(klass, "to_h", Message_to_h, 0);
1412
+ rb_define_method(klass, "inspect", Message_inspect, 0);
1413
+ rb_define_method(klass, "to_s", Message_inspect, 0);
1414
+ rb_define_method(klass, "[]", Message_index, 1);
1415
+ rb_define_method(klass, "[]=", Message_index_set, 2);
1416
+ rb_define_singleton_method(klass, "decode", Message_decode, -1);
1417
+ rb_define_singleton_method(klass, "encode", Message_encode, -1);
1418
+ rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
1419
+ rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
1420
+ rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
1421
+ }
1422
+
1322
1423
  void Message_register(VALUE protobuf) {
1323
1424
  cParseError = rb_const_get(protobuf, rb_intern("ParseError"));
1425
+ cAbstractMessage =
1426
+ rb_define_class_under(protobuf, "AbstractMessage", rb_cObject);
1427
+ Message_define_class(cAbstractMessage);
1428
+ rb_gc_register_address(&cAbstractMessage);
1324
1429
 
1325
1430
  // Ruby-interned string: "descriptor". We use this identifier to store an
1326
1431
  // instance variable on message classes we create in order to link them back
1327
1432
  // to their descriptors.
1328
- descriptor_instancevar_interned = rb_intern("descriptor");
1433
+ descriptor_instancevar_interned = rb_intern("@descriptor");
1329
1434
  }