google-protobuf 3.9.2-x64-mingw32 → 3.10.0.rc.1-x64-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '05119520ca900be39ac63ef834f2077da21bafa511d65b213f2a257225c319b9'
4
- data.tar.gz: ed0669c4c313e0ba4d3344b29e1f722f6c6f9086236c522e41c9cff32fdd461e
3
+ metadata.gz: a7740fcdceef1e14dd5b0959a10b0165fb5d0b843986b646fd228bc86c65bac6
4
+ data.tar.gz: 0530aa4dc7cb4fd6d52784dc0ca4ba309a9c0a353e949ff6cad8df15f820b6de
5
5
  SHA512:
6
- metadata.gz: a5031d94295f3c6bbad0265faea15cd2965340dd9f93892396b2156f5da7338e9c58c1a881d20c93c1a6e43c89b461ccdee2c0522cca56ab6e79980bbe6861f6
7
- data.tar.gz: 5a2d543a4c12141810941e6d0da7aa695fca7e824864e3a62a23d35e4d67761a29b5ffd1296ea94abebac05c438f0e27c7318738a5fae140cb6d2db330ba4392
6
+ metadata.gz: ea4bfefbcd3ca7742a0831116e03ffada82c8c1d90b17676004e65a2ea9ed81282614b97288caea5343e53a0a0befabfeb458d9dd4afb0aa404db630a91aaaa8
7
+ data.tar.gz: 1665adc6eb0013fe6e2b9a6ec883324bff929b0d4f8535f2b3967a1a3e102338c75e7d0137e632d58e7f8cda28b30e703db39157651913b5878dfddd0150f2fb
@@ -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
  }