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