google-protobuf 3.9.2 → 3.10.0.rc.1

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

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5c195b54c2ae6902acfe99c8d060e4789b535abc877641e735091218fddc382
4
- data.tar.gz: bb3fde93da214d7b549536fe7920e32f5d21c17b8f42a44cc50ed51116cc1fa2
3
+ metadata.gz: 49f7aab0e975e52186fdce82e0f544b06a9110506258f8d9eaa564197ac3c26f
4
+ data.tar.gz: 4fbcf3a34dec8ed7070acc7ad218c622d6d837ee722913be0add378f3b7c565b
5
5
  SHA512:
6
- metadata.gz: 0d8cf6b764e568c3df5d8f5e7496ca67d989b626bbd2e3ded9661412e54b11eceb39552e4f238ed79696dc38e4de1152c766932f52873e3fc86bb2458dc0eeff
7
- data.tar.gz: d5e538a5926cf80ef1c5786fe90a2e521c94edd92a399e322435f36e231a23549485dab33aa1784379d0debd67ff3467df4dd259e5ceec7d8c6541fff0c20ae6
6
+ metadata.gz: fdcfa42deaef090c93599530d259535d814befff20957d5f1fd2375c908b892bfc87d796db32b90d0002dc178c5f31ccbf5ca3449a9a58e1e114f7e16b9c7010
7
+ data.tar.gz: 066fa3dc9926d45b77b9ded8eee63672d07317daf27af727a7ba4f541a9cb21ad8950ecc87397094c3276af488560224c624382d529a32ae10b297f526eb154a
@@ -28,6 +28,8 @@
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>
31
33
  #include "protobuf.h"
32
34
 
33
35
  // -----------------------------------------------------------------------------
@@ -46,29 +48,290 @@ static VALUE rb_str_maybe_null(const char* s) {
46
48
  return rb_str_new2(s);
47
49
  }
48
50
 
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.");
51
+ static void rewrite_enum_default(const upb_symtab* symtab,
52
+ google_protobuf_FileDescriptorProto* file,
53
+ google_protobuf_FieldDescriptorProto* field) {
54
+ upb_strview defaultval;
55
+ const char *type_name_str;
56
+ char *end;
57
+ long val;
58
+ const upb_enumdef *e;
59
+ upb_strview type_name;
60
+
61
+ /* Look for TYPE_ENUM fields that have a default. */
62
+ if (google_protobuf_FieldDescriptorProto_type(field) !=
63
+ google_protobuf_FieldDescriptorProto_TYPE_ENUM ||
64
+ !google_protobuf_FieldDescriptorProto_has_default_value(field) ||
65
+ !google_protobuf_FieldDescriptorProto_has_type_name(field)) {
66
+ return;
54
67
  }
55
- return (upb_def*)def;
56
- }
57
68
 
58
- static upb_msgdef* check_msg_notfrozen(const upb_msgdef* def) {
59
- return upb_downcast_msgdef_mutable(check_notfrozen((const upb_def*)def));
69
+ defaultval = google_protobuf_FieldDescriptorProto_default_value(field);
70
+ type_name = google_protobuf_FieldDescriptorProto_type_name(field);
71
+
72
+ if (defaultval.size == 0 || !isdigit(defaultval.data[0])) {
73
+ return;
74
+ }
75
+
76
+ if (type_name.size == 0 || type_name.data[0] != '.') {
77
+ return;
78
+ }
79
+
80
+ type_name_str = type_name.data + 1;
81
+
82
+ errno = 0;
83
+ val = strtol(defaultval.data, &end, 10);
84
+
85
+ if (errno != 0 || *end != 0 || val < INT32_MIN || val > INT32_MAX) {
86
+ return;
87
+ }
88
+
89
+ /* Now find the corresponding enum definition. */
90
+ e = upb_symtab_lookupenum(symtab, type_name_str);
91
+ if (e) {
92
+ /* Look in previously loaded files. */
93
+ const char *label = upb_enumdef_iton(e, val);
94
+ if (!label) {
95
+ return;
96
+ }
97
+ google_protobuf_FieldDescriptorProto_set_default_value(
98
+ field, upb_strview_makez(label));
99
+ } else {
100
+ /* Look in enums defined in this file. */
101
+ const google_protobuf_EnumDescriptorProto* matching_enum = NULL;
102
+ size_t i, n;
103
+ const google_protobuf_EnumDescriptorProto* const* enums =
104
+ google_protobuf_FileDescriptorProto_enum_type(file, &n);
105
+ const google_protobuf_EnumValueDescriptorProto* const* values;
106
+
107
+ for (i = 0; i < n; i++) {
108
+ if (upb_strview_eql(google_protobuf_EnumDescriptorProto_name(enums[i]),
109
+ upb_strview_makez(type_name_str))) {
110
+ matching_enum = enums[i];
111
+ break;
112
+ }
113
+ }
114
+
115
+ if (!matching_enum) {
116
+ return;
117
+ }
118
+
119
+ values = google_protobuf_EnumDescriptorProto_value(matching_enum, &n);
120
+ for (i = 0; i < n; i++) {
121
+ if (google_protobuf_EnumValueDescriptorProto_number(values[i]) == val) {
122
+ google_protobuf_FieldDescriptorProto_set_default_value(
123
+ field, google_protobuf_EnumValueDescriptorProto_name(values[i]));
124
+ return;
125
+ }
126
+ }
127
+
128
+ /* We failed to find an enum default. But we'll just leave the enum
129
+ * untouched and let the normal def-building code catch it. */
130
+ }
60
131
  }
61
132
 
62
- static upb_fielddef* check_field_notfrozen(const upb_fielddef* def) {
63
- return upb_downcast_fielddef_mutable(check_notfrozen((const upb_def*)def));
133
+ /* Historically we allowed enum defaults to be specified as a number. In
134
+ * retrospect this was a mistake as descriptors require defaults to be
135
+ * specified as a label. This can make a difference if multiple labels have the
136
+ * same number.
137
+ *
138
+ * Here we do a pass over all enum defaults and rewrite numeric defaults by
139
+ * looking up their labels. This is compilcated by the fact that the enum
140
+ * definition can live in either the symtab or the file_proto.
141
+ * */
142
+ static void rewrite_enum_defaults(
143
+ const upb_symtab* symtab, google_protobuf_FileDescriptorProto* file_proto) {
144
+ size_t i, n;
145
+ google_protobuf_DescriptorProto** msgs =
146
+ google_protobuf_FileDescriptorProto_mutable_message_type(file_proto, &n);
147
+
148
+ for (i = 0; i < n; i++) {
149
+ size_t j, m;
150
+ google_protobuf_FieldDescriptorProto** fields =
151
+ google_protobuf_DescriptorProto_mutable_field(msgs[i], &m);
152
+ for (j = 0; j < m; j++) {
153
+ rewrite_enum_default(symtab, file_proto, fields[j]);
154
+ }
155
+ }
64
156
  }
65
157
 
66
- static upb_oneofdef* check_oneof_notfrozen(const upb_oneofdef* def) {
67
- return (upb_oneofdef*)check_notfrozen((const upb_def*)def);
158
+ static void remove_path(upb_strview *name) {
159
+ const char* last = strrchr(name->data, '.');
160
+ if (last) {
161
+ size_t remove = last - name->data + 1;
162
+ name->data += remove;
163
+ name->size -= remove;
164
+ }
165
+ }
166
+
167
+ static void rewrite_nesting(VALUE msg_ent, google_protobuf_DescriptorProto* msg,
168
+ google_protobuf_DescriptorProto* const* msgs,
169
+ google_protobuf_EnumDescriptorProto* const* enums,
170
+ upb_arena *arena) {
171
+ VALUE submsgs = rb_hash_aref(msg_ent, ID2SYM(rb_intern("msgs")));
172
+ VALUE enum_pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("enums")));
173
+ int submsg_count;
174
+ int enum_count;
175
+ int i;
176
+ google_protobuf_DescriptorProto** msg_msgs;
177
+ google_protobuf_EnumDescriptorProto** msg_enums;
178
+
179
+ Check_Type(submsgs, T_ARRAY);
180
+ Check_Type(enum_pos, T_ARRAY);
181
+
182
+ submsg_count = RARRAY_LEN(submsgs);
183
+ enum_count = RARRAY_LEN(enum_pos);
184
+
185
+ msg_msgs = google_protobuf_DescriptorProto_resize_nested_type(
186
+ msg, submsg_count, arena);
187
+ msg_enums =
188
+ google_protobuf_DescriptorProto_resize_enum_type(msg, enum_count, arena);
189
+
190
+ for (i = 0; i < submsg_count; i++) {
191
+ VALUE submsg_ent = RARRAY_PTR(submsgs)[i];
192
+ VALUE pos = rb_hash_aref(submsg_ent, ID2SYM(rb_intern("pos")));
193
+ upb_strview name;
194
+
195
+ msg_msgs[i] = msgs[NUM2INT(pos)];
196
+ name = google_protobuf_DescriptorProto_name(msg_msgs[i]);
197
+ remove_path(&name);
198
+ google_protobuf_DescriptorProto_set_name(msg_msgs[i], name);
199
+ rewrite_nesting(submsg_ent, msg_msgs[i], msgs, enums, arena);
200
+ }
201
+
202
+ for (i = 0; i < enum_count; i++) {
203
+ VALUE pos = RARRAY_PTR(enum_pos)[i];
204
+ msg_enums[i] = enums[NUM2INT(pos)];
205
+ }
68
206
  }
69
207
 
70
- static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
71
- return (upb_enumdef*)check_notfrozen((const upb_def*)def);
208
+ /* We have to do some relatively complicated logic here for backward
209
+ * compatibility.
210
+ *
211
+ * In descriptor.proto, messages are nested inside other messages if that is
212
+ * what the original .proto file looks like. For example, suppose we have this
213
+ * foo.proto:
214
+ *
215
+ * package foo;
216
+ * message Bar {
217
+ * message Baz {}
218
+ * }
219
+ *
220
+ * The descriptor for this must look like this:
221
+ *
222
+ * file {
223
+ * name: "test.proto"
224
+ * package: "foo"
225
+ * message_type {
226
+ * name: "Bar"
227
+ * nested_type {
228
+ * name: "Baz"
229
+ * }
230
+ * }
231
+ * }
232
+ *
233
+ * However, the Ruby generated code has always generated messages in a flat,
234
+ * non-nested way:
235
+ *
236
+ * Google::Protobuf::DescriptorPool.generated_pool.build do
237
+ * add_message "foo.Bar" do
238
+ * end
239
+ * add_message "foo.Bar.Baz" do
240
+ * end
241
+ * end
242
+ *
243
+ * Here we need to do a translation where we turn this generated code into the
244
+ * above descriptor. We need to infer that "foo" is the package name, and not
245
+ * a message itself.
246
+ *
247
+ * We delegate to Ruby to compute the transformation, for more concice and
248
+ * readable code than we can do in C */
249
+ static void rewrite_names(VALUE _file_builder,
250
+ google_protobuf_FileDescriptorProto* file_proto) {
251
+ FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
252
+ upb_arena *arena = file_builder->arena;
253
+ // Build params (package, msg_names, enum_names).
254
+ VALUE package = Qnil;
255
+ VALUE msg_names = rb_ary_new();
256
+ VALUE enum_names = rb_ary_new();
257
+ size_t msg_count, enum_count, i;
258
+ VALUE new_package, nesting, msg_ents, enum_ents;
259
+ google_protobuf_DescriptorProto** msgs;
260
+ google_protobuf_EnumDescriptorProto** enums;
261
+
262
+ if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
263
+ upb_strview package_str =
264
+ google_protobuf_FileDescriptorProto_package(file_proto);
265
+ package = rb_str_new(package_str.data, package_str.size);
266
+ }
267
+
268
+ msgs = google_protobuf_FileDescriptorProto_mutable_message_type(file_proto,
269
+ &msg_count);
270
+ for (i = 0; i < msg_count; i++) {
271
+ upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
272
+ rb_ary_push(msg_names, rb_str_new(name.data, name.size));
273
+ }
274
+
275
+ enums = google_protobuf_FileDescriptorProto_mutable_enum_type(file_proto,
276
+ &enum_count);
277
+ for (i = 0; i < enum_count; i++) {
278
+ upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
279
+ rb_ary_push(enum_names, rb_str_new(name.data, name.size));
280
+ }
281
+
282
+ {
283
+ // Call Ruby code to calculate package name and nesting.
284
+ VALUE args[3] = { package, msg_names, enum_names };
285
+ VALUE internal = rb_eval_string("Google::Protobuf::Internal");
286
+ VALUE ret = rb_funcallv(internal, rb_intern("fixup_descriptor"), 3, args);
287
+
288
+ new_package = rb_ary_entry(ret, 0);
289
+ nesting = rb_ary_entry(ret, 1);
290
+ }
291
+
292
+ // Rewrite package and names.
293
+ if (new_package != Qnil) {
294
+ upb_strview new_package_str =
295
+ FileBuilderContext_strdup(_file_builder, new_package);
296
+ google_protobuf_FileDescriptorProto_set_package(file_proto,
297
+ new_package_str);
298
+ }
299
+
300
+ for (i = 0; i < msg_count; i++) {
301
+ upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
302
+ remove_path(&name);
303
+ google_protobuf_DescriptorProto_set_name(msgs[i], name);
304
+ }
305
+
306
+ for (i = 0; i < enum_count; i++) {
307
+ upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
308
+ remove_path(&name);
309
+ google_protobuf_EnumDescriptorProto_set_name(enums[i], name);
310
+ }
311
+
312
+ // Rewrite nesting.
313
+ msg_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("msgs")));
314
+ enum_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("enums")));
315
+
316
+ Check_Type(msg_ents, T_ARRAY);
317
+ Check_Type(enum_ents, T_ARRAY);
318
+
319
+ for (i = 0; i < (size_t)RARRAY_LEN(msg_ents); i++) {
320
+ VALUE msg_ent = rb_ary_entry(msg_ents, i);
321
+ VALUE pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("pos")));
322
+ msgs[i] = msgs[NUM2INT(pos)];
323
+ rewrite_nesting(msg_ent, msgs[i], msgs, enums, arena);
324
+ }
325
+
326
+ for (i = 0; i < (size_t)RARRAY_LEN(enum_ents); i++) {
327
+ VALUE enum_pos = rb_ary_entry(enum_ents, i);
328
+ enums[i] = enums[NUM2INT(enum_pos)];
329
+ }
330
+
331
+ google_protobuf_FileDescriptorProto_resize_message_type(
332
+ file_proto, RARRAY_LEN(msg_ents), arena);
333
+ google_protobuf_FileDescriptorProto_resize_enum_type(
334
+ file_proto, RARRAY_LEN(enum_ents), arena);
72
335
  }
73
336
 
74
337
  // -----------------------------------------------------------------------------
@@ -92,16 +355,26 @@ static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
92
355
 
93
356
  // Global singleton DescriptorPool. The user is free to create others, but this
94
357
  // is used by generated code.
95
- VALUE generated_pool;
358
+ VALUE generated_pool = Qnil;
96
359
 
97
360
  DEFINE_CLASS(DescriptorPool, "Google::Protobuf::DescriptorPool");
98
361
 
99
362
  void DescriptorPool_mark(void* _self) {
363
+ DescriptorPool* self = _self;
364
+ rb_gc_mark(self->def_to_descriptor);
100
365
  }
101
366
 
102
367
  void DescriptorPool_free(void* _self) {
103
368
  DescriptorPool* self = _self;
369
+
104
370
  upb_symtab_free(self->symtab);
371
+ upb_handlercache_free(self->fill_handler_cache);
372
+ upb_handlercache_free(self->pb_serialize_handler_cache);
373
+ upb_handlercache_free(self->json_serialize_handler_cache);
374
+ upb_handlercache_free(self->json_serialize_handler_preserve_cache);
375
+ upb_pbcodecache_free(self->fill_method_cache);
376
+ upb_json_codecache_free(self->json_fill_method_cache);
377
+
105
378
  xfree(self);
106
379
  }
107
380
 
@@ -113,15 +386,29 @@ void DescriptorPool_free(void* _self) {
113
386
  */
114
387
  VALUE DescriptorPool_alloc(VALUE klass) {
115
388
  DescriptorPool* self = ALLOC(DescriptorPool);
389
+ VALUE ret;
390
+
391
+ self->def_to_descriptor = Qnil;
392
+ ret = TypedData_Wrap_Struct(klass, &_DescriptorPool_type, self);
393
+
394
+ self->def_to_descriptor = rb_hash_new();
116
395
  self->symtab = upb_symtab_new();
117
- return TypedData_Wrap_Struct(klass, &_DescriptorPool_type, self);
396
+ self->fill_handler_cache =
397
+ upb_handlercache_new(add_handlers_for_message, (void*)ret);
398
+ self->pb_serialize_handler_cache = upb_pb_encoder_newcache();
399
+ self->json_serialize_handler_cache = upb_json_printer_newcache(false);
400
+ self->json_serialize_handler_preserve_cache =
401
+ upb_json_printer_newcache(true);
402
+ self->fill_method_cache = upb_pbcodecache_new(self->fill_handler_cache);
403
+ self->json_fill_method_cache = upb_json_codecache_new();
404
+
405
+ return ret;
118
406
  }
119
407
 
120
408
  void DescriptorPool_register(VALUE module) {
121
409
  VALUE klass = rb_define_class_under(
122
410
  module, "DescriptorPool", rb_cObject);
123
411
  rb_define_alloc_func(klass, DescriptorPool_alloc);
124
- rb_define_method(klass, "add", DescriptorPool_add, 1);
125
412
  rb_define_method(klass, "build", DescriptorPool_build, -1);
126
413
  rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
127
414
  rb_define_singleton_method(klass, "generated_pool",
@@ -133,44 +420,6 @@ void DescriptorPool_register(VALUE module) {
133
420
  generated_pool = rb_class_new_instance(0, NULL, klass);
134
421
  }
135
422
 
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
- }
143
-
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");
150
- }
151
-
152
- /*
153
- * call-seq:
154
- * DescriptorPool.add(descriptor)
155
- *
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.
159
- */
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.");
170
- }
171
- return Qnil;
172
- }
173
-
174
423
  /*
175
424
  * call-seq:
176
425
  * DescriptorPool.build(&block)
@@ -182,10 +431,10 @@ VALUE DescriptorPool_add(VALUE _self, VALUE def) {
182
431
  * idiomatic way to define new message and enum types.
183
432
  */
184
433
  VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
185
- VALUE ctx = rb_class_new_instance(0, NULL, cBuilder);
434
+ VALUE ctx = rb_class_new_instance(1, &_self, cBuilder);
186
435
  VALUE block = rb_block_proc();
187
436
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
188
- rb_funcall(ctx, rb_intern("finalize_to_pool"), 1, _self);
437
+ Builder_build(ctx);
189
438
  return Qnil;
190
439
  }
191
440
 
@@ -199,11 +448,20 @@ VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
199
448
  VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
200
449
  DEFINE_SELF(DescriptorPool, self, _self);
201
450
  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;
451
+ const upb_msgdef* msgdef;
452
+ const upb_enumdef* enumdef;
453
+
454
+ msgdef = upb_symtab_lookupmsg(self->symtab, name_str);
455
+ if (msgdef) {
456
+ return get_msgdef_obj(_self, msgdef);
205
457
  }
206
- return get_def_obj(def);
458
+
459
+ enumdef = upb_symtab_lookupenum(self->symtab, name_str);
460
+ if (enumdef) {
461
+ return get_enumdef_obj(_self, enumdef);
462
+ }
463
+
464
+ return Qnil;
207
465
  }
208
466
 
209
467
  /*
@@ -228,36 +486,17 @@ DEFINE_CLASS(Descriptor, "Google::Protobuf::Descriptor");
228
486
  void Descriptor_mark(void* _self) {
229
487
  Descriptor* self = _self;
230
488
  rb_gc_mark(self->klass);
489
+ rb_gc_mark(self->descriptor_pool);
490
+ if (self->layout && self->layout->empty_template) {
491
+ layout_mark(self->layout, self->layout->empty_template);
492
+ }
231
493
  }
232
494
 
233
495
  void Descriptor_free(void* _self) {
234
496
  Descriptor* self = _self;
235
- upb_msgdef_unref(self->msgdef, &self->msgdef);
236
497
  if (self->layout) {
237
498
  free_layout(self->layout);
238
499
  }
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
500
  xfree(self);
262
501
  }
263
502
 
@@ -273,15 +512,10 @@ void Descriptor_free(void* _self) {
273
512
  VALUE Descriptor_alloc(VALUE klass) {
274
513
  Descriptor* self = ALLOC(Descriptor);
275
514
  VALUE ret = TypedData_Wrap_Struct(klass, &_Descriptor_type, self);
276
- self->msgdef = upb_msgdef_new(&self->msgdef);
515
+ self->msgdef = NULL;
277
516
  self->klass = Qnil;
517
+ self->descriptor_pool = Qnil;
278
518
  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;
285
519
  return ret;
286
520
  }
287
521
 
@@ -289,16 +523,13 @@ void Descriptor_register(VALUE module) {
289
523
  VALUE klass = rb_define_class_under(
290
524
  module, "Descriptor", rb_cObject);
291
525
  rb_define_alloc_func(klass, Descriptor_alloc);
292
- rb_define_method(klass, "initialize", Descriptor_initialize, 1);
526
+ rb_define_method(klass, "initialize", Descriptor_initialize, 3);
293
527
  rb_define_method(klass, "each", Descriptor_each, 0);
294
528
  rb_define_method(klass, "lookup", Descriptor_lookup, 1);
295
- rb_define_method(klass, "add_field", Descriptor_add_field, 1);
296
- rb_define_method(klass, "add_oneof", Descriptor_add_oneof, 1);
297
529
  rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
298
530
  rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
299
531
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
300
532
  rb_define_method(klass, "name", Descriptor_name, 0);
301
- rb_define_method(klass, "name=", Descriptor_name_set, 1);
302
533
  rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
303
534
  rb_include_module(klass, rb_mEnumerable);
304
535
  rb_gc_register_address(&cDescriptor);
@@ -307,19 +538,21 @@ void Descriptor_register(VALUE module) {
307
538
 
308
539
  /*
309
540
  * call-seq:
310
- * Descriptor.new(file_descriptor)
541
+ * Descriptor.new(c_only_cookie, ptr) => Descriptor
311
542
  *
312
- * Initializes a new descriptor and assigns a file descriptor to it.
543
+ * Creates a descriptor wrapper object. May only be called from C.
313
544
  */
314
- VALUE Descriptor_initialize(VALUE _self, VALUE file_descriptor_rb) {
545
+ VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
546
+ VALUE descriptor_pool, VALUE ptr) {
315
547
  DEFINE_SELF(Descriptor, self, _self);
316
548
 
317
- FileDescriptor* file_descriptor = ruby_to_FileDescriptor(file_descriptor_rb);
549
+ if (cookie != c_only_cookie) {
550
+ rb_raise(rb_eRuntimeError,
551
+ "Descriptor objects may not be created from Ruby.");
552
+ }
318
553
 
319
- CHECK_UPB(
320
- upb_filedef_addmsg(file_descriptor->filedef, self->msgdef, NULL, &status),
321
- "Failed to associate message to file descriptor.");
322
- add_def_obj(file_descriptor->filedef, file_descriptor_rb);
554
+ self->descriptor_pool = descriptor_pool;
555
+ self->msgdef = (const upb_msgdef*)NUM2ULL(ptr);
323
556
 
324
557
  return Qnil;
325
558
  }
@@ -332,7 +565,7 @@ VALUE Descriptor_initialize(VALUE _self, VALUE file_descriptor_rb) {
332
565
  */
333
566
  VALUE Descriptor_file_descriptor(VALUE _self) {
334
567
  DEFINE_SELF(Descriptor, self, _self);
335
- return get_def_obj(upb_def_file(self->msgdef));
568
+ return get_filedef_obj(self->descriptor_pool, upb_msgdef_file(self->msgdef));
336
569
  }
337
570
 
338
571
  /*
@@ -347,23 +580,6 @@ VALUE Descriptor_name(VALUE _self) {
347
580
  return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
348
581
  }
349
582
 
350
- /*
351
- * call-seq:
352
- * Descriptor.name = name
353
- *
354
- * Assigns a name to this message type. The descriptor must not have been added
355
- * to a pool yet.
356
- */
357
- VALUE Descriptor_name_set(VALUE _self, VALUE str) {
358
- DEFINE_SELF(Descriptor, self, _self);
359
- upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
360
- const char* name = get_str(str);
361
- CHECK_UPB(
362
- upb_msgdef_setfullname(mut_def, name, &status),
363
- "Error setting Descriptor name");
364
- return Qnil;
365
- }
366
-
367
583
  /*
368
584
  * call-seq:
369
585
  * Descriptor.each(&block)
@@ -378,7 +594,7 @@ VALUE Descriptor_each(VALUE _self) {
378
594
  !upb_msg_field_done(&it);
379
595
  upb_msg_field_next(&it)) {
380
596
  const upb_fielddef* field = upb_msg_iter_field(&it);
381
- VALUE obj = get_def_obj(field);
597
+ VALUE obj = get_fielddef_obj(self->descriptor_pool, field);
382
598
  rb_yield(obj);
383
599
  }
384
600
  return Qnil;
@@ -398,51 +614,7 @@ VALUE Descriptor_lookup(VALUE _self, VALUE name) {
398
614
  if (field == NULL) {
399
615
  return Qnil;
400
616
  }
401
- return get_def_obj(field);
402
- }
403
-
404
- /*
405
- * call-seq:
406
- * Descriptor.add_field(field) => nil
407
- *
408
- * Adds the given FieldDescriptor to this message type. This descriptor must not
409
- * have been added to a pool yet. Raises an exception if a field with the same
410
- * name or number already exists. Sub-type references (e.g. for fields of type
411
- * message) are not resolved at this point.
412
- */
413
- VALUE Descriptor_add_field(VALUE _self, VALUE obj) {
414
- DEFINE_SELF(Descriptor, self, _self);
415
- upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
416
- FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
417
- upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
418
- CHECK_UPB(
419
- upb_msgdef_addfield(mut_def, mut_field_def, NULL, &status),
420
- "Adding field to Descriptor failed");
421
- add_def_obj(def->fielddef, obj);
422
- return Qnil;
423
- }
424
-
425
- /*
426
- * call-seq:
427
- * Descriptor.add_oneof(oneof) => nil
428
- *
429
- * Adds the given OneofDescriptor to this message type. This descriptor must not
430
- * have been added to a pool yet. Raises an exception if a oneof with the same
431
- * name already exists, or if any of the oneof's fields' names or numbers
432
- * conflict with an existing field in this message type. All fields in the oneof
433
- * are added to the message descriptor. Sub-type references (e.g. for fields of
434
- * type message) are not resolved at this point.
435
- */
436
- VALUE Descriptor_add_oneof(VALUE _self, VALUE obj) {
437
- DEFINE_SELF(Descriptor, self, _self);
438
- upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
439
- OneofDescriptor* def = ruby_to_OneofDescriptor(obj);
440
- upb_oneofdef* mut_oneof_def = check_oneof_notfrozen(def->oneofdef);
441
- CHECK_UPB(
442
- upb_msgdef_addoneof(mut_def, mut_oneof_def, NULL, &status),
443
- "Adding oneof to Descriptor failed");
444
- add_def_obj(def->oneofdef, obj);
445
- return Qnil;
617
+ return get_fielddef_obj(self->descriptor_pool, field);
446
618
  }
447
619
 
448
620
  /*
@@ -460,7 +632,7 @@ VALUE Descriptor_each_oneof(VALUE _self) {
460
632
  !upb_msg_oneof_done(&it);
461
633
  upb_msg_oneof_next(&it)) {
462
634
  const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
463
- VALUE obj = get_def_obj(oneof);
635
+ VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof);
464
636
  rb_yield(obj);
465
637
  }
466
638
  return Qnil;
@@ -480,24 +652,19 @@ VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
480
652
  if (oneof == NULL) {
481
653
  return Qnil;
482
654
  }
483
- return get_def_obj(oneof);
655
+ return get_oneofdef_obj(self->descriptor_pool, oneof);
484
656
  }
485
657
 
486
658
  /*
487
659
  * call-seq:
488
660
  * Descriptor.msgclass => message_klass
489
661
  *
490
- * Returns the Ruby class created for this message type. Valid only once the
491
- * message type has been added to a pool.
662
+ * Returns the Ruby class created for this message type.
492
663
  */
493
664
  VALUE Descriptor_msgclass(VALUE _self) {
494
665
  DEFINE_SELF(Descriptor, self, _self);
495
- if (!upb_def_isfrozen((const upb_def*)self->msgdef)) {
496
- rb_raise(rb_eRuntimeError,
497
- "Cannot fetch message class from a Descriptor not yet in a pool.");
498
- }
499
666
  if (self->klass == Qnil) {
500
- self->klass = build_class_from_descriptor(self);
667
+ self->klass = build_class_from_descriptor(_self);
501
668
  }
502
669
  return self->klass;
503
670
  }
@@ -509,12 +676,20 @@ VALUE Descriptor_msgclass(VALUE _self) {
509
676
  DEFINE_CLASS(FileDescriptor, "Google::Protobuf::FileDescriptor");
510
677
 
511
678
  void FileDescriptor_mark(void* _self) {
679
+ FileDescriptor* self = _self;
680
+ rb_gc_mark(self->descriptor_pool);
512
681
  }
513
682
 
514
683
  void FileDescriptor_free(void* _self) {
515
- FileDescriptor* self = _self;
516
- upb_filedef_unref(self->filedef, &self->filedef);
517
- xfree(self);
684
+ xfree(_self);
685
+ }
686
+
687
+ VALUE FileDescriptor_alloc(VALUE klass) {
688
+ FileDescriptor* self = ALLOC(FileDescriptor);
689
+ VALUE ret = TypedData_Wrap_Struct(klass, &_FileDescriptor_type, self);
690
+ self->descriptor_pool = Qnil;
691
+ self->filedef = NULL;
692
+ return ret;
518
693
  }
519
694
 
520
695
  /*
@@ -524,64 +699,32 @@ void FileDescriptor_free(void* _self) {
524
699
  * Returns a new file descriptor. The syntax must be set before it's passed
525
700
  * to a builder.
526
701
  */
527
- VALUE FileDescriptor_alloc(VALUE klass) {
528
- FileDescriptor* self = ALLOC(FileDescriptor);
529
- VALUE ret = TypedData_Wrap_Struct(klass, &_FileDescriptor_type, self);
530
- upb_filedef* filedef = upb_filedef_new(&self->filedef);
531
- self->filedef = filedef;
532
- return ret;
702
+ VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
703
+ VALUE descriptor_pool, VALUE ptr) {
704
+ DEFINE_SELF(FileDescriptor, self, _self);
705
+
706
+ if (cookie != c_only_cookie) {
707
+ rb_raise(rb_eRuntimeError,
708
+ "Descriptor objects may not be created from Ruby.");
709
+ }
710
+
711
+ self->descriptor_pool = descriptor_pool;
712
+ self->filedef = (const upb_filedef*)NUM2ULL(ptr);
713
+
714
+ return Qnil;
533
715
  }
534
716
 
535
717
  void FileDescriptor_register(VALUE module) {
536
718
  VALUE klass = rb_define_class_under(
537
719
  module, "FileDescriptor", rb_cObject);
538
720
  rb_define_alloc_func(klass, FileDescriptor_alloc);
539
- rb_define_method(klass, "initialize", FileDescriptor_initialize, -1);
721
+ rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
540
722
  rb_define_method(klass, "name", FileDescriptor_name, 0);
541
723
  rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
542
- rb_define_method(klass, "syntax=", FileDescriptor_syntax_set, 1);
543
724
  rb_gc_register_address(&cFileDescriptor);
544
725
  cFileDescriptor = klass;
545
726
  }
546
727
 
547
- /*
548
- * call-seq:
549
- * FileDescriptor.new(name, options = nil) => file
550
- *
551
- * Initializes a new file descriptor with the given file name.
552
- * Also accepts an optional "options" hash, specifying other optional
553
- * metadata about the file. The options hash currently accepts the following
554
- * * "syntax": :proto2 or :proto3 (default: :proto3)
555
- */
556
- VALUE FileDescriptor_initialize(int argc, VALUE* argv, VALUE _self) {
557
- DEFINE_SELF(FileDescriptor, self, _self);
558
-
559
- VALUE name_rb;
560
- VALUE options = Qnil;
561
- rb_scan_args(argc, argv, "11", &name_rb, &options);
562
-
563
- if (name_rb != Qnil) {
564
- Check_Type(name_rb, T_STRING);
565
- const char* name = get_str(name_rb);
566
- CHECK_UPB(upb_filedef_setname(self->filedef, name, &status),
567
- "Error setting file name");
568
- }
569
-
570
- // Default syntax is proto3.
571
- VALUE syntax = ID2SYM(rb_intern("proto3"));
572
- if (options != Qnil) {
573
- Check_Type(options, T_HASH);
574
-
575
- if (rb_funcall(options, rb_intern("key?"), 1,
576
- ID2SYM(rb_intern("syntax"))) == Qtrue) {
577
- syntax = rb_hash_lookup(options, ID2SYM(rb_intern("syntax")));
578
- }
579
- }
580
- FileDescriptor_syntax_set(_self, syntax);
581
-
582
- return Qnil;
583
- }
584
-
585
728
  /*
586
729
  * call-seq:
587
730
  * FileDescriptor.name => name
@@ -613,31 +756,6 @@ VALUE FileDescriptor_syntax(VALUE _self) {
613
756
  }
614
757
  }
615
758
 
616
- /*
617
- * call-seq:
618
- * FileDescriptor.syntax = version
619
- *
620
- * Sets this file descriptor's syntax, can be :proto3 or :proto2.
621
- */
622
- VALUE FileDescriptor_syntax_set(VALUE _self, VALUE syntax_rb) {
623
- DEFINE_SELF(FileDescriptor, self, _self);
624
- Check_Type(syntax_rb, T_SYMBOL);
625
-
626
- upb_syntax_t syntax;
627
- if (SYM2ID(syntax_rb) == rb_intern("proto3")) {
628
- syntax = UPB_SYNTAX_PROTO3;
629
- } else if (SYM2ID(syntax_rb) == rb_intern("proto2")) {
630
- syntax = UPB_SYNTAX_PROTO2;
631
- } else {
632
- rb_raise(rb_eArgError, "Expected :proto3 or :proto3, received '%s'",
633
- rb_id2name(SYM2ID(syntax_rb)));
634
- }
635
-
636
- CHECK_UPB(upb_filedef_setsyntax(self->filedef, syntax, &status),
637
- "Error setting file syntax for proto");
638
- return Qnil;
639
- }
640
-
641
759
  // -----------------------------------------------------------------------------
642
760
  // FieldDescriptor.
643
761
  // -----------------------------------------------------------------------------
@@ -645,12 +763,12 @@ VALUE FileDescriptor_syntax_set(VALUE _self, VALUE syntax_rb) {
645
763
  DEFINE_CLASS(FieldDescriptor, "Google::Protobuf::FieldDescriptor");
646
764
 
647
765
  void FieldDescriptor_mark(void* _self) {
766
+ FieldDescriptor* self = _self;
767
+ rb_gc_mark(self->descriptor_pool);
648
768
  }
649
769
 
650
770
  void FieldDescriptor_free(void* _self) {
651
- FieldDescriptor* self = _self;
652
- upb_fielddef_unref(self->fielddef, &self->fielddef);
653
- xfree(self);
771
+ xfree(_self);
654
772
  }
655
773
 
656
774
  /*
@@ -663,9 +781,7 @@ void FieldDescriptor_free(void* _self) {
663
781
  VALUE FieldDescriptor_alloc(VALUE klass) {
664
782
  FieldDescriptor* self = ALLOC(FieldDescriptor);
665
783
  VALUE ret = TypedData_Wrap_Struct(klass, &_FieldDescriptor_type, self);
666
- upb_fielddef* fielddef = upb_fielddef_new(&self->fielddef);
667
- upb_fielddef_setpacked(fielddef, false);
668
- self->fielddef = fielddef;
784
+ self->fielddef = NULL;
669
785
  return ret;
670
786
  }
671
787
 
@@ -673,18 +789,13 @@ void FieldDescriptor_register(VALUE module) {
673
789
  VALUE klass = rb_define_class_under(
674
790
  module, "FieldDescriptor", rb_cObject);
675
791
  rb_define_alloc_func(klass, FieldDescriptor_alloc);
792
+ rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
676
793
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
677
- rb_define_method(klass, "name=", FieldDescriptor_name_set, 1);
678
794
  rb_define_method(klass, "type", FieldDescriptor_type, 0);
679
- rb_define_method(klass, "type=", FieldDescriptor_type_set, 1);
680
795
  rb_define_method(klass, "default", FieldDescriptor_default, 0);
681
- rb_define_method(klass, "default=", FieldDescriptor_default_set, 1);
682
796
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
683
- rb_define_method(klass, "label=", FieldDescriptor_label_set, 1);
684
797
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
685
- rb_define_method(klass, "number=", FieldDescriptor_number_set, 1);
686
798
  rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
687
- rb_define_method(klass, "submsg_name=", FieldDescriptor_submsg_name_set, 1);
688
799
  rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
689
800
  rb_define_method(klass, "has?", FieldDescriptor_has, 1);
690
801
  rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
@@ -696,29 +807,34 @@ void FieldDescriptor_register(VALUE module) {
696
807
 
697
808
  /*
698
809
  * call-seq:
699
- * FieldDescriptor.name => name
810
+ * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
700
811
  *
701
- * Returns the name of this field.
812
+ * Creates a descriptor wrapper object. May only be called from C.
702
813
  */
703
- VALUE FieldDescriptor_name(VALUE _self) {
814
+ VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
815
+ VALUE descriptor_pool, VALUE ptr) {
704
816
  DEFINE_SELF(FieldDescriptor, self, _self);
705
- return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
817
+
818
+ if (cookie != c_only_cookie) {
819
+ rb_raise(rb_eRuntimeError,
820
+ "Descriptor objects may not be created from Ruby.");
821
+ }
822
+
823
+ self->descriptor_pool = descriptor_pool;
824
+ self->fielddef = (const upb_fielddef*)NUM2ULL(ptr);
825
+
826
+ return Qnil;
706
827
  }
707
828
 
708
829
  /*
709
830
  * call-seq:
710
- * FieldDescriptor.name = name
831
+ * FieldDescriptor.name => name
711
832
  *
712
- * Sets the name of this field. Cannot be called once the containing message
713
- * type, if any, is added to a pool.
833
+ * Returns the name of this field.
714
834
  */
715
- VALUE FieldDescriptor_name_set(VALUE _self, VALUE str) {
835
+ VALUE FieldDescriptor_name(VALUE _self) {
716
836
  DEFINE_SELF(FieldDescriptor, self, _self);
717
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
718
- const char* name = get_str(str);
719
- CHECK_UPB(upb_fielddef_setname(mut_def, name, &status),
720
- "Error setting FieldDescriptor name");
721
- return Qnil;
837
+ return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
722
838
  }
723
839
 
724
840
  upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
@@ -831,6 +947,29 @@ VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
831
947
  return Qnil;
832
948
  }
833
949
 
950
+ VALUE ruby_to_label(VALUE label) {
951
+ upb_label_t upb_label;
952
+ bool converted = false;
953
+
954
+ #define CONVERT(upb, ruby) \
955
+ if (SYM2ID(label) == rb_intern( # ruby )) { \
956
+ upb_label = UPB_LABEL_ ## upb; \
957
+ converted = true; \
958
+ }
959
+
960
+ CONVERT(OPTIONAL, optional);
961
+ CONVERT(REQUIRED, required);
962
+ CONVERT(REPEATED, repeated);
963
+
964
+ #undef CONVERT
965
+
966
+ if (!converted) {
967
+ rb_raise(rb_eArgError, "Unknown field label.");
968
+ }
969
+
970
+ return upb_label;
971
+ }
972
+
834
973
  /*
835
974
  * call-seq:
836
975
  * FieldDescriptor.type => type
@@ -843,26 +982,9 @@ VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
843
982
  */
844
983
  VALUE FieldDescriptor_type(VALUE _self) {
845
984
  DEFINE_SELF(FieldDescriptor, self, _self);
846
- if (!upb_fielddef_typeisset(self->fielddef)) {
847
- return Qnil;
848
- }
849
985
  return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
850
986
  }
851
987
 
852
- /*
853
- * call-seq:
854
- * FieldDescriptor.type = type
855
- *
856
- * Sets this field's type. Cannot be called if field is part of a message type
857
- * already in a pool.
858
- */
859
- VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
860
- DEFINE_SELF(FieldDescriptor, self, _self);
861
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
862
- upb_fielddef_setdescriptortype(mut_def, ruby_to_descriptortype(type));
863
- return Qnil;
864
- }
865
-
866
988
  /*
867
989
  * call-seq:
868
990
  * FieldDescriptor.default => default
@@ -874,60 +996,6 @@ VALUE FieldDescriptor_default(VALUE _self) {
874
996
  return layout_get_default(self->fielddef);
875
997
  }
876
998
 
877
- /*
878
- * call-seq:
879
- * FieldDescriptor.default = default
880
- *
881
- * Sets this field's default value. Raises an exception when calling with
882
- * proto syntax 3.
883
- */
884
- VALUE FieldDescriptor_default_set(VALUE _self, VALUE default_value) {
885
- DEFINE_SELF(FieldDescriptor, self, _self);
886
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
887
-
888
- switch (upb_fielddef_type(mut_def)) {
889
- case UPB_TYPE_FLOAT:
890
- upb_fielddef_setdefaultfloat(mut_def, NUM2DBL(default_value));
891
- break;
892
- case UPB_TYPE_DOUBLE:
893
- upb_fielddef_setdefaultdouble(mut_def, NUM2DBL(default_value));
894
- break;
895
- case UPB_TYPE_BOOL:
896
- if (!RB_TYPE_P(default_value, T_TRUE) &&
897
- !RB_TYPE_P(default_value, T_FALSE) &&
898
- !RB_TYPE_P(default_value, T_NIL)) {
899
- rb_raise(cTypeError, "Expected boolean for default value.");
900
- }
901
-
902
- upb_fielddef_setdefaultbool(mut_def, RTEST(default_value));
903
- break;
904
- case UPB_TYPE_ENUM:
905
- case UPB_TYPE_INT32:
906
- upb_fielddef_setdefaultint32(mut_def, NUM2INT(default_value));
907
- break;
908
- case UPB_TYPE_INT64:
909
- upb_fielddef_setdefaultint64(mut_def, NUM2INT(default_value));
910
- break;
911
- case UPB_TYPE_UINT32:
912
- upb_fielddef_setdefaultuint32(mut_def, NUM2UINT(default_value));
913
- break;
914
- case UPB_TYPE_UINT64:
915
- upb_fielddef_setdefaultuint64(mut_def, NUM2UINT(default_value));
916
- break;
917
- case UPB_TYPE_STRING:
918
- case UPB_TYPE_BYTES:
919
- CHECK_UPB(upb_fielddef_setdefaultcstr(mut_def, StringValuePtr(default_value),
920
- &status),
921
- "Error setting default string");
922
- break;
923
- default:
924
- rb_raise(rb_eArgError, "Defaults not supported on field %s.%s",
925
- upb_fielddef_fullname(mut_def), upb_fielddef_name(mut_def));
926
- }
927
-
928
- return Qnil;
929
- }
930
-
931
999
  /*
932
1000
  * call-seq:
933
1001
  * FieldDescriptor.label => label
@@ -953,44 +1021,6 @@ VALUE FieldDescriptor_label(VALUE _self) {
953
1021
  return Qnil;
954
1022
  }
955
1023
 
956
- /*
957
- * call-seq:
958
- * FieldDescriptor.label = label
959
- *
960
- * Sets the label on this field. Cannot be called if field is part of a message
961
- * type already in a pool.
962
- */
963
- VALUE FieldDescriptor_label_set(VALUE _self, VALUE label) {
964
- DEFINE_SELF(FieldDescriptor, self, _self);
965
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
966
- upb_label_t upb_label = -1;
967
- bool converted = false;
968
-
969
- if (TYPE(label) != T_SYMBOL) {
970
- rb_raise(rb_eArgError, "Expected symbol for field label.");
971
- }
972
-
973
- #define CONVERT(upb, ruby) \
974
- if (SYM2ID(label) == rb_intern( # ruby )) { \
975
- upb_label = UPB_LABEL_ ## upb; \
976
- converted = true; \
977
- }
978
-
979
- CONVERT(OPTIONAL, optional);
980
- CONVERT(REQUIRED, required);
981
- CONVERT(REPEATED, repeated);
982
-
983
- #undef CONVERT
984
-
985
- if (!converted) {
986
- rb_raise(rb_eArgError, "Unknown field label.");
987
- }
988
-
989
- upb_fielddef_setlabel(mut_def, upb_label);
990
-
991
- return Qnil;
992
- }
993
-
994
1024
  /*
995
1025
  * call-seq:
996
1026
  * FieldDescriptor.number => number
@@ -1002,21 +1032,6 @@ VALUE FieldDescriptor_number(VALUE _self) {
1002
1032
  return INT2NUM(upb_fielddef_number(self->fielddef));
1003
1033
  }
1004
1034
 
1005
- /*
1006
- * call-seq:
1007
- * FieldDescriptor.number = number
1008
- *
1009
- * Sets the tag number for this field. Cannot be called if field is part of a
1010
- * message type already in a pool.
1011
- */
1012
- VALUE FieldDescriptor_number_set(VALUE _self, VALUE number) {
1013
- DEFINE_SELF(FieldDescriptor, self, _self);
1014
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
1015
- CHECK_UPB(upb_fielddef_setnumber(mut_def, NUM2INT(number), &status),
1016
- "Error setting field number");
1017
- return Qnil;
1018
- }
1019
-
1020
1035
  /*
1021
1036
  * call-seq:
1022
1037
  * FieldDescriptor.submsg_name => submsg_name
@@ -1028,32 +1043,16 @@ VALUE FieldDescriptor_number_set(VALUE _self, VALUE number) {
1028
1043
  */
1029
1044
  VALUE FieldDescriptor_submsg_name(VALUE _self) {
1030
1045
  DEFINE_SELF(FieldDescriptor, self, _self);
1031
- if (!upb_fielddef_hassubdef(self->fielddef)) {
1032
- return Qnil;
1033
- }
1034
- return rb_str_maybe_null(upb_fielddef_subdefname(self->fielddef));
1035
- }
1036
-
1037
- /*
1038
- * call-seq:
1039
- * FieldDescriptor.submsg_name = submsg_name
1040
- *
1041
- * Sets the name of the message or enum type corresponding to this field, if it
1042
- * is a message or enum field (respectively). This type name will be resolved
1043
- * within the context of the pool to which the containing message type is added.
1044
- * Cannot be called on field that are not of message or enum type, or on fields
1045
- * that are part of a message type already added to a pool.
1046
- */
1047
- VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
1048
- DEFINE_SELF(FieldDescriptor, self, _self);
1049
- upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
1050
- const char* str = get_str(value);
1051
- if (!upb_fielddef_hassubdef(self->fielddef)) {
1052
- rb_raise(cTypeError, "FieldDescriptor does not have subdef.");
1046
+ switch (upb_fielddef_type(self->fielddef)) {
1047
+ case UPB_TYPE_ENUM:
1048
+ return rb_str_new2(
1049
+ upb_enumdef_fullname(upb_fielddef_enumsubdef(self->fielddef)));
1050
+ case UPB_TYPE_MESSAGE:
1051
+ return rb_str_new2(
1052
+ upb_msgdef_fullname(upb_fielddef_msgsubdef(self->fielddef)));
1053
+ default:
1054
+ return Qnil;
1053
1055
  }
1054
- CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
1055
- "Error setting submessage name");
1056
- return Qnil;
1057
1056
  }
1058
1057
 
1059
1058
  /*
@@ -1067,16 +1066,16 @@ VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
1067
1066
  */
1068
1067
  VALUE FieldDescriptor_subtype(VALUE _self) {
1069
1068
  DEFINE_SELF(FieldDescriptor, self, _self);
1070
- const upb_def* def;
1071
-
1072
- if (!upb_fielddef_hassubdef(self->fielddef)) {
1073
- return Qnil;
1074
- }
1075
- def = upb_fielddef_subdef(self->fielddef);
1076
- if (def == NULL) {
1077
- return Qnil;
1069
+ switch (upb_fielddef_type(self->fielddef)) {
1070
+ case UPB_TYPE_ENUM:
1071
+ return get_enumdef_obj(self->descriptor_pool,
1072
+ upb_fielddef_enumsubdef(self->fielddef));
1073
+ case UPB_TYPE_MESSAGE:
1074
+ return get_msgdef_obj(self->descriptor_pool,
1075
+ upb_fielddef_msgsubdef(self->fielddef));
1076
+ default:
1077
+ return Qnil;
1078
1078
  }
1079
- return get_def_obj(def);
1080
1079
  }
1081
1080
 
1082
1081
  /*
@@ -1160,12 +1159,12 @@ VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
1160
1159
  DEFINE_CLASS(OneofDescriptor, "Google::Protobuf::OneofDescriptor");
1161
1160
 
1162
1161
  void OneofDescriptor_mark(void* _self) {
1162
+ OneofDescriptor* self = _self;
1163
+ rb_gc_mark(self->descriptor_pool);
1163
1164
  }
1164
1165
 
1165
1166
  void OneofDescriptor_free(void* _self) {
1166
- OneofDescriptor* self = _self;
1167
- upb_oneofdef_unref(self->oneofdef, &self->oneofdef);
1168
- xfree(self);
1167
+ xfree(_self);
1169
1168
  }
1170
1169
 
1171
1170
  /*
@@ -1178,7 +1177,8 @@ void OneofDescriptor_free(void* _self) {
1178
1177
  VALUE OneofDescriptor_alloc(VALUE klass) {
1179
1178
  OneofDescriptor* self = ALLOC(OneofDescriptor);
1180
1179
  VALUE ret = TypedData_Wrap_Struct(klass, &_OneofDescriptor_type, self);
1181
- self->oneofdef = upb_oneofdef_new(&self->oneofdef);
1180
+ self->oneofdef = NULL;
1181
+ self->descriptor_pool = Qnil;
1182
1182
  return ret;
1183
1183
  }
1184
1184
 
@@ -1186,9 +1186,8 @@ void OneofDescriptor_register(VALUE module) {
1186
1186
  VALUE klass = rb_define_class_under(
1187
1187
  module, "OneofDescriptor", rb_cObject);
1188
1188
  rb_define_alloc_func(klass, OneofDescriptor_alloc);
1189
+ rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
1189
1190
  rb_define_method(klass, "name", OneofDescriptor_name, 0);
1190
- rb_define_method(klass, "name=", OneofDescriptor_name_set, 1);
1191
- rb_define_method(klass, "add_field", OneofDescriptor_add_field, 1);
1192
1191
  rb_define_method(klass, "each", OneofDescriptor_each, 0);
1193
1192
  rb_include_module(klass, rb_mEnumerable);
1194
1193
  rb_gc_register_address(&cOneofDescriptor);
@@ -1197,55 +1196,34 @@ void OneofDescriptor_register(VALUE module) {
1197
1196
 
1198
1197
  /*
1199
1198
  * call-seq:
1200
- * OneofDescriptor.name => name
1199
+ * OneofDescriptor.new(c_only_cookie, pool, ptr) => OneofDescriptor
1201
1200
  *
1202
- * Returns the name of this oneof.
1201
+ * Creates a descriptor wrapper object. May only be called from C.
1203
1202
  */
1204
- VALUE OneofDescriptor_name(VALUE _self) {
1203
+ VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
1204
+ VALUE descriptor_pool, VALUE ptr) {
1205
1205
  DEFINE_SELF(OneofDescriptor, self, _self);
1206
- return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
1207
- }
1208
1206
 
1209
- /*
1210
- * call-seq:
1211
- * OneofDescriptor.name = name
1212
- *
1213
- * Sets a new name for this oneof. The oneof must not have been added to a
1214
- * message descriptor yet.
1215
- */
1216
- VALUE OneofDescriptor_name_set(VALUE _self, VALUE value) {
1217
- DEFINE_SELF(OneofDescriptor, self, _self);
1218
- upb_oneofdef* mut_def = check_oneof_notfrozen(self->oneofdef);
1219
- const char* str = get_str(value);
1220
- CHECK_UPB(upb_oneofdef_setname(mut_def, str, &status),
1221
- "Error setting oneof name");
1207
+ if (cookie != c_only_cookie) {
1208
+ rb_raise(rb_eRuntimeError,
1209
+ "Descriptor objects may not be created from Ruby.");
1210
+ }
1211
+
1212
+ self->descriptor_pool = descriptor_pool;
1213
+ self->oneofdef = (const upb_oneofdef*)NUM2ULL(ptr);
1214
+
1222
1215
  return Qnil;
1223
1216
  }
1224
1217
 
1225
1218
  /*
1226
1219
  * call-seq:
1227
- * OneofDescriptor.add_field(field) => nil
1228
- *
1229
- * Adds a field to this oneof. The field may have been added to this oneof in
1230
- * the past, or the message to which this oneof belongs (if any), but may not
1231
- * have already been added to any other oneof or message. Otherwise, an
1232
- * exception is raised.
1220
+ * OneofDescriptor.name => name
1233
1221
  *
1234
- * All fields added to the oneof via this method will be automatically added to
1235
- * the message to which this oneof belongs, if it belongs to one currently, or
1236
- * else will be added to any message to which the oneof is later added at the
1237
- * time that it is added.
1222
+ * Returns the name of this oneof.
1238
1223
  */
1239
- VALUE OneofDescriptor_add_field(VALUE _self, VALUE obj) {
1224
+ VALUE OneofDescriptor_name(VALUE _self) {
1240
1225
  DEFINE_SELF(OneofDescriptor, self, _self);
1241
- upb_oneofdef* mut_def = check_oneof_notfrozen(self->oneofdef);
1242
- FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
1243
- upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
1244
- CHECK_UPB(
1245
- upb_oneofdef_addfield(mut_def, mut_field_def, NULL, &status),
1246
- "Adding field to OneofDescriptor failed");
1247
- add_def_obj(def->fielddef, obj);
1248
- return Qnil;
1226
+ return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
1249
1227
  }
1250
1228
 
1251
1229
  /*
@@ -1261,7 +1239,7 @@ VALUE OneofDescriptor_each(VALUE _self, VALUE field) {
1261
1239
  !upb_oneof_done(&it);
1262
1240
  upb_oneof_next(&it)) {
1263
1241
  const upb_fielddef* f = upb_oneof_iter_field(&it);
1264
- VALUE obj = get_def_obj(f);
1242
+ VALUE obj = get_fielddef_obj(self->descriptor_pool, f);
1265
1243
  rb_yield(obj);
1266
1244
  }
1267
1245
  return Qnil;
@@ -1276,38 +1254,49 @@ DEFINE_CLASS(EnumDescriptor, "Google::Protobuf::EnumDescriptor");
1276
1254
  void EnumDescriptor_mark(void* _self) {
1277
1255
  EnumDescriptor* self = _self;
1278
1256
  rb_gc_mark(self->module);
1257
+ rb_gc_mark(self->descriptor_pool);
1279
1258
  }
1280
1259
 
1281
1260
  void EnumDescriptor_free(void* _self) {
1282
- EnumDescriptor* self = _self;
1283
- upb_enumdef_unref(self->enumdef, &self->enumdef);
1284
- xfree(self);
1261
+ xfree(_self);
1285
1262
  }
1286
1263
 
1287
- /*
1288
- * call-seq:
1289
- * EnumDescriptor.new => enum_descriptor
1290
- *
1291
- * Creates a new, empty, enum descriptor. Must be added to a pool before the
1292
- * enum type can be used. The enum type may only be modified prior to adding to
1293
- * a pool.
1294
- */
1295
1264
  VALUE EnumDescriptor_alloc(VALUE klass) {
1296
1265
  EnumDescriptor* self = ALLOC(EnumDescriptor);
1297
1266
  VALUE ret = TypedData_Wrap_Struct(klass, &_EnumDescriptor_type, self);
1298
- self->enumdef = upb_enumdef_new(&self->enumdef);
1267
+ self->enumdef = NULL;
1299
1268
  self->module = Qnil;
1269
+ self->descriptor_pool = Qnil;
1300
1270
  return ret;
1301
1271
  }
1302
1272
 
1273
+ /*
1274
+ * call-seq:
1275
+ * EnumDescriptor.new(c_only_cookie, ptr) => EnumDescriptor
1276
+ *
1277
+ * Creates a descriptor wrapper object. May only be called from C.
1278
+ */
1279
+ VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
1280
+ VALUE descriptor_pool, VALUE ptr) {
1281
+ DEFINE_SELF(EnumDescriptor, self, _self);
1282
+
1283
+ if (cookie != c_only_cookie) {
1284
+ rb_raise(rb_eRuntimeError,
1285
+ "Descriptor objects may not be created from Ruby.");
1286
+ }
1287
+
1288
+ self->descriptor_pool = descriptor_pool;
1289
+ self->enumdef = (const upb_enumdef*)NUM2ULL(ptr);
1290
+
1291
+ return Qnil;
1292
+ }
1293
+
1303
1294
  void EnumDescriptor_register(VALUE module) {
1304
1295
  VALUE klass = rb_define_class_under(
1305
1296
  module, "EnumDescriptor", rb_cObject);
1306
1297
  rb_define_alloc_func(klass, EnumDescriptor_alloc);
1307
- rb_define_method(klass, "initialize", EnumDescriptor_initialize, 1);
1298
+ rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
1308
1299
  rb_define_method(klass, "name", EnumDescriptor_name, 0);
1309
- rb_define_method(klass, "name=", EnumDescriptor_name_set, 1);
1310
- rb_define_method(klass, "add_value", EnumDescriptor_add_value, 2);
1311
1300
  rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
1312
1301
  rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
1313
1302
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
@@ -1320,31 +1309,14 @@ void EnumDescriptor_register(VALUE module) {
1320
1309
 
1321
1310
  /*
1322
1311
  * call-seq:
1323
- * Descriptor.new(file_descriptor)
1324
- *
1325
- * Initializes a new descriptor and assigns a file descriptor to it.
1326
- */
1327
- VALUE EnumDescriptor_initialize(VALUE _self, VALUE file_descriptor_rb) {
1328
- DEFINE_SELF(EnumDescriptor, self, _self);
1329
- FileDescriptor* file_descriptor = ruby_to_FileDescriptor(file_descriptor_rb);
1330
- CHECK_UPB(
1331
- upb_filedef_addenum(file_descriptor->filedef, self->enumdef,
1332
- NULL, &status),
1333
- "Failed to associate enum to file descriptor.");
1334
- add_def_obj(file_descriptor->filedef, file_descriptor_rb);
1335
-
1336
- return Qnil;
1337
- }
1338
-
1339
- /*
1340
- * call-seq:
1341
- * Descriptor.file_descriptor
1312
+ * EnumDescriptor.file_descriptor
1342
1313
  *
1343
1314
  * Returns the FileDescriptor object this enum belongs to.
1344
1315
  */
1345
1316
  VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1346
1317
  DEFINE_SELF(EnumDescriptor, self, _self);
1347
- return get_def_obj(upb_def_file(self->enumdef));
1318
+ return get_filedef_obj(self->descriptor_pool,
1319
+ upb_enumdef_file(self->enumdef));
1348
1320
  }
1349
1321
 
1350
1322
  /*
@@ -1358,40 +1330,6 @@ VALUE EnumDescriptor_name(VALUE _self) {
1358
1330
  return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
1359
1331
  }
1360
1332
 
1361
- /*
1362
- * call-seq:
1363
- * EnumDescriptor.name = name
1364
- *
1365
- * Sets the name of this enum type. Cannot be called if the enum type has
1366
- * already been added to a pool.
1367
- */
1368
- VALUE EnumDescriptor_name_set(VALUE _self, VALUE str) {
1369
- DEFINE_SELF(EnumDescriptor, self, _self);
1370
- upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
1371
- const char* name = get_str(str);
1372
- CHECK_UPB(upb_enumdef_setfullname(mut_def, name, &status),
1373
- "Error setting EnumDescriptor name");
1374
- return Qnil;
1375
- }
1376
-
1377
- /*
1378
- * call-seq:
1379
- * EnumDescriptor.add_value(key, value)
1380
- *
1381
- * Adds a new key => value mapping to this enum type. Key must be given as a
1382
- * Ruby symbol. Cannot be called if the enum type has already been added to a
1383
- * pool. Will raise an exception if the key or value is already in use.
1384
- */
1385
- VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number) {
1386
- DEFINE_SELF(EnumDescriptor, self, _self);
1387
- upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
1388
- const char* name_str = rb_id2name(SYM2ID(name));
1389
- int32_t val = NUM2INT(number);
1390
- CHECK_UPB(upb_enumdef_addval(mut_def, name_str, val, &status),
1391
- "Error adding value to enum");
1392
- return Qnil;
1393
- }
1394
-
1395
1333
  /*
1396
1334
  * call-seq:
1397
1335
  * EnumDescriptor.lookup_name(name) => value
@@ -1454,18 +1392,12 @@ VALUE EnumDescriptor_each(VALUE _self) {
1454
1392
  * call-seq:
1455
1393
  * EnumDescriptor.enummodule => module
1456
1394
  *
1457
- * Returns the Ruby module corresponding to this enum type. Cannot be called
1458
- * until the enum descriptor has been added to a pool.
1395
+ * Returns the Ruby module corresponding to this enum type.
1459
1396
  */
1460
1397
  VALUE EnumDescriptor_enummodule(VALUE _self) {
1461
1398
  DEFINE_SELF(EnumDescriptor, self, _self);
1462
- if (!upb_def_isfrozen((const upb_def*)self->enumdef)) {
1463
- rb_raise(rb_eRuntimeError,
1464
- "Cannot fetch enum module from an EnumDescriptor not yet "
1465
- "in a pool.");
1466
- }
1467
1399
  if (self->module == Qnil) {
1468
- self->module = build_module_from_enumdesc(self);
1400
+ self->module = build_module_from_enumdesc(_self);
1469
1401
  }
1470
1402
  return self->module;
1471
1403
  }
@@ -1479,8 +1411,7 @@ DEFINE_CLASS(MessageBuilderContext,
1479
1411
 
1480
1412
  void MessageBuilderContext_mark(void* _self) {
1481
1413
  MessageBuilderContext* self = _self;
1482
- rb_gc_mark(self->descriptor);
1483
- rb_gc_mark(self->builder);
1414
+ rb_gc_mark(self->file_builder);
1484
1415
  }
1485
1416
 
1486
1417
  void MessageBuilderContext_free(void* _self) {
@@ -1492,8 +1423,7 @@ VALUE MessageBuilderContext_alloc(VALUE klass) {
1492
1423
  MessageBuilderContext* self = ALLOC(MessageBuilderContext);
1493
1424
  VALUE ret = TypedData_Wrap_Struct(
1494
1425
  klass, &_MessageBuilderContext_type, self);
1495
- self->descriptor = Qnil;
1496
- self->builder = Qnil;
1426
+ self->file_builder = Qnil;
1497
1427
  return ret;
1498
1428
  }
1499
1429
 
@@ -1514,65 +1444,110 @@ void MessageBuilderContext_register(VALUE module) {
1514
1444
 
1515
1445
  /*
1516
1446
  * call-seq:
1517
- * MessageBuilderContext.new(desc, builder) => context
1447
+ * MessageBuilderContext.new(file_builder, name) => context
1518
1448
  *
1519
1449
  * Create a new message builder context around the given message descriptor and
1520
1450
  * builder context. This class is intended to serve as a DSL context to be used
1521
1451
  * with #instance_eval.
1522
1452
  */
1523
1453
  VALUE MessageBuilderContext_initialize(VALUE _self,
1524
- VALUE msgdef,
1525
- VALUE builder) {
1454
+ VALUE _file_builder,
1455
+ VALUE name) {
1526
1456
  DEFINE_SELF(MessageBuilderContext, self, _self);
1527
- self->descriptor = msgdef;
1528
- self->builder = builder;
1457
+ FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
1458
+ google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
1459
+
1460
+ self->file_builder = _file_builder;
1461
+ self->msg_proto = google_protobuf_FileDescriptorProto_add_message_type(
1462
+ file_proto, file_builder->arena);
1463
+
1464
+ google_protobuf_DescriptorProto_set_name(
1465
+ self->msg_proto, FileBuilderContext_strdup(_file_builder, name));
1466
+
1529
1467
  return Qnil;
1530
1468
  }
1531
1469
 
1532
- static VALUE msgdef_add_field(VALUE msgdef_rb,
1533
- const char* label, VALUE name,
1534
- VALUE type, VALUE number,
1535
- VALUE type_class,
1536
- VALUE options) {
1537
- VALUE fielddef_rb = rb_class_new_instance(0, NULL, cFieldDescriptor);
1538
- VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1470
+ static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
1471
+ VALUE type, VALUE number, VALUE type_class,
1472
+ VALUE options, int oneof_index) {
1473
+ DEFINE_SELF(MessageBuilderContext, self, msgbuilder_rb);
1474
+ FileBuilderContext* file_context =
1475
+ ruby_to_FileBuilderContext(self->file_builder);
1476
+ google_protobuf_FieldDescriptorProto* field_proto;
1477
+ VALUE name_str;
1478
+
1479
+ field_proto = google_protobuf_DescriptorProto_add_field(self->msg_proto,
1480
+ file_context->arena);
1481
+
1482
+ Check_Type(name, T_SYMBOL);
1483
+ name_str = rb_id2str(SYM2ID(name));
1539
1484
 
1540
- rb_funcall(fielddef_rb, rb_intern("label="), 1, ID2SYM(rb_intern(label)));
1541
- rb_funcall(fielddef_rb, rb_intern("name="), 1, name_str);
1542
- rb_funcall(fielddef_rb, rb_intern("type="), 1, type);
1543
- rb_funcall(fielddef_rb, rb_intern("number="), 1, number);
1485
+ google_protobuf_FieldDescriptorProto_set_name(
1486
+ field_proto, FileBuilderContext_strdup(self->file_builder, name_str));
1487
+ google_protobuf_FieldDescriptorProto_set_number(field_proto, NUM2INT(number));
1488
+ google_protobuf_FieldDescriptorProto_set_label(field_proto, (int)label);
1489
+ google_protobuf_FieldDescriptorProto_set_type(
1490
+ field_proto, (int)ruby_to_descriptortype(type));
1544
1491
 
1545
1492
  if (type_class != Qnil) {
1546
1493
  Check_Type(type_class, T_STRING);
1547
1494
 
1548
1495
  // Make it an absolute type name by prepending a dot.
1549
1496
  type_class = rb_str_append(rb_str_new2("."), type_class);
1550
- rb_funcall(fielddef_rb, rb_intern("submsg_name="), 1, type_class);
1497
+ google_protobuf_FieldDescriptorProto_set_type_name(
1498
+ field_proto, FileBuilderContext_strdup(self->file_builder, type_class));
1551
1499
  }
1552
1500
 
1553
1501
  if (options != Qnil) {
1554
1502
  Check_Type(options, T_HASH);
1555
1503
 
1556
1504
  if (rb_funcall(options, rb_intern("key?"), 1,
1557
- ID2SYM(rb_intern("default"))) == Qtrue) {
1558
- Descriptor* msgdef = ruby_to_Descriptor(msgdef_rb);
1559
- if (upb_msgdef_syntax((upb_msgdef*)msgdef->msgdef) == UPB_SYNTAX_PROTO3) {
1560
- rb_raise(rb_eArgError, "Cannot set :default when using proto3 syntax.");
1561
- }
1505
+ ID2SYM(rb_intern("default"))) == Qtrue) {
1506
+ VALUE default_value =
1507
+ rb_hash_lookup(options, ID2SYM(rb_intern("default")));
1562
1508
 
1563
- FieldDescriptor* fielddef = ruby_to_FieldDescriptor(fielddef_rb);
1564
- if (!upb_fielddef_haspresence((upb_fielddef*)fielddef->fielddef) ||
1565
- upb_fielddef_issubmsg((upb_fielddef*)fielddef->fielddef)) {
1566
- rb_raise(rb_eArgError, "Cannot set :default on this kind of field.");
1567
- }
1509
+ /* Call #to_s since all defaults are strings in the descriptor. */
1510
+ default_value = rb_funcall(default_value, rb_intern("to_s"), 0);
1568
1511
 
1569
- rb_funcall(fielddef_rb, rb_intern("default="), 1,
1570
- rb_hash_lookup(options, ID2SYM(rb_intern("default"))));
1512
+ google_protobuf_FieldDescriptorProto_set_default_value(
1513
+ field_proto,
1514
+ FileBuilderContext_strdup(self->file_builder, default_value));
1571
1515
  }
1572
1516
  }
1573
1517
 
1574
- rb_funcall(msgdef_rb, rb_intern("add_field"), 1, fielddef_rb);
1575
- return fielddef_rb;
1518
+ if (oneof_index >= 0) {
1519
+ google_protobuf_FieldDescriptorProto_set_oneof_index(field_proto,
1520
+ oneof_index);
1521
+ }
1522
+ }
1523
+
1524
+ static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
1525
+ VALUE* argv) {
1526
+ DEFINE_SELF(MessageBuilderContext, message_builder, _message_builder);
1527
+ VALUE type_class = rb_ary_entry(types, 2);
1528
+ FileBuilderContext* file_context =
1529
+ ruby_to_FileBuilderContext(message_builder->file_builder);
1530
+ google_protobuf_MessageOptions* options =
1531
+ google_protobuf_DescriptorProto_mutable_options(
1532
+ message_builder->msg_proto, file_context->arena);
1533
+
1534
+ google_protobuf_MessageOptions_set_map_entry(options, true);
1535
+
1536
+ // optional <type> key = 1;
1537
+ rb_funcall(_message_builder, rb_intern("optional"), 3,
1538
+ ID2SYM(rb_intern("key")), rb_ary_entry(types, 0), INT2NUM(1));
1539
+
1540
+ // optional <type> value = 2;
1541
+ if (type_class == Qnil) {
1542
+ rb_funcall(_message_builder, rb_intern("optional"), 3,
1543
+ ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2));
1544
+ } else {
1545
+ rb_funcall(_message_builder, rb_intern("optional"), 4,
1546
+ ID2SYM(rb_intern("value")), rb_ary_entry(types, 1), INT2NUM(2),
1547
+ type_class);
1548
+ }
1549
+
1550
+ return Qnil;
1576
1551
  }
1577
1552
 
1578
1553
  /*
@@ -1586,7 +1561,6 @@ static VALUE msgdef_add_field(VALUE msgdef_rb,
1586
1561
  * string, if present (as accepted by FieldDescriptor#submsg_name=).
1587
1562
  */
1588
1563
  VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1589
- DEFINE_SELF(MessageBuilderContext, self, _self);
1590
1564
  VALUE name, type, number;
1591
1565
  VALUE type_class, options = Qnil;
1592
1566
 
@@ -1599,8 +1573,10 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1599
1573
  type_class = Qnil;
1600
1574
  }
1601
1575
 
1602
- return msgdef_add_field(self->descriptor, "optional",
1603
- name, type, number, type_class, options);
1576
+ msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class,
1577
+ options, -1);
1578
+
1579
+ return Qnil;
1604
1580
  }
1605
1581
 
1606
1582
  /*
@@ -1618,7 +1594,6 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1618
1594
  * pool will currently result in an error.
1619
1595
  */
1620
1596
  VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1621
- DEFINE_SELF(MessageBuilderContext, self, _self);
1622
1597
  VALUE name, type, number;
1623
1598
  VALUE type_class, options = Qnil;
1624
1599
 
@@ -1631,8 +1606,10 @@ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1631
1606
  type_class = Qnil;
1632
1607
  }
1633
1608
 
1634
- return msgdef_add_field(self->descriptor, "required",
1635
- name, type, number, type_class, options);
1609
+ msgdef_add_field(_self, UPB_LABEL_REQUIRED, name, type, number, type_class,
1610
+ options, -1);
1611
+
1612
+ return Qnil;
1636
1613
  }
1637
1614
 
1638
1615
  /*
@@ -1645,7 +1622,6 @@ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1645
1622
  * string, if present (as accepted by FieldDescriptor#submsg_name=).
1646
1623
  */
1647
1624
  VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1648
- DEFINE_SELF(MessageBuilderContext, self, _self);
1649
1625
  VALUE name, type, number, type_class;
1650
1626
 
1651
1627
  if (argc < 3) {
@@ -1656,8 +1632,10 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1656
1632
  number = argv[2];
1657
1633
  type_class = (argc > 3) ? argv[3] : Qnil;
1658
1634
 
1659
- return msgdef_add_field(self->descriptor, "repeated",
1660
- name, type, number, type_class, Qnil);
1635
+ msgdef_add_field(_self, UPB_LABEL_REPEATED, name, type, number, type_class,
1636
+ Qnil, -1);
1637
+
1638
+ return Qnil;
1661
1639
  }
1662
1640
 
1663
1641
  /*
@@ -1675,7 +1653,9 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1675
1653
  VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1676
1654
  DEFINE_SELF(MessageBuilderContext, self, _self);
1677
1655
  VALUE name, key_type, value_type, number, type_class;
1678
- VALUE mapentry_desc, mapentry_desc_name;
1656
+ VALUE mapentry_desc_name;
1657
+ FileBuilderContext* file_builder;
1658
+ upb_strview msg_name;
1679
1659
 
1680
1660
  if (argc < 4) {
1681
1661
  rb_raise(rb_eArgError, "Expected at least 4 arguments.");
@@ -1698,77 +1678,44 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1698
1678
  "type.");
1699
1679
  }
1700
1680
 
1701
- Descriptor* descriptor = ruby_to_Descriptor(self->descriptor);
1702
- if (upb_msgdef_syntax(descriptor->msgdef) == UPB_SYNTAX_PROTO2) {
1681
+ file_builder = ruby_to_FileBuilderContext(self->file_builder);
1682
+
1683
+ // TODO(haberman): remove this restriction, maps are supported in proto2.
1684
+ if (upb_strview_eql(
1685
+ google_protobuf_FileDescriptorProto_syntax(file_builder->file_proto),
1686
+ upb_strview_makez("proto2"))) {
1703
1687
  rb_raise(rb_eArgError,
1704
- "Cannot add a native map field using proto2 syntax.");
1688
+ "Cannot add a native map field using proto2 syntax.");
1705
1689
  }
1706
1690
 
1707
1691
  // Create a new message descriptor for the map entry message, and create a
1708
1692
  // repeated submessage field here with that type.
1709
- VALUE file_descriptor_rb =
1710
- rb_funcall(self->descriptor, rb_intern("file_descriptor"), 0);
1711
- mapentry_desc = rb_class_new_instance(1, &file_descriptor_rb, cDescriptor);
1712
- mapentry_desc_name = rb_funcall(self->descriptor, rb_intern("name"), 0);
1693
+ msg_name = google_protobuf_DescriptorProto_name(self->msg_proto);
1694
+ mapentry_desc_name = rb_str_new(msg_name.data, msg_name.size);
1713
1695
  mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
1714
- mapentry_desc_name = rb_str_cat2(mapentry_desc_name,
1715
- rb_id2name(SYM2ID(name)));
1716
- Descriptor_name_set(mapentry_desc, mapentry_desc_name);
1717
-
1718
- {
1719
- // The 'mapentry' attribute has no Ruby setter because we do not want the
1720
- // user attempting to DIY the setup below; we want to ensure that the fields
1721
- // are correct. So we reach into the msgdef here to set the bit manually.
1722
- Descriptor* mapentry_desc_self = ruby_to_Descriptor(mapentry_desc);
1723
- upb_msgdef_setmapentry((upb_msgdef*)mapentry_desc_self->msgdef, true);
1724
- }
1725
-
1726
- {
1727
- // optional <type> key = 1;
1728
- VALUE key_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
1729
- FieldDescriptor_name_set(key_field, rb_str_new2("key"));
1730
- FieldDescriptor_label_set(key_field, ID2SYM(rb_intern("optional")));
1731
- FieldDescriptor_number_set(key_field, INT2NUM(1));
1732
- FieldDescriptor_type_set(key_field, key_type);
1733
- Descriptor_add_field(mapentry_desc, key_field);
1734
- }
1696
+ mapentry_desc_name =
1697
+ rb_str_cat2(mapentry_desc_name, rb_id2name(SYM2ID(name)));
1735
1698
 
1736
1699
  {
1737
- // optional <type> value = 2;
1738
- VALUE value_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
1739
- FieldDescriptor_name_set(value_field, rb_str_new2("value"));
1740
- FieldDescriptor_label_set(value_field, ID2SYM(rb_intern("optional")));
1741
- FieldDescriptor_number_set(value_field, INT2NUM(2));
1742
- FieldDescriptor_type_set(value_field, value_type);
1743
- if (type_class != Qnil) {
1744
- VALUE submsg_name = rb_str_new2("."); // prepend '.' to make absolute.
1745
- submsg_name = rb_str_append(submsg_name, type_class);
1746
- FieldDescriptor_submsg_name_set(value_field, submsg_name);
1747
- }
1748
- Descriptor_add_field(mapentry_desc, value_field);
1700
+ // message <msgname>_MapEntry_ { /* ... */ }
1701
+ VALUE args[1] = {mapentry_desc_name};
1702
+ VALUE types = rb_ary_new3(3, key_type, value_type, type_class);
1703
+ rb_block_call(self->file_builder, rb_intern("add_message"), 1, args,
1704
+ make_mapentry, types);
1749
1705
  }
1750
1706
 
1751
- {
1752
- // Add the map-entry message type to the current builder, and use the type
1753
- // to create the map field itself.
1754
- Builder* builder = ruby_to_Builder(self->builder);
1755
- rb_ary_push(builder->pending_list, mapentry_desc);
1707
+ // If this file is in a package, we need to qualify the map entry type.
1708
+ if (google_protobuf_FileDescriptorProto_has_package(file_builder->file_proto)) {
1709
+ upb_strview package_view =
1710
+ google_protobuf_FileDescriptorProto_package(file_builder->file_proto);
1711
+ VALUE package = rb_str_new(package_view.data, package_view.size);
1712
+ package = rb_str_cat2(package, ".");
1713
+ mapentry_desc_name = rb_str_concat(package, mapentry_desc_name);
1756
1714
  }
1757
1715
 
1758
- {
1759
- VALUE map_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
1760
- VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1761
- VALUE submsg_name;
1762
-
1763
- FieldDescriptor_name_set(map_field, name_str);
1764
- FieldDescriptor_number_set(map_field, number);
1765
- FieldDescriptor_label_set(map_field, ID2SYM(rb_intern("repeated")));
1766
- FieldDescriptor_type_set(map_field, ID2SYM(rb_intern("message")));
1767
- submsg_name = rb_str_new2("."); // prepend '.' to make name absolute.
1768
- submsg_name = rb_str_append(submsg_name, mapentry_desc_name);
1769
- FieldDescriptor_submsg_name_set(map_field, submsg_name);
1770
- Descriptor_add_field(self->descriptor, map_field);
1771
- }
1716
+ // repeated MapEntry <name> = <number>;
1717
+ rb_funcall(_self, rb_intern("repeated"), 4, name,
1718
+ ID2SYM(rb_intern("message")), number, mapentry_desc_name);
1772
1719
 
1773
1720
  return Qnil;
1774
1721
  }
@@ -1786,14 +1733,27 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1786
1733
  */
1787
1734
  VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
1788
1735
  DEFINE_SELF(MessageBuilderContext, self, _self);
1789
- VALUE oneofdef = rb_class_new_instance(0, NULL, cOneofDescriptor);
1790
- VALUE args[2] = { oneofdef, self->builder };
1791
- VALUE ctx = rb_class_new_instance(2, args, cOneofBuilderContext);
1792
- VALUE block = rb_block_proc();
1793
- VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1794
- rb_funcall(oneofdef, rb_intern("name="), 1, name_str);
1795
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1796
- Descriptor_add_oneof(self->descriptor, oneofdef);
1736
+ size_t oneof_count;
1737
+ FileBuilderContext* file_context =
1738
+ ruby_to_FileBuilderContext(self->file_builder);
1739
+ google_protobuf_OneofDescriptorProto* oneof_proto;
1740
+
1741
+ // Existing oneof_count becomes oneof_index.
1742
+ google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count);
1743
+
1744
+ // Create oneof_proto and set its name.
1745
+ oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl(
1746
+ self->msg_proto, file_context->arena);
1747
+ google_protobuf_OneofDescriptorProto_set_name(
1748
+ oneof_proto, FileBuilderContext_strdup_sym(self->file_builder, name));
1749
+
1750
+ // Evaluate the block with the builder as argument.
1751
+ {
1752
+ VALUE args[2] = { INT2NUM(oneof_count), _self };
1753
+ VALUE ctx = rb_class_new_instance(2, args, cOneofBuilderContext);
1754
+ VALUE block = rb_block_proc();
1755
+ rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1756
+ }
1797
1757
 
1798
1758
  return Qnil;
1799
1759
  }
@@ -1807,21 +1767,19 @@ DEFINE_CLASS(OneofBuilderContext,
1807
1767
 
1808
1768
  void OneofBuilderContext_mark(void* _self) {
1809
1769
  OneofBuilderContext* self = _self;
1810
- rb_gc_mark(self->descriptor);
1811
- rb_gc_mark(self->builder);
1770
+ rb_gc_mark(self->message_builder);
1812
1771
  }
1813
1772
 
1814
1773
  void OneofBuilderContext_free(void* _self) {
1815
- OneofBuilderContext* self = _self;
1816
- xfree(self);
1774
+ xfree(_self);
1817
1775
  }
1818
1776
 
1819
1777
  VALUE OneofBuilderContext_alloc(VALUE klass) {
1820
1778
  OneofBuilderContext* self = ALLOC(OneofBuilderContext);
1821
1779
  VALUE ret = TypedData_Wrap_Struct(
1822
1780
  klass, &_OneofBuilderContext_type, self);
1823
- self->descriptor = Qnil;
1824
- self->builder = Qnil;
1781
+ self->oneof_index = 0;
1782
+ self->message_builder = Qnil;
1825
1783
  return ret;
1826
1784
  }
1827
1785
 
@@ -1838,18 +1796,18 @@ void OneofBuilderContext_register(VALUE module) {
1838
1796
 
1839
1797
  /*
1840
1798
  * call-seq:
1841
- * OneofBuilderContext.new(desc, builder) => context
1799
+ * OneofBuilderContext.new(oneof_index, message_builder) => context
1842
1800
  *
1843
1801
  * Create a new oneof builder context around the given oneof descriptor and
1844
1802
  * builder context. This class is intended to serve as a DSL context to be used
1845
1803
  * with #instance_eval.
1846
1804
  */
1847
1805
  VALUE OneofBuilderContext_initialize(VALUE _self,
1848
- VALUE oneofdef,
1849
- VALUE builder) {
1806
+ VALUE oneof_index,
1807
+ VALUE message_builder) {
1850
1808
  DEFINE_SELF(OneofBuilderContext, self, _self);
1851
- self->descriptor = oneofdef;
1852
- self->builder = builder;
1809
+ self->oneof_index = NUM2INT(oneof_index);
1810
+ self->message_builder = message_builder;
1853
1811
  return Qnil;
1854
1812
  }
1855
1813
 
@@ -1870,8 +1828,10 @@ VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1870
1828
 
1871
1829
  rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
1872
1830
 
1873
- return msgdef_add_field(self->descriptor, "optional",
1874
- name, type, number, type_class, options);
1831
+ msgdef_add_field(self->message_builder, UPB_LABEL_OPTIONAL, name, type,
1832
+ number, type_class, options, self->oneof_index);
1833
+
1834
+ return Qnil;
1875
1835
  }
1876
1836
 
1877
1837
  // -----------------------------------------------------------------------------
@@ -1883,19 +1843,19 @@ DEFINE_CLASS(EnumBuilderContext,
1883
1843
 
1884
1844
  void EnumBuilderContext_mark(void* _self) {
1885
1845
  EnumBuilderContext* self = _self;
1886
- rb_gc_mark(self->enumdesc);
1846
+ rb_gc_mark(self->file_builder);
1887
1847
  }
1888
1848
 
1889
1849
  void EnumBuilderContext_free(void* _self) {
1890
- EnumBuilderContext* self = _self;
1891
- xfree(self);
1850
+ xfree(_self);
1892
1851
  }
1893
1852
 
1894
1853
  VALUE EnumBuilderContext_alloc(VALUE klass) {
1895
1854
  EnumBuilderContext* self = ALLOC(EnumBuilderContext);
1896
1855
  VALUE ret = TypedData_Wrap_Struct(
1897
1856
  klass, &_EnumBuilderContext_type, self);
1898
- self->enumdesc = Qnil;
1857
+ self->enum_proto = NULL;
1858
+ self->file_builder = Qnil;
1899
1859
  return ret;
1900
1860
  }
1901
1861
 
@@ -1903,8 +1863,7 @@ void EnumBuilderContext_register(VALUE module) {
1903
1863
  VALUE klass = rb_define_class_under(
1904
1864
  module, "EnumBuilderContext", rb_cObject);
1905
1865
  rb_define_alloc_func(klass, EnumBuilderContext_alloc);
1906
- rb_define_method(klass, "initialize",
1907
- EnumBuilderContext_initialize, 1);
1866
+ rb_define_method(klass, "initialize", EnumBuilderContext_initialize, 2);
1908
1867
  rb_define_method(klass, "value", EnumBuilderContext_value, 2);
1909
1868
  rb_gc_register_address(&cEnumBuilderContext);
1910
1869
  cEnumBuilderContext = klass;
@@ -1912,20 +1871,24 @@ void EnumBuilderContext_register(VALUE module) {
1912
1871
 
1913
1872
  /*
1914
1873
  * call-seq:
1915
- * EnumBuilderContext.new(enumdesc) => context
1874
+ * EnumBuilderContext.new(file_builder) => context
1916
1875
  *
1917
1876
  * Create a new builder context around the given enum descriptor. This class is
1918
1877
  * intended to serve as a DSL context to be used with #instance_eval.
1919
1878
  */
1920
- VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdef) {
1879
+ VALUE EnumBuilderContext_initialize(VALUE _self, VALUE _file_builder,
1880
+ VALUE name) {
1921
1881
  DEFINE_SELF(EnumBuilderContext, self, _self);
1922
- self->enumdesc = enumdef;
1923
- return Qnil;
1924
- }
1882
+ FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
1883
+ google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
1884
+
1885
+ self->file_builder = _file_builder;
1886
+ self->enum_proto = google_protobuf_FileDescriptorProto_add_enum_type(
1887
+ file_proto, file_builder->arena);
1888
+
1889
+ google_protobuf_EnumDescriptorProto_set_name(
1890
+ self->enum_proto, FileBuilderContext_strdup(_file_builder, name));
1925
1891
 
1926
- static VALUE enumdef_add_value(VALUE enumdef,
1927
- VALUE name, VALUE number) {
1928
- rb_funcall(enumdef, rb_intern("add_value"), 2, name, number);
1929
1892
  return Qnil;
1930
1893
  }
1931
1894
 
@@ -1938,7 +1901,19 @@ static VALUE enumdef_add_value(VALUE enumdef,
1938
1901
  */
1939
1902
  VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
1940
1903
  DEFINE_SELF(EnumBuilderContext, self, _self);
1941
- return enumdef_add_value(self->enumdesc, name, number);
1904
+ FileBuilderContext* file_builder =
1905
+ ruby_to_FileBuilderContext(self->file_builder);
1906
+ google_protobuf_EnumValueDescriptorProto* enum_value;
1907
+
1908
+ enum_value = google_protobuf_EnumDescriptorProto_add_value(
1909
+ self->enum_proto, file_builder->arena);
1910
+
1911
+ google_protobuf_EnumValueDescriptorProto_set_name(
1912
+ enum_value, FileBuilderContext_strdup_sym(self->file_builder, name));
1913
+ google_protobuf_EnumValueDescriptorProto_set_number(enum_value,
1914
+ NUM2INT(number));
1915
+
1916
+ return Qnil;
1942
1917
  }
1943
1918
 
1944
1919
 
@@ -1947,33 +1922,55 @@ VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
1947
1922
  // -----------------------------------------------------------------------------
1948
1923
 
1949
1924
  DEFINE_CLASS(FileBuilderContext,
1950
- "Google::Protobuf::Internal::FileBuilderContext");
1925
+ "Google::Protobuf::Internal::FileBuilderContext");
1951
1926
 
1952
1927
  void FileBuilderContext_mark(void* _self) {
1953
1928
  FileBuilderContext* self = _self;
1954
- rb_gc_mark(self->pending_list);
1955
- rb_gc_mark(self->file_descriptor);
1956
- rb_gc_mark(self->builder);
1929
+ rb_gc_mark(self->descriptor_pool);
1957
1930
  }
1958
1931
 
1959
1932
  void FileBuilderContext_free(void* _self) {
1960
1933
  FileBuilderContext* self = _self;
1934
+ upb_arena_free(self->arena);
1961
1935
  xfree(self);
1962
1936
  }
1963
1937
 
1938
+ upb_strview FileBuilderContext_strdup2(VALUE _self, const char *str) {
1939
+ DEFINE_SELF(FileBuilderContext, self, _self);
1940
+ upb_strview ret;
1941
+ char *data;
1942
+
1943
+ ret.size = strlen(str);
1944
+ data = upb_malloc(upb_arena_alloc(self->arena), ret.size + 1);
1945
+ ret.data = data;
1946
+ memcpy(data, str, ret.size);
1947
+ /* Null-terminate required by rewrite_enum_defaults() above. */
1948
+ data[ret.size] = '\0';
1949
+ return ret;
1950
+ }
1951
+
1952
+ upb_strview FileBuilderContext_strdup(VALUE _self, VALUE rb_str) {
1953
+ return FileBuilderContext_strdup2(_self, get_str(rb_str));
1954
+ }
1955
+
1956
+ upb_strview FileBuilderContext_strdup_sym(VALUE _self, VALUE rb_sym) {
1957
+ Check_Type(rb_sym, T_SYMBOL);
1958
+ return FileBuilderContext_strdup(_self, rb_id2str(SYM2ID(rb_sym)));
1959
+ }
1960
+
1964
1961
  VALUE FileBuilderContext_alloc(VALUE klass) {
1965
1962
  FileBuilderContext* self = ALLOC(FileBuilderContext);
1966
1963
  VALUE ret = TypedData_Wrap_Struct(klass, &_FileBuilderContext_type, self);
1967
- self->pending_list = Qnil;
1968
- self->file_descriptor = Qnil;
1969
- self->builder = Qnil;
1964
+ self->arena = upb_arena_new();
1965
+ self->file_proto = google_protobuf_FileDescriptorProto_new(self->arena);
1966
+ self->descriptor_pool = Qnil;
1970
1967
  return ret;
1971
1968
  }
1972
1969
 
1973
1970
  void FileBuilderContext_register(VALUE module) {
1974
1971
  VALUE klass = rb_define_class_under(module, "FileBuilderContext", rb_cObject);
1975
1972
  rb_define_alloc_func(klass, FileBuilderContext_alloc);
1976
- rb_define_method(klass, "initialize", FileBuilderContext_initialize, 2);
1973
+ rb_define_method(klass, "initialize", FileBuilderContext_initialize, 3);
1977
1974
  rb_define_method(klass, "add_message", FileBuilderContext_add_message, 1);
1978
1975
  rb_define_method(klass, "add_enum", FileBuilderContext_add_enum, 1);
1979
1976
  rb_gc_register_address(&cFileBuilderContext);
@@ -1982,18 +1979,41 @@ void FileBuilderContext_register(VALUE module) {
1982
1979
 
1983
1980
  /*
1984
1981
  * call-seq:
1985
- * FileBuilderContext.new(file_descriptor, builder) => context
1982
+ * FileBuilderContext.new(descriptor_pool) => context
1986
1983
  *
1987
1984
  * Create a new file builder context for the given file descriptor and
1988
1985
  * builder context. This class is intended to serve as a DSL context to be used
1989
1986
  * with #instance_eval.
1990
1987
  */
1991
- VALUE FileBuilderContext_initialize(VALUE _self, VALUE file_descriptor,
1992
- VALUE builder) {
1988
+ VALUE FileBuilderContext_initialize(VALUE _self, VALUE descriptor_pool,
1989
+ VALUE name, VALUE options) {
1993
1990
  DEFINE_SELF(FileBuilderContext, self, _self);
1994
- self->pending_list = rb_ary_new();
1995
- self->file_descriptor = file_descriptor;
1996
- self->builder = builder;
1991
+ self->descriptor_pool = descriptor_pool;
1992
+
1993
+ google_protobuf_FileDescriptorProto_set_name(
1994
+ self->file_proto, FileBuilderContext_strdup(_self, name));
1995
+
1996
+ // Default syntax for Ruby is proto3.
1997
+ google_protobuf_FileDescriptorProto_set_syntax(
1998
+ self->file_proto,
1999
+ FileBuilderContext_strdup(_self, rb_str_new2("proto3")));
2000
+
2001
+ if (options != Qnil) {
2002
+ VALUE syntax;
2003
+
2004
+ Check_Type(options, T_HASH);
2005
+ syntax = rb_hash_lookup2(options, ID2SYM(rb_intern("syntax")), Qnil);
2006
+
2007
+ if (syntax != Qnil) {
2008
+ VALUE syntax_str;
2009
+
2010
+ Check_Type(syntax, T_SYMBOL);
2011
+ syntax_str = rb_id2str(SYM2ID(syntax));
2012
+ google_protobuf_FileDescriptorProto_set_syntax(
2013
+ self->file_proto, FileBuilderContext_strdup(_self, syntax_str));
2014
+ }
2015
+ }
2016
+
1997
2017
  return Qnil;
1998
2018
  }
1999
2019
 
@@ -2009,14 +2029,10 @@ VALUE FileBuilderContext_initialize(VALUE _self, VALUE file_descriptor,
2009
2029
  * This is the recommended, idiomatic way to build message definitions.
2010
2030
  */
2011
2031
  VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
2012
- DEFINE_SELF(FileBuilderContext, self, _self);
2013
- VALUE msgdef = rb_class_new_instance(1, &self->file_descriptor, cDescriptor);
2014
- VALUE args[2] = { msgdef, self->builder };
2032
+ VALUE args[2] = { _self, name };
2015
2033
  VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
2016
2034
  VALUE block = rb_block_proc();
2017
- rb_funcall(msgdef, rb_intern("name="), 1, name);
2018
2035
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2019
- rb_ary_push(self->pending_list, msgdef);
2020
2036
  return Qnil;
2021
2037
  }
2022
2038
 
@@ -2031,20 +2047,26 @@ VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
2031
2047
  * This is the recommended, idiomatic way to build enum definitions.
2032
2048
  */
2033
2049
  VALUE FileBuilderContext_add_enum(VALUE _self, VALUE name) {
2034
- DEFINE_SELF(FileBuilderContext, self, _self);
2035
- VALUE enumdef =
2036
- rb_class_new_instance(1, &self->file_descriptor, cEnumDescriptor);
2037
- VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
2050
+ VALUE args[2] = { _self, name };
2051
+ VALUE ctx = rb_class_new_instance(2, args, cEnumBuilderContext);
2038
2052
  VALUE block = rb_block_proc();
2039
- rb_funcall(enumdef, rb_intern("name="), 1, name);
2040
2053
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2041
- rb_ary_push(self->pending_list, enumdef);
2042
2054
  return Qnil;
2043
2055
  }
2044
2056
 
2045
- VALUE FileBuilderContext_pending_descriptors(VALUE _self) {
2057
+ void FileBuilderContext_build(VALUE _self) {
2046
2058
  DEFINE_SELF(FileBuilderContext, self, _self);
2047
- return self->pending_list;
2059
+ DescriptorPool* pool = ruby_to_DescriptorPool(self->descriptor_pool);
2060
+ upb_status status;
2061
+
2062
+ rewrite_enum_defaults(pool->symtab, self->file_proto);
2063
+ rewrite_names(_self, self->file_proto);
2064
+
2065
+ upb_status_clear(&status);
2066
+ if (!upb_symtab_addfile(pool->symtab, self->file_proto, &status)) {
2067
+ rb_raise(cTypeError, "Unable to add defs to DescriptorPool: %s",
2068
+ upb_status_errmsg(&status));
2069
+ }
2048
2070
  }
2049
2071
 
2050
2072
  // -----------------------------------------------------------------------------
@@ -2055,58 +2077,46 @@ DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
2055
2077
 
2056
2078
  void Builder_mark(void* _self) {
2057
2079
  Builder* self = _self;
2058
- rb_gc_mark(self->pending_list);
2059
- rb_gc_mark(self->default_file_descriptor);
2080
+ rb_gc_mark(self->descriptor_pool);
2081
+ rb_gc_mark(self->default_file_builder);
2060
2082
  }
2061
2083
 
2062
2084
  void Builder_free(void* _self) {
2063
- Builder* self = _self;
2064
- xfree(self->defs);
2065
- xfree(self);
2085
+ xfree(_self);
2066
2086
  }
2067
2087
 
2068
- /*
2069
- * call-seq:
2070
- * Builder.new => builder
2071
- *
2072
- * Creates a new Builder. A Builder can accumulate a set of new message and enum
2073
- * descriptors and atomically register them into a pool in a way that allows for
2074
- * (co)recursive type references.
2075
- */
2076
2088
  VALUE Builder_alloc(VALUE klass) {
2077
2089
  Builder* self = ALLOC(Builder);
2078
2090
  VALUE ret = TypedData_Wrap_Struct(
2079
2091
  klass, &_Builder_type, self);
2080
- self->pending_list = Qnil;
2081
- self->defs = NULL;
2082
- self->default_file_descriptor = Qnil;
2092
+ self->descriptor_pool = Qnil;
2093
+ self->default_file_builder = Qnil;
2083
2094
  return ret;
2084
2095
  }
2085
2096
 
2086
2097
  void Builder_register(VALUE module) {
2087
2098
  VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
2088
- rb_define_alloc_func(klass, Builder_alloc);
2089
- rb_define_method(klass, "initialize", Builder_initialize, 0);
2099
+ rb_define_alloc_func(klass, Builder_alloc);
2100
+ rb_define_method(klass, "initialize", Builder_initialize, 1);
2090
2101
  rb_define_method(klass, "add_file", Builder_add_file, -1);
2091
2102
  rb_define_method(klass, "add_message", Builder_add_message, 1);
2092
2103
  rb_define_method(klass, "add_enum", Builder_add_enum, 1);
2093
- rb_define_method(klass, "finalize_to_pool", Builder_finalize_to_pool, 1);
2094
2104
  rb_gc_register_address(&cBuilder);
2095
2105
  cBuilder = klass;
2096
2106
  }
2097
2107
 
2098
2108
  /*
2099
2109
  * call-seq:
2100
- * Builder.new
2110
+ * Builder.new(descriptor_pool) => builder
2101
2111
  *
2102
- * Initializes a new builder.
2112
+ * Creates a new Builder. A Builder can accumulate a set of new message and enum
2113
+ * descriptors and atomically register them into a pool in a way that allows for
2114
+ * (co)recursive type references.
2103
2115
  */
2104
- VALUE Builder_initialize(VALUE _self) {
2116
+ VALUE Builder_initialize(VALUE _self, VALUE pool) {
2105
2117
  DEFINE_SELF(Builder, self, _self);
2106
- self->pending_list = rb_ary_new();
2107
- VALUE file_name = Qnil;
2108
- self->default_file_descriptor =
2109
- rb_class_new_instance(1, &file_name, cFileDescriptor);
2118
+ self->descriptor_pool = pool;
2119
+ self->default_file_builder = Qnil; // Created lazily if needed.
2110
2120
  return Qnil;
2111
2121
  }
2112
2122
 
@@ -2123,17 +2133,38 @@ VALUE Builder_initialize(VALUE _self) {
2123
2133
  */
2124
2134
  VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
2125
2135
  DEFINE_SELF(Builder, self, _self);
2126
- VALUE file_descriptor = rb_class_new_instance(argc, argv, cFileDescriptor);
2127
- VALUE args[2] = { file_descriptor, _self };
2128
- VALUE ctx = rb_class_new_instance(2, args, cFileBuilderContext);
2129
- VALUE block = rb_block_proc();
2136
+ VALUE name, options;
2137
+ VALUE ctx;
2138
+ VALUE block;
2139
+
2140
+ rb_scan_args(argc, argv, "11", &name, &options);
2141
+
2142
+ {
2143
+ VALUE args[3] = { self->descriptor_pool, name, options };
2144
+ ctx = rb_class_new_instance(3, args, cFileBuilderContext);
2145
+ }
2146
+
2147
+ block = rb_block_proc();
2130
2148
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2149
+ FileBuilderContext_build(ctx);
2131
2150
 
2132
- rb_ary_concat(self->pending_list,
2133
- FileBuilderContext_pending_descriptors(ctx));
2134
2151
  return Qnil;
2135
2152
  }
2136
2153
 
2154
+ static VALUE Builder_get_default_file(VALUE _self) {
2155
+ DEFINE_SELF(Builder, self, _self);
2156
+
2157
+ /* Lazily create only if legacy builder-level methods are called. */
2158
+ if (self->default_file_builder == Qnil) {
2159
+ VALUE name = rb_str_new2("ruby_default_file.proto");
2160
+ VALUE args [3] = { self->descriptor_pool, name, rb_hash_new() };
2161
+ self->default_file_builder =
2162
+ rb_class_new_instance(3, args, cFileBuilderContext);
2163
+ }
2164
+
2165
+ return self->default_file_builder;
2166
+ }
2167
+
2137
2168
  /*
2138
2169
  * call-seq:
2139
2170
  * Builder.add_message(name, &block)
@@ -2146,15 +2177,9 @@ VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
2146
2177
  * Descriptors created this way get assigned to a default empty FileDescriptor.
2147
2178
  */
2148
2179
  VALUE Builder_add_message(VALUE _self, VALUE name) {
2149
- DEFINE_SELF(Builder, self, _self);
2150
- VALUE msgdef =
2151
- rb_class_new_instance(1, &self->default_file_descriptor, cDescriptor);
2152
- VALUE args[2] = { msgdef, _self };
2153
- VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
2154
- VALUE block = rb_block_proc();
2155
- rb_funcall(msgdef, rb_intern("name="), 1, name);
2156
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2157
- rb_ary_push(self->pending_list, msgdef);
2180
+ VALUE file_builder = Builder_get_default_file(_self);
2181
+ rb_funcall_with_block(file_builder, rb_intern("add_message"), 1, &name,
2182
+ rb_block_proc());
2158
2183
  return Qnil;
2159
2184
  }
2160
2185
 
@@ -2171,87 +2196,83 @@ VALUE Builder_add_message(VALUE _self, VALUE name) {
2171
2196
  * FileDescriptor.
2172
2197
  */
2173
2198
  VALUE Builder_add_enum(VALUE _self, VALUE name) {
2174
- DEFINE_SELF(Builder, self, _self);
2175
- VALUE enumdef =
2176
- rb_class_new_instance(1, &self->default_file_descriptor, cEnumDescriptor);
2177
- VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
2178
- VALUE block = rb_block_proc();
2179
- rb_funcall(enumdef, rb_intern("name="), 1, name);
2180
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2181
- rb_ary_push(self->pending_list, enumdef);
2199
+ VALUE file_builder = Builder_get_default_file(_self);
2200
+ rb_funcall_with_block(file_builder, rb_intern("add_enum"), 1, &name,
2201
+ rb_block_proc());
2182
2202
  return Qnil;
2183
2203
  }
2184
2204
 
2185
- static void proto3_validate_msgdef(const upb_msgdef* msgdef) {
2186
- // Verify that no required fields exist. proto3 does not support these.
2187
- upb_msg_field_iter it;
2188
- for (upb_msg_field_begin(&it, msgdef);
2189
- !upb_msg_field_done(&it);
2190
- upb_msg_field_next(&it)) {
2191
- const upb_fielddef* field = upb_msg_iter_field(&it);
2192
- if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
2193
- rb_raise(cTypeError, "Required fields are unsupported in proto3.");
2194
- }
2195
- }
2196
- }
2205
+ /* This method is hidden from Ruby, and only called directly from
2206
+ * DescriptorPool_build(). */
2207
+ VALUE Builder_build(VALUE _self) {
2208
+ DEFINE_SELF(Builder, self, _self);
2197
2209
 
2198
- static void proto3_validate_enumdef(const upb_enumdef* enumdef) {
2199
- // Verify that an entry exists with integer value 0. (This is the default
2200
- // value.)
2201
- const char* lookup = upb_enumdef_iton(enumdef, 0);
2202
- if (lookup == NULL) {
2203
- rb_raise(cTypeError,
2204
- "Enum definition does not contain a value for '0'.");
2210
+ if (self->default_file_builder != Qnil) {
2211
+ FileBuilderContext_build(self->default_file_builder);
2212
+ self->default_file_builder = Qnil;
2205
2213
  }
2206
- }
2207
-
2208
- /*
2209
- * call-seq:
2210
- * Builder.finalize_to_pool(pool)
2211
- *
2212
- * Adds all accumulated message and enum descriptors created in this builder
2213
- * context to the given pool. The operation occurs atomically, and all
2214
- * descriptors can refer to each other (including in cycles). This is the only
2215
- * way to build (co)recursive message definitions.
2216
- *
2217
- * This method is usually called automatically by DescriptorPool#build after it
2218
- * invokes the given user block in the context of the builder. The user should
2219
- * not normally need to call this manually because a Builder is not normally
2220
- * created manually.
2221
- */
2222
- VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb) {
2223
- DEFINE_SELF(Builder, self, _self);
2224
2214
 
2225
- DescriptorPool* pool = ruby_to_DescriptorPool(pool_rb);
2215
+ return Qnil;
2216
+ }
2226
2217
 
2227
- REALLOC_N(self->defs, upb_def*, RARRAY_LEN(self->pending_list));
2218
+ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
2219
+ DEFINE_SELF(DescriptorPool, descriptor_pool, _descriptor_pool);
2220
+ VALUE key = ULL2NUM((intptr_t)ptr);
2221
+ VALUE def;
2228
2222
 
2229
- for (int i = 0; i < RARRAY_LEN(self->pending_list); i++) {
2230
- VALUE def_rb = rb_ary_entry(self->pending_list, i);
2231
- if (CLASS_OF(def_rb) == cDescriptor) {
2232
- self->defs[i] = (upb_def*)ruby_to_Descriptor(def_rb)->msgdef;
2223
+ def = rb_hash_aref(descriptor_pool->def_to_descriptor, key);
2233
2224
 
2234
- if (upb_filedef_syntax(upb_def_file(self->defs[i])) == UPB_SYNTAX_PROTO3) {
2235
- proto3_validate_msgdef((const upb_msgdef*)self->defs[i]);
2236
- }
2237
- } else if (CLASS_OF(def_rb) == cEnumDescriptor) {
2238
- self->defs[i] = (upb_def*)ruby_to_EnumDescriptor(def_rb)->enumdef;
2225
+ if (ptr == NULL) {
2226
+ return Qnil;
2227
+ }
2239
2228
 
2240
- if (upb_filedef_syntax(upb_def_file(self->defs[i])) == UPB_SYNTAX_PROTO3) {
2241
- proto3_validate_enumdef((const upb_enumdef*)self->defs[i]);
2229
+ if (def == Qnil) {
2230
+ // Lazily create wrapper object.
2231
+ VALUE args[3] = { c_only_cookie, _descriptor_pool, key };
2232
+ def = rb_class_new_instance(3, args, klass);
2233
+ rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
2234
+
2235
+ // For message defs, we now eagerly get/create descriptors for all
2236
+ // submessages. We will need these anyway to parse or serialize this
2237
+ // message type. But more importantly, we must do this now so that
2238
+ // add_handlers_for_message() (which calls get_msgdef_obj()) does *not*
2239
+ // need to create a Ruby object or insert into a Ruby Hash. We need to
2240
+ // avoid triggering GC, which can switch Ruby threads and re-enter our
2241
+ // C extension from a different thread. This wreaks havoc on our state
2242
+ // if we were in the middle of building handlers.
2243
+ if (klass == cDescriptor) {
2244
+ const upb_msgdef *m = ptr;
2245
+ upb_msg_field_iter it;
2246
+ for (upb_msg_field_begin(&it, m);
2247
+ !upb_msg_field_done(&it);
2248
+ upb_msg_field_next(&it)) {
2249
+ const upb_fielddef* f = upb_msg_iter_field(&it);
2250
+ if (upb_fielddef_issubmsg(f)) {
2251
+ get_msgdef_obj(_descriptor_pool, upb_fielddef_msgsubdef(f));
2252
+ }
2242
2253
  }
2243
2254
  }
2244
2255
  }
2245
2256
 
2246
- CHECK_UPB(upb_symtab_add(pool->symtab, (upb_def**)self->defs,
2247
- RARRAY_LEN(self->pending_list), NULL, &status),
2248
- "Unable to add defs to DescriptorPool");
2257
+ return def;
2258
+ }
2249
2259
 
2250
- for (int i = 0; i < RARRAY_LEN(self->pending_list); i++) {
2251
- VALUE def_rb = rb_ary_entry(self->pending_list, i);
2252
- add_def_obj(self->defs[i], def_rb);
2253
- }
2260
+ VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) {
2261
+ return get_def_obj(descriptor_pool, def, cDescriptor);
2262
+ }
2254
2263
 
2255
- self->pending_list = rb_ary_new();
2256
- return Qnil;
2264
+ VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) {
2265
+ return get_def_obj(descriptor_pool, def, cEnumDescriptor);
2266
+ }
2267
+
2268
+ VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) {
2269
+ return get_def_obj(descriptor_pool, def, cFieldDescriptor);
2270
+ }
2271
+
2272
+ VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) {
2273
+ return get_def_obj(descriptor_pool, def, cFileDescriptor);
2274
+ }
2275
+
2276
+ VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
2277
+ return get_def_obj(descriptor_pool, def, cOneofDescriptor);
2257
2278
  }