google-protobuf-z 3.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a44d23436ff96b0915212a49c379781a384775b4
4
+ data.tar.gz: 90fff3425a4cde089076e23afae84efbe7483b68
5
+ SHA512:
6
+ metadata.gz: a895814dc0d8a5b5186018b213b641e0faf069de9d2e41f6c9dd1999b7b1cc09e9ed3f4d5335b5b2c35c52610524337b31183c2e5597dc6e2d54af1cdd0f4eba
7
+ data.tar.gz: 5bfab24d5486b921f3a7ed1f81c4947fe849823c0b391f2839931498fa9f4b82edff49fc2e407b8e48398ef9960678769f05dec32fcb09222cf200735dd6a9b5
@@ -0,0 +1,2257 @@
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
+
37
+ static const char* get_str(VALUE str) {
38
+ Check_Type(str, T_STRING);
39
+ return RSTRING_PTR(str);
40
+ }
41
+
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
+
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
+
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
+
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
+
66
+ static upb_oneofdef* check_oneof_notfrozen(const upb_oneofdef* def) {
67
+ return (upb_oneofdef*)check_notfrozen((const upb_def*)def);
68
+ }
69
+
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
+
99
+ void DescriptorPool_mark(void* _self) {
100
+ }
101
+
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
+ */
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
+
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
+
136
+ static void add_descriptor_to_pool(DescriptorPool* self,
137
+ Descriptor* descriptor) {
138
+ CHECK_UPB(
139
+ upb_symtab_add(self->symtab, (upb_def**)&descriptor->msgdef, 1,
140
+ NULL, &status),
141
+ "Adding Descriptor to DescriptorPool failed");
142
+ }
143
+
144
+ static void add_enumdesc_to_pool(DescriptorPool* self,
145
+ EnumDescriptor* enumdesc) {
146
+ CHECK_UPB(
147
+ upb_symtab_add(self->symtab, (upb_def**)&enumdesc->enumdef, 1,
148
+ NULL, &status),
149
+ "Adding EnumDescriptor to DescriptorPool failed");
150
+ }
151
+
152
+ /*
153
+ * call-seq:
154
+ * DescriptorPool.add(descriptor)
155
+ *
156
+ * Adds the given Descriptor or EnumDescriptor to this pool. All references to
157
+ * other types in a Descriptor's fields must be resolvable within this pool or
158
+ * an exception will be raised.
159
+ */
160
+ VALUE DescriptorPool_add(VALUE _self, VALUE def) {
161
+ DEFINE_SELF(DescriptorPool, self, _self);
162
+ VALUE def_klass = rb_obj_class(def);
163
+ if (def_klass == cDescriptor) {
164
+ add_descriptor_to_pool(self, ruby_to_Descriptor(def));
165
+ } else if (def_klass == cEnumDescriptor) {
166
+ add_enumdesc_to_pool(self, ruby_to_EnumDescriptor(def));
167
+ } else {
168
+ rb_raise(rb_eArgError,
169
+ "Second argument must be a Descriptor or EnumDescriptor.");
170
+ }
171
+ return Qnil;
172
+ }
173
+
174
+ /*
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
+ */
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
+ */
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
+ */
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
+
228
+ void Descriptor_mark(void* _self) {
229
+ Descriptor* self = _self;
230
+ rb_gc_mark(self->klass);
231
+ }
232
+
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
+ */
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
+
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
413
+ VALUE Descriptor_add_field(VALUE _self, VALUE obj) {
414
+ DEFINE_SELF(Descriptor, self, _self);
415
+ upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
416
+ FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
417
+ upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
418
+ CHECK_UPB(
419
+ upb_msgdef_addfield(mut_def, mut_field_def, NULL, &status),
420
+ "Adding field to Descriptor failed");
421
+ add_def_obj(def->fielddef, obj);
422
+ return Qnil;
423
+ }
424
+
425
+ /*
426
+ * call-seq:
427
+ * Descriptor.add_oneof(oneof) => nil
428
+ *
429
+ * Adds the given OneofDescriptor to this message type. This descriptor must not
430
+ * have been added to a pool yet. Raises an exception if a oneof with the same
431
+ * name already exists, or if any of the oneof's fields' names or numbers
432
+ * conflict with an existing field in this message type. All fields in the oneof
433
+ * are added to the message descriptor. Sub-type references (e.g. for fields of
434
+ * type message) are not resolved at this point.
435
+ */
436
+ VALUE Descriptor_add_oneof(VALUE _self, VALUE obj) {
437
+ DEFINE_SELF(Descriptor, self, _self);
438
+ upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
439
+ OneofDescriptor* def = ruby_to_OneofDescriptor(obj);
440
+ upb_oneofdef* mut_oneof_def = check_oneof_notfrozen(def->oneofdef);
441
+ CHECK_UPB(
442
+ upb_msgdef_addoneof(mut_def, mut_oneof_def, NULL, &status),
443
+ "Adding oneof to Descriptor failed");
444
+ add_def_obj(def->oneofdef, obj);
445
+ return Qnil;
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
+ */
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
+ */
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
+ */
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
+
511
+ void FileDescriptor_mark(void* _self) {
512
+ }
513
+
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
+ */
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
+
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
+ */
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
+ */
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
+ */
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
+ */
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
+
647
+ void FieldDescriptor_mark(void* _self) {
648
+ }
649
+
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
+ */
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
+
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
+ */
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
+ */
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
+
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
+
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
+
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
+
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+
1162
+ void OneofDescriptor_mark(void* _self) {
1163
+ }
1164
+
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
+ */
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
+
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
+ */
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
+ */
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
+ */
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
+ */
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
+
1276
+ void EnumDescriptor_mark(void* _self) {
1277
+ EnumDescriptor* self = _self;
1278
+ rb_gc_mark(self->module);
1279
+ }
1280
+
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
+ */
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
+
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
+ */
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
+ */
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
+ */
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
+ */
1368
+ VALUE EnumDescriptor_name_set(VALUE _self, VALUE str) {
1369
+ DEFINE_SELF(EnumDescriptor, self, _self);
1370
+ upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
1371
+ const char* name = get_str(str);
1372
+ CHECK_UPB(upb_enumdef_setfullname(mut_def, name, &status),
1373
+ "Error setting EnumDescriptor name");
1374
+ return Qnil;
1375
+ }
1376
+
1377
+ /*
1378
+ * call-seq:
1379
+ * EnumDescriptor.add_value(key, value)
1380
+ *
1381
+ * Adds a new key => value mapping to this enum type. Key must be given as a
1382
+ * Ruby symbol. Cannot be called if the enum type has already been added to a
1383
+ * pool. Will raise an exception if the key or value is already in use.
1384
+ */
1385
+ VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number) {
1386
+ DEFINE_SELF(EnumDescriptor, self, _self);
1387
+ upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
1388
+ const char* name_str = rb_id2name(SYM2ID(name));
1389
+ int32_t val = NUM2INT(number);
1390
+ CHECK_UPB(upb_enumdef_addval(mut_def, name_str, val, &status),
1391
+ "Error adding value to enum");
1392
+ return Qnil;
1393
+ }
1394
+
1395
+ /*
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
+ */
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
+ */
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
+ */
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
+ */
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
+
1480
+ void MessageBuilderContext_mark(void* _self) {
1481
+ MessageBuilderContext* self = _self;
1482
+ rb_gc_mark(self->descriptor);
1483
+ rb_gc_mark(self->builder);
1484
+ }
1485
+
1486
+ void MessageBuilderContext_free(void* _self) {
1487
+ MessageBuilderContext* self = _self;
1488
+ xfree(self);
1489
+ }
1490
+
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
+
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
+ */
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
+
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
+ */
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
+ */
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
+ */
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
+ */
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
+ */
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
+
1808
+ void OneofBuilderContext_mark(void* _self) {
1809
+ OneofBuilderContext* self = _self;
1810
+ rb_gc_mark(self->descriptor);
1811
+ rb_gc_mark(self->builder);
1812
+ }
1813
+
1814
+ void OneofBuilderContext_free(void* _self) {
1815
+ OneofBuilderContext* self = _self;
1816
+ xfree(self);
1817
+ }
1818
+
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
+
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
+ */
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
+ */
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
+
1884
+ void EnumBuilderContext_mark(void* _self) {
1885
+ EnumBuilderContext* self = _self;
1886
+ rb_gc_mark(self->enumdesc);
1887
+ }
1888
+
1889
+ void EnumBuilderContext_free(void* _self) {
1890
+ EnumBuilderContext* self = _self;
1891
+ xfree(self);
1892
+ }
1893
+
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
+
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
+ */
1920
+ VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdef) {
1921
+ DEFINE_SELF(EnumBuilderContext, self, _self);
1922
+ self->enumdesc = enumdef;
1923
+ return Qnil;
1924
+ }
1925
+
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
+ */
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
+
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
+
1959
+ void FileBuilderContext_free(void* _self) {
1960
+ FileBuilderContext* self = _self;
1961
+ xfree(self);
1962
+ }
1963
+
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
+
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
+ */
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
+ */
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
+ */
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
+
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
+
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
+
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
+ */
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
+
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
+ */
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
+ */
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
+ */
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
+ */
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
+
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
+
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
+ */
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
+ }