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