google-protobuf 3.5.0 → 3.23.4

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 (47) hide show
  1. checksums.yaml +5 -5
  2. data/ext/google/protobuf_c/convert.c +361 -0
  3. data/ext/google/protobuf_c/convert.h +75 -0
  4. data/ext/google/protobuf_c/defs.c +770 -1254
  5. data/ext/google/protobuf_c/defs.h +107 -0
  6. data/ext/google/protobuf_c/extconf.rb +15 -5
  7. data/ext/google/protobuf_c/map.c +312 -474
  8. data/ext/google/protobuf_c/map.h +66 -0
  9. data/ext/google/protobuf_c/message.c +1139 -372
  10. data/ext/google/protobuf_c/message.h +104 -0
  11. data/ext/google/protobuf_c/protobuf.c +418 -51
  12. data/ext/google/protobuf_c/protobuf.h +53 -485
  13. data/ext/google/protobuf_c/repeated_field.c +319 -316
  14. data/ext/google/protobuf_c/repeated_field.h +63 -0
  15. data/ext/google/protobuf_c/ruby-upb.c +13974 -0
  16. data/ext/google/protobuf_c/ruby-upb.h +11780 -0
  17. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  18. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +92 -0
  19. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +157 -0
  20. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +170 -0
  21. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +21 -0
  22. data/ext/google/protobuf_c/wrap_memcpy.c +4 -3
  23. data/lib/google/protobuf/any_pb.rb +26 -5
  24. data/lib/google/protobuf/api_pb.rb +31 -25
  25. data/lib/google/protobuf/descriptor_dsl.rb +465 -0
  26. data/lib/google/protobuf/descriptor_pb.rb +75 -0
  27. data/lib/google/protobuf/duration_pb.rb +26 -5
  28. data/lib/google/protobuf/empty_pb.rb +26 -3
  29. data/lib/google/protobuf/field_mask_pb.rb +26 -4
  30. data/lib/google/protobuf/message_exts.rb +9 -4
  31. data/lib/google/protobuf/plugin_pb.rb +47 -0
  32. data/lib/google/protobuf/repeated_field.rb +17 -4
  33. data/lib/google/protobuf/source_context_pb.rb +26 -4
  34. data/lib/google/protobuf/struct_pb.rb +28 -22
  35. data/lib/google/protobuf/timestamp_pb.rb +26 -5
  36. data/lib/google/protobuf/type_pb.rb +37 -76
  37. data/lib/google/protobuf/well_known_types.rb +32 -4
  38. data/lib/google/protobuf/wrappers_pb.rb +35 -37
  39. data/lib/google/protobuf.rb +11 -8
  40. metadata +29 -37
  41. data/ext/google/protobuf_c/encode_decode.c +0 -1307
  42. data/ext/google/protobuf_c/storage.c +0 -904
  43. data/ext/google/protobuf_c/upb.c +0 -14913
  44. data/ext/google/protobuf_c/upb.h +0 -8969
  45. data/tests/basic.rb +0 -1403
  46. data/tests/generated_code_test.rb +0 -19
  47. data/tests/stress.rb +0 -38
@@ -28,8 +28,30 @@
28
28
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
29
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
+ #include <ctype.h>
32
+ #include <errno.h>
33
+ #include <ruby/version.h>
34
+
35
+ #include "convert.h"
36
+ #include "message.h"
31
37
  #include "protobuf.h"
32
38
 
39
+ // -----------------------------------------------------------------------------
40
+ // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
41
+ // instances.
42
+ // -----------------------------------------------------------------------------
43
+
44
+ static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* 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);
49
+
50
+ // A distinct object that is not accessible from Ruby. We use this as a
51
+ // constructor argument to enforce that certain objects cannot be created from
52
+ // Ruby.
53
+ VALUE c_only_cookie = Qnil;
54
+
33
55
  // -----------------------------------------------------------------------------
34
56
  // Common utilities.
35
57
  // -----------------------------------------------------------------------------
@@ -46,147 +68,99 @@ static VALUE rb_str_maybe_null(const char* s) {
46
68
  return rb_str_new2(s);
47
69
  }
48
70
 
49
- static upb_def* check_notfrozen(const upb_def* def) {
50
- if (upb_def_isfrozen(def)) {
51
- rb_raise(rb_eRuntimeError,
52
- "Attempt to modify a frozen descriptor. Once descriptors are "
53
- "added to the descriptor pool, they may not be modified.");
54
- }
55
- return (upb_def*)def;
56
- }
57
-
58
- static upb_msgdef* check_msg_notfrozen(const upb_msgdef* def) {
59
- return upb_downcast_msgdef_mutable(check_notfrozen((const upb_def*)def));
60
- }
61
-
62
- static upb_fielddef* check_field_notfrozen(const upb_fielddef* def) {
63
- return upb_downcast_fielddef_mutable(check_notfrozen((const upb_def*)def));
64
- }
65
-
66
- static upb_oneofdef* check_oneof_notfrozen(const upb_oneofdef* def) {
67
- return (upb_oneofdef*)check_notfrozen((const upb_def*)def);
68
- }
69
-
70
- static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
71
- return (upb_enumdef*)check_notfrozen((const upb_def*)def);
72
- }
73
-
74
71
  // -----------------------------------------------------------------------------
75
72
  // DescriptorPool.
76
73
  // -----------------------------------------------------------------------------
77
74
 
78
- #define DEFINE_CLASS(name, string_name) \
79
- VALUE c ## name; \
80
- const rb_data_type_t _ ## name ## _type = { \
81
- string_name, \
82
- { name ## _mark, name ## _free, NULL }, \
83
- }; \
84
- name* ruby_to_ ## name(VALUE val) { \
85
- name* ret; \
86
- TypedData_Get_Struct(val, name, &_ ## name ## _type, ret); \
87
- return ret; \
88
- } \
89
-
90
- #define DEFINE_SELF(type, var, rb_var) \
91
- type* var = ruby_to_ ## type(rb_var)
75
+ typedef struct {
76
+ VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor.
77
+ upb_DefPool* symtab;
78
+ } DescriptorPool;
79
+
80
+ VALUE cDescriptorPool = Qnil;
92
81
 
93
82
  // Global singleton DescriptorPool. The user is free to create others, but this
94
83
  // is used by generated code.
95
- VALUE generated_pool;
96
-
97
- DEFINE_CLASS(DescriptorPool, "Google::Protobuf::DescriptorPool");
84
+ VALUE generated_pool = Qnil;
98
85
 
99
- void DescriptorPool_mark(void* _self) {
86
+ static void DescriptorPool_mark(void* _self) {
87
+ DescriptorPool* self = _self;
88
+ rb_gc_mark(self->def_to_descriptor);
100
89
  }
101
90
 
102
- void DescriptorPool_free(void* _self) {
91
+ static void DescriptorPool_free(void* _self) {
103
92
  DescriptorPool* self = _self;
104
- upb_symtab_free(self->symtab);
93
+ upb_DefPool_Free(self->symtab);
105
94
  xfree(self);
106
95
  }
107
96
 
97
+ static const rb_data_type_t DescriptorPool_type = {
98
+ "Google::Protobuf::DescriptorPool",
99
+ {DescriptorPool_mark, DescriptorPool_free, NULL},
100
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
101
+ };
102
+
103
+ static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
104
+ DescriptorPool* ret;
105
+ TypedData_Get_Struct(val, DescriptorPool, &DescriptorPool_type, ret);
106
+ return ret;
107
+ }
108
+
109
+ // Exposed to other modules in defs.h.
110
+ const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb) {
111
+ DescriptorPool* pool = ruby_to_DescriptorPool(desc_pool_rb);
112
+ return pool->symtab;
113
+ }
114
+
108
115
  /*
109
116
  * call-seq:
110
117
  * DescriptorPool.new => pool
111
118
  *
112
119
  * Creates a new, empty, descriptor pool.
113
120
  */
114
- VALUE DescriptorPool_alloc(VALUE klass) {
121
+ static VALUE DescriptorPool_alloc(VALUE klass) {
115
122
  DescriptorPool* self = ALLOC(DescriptorPool);
116
- self->symtab = upb_symtab_new();
117
- return TypedData_Wrap_Struct(klass, &_DescriptorPool_type, self);
118
- }
119
-
120
- void DescriptorPool_register(VALUE module) {
121
- VALUE klass = rb_define_class_under(
122
- module, "DescriptorPool", rb_cObject);
123
- rb_define_alloc_func(klass, DescriptorPool_alloc);
124
- rb_define_method(klass, "add", DescriptorPool_add, 1);
125
- rb_define_method(klass, "build", DescriptorPool_build, 0);
126
- rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
127
- rb_define_singleton_method(klass, "generated_pool",
128
- DescriptorPool_generated_pool, 0);
129
- cDescriptorPool = klass;
130
- rb_gc_register_address(&cDescriptorPool);
123
+ VALUE ret;
131
124
 
132
- generated_pool = rb_class_new_instance(0, NULL, klass);
133
- rb_gc_register_address(&generated_pool);
134
- }
125
+ self->def_to_descriptor = Qnil;
126
+ ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self);
135
127
 
136
- static void add_descriptor_to_pool(DescriptorPool* self,
137
- Descriptor* descriptor) {
138
- CHECK_UPB(
139
- upb_symtab_add(self->symtab, (upb_def**)&descriptor->msgdef, 1,
140
- NULL, &status),
141
- "Adding Descriptor to DescriptorPool failed");
142
- }
128
+ self->def_to_descriptor = rb_hash_new();
129
+ self->symtab = upb_DefPool_New();
130
+ ObjectCache_Add(self->symtab, ret);
143
131
 
144
- static void add_enumdesc_to_pool(DescriptorPool* self,
145
- EnumDescriptor* enumdesc) {
146
- CHECK_UPB(
147
- upb_symtab_add(self->symtab, (upb_def**)&enumdesc->enumdef, 1,
148
- NULL, &status),
149
- "Adding EnumDescriptor to DescriptorPool failed");
132
+ return ret;
150
133
  }
151
134
 
152
135
  /*
153
136
  * call-seq:
154
- * DescriptorPool.add(descriptor)
137
+ * DescriptorPool.add_serialized_file(serialized_file_proto)
155
138
  *
156
- * Adds the given Descriptor or EnumDescriptor to this pool. All references to
157
- * other types in a Descriptor's fields must be resolvable within this pool or
158
- * an exception will be raised.
139
+ * Adds the given serialized FileDescriptorProto to the pool.
159
140
  */
160
- VALUE DescriptorPool_add(VALUE _self, VALUE def) {
161
- DEFINE_SELF(DescriptorPool, self, _self);
162
- VALUE def_klass = rb_obj_class(def);
163
- if (def_klass == cDescriptor) {
164
- add_descriptor_to_pool(self, ruby_to_Descriptor(def));
165
- } else if (def_klass == cEnumDescriptor) {
166
- add_enumdesc_to_pool(self, ruby_to_EnumDescriptor(def));
167
- } else {
168
- rb_raise(rb_eArgError,
169
- "Second argument must be a Descriptor or EnumDescriptor.");
141
+ VALUE DescriptorPool_add_serialized_file(VALUE _self,
142
+ VALUE serialized_file_proto) {
143
+ DescriptorPool* self = ruby_to_DescriptorPool(_self);
144
+ Check_Type(serialized_file_proto, T_STRING);
145
+ VALUE arena_rb = Arena_new();
146
+ upb_Arena* arena = Arena_get(arena_rb);
147
+ google_protobuf_FileDescriptorProto* file_proto =
148
+ google_protobuf_FileDescriptorProto_parse(
149
+ RSTRING_PTR(serialized_file_proto),
150
+ RSTRING_LEN(serialized_file_proto), arena);
151
+ if (!file_proto) {
152
+ rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto");
170
153
  }
171
- return Qnil;
172
- }
173
-
174
- /*
175
- * call-seq:
176
- * DescriptorPool.build(&block)
177
- *
178
- * Invokes the block with a Builder instance as self. All message and enum types
179
- * added within the block are committed to the pool atomically, and may refer
180
- * (co)recursively to each other. The user should call Builder#add_message and
181
- * Builder#add_enum within the block as appropriate. This is the recommended,
182
- * idiomatic way to define new message and enum types.
183
- */
184
- VALUE DescriptorPool_build(VALUE _self) {
185
- VALUE ctx = rb_class_new_instance(0, NULL, cBuilder);
186
- VALUE block = rb_block_proc();
187
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
188
- rb_funcall(ctx, rb_intern("finalize_to_pool"), 1, _self);
189
- return Qnil;
154
+ upb_Status status;
155
+ upb_Status_Clear(&status);
156
+ const upb_FileDef* filedef =
157
+ upb_DefPool_AddFile(self->symtab, file_proto, &status);
158
+ if (!filedef) {
159
+ rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s",
160
+ upb_Status_ErrorMessage(&status));
161
+ }
162
+ RB_GC_GUARD(arena_rb);
163
+ return get_filedef_obj(_self, filedef);
190
164
  }
191
165
 
192
166
  /*
@@ -196,14 +170,23 @@ VALUE DescriptorPool_build(VALUE _self) {
196
170
  * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
197
171
  * exists with the given name.
198
172
  */
199
- VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
200
- DEFINE_SELF(DescriptorPool, self, _self);
173
+ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
174
+ DescriptorPool* self = ruby_to_DescriptorPool(_self);
201
175
  const char* name_str = get_str(name);
202
- const upb_def* def = upb_symtab_lookup(self->symtab, name_str);
203
- if (!def) {
204
- return Qnil;
176
+ const upb_MessageDef* msgdef;
177
+ const upb_EnumDef* enumdef;
178
+
179
+ msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
180
+ if (msgdef) {
181
+ return get_msgdef_obj(_self, msgdef);
205
182
  }
206
- return get_def_obj(def);
183
+
184
+ enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str);
185
+ if (enumdef) {
186
+ return get_enumdef_obj(_self, enumdef);
187
+ }
188
+
189
+ return Qnil;
207
190
  }
208
191
 
209
192
  /*
@@ -215,50 +198,55 @@ VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
215
198
  * register types in this pool for convenience so that they do not have to hold
216
199
  * a reference to a private pool instance.
217
200
  */
218
- VALUE DescriptorPool_generated_pool(VALUE _self) {
201
+ static VALUE DescriptorPool_generated_pool(VALUE _self) {
219
202
  return generated_pool;
220
203
  }
221
204
 
205
+ static void DescriptorPool_register(VALUE module) {
206
+ VALUE klass = rb_define_class_under(module, "DescriptorPool", rb_cObject);
207
+ rb_define_alloc_func(klass, DescriptorPool_alloc);
208
+ rb_define_method(klass, "add_serialized_file",
209
+ DescriptorPool_add_serialized_file, 1);
210
+ rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
211
+ rb_define_singleton_method(klass, "generated_pool",
212
+ DescriptorPool_generated_pool, 0);
213
+ rb_gc_register_address(&cDescriptorPool);
214
+ cDescriptorPool = klass;
215
+
216
+ rb_gc_register_address(&generated_pool);
217
+ generated_pool = rb_class_new_instance(0, NULL, klass);
218
+ }
219
+
222
220
  // -----------------------------------------------------------------------------
223
221
  // Descriptor.
224
222
  // -----------------------------------------------------------------------------
225
223
 
226
- DEFINE_CLASS(Descriptor, "Google::Protobuf::Descriptor");
224
+ typedef struct {
225
+ const upb_MessageDef* msgdef;
226
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
227
+ // macro to update VALUE references, as to trigger write barriers.
228
+ VALUE klass;
229
+ VALUE descriptor_pool;
230
+ } Descriptor;
231
+
232
+ VALUE cDescriptor = Qnil;
227
233
 
228
- void Descriptor_mark(void* _self) {
234
+ static void Descriptor_mark(void* _self) {
229
235
  Descriptor* self = _self;
230
236
  rb_gc_mark(self->klass);
237
+ rb_gc_mark(self->descriptor_pool);
231
238
  }
232
239
 
233
- void Descriptor_free(void* _self) {
234
- Descriptor* self = _self;
235
- upb_msgdef_unref(self->msgdef, &self->msgdef);
236
- if (self->layout) {
237
- free_layout(self->layout);
238
- }
239
- if (self->fill_handlers) {
240
- upb_handlers_unref(self->fill_handlers, &self->fill_handlers);
241
- }
242
- if (self->fill_method) {
243
- upb_pbdecodermethod_unref(self->fill_method, &self->fill_method);
244
- }
245
- if (self->json_fill_method) {
246
- upb_json_parsermethod_unref(self->json_fill_method,
247
- &self->json_fill_method);
248
- }
249
- if (self->pb_serialize_handlers) {
250
- upb_handlers_unref(self->pb_serialize_handlers,
251
- &self->pb_serialize_handlers);
252
- }
253
- if (self->json_serialize_handlers) {
254
- upb_handlers_unref(self->json_serialize_handlers,
255
- &self->json_serialize_handlers);
256
- }
257
- if (self->json_serialize_handlers_preserve) {
258
- upb_handlers_unref(self->json_serialize_handlers_preserve,
259
- &self->json_serialize_handlers_preserve);
260
- }
261
- xfree(self);
240
+ static const rb_data_type_t Descriptor_type = {
241
+ "Google::Protobuf::Descriptor",
242
+ {Descriptor_mark, RUBY_DEFAULT_FREE, NULL},
243
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
244
+ };
245
+
246
+ static Descriptor* ruby_to_Descriptor(VALUE val) {
247
+ Descriptor* ret;
248
+ TypedData_Get_Struct(val, Descriptor, &Descriptor_type, ret);
249
+ return ret;
262
250
  }
263
251
 
264
252
  /*
@@ -270,66 +258,58 @@ void Descriptor_free(void* _self) {
270
258
  * it is added to a pool, after which it becomes immutable (as part of a
271
259
  * finalization process).
272
260
  */
273
- VALUE Descriptor_alloc(VALUE klass) {
261
+ static VALUE Descriptor_alloc(VALUE klass) {
274
262
  Descriptor* self = ALLOC(Descriptor);
275
- VALUE ret = TypedData_Wrap_Struct(klass, &_Descriptor_type, self);
276
- self->msgdef = upb_msgdef_new(&self->msgdef);
263
+ VALUE ret = TypedData_Wrap_Struct(klass, &Descriptor_type, self);
264
+ self->msgdef = NULL;
277
265
  self->klass = Qnil;
278
- self->layout = NULL;
279
- self->fill_handlers = NULL;
280
- self->fill_method = NULL;
281
- self->json_fill_method = NULL;
282
- self->pb_serialize_handlers = NULL;
283
- self->json_serialize_handlers = NULL;
284
- self->json_serialize_handlers_preserve = NULL;
266
+ self->descriptor_pool = Qnil;
285
267
  return ret;
286
268
  }
287
269
 
288
- void Descriptor_register(VALUE module) {
289
- VALUE klass = rb_define_class_under(
290
- module, "Descriptor", rb_cObject);
291
- rb_define_alloc_func(klass, Descriptor_alloc);
292
- rb_define_method(klass, "each", Descriptor_each, 0);
293
- rb_define_method(klass, "lookup", Descriptor_lookup, 1);
294
- rb_define_method(klass, "add_field", Descriptor_add_field, 1);
295
- rb_define_method(klass, "add_oneof", Descriptor_add_oneof, 1);
296
- rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
297
- rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
298
- rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
299
- rb_define_method(klass, "name", Descriptor_name, 0);
300
- rb_define_method(klass, "name=", Descriptor_name_set, 1);
301
- rb_include_module(klass, rb_mEnumerable);
302
- cDescriptor = klass;
303
- rb_gc_register_address(&cDescriptor);
270
+ /*
271
+ * call-seq:
272
+ * Descriptor.new(c_only_cookie, ptr) => Descriptor
273
+ *
274
+ * Creates a descriptor wrapper object. May only be called from C.
275
+ */
276
+ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
277
+ VALUE descriptor_pool, VALUE ptr) {
278
+ Descriptor* self = ruby_to_Descriptor(_self);
279
+
280
+ if (cookie != c_only_cookie) {
281
+ rb_raise(rb_eRuntimeError,
282
+ "Descriptor objects may not be created from Ruby.");
283
+ }
284
+
285
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
286
+ self->msgdef = (const upb_MessageDef*)NUM2ULL(ptr);
287
+
288
+ return Qnil;
304
289
  }
305
290
 
306
291
  /*
307
292
  * call-seq:
308
- * Descriptor.name => name
293
+ * Descriptor.file_descriptor
309
294
  *
310
- * Returns the name of this message type as a fully-qualfied string (e.g.,
311
- * My.Package.MessageType).
295
+ * Returns the FileDescriptor object this message belongs to.
312
296
  */
313
- VALUE Descriptor_name(VALUE _self) {
314
- DEFINE_SELF(Descriptor, self, _self);
315
- return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
297
+ static VALUE Descriptor_file_descriptor(VALUE _self) {
298
+ Descriptor* self = ruby_to_Descriptor(_self);
299
+ return get_filedef_obj(self->descriptor_pool,
300
+ upb_MessageDef_File(self->msgdef));
316
301
  }
317
302
 
318
303
  /*
319
304
  * call-seq:
320
- * Descriptor.name = name
305
+ * Descriptor.name => name
321
306
  *
322
- * Assigns a name to this message type. The descriptor must not have been added
323
- * to a pool yet.
307
+ * Returns the name of this message type as a fully-qualified string (e.g.,
308
+ * My.Package.MessageType).
324
309
  */
325
- VALUE Descriptor_name_set(VALUE _self, VALUE str) {
326
- DEFINE_SELF(Descriptor, self, _self);
327
- upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
328
- const char* name = get_str(str);
329
- CHECK_UPB(
330
- upb_msgdef_setfullname(mut_def, name, &status),
331
- "Error setting Descriptor name");
332
- return Qnil;
310
+ static VALUE Descriptor_name(VALUE _self) {
311
+ Descriptor* self = ruby_to_Descriptor(_self);
312
+ return rb_str_maybe_null(upb_MessageDef_FullName(self->msgdef));
333
313
  }
334
314
 
335
315
  /*
@@ -338,15 +318,13 @@ VALUE Descriptor_name_set(VALUE _self, VALUE str) {
338
318
  *
339
319
  * Iterates over fields in this message type, yielding to the block on each one.
340
320
  */
341
- VALUE Descriptor_each(VALUE _self) {
342
- DEFINE_SELF(Descriptor, self, _self);
343
-
344
- upb_msg_field_iter it;
345
- for (upb_msg_field_begin(&it, self->msgdef);
346
- !upb_msg_field_done(&it);
347
- upb_msg_field_next(&it)) {
348
- const upb_fielddef* field = upb_msg_iter_field(&it);
349
- VALUE obj = get_def_obj(field);
321
+ static VALUE Descriptor_each(VALUE _self) {
322
+ Descriptor* self = ruby_to_Descriptor(_self);
323
+
324
+ int n = upb_MessageDef_FieldCount(self->msgdef);
325
+ for (int i = 0; i < n; i++) {
326
+ const upb_FieldDef* field = upb_MessageDef_Field(self->msgdef, i);
327
+ VALUE obj = get_fielddef_obj(self->descriptor_pool, field);
350
328
  rb_yield(obj);
351
329
  }
352
330
  return Qnil;
@@ -359,58 +337,14 @@ VALUE Descriptor_each(VALUE _self) {
359
337
  * Returns the field descriptor for the field with the given name, if present,
360
338
  * or nil if none.
361
339
  */
362
- VALUE Descriptor_lookup(VALUE _self, VALUE name) {
363
- DEFINE_SELF(Descriptor, self, _self);
340
+ static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
341
+ Descriptor* self = ruby_to_Descriptor(_self);
364
342
  const char* s = get_str(name);
365
- const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s);
343
+ const upb_FieldDef* field = upb_MessageDef_FindFieldByName(self->msgdef, s);
366
344
  if (field == NULL) {
367
345
  return Qnil;
368
346
  }
369
- return get_def_obj(field);
370
- }
371
-
372
- /*
373
- * call-seq:
374
- * Descriptor.add_field(field) => nil
375
- *
376
- * Adds the given FieldDescriptor to this message type. This descriptor must not
377
- * have been added to a pool yet. Raises an exception if a field with the same
378
- * name or number already exists. Sub-type references (e.g. for fields of type
379
- * message) are not resolved at this point.
380
- */
381
- VALUE Descriptor_add_field(VALUE _self, VALUE obj) {
382
- DEFINE_SELF(Descriptor, self, _self);
383
- upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
384
- FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
385
- upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
386
- CHECK_UPB(
387
- upb_msgdef_addfield(mut_def, mut_field_def, NULL, &status),
388
- "Adding field to Descriptor failed");
389
- add_def_obj(def->fielddef, obj);
390
- return Qnil;
391
- }
392
-
393
- /*
394
- * call-seq:
395
- * Descriptor.add_oneof(oneof) => nil
396
- *
397
- * Adds the given OneofDescriptor to this message type. This descriptor must not
398
- * have been added to a pool yet. Raises an exception if a oneof with the same
399
- * name already exists, or if any of the oneof's fields' names or numbers
400
- * conflict with an existing field in this message type. All fields in the oneof
401
- * are added to the message descriptor. Sub-type references (e.g. for fields of
402
- * type message) are not resolved at this point.
403
- */
404
- VALUE Descriptor_add_oneof(VALUE _self, VALUE obj) {
405
- DEFINE_SELF(Descriptor, self, _self);
406
- upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
407
- OneofDescriptor* def = ruby_to_OneofDescriptor(obj);
408
- upb_oneofdef* mut_oneof_def = check_oneof_notfrozen(def->oneofdef);
409
- CHECK_UPB(
410
- upb_msgdef_addoneof(mut_def, mut_oneof_def, NULL, &status),
411
- "Adding oneof to Descriptor failed");
412
- add_def_obj(def->oneofdef, obj);
413
- return Qnil;
347
+ return get_fielddef_obj(self->descriptor_pool, field);
414
348
  }
415
349
 
416
350
  /*
@@ -420,15 +354,13 @@ VALUE Descriptor_add_oneof(VALUE _self, VALUE obj) {
420
354
  * Invokes the given block for each oneof in this message type, passing the
421
355
  * corresponding OneofDescriptor.
422
356
  */
423
- VALUE Descriptor_each_oneof(VALUE _self) {
424
- DEFINE_SELF(Descriptor, self, _self);
425
-
426
- upb_msg_oneof_iter it;
427
- for (upb_msg_oneof_begin(&it, self->msgdef);
428
- !upb_msg_oneof_done(&it);
429
- upb_msg_oneof_next(&it)) {
430
- const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
431
- VALUE obj = get_def_obj(oneof);
357
+ static VALUE Descriptor_each_oneof(VALUE _self) {
358
+ Descriptor* self = ruby_to_Descriptor(_self);
359
+
360
+ int n = upb_MessageDef_OneofCount(self->msgdef);
361
+ for (int i = 0; i < n; i++) {
362
+ const upb_OneofDef* oneof = upb_MessageDef_Oneof(self->msgdef, i);
363
+ VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof);
432
364
  rb_yield(obj);
433
365
  }
434
366
  return Qnil;
@@ -441,190 +373,248 @@ VALUE Descriptor_each_oneof(VALUE _self) {
441
373
  * Returns the oneof descriptor for the oneof with the given name, if present,
442
374
  * or nil if none.
443
375
  */
444
- VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
445
- DEFINE_SELF(Descriptor, self, _self);
376
+ static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
377
+ Descriptor* self = ruby_to_Descriptor(_self);
446
378
  const char* s = get_str(name);
447
- const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s);
379
+ const upb_OneofDef* oneof = upb_MessageDef_FindOneofByName(self->msgdef, s);
448
380
  if (oneof == NULL) {
449
381
  return Qnil;
450
382
  }
451
- return get_def_obj(oneof);
383
+ return get_oneofdef_obj(self->descriptor_pool, oneof);
452
384
  }
453
385
 
454
386
  /*
455
387
  * call-seq:
456
388
  * Descriptor.msgclass => message_klass
457
389
  *
458
- * Returns the Ruby class created for this message type. Valid only once the
459
- * message type has been added to a pool.
390
+ * Returns the Ruby class created for this message type.
460
391
  */
461
- VALUE Descriptor_msgclass(VALUE _self) {
462
- DEFINE_SELF(Descriptor, self, _self);
463
- if (!upb_def_isfrozen((const upb_def*)self->msgdef)) {
464
- rb_raise(rb_eRuntimeError,
465
- "Cannot fetch message class from a Descriptor not yet in a pool.");
466
- }
392
+ static VALUE Descriptor_msgclass(VALUE _self) {
393
+ Descriptor* self = ruby_to_Descriptor(_self);
467
394
  if (self->klass == Qnil) {
468
- self->klass = build_class_from_descriptor(self);
395
+ RB_OBJ_WRITE(_self, &self->klass, build_class_from_descriptor(_self));
469
396
  }
470
397
  return self->klass;
471
398
  }
472
399
 
400
+ static void Descriptor_register(VALUE module) {
401
+ VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
402
+ rb_define_alloc_func(klass, Descriptor_alloc);
403
+ rb_define_method(klass, "initialize", Descriptor_initialize, 3);
404
+ rb_define_method(klass, "each", Descriptor_each, 0);
405
+ rb_define_method(klass, "lookup", Descriptor_lookup, 1);
406
+ rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
407
+ rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
408
+ rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
409
+ rb_define_method(klass, "name", Descriptor_name, 0);
410
+ rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
411
+ rb_include_module(klass, rb_mEnumerable);
412
+ rb_gc_register_address(&cDescriptor);
413
+ cDescriptor = klass;
414
+ }
415
+
473
416
  // -----------------------------------------------------------------------------
474
- // FieldDescriptor.
417
+ // FileDescriptor.
475
418
  // -----------------------------------------------------------------------------
476
419
 
477
- DEFINE_CLASS(FieldDescriptor, "Google::Protobuf::FieldDescriptor");
420
+ typedef struct {
421
+ const upb_FileDef* filedef;
422
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
423
+ // macro to update VALUE references, as to trigger write barriers.
424
+ VALUE descriptor_pool; // Owns the upb_FileDef.
425
+ } FileDescriptor;
426
+
427
+ static VALUE cFileDescriptor = Qnil;
478
428
 
479
- void FieldDescriptor_mark(void* _self) {
429
+ static void FileDescriptor_mark(void* _self) {
430
+ FileDescriptor* self = _self;
431
+ rb_gc_mark(self->descriptor_pool);
480
432
  }
481
433
 
482
- void FieldDescriptor_free(void* _self) {
483
- FieldDescriptor* self = _self;
484
- upb_fielddef_unref(self->fielddef, &self->fielddef);
485
- xfree(self);
434
+ 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 | RUBY_TYPED_WB_PROTECTED,
438
+ };
439
+
440
+ static FileDescriptor* ruby_to_FileDescriptor(VALUE val) {
441
+ FileDescriptor* ret;
442
+ TypedData_Get_Struct(val, FileDescriptor, &FileDescriptor_type, ret);
443
+ return ret;
444
+ }
445
+
446
+ static VALUE FileDescriptor_alloc(VALUE klass) {
447
+ FileDescriptor* self = ALLOC(FileDescriptor);
448
+ VALUE ret = TypedData_Wrap_Struct(klass, &FileDescriptor_type, self);
449
+ self->descriptor_pool = Qnil;
450
+ self->filedef = NULL;
451
+ return ret;
486
452
  }
487
453
 
488
454
  /*
489
455
  * call-seq:
490
- * FieldDescriptor.new => field
456
+ * FileDescriptor.new => file
491
457
  *
492
- * Returns a new field descriptor. Its name, type, etc. must be set before it is
493
- * added to a message type.
458
+ * Returns a new file descriptor. The syntax must be set before it's passed
459
+ * to a builder.
494
460
  */
495
- VALUE FieldDescriptor_alloc(VALUE klass) {
496
- FieldDescriptor* self = ALLOC(FieldDescriptor);
497
- VALUE ret = TypedData_Wrap_Struct(klass, &_FieldDescriptor_type, self);
498
- upb_fielddef* fielddef = upb_fielddef_new(&self->fielddef);
499
- upb_fielddef_setpacked(fielddef, false);
500
- self->fielddef = fielddef;
501
- return ret;
502
- }
461
+ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
462
+ VALUE descriptor_pool, VALUE ptr) {
463
+ FileDescriptor* self = ruby_to_FileDescriptor(_self);
503
464
 
504
- void FieldDescriptor_register(VALUE module) {
505
- VALUE klass = rb_define_class_under(
506
- module, "FieldDescriptor", rb_cObject);
507
- rb_define_alloc_func(klass, FieldDescriptor_alloc);
508
- rb_define_method(klass, "name", FieldDescriptor_name, 0);
509
- rb_define_method(klass, "name=", FieldDescriptor_name_set, 1);
510
- rb_define_method(klass, "type", FieldDescriptor_type, 0);
511
- rb_define_method(klass, "type=", FieldDescriptor_type_set, 1);
512
- rb_define_method(klass, "label", FieldDescriptor_label, 0);
513
- rb_define_method(klass, "label=", FieldDescriptor_label_set, 1);
514
- rb_define_method(klass, "number", FieldDescriptor_number, 0);
515
- rb_define_method(klass, "number=", FieldDescriptor_number_set, 1);
516
- rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
517
- rb_define_method(klass, "submsg_name=", FieldDescriptor_submsg_name_set, 1);
518
- rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
519
- rb_define_method(klass, "get", FieldDescriptor_get, 1);
520
- rb_define_method(klass, "set", FieldDescriptor_set, 2);
521
- cFieldDescriptor = klass;
522
- rb_gc_register_address(&cFieldDescriptor);
465
+ if (cookie != c_only_cookie) {
466
+ rb_raise(rb_eRuntimeError,
467
+ "Descriptor objects may not be created from Ruby.");
468
+ }
469
+
470
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
471
+ self->filedef = (const upb_FileDef*)NUM2ULL(ptr);
472
+
473
+ return Qnil;
523
474
  }
524
475
 
525
476
  /*
526
477
  * call-seq:
527
- * FieldDescriptor.name => name
478
+ * FileDescriptor.name => name
528
479
  *
529
- * Returns the name of this field.
480
+ * Returns the name of the file.
530
481
  */
531
- VALUE FieldDescriptor_name(VALUE _self) {
532
- DEFINE_SELF(FieldDescriptor, self, _self);
533
- return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
482
+ static VALUE FileDescriptor_name(VALUE _self) {
483
+ FileDescriptor* self = ruby_to_FileDescriptor(_self);
484
+ const char* name = upb_FileDef_Name(self->filedef);
485
+ return name == NULL ? Qnil : rb_str_new2(name);
534
486
  }
535
487
 
536
488
  /*
537
489
  * call-seq:
538
- * FieldDescriptor.name = name
490
+ * FileDescriptor.syntax => syntax
539
491
  *
540
- * Sets the name of this field. Cannot be called once the containing message
541
- * type, if any, is added to a pool.
492
+ * Returns this file descriptors syntax.
493
+ *
494
+ * Valid syntax versions are:
495
+ * :proto2 or :proto3.
542
496
  */
543
- VALUE FieldDescriptor_name_set(VALUE _self, VALUE str) {
544
- DEFINE_SELF(FieldDescriptor, self, _self);
545
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
546
- const char* name = get_str(str);
547
- CHECK_UPB(upb_fielddef_setname(mut_def, name, &status),
548
- "Error setting FieldDescriptor name");
549
- return Qnil;
497
+ static VALUE FileDescriptor_syntax(VALUE _self) {
498
+ FileDescriptor* self = ruby_to_FileDescriptor(_self);
499
+
500
+ switch (upb_FileDef_Syntax(self->filedef)) {
501
+ case kUpb_Syntax_Proto3:
502
+ return ID2SYM(rb_intern("proto3"));
503
+ case kUpb_Syntax_Proto2:
504
+ return ID2SYM(rb_intern("proto2"));
505
+ default:
506
+ return Qnil;
507
+ }
550
508
  }
551
509
 
552
- upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
553
- if (TYPE(type) != T_SYMBOL) {
554
- rb_raise(rb_eArgError, "Expected symbol for field type.");
555
- }
510
+ static void FileDescriptor_register(VALUE module) {
511
+ VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject);
512
+ rb_define_alloc_func(klass, FileDescriptor_alloc);
513
+ rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
514
+ rb_define_method(klass, "name", FileDescriptor_name, 0);
515
+ rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
516
+ rb_gc_register_address(&cFileDescriptor);
517
+ cFileDescriptor = klass;
518
+ }
556
519
 
557
- #define CONVERT(upb, ruby) \
558
- if (SYM2ID(type) == rb_intern( # ruby )) { \
559
- return UPB_TYPE_ ## upb; \
560
- }
520
+ // -----------------------------------------------------------------------------
521
+ // FieldDescriptor.
522
+ // -----------------------------------------------------------------------------
561
523
 
562
- CONVERT(FLOAT, float);
563
- CONVERT(DOUBLE, double);
564
- CONVERT(BOOL, bool);
565
- CONVERT(STRING, string);
566
- CONVERT(BYTES, bytes);
567
- CONVERT(MESSAGE, message);
568
- CONVERT(ENUM, enum);
569
- CONVERT(INT32, int32);
570
- CONVERT(INT64, int64);
571
- CONVERT(UINT32, uint32);
572
- CONVERT(UINT64, uint64);
524
+ typedef struct {
525
+ const upb_FieldDef* fielddef;
526
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
527
+ // macro to update VALUE references, as to trigger write barriers.
528
+ VALUE descriptor_pool; // Owns the upb_FieldDef.
529
+ } FieldDescriptor;
573
530
 
574
- #undef CONVERT
531
+ static VALUE cFieldDescriptor = Qnil;
575
532
 
576
- rb_raise(rb_eArgError, "Unknown field type.");
577
- return 0;
533
+ static void FieldDescriptor_mark(void* _self) {
534
+ FieldDescriptor* self = _self;
535
+ rb_gc_mark(self->descriptor_pool);
578
536
  }
579
537
 
580
- VALUE fieldtype_to_ruby(upb_fieldtype_t type) {
581
- switch (type) {
582
- #define CONVERT(upb, ruby) \
583
- case UPB_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
584
- CONVERT(FLOAT, float);
585
- CONVERT(DOUBLE, double);
586
- CONVERT(BOOL, bool);
587
- CONVERT(STRING, string);
588
- CONVERT(BYTES, bytes);
589
- CONVERT(MESSAGE, message);
590
- CONVERT(ENUM, enum);
591
- CONVERT(INT32, int32);
592
- CONVERT(INT64, int64);
593
- CONVERT(UINT32, uint32);
594
- CONVERT(UINT64, uint64);
595
- #undef CONVERT
538
+ static const rb_data_type_t FieldDescriptor_type = {
539
+ "Google::Protobuf::FieldDescriptor",
540
+ {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
541
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
542
+ };
543
+
544
+ static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) {
545
+ FieldDescriptor* ret;
546
+ TypedData_Get_Struct(val, FieldDescriptor, &FieldDescriptor_type, ret);
547
+ return ret;
548
+ }
549
+
550
+ /*
551
+ * call-seq:
552
+ * FieldDescriptor.new => field
553
+ *
554
+ * Returns a new field descriptor. Its name, type, etc. must be set before it is
555
+ * added to a message type.
556
+ */
557
+ static VALUE FieldDescriptor_alloc(VALUE klass) {
558
+ FieldDescriptor* self = ALLOC(FieldDescriptor);
559
+ VALUE ret = TypedData_Wrap_Struct(klass, &FieldDescriptor_type, self);
560
+ self->fielddef = NULL;
561
+ return ret;
562
+ }
563
+
564
+ /*
565
+ * call-seq:
566
+ * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
567
+ *
568
+ * Creates a descriptor wrapper object. May only be called from C.
569
+ */
570
+ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
571
+ VALUE descriptor_pool, VALUE ptr) {
572
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
573
+
574
+ if (cookie != c_only_cookie) {
575
+ rb_raise(rb_eRuntimeError,
576
+ "Descriptor objects may not be created from Ruby.");
596
577
  }
578
+
579
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
580
+ self->fielddef = (const upb_FieldDef*)NUM2ULL(ptr);
581
+
597
582
  return Qnil;
598
583
  }
599
584
 
600
- upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
585
+ /*
586
+ * call-seq:
587
+ * FieldDescriptor.name => name
588
+ *
589
+ * Returns the name of this field.
590
+ */
591
+ static VALUE FieldDescriptor_name(VALUE _self) {
592
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
593
+ return rb_str_maybe_null(upb_FieldDef_Name(self->fielddef));
594
+ }
595
+
596
+ // Non-static, exposed to other .c files.
597
+ upb_CType ruby_to_fieldtype(VALUE type) {
601
598
  if (TYPE(type) != T_SYMBOL) {
602
599
  rb_raise(rb_eArgError, "Expected symbol for field type.");
603
600
  }
604
601
 
605
- #define CONVERT(upb, ruby) \
606
- if (SYM2ID(type) == rb_intern( # ruby )) { \
607
- return UPB_DESCRIPTOR_TYPE_ ## upb; \
602
+ #define CONVERT(upb, ruby) \
603
+ if (SYM2ID(type) == rb_intern(#ruby)) { \
604
+ return kUpb_CType_##upb; \
608
605
  }
609
606
 
610
- CONVERT(FLOAT, float);
611
- CONVERT(DOUBLE, double);
612
- CONVERT(BOOL, bool);
613
- CONVERT(STRING, string);
614
- CONVERT(BYTES, bytes);
615
- CONVERT(MESSAGE, message);
616
- CONVERT(GROUP, group);
617
- CONVERT(ENUM, enum);
618
- CONVERT(INT32, int32);
619
- CONVERT(INT64, int64);
620
- CONVERT(UINT32, uint32);
621
- CONVERT(UINT64, uint64);
622
- CONVERT(SINT32, sint32);
623
- CONVERT(SINT64, sint64);
624
- CONVERT(FIXED32, fixed32);
625
- CONVERT(FIXED64, fixed64);
626
- CONVERT(SFIXED32, sfixed32);
627
- CONVERT(SFIXED64, sfixed64);
607
+ CONVERT(Float, float);
608
+ CONVERT(Double, double);
609
+ CONVERT(Bool, bool);
610
+ CONVERT(String, string);
611
+ CONVERT(Bytes, bytes);
612
+ CONVERT(Message, message);
613
+ CONVERT(Enum, enum);
614
+ CONVERT(Int32, int32);
615
+ CONVERT(Int64, int64);
616
+ CONVERT(UInt32, uint32);
617
+ CONVERT(UInt64, uint64);
628
618
 
629
619
  #undef CONVERT
630
620
 
@@ -632,28 +622,29 @@ upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
632
622
  return 0;
633
623
  }
634
624
 
635
- VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
625
+ static VALUE descriptortype_to_ruby(upb_FieldType type) {
636
626
  switch (type) {
637
- #define CONVERT(upb, ruby) \
638
- case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
639
- CONVERT(FLOAT, float);
640
- CONVERT(DOUBLE, double);
641
- CONVERT(BOOL, bool);
642
- CONVERT(STRING, string);
643
- CONVERT(BYTES, bytes);
644
- CONVERT(MESSAGE, message);
645
- CONVERT(GROUP, group);
646
- CONVERT(ENUM, enum);
647
- CONVERT(INT32, int32);
648
- CONVERT(INT64, int64);
649
- CONVERT(UINT32, uint32);
650
- CONVERT(UINT64, uint64);
651
- CONVERT(SINT32, sint32);
652
- CONVERT(SINT64, sint64);
653
- CONVERT(FIXED32, fixed32);
654
- CONVERT(FIXED64, fixed64);
655
- CONVERT(SFIXED32, sfixed32);
656
- CONVERT(SFIXED64, sfixed64);
627
+ #define CONVERT(upb, ruby) \
628
+ case kUpb_FieldType_##upb: \
629
+ return ID2SYM(rb_intern(#ruby));
630
+ CONVERT(Float, float);
631
+ CONVERT(Double, double);
632
+ CONVERT(Bool, bool);
633
+ CONVERT(String, string);
634
+ CONVERT(Bytes, bytes);
635
+ CONVERT(Message, message);
636
+ CONVERT(Group, group);
637
+ CONVERT(Enum, enum);
638
+ CONVERT(Int32, int32);
639
+ CONVERT(Int64, int64);
640
+ CONVERT(UInt32, uint32);
641
+ CONVERT(UInt64, uint64);
642
+ CONVERT(SInt32, sint32);
643
+ CONVERT(SInt64, sint64);
644
+ CONVERT(Fixed32, fixed32);
645
+ CONVERT(Fixed64, fixed64);
646
+ CONVERT(SFixed32, sfixed32);
647
+ CONVERT(SFixed64, sfixed64);
657
648
  #undef CONVERT
658
649
  }
659
650
  return Qnil;
@@ -669,26 +660,40 @@ VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
669
660
  * :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string,
670
661
  * :bytes, :message.
671
662
  */
672
- VALUE FieldDescriptor_type(VALUE _self) {
673
- DEFINE_SELF(FieldDescriptor, self, _self);
674
- if (!upb_fielddef_typeisset(self->fielddef)) {
663
+ static VALUE FieldDescriptor__type(VALUE _self) {
664
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
665
+ return descriptortype_to_ruby(upb_FieldDef_Type(self->fielddef));
666
+ }
667
+
668
+ /*
669
+ * call-seq:
670
+ * FieldDescriptor.default => default
671
+ *
672
+ * Returns this field's default, as a Ruby object, or nil if not yet set.
673
+ */
674
+ static VALUE FieldDescriptor_default(VALUE _self) {
675
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
676
+ const upb_FieldDef* f = self->fielddef;
677
+ upb_MessageValue default_val = {0};
678
+ if (upb_FieldDef_IsSubMessage(f)) {
675
679
  return Qnil;
680
+ } else if (!upb_FieldDef_IsRepeated(f)) {
681
+ default_val = upb_FieldDef_Default(f);
676
682
  }
677
- return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
683
+ return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
678
684
  }
679
685
 
680
686
  /*
681
687
  * call-seq:
682
- * FieldDescriptor.type = type
688
+ * FieldDescriptor.json_name => json_name
683
689
  *
684
- * Sets this field's type. Cannot be called if field is part of a message type
685
- * already in a pool.
690
+ * Returns this field's json_name, as a Ruby string, or nil if not yet set.
686
691
  */
687
- VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
688
- DEFINE_SELF(FieldDescriptor, self, _self);
689
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
690
- upb_fielddef_setdescriptortype(mut_def, ruby_to_descriptortype(type));
691
- return Qnil;
692
+ static VALUE FieldDescriptor_json_name(VALUE _self) {
693
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
694
+ const upb_FieldDef* f = self->fielddef;
695
+ const char* json_name = upb_FieldDef_JsonName(f);
696
+ return rb_str_new2(json_name);
692
697
  }
693
698
 
694
699
  /*
@@ -700,57 +705,20 @@ VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
700
705
  * Valid field labels are:
701
706
  * :optional, :repeated
702
707
  */
703
- VALUE FieldDescriptor_label(VALUE _self) {
704
- DEFINE_SELF(FieldDescriptor, self, _self);
705
- switch (upb_fielddef_label(self->fielddef)) {
706
- #define CONVERT(upb, ruby) \
707
- case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby ));
708
-
709
- CONVERT(OPTIONAL, optional);
710
- CONVERT(REQUIRED, required);
711
- CONVERT(REPEATED, repeated);
712
-
713
- #undef CONVERT
714
- }
715
-
716
- return Qnil;
717
- }
718
-
719
- /*
720
- * call-seq:
721
- * FieldDescriptor.label = label
722
- *
723
- * Sets the label on this field. Cannot be called if field is part of a message
724
- * type already in a pool.
725
- */
726
- VALUE FieldDescriptor_label_set(VALUE _self, VALUE label) {
727
- DEFINE_SELF(FieldDescriptor, self, _self);
728
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
729
- upb_label_t upb_label = -1;
730
- bool converted = false;
731
-
732
- if (TYPE(label) != T_SYMBOL) {
733
- rb_raise(rb_eArgError, "Expected symbol for field label.");
734
- }
735
-
736
- #define CONVERT(upb, ruby) \
737
- if (SYM2ID(label) == rb_intern( # ruby )) { \
738
- upb_label = UPB_LABEL_ ## upb; \
739
- converted = true; \
740
- }
708
+ static VALUE FieldDescriptor_label(VALUE _self) {
709
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
710
+ switch (upb_FieldDef_Label(self->fielddef)) {
711
+ #define CONVERT(upb, ruby) \
712
+ case kUpb_Label_##upb: \
713
+ return ID2SYM(rb_intern(#ruby));
741
714
 
742
- CONVERT(OPTIONAL, optional);
743
- CONVERT(REQUIRED, required);
744
- CONVERT(REPEATED, repeated);
715
+ CONVERT(Optional, optional);
716
+ CONVERT(Required, required);
717
+ CONVERT(Repeated, repeated);
745
718
 
746
719
  #undef CONVERT
747
-
748
- if (!converted) {
749
- rb_raise(rb_eArgError, "Unknown field label.");
750
720
  }
751
721
 
752
- upb_fielddef_setlabel(mut_def, upb_label);
753
-
754
722
  return Qnil;
755
723
  }
756
724
 
@@ -760,24 +728,9 @@ VALUE FieldDescriptor_label_set(VALUE _self, VALUE label) {
760
728
  *
761
729
  * Returns the tag number for this field.
762
730
  */
763
- VALUE FieldDescriptor_number(VALUE _self) {
764
- DEFINE_SELF(FieldDescriptor, self, _self);
765
- return INT2NUM(upb_fielddef_number(self->fielddef));
766
- }
767
-
768
- /*
769
- * call-seq:
770
- * FieldDescriptor.number = number
771
- *
772
- * Sets the tag number for this field. Cannot be called if field is part of a
773
- * message type already in a pool.
774
- */
775
- VALUE FieldDescriptor_number_set(VALUE _self, VALUE number) {
776
- DEFINE_SELF(FieldDescriptor, self, _self);
777
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
778
- CHECK_UPB(upb_fielddef_setnumber(mut_def, NUM2INT(number), &status),
779
- "Error setting field number");
780
- return Qnil;
731
+ static VALUE FieldDescriptor_number(VALUE _self) {
732
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
733
+ return INT2NUM(upb_FieldDef_Number(self->fielddef));
781
734
  }
782
735
 
783
736
  /*
@@ -789,34 +742,18 @@ VALUE FieldDescriptor_number_set(VALUE _self, VALUE number) {
789
742
  * name will be resolved within the context of the pool to which the containing
790
743
  * message type is added.
791
744
  */
792
- VALUE FieldDescriptor_submsg_name(VALUE _self) {
793
- DEFINE_SELF(FieldDescriptor, self, _self);
794
- if (!upb_fielddef_hassubdef(self->fielddef)) {
795
- return Qnil;
796
- }
797
- return rb_str_maybe_null(upb_fielddef_subdefname(self->fielddef));
798
- }
799
-
800
- /*
801
- * call-seq:
802
- * FieldDescriptor.submsg_name = submsg_name
803
- *
804
- * Sets the name of the message or enum type corresponding to this field, if it
805
- * is a message or enum field (respectively). This type name will be resolved
806
- * within the context of the pool to which the containing message type is added.
807
- * Cannot be called on field that are not of message or enum type, or on fields
808
- * that are part of a message type already added to a pool.
809
- */
810
- VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
811
- DEFINE_SELF(FieldDescriptor, self, _self);
812
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
813
- const char* str = get_str(value);
814
- if (!upb_fielddef_hassubdef(self->fielddef)) {
815
- rb_raise(rb_eTypeError, "FieldDescriptor does not have subdef.");
745
+ static VALUE FieldDescriptor_submsg_name(VALUE _self) {
746
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
747
+ switch (upb_FieldDef_CType(self->fielddef)) {
748
+ case kUpb_CType_Enum:
749
+ return rb_str_new2(
750
+ upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(self->fielddef)));
751
+ case kUpb_CType_Message:
752
+ return rb_str_new2(
753
+ upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(self->fielddef)));
754
+ default:
755
+ return Qnil;
816
756
  }
817
- CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
818
- "Error setting submessage name");
819
- return Qnil;
820
757
  }
821
758
 
822
759
  /*
@@ -828,18 +765,18 @@ VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
828
765
  * called *until* the containing message type is added to a pool (and thus
829
766
  * resolved).
830
767
  */
831
- VALUE FieldDescriptor_subtype(VALUE _self) {
832
- DEFINE_SELF(FieldDescriptor, self, _self);
833
- const upb_def* def;
834
-
835
- if (!upb_fielddef_hassubdef(self->fielddef)) {
836
- return Qnil;
768
+ static VALUE FieldDescriptor_subtype(VALUE _self) {
769
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
770
+ switch (upb_FieldDef_CType(self->fielddef)) {
771
+ case kUpb_CType_Enum:
772
+ return get_enumdef_obj(self->descriptor_pool,
773
+ upb_FieldDef_EnumSubDef(self->fielddef));
774
+ case kUpb_CType_Message:
775
+ return get_msgdef_obj(self->descriptor_pool,
776
+ upb_FieldDef_MessageSubDef(self->fielddef));
777
+ default:
778
+ return Qnil;
837
779
  }
838
- def = upb_fielddef_subdef(self->fielddef);
839
- if (def == NULL) {
840
- return Qnil;
841
- }
842
- return get_def_obj(def);
843
780
  }
844
781
 
845
782
  /*
@@ -849,14 +786,57 @@ VALUE FieldDescriptor_subtype(VALUE _self) {
849
786
  * Returns the value set for this field on the given message. Raises an
850
787
  * exception if message is of the wrong type.
851
788
  */
852
- VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
853
- DEFINE_SELF(FieldDescriptor, self, _self);
854
- MessageHeader* msg;
855
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
856
- if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
857
- rb_raise(rb_eTypeError, "get method called on wrong message type");
789
+ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
790
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
791
+ const upb_MessageDef* m;
792
+
793
+ Message_Get(msg_rb, &m);
794
+
795
+ if (m != upb_FieldDef_ContainingType(self->fielddef)) {
796
+ rb_raise(cTypeError, "get method called on wrong message type");
858
797
  }
859
- return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
798
+
799
+ return Message_getfield(msg_rb, self->fielddef);
800
+ }
801
+
802
+ /*
803
+ * call-seq:
804
+ * FieldDescriptor.has?(message) => boolean
805
+ *
806
+ * Returns whether the value is set on the given message. Raises an
807
+ * exception when calling for fields that do not have presence.
808
+ */
809
+ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
810
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
811
+ const upb_MessageDef* m;
812
+ const upb_MessageDef* msg = Message_Get(msg_rb, &m);
813
+
814
+ if (m != upb_FieldDef_ContainingType(self->fielddef)) {
815
+ rb_raise(cTypeError, "has method called on wrong message type");
816
+ } else if (!upb_FieldDef_HasPresence(self->fielddef)) {
817
+ rb_raise(rb_eArgError, "does not track presence");
818
+ }
819
+
820
+ return upb_Message_HasFieldByDef(msg, self->fielddef) ? Qtrue : Qfalse;
821
+ }
822
+
823
+ /*
824
+ * call-seq:
825
+ * FieldDescriptor.clear(message)
826
+ *
827
+ * Clears the field from the message if it's set.
828
+ */
829
+ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
830
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
831
+ const upb_MessageDef* m;
832
+ upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
833
+
834
+ if (m != upb_FieldDef_ContainingType(self->fielddef)) {
835
+ rb_raise(cTypeError, "has method called on wrong message type");
836
+ }
837
+
838
+ upb_Message_ClearFieldByDef(msg, self->fielddef);
839
+ return Qnil;
860
840
  }
861
841
 
862
842
  /*
@@ -867,30 +847,71 @@ VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
867
847
  * message. Raises an exception if message is of the wrong type. Performs the
868
848
  * ordinary type-checks for field setting.
869
849
  */
870
- VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
871
- DEFINE_SELF(FieldDescriptor, self, _self);
872
- MessageHeader* msg;
873
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
874
- if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
875
- rb_raise(rb_eTypeError, "set method called on wrong message type");
850
+ static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
851
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
852
+ const upb_MessageDef* m;
853
+ upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
854
+ upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
855
+ upb_MessageValue msgval;
856
+
857
+ if (m != upb_FieldDef_ContainingType(self->fielddef)) {
858
+ rb_raise(cTypeError, "set method called on wrong message type");
876
859
  }
877
- layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
860
+
861
+ msgval = Convert_RubyToUpb(value, upb_FieldDef_Name(self->fielddef),
862
+ TypeInfo_get(self->fielddef), arena);
863
+ upb_Message_SetFieldByDef(msg, self->fielddef, msgval, arena);
878
864
  return Qnil;
879
865
  }
880
866
 
867
+ static void FieldDescriptor_register(VALUE module) {
868
+ VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
869
+ rb_define_alloc_func(klass, FieldDescriptor_alloc);
870
+ rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
871
+ rb_define_method(klass, "name", FieldDescriptor_name, 0);
872
+ rb_define_method(klass, "type", FieldDescriptor__type, 0);
873
+ rb_define_method(klass, "default", FieldDescriptor_default, 0);
874
+ rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
875
+ rb_define_method(klass, "label", FieldDescriptor_label, 0);
876
+ rb_define_method(klass, "number", FieldDescriptor_number, 0);
877
+ rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
878
+ rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
879
+ rb_define_method(klass, "has?", FieldDescriptor_has, 1);
880
+ rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
881
+ rb_define_method(klass, "get", FieldDescriptor_get, 1);
882
+ rb_define_method(klass, "set", FieldDescriptor_set, 2);
883
+ rb_gc_register_address(&cFieldDescriptor);
884
+ cFieldDescriptor = klass;
885
+ }
886
+
881
887
  // -----------------------------------------------------------------------------
882
888
  // OneofDescriptor.
883
889
  // -----------------------------------------------------------------------------
884
890
 
885
- DEFINE_CLASS(OneofDescriptor, "Google::Protobuf::OneofDescriptor");
891
+ typedef struct {
892
+ const upb_OneofDef* oneofdef;
893
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
894
+ // macro to update VALUE references, as to trigger write barriers.
895
+ VALUE descriptor_pool; // Owns the upb_OneofDef.
896
+ } OneofDescriptor;
886
897
 
887
- void OneofDescriptor_mark(void* _self) {
888
- }
898
+ static VALUE cOneofDescriptor = Qnil;
889
899
 
890
- void OneofDescriptor_free(void* _self) {
900
+ static void OneofDescriptor_mark(void* _self) {
891
901
  OneofDescriptor* self = _self;
892
- upb_oneofdef_unref(self->oneofdef, &self->oneofdef);
893
- xfree(self);
902
+ rb_gc_mark(self->descriptor_pool);
903
+ }
904
+
905
+ static const rb_data_type_t OneofDescriptor_type = {
906
+ "Google::Protobuf::OneofDescriptor",
907
+ {OneofDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
908
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
909
+ };
910
+
911
+ static OneofDescriptor* ruby_to_OneofDescriptor(VALUE val) {
912
+ OneofDescriptor* ret;
913
+ TypedData_Get_Struct(val, OneofDescriptor, &OneofDescriptor_type, ret);
914
+ return ret;
894
915
  }
895
916
 
896
917
  /*
@@ -900,77 +921,44 @@ void OneofDescriptor_free(void* _self) {
900
921
  * Creates a new, empty, oneof descriptor. The oneof may only be modified prior
901
922
  * to being added to a message descriptor which is subsequently added to a pool.
902
923
  */
903
- VALUE OneofDescriptor_alloc(VALUE klass) {
924
+ static VALUE OneofDescriptor_alloc(VALUE klass) {
904
925
  OneofDescriptor* self = ALLOC(OneofDescriptor);
905
- VALUE ret = TypedData_Wrap_Struct(klass, &_OneofDescriptor_type, self);
906
- self->oneofdef = upb_oneofdef_new(&self->oneofdef);
926
+ VALUE ret = TypedData_Wrap_Struct(klass, &OneofDescriptor_type, self);
927
+ self->oneofdef = NULL;
928
+ self->descriptor_pool = Qnil;
907
929
  return ret;
908
930
  }
909
931
 
910
- void OneofDescriptor_register(VALUE module) {
911
- VALUE klass = rb_define_class_under(
912
- module, "OneofDescriptor", rb_cObject);
913
- rb_define_alloc_func(klass, OneofDescriptor_alloc);
914
- rb_define_method(klass, "name", OneofDescriptor_name, 0);
915
- rb_define_method(klass, "name=", OneofDescriptor_name_set, 1);
916
- rb_define_method(klass, "add_field", OneofDescriptor_add_field, 1);
917
- rb_define_method(klass, "each", OneofDescriptor_each, 0);
918
- rb_include_module(klass, rb_mEnumerable);
919
- cOneofDescriptor = klass;
920
- rb_gc_register_address(&cOneofDescriptor);
921
- }
922
-
923
932
  /*
924
933
  * call-seq:
925
- * OneofDescriptor.name => name
934
+ * OneofDescriptor.new(c_only_cookie, pool, ptr) => OneofDescriptor
926
935
  *
927
- * Returns the name of this oneof.
936
+ * Creates a descriptor wrapper object. May only be called from C.
928
937
  */
929
- VALUE OneofDescriptor_name(VALUE _self) {
930
- DEFINE_SELF(OneofDescriptor, self, _self);
931
- return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
932
- }
938
+ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
939
+ VALUE descriptor_pool, VALUE ptr) {
940
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
941
+
942
+ if (cookie != c_only_cookie) {
943
+ rb_raise(rb_eRuntimeError,
944
+ "Descriptor objects may not be created from Ruby.");
945
+ }
946
+
947
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
948
+ self->oneofdef = (const upb_OneofDef*)NUM2ULL(ptr);
933
949
 
934
- /*
935
- * call-seq:
936
- * OneofDescriptor.name = name
937
- *
938
- * Sets a new name for this oneof. The oneof must not have been added to a
939
- * message descriptor yet.
940
- */
941
- VALUE OneofDescriptor_name_set(VALUE _self, VALUE value) {
942
- DEFINE_SELF(OneofDescriptor, self, _self);
943
- upb_oneofdef* mut_def = check_oneof_notfrozen(self->oneofdef);
944
- const char* str = get_str(value);
945
- CHECK_UPB(upb_oneofdef_setname(mut_def, str, &status),
946
- "Error setting oneof name");
947
950
  return Qnil;
948
951
  }
949
952
 
950
953
  /*
951
954
  * call-seq:
952
- * OneofDescriptor.add_field(field) => nil
953
- *
954
- * Adds a field to this oneof. The field may have been added to this oneof in
955
- * the past, or the message to which this oneof belongs (if any), but may not
956
- * have already been added to any other oneof or message. Otherwise, an
957
- * exception is raised.
955
+ * OneofDescriptor.name => name
958
956
  *
959
- * All fields added to the oneof via this method will be automatically added to
960
- * the message to which this oneof belongs, if it belongs to one currently, or
961
- * else will be added to any message to which the oneof is later added at the
962
- * time that it is added.
957
+ * Returns the name of this oneof.
963
958
  */
964
- VALUE OneofDescriptor_add_field(VALUE _self, VALUE obj) {
965
- DEFINE_SELF(OneofDescriptor, self, _self);
966
- upb_oneofdef* mut_def = check_oneof_notfrozen(self->oneofdef);
967
- FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
968
- upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
969
- CHECK_UPB(
970
- upb_oneofdef_addfield(mut_def, mut_field_def, NULL, &status),
971
- "Adding field to OneofDescriptor failed");
972
- add_def_obj(def->fielddef, obj);
973
- return Qnil;
959
+ static VALUE OneofDescriptor_name(VALUE _self) {
960
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
961
+ return rb_str_maybe_null(upb_OneofDef_Name(self->oneofdef));
974
962
  }
975
963
 
976
964
  /*
@@ -979,111 +967,118 @@ VALUE OneofDescriptor_add_field(VALUE _self, VALUE obj) {
979
967
  *
980
968
  * Iterates through fields in this oneof, yielding to the block on each one.
981
969
  */
982
- VALUE OneofDescriptor_each(VALUE _self, VALUE field) {
983
- DEFINE_SELF(OneofDescriptor, self, _self);
984
- upb_oneof_iter it;
985
- for (upb_oneof_begin(&it, self->oneofdef);
986
- !upb_oneof_done(&it);
987
- upb_oneof_next(&it)) {
988
- const upb_fielddef* f = upb_oneof_iter_field(&it);
989
- VALUE obj = get_def_obj(f);
970
+ static VALUE OneofDescriptor_each(VALUE _self) {
971
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
972
+
973
+ int n = upb_OneofDef_FieldCount(self->oneofdef);
974
+ for (int i = 0; i < n; i++) {
975
+ const upb_FieldDef* f = upb_OneofDef_Field(self->oneofdef, i);
976
+ VALUE obj = get_fielddef_obj(self->descriptor_pool, f);
990
977
  rb_yield(obj);
991
978
  }
992
979
  return Qnil;
993
980
  }
994
981
 
982
+ static void OneofDescriptor_register(VALUE module) {
983
+ VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
984
+ rb_define_alloc_func(klass, OneofDescriptor_alloc);
985
+ rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
986
+ rb_define_method(klass, "name", OneofDescriptor_name, 0);
987
+ rb_define_method(klass, "each", OneofDescriptor_each, 0);
988
+ rb_include_module(klass, rb_mEnumerable);
989
+ rb_gc_register_address(&cOneofDescriptor);
990
+ cOneofDescriptor = klass;
991
+ }
992
+
995
993
  // -----------------------------------------------------------------------------
996
994
  // EnumDescriptor.
997
995
  // -----------------------------------------------------------------------------
998
996
 
999
- DEFINE_CLASS(EnumDescriptor, "Google::Protobuf::EnumDescriptor");
997
+ typedef struct {
998
+ const upb_EnumDef* enumdef;
999
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
1000
+ // macro to update VALUE references, as to trigger write barriers.
1001
+ VALUE module; // begins as nil
1002
+ VALUE descriptor_pool; // Owns the upb_EnumDef.
1003
+ } EnumDescriptor;
1000
1004
 
1001
- void EnumDescriptor_mark(void* _self) {
1005
+ static VALUE cEnumDescriptor = Qnil;
1006
+
1007
+ static void EnumDescriptor_mark(void* _self) {
1002
1008
  EnumDescriptor* self = _self;
1003
1009
  rb_gc_mark(self->module);
1010
+ rb_gc_mark(self->descriptor_pool);
1004
1011
  }
1005
1012
 
1006
- void EnumDescriptor_free(void* _self) {
1007
- EnumDescriptor* self = _self;
1008
- upb_enumdef_unref(self->enumdef, &self->enumdef);
1009
- xfree(self);
1013
+ static const rb_data_type_t EnumDescriptor_type = {
1014
+ "Google::Protobuf::EnumDescriptor",
1015
+ {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1016
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1017
+ };
1018
+
1019
+ static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) {
1020
+ EnumDescriptor* ret;
1021
+ TypedData_Get_Struct(val, EnumDescriptor, &EnumDescriptor_type, ret);
1022
+ return ret;
1010
1023
  }
1011
1024
 
1012
- /*
1013
- * call-seq:
1014
- * EnumDescriptor.new => enum_descriptor
1015
- *
1016
- * Creates a new, empty, enum descriptor. Must be added to a pool before the
1017
- * enum type can be used. The enum type may only be modified prior to adding to
1018
- * a pool.
1019
- */
1020
- VALUE EnumDescriptor_alloc(VALUE klass) {
1025
+ static VALUE EnumDescriptor_alloc(VALUE klass) {
1021
1026
  EnumDescriptor* self = ALLOC(EnumDescriptor);
1022
- VALUE ret = TypedData_Wrap_Struct(klass, &_EnumDescriptor_type, self);
1023
- self->enumdef = upb_enumdef_new(&self->enumdef);
1027
+ VALUE ret = TypedData_Wrap_Struct(klass, &EnumDescriptor_type, self);
1028
+ self->enumdef = NULL;
1024
1029
  self->module = Qnil;
1030
+ self->descriptor_pool = Qnil;
1025
1031
  return ret;
1026
1032
  }
1027
1033
 
1028
- void EnumDescriptor_register(VALUE module) {
1029
- VALUE klass = rb_define_class_under(
1030
- module, "EnumDescriptor", rb_cObject);
1031
- rb_define_alloc_func(klass, EnumDescriptor_alloc);
1032
- rb_define_method(klass, "name", EnumDescriptor_name, 0);
1033
- rb_define_method(klass, "name=", EnumDescriptor_name_set, 1);
1034
- rb_define_method(klass, "add_value", EnumDescriptor_add_value, 2);
1035
- rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
1036
- rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
1037
- rb_define_method(klass, "each", EnumDescriptor_each, 0);
1038
- rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1039
- rb_include_module(klass, rb_mEnumerable);
1040
- cEnumDescriptor = klass;
1041
- rb_gc_register_address(&cEnumDescriptor);
1034
+ // Exposed to other modules in defs.h.
1035
+ const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) {
1036
+ EnumDescriptor* desc = ruby_to_EnumDescriptor(enum_desc_rb);
1037
+ return desc->enumdef;
1042
1038
  }
1043
1039
 
1044
1040
  /*
1045
1041
  * call-seq:
1046
- * EnumDescriptor.name => name
1042
+ * EnumDescriptor.new(c_only_cookie, ptr) => EnumDescriptor
1047
1043
  *
1048
- * Returns the name of this enum type.
1044
+ * Creates a descriptor wrapper object. May only be called from C.
1049
1045
  */
1050
- VALUE EnumDescriptor_name(VALUE _self) {
1051
- DEFINE_SELF(EnumDescriptor, self, _self);
1052
- return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
1046
+ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
1047
+ VALUE descriptor_pool, VALUE ptr) {
1048
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1049
+
1050
+ if (cookie != c_only_cookie) {
1051
+ rb_raise(rb_eRuntimeError,
1052
+ "Descriptor objects may not be created from Ruby.");
1053
+ }
1054
+
1055
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1056
+ self->enumdef = (const upb_EnumDef*)NUM2ULL(ptr);
1057
+
1058
+ return Qnil;
1053
1059
  }
1054
1060
 
1055
1061
  /*
1056
1062
  * call-seq:
1057
- * EnumDescriptor.name = name
1063
+ * EnumDescriptor.file_descriptor
1058
1064
  *
1059
- * Sets the name of this enum type. Cannot be called if the enum type has
1060
- * already been added to a pool.
1065
+ * Returns the FileDescriptor object this enum belongs to.
1061
1066
  */
1062
- VALUE EnumDescriptor_name_set(VALUE _self, VALUE str) {
1063
- DEFINE_SELF(EnumDescriptor, self, _self);
1064
- upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
1065
- const char* name = get_str(str);
1066
- CHECK_UPB(upb_enumdef_setfullname(mut_def, name, &status),
1067
- "Error setting EnumDescriptor name");
1068
- return Qnil;
1067
+ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1068
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1069
+ return get_filedef_obj(self->descriptor_pool,
1070
+ upb_EnumDef_File(self->enumdef));
1069
1071
  }
1070
1072
 
1071
1073
  /*
1072
1074
  * call-seq:
1073
- * EnumDescriptor.add_value(key, value)
1075
+ * EnumDescriptor.name => name
1074
1076
  *
1075
- * Adds a new key => value mapping to this enum type. Key must be given as a
1076
- * Ruby symbol. Cannot be called if the enum type has already been added to a
1077
- * pool. Will raise an exception if the key or value is already in use.
1077
+ * Returns the name of this enum type.
1078
1078
  */
1079
- VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number) {
1080
- DEFINE_SELF(EnumDescriptor, self, _self);
1081
- upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
1082
- const char* name_str = rb_id2name(SYM2ID(name));
1083
- int32_t val = NUM2INT(number);
1084
- CHECK_UPB(upb_enumdef_addval(mut_def, name_str, val, &status),
1085
- "Error adding value to enum");
1086
- return Qnil;
1079
+ static VALUE EnumDescriptor_name(VALUE _self) {
1080
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1081
+ return rb_str_maybe_null(upb_EnumDef_FullName(self->enumdef));
1087
1082
  }
1088
1083
 
1089
1084
  /*
@@ -1093,12 +1088,13 @@ VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number) {
1093
1088
  * Returns the numeric value corresponding to the given key name (as a Ruby
1094
1089
  * symbol), or nil if none.
1095
1090
  */
1096
- VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1097
- DEFINE_SELF(EnumDescriptor, self, _self);
1098
- const char* name_str= rb_id2name(SYM2ID(name));
1099
- int32_t val = 0;
1100
- if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) {
1101
- return INT2NUM(val);
1091
+ static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1092
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1093
+ const char* name_str = rb_id2name(SYM2ID(name));
1094
+ const upb_EnumValueDef *ev =
1095
+ upb_EnumDef_FindValueByName(self->enumdef, name_str);
1096
+ if (ev) {
1097
+ return INT2NUM(upb_EnumValueDef_Number(ev));
1102
1098
  } else {
1103
1099
  return Qnil;
1104
1100
  }
@@ -1111,12 +1107,12 @@ VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1111
1107
  * Returns the key name (as a Ruby symbol) corresponding to the integer value,
1112
1108
  * or nil if none.
1113
1109
  */
1114
- VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1115
- DEFINE_SELF(EnumDescriptor, self, _self);
1110
+ static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1111
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1116
1112
  int32_t val = NUM2INT(number);
1117
- const char* name = upb_enumdef_iton(self->enumdef, val);
1118
- if (name != NULL) {
1119
- return ID2SYM(rb_intern(name));
1113
+ const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(self->enumdef, val);
1114
+ if (ev) {
1115
+ return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
1120
1116
  } else {
1121
1117
  return Qnil;
1122
1118
  }
@@ -1129,15 +1125,14 @@ VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1129
1125
  * Iterates over key => value mappings in this enum's definition, yielding to
1130
1126
  * the block with (key, value) arguments for each one.
1131
1127
  */
1132
- VALUE EnumDescriptor_each(VALUE _self) {
1133
- DEFINE_SELF(EnumDescriptor, self, _self);
1134
-
1135
- upb_enum_iter it;
1136
- for (upb_enum_begin(&it, self->enumdef);
1137
- !upb_enum_done(&it);
1138
- upb_enum_next(&it)) {
1139
- VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it)));
1140
- VALUE number = INT2NUM(upb_enum_iter_number(&it));
1128
+ static VALUE EnumDescriptor_each(VALUE _self) {
1129
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1130
+
1131
+ int n = upb_EnumDef_ValueCount(self->enumdef);
1132
+ for (int i = 0; i < n; i++) {
1133
+ const upb_EnumValueDef* ev = upb_EnumDef_Value(self->enumdef, i);
1134
+ VALUE key = ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
1135
+ VALUE number = INT2NUM(upb_EnumValueDef_Number(ev));
1141
1136
  rb_yield_values(2, key, number);
1142
1137
  }
1143
1138
 
@@ -1148,627 +1143,148 @@ VALUE EnumDescriptor_each(VALUE _self) {
1148
1143
  * call-seq:
1149
1144
  * EnumDescriptor.enummodule => module
1150
1145
  *
1151
- * Returns the Ruby module corresponding to this enum type. Cannot be called
1152
- * until the enum descriptor has been added to a pool.
1146
+ * Returns the Ruby module corresponding to this enum type.
1153
1147
  */
1154
- VALUE EnumDescriptor_enummodule(VALUE _self) {
1155
- DEFINE_SELF(EnumDescriptor, self, _self);
1156
- if (!upb_def_isfrozen((const upb_def*)self->enumdef)) {
1157
- rb_raise(rb_eRuntimeError,
1158
- "Cannot fetch enum module from an EnumDescriptor not yet "
1159
- "in a pool.");
1160
- }
1148
+ static VALUE EnumDescriptor_enummodule(VALUE _self) {
1149
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1161
1150
  if (self->module == Qnil) {
1162
- self->module = build_module_from_enumdesc(self);
1151
+ RB_OBJ_WRITE(_self, &self->module, build_module_from_enumdesc(_self));
1163
1152
  }
1164
1153
  return self->module;
1165
1154
  }
1166
1155
 
1167
- // -----------------------------------------------------------------------------
1168
- // MessageBuilderContext.
1169
- // -----------------------------------------------------------------------------
1170
-
1171
- DEFINE_CLASS(MessageBuilderContext,
1172
- "Google::Protobuf::Internal::MessageBuilderContext");
1173
-
1174
- void MessageBuilderContext_mark(void* _self) {
1175
- MessageBuilderContext* self = _self;
1176
- rb_gc_mark(self->descriptor);
1177
- rb_gc_mark(self->builder);
1178
- }
1179
-
1180
- void MessageBuilderContext_free(void* _self) {
1181
- MessageBuilderContext* self = _self;
1182
- xfree(self);
1183
- }
1184
-
1185
- VALUE MessageBuilderContext_alloc(VALUE klass) {
1186
- MessageBuilderContext* self = ALLOC(MessageBuilderContext);
1187
- VALUE ret = TypedData_Wrap_Struct(
1188
- klass, &_MessageBuilderContext_type, self);
1189
- self->descriptor = Qnil;
1190
- self->builder = Qnil;
1191
- return ret;
1192
- }
1193
-
1194
- void MessageBuilderContext_register(VALUE module) {
1195
- VALUE klass = rb_define_class_under(
1196
- module, "MessageBuilderContext", rb_cObject);
1197
- rb_define_alloc_func(klass, MessageBuilderContext_alloc);
1198
- rb_define_method(klass, "initialize",
1199
- MessageBuilderContext_initialize, 2);
1200
- rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
1201
- rb_define_method(klass, "required", MessageBuilderContext_required, -1);
1202
- rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
1203
- rb_define_method(klass, "map", MessageBuilderContext_map, -1);
1204
- rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
1205
- cMessageBuilderContext = klass;
1206
- rb_gc_register_address(&cMessageBuilderContext);
1207
- }
1208
-
1209
- /*
1210
- * call-seq:
1211
- * MessageBuilderContext.new(desc, builder) => context
1212
- *
1213
- * Create a new message builder context around the given message descriptor and
1214
- * builder context. This class is intended to serve as a DSL context to be used
1215
- * with #instance_eval.
1216
- */
1217
- VALUE MessageBuilderContext_initialize(VALUE _self,
1218
- VALUE msgdef,
1219
- VALUE builder) {
1220
- DEFINE_SELF(MessageBuilderContext, self, _self);
1221
- self->descriptor = msgdef;
1222
- self->builder = builder;
1223
- return Qnil;
1224
- }
1225
-
1226
- static VALUE msgdef_add_field(VALUE msgdef,
1227
- const char* label, VALUE name,
1228
- VALUE type, VALUE number,
1229
- VALUE type_class) {
1230
- VALUE fielddef = rb_class_new_instance(0, NULL, cFieldDescriptor);
1231
- VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1232
-
1233
- rb_funcall(fielddef, rb_intern("label="), 1, ID2SYM(rb_intern(label)));
1234
- rb_funcall(fielddef, rb_intern("name="), 1, name_str);
1235
- rb_funcall(fielddef, rb_intern("type="), 1, type);
1236
- rb_funcall(fielddef, rb_intern("number="), 1, number);
1237
-
1238
- if (type_class != Qnil) {
1239
- if (TYPE(type_class) != T_STRING) {
1240
- rb_raise(rb_eArgError, "Expected string for type class");
1241
- }
1242
- // Make it an absolute type name by prepending a dot.
1243
- type_class = rb_str_append(rb_str_new2("."), type_class);
1244
- rb_funcall(fielddef, rb_intern("submsg_name="), 1, type_class);
1245
- }
1246
-
1247
- rb_funcall(msgdef, rb_intern("add_field"), 1, fielddef);
1248
- return fielddef;
1249
- }
1250
-
1251
- /*
1252
- * call-seq:
1253
- * MessageBuilderContext.optional(name, type, number, type_class = nil)
1254
- *
1255
- * Defines a new optional field on this message type with the given type, tag
1256
- * number, and type class (for message and enum fields). The type must be a Ruby
1257
- * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1258
- * string, if present (as accepted by FieldDescriptor#submsg_name=).
1259
- */
1260
- VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1261
- DEFINE_SELF(MessageBuilderContext, self, _self);
1262
- VALUE name, type, number, type_class;
1263
-
1264
- if (argc < 3) {
1265
- rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1266
- }
1267
- name = argv[0];
1268
- type = argv[1];
1269
- number = argv[2];
1270
- type_class = (argc > 3) ? argv[3] : Qnil;
1271
-
1272
- return msgdef_add_field(self->descriptor, "optional",
1273
- name, type, number, type_class);
1274
- }
1275
-
1276
- /*
1277
- * call-seq:
1278
- * MessageBuilderContext.required(name, type, number, type_class = nil)
1279
- *
1280
- * Defines a new required field on this message type with the given type, tag
1281
- * number, and type class (for message and enum fields). The type must be a Ruby
1282
- * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1283
- * string, if present (as accepted by FieldDescriptor#submsg_name=).
1284
- *
1285
- * Proto3 does not have required fields, but this method exists for
1286
- * completeness. Any attempt to add a message type with required fields to a
1287
- * pool will currently result in an error.
1288
- */
1289
- VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1290
- DEFINE_SELF(MessageBuilderContext, self, _self);
1291
- VALUE name, type, number, type_class;
1292
-
1293
- if (argc < 3) {
1294
- rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1295
- }
1296
- name = argv[0];
1297
- type = argv[1];
1298
- number = argv[2];
1299
- type_class = (argc > 3) ? argv[3] : Qnil;
1300
-
1301
- return msgdef_add_field(self->descriptor, "required",
1302
- name, type, number, type_class);
1303
- }
1304
-
1305
- /*
1306
- * call-seq:
1307
- * MessageBuilderContext.repeated(name, type, number, type_class = nil)
1308
- *
1309
- * Defines a new repeated field on this message type with the given type, tag
1310
- * number, and type class (for message and enum fields). The type must be a Ruby
1311
- * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1312
- * string, if present (as accepted by FieldDescriptor#submsg_name=).
1313
- */
1314
- VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1315
- DEFINE_SELF(MessageBuilderContext, self, _self);
1316
- VALUE name, type, number, type_class;
1317
-
1318
- if (argc < 3) {
1319
- rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1320
- }
1321
- name = argv[0];
1322
- type = argv[1];
1323
- number = argv[2];
1324
- type_class = (argc > 3) ? argv[3] : Qnil;
1325
-
1326
- return msgdef_add_field(self->descriptor, "repeated",
1327
- name, type, number, type_class);
1156
+ static void EnumDescriptor_register(VALUE module) {
1157
+ VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
1158
+ rb_define_alloc_func(klass, EnumDescriptor_alloc);
1159
+ rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
1160
+ rb_define_method(klass, "name", EnumDescriptor_name, 0);
1161
+ rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
1162
+ rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
1163
+ rb_define_method(klass, "each", EnumDescriptor_each, 0);
1164
+ rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1165
+ rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1166
+ rb_include_module(klass, rb_mEnumerable);
1167
+ rb_gc_register_address(&cEnumDescriptor);
1168
+ cEnumDescriptor = klass;
1328
1169
  }
1329
1170
 
1330
- /*
1331
- * call-seq:
1332
- * MessageBuilderContext.map(name, key_type, value_type, number,
1333
- * value_type_class = nil)
1334
- *
1335
- * Defines a new map field on this message type with the given key and value
1336
- * types, tag number, and type class (for message and enum value types). The key
1337
- * type must be :int32/:uint32/:int64/:uint64, :bool, or :string. The value type
1338
- * type must be a Ruby symbol (as accepted by FieldDescriptor#type=) and the
1339
- * type_class must be a string, if present (as accepted by
1340
- * FieldDescriptor#submsg_name=).
1341
- */
1342
- VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1343
- DEFINE_SELF(MessageBuilderContext, self, _self);
1344
- VALUE name, key_type, value_type, number, type_class;
1345
- VALUE mapentry_desc, mapentry_desc_name;
1346
-
1347
- if (argc < 4) {
1348
- rb_raise(rb_eArgError, "Expected at least 4 arguments.");
1349
- }
1350
- name = argv[0];
1351
- key_type = argv[1];
1352
- value_type = argv[2];
1353
- number = argv[3];
1354
- type_class = (argc > 4) ? argv[4] : Qnil;
1355
-
1356
- // Validate the key type. We can't accept enums, messages, or floats/doubles
1357
- // as map keys. (We exclude these explicitly, and the field-descriptor setter
1358
- // below then ensures that the type is one of the remaining valid options.)
1359
- if (SYM2ID(key_type) == rb_intern("float") ||
1360
- SYM2ID(key_type) == rb_intern("double") ||
1361
- SYM2ID(key_type) == rb_intern("enum") ||
1362
- SYM2ID(key_type) == rb_intern("message")) {
1363
- rb_raise(rb_eArgError,
1364
- "Cannot add a map field with a float, double, enum, or message "
1365
- "type.");
1366
- }
1367
-
1368
- // Create a new message descriptor for the map entry message, and create a
1369
- // repeated submessage field here with that type.
1370
- mapentry_desc = rb_class_new_instance(0, NULL, cDescriptor);
1371
- mapentry_desc_name = rb_funcall(self->descriptor, rb_intern("name"), 0);
1372
- mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
1373
- mapentry_desc_name = rb_str_cat2(mapentry_desc_name,
1374
- rb_id2name(SYM2ID(name)));
1375
- Descriptor_name_set(mapentry_desc, mapentry_desc_name);
1376
-
1377
- {
1378
- // The 'mapentry' attribute has no Ruby setter because we do not want the
1379
- // user attempting to DIY the setup below; we want to ensure that the fields
1380
- // are correct. So we reach into the msgdef here to set the bit manually.
1381
- Descriptor* mapentry_desc_self = ruby_to_Descriptor(mapentry_desc);
1382
- upb_msgdef_setmapentry((upb_msgdef*)mapentry_desc_self->msgdef, true);
1383
- }
1384
-
1385
- {
1386
- // optional <type> key = 1;
1387
- VALUE key_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
1388
- FieldDescriptor_name_set(key_field, rb_str_new2("key"));
1389
- FieldDescriptor_label_set(key_field, ID2SYM(rb_intern("optional")));
1390
- FieldDescriptor_number_set(key_field, INT2NUM(1));
1391
- FieldDescriptor_type_set(key_field, key_type);
1392
- Descriptor_add_field(mapentry_desc, key_field);
1393
- }
1394
-
1395
- {
1396
- // optional <type> value = 2;
1397
- VALUE value_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
1398
- FieldDescriptor_name_set(value_field, rb_str_new2("value"));
1399
- FieldDescriptor_label_set(value_field, ID2SYM(rb_intern("optional")));
1400
- FieldDescriptor_number_set(value_field, INT2NUM(2));
1401
- FieldDescriptor_type_set(value_field, value_type);
1402
- if (type_class != Qnil) {
1403
- VALUE submsg_name = rb_str_new2("."); // prepend '.' to make absolute.
1404
- submsg_name = rb_str_append(submsg_name, type_class);
1405
- FieldDescriptor_submsg_name_set(value_field, submsg_name);
1406
- }
1407
- Descriptor_add_field(mapentry_desc, value_field);
1408
- }
1171
+ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
1172
+ DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
1173
+ VALUE key = ULL2NUM((intptr_t)ptr);
1174
+ VALUE def;
1409
1175
 
1410
- {
1411
- // Add the map-entry message type to the current builder, and use the type
1412
- // to create the map field itself.
1413
- Builder* builder_self = ruby_to_Builder(self->builder);
1414
- rb_ary_push(builder_self->pending_list, mapentry_desc);
1415
- }
1176
+ def = rb_hash_aref(descriptor_pool->def_to_descriptor, key);
1416
1177
 
1417
- {
1418
- VALUE map_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
1419
- VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1420
- VALUE submsg_name;
1421
-
1422
- FieldDescriptor_name_set(map_field, name_str);
1423
- FieldDescriptor_number_set(map_field, number);
1424
- FieldDescriptor_label_set(map_field, ID2SYM(rb_intern("repeated")));
1425
- FieldDescriptor_type_set(map_field, ID2SYM(rb_intern("message")));
1426
- submsg_name = rb_str_new2("."); // prepend '.' to make name absolute.
1427
- submsg_name = rb_str_append(submsg_name, mapentry_desc_name);
1428
- FieldDescriptor_submsg_name_set(map_field, submsg_name);
1429
- Descriptor_add_field(self->descriptor, map_field);
1178
+ if (ptr == NULL) {
1179
+ return Qnil;
1430
1180
  }
1431
1181
 
1432
- return Qnil;
1433
- }
1434
-
1435
- /*
1436
- * call-seq:
1437
- * MessageBuilderContext.oneof(name, &block) => nil
1438
- *
1439
- * Creates a new OneofDescriptor with the given name, creates a
1440
- * OneofBuilderContext attached to that OneofDescriptor, evaluates the given
1441
- * block in the context of that OneofBuilderContext with #instance_eval, and
1442
- * then adds the oneof to the message.
1443
- *
1444
- * This is the recommended, idiomatic way to build oneof definitions.
1445
- */
1446
- VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
1447
- DEFINE_SELF(MessageBuilderContext, self, _self);
1448
- VALUE oneofdef = rb_class_new_instance(0, NULL, cOneofDescriptor);
1449
- VALUE args[2] = { oneofdef, self->builder };
1450
- VALUE ctx = rb_class_new_instance(2, args, cOneofBuilderContext);
1451
- VALUE block = rb_block_proc();
1452
- VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1453
- rb_funcall(oneofdef, rb_intern("name="), 1, name_str);
1454
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1455
- Descriptor_add_oneof(self->descriptor, oneofdef);
1456
-
1457
- return Qnil;
1458
- }
1459
-
1460
- // -----------------------------------------------------------------------------
1461
- // OneofBuilderContext.
1462
- // -----------------------------------------------------------------------------
1463
-
1464
- DEFINE_CLASS(OneofBuilderContext,
1465
- "Google::Protobuf::Internal::OneofBuilderContext");
1466
-
1467
- void OneofBuilderContext_mark(void* _self) {
1468
- OneofBuilderContext* self = _self;
1469
- rb_gc_mark(self->descriptor);
1470
- rb_gc_mark(self->builder);
1471
- }
1472
-
1473
- void OneofBuilderContext_free(void* _self) {
1474
- OneofBuilderContext* self = _self;
1475
- xfree(self);
1476
- }
1477
-
1478
- VALUE OneofBuilderContext_alloc(VALUE klass) {
1479
- OneofBuilderContext* self = ALLOC(OneofBuilderContext);
1480
- VALUE ret = TypedData_Wrap_Struct(
1481
- klass, &_OneofBuilderContext_type, self);
1482
- self->descriptor = Qnil;
1483
- self->builder = Qnil;
1484
- return ret;
1485
- }
1486
-
1487
- void OneofBuilderContext_register(VALUE module) {
1488
- VALUE klass = rb_define_class_under(
1489
- module, "OneofBuilderContext", rb_cObject);
1490
- rb_define_alloc_func(klass, OneofBuilderContext_alloc);
1491
- rb_define_method(klass, "initialize",
1492
- OneofBuilderContext_initialize, 2);
1493
- rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
1494
- cOneofBuilderContext = klass;
1495
- rb_gc_register_address(&cOneofBuilderContext);
1496
- }
1497
-
1498
- /*
1499
- * call-seq:
1500
- * OneofBuilderContext.new(desc, builder) => context
1501
- *
1502
- * Create a new oneof builder context around the given oneof descriptor and
1503
- * builder context. This class is intended to serve as a DSL context to be used
1504
- * with #instance_eval.
1505
- */
1506
- VALUE OneofBuilderContext_initialize(VALUE _self,
1507
- VALUE oneofdef,
1508
- VALUE builder) {
1509
- DEFINE_SELF(OneofBuilderContext, self, _self);
1510
- self->descriptor = oneofdef;
1511
- self->builder = builder;
1512
- return Qnil;
1513
- }
1514
-
1515
- /*
1516
- * call-seq:
1517
- * OneofBuilderContext.optional(name, type, number, type_class = nil)
1518
- *
1519
- * Defines a new optional field in this oneof with the given type, tag number,
1520
- * and type class (for message and enum fields). The type must be a Ruby symbol
1521
- * (as accepted by FieldDescriptor#type=) and the type_class must be a string,
1522
- * if present (as accepted by FieldDescriptor#submsg_name=).
1523
- */
1524
- VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1525
- DEFINE_SELF(OneofBuilderContext, self, _self);
1526
- VALUE name, type, number, type_class;
1527
-
1528
- if (argc < 3) {
1529
- rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1182
+ if (def == Qnil) {
1183
+ // Lazily create wrapper object.
1184
+ VALUE args[3] = {c_only_cookie, _descriptor_pool, key};
1185
+ def = rb_class_new_instance(3, args, klass);
1186
+ rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
1530
1187
  }
1531
- name = argv[0];
1532
- type = argv[1];
1533
- number = argv[2];
1534
- type_class = (argc > 3) ? argv[3] : Qnil;
1535
1188
 
1536
- return msgdef_add_field(self->descriptor, "optional",
1537
- name, type, number, type_class);
1189
+ return def;
1538
1190
  }
1539
1191
 
1540
- // -----------------------------------------------------------------------------
1541
- // EnumBuilderContext.
1542
- // -----------------------------------------------------------------------------
1543
-
1544
- DEFINE_CLASS(EnumBuilderContext,
1545
- "Google::Protobuf::Internal::EnumBuilderContext");
1546
-
1547
- void EnumBuilderContext_mark(void* _self) {
1548
- EnumBuilderContext* self = _self;
1549
- rb_gc_mark(self->enumdesc);
1192
+ static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def) {
1193
+ return get_def_obj(descriptor_pool, def, cDescriptor);
1550
1194
  }
1551
1195
 
1552
- void EnumBuilderContext_free(void* _self) {
1553
- EnumBuilderContext* self = _self;
1554
- xfree(self);
1196
+ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def) {
1197
+ return get_def_obj(descriptor_pool, def, cEnumDescriptor);
1555
1198
  }
1556
1199
 
1557
- VALUE EnumBuilderContext_alloc(VALUE klass) {
1558
- EnumBuilderContext* self = ALLOC(EnumBuilderContext);
1559
- VALUE ret = TypedData_Wrap_Struct(
1560
- klass, &_EnumBuilderContext_type, self);
1561
- self->enumdesc = Qnil;
1562
- return ret;
1200
+ static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def) {
1201
+ return get_def_obj(descriptor_pool, def, cFieldDescriptor);
1563
1202
  }
1564
1203
 
1565
- void EnumBuilderContext_register(VALUE module) {
1566
- VALUE klass = rb_define_class_under(
1567
- module, "EnumBuilderContext", rb_cObject);
1568
- rb_define_alloc_func(klass, EnumBuilderContext_alloc);
1569
- rb_define_method(klass, "initialize",
1570
- EnumBuilderContext_initialize, 1);
1571
- rb_define_method(klass, "value", EnumBuilderContext_value, 2);
1572
- cEnumBuilderContext = klass;
1573
- rb_gc_register_address(&cEnumBuilderContext);
1204
+ static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def) {
1205
+ return get_def_obj(descriptor_pool, def, cFileDescriptor);
1574
1206
  }
1575
1207
 
1576
- /*
1577
- * call-seq:
1578
- * EnumBuilderContext.new(enumdesc) => context
1579
- *
1580
- * Create a new builder context around the given enum descriptor. This class is
1581
- * intended to serve as a DSL context to be used with #instance_eval.
1582
- */
1583
- VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdef) {
1584
- DEFINE_SELF(EnumBuilderContext, self, _self);
1585
- self->enumdesc = enumdef;
1586
- return Qnil;
1587
- }
1588
-
1589
- static VALUE enumdef_add_value(VALUE enumdef,
1590
- VALUE name, VALUE number) {
1591
- rb_funcall(enumdef, rb_intern("add_value"), 2, name, number);
1592
- return Qnil;
1593
- }
1594
-
1595
- /*
1596
- * call-seq:
1597
- * EnumBuilder.add_value(name, number)
1598
- *
1599
- * Adds the given name => number mapping to the enum type. Name must be a Ruby
1600
- * symbol.
1601
- */
1602
- VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
1603
- DEFINE_SELF(EnumBuilderContext, self, _self);
1604
- return enumdef_add_value(self->enumdesc, name, number);
1208
+ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
1209
+ return get_def_obj(descriptor_pool, def, cOneofDescriptor);
1605
1210
  }
1606
1211
 
1607
1212
  // -----------------------------------------------------------------------------
1608
- // Builder.
1213
+ // Shared functions
1609
1214
  // -----------------------------------------------------------------------------
1610
1215
 
1611
- DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
1612
-
1613
- void Builder_mark(void* _self) {
1614
- Builder* self = _self;
1615
- rb_gc_mark(self->pending_list);
1616
- }
1617
-
1618
- void Builder_free(void* _self) {
1619
- Builder* self = _self;
1620
- xfree(self->defs);
1621
- xfree(self);
1622
- }
1623
-
1624
- /*
1625
- * call-seq:
1626
- * Builder.new => builder
1627
- *
1628
- * Creates a new Builder. A Builder can accumulate a set of new message and enum
1629
- * descriptors and atomically register them into a pool in a way that allows for
1630
- * (co)recursive type references.
1631
- */
1632
- VALUE Builder_alloc(VALUE klass) {
1633
- Builder* self = ALLOC(Builder);
1634
- VALUE ret = TypedData_Wrap_Struct(
1635
- klass, &_Builder_type, self);
1636
- self->pending_list = Qnil;
1637
- self->defs = NULL;
1638
- return ret;
1639
- }
1640
-
1641
- void Builder_register(VALUE module) {
1642
- VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
1643
- rb_define_alloc_func(klass, Builder_alloc);
1644
- rb_define_method(klass, "add_message", Builder_add_message, 1);
1645
- rb_define_method(klass, "add_enum", Builder_add_enum, 1);
1646
- rb_define_method(klass, "initialize", Builder_initialize, 0);
1647
- rb_define_method(klass, "finalize_to_pool", Builder_finalize_to_pool, 1);
1648
- cBuilder = klass;
1649
- rb_gc_register_address(&cBuilder);
1650
- }
1216
+ // Functions exposed to other modules in defs.h.
1651
1217
 
1652
- /*
1653
- * call-seq:
1654
- * Builder.new(d) => builder
1655
- *
1656
- * Create a new message builder.
1657
- */
1658
- VALUE Builder_initialize(VALUE _self) {
1659
- DEFINE_SELF(Builder, self, _self);
1660
- self->pending_list = rb_ary_new();
1661
- return Qnil;
1218
+ VALUE Descriptor_DefToClass(const upb_MessageDef* m) {
1219
+ const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m));
1220
+ VALUE pool = ObjectCache_Get(symtab);
1221
+ PBRUBY_ASSERT(pool != Qnil);
1222
+ VALUE desc_rb = get_msgdef_obj(pool, m);
1223
+ const Descriptor* desc = ruby_to_Descriptor(desc_rb);
1224
+ return desc->klass;
1662
1225
  }
1663
1226
 
1664
- /*
1665
- * call-seq:
1666
- * Builder.add_message(name, &block)
1667
- *
1668
- * Creates a new, empty descriptor with the given name, and invokes the block in
1669
- * the context of a MessageBuilderContext on that descriptor. The block can then
1670
- * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
1671
- * methods to define the message fields.
1672
- *
1673
- * This is the recommended, idiomatic way to build message definitions.
1674
- */
1675
- VALUE Builder_add_message(VALUE _self, VALUE name) {
1676
- DEFINE_SELF(Builder, self, _self);
1677
- VALUE msgdef = rb_class_new_instance(0, NULL, cDescriptor);
1678
- VALUE args[2] = { msgdef, _self };
1679
- VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
1680
- VALUE block = rb_block_proc();
1681
- rb_funcall(msgdef, rb_intern("name="), 1, name);
1682
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1683
- rb_ary_push(self->pending_list, msgdef);
1684
- return Qnil;
1227
+ const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb) {
1228
+ const Descriptor* desc = ruby_to_Descriptor(desc_rb);
1229
+ return desc->msgdef;
1685
1230
  }
1686
1231
 
1687
- /*
1688
- * call-seq:
1689
- * Builder.add_enum(name, &block)
1690
- *
1691
- * Creates a new, empty enum descriptor with the given name, and invokes the
1692
- * block in the context of an EnumBuilderContext on that descriptor. The block
1693
- * can then call EnumBuilderContext#add_value to define the enum values.
1694
- *
1695
- * This is the recommended, idiomatic way to build enum definitions.
1696
- */
1697
- VALUE Builder_add_enum(VALUE _self, VALUE name) {
1698
- DEFINE_SELF(Builder, self, _self);
1699
- VALUE enumdef = rb_class_new_instance(0, NULL, cEnumDescriptor);
1700
- VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
1701
- VALUE block = rb_block_proc();
1702
- rb_funcall(enumdef, rb_intern("name="), 1, name);
1703
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1704
- rb_ary_push(self->pending_list, enumdef);
1705
- return Qnil;
1706
- }
1707
-
1708
- static void validate_msgdef(const upb_msgdef* msgdef) {
1709
- // Verify that no required fields exist. proto3 does not support these.
1710
- upb_msg_field_iter it;
1711
- for (upb_msg_field_begin(&it, msgdef);
1712
- !upb_msg_field_done(&it);
1713
- upb_msg_field_next(&it)) {
1714
- const upb_fielddef* field = upb_msg_iter_field(&it);
1715
- if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
1716
- rb_raise(rb_eTypeError, "Required fields are unsupported in proto3.");
1232
+ VALUE TypeInfo_InitArg(int argc, VALUE* argv, int skip_arg) {
1233
+ if (argc > skip_arg) {
1234
+ if (argc > 1 + skip_arg) {
1235
+ rb_raise(rb_eArgError, "Expected a maximum of %d arguments.",
1236
+ skip_arg + 1);
1717
1237
  }
1238
+ return argv[skip_arg];
1239
+ } else {
1240
+ return Qnil;
1718
1241
  }
1719
1242
  }
1720
1243
 
1721
- static void validate_enumdef(const upb_enumdef* enumdef) {
1722
- // Verify that an entry exists with integer value 0. (This is the default
1723
- // value.)
1724
- const char* lookup = upb_enumdef_iton(enumdef, 0);
1725
- if (lookup == NULL) {
1726
- rb_raise(rb_eTypeError,
1727
- "Enum definition does not contain a value for '0'.");
1728
- }
1729
- }
1244
+ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
1245
+ VALUE* type_class, VALUE* init_arg) {
1246
+ TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])};
1730
1247
 
1731
- /*
1732
- * call-seq:
1733
- * Builder.finalize_to_pool(pool)
1734
- *
1735
- * Adds all accumulated message and enum descriptors created in this builder
1736
- * context to the given pool. The operation occurs atomically, and all
1737
- * descriptors can refer to each other (including in cycles). This is the only
1738
- * way to build (co)recursive message definitions.
1739
- *
1740
- * This method is usually called automatically by DescriptorPool#build after it
1741
- * invokes the given user block in the context of the builder. The user should
1742
- * not normally need to call this manually because a Builder is not normally
1743
- * created manually.
1744
- */
1745
- VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb) {
1746
- DEFINE_SELF(Builder, self, _self);
1248
+ if (ret.type == kUpb_CType_Message || ret.type == kUpb_CType_Enum) {
1249
+ *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2);
1747
1250
 
1748
- DescriptorPool* pool = ruby_to_DescriptorPool(pool_rb);
1251
+ if (argc < 2 + skip_arg) {
1252
+ rb_raise(rb_eArgError, "Expected at least %d arguments for message/enum.",
1253
+ 2 + skip_arg);
1254
+ }
1749
1255
 
1750
- REALLOC_N(self->defs, upb_def*, RARRAY_LEN(self->pending_list));
1256
+ VALUE klass = argv[1 + skip_arg];
1257
+ VALUE desc = MessageOrEnum_GetDescriptor(klass);
1258
+ *type_class = klass;
1751
1259
 
1752
- for (int i = 0; i < RARRAY_LEN(self->pending_list); i++) {
1753
- VALUE def_rb = rb_ary_entry(self->pending_list, i);
1754
- if (CLASS_OF(def_rb) == cDescriptor) {
1755
- self->defs[i] = (upb_def*)ruby_to_Descriptor(def_rb)->msgdef;
1756
- validate_msgdef((const upb_msgdef*)self->defs[i]);
1757
- } else if (CLASS_OF(def_rb) == cEnumDescriptor) {
1758
- self->defs[i] = (upb_def*)ruby_to_EnumDescriptor(def_rb)->enumdef;
1759
- validate_enumdef((const upb_enumdef*)self->defs[i]);
1260
+ if (desc == Qnil) {
1261
+ rb_raise(rb_eArgError,
1262
+ "Type class has no descriptor. Please pass a "
1263
+ "class or enum as returned by the DescriptorPool.");
1760
1264
  }
1265
+
1266
+ if (ret.type == kUpb_CType_Message) {
1267
+ ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef;
1268
+ Message_CheckClass(klass);
1269
+ } else {
1270
+ PBRUBY_ASSERT(ret.type == kUpb_CType_Enum);
1271
+ ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef;
1272
+ }
1273
+ } else {
1274
+ *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 1);
1761
1275
  }
1762
1276
 
1763
- CHECK_UPB(upb_symtab_add(pool->symtab, (upb_def**)self->defs,
1764
- RARRAY_LEN(self->pending_list), NULL, &status),
1765
- "Unable to add defs to DescriptorPool");
1277
+ return ret;
1278
+ }
1766
1279
 
1767
- for (int i = 0; i < RARRAY_LEN(self->pending_list); i++) {
1768
- VALUE def_rb = rb_ary_entry(self->pending_list, i);
1769
- add_def_obj(self->defs[i], def_rb);
1770
- }
1280
+ void Defs_register(VALUE module) {
1281
+ DescriptorPool_register(module);
1282
+ Descriptor_register(module);
1283
+ FileDescriptor_register(module);
1284
+ FieldDescriptor_register(module);
1285
+ OneofDescriptor_register(module);
1286
+ EnumDescriptor_register(module);
1771
1287
 
1772
- self->pending_list = rb_ary_new();
1773
- return Qnil;
1288
+ rb_gc_register_address(&c_only_cookie);
1289
+ c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);
1774
1290
  }