google-protobuf 3.19.1 → 3.25.1

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 (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 {