• 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 = Qnil;                                         \
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_free(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();
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, -1);
126   rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
127   rb_define_singleton_method(klass, "generated_pool",
128                              DescriptorPool_generated_pool, 0);
129   rb_gc_register_address(&cDescriptorPool);
130   cDescriptorPool = klass;
131 
132   rb_gc_register_address(&generated_pool);
133   generated_pool = rb_class_new_instance(0, NULL, klass);
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(int argc,VALUE * argv,VALUE _self)184 VALUE DescriptorPool_build(int argc, VALUE* argv, 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 }
232 
Descriptor_free(void * _self)233 void Descriptor_free(void* _self) {
234   Descriptor* self = _self;
235   upb_msgdef_unref(self->msgdef, &self->msgdef);
236   if (self->layout) {
237     free_layout(self->layout);
238   }
239   if (self->fill_handlers) {
240     upb_handlers_unref(self->fill_handlers, &self->fill_handlers);
241   }
242   if (self->fill_method) {
243     upb_pbdecodermethod_unref(self->fill_method, &self->fill_method);
244   }
245   if (self->json_fill_method) {
246     upb_json_parsermethod_unref(self->json_fill_method,
247                                 &self->json_fill_method);
248   }
249   if (self->pb_serialize_handlers) {
250     upb_handlers_unref(self->pb_serialize_handlers,
251                        &self->pb_serialize_handlers);
252   }
253   if (self->json_serialize_handlers) {
254     upb_handlers_unref(self->json_serialize_handlers,
255                        &self->json_serialize_handlers);
256   }
257   if (self->json_serialize_handlers_preserve) {
258     upb_handlers_unref(self->json_serialize_handlers_preserve,
259                        &self->json_serialize_handlers_preserve);
260   }
261   xfree(self);
262 }
263 
264 /*
265  * call-seq:
266  *     Descriptor.new => descriptor
267  *
268  * Creates a new, empty, message type descriptor. At a minimum, its name must be
269  * set before it is added to a pool. It cannot be used to create messages until
270  * it is added to a pool, after which it becomes immutable (as part of a
271  * finalization process).
272  */
Descriptor_alloc(VALUE klass)273 VALUE Descriptor_alloc(VALUE klass) {
274   Descriptor* self = ALLOC(Descriptor);
275   VALUE ret = TypedData_Wrap_Struct(klass, &_Descriptor_type, self);
276   self->msgdef = upb_msgdef_new(&self->msgdef);
277   self->klass = Qnil;
278   self->layout = NULL;
279   self->fill_handlers = NULL;
280   self->fill_method = NULL;
281   self->json_fill_method = NULL;
282   self->pb_serialize_handlers = NULL;
283   self->json_serialize_handlers = NULL;
284   self->json_serialize_handlers_preserve = NULL;
285   return ret;
286 }
287 
Descriptor_register(VALUE module)288 void Descriptor_register(VALUE module) {
289   VALUE klass = rb_define_class_under(
290       module, "Descriptor", rb_cObject);
291   rb_define_alloc_func(klass, Descriptor_alloc);
292   rb_define_method(klass, "initialize", Descriptor_initialize, 1);
293   rb_define_method(klass, "each", Descriptor_each, 0);
294   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   rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
298   rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
299   rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
300   rb_define_method(klass, "name", Descriptor_name, 0);
301   rb_define_method(klass, "name=", Descriptor_name_set, 1);
302   rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
303   rb_include_module(klass, rb_mEnumerable);
304   rb_gc_register_address(&cDescriptor);
305   cDescriptor = klass;
306 }
307 
308 /*
309  * call-seq:
310  *    Descriptor.new(file_descriptor)
311  *
312  * Initializes a new descriptor and assigns a file descriptor to it.
313  */
Descriptor_initialize(VALUE _self,VALUE file_descriptor_rb)314 VALUE Descriptor_initialize(VALUE _self, VALUE file_descriptor_rb) {
315   DEFINE_SELF(Descriptor, self, _self);
316 
317   FileDescriptor* file_descriptor = ruby_to_FileDescriptor(file_descriptor_rb);
318 
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);
323 
324   return Qnil;
325 }
326 
327 /*
328  * call-seq:
329  *    Descriptor.file_descriptor
330  *
331  * Returns the FileDescriptor object this message belongs to.
332  */
Descriptor_file_descriptor(VALUE _self)333 VALUE Descriptor_file_descriptor(VALUE _self) {
334   DEFINE_SELF(Descriptor, self, _self);
335   return get_def_obj(upb_def_file(self->msgdef));
336 }
337 
338 /*
339  * call-seq:
340  *     Descriptor.name => name
341  *
342  * Returns the name of this message type as a fully-qualfied string (e.g.,
343  * My.Package.MessageType).
344  */
Descriptor_name(VALUE _self)345 VALUE Descriptor_name(VALUE _self) {
346   DEFINE_SELF(Descriptor, self, _self);
347   return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
348 }
349 
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  */
Descriptor_name_set(VALUE _self,VALUE str)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 /*
368  * call-seq:
369  *     Descriptor.each(&block)
370  *
371  * Iterates over fields in this message type, yielding to the block on each one.
372  */
Descriptor_each(VALUE _self)373 VALUE Descriptor_each(VALUE _self) {
374   DEFINE_SELF(Descriptor, self, _self);
375 
376   upb_msg_field_iter it;
377   for (upb_msg_field_begin(&it, self->msgdef);
378        !upb_msg_field_done(&it);
379        upb_msg_field_next(&it)) {
380     const upb_fielddef* field = upb_msg_iter_field(&it);
381     VALUE obj = get_def_obj(field);
382     rb_yield(obj);
383   }
384   return Qnil;
385 }
386 
387 /*
388  * call-seq:
389  *     Descriptor.lookup(name) => FieldDescriptor
390  *
391  * Returns the field descriptor for the field with the given name, if present,
392  * or nil if none.
393  */
Descriptor_lookup(VALUE _self,VALUE name)394 VALUE Descriptor_lookup(VALUE _self, VALUE name) {
395   DEFINE_SELF(Descriptor, self, _self);
396   const char* s = get_str(name);
397   const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s);
398   if (field == NULL) {
399     return Qnil;
400   }
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  */
Descriptor_add_field(VALUE _self,VALUE obj)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  */
Descriptor_add_oneof(VALUE _self,VALUE obj)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;
446 }
447 
448 /*
449  * call-seq:
450  *     Descriptor.each_oneof(&block) => nil
451  *
452  * Invokes the given block for each oneof in this message type, passing the
453  * corresponding OneofDescriptor.
454  */
Descriptor_each_oneof(VALUE _self)455 VALUE Descriptor_each_oneof(VALUE _self) {
456   DEFINE_SELF(Descriptor, self, _self);
457 
458   upb_msg_oneof_iter it;
459   for (upb_msg_oneof_begin(&it, self->msgdef);
460        !upb_msg_oneof_done(&it);
461        upb_msg_oneof_next(&it)) {
462     const upb_oneofdef* oneof = upb_msg_iter_oneof(&it);
463     VALUE obj = get_def_obj(oneof);
464     rb_yield(obj);
465   }
466   return Qnil;
467 }
468 
469 /*
470  * call-seq:
471  *     Descriptor.lookup_oneof(name) => OneofDescriptor
472  *
473  * Returns the oneof descriptor for the oneof with the given name, if present,
474  * or nil if none.
475  */
Descriptor_lookup_oneof(VALUE _self,VALUE name)476 VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
477   DEFINE_SELF(Descriptor, self, _self);
478   const char* s = get_str(name);
479   const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s);
480   if (oneof == NULL) {
481     return Qnil;
482   }
483   return get_def_obj(oneof);
484 }
485 
486 /*
487  * call-seq:
488  *     Descriptor.msgclass => message_klass
489  *
490  * Returns the Ruby class created for this message type. Valid only once the
491  * message type has been added to a pool.
492  */
Descriptor_msgclass(VALUE _self)493 VALUE Descriptor_msgclass(VALUE _self) {
494   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   if (self->klass == Qnil) {
500     self->klass = build_class_from_descriptor(self);
501   }
502   return self->klass;
503 }
504 
505 // -----------------------------------------------------------------------------
506 // FileDescriptor.
507 // -----------------------------------------------------------------------------
508 
509 DEFINE_CLASS(FileDescriptor, "Google::Protobuf::FileDescriptor");
510 
FileDescriptor_mark(void * _self)511 void FileDescriptor_mark(void* _self) {
512 }
513 
FileDescriptor_free(void * _self)514 void FileDescriptor_free(void* _self) {
515   FileDescriptor* self = _self;
516   upb_filedef_unref(self->filedef, &self->filedef);
517   xfree(self);
518 }
519 
520 /*
521  * call-seq:
522  *     FileDescriptor.new => file
523  *
524  * Returns a new file descriptor. The syntax must be set before it's passed
525  * to a builder.
526  */
FileDescriptor_alloc(VALUE klass)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;
533 }
534 
FileDescriptor_register(VALUE module)535 void FileDescriptor_register(VALUE module) {
536   VALUE klass = rb_define_class_under(
537       module, "FileDescriptor", rb_cObject);
538   rb_define_alloc_func(klass, FileDescriptor_alloc);
539   rb_define_method(klass, "initialize", FileDescriptor_initialize, -1);
540   rb_define_method(klass, "name", FileDescriptor_name, 0);
541   rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
542   rb_define_method(klass, "syntax=", FileDescriptor_syntax_set, 1);
543   rb_gc_register_address(&cFileDescriptor);
544   cFileDescriptor = klass;
545 }
546 
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  */
FileDescriptor_initialize(int argc,VALUE * argv,VALUE _self)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 /*
586  * call-seq:
587  *     FileDescriptor.name => name
588  *
589  * Returns the name of the file.
590  */
FileDescriptor_name(VALUE _self)591 VALUE FileDescriptor_name(VALUE _self) {
592   DEFINE_SELF(FileDescriptor, self, _self);
593   const char* name = upb_filedef_name(self->filedef);
594   return name == NULL ? Qnil : rb_str_new2(name);
595 }
596 
597 /*
598  * call-seq:
599  *     FileDescriptor.syntax => syntax
600  *
601  * Returns this file descriptors syntax.
602  *
603  * Valid syntax versions are:
604  *     :proto2 or :proto3.
605  */
FileDescriptor_syntax(VALUE _self)606 VALUE FileDescriptor_syntax(VALUE _self) {
607   DEFINE_SELF(FileDescriptor, self, _self);
608 
609   switch (upb_filedef_syntax(self->filedef)) {
610     case UPB_SYNTAX_PROTO3: return ID2SYM(rb_intern("proto3"));
611     case UPB_SYNTAX_PROTO2: return ID2SYM(rb_intern("proto2"));
612     default: return Qnil;
613   }
614 }
615 
616 /*
617  * call-seq:
618  *     FileDescriptor.syntax = version
619  *
620  * Sets this file descriptor's syntax, can be :proto3 or :proto2.
621  */
FileDescriptor_syntax_set(VALUE _self,VALUE syntax_rb)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 // -----------------------------------------------------------------------------
642 // FieldDescriptor.
643 // -----------------------------------------------------------------------------
644 
645 DEFINE_CLASS(FieldDescriptor, "Google::Protobuf::FieldDescriptor");
646 
FieldDescriptor_mark(void * _self)647 void FieldDescriptor_mark(void* _self) {
648 }
649 
FieldDescriptor_free(void * _self)650 void FieldDescriptor_free(void* _self) {
651   FieldDescriptor* self = _self;
652   upb_fielddef_unref(self->fielddef, &self->fielddef);
653   xfree(self);
654 }
655 
656 /*
657  * call-seq:
658  *     FieldDescriptor.new => field
659  *
660  * Returns a new field descriptor. Its name, type, etc. must be set before it is
661  * added to a message type.
662  */
FieldDescriptor_alloc(VALUE klass)663 VALUE FieldDescriptor_alloc(VALUE klass) {
664   FieldDescriptor* self = ALLOC(FieldDescriptor);
665   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;
669   return ret;
670 }
671 
FieldDescriptor_register(VALUE module)672 void FieldDescriptor_register(VALUE module) {
673   VALUE klass = rb_define_class_under(
674       module, "FieldDescriptor", rb_cObject);
675   rb_define_alloc_func(klass, FieldDescriptor_alloc);
676   rb_define_method(klass, "name", FieldDescriptor_name, 0);
677   rb_define_method(klass, "name=", FieldDescriptor_name_set, 1);
678   rb_define_method(klass, "type", FieldDescriptor_type, 0);
679   rb_define_method(klass, "type=", FieldDescriptor_type_set, 1);
680   rb_define_method(klass, "default", FieldDescriptor_default, 0);
681   rb_define_method(klass, "default=", FieldDescriptor_default_set, 1);
682   rb_define_method(klass, "label", FieldDescriptor_label, 0);
683   rb_define_method(klass, "label=", FieldDescriptor_label_set, 1);
684   rb_define_method(klass, "number", FieldDescriptor_number, 0);
685   rb_define_method(klass, "number=", FieldDescriptor_number_set, 1);
686   rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
687   rb_define_method(klass, "submsg_name=", FieldDescriptor_submsg_name_set, 1);
688   rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
689   rb_define_method(klass, "has?", FieldDescriptor_has, 1);
690   rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
691   rb_define_method(klass, "get", FieldDescriptor_get, 1);
692   rb_define_method(klass, "set", FieldDescriptor_set, 2);
693   rb_gc_register_address(&cFieldDescriptor);
694   cFieldDescriptor = klass;
695 }
696 
697 /*
698  * call-seq:
699  *     FieldDescriptor.name => name
700  *
701  * Returns the name of this field.
702  */
FieldDescriptor_name(VALUE _self)703 VALUE FieldDescriptor_name(VALUE _self) {
704   DEFINE_SELF(FieldDescriptor, self, _self);
705   return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
706 }
707 
708 /*
709  * call-seq:
710  *     FieldDescriptor.name = name
711  *
712  * Sets the name of this field. Cannot be called once the containing message
713  * type, if any, is added to a pool.
714  */
FieldDescriptor_name_set(VALUE _self,VALUE str)715 VALUE FieldDescriptor_name_set(VALUE _self, VALUE str) {
716   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;
722 }
723 
ruby_to_fieldtype(VALUE type)724 upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
725   if (TYPE(type) != T_SYMBOL) {
726     rb_raise(rb_eArgError, "Expected symbol for field type.");
727   }
728 
729 #define CONVERT(upb, ruby)                                           \
730   if (SYM2ID(type) == rb_intern( # ruby )) {                         \
731     return UPB_TYPE_ ## upb;                                         \
732   }
733 
734   CONVERT(FLOAT, float);
735   CONVERT(DOUBLE, double);
736   CONVERT(BOOL, bool);
737   CONVERT(STRING, string);
738   CONVERT(BYTES, bytes);
739   CONVERT(MESSAGE, message);
740   CONVERT(ENUM, enum);
741   CONVERT(INT32, int32);
742   CONVERT(INT64, int64);
743   CONVERT(UINT32, uint32);
744   CONVERT(UINT64, uint64);
745 
746 #undef CONVERT
747 
748   rb_raise(rb_eArgError, "Unknown field type.");
749   return 0;
750 }
751 
fieldtype_to_ruby(upb_fieldtype_t type)752 VALUE fieldtype_to_ruby(upb_fieldtype_t type) {
753   switch (type) {
754 #define CONVERT(upb, ruby)                                           \
755     case UPB_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
756     CONVERT(FLOAT, float);
757     CONVERT(DOUBLE, double);
758     CONVERT(BOOL, bool);
759     CONVERT(STRING, string);
760     CONVERT(BYTES, bytes);
761     CONVERT(MESSAGE, message);
762     CONVERT(ENUM, enum);
763     CONVERT(INT32, int32);
764     CONVERT(INT64, int64);
765     CONVERT(UINT32, uint32);
766     CONVERT(UINT64, uint64);
767 #undef CONVERT
768   }
769   return Qnil;
770 }
771 
ruby_to_descriptortype(VALUE type)772 upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
773   if (TYPE(type) != T_SYMBOL) {
774     rb_raise(rb_eArgError, "Expected symbol for field type.");
775   }
776 
777 #define CONVERT(upb, ruby)                                           \
778   if (SYM2ID(type) == rb_intern( # ruby )) {                         \
779     return UPB_DESCRIPTOR_TYPE_ ## upb;                              \
780   }
781 
782   CONVERT(FLOAT, float);
783   CONVERT(DOUBLE, double);
784   CONVERT(BOOL, bool);
785   CONVERT(STRING, string);
786   CONVERT(BYTES, bytes);
787   CONVERT(MESSAGE, message);
788   CONVERT(GROUP, group);
789   CONVERT(ENUM, enum);
790   CONVERT(INT32, int32);
791   CONVERT(INT64, int64);
792   CONVERT(UINT32, uint32);
793   CONVERT(UINT64, uint64);
794   CONVERT(SINT32, sint32);
795   CONVERT(SINT64, sint64);
796   CONVERT(FIXED32, fixed32);
797   CONVERT(FIXED64, fixed64);
798   CONVERT(SFIXED32, sfixed32);
799   CONVERT(SFIXED64, sfixed64);
800 
801 #undef CONVERT
802 
803   rb_raise(rb_eArgError, "Unknown field type.");
804   return 0;
805 }
806 
descriptortype_to_ruby(upb_descriptortype_t type)807 VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
808   switch (type) {
809 #define CONVERT(upb, ruby)                                           \
810     case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
811     CONVERT(FLOAT, float);
812     CONVERT(DOUBLE, double);
813     CONVERT(BOOL, bool);
814     CONVERT(STRING, string);
815     CONVERT(BYTES, bytes);
816     CONVERT(MESSAGE, message);
817     CONVERT(GROUP, group);
818     CONVERT(ENUM, enum);
819     CONVERT(INT32, int32);
820     CONVERT(INT64, int64);
821     CONVERT(UINT32, uint32);
822     CONVERT(UINT64, uint64);
823     CONVERT(SINT32, sint32);
824     CONVERT(SINT64, sint64);
825     CONVERT(FIXED32, fixed32);
826     CONVERT(FIXED64, fixed64);
827     CONVERT(SFIXED32, sfixed32);
828     CONVERT(SFIXED64, sfixed64);
829 #undef CONVERT
830   }
831   return Qnil;
832 }
833 
834 /*
835  * call-seq:
836  *     FieldDescriptor.type => type
837  *
838  * Returns this field's type, as a Ruby symbol, or nil if not yet set.
839  *
840  * Valid field types are:
841  *     :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string,
842  *     :bytes, :message.
843  */
FieldDescriptor_type(VALUE _self)844 VALUE FieldDescriptor_type(VALUE _self) {
845   DEFINE_SELF(FieldDescriptor, self, _self);
846   if (!upb_fielddef_typeisset(self->fielddef)) {
847     return Qnil;
848   }
849   return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
850 }
851 
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  */
FieldDescriptor_type_set(VALUE _self,VALUE type)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 /*
867  * call-seq:
868  *     FieldDescriptor.default => default
869  *
870  * Returns this field's default, as a Ruby object, or nil if not yet set.
871  */
FieldDescriptor_default(VALUE _self)872 VALUE FieldDescriptor_default(VALUE _self) {
873   DEFINE_SELF(FieldDescriptor, self, _self);
874   return layout_get_default(self->fielddef);
875 }
876 
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  */
FieldDescriptor_default_set(VALUE _self,VALUE default_value)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 /*
932  * call-seq:
933  *     FieldDescriptor.label => label
934  *
935  * Returns this field's label (i.e., plurality), as a Ruby symbol.
936  *
937  * Valid field labels are:
938  *     :optional, :repeated
939  */
FieldDescriptor_label(VALUE _self)940 VALUE FieldDescriptor_label(VALUE _self) {
941   DEFINE_SELF(FieldDescriptor, self, _self);
942   switch (upb_fielddef_label(self->fielddef)) {
943 #define CONVERT(upb, ruby)                                           \
944     case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby ));
945 
946     CONVERT(OPTIONAL, optional);
947     CONVERT(REQUIRED, required);
948     CONVERT(REPEATED, repeated);
949 
950 #undef CONVERT
951   }
952 
953   return Qnil;
954 }
955 
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  */
FieldDescriptor_label_set(VALUE _self,VALUE label)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 /*
995  * call-seq:
996  *     FieldDescriptor.number => number
997  *
998  * Returns the tag number for this field.
999  */
FieldDescriptor_number(VALUE _self)1000 VALUE FieldDescriptor_number(VALUE _self) {
1001   DEFINE_SELF(FieldDescriptor, self, _self);
1002   return INT2NUM(upb_fielddef_number(self->fielddef));
1003 }
1004 
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  */
FieldDescriptor_number_set(VALUE _self,VALUE number)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 /*
1021  * call-seq:
1022  *     FieldDescriptor.submsg_name => submsg_name
1023  *
1024  * Returns the name of the message or enum type corresponding to this field, if
1025  * it is a message or enum field (respectively), or nil otherwise. This type
1026  * name will be resolved within the context of the pool to which the containing
1027  * message type is added.
1028  */
FieldDescriptor_submsg_name(VALUE _self)1029 VALUE FieldDescriptor_submsg_name(VALUE _self) {
1030   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  */
FieldDescriptor_submsg_name_set(VALUE _self,VALUE value)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.");
1053   }
1054   CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
1055             "Error setting submessage name");
1056   return Qnil;
1057 }
1058 
1059 /*
1060  * call-seq:
1061  *     FieldDescriptor.subtype => message_or_enum_descriptor
1062  *
1063  * Returns the message or enum descriptor corresponding to this field's type if
1064  * it is a message or enum field, respectively, or nil otherwise. Cannot be
1065  * called *until* the containing message type is added to a pool (and thus
1066  * resolved).
1067  */
FieldDescriptor_subtype(VALUE _self)1068 VALUE FieldDescriptor_subtype(VALUE _self) {
1069   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;
1078   }
1079   return get_def_obj(def);
1080 }
1081 
1082 /*
1083  * call-seq:
1084  *     FieldDescriptor.get(message) => value
1085  *
1086  * Returns the value set for this field on the given message. Raises an
1087  * exception if message is of the wrong type.
1088  */
FieldDescriptor_get(VALUE _self,VALUE msg_rb)1089 VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
1090   DEFINE_SELF(FieldDescriptor, self, _self);
1091   MessageHeader* msg;
1092   TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1093   if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
1094     rb_raise(cTypeError, "get method called on wrong message type");
1095   }
1096   return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
1097 }
1098 
1099 /*
1100  * call-seq:
1101  *     FieldDescriptor.has?(message) => boolean
1102  *
1103  * Returns whether the value is set on the given message. Raises an
1104  * exception when calling with proto syntax 3.
1105  */
FieldDescriptor_has(VALUE _self,VALUE msg_rb)1106 VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
1107   DEFINE_SELF(FieldDescriptor, self, _self);
1108   MessageHeader* msg;
1109   TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1110   if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
1111     rb_raise(cTypeError, "has method called on wrong message type");
1112   } else if (!upb_fielddef_haspresence(self->fielddef)) {
1113     rb_raise(rb_eArgError, "does not track presence");
1114   }
1115 
1116   return layout_has(msg->descriptor->layout, Message_data(msg), self->fielddef);
1117 }
1118 
1119 /*
1120  * call-seq:
1121  *     FieldDescriptor.clear(message)
1122  *
1123  * Clears the field from the message if it's set.
1124  */
FieldDescriptor_clear(VALUE _self,VALUE msg_rb)1125 VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
1126   DEFINE_SELF(FieldDescriptor, self, _self);
1127   MessageHeader* msg;
1128   TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1129   if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
1130     rb_raise(cTypeError, "has method called on wrong message type");
1131   }
1132 
1133   layout_clear(msg->descriptor->layout, Message_data(msg), self->fielddef);
1134   return Qnil;
1135 }
1136 
1137 /*
1138  * call-seq:
1139  *     FieldDescriptor.set(message, value)
1140  *
1141  * Sets the value corresponding to this field to the given value on the given
1142  * message. Raises an exception if message is of the wrong type. Performs the
1143  * ordinary type-checks for field setting.
1144  */
FieldDescriptor_set(VALUE _self,VALUE msg_rb,VALUE value)1145 VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
1146   DEFINE_SELF(FieldDescriptor, self, _self);
1147   MessageHeader* msg;
1148   TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1149   if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
1150     rb_raise(cTypeError, "set method called on wrong message type");
1151   }
1152   layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
1153   return Qnil;
1154 }
1155 
1156 // -----------------------------------------------------------------------------
1157 // OneofDescriptor.
1158 // -----------------------------------------------------------------------------
1159 
1160 DEFINE_CLASS(OneofDescriptor, "Google::Protobuf::OneofDescriptor");
1161 
OneofDescriptor_mark(void * _self)1162 void OneofDescriptor_mark(void* _self) {
1163 }
1164 
OneofDescriptor_free(void * _self)1165 void OneofDescriptor_free(void* _self) {
1166   OneofDescriptor* self = _self;
1167   upb_oneofdef_unref(self->oneofdef, &self->oneofdef);
1168   xfree(self);
1169 }
1170 
1171 /*
1172  * call-seq:
1173  *     OneofDescriptor.new => oneof_descriptor
1174  *
1175  * Creates a new, empty, oneof descriptor. The oneof may only be modified prior
1176  * to being added to a message descriptor which is subsequently added to a pool.
1177  */
OneofDescriptor_alloc(VALUE klass)1178 VALUE OneofDescriptor_alloc(VALUE klass) {
1179   OneofDescriptor* self = ALLOC(OneofDescriptor);
1180   VALUE ret = TypedData_Wrap_Struct(klass, &_OneofDescriptor_type, self);
1181   self->oneofdef = upb_oneofdef_new(&self->oneofdef);
1182   return ret;
1183 }
1184 
OneofDescriptor_register(VALUE module)1185 void OneofDescriptor_register(VALUE module) {
1186   VALUE klass = rb_define_class_under(
1187       module, "OneofDescriptor", rb_cObject);
1188   rb_define_alloc_func(klass, OneofDescriptor_alloc);
1189   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   rb_define_method(klass, "each", OneofDescriptor_each, 0);
1193   rb_include_module(klass, rb_mEnumerable);
1194   rb_gc_register_address(&cOneofDescriptor);
1195   cOneofDescriptor = klass;
1196 }
1197 
1198 /*
1199  * call-seq:
1200  *     OneofDescriptor.name => name
1201  *
1202  * Returns the name of this oneof.
1203  */
OneofDescriptor_name(VALUE _self)1204 VALUE OneofDescriptor_name(VALUE _self) {
1205   DEFINE_SELF(OneofDescriptor, self, _self);
1206   return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
1207 }
1208 
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  */
OneofDescriptor_name_set(VALUE _self,VALUE value)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");
1222   return Qnil;
1223 }
1224 
1225 /*
1226  * 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.
1233  *
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.
1238  */
OneofDescriptor_add_field(VALUE _self,VALUE obj)1239 VALUE OneofDescriptor_add_field(VALUE _self, VALUE obj) {
1240   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;
1249 }
1250 
1251 /*
1252  * call-seq:
1253  *     OneofDescriptor.each(&block) => nil
1254  *
1255  * Iterates through fields in this oneof, yielding to the block on each one.
1256  */
OneofDescriptor_each(VALUE _self,VALUE field)1257 VALUE OneofDescriptor_each(VALUE _self, VALUE field) {
1258   DEFINE_SELF(OneofDescriptor, self, _self);
1259   upb_oneof_iter it;
1260   for (upb_oneof_begin(&it, self->oneofdef);
1261        !upb_oneof_done(&it);
1262        upb_oneof_next(&it)) {
1263     const upb_fielddef* f = upb_oneof_iter_field(&it);
1264     VALUE obj = get_def_obj(f);
1265     rb_yield(obj);
1266   }
1267   return Qnil;
1268 }
1269 
1270 // -----------------------------------------------------------------------------
1271 // EnumDescriptor.
1272 // -----------------------------------------------------------------------------
1273 
1274 DEFINE_CLASS(EnumDescriptor, "Google::Protobuf::EnumDescriptor");
1275 
EnumDescriptor_mark(void * _self)1276 void EnumDescriptor_mark(void* _self) {
1277   EnumDescriptor* self = _self;
1278   rb_gc_mark(self->module);
1279 }
1280 
EnumDescriptor_free(void * _self)1281 void EnumDescriptor_free(void* _self) {
1282   EnumDescriptor* self = _self;
1283   upb_enumdef_unref(self->enumdef, &self->enumdef);
1284   xfree(self);
1285 }
1286 
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  */
EnumDescriptor_alloc(VALUE klass)1295 VALUE EnumDescriptor_alloc(VALUE klass) {
1296   EnumDescriptor* self = ALLOC(EnumDescriptor);
1297   VALUE ret = TypedData_Wrap_Struct(klass, &_EnumDescriptor_type, self);
1298   self->enumdef = upb_enumdef_new(&self->enumdef);
1299   self->module = Qnil;
1300   return ret;
1301 }
1302 
EnumDescriptor_register(VALUE module)1303 void EnumDescriptor_register(VALUE module) {
1304   VALUE klass = rb_define_class_under(
1305       module, "EnumDescriptor", rb_cObject);
1306   rb_define_alloc_func(klass, EnumDescriptor_alloc);
1307   rb_define_method(klass, "initialize", EnumDescriptor_initialize, 1);
1308   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   rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
1312   rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
1313   rb_define_method(klass, "each", EnumDescriptor_each, 0);
1314   rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1315   rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1316   rb_include_module(klass, rb_mEnumerable);
1317   rb_gc_register_address(&cEnumDescriptor);
1318   cEnumDescriptor = klass;
1319 }
1320 
1321 /*
1322  * call-seq:
1323  *    Descriptor.new(file_descriptor)
1324  *
1325  * Initializes a new descriptor and assigns a file descriptor to it.
1326  */
EnumDescriptor_initialize(VALUE _self,VALUE file_descriptor_rb)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
1342  *
1343  * Returns the FileDescriptor object this enum belongs to.
1344  */
EnumDescriptor_file_descriptor(VALUE _self)1345 VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1346   DEFINE_SELF(EnumDescriptor, self, _self);
1347   return get_def_obj(upb_def_file(self->enumdef));
1348 }
1349 
1350 /*
1351  * call-seq:
1352  *     EnumDescriptor.name => name
1353  *
1354  * Returns the name of this enum type.
1355  */
EnumDescriptor_name(VALUE _self)1356 VALUE EnumDescriptor_name(VALUE _self) {
1357   DEFINE_SELF(EnumDescriptor, self, _self);
1358   return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
1359 }
1360 
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  */
EnumDescriptor_name_set(VALUE _self,VALUE str)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  */
EnumDescriptor_add_value(VALUE _self,VALUE name,VALUE number)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 /*
1396  * call-seq:
1397  *     EnumDescriptor.lookup_name(name) => value
1398  *
1399  * Returns the numeric value corresponding to the given key name (as a Ruby
1400  * symbol), or nil if none.
1401  */
EnumDescriptor_lookup_name(VALUE _self,VALUE name)1402 VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1403   DEFINE_SELF(EnumDescriptor, self, _self);
1404   const char* name_str= rb_id2name(SYM2ID(name));
1405   int32_t val = 0;
1406   if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) {
1407     return INT2NUM(val);
1408   } else {
1409     return Qnil;
1410   }
1411 }
1412 
1413 /*
1414  * call-seq:
1415  *     EnumDescriptor.lookup_value(name) => value
1416  *
1417  * Returns the key name (as a Ruby symbol) corresponding to the integer value,
1418  * or nil if none.
1419  */
EnumDescriptor_lookup_value(VALUE _self,VALUE number)1420 VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1421   DEFINE_SELF(EnumDescriptor, self, _self);
1422   int32_t val = NUM2INT(number);
1423   const char* name = upb_enumdef_iton(self->enumdef, val);
1424   if (name != NULL) {
1425     return ID2SYM(rb_intern(name));
1426   } else {
1427     return Qnil;
1428   }
1429 }
1430 
1431 /*
1432  * call-seq:
1433  *     EnumDescriptor.each(&block)
1434  *
1435  * Iterates over key => value mappings in this enum's definition, yielding to
1436  * the block with (key, value) arguments for each one.
1437  */
EnumDescriptor_each(VALUE _self)1438 VALUE EnumDescriptor_each(VALUE _self) {
1439   DEFINE_SELF(EnumDescriptor, self, _self);
1440 
1441   upb_enum_iter it;
1442   for (upb_enum_begin(&it, self->enumdef);
1443        !upb_enum_done(&it);
1444        upb_enum_next(&it)) {
1445     VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it)));
1446     VALUE number = INT2NUM(upb_enum_iter_number(&it));
1447     rb_yield_values(2, key, number);
1448   }
1449 
1450   return Qnil;
1451 }
1452 
1453 /*
1454  * call-seq:
1455  *     EnumDescriptor.enummodule => module
1456  *
1457  * Returns the Ruby module corresponding to this enum type. Cannot be called
1458  * until the enum descriptor has been added to a pool.
1459  */
EnumDescriptor_enummodule(VALUE _self)1460 VALUE EnumDescriptor_enummodule(VALUE _self) {
1461   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   if (self->module == Qnil) {
1468     self->module = build_module_from_enumdesc(self);
1469   }
1470   return self->module;
1471 }
1472 
1473 // -----------------------------------------------------------------------------
1474 // MessageBuilderContext.
1475 // -----------------------------------------------------------------------------
1476 
1477 DEFINE_CLASS(MessageBuilderContext,
1478     "Google::Protobuf::Internal::MessageBuilderContext");
1479 
MessageBuilderContext_mark(void * _self)1480 void MessageBuilderContext_mark(void* _self) {
1481   MessageBuilderContext* self = _self;
1482   rb_gc_mark(self->descriptor);
1483   rb_gc_mark(self->builder);
1484 }
1485 
MessageBuilderContext_free(void * _self)1486 void MessageBuilderContext_free(void* _self) {
1487   MessageBuilderContext* self = _self;
1488   xfree(self);
1489 }
1490 
MessageBuilderContext_alloc(VALUE klass)1491 VALUE MessageBuilderContext_alloc(VALUE klass) {
1492   MessageBuilderContext* self = ALLOC(MessageBuilderContext);
1493   VALUE ret = TypedData_Wrap_Struct(
1494       klass, &_MessageBuilderContext_type, self);
1495   self->descriptor = Qnil;
1496   self->builder = Qnil;
1497   return ret;
1498 }
1499 
MessageBuilderContext_register(VALUE module)1500 void MessageBuilderContext_register(VALUE module) {
1501   VALUE klass = rb_define_class_under(
1502       module, "MessageBuilderContext", rb_cObject);
1503   rb_define_alloc_func(klass, MessageBuilderContext_alloc);
1504   rb_define_method(klass, "initialize",
1505                    MessageBuilderContext_initialize, 2);
1506   rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
1507   rb_define_method(klass, "required", MessageBuilderContext_required, -1);
1508   rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
1509   rb_define_method(klass, "map", MessageBuilderContext_map, -1);
1510   rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
1511   rb_gc_register_address(&cMessageBuilderContext);
1512   cMessageBuilderContext = klass;
1513 }
1514 
1515 /*
1516  * call-seq:
1517  *     MessageBuilderContext.new(desc, builder) => context
1518  *
1519  * Create a new message builder context around the given message descriptor and
1520  * builder context. This class is intended to serve as a DSL context to be used
1521  * with #instance_eval.
1522  */
MessageBuilderContext_initialize(VALUE _self,VALUE msgdef,VALUE builder)1523 VALUE MessageBuilderContext_initialize(VALUE _self,
1524                                        VALUE msgdef,
1525                                        VALUE builder) {
1526   DEFINE_SELF(MessageBuilderContext, self, _self);
1527   self->descriptor = msgdef;
1528   self->builder = builder;
1529   return Qnil;
1530 }
1531 
msgdef_add_field(VALUE msgdef_rb,const char * label,VALUE name,VALUE type,VALUE number,VALUE type_class,VALUE options)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)));
1539 
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);
1544 
1545   if (type_class != Qnil) {
1546     Check_Type(type_class, T_STRING);
1547 
1548     // Make it an absolute type name by prepending a dot.
1549     type_class = rb_str_append(rb_str_new2("."), type_class);
1550     rb_funcall(fielddef_rb, rb_intern("submsg_name="), 1, type_class);
1551   }
1552 
1553   if (options != Qnil) {
1554     Check_Type(options, T_HASH);
1555 
1556     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       }
1562 
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       }
1568 
1569       rb_funcall(fielddef_rb, rb_intern("default="), 1,
1570 		 rb_hash_lookup(options, ID2SYM(rb_intern("default"))));
1571     }
1572   }
1573 
1574   rb_funcall(msgdef_rb, rb_intern("add_field"), 1, fielddef_rb);
1575   return fielddef_rb;
1576 }
1577 
1578 /*
1579  * call-seq:
1580  *     MessageBuilderContext.optional(name, type, number, type_class = nil,
1581  *                                    options = nil)
1582  *
1583  * Defines a new optional field on this message type with the given type, tag
1584  * number, and type class (for message and enum fields). The type must be a Ruby
1585  * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1586  * string, if present (as accepted by FieldDescriptor#submsg_name=).
1587  */
MessageBuilderContext_optional(int argc,VALUE * argv,VALUE _self)1588 VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1589   DEFINE_SELF(MessageBuilderContext, self, _self);
1590   VALUE name, type, number;
1591   VALUE type_class, options = Qnil;
1592 
1593   rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
1594 
1595   // Allow passing (name, type, number, options) or
1596   // (name, type, number, type_class, options)
1597   if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
1598     options = type_class;
1599     type_class = Qnil;
1600   }
1601 
1602   return msgdef_add_field(self->descriptor, "optional",
1603                           name, type, number, type_class, options);
1604 }
1605 
1606 /*
1607  * call-seq:
1608  *     MessageBuilderContext.required(name, type, number, type_class = nil,
1609  *                                    options = nil)
1610  *
1611  * Defines a new required field on this message type with the given type, tag
1612  * number, and type class (for message and enum fields). The type must be a Ruby
1613  * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1614  * string, if present (as accepted by FieldDescriptor#submsg_name=).
1615  *
1616  * Proto3 does not have required fields, but this method exists for
1617  * completeness. Any attempt to add a message type with required fields to a
1618  * pool will currently result in an error.
1619  */
MessageBuilderContext_required(int argc,VALUE * argv,VALUE _self)1620 VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1621   DEFINE_SELF(MessageBuilderContext, self, _self);
1622   VALUE name, type, number;
1623   VALUE type_class, options = Qnil;
1624 
1625   rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
1626 
1627   // Allow passing (name, type, number, options) or
1628   // (name, type, number, type_class, options)
1629   if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
1630     options = type_class;
1631     type_class = Qnil;
1632   }
1633 
1634   return msgdef_add_field(self->descriptor, "required",
1635                           name, type, number, type_class, options);
1636 }
1637 
1638 /*
1639  * call-seq:
1640  *     MessageBuilderContext.repeated(name, type, number, type_class = nil)
1641  *
1642  * Defines a new repeated field on this message type with the given type, tag
1643  * number, and type class (for message and enum fields). The type must be a Ruby
1644  * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1645  * string, if present (as accepted by FieldDescriptor#submsg_name=).
1646  */
MessageBuilderContext_repeated(int argc,VALUE * argv,VALUE _self)1647 VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1648   DEFINE_SELF(MessageBuilderContext, self, _self);
1649   VALUE name, type, number, type_class;
1650 
1651   if (argc < 3) {
1652     rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1653   }
1654   name = argv[0];
1655   type = argv[1];
1656   number = argv[2];
1657   type_class = (argc > 3) ? argv[3] : Qnil;
1658 
1659   return msgdef_add_field(self->descriptor, "repeated",
1660                           name, type, number, type_class, Qnil);
1661 }
1662 
1663 /*
1664  * call-seq:
1665  *     MessageBuilderContext.map(name, key_type, value_type, number,
1666  *                               value_type_class = nil)
1667  *
1668  * Defines a new map field on this message type with the given key and value
1669  * types, tag number, and type class (for message and enum value types). The key
1670  * type must be :int32/:uint32/:int64/:uint64, :bool, or :string. The value type
1671  * type must be a Ruby symbol (as accepted by FieldDescriptor#type=) and the
1672  * type_class must be a string, if present (as accepted by
1673  * FieldDescriptor#submsg_name=).
1674  */
MessageBuilderContext_map(int argc,VALUE * argv,VALUE _self)1675 VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1676   DEFINE_SELF(MessageBuilderContext, self, _self);
1677   VALUE name, key_type, value_type, number, type_class;
1678   VALUE mapentry_desc, mapentry_desc_name;
1679 
1680   if (argc < 4) {
1681     rb_raise(rb_eArgError, "Expected at least 4 arguments.");
1682   }
1683   name = argv[0];
1684   key_type = argv[1];
1685   value_type = argv[2];
1686   number = argv[3];
1687   type_class = (argc > 4) ? argv[4] : Qnil;
1688 
1689   // Validate the key type. We can't accept enums, messages, or floats/doubles
1690   // as map keys. (We exclude these explicitly, and the field-descriptor setter
1691   // below then ensures that the type is one of the remaining valid options.)
1692   if (SYM2ID(key_type) == rb_intern("float") ||
1693       SYM2ID(key_type) == rb_intern("double") ||
1694       SYM2ID(key_type) == rb_intern("enum") ||
1695       SYM2ID(key_type) == rb_intern("message")) {
1696     rb_raise(rb_eArgError,
1697              "Cannot add a map field with a float, double, enum, or message "
1698              "type.");
1699   }
1700 
1701   Descriptor* descriptor = ruby_to_Descriptor(self->descriptor);
1702   if (upb_msgdef_syntax(descriptor->msgdef) == UPB_SYNTAX_PROTO2) {
1703     rb_raise(rb_eArgError,
1704 	     "Cannot add a native map field using proto2 syntax.");
1705   }
1706 
1707   // Create a new message descriptor for the map entry message, and create a
1708   // 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);
1713   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   }
1735 
1736   {
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);
1749   }
1750 
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);
1756   }
1757 
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   }
1772 
1773   return Qnil;
1774 }
1775 
1776 /*
1777  * call-seq:
1778  *     MessageBuilderContext.oneof(name, &block) => nil
1779  *
1780  * Creates a new OneofDescriptor with the given name, creates a
1781  * OneofBuilderContext attached to that OneofDescriptor, evaluates the given
1782  * block in the context of that OneofBuilderContext with #instance_eval, and
1783  * then adds the oneof to the message.
1784  *
1785  * This is the recommended, idiomatic way to build oneof definitions.
1786  */
MessageBuilderContext_oneof(VALUE _self,VALUE name)1787 VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
1788   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);
1797 
1798   return Qnil;
1799 }
1800 
1801 // -----------------------------------------------------------------------------
1802 // OneofBuilderContext.
1803 // -----------------------------------------------------------------------------
1804 
1805 DEFINE_CLASS(OneofBuilderContext,
1806     "Google::Protobuf::Internal::OneofBuilderContext");
1807 
OneofBuilderContext_mark(void * _self)1808 void OneofBuilderContext_mark(void* _self) {
1809   OneofBuilderContext* self = _self;
1810   rb_gc_mark(self->descriptor);
1811   rb_gc_mark(self->builder);
1812 }
1813 
OneofBuilderContext_free(void * _self)1814 void OneofBuilderContext_free(void* _self) {
1815   OneofBuilderContext* self = _self;
1816   xfree(self);
1817 }
1818 
OneofBuilderContext_alloc(VALUE klass)1819 VALUE OneofBuilderContext_alloc(VALUE klass) {
1820   OneofBuilderContext* self = ALLOC(OneofBuilderContext);
1821   VALUE ret = TypedData_Wrap_Struct(
1822       klass, &_OneofBuilderContext_type, self);
1823   self->descriptor = Qnil;
1824   self->builder = Qnil;
1825   return ret;
1826 }
1827 
OneofBuilderContext_register(VALUE module)1828 void OneofBuilderContext_register(VALUE module) {
1829   VALUE klass = rb_define_class_under(
1830       module, "OneofBuilderContext", rb_cObject);
1831   rb_define_alloc_func(klass, OneofBuilderContext_alloc);
1832   rb_define_method(klass, "initialize",
1833                    OneofBuilderContext_initialize, 2);
1834   rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
1835   rb_gc_register_address(&cOneofBuilderContext);
1836   cOneofBuilderContext = klass;
1837 }
1838 
1839 /*
1840  * call-seq:
1841  *     OneofBuilderContext.new(desc, builder) => context
1842  *
1843  * Create a new oneof builder context around the given oneof descriptor and
1844  * builder context. This class is intended to serve as a DSL context to be used
1845  * with #instance_eval.
1846  */
OneofBuilderContext_initialize(VALUE _self,VALUE oneofdef,VALUE builder)1847 VALUE OneofBuilderContext_initialize(VALUE _self,
1848                                      VALUE oneofdef,
1849                                      VALUE builder) {
1850   DEFINE_SELF(OneofBuilderContext, self, _self);
1851   self->descriptor = oneofdef;
1852   self->builder = builder;
1853   return Qnil;
1854 }
1855 
1856 /*
1857  * call-seq:
1858  *     OneofBuilderContext.optional(name, type, number, type_class = nil,
1859  *                                  default_value = nil)
1860  *
1861  * Defines a new optional field in this oneof with the given type, tag number,
1862  * and type class (for message and enum fields). The type must be a Ruby symbol
1863  * (as accepted by FieldDescriptor#type=) and the type_class must be a string,
1864  * if present (as accepted by FieldDescriptor#submsg_name=).
1865  */
OneofBuilderContext_optional(int argc,VALUE * argv,VALUE _self)1866 VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1867   DEFINE_SELF(OneofBuilderContext, self, _self);
1868   VALUE name, type, number;
1869   VALUE type_class, options = Qnil;
1870 
1871   rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
1872 
1873   return msgdef_add_field(self->descriptor, "optional",
1874                           name, type, number, type_class, options);
1875 }
1876 
1877 // -----------------------------------------------------------------------------
1878 // EnumBuilderContext.
1879 // -----------------------------------------------------------------------------
1880 
1881 DEFINE_CLASS(EnumBuilderContext,
1882     "Google::Protobuf::Internal::EnumBuilderContext");
1883 
EnumBuilderContext_mark(void * _self)1884 void EnumBuilderContext_mark(void* _self) {
1885   EnumBuilderContext* self = _self;
1886   rb_gc_mark(self->enumdesc);
1887 }
1888 
EnumBuilderContext_free(void * _self)1889 void EnumBuilderContext_free(void* _self) {
1890   EnumBuilderContext* self = _self;
1891   xfree(self);
1892 }
1893 
EnumBuilderContext_alloc(VALUE klass)1894 VALUE EnumBuilderContext_alloc(VALUE klass) {
1895   EnumBuilderContext* self = ALLOC(EnumBuilderContext);
1896   VALUE ret = TypedData_Wrap_Struct(
1897       klass, &_EnumBuilderContext_type, self);
1898   self->enumdesc = Qnil;
1899   return ret;
1900 }
1901 
EnumBuilderContext_register(VALUE module)1902 void EnumBuilderContext_register(VALUE module) {
1903   VALUE klass = rb_define_class_under(
1904       module, "EnumBuilderContext", rb_cObject);
1905   rb_define_alloc_func(klass, EnumBuilderContext_alloc);
1906   rb_define_method(klass, "initialize",
1907                    EnumBuilderContext_initialize, 1);
1908   rb_define_method(klass, "value", EnumBuilderContext_value, 2);
1909   rb_gc_register_address(&cEnumBuilderContext);
1910   cEnumBuilderContext = klass;
1911 }
1912 
1913 /*
1914  * call-seq:
1915  *     EnumBuilderContext.new(enumdesc) => context
1916  *
1917  * Create a new builder context around the given enum descriptor. This class is
1918  * intended to serve as a DSL context to be used with #instance_eval.
1919  */
EnumBuilderContext_initialize(VALUE _self,VALUE enumdef)1920 VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdef) {
1921   DEFINE_SELF(EnumBuilderContext, self, _self);
1922   self->enumdesc = enumdef;
1923   return Qnil;
1924 }
1925 
enumdef_add_value(VALUE enumdef,VALUE name,VALUE number)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   return Qnil;
1930 }
1931 
1932 /*
1933  * call-seq:
1934  *     EnumBuilder.add_value(name, number)
1935  *
1936  * Adds the given name => number mapping to the enum type. Name must be a Ruby
1937  * symbol.
1938  */
EnumBuilderContext_value(VALUE _self,VALUE name,VALUE number)1939 VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
1940   DEFINE_SELF(EnumBuilderContext, self, _self);
1941   return enumdef_add_value(self->enumdesc, name, number);
1942 }
1943 
1944 
1945 // -----------------------------------------------------------------------------
1946 // FileBuilderContext.
1947 // -----------------------------------------------------------------------------
1948 
1949 DEFINE_CLASS(FileBuilderContext,
1950 	     "Google::Protobuf::Internal::FileBuilderContext");
1951 
FileBuilderContext_mark(void * _self)1952 void FileBuilderContext_mark(void* _self) {
1953   FileBuilderContext* self = _self;
1954   rb_gc_mark(self->pending_list);
1955   rb_gc_mark(self->file_descriptor);
1956   rb_gc_mark(self->builder);
1957 }
1958 
FileBuilderContext_free(void * _self)1959 void FileBuilderContext_free(void* _self) {
1960   FileBuilderContext* self = _self;
1961   xfree(self);
1962 }
1963 
FileBuilderContext_alloc(VALUE klass)1964 VALUE FileBuilderContext_alloc(VALUE klass) {
1965   FileBuilderContext* self = ALLOC(FileBuilderContext);
1966   VALUE ret = TypedData_Wrap_Struct(klass, &_FileBuilderContext_type, self);
1967   self->pending_list = Qnil;
1968   self->file_descriptor = Qnil;
1969   self->builder = Qnil;
1970   return ret;
1971 }
1972 
FileBuilderContext_register(VALUE module)1973 void FileBuilderContext_register(VALUE module) {
1974   VALUE klass = rb_define_class_under(module, "FileBuilderContext", rb_cObject);
1975   rb_define_alloc_func(klass, FileBuilderContext_alloc);
1976   rb_define_method(klass, "initialize", FileBuilderContext_initialize, 2);
1977   rb_define_method(klass, "add_message", FileBuilderContext_add_message, 1);
1978   rb_define_method(klass, "add_enum", FileBuilderContext_add_enum, 1);
1979   rb_gc_register_address(&cFileBuilderContext);
1980   cFileBuilderContext = klass;
1981 }
1982 
1983 /*
1984  * call-seq:
1985  *     FileBuilderContext.new(file_descriptor, builder) => context
1986  *
1987  * Create a new file builder context for the given file descriptor and
1988  * builder context. This class is intended to serve as a DSL context to be used
1989  * with #instance_eval.
1990  */
FileBuilderContext_initialize(VALUE _self,VALUE file_descriptor,VALUE builder)1991 VALUE FileBuilderContext_initialize(VALUE _self, VALUE file_descriptor,
1992 				    VALUE builder) {
1993   DEFINE_SELF(FileBuilderContext, self, _self);
1994   self->pending_list = rb_ary_new();
1995   self->file_descriptor = file_descriptor;
1996   self->builder = builder;
1997   return Qnil;
1998 }
1999 
2000 /*
2001  * call-seq:
2002  *     FileBuilderContext.add_message(name, &block)
2003  *
2004  * Creates a new, empty descriptor with the given name, and invokes the block in
2005  * the context of a MessageBuilderContext on that descriptor. The block can then
2006  * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
2007  * methods to define the message fields.
2008  *
2009  * This is the recommended, idiomatic way to build message definitions.
2010  */
FileBuilderContext_add_message(VALUE _self,VALUE name)2011 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 };
2015   VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
2016   VALUE block = rb_block_proc();
2017   rb_funcall(msgdef, rb_intern("name="), 1, name);
2018   rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2019   rb_ary_push(self->pending_list, msgdef);
2020   return Qnil;
2021 }
2022 
2023 /*
2024  * call-seq:
2025  *     FileBuilderContext.add_enum(name, &block)
2026  *
2027  * Creates a new, empty enum descriptor with the given name, and invokes the
2028  * block in the context of an EnumBuilderContext on that descriptor. The block
2029  * can then call EnumBuilderContext#add_value to define the enum values.
2030  *
2031  * This is the recommended, idiomatic way to build enum definitions.
2032  */
FileBuilderContext_add_enum(VALUE _self,VALUE name)2033 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);
2038   VALUE block = rb_block_proc();
2039   rb_funcall(enumdef, rb_intern("name="), 1, name);
2040   rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2041   rb_ary_push(self->pending_list, enumdef);
2042   return Qnil;
2043 }
2044 
FileBuilderContext_pending_descriptors(VALUE _self)2045 VALUE FileBuilderContext_pending_descriptors(VALUE _self) {
2046   DEFINE_SELF(FileBuilderContext, self, _self);
2047   return self->pending_list;
2048 }
2049 
2050 // -----------------------------------------------------------------------------
2051 // Builder.
2052 // -----------------------------------------------------------------------------
2053 
2054 DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
2055 
Builder_mark(void * _self)2056 void Builder_mark(void* _self) {
2057   Builder* self = _self;
2058   rb_gc_mark(self->pending_list);
2059   rb_gc_mark(self->default_file_descriptor);
2060 }
2061 
Builder_free(void * _self)2062 void Builder_free(void* _self) {
2063   Builder* self = _self;
2064   xfree(self->defs);
2065   xfree(self);
2066 }
2067 
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  */
Builder_alloc(VALUE klass)2076 VALUE Builder_alloc(VALUE klass) {
2077   Builder* self = ALLOC(Builder);
2078   VALUE ret = TypedData_Wrap_Struct(
2079       klass, &_Builder_type, self);
2080   self->pending_list = Qnil;
2081   self->defs = NULL;
2082   self->default_file_descriptor = Qnil;
2083   return ret;
2084 }
2085 
Builder_register(VALUE module)2086 void Builder_register(VALUE module) {
2087   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);
2090   rb_define_method(klass, "add_file", Builder_add_file, -1);
2091   rb_define_method(klass, "add_message", Builder_add_message, 1);
2092   rb_define_method(klass, "add_enum", Builder_add_enum, 1);
2093   rb_define_method(klass, "finalize_to_pool", Builder_finalize_to_pool, 1);
2094   rb_gc_register_address(&cBuilder);
2095   cBuilder = klass;
2096 }
2097 
2098 /*
2099  * call-seq:
2100  *    Builder.new
2101  *
2102  * Initializes a new builder.
2103  */
Builder_initialize(VALUE _self)2104 VALUE Builder_initialize(VALUE _self) {
2105   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);
2110   return Qnil;
2111 }
2112 
2113 /*
2114  * call-seq:
2115  *     Builder.add_file(name, options = nil, &block)
2116  *
2117  * Creates a new, file descriptor with the given name and options and invokes
2118  * the block in the context of a FileBuilderContext on that descriptor. The
2119  * block can then call FileBuilderContext#add_message or
2120  * FileBuilderContext#add_enum to define new messages or enums, respectively.
2121  *
2122  * This is the recommended, idiomatic way to build file descriptors.
2123  */
Builder_add_file(int argc,VALUE * argv,VALUE _self)2124 VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
2125   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();
2130   rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2131 
2132   rb_ary_concat(self->pending_list,
2133       FileBuilderContext_pending_descriptors(ctx));
2134   return Qnil;
2135 }
2136 
2137 /*
2138  * call-seq:
2139  *     Builder.add_message(name, &block)
2140  *
2141  * Old and deprecated way to create a new descriptor.
2142  * See FileBuilderContext.add_message for the recommended way.
2143  *
2144  * Exists for backwards compatibility to allow building descriptor pool for
2145  * files generated by protoc which don't add messages within "add_file" block.
2146  * Descriptors created this way get assigned to a default empty FileDescriptor.
2147  */
Builder_add_message(VALUE _self,VALUE name)2148 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);
2158   return Qnil;
2159 }
2160 
2161 /*
2162  * call-seq:
2163  *     Builder.add_enum(name, &block)
2164  *
2165  * Old and deprecated way to create a new enum descriptor.
2166  * See FileBuilderContext.add_enum for the recommended way.
2167  *
2168  * Exists for backwards compatibility to allow building descriptor pool for
2169  * files generated by protoc which don't add enums within "add_file" block.
2170  * Enum descriptors created this way get assigned to a default empty
2171  * FileDescriptor.
2172  */
Builder_add_enum(VALUE _self,VALUE name)2173 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);
2182   return Qnil;
2183 }
2184 
proto3_validate_msgdef(const upb_msgdef * msgdef)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 }
2197 
proto3_validate_enumdef(const upb_enumdef * enumdef)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'.");
2205   }
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  */
Builder_finalize_to_pool(VALUE _self,VALUE pool_rb)2222 VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb) {
2223   DEFINE_SELF(Builder, self, _self);
2224 
2225   DescriptorPool* pool = ruby_to_DescriptorPool(pool_rb);
2226 
2227   REALLOC_N(self->defs, upb_def*, RARRAY_LEN(self->pending_list));
2228 
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;
2233 
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;
2239 
2240       if (upb_filedef_syntax(upb_def_file(self->defs[i])) == UPB_SYNTAX_PROTO3) {
2241         proto3_validate_enumdef((const upb_enumdef*)self->defs[i]);
2242       }
2243     }
2244   }
2245 
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");
2249 
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   }
2254 
2255   self->pending_list = rb_ary_new();
2256   return Qnil;
2257 }
2258