google-protobuf 3.19.1 → 3.25.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +121 -155
  4. data/ext/google/protobuf_c/convert.h +15 -37
  5. data/ext/google/protobuf_c/defs.c +362 -243
  6. data/ext/google/protobuf_c/defs.h +22 -47
  7. data/ext/google/protobuf_c/extconf.rb +13 -5
  8. data/ext/google/protobuf_c/glue.c +56 -0
  9. data/ext/google/protobuf_c/map.c +129 -137
  10. data/ext/google/protobuf_c/map.h +13 -36
  11. data/ext/google/protobuf_c/message.c +486 -389
  12. data/ext/google/protobuf_c/message.h +32 -47
  13. data/ext/google/protobuf_c/protobuf.c +101 -228
  14. data/ext/google/protobuf_c/protobuf.h +37 -42
  15. data/ext/google/protobuf_c/repeated_field.c +110 -113
  16. data/ext/google/protobuf_c/repeated_field.h +12 -34
  17. data/ext/google/protobuf_c/ruby-upb.c +12236 -6993
  18. data/ext/google/protobuf_c/ruby-upb.h +12127 -3787
  19. data/ext/google/protobuf_c/shared_convert.c +64 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +65 -0
  22. data/ext/google/protobuf_c/shared_message.h +25 -0
  23. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  24. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +92 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +157 -0
  26. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +170 -0
  27. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +21 -0
  28. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  29. data/lib/google/protobuf/any_pb.rb +24 -5
  30. data/lib/google/protobuf/api_pb.rb +26 -23
  31. data/lib/google/protobuf/descriptor_dsl.rb +8 -1
  32. data/lib/google/protobuf/descriptor_pb.rb +43 -225
  33. data/lib/google/protobuf/duration_pb.rb +24 -5
  34. data/lib/google/protobuf/empty_pb.rb +24 -3
  35. data/lib/google/protobuf/ffi/descriptor.rb +165 -0
  36. data/lib/google/protobuf/ffi/descriptor_pool.rb +75 -0
  37. data/lib/google/protobuf/ffi/enum_descriptor.rb +171 -0
  38. data/lib/google/protobuf/ffi/ffi.rb +213 -0
  39. data/lib/google/protobuf/ffi/field_descriptor.rb +319 -0
  40. data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
  41. data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
  42. data/lib/google/protobuf/ffi/internal/convert.rb +305 -0
  43. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  44. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  45. data/lib/google/protobuf/ffi/map.rb +407 -0
  46. data/lib/google/protobuf/ffi/message.rb +662 -0
  47. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  48. data/lib/google/protobuf/ffi/oneof_descriptor.rb +95 -0
  49. data/lib/google/protobuf/ffi/repeated_field.rb +383 -0
  50. data/lib/google/protobuf/field_mask_pb.rb +24 -4
  51. data/lib/google/protobuf/message_exts.rb +10 -28
  52. data/lib/google/protobuf/object_cache.rb +97 -0
  53. data/lib/google/protobuf/plugin_pb.rb +47 -0
  54. data/lib/google/protobuf/repeated_field.rb +18 -28
  55. data/lib/google/protobuf/source_context_pb.rb +24 -4
  56. data/lib/google/protobuf/struct_pb.rb +24 -20
  57. data/lib/google/protobuf/timestamp_pb.rb +24 -5
  58. data/lib/google/protobuf/type_pb.rb +26 -68
  59. data/lib/google/protobuf/well_known_types.rb +16 -40
  60. data/lib/google/protobuf/wrappers_pb.rb +24 -28
  61. data/lib/google/protobuf.rb +32 -50
  62. data/lib/google/protobuf_ffi.rb +50 -0
  63. data/lib/google/protobuf_native.rb +20 -0
  64. data/lib/google/tasks/ffi.rake +102 -0
  65. metadata +82 -20
  66. data/tests/basic.rb +0 -640
  67. data/tests/generated_code_test.rb +0 -23
  68. data/tests/stress.rb +0 -38
@@ -1,32 +1,9 @@
1
1
  // Protocol Buffers - Google's data interchange format
2
2
  // Copyright 2014 Google Inc. All rights reserved.
3
- // https://developers.google.com/protocol-buffers/
4
3
  //
5
- // Redistribution and use in source and binary forms, with or without
6
- // modification, are permitted provided that the following conditions are
7
- // met:
8
- //
9
- // * Redistributions of source code must retain the above copyright
10
- // notice, this list of conditions and the following disclaimer.
11
- // * Redistributions in binary form must reproduce the above
12
- // copyright notice, this list of conditions and the following disclaimer
13
- // in the documentation and/or other materials provided with the
14
- // distribution.
15
- // * Neither the name of Google Inc. nor the names of its
16
- // contributors may be used to endorse or promote products derived from
17
- // this software without specific prior written permission.
18
- //
19
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4
+ // Use of this source code is governed by a BSD-style
5
+ // license that can be found in the LICENSE file or at
6
+ // https://developers.google.com/open-source/licenses/bsd
30
7
 
31
8
  #include <ctype.h>
32
9
  #include <errno.h>
@@ -41,11 +18,11 @@
41
18
  // instances.
42
19
  // -----------------------------------------------------------------------------
43
20
 
44
- static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def);
45
- static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def);
46
- static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def);
47
- static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def);
48
- static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def);
21
+ static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def);
22
+ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def);
23
+ static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def);
24
+ static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def);
25
+ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def);
49
26
 
50
27
  // A distinct object that is not accessible from Ruby. We use this as a
51
28
  // constructor argument to enforce that certain objects cannot be created from
@@ -67,14 +44,16 @@ static VALUE rb_str_maybe_null(const char* s) {
67
44
  }
68
45
  return rb_str_new2(s);
69
46
  }
70
-
47
+ static ID options_instancevar_interned;
71
48
  // -----------------------------------------------------------------------------
72
49
  // DescriptorPool.
73
50
  // -----------------------------------------------------------------------------
74
51
 
75
52
  typedef struct {
53
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
54
+ // macro to update VALUE references, as to trigger write barriers.
76
55
  VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor.
77
- upb_symtab* symtab;
56
+ upb_DefPool* symtab;
78
57
  } DescriptorPool;
79
58
 
80
59
  VALUE cDescriptorPool = Qnil;
@@ -90,14 +69,14 @@ static void DescriptorPool_mark(void* _self) {
90
69
 
91
70
  static void DescriptorPool_free(void* _self) {
92
71
  DescriptorPool* self = _self;
93
- upb_symtab_free(self->symtab);
72
+ upb_DefPool_Free(self->symtab);
94
73
  xfree(self);
95
74
  }
96
75
 
97
76
  static const rb_data_type_t DescriptorPool_type = {
98
- "Google::Protobuf::DescriptorPool",
99
- {DescriptorPool_mark, DescriptorPool_free, NULL},
100
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
77
+ "Google::Protobuf::DescriptorPool",
78
+ {DescriptorPool_mark, DescriptorPool_free, NULL},
79
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
101
80
  };
102
81
 
103
82
  static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
@@ -107,8 +86,8 @@ static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
107
86
  }
108
87
 
109
88
  // Exposed to other modules in defs.h.
110
- const upb_symtab *DescriptorPool_GetSymtab(VALUE desc_pool_rb) {
111
- DescriptorPool *pool = ruby_to_DescriptorPool(desc_pool_rb);
89
+ const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb) {
90
+ DescriptorPool* pool = ruby_to_DescriptorPool(desc_pool_rb);
112
91
  return pool->symtab;
113
92
  }
114
93
 
@@ -125,11 +104,9 @@ static VALUE DescriptorPool_alloc(VALUE klass) {
125
104
  self->def_to_descriptor = Qnil;
126
105
  ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self);
127
106
 
128
- self->def_to_descriptor = rb_hash_new();
129
- self->symtab = upb_symtab_new();
130
- ObjectCache_Add(self->symtab, ret);
131
-
132
- return ret;
107
+ RB_OBJ_WRITE(ret, &self->def_to_descriptor, rb_hash_new());
108
+ self->symtab = upb_DefPool_New();
109
+ return ObjectCache_TryAdd(self->symtab, ret);
133
110
  }
134
111
 
135
112
  /*
@@ -143,7 +120,7 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
143
120
  DescriptorPool* self = ruby_to_DescriptorPool(_self);
144
121
  Check_Type(serialized_file_proto, T_STRING);
145
122
  VALUE arena_rb = Arena_new();
146
- upb_arena *arena = Arena_get(arena_rb);
123
+ upb_Arena* arena = Arena_get(arena_rb);
147
124
  google_protobuf_FileDescriptorProto* file_proto =
148
125
  google_protobuf_FileDescriptorProto_parse(
149
126
  RSTRING_PTR(serialized_file_proto),
@@ -151,14 +128,15 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
151
128
  if (!file_proto) {
152
129
  rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto");
153
130
  }
154
- upb_status status;
155
- upb_status_clear(&status);
156
- const upb_filedef* filedef =
157
- upb_symtab_addfile(self->symtab, file_proto, &status);
131
+ upb_Status status;
132
+ upb_Status_Clear(&status);
133
+ const upb_FileDef* filedef =
134
+ upb_DefPool_AddFile(self->symtab, file_proto, &status);
158
135
  if (!filedef) {
159
136
  rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s",
160
- upb_status_errmsg(&status));
137
+ upb_Status_ErrorMessage(&status));
161
138
  }
139
+ RB_GC_GUARD(arena_rb);
162
140
  return get_filedef_obj(_self, filedef);
163
141
  }
164
142
 
@@ -166,21 +144,27 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
166
144
  * call-seq:
167
145
  * DescriptorPool.lookup(name) => descriptor
168
146
  *
169
- * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
170
- * exists with the given name.
147
+ * Finds a Descriptor, EnumDescriptor or FieldDescriptor by name and returns it,
148
+ * or nil if none exists with the given name.
171
149
  */
172
150
  static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
173
151
  DescriptorPool* self = ruby_to_DescriptorPool(_self);
174
152
  const char* name_str = get_str(name);
175
- const upb_msgdef* msgdef;
176
- const upb_enumdef* enumdef;
153
+ const upb_MessageDef* msgdef;
154
+ const upb_EnumDef* enumdef;
155
+ const upb_FieldDef* fielddef;
177
156
 
178
- msgdef = upb_symtab_lookupmsg(self->symtab, name_str);
157
+ msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
179
158
  if (msgdef) {
180
159
  return get_msgdef_obj(_self, msgdef);
181
160
  }
182
161
 
183
- enumdef = upb_symtab_lookupenum(self->symtab, name_str);
162
+ fielddef = upb_DefPool_FindExtensionByName(self->symtab, name_str);
163
+ if (fielddef) {
164
+ return get_fielddef_obj(_self, fielddef);
165
+ }
166
+
167
+ enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str);
184
168
  if (enumdef) {
185
169
  return get_enumdef_obj(_self, enumdef);
186
170
  }
@@ -202,8 +186,7 @@ static VALUE DescriptorPool_generated_pool(VALUE _self) {
202
186
  }
203
187
 
204
188
  static void DescriptorPool_register(VALUE module) {
205
- VALUE klass = rb_define_class_under(
206
- module, "DescriptorPool", rb_cObject);
189
+ VALUE klass = rb_define_class_under(module, "DescriptorPool", rb_cObject);
207
190
  rb_define_alloc_func(klass, DescriptorPool_alloc);
208
191
  rb_define_method(klass, "add_serialized_file",
209
192
  DescriptorPool_add_serialized_file, 1);
@@ -215,6 +198,7 @@ static void DescriptorPool_register(VALUE module) {
215
198
 
216
199
  rb_gc_register_address(&generated_pool);
217
200
  generated_pool = rb_class_new_instance(0, NULL, klass);
201
+ options_instancevar_interned = rb_intern("options");
218
202
  }
219
203
 
220
204
  // -----------------------------------------------------------------------------
@@ -222,7 +206,9 @@ static void DescriptorPool_register(VALUE module) {
222
206
  // -----------------------------------------------------------------------------
223
207
 
224
208
  typedef struct {
225
- const upb_msgdef* msgdef;
209
+ const upb_MessageDef* msgdef;
210
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
211
+ // macro to update VALUE references, as to trigger write barriers.
226
212
  VALUE klass;
227
213
  VALUE descriptor_pool;
228
214
  } Descriptor;
@@ -236,9 +222,9 @@ static void Descriptor_mark(void* _self) {
236
222
  }
237
223
 
238
224
  static const rb_data_type_t Descriptor_type = {
239
- "Google::Protobuf::Descriptor",
240
- {Descriptor_mark, RUBY_DEFAULT_FREE, NULL},
241
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
225
+ "Google::Protobuf::Descriptor",
226
+ {Descriptor_mark, RUBY_DEFAULT_FREE, NULL},
227
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
242
228
  };
243
229
 
244
230
  static Descriptor* ruby_to_Descriptor(VALUE val) {
@@ -247,6 +233,35 @@ static Descriptor* ruby_to_Descriptor(VALUE val) {
247
233
  return ret;
248
234
  }
249
235
 
236
+ // Decode and return a frozen instance of a Descriptor Option for the given pool
237
+ static VALUE decode_options(VALUE self, const char* option_type, int size,
238
+ const char* bytes, VALUE descriptor_pool) {
239
+ VALUE options_rb = rb_ivar_get(self, options_instancevar_interned);
240
+ if (options_rb != Qnil) {
241
+ return options_rb;
242
+ }
243
+
244
+ static const char* prefix = "google.protobuf.";
245
+ char fullname
246
+ [/*strlen(prefix)*/ 16 +
247
+ /*strln(longest option type supported e.g. "MessageOptions")*/ 14 +
248
+ /*null terminator*/ 1];
249
+
250
+ snprintf(fullname, sizeof(fullname), "%s%s", prefix, option_type);
251
+ const upb_MessageDef* msgdef = upb_DefPool_FindMessageByName(
252
+ ruby_to_DescriptorPool(descriptor_pool)->symtab, fullname);
253
+ if (!msgdef) {
254
+ rb_raise(rb_eRuntimeError, "Cannot find %s in DescriptorPool", option_type);
255
+ }
256
+
257
+ VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef);
258
+ const Descriptor* desc = ruby_to_Descriptor(desc_rb);
259
+
260
+ options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, true);
261
+ rb_ivar_set(self, options_instancevar_interned, options_rb);
262
+ return options_rb;
263
+ }
264
+
250
265
  /*
251
266
  * call-seq:
252
267
  * Descriptor.new => descriptor
@@ -280,8 +295,8 @@ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
280
295
  "Descriptor objects may not be created from Ruby.");
281
296
  }
282
297
 
283
- self->descriptor_pool = descriptor_pool;
284
- self->msgdef = (const upb_msgdef*)NUM2ULL(ptr);
298
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
299
+ self->msgdef = (const upb_MessageDef*)NUM2ULL(ptr);
285
300
 
286
301
  return Qnil;
287
302
  }
@@ -294,7 +309,8 @@ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
294
309
  */
295
310
  static VALUE Descriptor_file_descriptor(VALUE _self) {
296
311
  Descriptor* self = ruby_to_Descriptor(_self);
297
- return get_filedef_obj(self->descriptor_pool, upb_msgdef_file(self->msgdef));
312
+ return get_filedef_obj(self->descriptor_pool,
313
+ upb_MessageDef_File(self->msgdef));
298
314
  }
299
315
 
300
316
  /*
@@ -306,7 +322,7 @@ static VALUE Descriptor_file_descriptor(VALUE _self) {
306
322
  */
307
323
  static VALUE Descriptor_name(VALUE _self) {
308
324
  Descriptor* self = ruby_to_Descriptor(_self);
309
- return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
325
+ return rb_str_maybe_null(upb_MessageDef_FullName(self->msgdef));
310
326
  }
311
327
 
312
328
  /*
@@ -318,11 +334,9 @@ static VALUE Descriptor_name(VALUE _self) {
318
334
  static VALUE Descriptor_each(VALUE _self) {
319
335
  Descriptor* self = ruby_to_Descriptor(_self);
320
336
 
321
- upb_msg_field_iter it;
322
- for (upb_msg_field_begin(&it, self->msgdef);
323
- !upb_msg_field_done(&it);
324
- upb_msg_field_next(&it)) {
325
- const upb_fielddef* field = upb_msg_iter_field(&it);
337
+ int n = upb_MessageDef_FieldCount(self->msgdef);
338
+ for (int i = 0; i < n; i++) {
339
+ const upb_FieldDef* field = upb_MessageDef_Field(self->msgdef, i);
326
340
  VALUE obj = get_fielddef_obj(self->descriptor_pool, field);
327
341
  rb_yield(obj);
328
342
  }
@@ -339,7 +353,7 @@ static VALUE Descriptor_each(VALUE _self) {
339
353
  static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
340
354
  Descriptor* self = ruby_to_Descriptor(_self);
341
355
  const char* s = get_str(name);
342
- const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s);
356
+ const upb_FieldDef* field = upb_MessageDef_FindFieldByName(self->msgdef, s);
343
357
  if (field == NULL) {
344
358
  return Qnil;
345
359
  }
@@ -356,11 +370,9 @@ static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
356
370
  static VALUE Descriptor_each_oneof(VALUE _self) {
357
371
  Descriptor* self = ruby_to_Descriptor(_self);
358
372
 
359
- upb_msg_oneof_iter it;
360
- for (upb_msg_oneof_begin(&it, self->msgdef);
361
- !upb_msg_oneof_done(&it);
362
- upb_msg_oneof_next(&it)) {
363
- const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
373
+ int n = upb_MessageDef_OneofCount(self->msgdef);
374
+ for (int i = 0; i < n; i++) {
375
+ const upb_OneofDef* oneof = upb_MessageDef_Oneof(self->msgdef, i);
364
376
  VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof);
365
377
  rb_yield(obj);
366
378
  }
@@ -377,7 +389,7 @@ static VALUE Descriptor_each_oneof(VALUE _self) {
377
389
  static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
378
390
  Descriptor* self = ruby_to_Descriptor(_self);
379
391
  const char* s = get_str(name);
380
- const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s);
392
+ const upb_OneofDef* oneof = upb_MessageDef_FindOneofByName(self->msgdef, s);
381
393
  if (oneof == NULL) {
382
394
  return Qnil;
383
395
  }
@@ -393,14 +405,33 @@ static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
393
405
  static VALUE Descriptor_msgclass(VALUE _self) {
394
406
  Descriptor* self = ruby_to_Descriptor(_self);
395
407
  if (self->klass == Qnil) {
396
- self->klass = build_class_from_descriptor(_self);
408
+ RB_OBJ_WRITE(_self, &self->klass, build_class_from_descriptor(_self));
397
409
  }
398
410
  return self->klass;
399
411
  }
400
412
 
413
+ /*
414
+ * call-seq:
415
+ * Descriptor.options => options
416
+ *
417
+ * Returns the `MessageOptions` for this `Descriptor`.
418
+ */
419
+ static VALUE Descriptor_options(VALUE _self) {
420
+ Descriptor* self = ruby_to_Descriptor(_self);
421
+ const google_protobuf_MessageOptions* opts =
422
+ upb_MessageDef_Options(self->msgdef);
423
+ upb_Arena* arena = upb_Arena_New();
424
+ size_t size;
425
+ char* serialized =
426
+ google_protobuf_MessageOptions_serialize(opts, arena, &size);
427
+ VALUE message_options = decode_options(_self, "MessageOptions", size,
428
+ serialized, self->descriptor_pool);
429
+ upb_Arena_Free(arena);
430
+ return message_options;
431
+ }
432
+
401
433
  static void Descriptor_register(VALUE module) {
402
- VALUE klass = rb_define_class_under(
403
- module, "Descriptor", rb_cObject);
434
+ VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
404
435
  rb_define_alloc_func(klass, Descriptor_alloc);
405
436
  rb_define_method(klass, "initialize", Descriptor_initialize, 3);
406
437
  rb_define_method(klass, "each", Descriptor_each, 0);
@@ -410,6 +441,7 @@ static void Descriptor_register(VALUE module) {
410
441
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
411
442
  rb_define_method(klass, "name", Descriptor_name, 0);
412
443
  rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
444
+ rb_define_method(klass, "options", Descriptor_options, 0);
413
445
  rb_include_module(klass, rb_mEnumerable);
414
446
  rb_gc_register_address(&cDescriptor);
415
447
  cDescriptor = klass;
@@ -420,8 +452,10 @@ static void Descriptor_register(VALUE module) {
420
452
  // -----------------------------------------------------------------------------
421
453
 
422
454
  typedef struct {
423
- const upb_filedef* filedef;
424
- VALUE descriptor_pool; // Owns the upb_filedef.
455
+ const upb_FileDef* filedef;
456
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
457
+ // macro to update VALUE references, as to trigger write barriers.
458
+ VALUE descriptor_pool; // Owns the upb_FileDef.
425
459
  } FileDescriptor;
426
460
 
427
461
  static VALUE cFileDescriptor = Qnil;
@@ -432,9 +466,9 @@ static void FileDescriptor_mark(void* _self) {
432
466
  }
433
467
 
434
468
  static const rb_data_type_t FileDescriptor_type = {
435
- "Google::Protobuf::FileDescriptor",
436
- {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
437
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
469
+ "Google::Protobuf::FileDescriptor",
470
+ {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
471
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
438
472
  };
439
473
 
440
474
  static FileDescriptor* ruby_to_FileDescriptor(VALUE val) {
@@ -459,7 +493,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
459
493
  * to a builder.
460
494
  */
461
495
  static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
462
- VALUE descriptor_pool, VALUE ptr) {
496
+ VALUE descriptor_pool, VALUE ptr) {
463
497
  FileDescriptor* self = ruby_to_FileDescriptor(_self);
464
498
 
465
499
  if (cookie != c_only_cookie) {
@@ -467,8 +501,8 @@ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
467
501
  "Descriptor objects may not be created from Ruby.");
468
502
  }
469
503
 
470
- self->descriptor_pool = descriptor_pool;
471
- self->filedef = (const upb_filedef*)NUM2ULL(ptr);
504
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
505
+ self->filedef = (const upb_FileDef*)NUM2ULL(ptr);
472
506
 
473
507
  return Qnil;
474
508
  }
@@ -481,7 +515,7 @@ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
481
515
  */
482
516
  static VALUE FileDescriptor_name(VALUE _self) {
483
517
  FileDescriptor* self = ruby_to_FileDescriptor(_self);
484
- const char* name = upb_filedef_name(self->filedef);
518
+ const char* name = upb_FileDef_Name(self->filedef);
485
519
  return name == NULL ? Qnil : rb_str_new2(name);
486
520
  }
487
521
 
@@ -497,20 +531,41 @@ static VALUE FileDescriptor_name(VALUE _self) {
497
531
  static VALUE FileDescriptor_syntax(VALUE _self) {
498
532
  FileDescriptor* self = ruby_to_FileDescriptor(_self);
499
533
 
500
- switch (upb_filedef_syntax(self->filedef)) {
501
- case UPB_SYNTAX_PROTO3: return ID2SYM(rb_intern("proto3"));
502
- case UPB_SYNTAX_PROTO2: return ID2SYM(rb_intern("proto2"));
503
- default: return Qnil;
534
+ switch (upb_FileDef_Syntax(self->filedef)) {
535
+ case kUpb_Syntax_Proto3:
536
+ return ID2SYM(rb_intern("proto3"));
537
+ case kUpb_Syntax_Proto2:
538
+ return ID2SYM(rb_intern("proto2"));
539
+ default:
540
+ return Qnil;
504
541
  }
505
542
  }
506
543
 
544
+ /*
545
+ * call-seq:
546
+ * FileDescriptor.options => options
547
+ *
548
+ * Returns the `FileOptions` for this `FileDescriptor`.
549
+ */
550
+ static VALUE FileDescriptor_options(VALUE _self) {
551
+ FileDescriptor* self = ruby_to_FileDescriptor(_self);
552
+ const google_protobuf_FileOptions* opts = upb_FileDef_Options(self->filedef);
553
+ upb_Arena* arena = upb_Arena_New();
554
+ size_t size;
555
+ char* serialized = google_protobuf_FileOptions_serialize(opts, arena, &size);
556
+ VALUE file_options = decode_options(_self, "FileOptions", size, serialized,
557
+ self->descriptor_pool);
558
+ upb_Arena_Free(arena);
559
+ return file_options;
560
+ }
561
+
507
562
  static void FileDescriptor_register(VALUE module) {
508
- VALUE klass = rb_define_class_under(
509
- module, "FileDescriptor", rb_cObject);
563
+ VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject);
510
564
  rb_define_alloc_func(klass, FileDescriptor_alloc);
511
565
  rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
512
566
  rb_define_method(klass, "name", FileDescriptor_name, 0);
513
567
  rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
568
+ rb_define_method(klass, "options", FileDescriptor_options, 0);
514
569
  rb_gc_register_address(&cFileDescriptor);
515
570
  cFileDescriptor = klass;
516
571
  }
@@ -520,8 +575,10 @@ static void FileDescriptor_register(VALUE module) {
520
575
  // -----------------------------------------------------------------------------
521
576
 
522
577
  typedef struct {
523
- const upb_fielddef* fielddef;
524
- VALUE descriptor_pool; // Owns the upb_fielddef.
578
+ const upb_FieldDef* fielddef;
579
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
580
+ // macro to update VALUE references, as to trigger write barriers.
581
+ VALUE descriptor_pool; // Owns the upb_FieldDef.
525
582
  } FieldDescriptor;
526
583
 
527
584
  static VALUE cFieldDescriptor = Qnil;
@@ -532,9 +589,9 @@ static void FieldDescriptor_mark(void* _self) {
532
589
  }
533
590
 
534
591
  static const rb_data_type_t FieldDescriptor_type = {
535
- "Google::Protobuf::FieldDescriptor",
536
- {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
537
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
592
+ "Google::Protobuf::FieldDescriptor",
593
+ {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
594
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
538
595
  };
539
596
 
540
597
  static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) {
@@ -559,7 +616,7 @@ static VALUE FieldDescriptor_alloc(VALUE klass) {
559
616
 
560
617
  /*
561
618
  * call-seq:
562
- * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
619
+ * FieldDescriptor.new(c_only_cookie, pool, ptr) => FieldDescriptor
563
620
  *
564
621
  * Creates a descriptor wrapper object. May only be called from C.
565
622
  */
@@ -572,8 +629,8 @@ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
572
629
  "Descriptor objects may not be created from Ruby.");
573
630
  }
574
631
 
575
- self->descriptor_pool = descriptor_pool;
576
- self->fielddef = (const upb_fielddef*)NUM2ULL(ptr);
632
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
633
+ self->fielddef = (const upb_FieldDef*)NUM2ULL(ptr);
577
634
 
578
635
  return Qnil;
579
636
  }
@@ -586,31 +643,31 @@ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
586
643
  */
587
644
  static VALUE FieldDescriptor_name(VALUE _self) {
588
645
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
589
- return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
646
+ return rb_str_maybe_null(upb_FieldDef_Name(self->fielddef));
590
647
  }
591
648
 
592
649
  // Non-static, exposed to other .c files.
593
- upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
650
+ upb_CType ruby_to_fieldtype(VALUE type) {
594
651
  if (TYPE(type) != T_SYMBOL) {
595
652
  rb_raise(rb_eArgError, "Expected symbol for field type.");
596
653
  }
597
654
 
598
- #define CONVERT(upb, ruby) \
599
- if (SYM2ID(type) == rb_intern( # ruby )) { \
600
- return UPB_TYPE_ ## upb; \
655
+ #define CONVERT(upb, ruby) \
656
+ if (SYM2ID(type) == rb_intern(#ruby)) { \
657
+ return kUpb_CType_##upb; \
601
658
  }
602
659
 
603
- CONVERT(FLOAT, float);
604
- CONVERT(DOUBLE, double);
605
- CONVERT(BOOL, bool);
606
- CONVERT(STRING, string);
607
- CONVERT(BYTES, bytes);
608
- CONVERT(MESSAGE, message);
609
- CONVERT(ENUM, enum);
610
- CONVERT(INT32, int32);
611
- CONVERT(INT64, int64);
612
- CONVERT(UINT32, uint32);
613
- CONVERT(UINT64, uint64);
660
+ CONVERT(Float, float);
661
+ CONVERT(Double, double);
662
+ CONVERT(Bool, bool);
663
+ CONVERT(String, string);
664
+ CONVERT(Bytes, bytes);
665
+ CONVERT(Message, message);
666
+ CONVERT(Enum, enum);
667
+ CONVERT(Int32, int32);
668
+ CONVERT(Int64, int64);
669
+ CONVERT(UInt32, uint32);
670
+ CONVERT(UInt64, uint64);
614
671
 
615
672
  #undef CONVERT
616
673
 
@@ -618,28 +675,29 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
618
675
  return 0;
619
676
  }
620
677
 
621
- static VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
678
+ static VALUE descriptortype_to_ruby(upb_FieldType type) {
622
679
  switch (type) {
623
- #define CONVERT(upb, ruby) \
624
- case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
625
- CONVERT(FLOAT, float);
626
- CONVERT(DOUBLE, double);
627
- CONVERT(BOOL, bool);
628
- CONVERT(STRING, string);
629
- CONVERT(BYTES, bytes);
630
- CONVERT(MESSAGE, message);
631
- CONVERT(GROUP, group);
632
- CONVERT(ENUM, enum);
633
- CONVERT(INT32, int32);
634
- CONVERT(INT64, int64);
635
- CONVERT(UINT32, uint32);
636
- CONVERT(UINT64, uint64);
637
- CONVERT(SINT32, sint32);
638
- CONVERT(SINT64, sint64);
639
- CONVERT(FIXED32, fixed32);
640
- CONVERT(FIXED64, fixed64);
641
- CONVERT(SFIXED32, sfixed32);
642
- CONVERT(SFIXED64, sfixed64);
680
+ #define CONVERT(upb, ruby) \
681
+ case kUpb_FieldType_##upb: \
682
+ return ID2SYM(rb_intern(#ruby));
683
+ CONVERT(Float, float);
684
+ CONVERT(Double, double);
685
+ CONVERT(Bool, bool);
686
+ CONVERT(String, string);
687
+ CONVERT(Bytes, bytes);
688
+ CONVERT(Message, message);
689
+ CONVERT(Group, group);
690
+ CONVERT(Enum, enum);
691
+ CONVERT(Int32, int32);
692
+ CONVERT(Int64, int64);
693
+ CONVERT(UInt32, uint32);
694
+ CONVERT(UInt64, uint64);
695
+ CONVERT(SInt32, sint32);
696
+ CONVERT(SInt64, sint64);
697
+ CONVERT(Fixed32, fixed32);
698
+ CONVERT(Fixed64, fixed64);
699
+ CONVERT(SFixed32, sfixed32);
700
+ CONVERT(SFixed64, sfixed64);
643
701
  #undef CONVERT
644
702
  }
645
703
  return Qnil;
@@ -657,7 +715,7 @@ static VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
657
715
  */
658
716
  static VALUE FieldDescriptor__type(VALUE _self) {
659
717
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
660
- return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
718
+ return descriptortype_to_ruby(upb_FieldDef_Type(self->fielddef));
661
719
  }
662
720
 
663
721
  /*
@@ -668,17 +726,16 @@ static VALUE FieldDescriptor__type(VALUE _self) {
668
726
  */
669
727
  static VALUE FieldDescriptor_default(VALUE _self) {
670
728
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
671
- const upb_fielddef *f = self->fielddef;
672
- upb_msgval default_val = {0};
673
- if (upb_fielddef_issubmsg(f)) {
729
+ const upb_FieldDef* f = self->fielddef;
730
+ upb_MessageValue default_val = {0};
731
+ if (upb_FieldDef_IsSubMessage(f)) {
674
732
  return Qnil;
675
- } else if (!upb_fielddef_isseq(f)) {
676
- default_val = upb_fielddef_default(f);
733
+ } else if (!upb_FieldDef_IsRepeated(f)) {
734
+ default_val = upb_FieldDef_Default(f);
677
735
  }
678
736
  return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
679
737
  }
680
738
 
681
-
682
739
  /*
683
740
  * call-seq:
684
741
  * FieldDescriptor.json_name => json_name
@@ -687,8 +744,8 @@ static VALUE FieldDescriptor_default(VALUE _self) {
687
744
  */
688
745
  static VALUE FieldDescriptor_json_name(VALUE _self) {
689
746
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
690
- const upb_fielddef *f = self->fielddef;
691
- const char *json_name = upb_fielddef_jsonname(f);
747
+ const upb_FieldDef* f = self->fielddef;
748
+ const char* json_name = upb_FieldDef_JsonName(f);
692
749
  return rb_str_new2(json_name);
693
750
  }
694
751
 
@@ -703,13 +760,14 @@ static VALUE FieldDescriptor_json_name(VALUE _self) {
703
760
  */
704
761
  static VALUE FieldDescriptor_label(VALUE _self) {
705
762
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
706
- switch (upb_fielddef_label(self->fielddef)) {
707
- #define CONVERT(upb, ruby) \
708
- case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby ));
763
+ switch (upb_FieldDef_Label(self->fielddef)) {
764
+ #define CONVERT(upb, ruby) \
765
+ case kUpb_Label_##upb: \
766
+ return ID2SYM(rb_intern(#ruby));
709
767
 
710
- CONVERT(OPTIONAL, optional);
711
- CONVERT(REQUIRED, required);
712
- CONVERT(REPEATED, repeated);
768
+ CONVERT(Optional, optional);
769
+ CONVERT(Required, required);
770
+ CONVERT(Repeated, repeated);
713
771
 
714
772
  #undef CONVERT
715
773
  }
@@ -725,7 +783,7 @@ static VALUE FieldDescriptor_label(VALUE _self) {
725
783
  */
726
784
  static VALUE FieldDescriptor_number(VALUE _self) {
727
785
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
728
- return INT2NUM(upb_fielddef_number(self->fielddef));
786
+ return INT2NUM(upb_FieldDef_Number(self->fielddef));
729
787
  }
730
788
 
731
789
  /*
@@ -739,13 +797,13 @@ static VALUE FieldDescriptor_number(VALUE _self) {
739
797
  */
740
798
  static VALUE FieldDescriptor_submsg_name(VALUE _self) {
741
799
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
742
- switch (upb_fielddef_type(self->fielddef)) {
743
- case UPB_TYPE_ENUM:
800
+ switch (upb_FieldDef_CType(self->fielddef)) {
801
+ case kUpb_CType_Enum:
744
802
  return rb_str_new2(
745
- upb_enumdef_fullname(upb_fielddef_enumsubdef(self->fielddef)));
746
- case UPB_TYPE_MESSAGE:
803
+ upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(self->fielddef)));
804
+ case kUpb_CType_Message:
747
805
  return rb_str_new2(
748
- upb_msgdef_fullname(upb_fielddef_msgsubdef(self->fielddef)));
806
+ upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(self->fielddef)));
749
807
  default:
750
808
  return Qnil;
751
809
  }
@@ -762,13 +820,13 @@ static VALUE FieldDescriptor_submsg_name(VALUE _self) {
762
820
  */
763
821
  static VALUE FieldDescriptor_subtype(VALUE _self) {
764
822
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
765
- switch (upb_fielddef_type(self->fielddef)) {
766
- case UPB_TYPE_ENUM:
823
+ switch (upb_FieldDef_CType(self->fielddef)) {
824
+ case kUpb_CType_Enum:
767
825
  return get_enumdef_obj(self->descriptor_pool,
768
- upb_fielddef_enumsubdef(self->fielddef));
769
- case UPB_TYPE_MESSAGE:
826
+ upb_FieldDef_EnumSubDef(self->fielddef));
827
+ case kUpb_CType_Message:
770
828
  return get_msgdef_obj(self->descriptor_pool,
771
- upb_fielddef_msgsubdef(self->fielddef));
829
+ upb_FieldDef_MessageSubDef(self->fielddef));
772
830
  default:
773
831
  return Qnil;
774
832
  }
@@ -783,11 +841,11 @@ static VALUE FieldDescriptor_subtype(VALUE _self) {
783
841
  */
784
842
  static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
785
843
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
786
- const upb_msgdef *m;
844
+ const upb_MessageDef* m;
787
845
 
788
846
  Message_Get(msg_rb, &m);
789
847
 
790
- if (m != upb_fielddef_containingtype(self->fielddef)) {
848
+ if (m != upb_FieldDef_ContainingType(self->fielddef)) {
791
849
  rb_raise(cTypeError, "get method called on wrong message type");
792
850
  }
793
851
 
@@ -803,16 +861,16 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
803
861
  */
804
862
  static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
805
863
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
806
- const upb_msgdef *m;
807
- const upb_msgdef *msg = Message_Get(msg_rb, &m);
864
+ const upb_MessageDef* m;
865
+ const upb_MessageDef* msg = Message_Get(msg_rb, &m);
808
866
 
809
- if (m != upb_fielddef_containingtype(self->fielddef)) {
867
+ if (m != upb_FieldDef_ContainingType(self->fielddef)) {
810
868
  rb_raise(cTypeError, "has method called on wrong message type");
811
- } else if (!upb_fielddef_haspresence(self->fielddef)) {
869
+ } else if (!upb_FieldDef_HasPresence(self->fielddef)) {
812
870
  rb_raise(rb_eArgError, "does not track presence");
813
871
  }
814
872
 
815
- return upb_msg_has(msg, self->fielddef) ? Qtrue : Qfalse;
873
+ return upb_Message_HasFieldByDef(msg, self->fielddef) ? Qtrue : Qfalse;
816
874
  }
817
875
 
818
876
  /*
@@ -823,14 +881,14 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
823
881
  */
824
882
  static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
825
883
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
826
- const upb_msgdef *m;
827
- upb_msgdef *msg = Message_GetMutable(msg_rb, &m);
884
+ const upb_MessageDef* m;
885
+ upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
828
886
 
829
- if (m != upb_fielddef_containingtype(self->fielddef)) {
887
+ if (m != upb_FieldDef_ContainingType(self->fielddef)) {
830
888
  rb_raise(cTypeError, "has method called on wrong message type");
831
889
  }
832
890
 
833
- upb_msg_clearfield(msg, self->fielddef);
891
+ upb_Message_ClearFieldByDef(msg, self->fielddef);
834
892
  return Qnil;
835
893
  }
836
894
 
@@ -844,24 +902,42 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
844
902
  */
845
903
  static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
846
904
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
847
- const upb_msgdef *m;
848
- upb_msgdef *msg = Message_GetMutable(msg_rb, &m);
849
- upb_arena *arena = Arena_get(Message_GetArena(msg_rb));
850
- upb_msgval msgval;
905
+ const upb_MessageDef* m;
906
+ upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
907
+ upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
908
+ upb_MessageValue msgval;
851
909
 
852
- if (m != upb_fielddef_containingtype(self->fielddef)) {
910
+ if (m != upb_FieldDef_ContainingType(self->fielddef)) {
853
911
  rb_raise(cTypeError, "set method called on wrong message type");
854
912
  }
855
913
 
856
- msgval = Convert_RubyToUpb(value, upb_fielddef_name(self->fielddef),
914
+ msgval = Convert_RubyToUpb(value, upb_FieldDef_Name(self->fielddef),
857
915
  TypeInfo_get(self->fielddef), arena);
858
- upb_msg_set(msg, self->fielddef, msgval, arena);
916
+ upb_Message_SetFieldByDef(msg, self->fielddef, msgval, arena);
859
917
  return Qnil;
860
918
  }
861
919
 
920
+ /*
921
+ * call-seq:
922
+ * FieldDescriptor.options => options
923
+ *
924
+ * Returns the `FieldOptions` for this `FieldDescriptor`.
925
+ */
926
+ static VALUE FieldDescriptor_options(VALUE _self) {
927
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
928
+ const google_protobuf_FieldOptions* opts =
929
+ upb_FieldDef_Options(self->fielddef);
930
+ upb_Arena* arena = upb_Arena_New();
931
+ size_t size;
932
+ char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, &size);
933
+ VALUE field_options = decode_options(_self, "FieldOptions", size, serialized,
934
+ self->descriptor_pool);
935
+ upb_Arena_Free(arena);
936
+ return field_options;
937
+ }
938
+
862
939
  static void FieldDescriptor_register(VALUE module) {
863
- VALUE klass = rb_define_class_under(
864
- module, "FieldDescriptor", rb_cObject);
940
+ VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
865
941
  rb_define_alloc_func(klass, FieldDescriptor_alloc);
866
942
  rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
867
943
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
@@ -876,6 +952,7 @@ static void FieldDescriptor_register(VALUE module) {
876
952
  rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
877
953
  rb_define_method(klass, "get", FieldDescriptor_get, 1);
878
954
  rb_define_method(klass, "set", FieldDescriptor_set, 2);
955
+ rb_define_method(klass, "options", FieldDescriptor_options, 0);
879
956
  rb_gc_register_address(&cFieldDescriptor);
880
957
  cFieldDescriptor = klass;
881
958
  }
@@ -885,8 +962,10 @@ static void FieldDescriptor_register(VALUE module) {
885
962
  // -----------------------------------------------------------------------------
886
963
 
887
964
  typedef struct {
888
- const upb_oneofdef* oneofdef;
889
- VALUE descriptor_pool; // Owns the upb_oneofdef.
965
+ const upb_OneofDef* oneofdef;
966
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
967
+ // macro to update VALUE references, as to trigger write barriers.
968
+ VALUE descriptor_pool; // Owns the upb_OneofDef.
890
969
  } OneofDescriptor;
891
970
 
892
971
  static VALUE cOneofDescriptor = Qnil;
@@ -899,7 +978,7 @@ static void OneofDescriptor_mark(void* _self) {
899
978
  static const rb_data_type_t OneofDescriptor_type = {
900
979
  "Google::Protobuf::OneofDescriptor",
901
980
  {OneofDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
902
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
981
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
903
982
  };
904
983
 
905
984
  static OneofDescriptor* ruby_to_OneofDescriptor(VALUE val) {
@@ -930,7 +1009,7 @@ static VALUE OneofDescriptor_alloc(VALUE klass) {
930
1009
  * Creates a descriptor wrapper object. May only be called from C.
931
1010
  */
932
1011
  static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
933
- VALUE descriptor_pool, VALUE ptr) {
1012
+ VALUE descriptor_pool, VALUE ptr) {
934
1013
  OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
935
1014
 
936
1015
  if (cookie != c_only_cookie) {
@@ -938,8 +1017,8 @@ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
938
1017
  "Descriptor objects may not be created from Ruby.");
939
1018
  }
940
1019
 
941
- self->descriptor_pool = descriptor_pool;
942
- self->oneofdef = (const upb_oneofdef*)NUM2ULL(ptr);
1020
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1021
+ self->oneofdef = (const upb_OneofDef*)NUM2ULL(ptr);
943
1022
 
944
1023
  return Qnil;
945
1024
  }
@@ -952,7 +1031,7 @@ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
952
1031
  */
953
1032
  static VALUE OneofDescriptor_name(VALUE _self) {
954
1033
  OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
955
- return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
1034
+ return rb_str_maybe_null(upb_OneofDef_Name(self->oneofdef));
956
1035
  }
957
1036
 
958
1037
  /*
@@ -963,24 +1042,42 @@ static VALUE OneofDescriptor_name(VALUE _self) {
963
1042
  */
964
1043
  static VALUE OneofDescriptor_each(VALUE _self) {
965
1044
  OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
966
- upb_oneof_iter it;
967
- for (upb_oneof_begin(&it, self->oneofdef);
968
- !upb_oneof_done(&it);
969
- upb_oneof_next(&it)) {
970
- const upb_fielddef* f = upb_oneof_iter_field(&it);
1045
+
1046
+ int n = upb_OneofDef_FieldCount(self->oneofdef);
1047
+ for (int i = 0; i < n; i++) {
1048
+ const upb_FieldDef* f = upb_OneofDef_Field(self->oneofdef, i);
971
1049
  VALUE obj = get_fielddef_obj(self->descriptor_pool, f);
972
1050
  rb_yield(obj);
973
1051
  }
974
1052
  return Qnil;
975
1053
  }
976
1054
 
1055
+ /*
1056
+ * call-seq:
1057
+ * OneofDescriptor.options => options
1058
+ *
1059
+ * Returns the `OneofOptions` for this `OneofDescriptor`.
1060
+ */
1061
+ static VALUE OneOfDescriptor_options(VALUE _self) {
1062
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1063
+ const google_protobuf_OneofOptions* opts =
1064
+ upb_OneofDef_Options(self->oneofdef);
1065
+ upb_Arena* arena = upb_Arena_New();
1066
+ size_t size;
1067
+ char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, &size);
1068
+ VALUE oneof_options = decode_options(_self, "OneofOptions", size, serialized,
1069
+ self->descriptor_pool);
1070
+ upb_Arena_Free(arena);
1071
+ return oneof_options;
1072
+ }
1073
+
977
1074
  static void OneofDescriptor_register(VALUE module) {
978
- VALUE klass = rb_define_class_under(
979
- module, "OneofDescriptor", rb_cObject);
1075
+ VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
980
1076
  rb_define_alloc_func(klass, OneofDescriptor_alloc);
981
1077
  rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
982
1078
  rb_define_method(klass, "name", OneofDescriptor_name, 0);
983
1079
  rb_define_method(klass, "each", OneofDescriptor_each, 0);
1080
+ rb_define_method(klass, "options", OneOfDescriptor_options, 0);
984
1081
  rb_include_module(klass, rb_mEnumerable);
985
1082
  rb_gc_register_address(&cOneofDescriptor);
986
1083
  cOneofDescriptor = klass;
@@ -991,9 +1088,11 @@ static void OneofDescriptor_register(VALUE module) {
991
1088
  // -----------------------------------------------------------------------------
992
1089
 
993
1090
  typedef struct {
994
- const upb_enumdef* enumdef;
995
- VALUE module; // begins as nil
996
- VALUE descriptor_pool; // Owns the upb_enumdef.
1091
+ const upb_EnumDef* enumdef;
1092
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
1093
+ // macro to update VALUE references, as to trigger write barriers.
1094
+ VALUE module; // begins as nil
1095
+ VALUE descriptor_pool; // Owns the upb_EnumDef.
997
1096
  } EnumDescriptor;
998
1097
 
999
1098
  static VALUE cEnumDescriptor = Qnil;
@@ -1005,9 +1104,9 @@ static void EnumDescriptor_mark(void* _self) {
1005
1104
  }
1006
1105
 
1007
1106
  static const rb_data_type_t EnumDescriptor_type = {
1008
- "Google::Protobuf::EnumDescriptor",
1009
- {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1010
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
1107
+ "Google::Protobuf::EnumDescriptor",
1108
+ {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1109
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1011
1110
  };
1012
1111
 
1013
1112
  static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) {
@@ -1026,8 +1125,8 @@ static VALUE EnumDescriptor_alloc(VALUE klass) {
1026
1125
  }
1027
1126
 
1028
1127
  // Exposed to other modules in defs.h.
1029
- const upb_enumdef *EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) {
1030
- EnumDescriptor *desc = ruby_to_EnumDescriptor(enum_desc_rb);
1128
+ const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) {
1129
+ EnumDescriptor* desc = ruby_to_EnumDescriptor(enum_desc_rb);
1031
1130
  return desc->enumdef;
1032
1131
  }
1033
1132
 
@@ -1046,8 +1145,8 @@ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
1046
1145
  "Descriptor objects may not be created from Ruby.");
1047
1146
  }
1048
1147
 
1049
- self->descriptor_pool = descriptor_pool;
1050
- self->enumdef = (const upb_enumdef*)NUM2ULL(ptr);
1148
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1149
+ self->enumdef = (const upb_EnumDef*)NUM2ULL(ptr);
1051
1150
 
1052
1151
  return Qnil;
1053
1152
  }
@@ -1061,7 +1160,7 @@ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
1061
1160
  static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1062
1161
  EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1063
1162
  return get_filedef_obj(self->descriptor_pool,
1064
- upb_enumdef_file(self->enumdef));
1163
+ upb_EnumDef_File(self->enumdef));
1065
1164
  }
1066
1165
 
1067
1166
  /*
@@ -1072,7 +1171,7 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1072
1171
  */
1073
1172
  static VALUE EnumDescriptor_name(VALUE _self) {
1074
1173
  EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1075
- return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
1174
+ return rb_str_maybe_null(upb_EnumDef_FullName(self->enumdef));
1076
1175
  }
1077
1176
 
1078
1177
  /*
@@ -1084,10 +1183,11 @@ static VALUE EnumDescriptor_name(VALUE _self) {
1084
1183
  */
1085
1184
  static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1086
1185
  EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1087
- const char* name_str= rb_id2name(SYM2ID(name));
1088
- int32_t val = 0;
1089
- if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) {
1090
- return INT2NUM(val);
1186
+ const char* name_str = rb_id2name(SYM2ID(name));
1187
+ const upb_EnumValueDef* ev =
1188
+ upb_EnumDef_FindValueByName(self->enumdef, name_str);
1189
+ if (ev) {
1190
+ return INT2NUM(upb_EnumValueDef_Number(ev));
1091
1191
  } else {
1092
1192
  return Qnil;
1093
1193
  }
@@ -1103,9 +1203,10 @@ static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1103
1203
  static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1104
1204
  EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1105
1205
  int32_t val = NUM2INT(number);
1106
- const char* name = upb_enumdef_iton(self->enumdef, val);
1107
- if (name != NULL) {
1108
- return ID2SYM(rb_intern(name));
1206
+ const upb_EnumValueDef* ev =
1207
+ upb_EnumDef_FindValueByNumber(self->enumdef, val);
1208
+ if (ev) {
1209
+ return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
1109
1210
  } else {
1110
1211
  return Qnil;
1111
1212
  }
@@ -1121,12 +1222,11 @@ static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1121
1222
  static VALUE EnumDescriptor_each(VALUE _self) {
1122
1223
  EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1123
1224
 
1124
- upb_enum_iter it;
1125
- for (upb_enum_begin(&it, self->enumdef);
1126
- !upb_enum_done(&it);
1127
- upb_enum_next(&it)) {
1128
- VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it)));
1129
- VALUE number = INT2NUM(upb_enum_iter_number(&it));
1225
+ int n = upb_EnumDef_ValueCount(self->enumdef);
1226
+ for (int i = 0; i < n; i++) {
1227
+ const upb_EnumValueDef* ev = upb_EnumDef_Value(self->enumdef, i);
1228
+ VALUE key = ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
1229
+ VALUE number = INT2NUM(upb_EnumValueDef_Number(ev));
1130
1230
  rb_yield_values(2, key, number);
1131
1231
  }
1132
1232
 
@@ -1142,14 +1242,31 @@ static VALUE EnumDescriptor_each(VALUE _self) {
1142
1242
  static VALUE EnumDescriptor_enummodule(VALUE _self) {
1143
1243
  EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1144
1244
  if (self->module == Qnil) {
1145
- self->module = build_module_from_enumdesc(_self);
1245
+ RB_OBJ_WRITE(_self, &self->module, build_module_from_enumdesc(_self));
1146
1246
  }
1147
1247
  return self->module;
1148
1248
  }
1149
1249
 
1250
+ /*
1251
+ * call-seq:
1252
+ * EnumDescriptor.options => options
1253
+ *
1254
+ * Returns the `EnumOptions` for this `EnumDescriptor`.
1255
+ */
1256
+ static VALUE EnumDescriptor_options(VALUE _self) {
1257
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1258
+ const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(self->enumdef);
1259
+ upb_Arena* arena = upb_Arena_New();
1260
+ size_t size;
1261
+ char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, &size);
1262
+ VALUE enum_options = decode_options(_self, "EnumOptions", size, serialized,
1263
+ self->descriptor_pool);
1264
+ upb_Arena_Free(arena);
1265
+ return enum_options;
1266
+ }
1267
+
1150
1268
  static void EnumDescriptor_register(VALUE module) {
1151
- VALUE klass = rb_define_class_under(
1152
- module, "EnumDescriptor", rb_cObject);
1269
+ VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
1153
1270
  rb_define_alloc_func(klass, EnumDescriptor_alloc);
1154
1271
  rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
1155
1272
  rb_define_method(klass, "name", EnumDescriptor_name, 0);
@@ -1158,6 +1275,7 @@ static void EnumDescriptor_register(VALUE module) {
1158
1275
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1159
1276
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1160
1277
  rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1278
+ rb_define_method(klass, "options", EnumDescriptor_options, 0);
1161
1279
  rb_include_module(klass, rb_mEnumerable);
1162
1280
  rb_gc_register_address(&cEnumDescriptor);
1163
1281
  cEnumDescriptor = klass;
@@ -1176,7 +1294,7 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
1176
1294
 
1177
1295
  if (def == Qnil) {
1178
1296
  // Lazily create wrapper object.
1179
- VALUE args[3] = { c_only_cookie, _descriptor_pool, key };
1297
+ VALUE args[3] = {c_only_cookie, _descriptor_pool, key};
1180
1298
  def = rb_class_new_instance(3, args, klass);
1181
1299
  rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
1182
1300
  }
@@ -1184,23 +1302,23 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
1184
1302
  return def;
1185
1303
  }
1186
1304
 
1187
- static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) {
1305
+ static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def) {
1188
1306
  return get_def_obj(descriptor_pool, def, cDescriptor);
1189
1307
  }
1190
1308
 
1191
- static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) {
1309
+ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def) {
1192
1310
  return get_def_obj(descriptor_pool, def, cEnumDescriptor);
1193
1311
  }
1194
1312
 
1195
- static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) {
1313
+ static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def) {
1196
1314
  return get_def_obj(descriptor_pool, def, cFieldDescriptor);
1197
1315
  }
1198
1316
 
1199
- static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) {
1317
+ static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def) {
1200
1318
  return get_def_obj(descriptor_pool, def, cFileDescriptor);
1201
1319
  }
1202
1320
 
1203
- static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
1321
+ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
1204
1322
  return get_def_obj(descriptor_pool, def, cOneofDescriptor);
1205
1323
  }
1206
1324
 
@@ -1210,8 +1328,8 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
1210
1328
 
1211
1329
  // Functions exposed to other modules in defs.h.
1212
1330
 
1213
- VALUE Descriptor_DefToClass(const upb_msgdef *m) {
1214
- const upb_symtab *symtab = upb_filedef_symtab(upb_msgdef_file(m));
1331
+ VALUE Descriptor_DefToClass(const upb_MessageDef* m) {
1332
+ const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m));
1215
1333
  VALUE pool = ObjectCache_Get(symtab);
1216
1334
  PBRUBY_ASSERT(pool != Qnil);
1217
1335
  VALUE desc_rb = get_msgdef_obj(pool, m);
@@ -1219,15 +1337,16 @@ VALUE Descriptor_DefToClass(const upb_msgdef *m) {
1219
1337
  return desc->klass;
1220
1338
  }
1221
1339
 
1222
- const upb_msgdef *Descriptor_GetMsgDef(VALUE desc_rb) {
1340
+ const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb) {
1223
1341
  const Descriptor* desc = ruby_to_Descriptor(desc_rb);
1224
1342
  return desc->msgdef;
1225
1343
  }
1226
1344
 
1227
- VALUE TypeInfo_InitArg(int argc, VALUE *argv, int skip_arg) {
1345
+ VALUE TypeInfo_InitArg(int argc, VALUE* argv, int skip_arg) {
1228
1346
  if (argc > skip_arg) {
1229
1347
  if (argc > 1 + skip_arg) {
1230
- rb_raise(rb_eArgError, "Expected a maximum of %d arguments.", skip_arg + 1);
1348
+ rb_raise(rb_eArgError, "Expected a maximum of %d arguments.",
1349
+ skip_arg + 1);
1231
1350
  }
1232
1351
  return argv[skip_arg];
1233
1352
  } else {
@@ -1239,7 +1358,7 @@ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
1239
1358
  VALUE* type_class, VALUE* init_arg) {
1240
1359
  TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])};
1241
1360
 
1242
- if (ret.type == UPB_TYPE_MESSAGE || ret.type == UPB_TYPE_ENUM) {
1361
+ if (ret.type == kUpb_CType_Message || ret.type == kUpb_CType_Enum) {
1243
1362
  *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2);
1244
1363
 
1245
1364
  if (argc < 2 + skip_arg) {
@@ -1257,11 +1376,11 @@ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
1257
1376
  "class or enum as returned by the DescriptorPool.");
1258
1377
  }
1259
1378
 
1260
- if (ret.type == UPB_TYPE_MESSAGE) {
1379
+ if (ret.type == kUpb_CType_Message) {
1261
1380
  ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef;
1262
1381
  Message_CheckClass(klass);
1263
1382
  } else {
1264
- PBRUBY_ASSERT(ret.type == UPB_TYPE_ENUM);
1383
+ PBRUBY_ASSERT(ret.type == kUpb_CType_Enum);
1265
1384
  ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef;
1266
1385
  }
1267
1386
  } else {