google-protobuf 3.17.3 → 3.22.1-arm64-darwin

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