google-protobuf 3.0.0.alpha.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OWE5ZmI5M2U5MjEyNzljNzllZWQ2N2NlZjMyMDg0Y2UyNDk0MWYzMQ==
5
+ data.tar.gz: !binary |-
6
+ NmRjOWI5YTRhYmJmNjlkN2U5OGViYmNiNzVkNDRhODAxOWFhYzE4OQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZWUwYzIzODQwZDdjMzc3M2NmOGVhN2M0NWFlYzczYjRlZDg1OWViMTAzZDkz
10
+ M2UzNDg2YTcwYzVlY2ZiNmNkMDMwMjg0YTUzNGM1MGRjOTVjNjVhZDA0NmJi
11
+ MjY4NWY1Y2VkYzZiMzFhOWM4ODRiM2EwYTJhZjM1NDEwODVmZGQ=
12
+ data.tar.gz: !binary |-
13
+ N2E3OTFlMDNmYWZkNjQyZjM2ODk4YmE2YmU5MDczYzg2N2I4NTJhNzRjNmIw
14
+ MWNhNDU2ZWIwZWMyOTcyMmIzMWQxYjMyM2FlZTU0NDEwYzI3ZDk1Yzk4MzEw
15
+ YzUzNmFlZThkODNiNmE3ZTdjNmE2ZDFmMGYzYzg0NTA2NTM3MDQ=
@@ -0,0 +1,1286 @@
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
+ const char* kDescriptorInstanceVar = "descriptor";
38
+
39
+ static const char* get_str(VALUE str) {
40
+ Check_Type(str, T_STRING);
41
+ return RSTRING_PTR(str);
42
+ }
43
+
44
+ static VALUE rb_str_maybe_null(const char* s) {
45
+ if (s == NULL) {
46
+ s = "";
47
+ }
48
+ return rb_str_new2(s);
49
+ }
50
+
51
+ static upb_def* check_notfrozen(const upb_def* def) {
52
+ if (upb_def_isfrozen(def)) {
53
+ rb_raise(rb_eRuntimeError,
54
+ "Attempt to modify a frozen descriptor. Once descriptors are "
55
+ "added to the descriptor pool, they may not be modified.");
56
+ }
57
+ return (upb_def*)def;
58
+ }
59
+
60
+ static upb_msgdef* check_msg_notfrozen(const upb_msgdef* def) {
61
+ return (upb_msgdef*)check_notfrozen((const upb_def*)def);
62
+ }
63
+
64
+ static upb_fielddef* check_field_notfrozen(const upb_fielddef* def) {
65
+ return (upb_fielddef*)check_notfrozen((const upb_def*)def);
66
+ }
67
+
68
+ static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
69
+ return (upb_enumdef*)check_notfrozen((const upb_def*)def);
70
+ }
71
+
72
+ // -----------------------------------------------------------------------------
73
+ // DescriptorPool.
74
+ // -----------------------------------------------------------------------------
75
+
76
+ #define DEFINE_CLASS(name, string_name) \
77
+ VALUE c ## name; \
78
+ const rb_data_type_t _ ## name ## _type = { \
79
+ string_name, \
80
+ { name ## _mark, name ## _free, NULL }, \
81
+ }; \
82
+ name* ruby_to_ ## name(VALUE val) { \
83
+ name* ret; \
84
+ TypedData_Get_Struct(val, name, &_ ## name ## _type, ret); \
85
+ return ret; \
86
+ } \
87
+
88
+ #define DEFINE_SELF(type, var, rb_var) \
89
+ type* var = ruby_to_ ## type(rb_var);
90
+
91
+ // Global singleton DescriptorPool. The user is free to create others, but this
92
+ // is used by generated code.
93
+ VALUE generated_pool;
94
+
95
+ DEFINE_CLASS(DescriptorPool, "Google::Protobuf::DescriptorPool");
96
+
97
+ void DescriptorPool_mark(void* _self) {
98
+ }
99
+
100
+ void DescriptorPool_free(void* _self) {
101
+ DescriptorPool* self = _self;
102
+ upb_symtab_unref(self->symtab, &self->symtab);
103
+ xfree(self);
104
+ }
105
+
106
+ /*
107
+ * call-seq:
108
+ * DescriptorPool.new => pool
109
+ *
110
+ * Creates a new, empty, descriptor pool.
111
+ */
112
+ VALUE DescriptorPool_alloc(VALUE klass) {
113
+ DescriptorPool* self = ALLOC(DescriptorPool);
114
+ self->symtab = upb_symtab_new(&self->symtab);
115
+ return TypedData_Wrap_Struct(klass, &_DescriptorPool_type, self);
116
+ }
117
+
118
+ void DescriptorPool_register(VALUE module) {
119
+ VALUE klass = rb_define_class_under(
120
+ module, "DescriptorPool", rb_cObject);
121
+ rb_define_alloc_func(klass, DescriptorPool_alloc);
122
+ rb_define_method(klass, "add", DescriptorPool_add, 1);
123
+ rb_define_method(klass, "build", DescriptorPool_build, 0);
124
+ rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
125
+ rb_define_singleton_method(klass, "generated_pool",
126
+ DescriptorPool_generated_pool, 0);
127
+ cDescriptorPool = klass;
128
+ rb_gc_register_address(&cDescriptorPool);
129
+
130
+ generated_pool = rb_class_new_instance(0, NULL, klass);
131
+ rb_gc_register_address(&generated_pool);
132
+ }
133
+
134
+ static void add_descriptor_to_pool(DescriptorPool* self,
135
+ Descriptor* descriptor) {
136
+ CHECK_UPB(
137
+ upb_symtab_add(self->symtab, (upb_def**)&descriptor->msgdef, 1,
138
+ NULL, &status),
139
+ "Adding Descriptor to DescriptorPool failed");
140
+ }
141
+
142
+ static void add_enumdesc_to_pool(DescriptorPool* self,
143
+ EnumDescriptor* enumdesc) {
144
+ CHECK_UPB(
145
+ upb_symtab_add(self->symtab, (upb_def**)&enumdesc->enumdef, 1,
146
+ NULL, &status),
147
+ "Adding EnumDescriptor to DescriptorPool failed");
148
+ }
149
+
150
+ /*
151
+ * call-seq:
152
+ * DescriptorPool.add(descriptor)
153
+ *
154
+ * Adds the given Descriptor or EnumDescriptor to this pool. All references to
155
+ * other types in a Descriptor's fields must be resolvable within this pool or
156
+ * an exception will be raised.
157
+ */
158
+ VALUE DescriptorPool_add(VALUE _self, VALUE def) {
159
+ DEFINE_SELF(DescriptorPool, self, _self);
160
+ VALUE def_klass = rb_obj_class(def);
161
+ if (def_klass == cDescriptor) {
162
+ add_descriptor_to_pool(self, ruby_to_Descriptor(def));
163
+ } else if (def_klass == cEnumDescriptor) {
164
+ add_enumdesc_to_pool(self, ruby_to_EnumDescriptor(def));
165
+ } else {
166
+ rb_raise(rb_eArgError,
167
+ "Second argument must be a Descriptor or EnumDescriptor.");
168
+ }
169
+ return Qnil;
170
+ }
171
+
172
+ /*
173
+ * call-seq:
174
+ * DescriptorPool.build(&block)
175
+ *
176
+ * Invokes the block with a Builder instance as self. All message and enum types
177
+ * added within the block are committed to the pool atomically, and may refer
178
+ * (co)recursively to each other. The user should call Builder#add_message and
179
+ * Builder#add_enum within the block as appropriate. This is the recommended,
180
+ * idiomatic way to define new message and enum types.
181
+ */
182
+ VALUE DescriptorPool_build(VALUE _self) {
183
+ VALUE ctx = rb_class_new_instance(0, NULL, cBuilder);
184
+ VALUE block = rb_block_proc();
185
+ rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
186
+ rb_funcall(ctx, rb_intern("finalize_to_pool"), 1, _self);
187
+ return Qnil;
188
+ }
189
+
190
+ /*
191
+ * call-seq:
192
+ * DescriptorPool.lookup(name) => descriptor
193
+ *
194
+ * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
195
+ * exists with the given name.
196
+ */
197
+ VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
198
+ DEFINE_SELF(DescriptorPool, self, _self);
199
+ const char* name_str = get_str(name);
200
+ const upb_def* def = upb_symtab_lookup(self->symtab, name_str);
201
+ if (!def) {
202
+ return Qnil;
203
+ }
204
+ return get_def_obj(def);
205
+ }
206
+
207
+ /*
208
+ * call-seq:
209
+ * DescriptorPool.generated_pool => descriptor_pool
210
+ *
211
+ * Class method that returns the global DescriptorPool. This is a singleton into
212
+ * which generated-code message and enum types are registered. The user may also
213
+ * register types in this pool for convenience so that they do not have to hold
214
+ * a reference to a private pool instance.
215
+ */
216
+ VALUE DescriptorPool_generated_pool(VALUE _self) {
217
+ return generated_pool;
218
+ }
219
+
220
+ // -----------------------------------------------------------------------------
221
+ // Descriptor.
222
+ // -----------------------------------------------------------------------------
223
+
224
+ DEFINE_CLASS(Descriptor, "Google::Protobuf::Descriptor");
225
+
226
+ void Descriptor_mark(void* _self) {
227
+ Descriptor* self = _self;
228
+ rb_gc_mark(self->klass);
229
+ }
230
+
231
+ void Descriptor_free(void* _self) {
232
+ Descriptor* self = _self;
233
+ upb_msgdef_unref(self->msgdef, &self->msgdef);
234
+ if (self->layout) {
235
+ free_layout(self->layout);
236
+ }
237
+ if (self->fill_handlers) {
238
+ upb_handlers_unref(self->fill_handlers, &self->fill_handlers);
239
+ }
240
+ if (self->fill_method) {
241
+ upb_pbdecodermethod_unref(self->fill_method, &self->fill_method);
242
+ }
243
+ if (self->pb_serialize_handlers) {
244
+ upb_handlers_unref(self->pb_serialize_handlers,
245
+ &self->pb_serialize_handlers);
246
+ }
247
+ if (self->json_serialize_handlers) {
248
+ upb_handlers_unref(self->pb_serialize_handlers,
249
+ &self->json_serialize_handlers);
250
+ }
251
+ xfree(self);
252
+ }
253
+
254
+ /*
255
+ * call-seq:
256
+ * Descriptor.new => descriptor
257
+ *
258
+ * Creates a new, empty, message type descriptor. At a minimum, its name must be
259
+ * set before it is added to a pool. It cannot be used to create messages until
260
+ * it is added to a pool, after which it becomes immutable (as part of a
261
+ * finalization process).
262
+ */
263
+ VALUE Descriptor_alloc(VALUE klass) {
264
+ Descriptor* self = ALLOC(Descriptor);
265
+ VALUE ret = TypedData_Wrap_Struct(klass, &_Descriptor_type, self);
266
+ self->msgdef = upb_msgdef_new(&self->msgdef);
267
+ self->klass = Qnil;
268
+ self->layout = NULL;
269
+ self->fill_handlers = NULL;
270
+ self->fill_method = NULL;
271
+ self->pb_serialize_handlers = NULL;
272
+ self->json_serialize_handlers = NULL;
273
+ return ret;
274
+ }
275
+
276
+ void Descriptor_register(VALUE module) {
277
+ VALUE klass = rb_define_class_under(
278
+ module, "Descriptor", rb_cObject);
279
+ rb_define_alloc_func(klass, Descriptor_alloc);
280
+ rb_define_method(klass, "each", Descriptor_each, 0);
281
+ rb_define_method(klass, "lookup", Descriptor_lookup, 1);
282
+ rb_define_method(klass, "add_field", Descriptor_add_field, 1);
283
+ rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
284
+ rb_define_method(klass, "name", Descriptor_name, 0);
285
+ rb_define_method(klass, "name=", Descriptor_name_set, 1);
286
+ rb_include_module(klass, rb_mEnumerable);
287
+ cDescriptor = klass;
288
+ rb_gc_register_address(&cDescriptor);
289
+ }
290
+
291
+ /*
292
+ * call-seq:
293
+ * Descriptor.name => name
294
+ *
295
+ * Returns the name of this message type as a fully-qualfied string (e.g.,
296
+ * My.Package.MessageType).
297
+ */
298
+ VALUE Descriptor_name(VALUE _self) {
299
+ DEFINE_SELF(Descriptor, self, _self);
300
+ return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
301
+ }
302
+
303
+ /*
304
+ * call-seq:
305
+ * Descriptor.name = name
306
+ *
307
+ * Assigns a name to this message type. The descriptor must not have been added
308
+ * to a pool yet.
309
+ */
310
+ VALUE Descriptor_name_set(VALUE _self, VALUE str) {
311
+ DEFINE_SELF(Descriptor, self, _self);
312
+ upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
313
+ const char* name = get_str(str);
314
+ CHECK_UPB(
315
+ upb_msgdef_setfullname(mut_def, name, &status),
316
+ "Error setting Descriptor name");
317
+ return Qnil;
318
+ }
319
+
320
+ /*
321
+ * call-seq:
322
+ * Descriptor.each(&block)
323
+ *
324
+ * Iterates over fields in this message type, yielding to the block on each one.
325
+ */
326
+ VALUE Descriptor_each(VALUE _self) {
327
+ DEFINE_SELF(Descriptor, self, _self);
328
+
329
+ upb_msg_iter it;
330
+ for (upb_msg_begin(&it, self->msgdef);
331
+ !upb_msg_done(&it);
332
+ upb_msg_next(&it)) {
333
+ const upb_fielddef* field = upb_msg_iter_field(&it);
334
+ VALUE obj = get_def_obj(field);
335
+ rb_yield(obj);
336
+ }
337
+ return Qnil;
338
+ }
339
+
340
+ /*
341
+ * call-seq:
342
+ * Descriptor.lookup(name) => FieldDescriptor
343
+ *
344
+ * Returns the field descriptor for the field with the given name, if present,
345
+ * or nil if none.
346
+ */
347
+ VALUE Descriptor_lookup(VALUE _self, VALUE name) {
348
+ DEFINE_SELF(Descriptor, self, _self);
349
+ const char* s = get_str(name);
350
+ const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s);
351
+ if (field == NULL) {
352
+ return Qnil;
353
+ }
354
+ return get_def_obj(field);
355
+ }
356
+
357
+ /*
358
+ * call-seq:
359
+ * Descriptor.add_field(field) => nil
360
+ *
361
+ * Adds the given FieldDescriptor to this message type. The descriptor must not
362
+ * have been added to a pool yet. Raises an exception if a field with the same
363
+ * name or number already exists. Sub-type references (e.g. for fields of type
364
+ * message) are not resolved at this point.
365
+ */
366
+ VALUE Descriptor_add_field(VALUE _self, VALUE obj) {
367
+ DEFINE_SELF(Descriptor, self, _self);
368
+ upb_msgdef* mut_def = check_msg_notfrozen(self->msgdef);
369
+ FieldDescriptor* def = ruby_to_FieldDescriptor(obj);
370
+ upb_fielddef* mut_field_def = check_field_notfrozen(def->fielddef);
371
+ CHECK_UPB(
372
+ upb_msgdef_addfield(mut_def, mut_field_def, NULL, &status),
373
+ "Adding field to Descriptor failed");
374
+ add_def_obj(def->fielddef, obj);
375
+ return Qnil;
376
+ }
377
+
378
+ /*
379
+ * call-seq:
380
+ * Descriptor.msgclass => message_klass
381
+ *
382
+ * Returns the Ruby class created for this message type. Valid only once the
383
+ * message type has been added to a pool.
384
+ */
385
+ VALUE Descriptor_msgclass(VALUE _self) {
386
+ DEFINE_SELF(Descriptor, self, _self);
387
+ if (!upb_def_isfrozen((const upb_def*)self->msgdef)) {
388
+ rb_raise(rb_eRuntimeError,
389
+ "Cannot fetch message class from a Descriptor not yet in a pool.");
390
+ }
391
+ if (self->klass == Qnil) {
392
+ self->klass = build_class_from_descriptor(self);
393
+ }
394
+ return self->klass;
395
+ }
396
+
397
+ // -----------------------------------------------------------------------------
398
+ // FieldDescriptor.
399
+ // -----------------------------------------------------------------------------
400
+
401
+ DEFINE_CLASS(FieldDescriptor, "Google::Protobuf::FieldDescriptor");
402
+
403
+ void FieldDescriptor_mark(void* _self) {
404
+ }
405
+
406
+ void FieldDescriptor_free(void* _self) {
407
+ FieldDescriptor* self = _self;
408
+ upb_fielddef_unref(self->fielddef, &self->fielddef);
409
+ xfree(self);
410
+ }
411
+
412
+ /*
413
+ * call-seq:
414
+ * FieldDescriptor.new => field
415
+ *
416
+ * Returns a new field descriptor. Its name, type, etc. must be set before it is
417
+ * added to a message type.
418
+ */
419
+ VALUE FieldDescriptor_alloc(VALUE klass) {
420
+ FieldDescriptor* self = ALLOC(FieldDescriptor);
421
+ VALUE ret = TypedData_Wrap_Struct(klass, &_FieldDescriptor_type, self);
422
+ upb_fielddef* fielddef = upb_fielddef_new(&self->fielddef);
423
+ upb_fielddef_setpacked(fielddef, false);
424
+ self->fielddef = fielddef;
425
+ return ret;
426
+ }
427
+
428
+ void FieldDescriptor_register(VALUE module) {
429
+ VALUE klass = rb_define_class_under(
430
+ module, "FieldDescriptor", rb_cObject);
431
+ rb_define_alloc_func(klass, FieldDescriptor_alloc);
432
+ rb_define_method(klass, "name", FieldDescriptor_name, 0);
433
+ rb_define_method(klass, "name=", FieldDescriptor_name_set, 1);
434
+ rb_define_method(klass, "type", FieldDescriptor_type, 0);
435
+ rb_define_method(klass, "type=", FieldDescriptor_type_set, 1);
436
+ rb_define_method(klass, "label", FieldDescriptor_label, 0);
437
+ rb_define_method(klass, "label=", FieldDescriptor_label_set, 1);
438
+ rb_define_method(klass, "number", FieldDescriptor_number, 0);
439
+ rb_define_method(klass, "number=", FieldDescriptor_number_set, 1);
440
+ rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
441
+ rb_define_method(klass, "submsg_name=", FieldDescriptor_submsg_name_set, 1);
442
+ rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
443
+ rb_define_method(klass, "get", FieldDescriptor_get, 1);
444
+ rb_define_method(klass, "set", FieldDescriptor_set, 2);
445
+ cFieldDescriptor = klass;
446
+ rb_gc_register_address(&cFieldDescriptor);
447
+ }
448
+
449
+ /*
450
+ * call-seq:
451
+ * FieldDescriptor.name => name
452
+ *
453
+ * Returns the name of this field.
454
+ */
455
+ VALUE FieldDescriptor_name(VALUE _self) {
456
+ DEFINE_SELF(FieldDescriptor, self, _self);
457
+ return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
458
+ }
459
+
460
+ /*
461
+ * call-seq:
462
+ * FieldDescriptor.name = name
463
+ *
464
+ * Sets the name of this field. Cannot be called once the containing message
465
+ * type, if any, is added to a pool.
466
+ */
467
+ VALUE FieldDescriptor_name_set(VALUE _self, VALUE str) {
468
+ DEFINE_SELF(FieldDescriptor, self, _self);
469
+ upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
470
+ const char* name = get_str(str);
471
+ CHECK_UPB(upb_fielddef_setname(mut_def, name, &status),
472
+ "Error setting FieldDescriptor name");
473
+ return Qnil;
474
+ }
475
+
476
+ upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
477
+ if (TYPE(type) != T_SYMBOL) {
478
+ rb_raise(rb_eArgError, "Expected symbol for field type.");
479
+ }
480
+
481
+ upb_fieldtype_t upb_type = -1;
482
+
483
+ #define CONVERT(upb, ruby) \
484
+ if (SYM2ID(type) == rb_intern( # ruby )) { \
485
+ upb_type = UPB_TYPE_ ## upb; \
486
+ }
487
+
488
+ CONVERT(FLOAT, float);
489
+ CONVERT(DOUBLE, double);
490
+ CONVERT(BOOL, bool);
491
+ CONVERT(STRING, string);
492
+ CONVERT(BYTES, bytes);
493
+ CONVERT(MESSAGE, message);
494
+ CONVERT(ENUM, enum);
495
+ CONVERT(INT32, int32);
496
+ CONVERT(INT64, int64);
497
+ CONVERT(UINT32, uint32);
498
+ CONVERT(UINT64, uint64);
499
+
500
+ #undef CONVERT
501
+
502
+ if (upb_type == -1) {
503
+ rb_raise(rb_eArgError, "Unknown field type.");
504
+ }
505
+
506
+ return upb_type;
507
+ }
508
+
509
+ VALUE fieldtype_to_ruby(upb_fieldtype_t type) {
510
+ switch (type) {
511
+ #define CONVERT(upb, ruby) \
512
+ case UPB_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
513
+ CONVERT(FLOAT, float);
514
+ CONVERT(DOUBLE, double);
515
+ CONVERT(BOOL, bool);
516
+ CONVERT(STRING, string);
517
+ CONVERT(BYTES, bytes);
518
+ CONVERT(MESSAGE, message);
519
+ CONVERT(ENUM, enum);
520
+ CONVERT(INT32, int32);
521
+ CONVERT(INT64, int64);
522
+ CONVERT(UINT32, uint32);
523
+ CONVERT(UINT64, uint64);
524
+ #undef CONVERT
525
+ }
526
+ return Qnil;
527
+ }
528
+
529
+ /*
530
+ * call-seq:
531
+ * FieldDescriptor.type => type
532
+ *
533
+ * Returns this field's type, as a Ruby symbol, or nil if not yet set.
534
+ *
535
+ * Valid field types are:
536
+ * :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string,
537
+ * :bytes, :message.
538
+ */
539
+ VALUE FieldDescriptor_type(VALUE _self) {
540
+ DEFINE_SELF(FieldDescriptor, self, _self);
541
+ if (!upb_fielddef_typeisset(self->fielddef)) {
542
+ return Qnil;
543
+ }
544
+ return fieldtype_to_ruby(upb_fielddef_type(self->fielddef));
545
+ }
546
+
547
+ /*
548
+ * call-seq:
549
+ * FieldDescriptor.type = type
550
+ *
551
+ * Sets this field's type. Cannot be called if field is part of a message type
552
+ * already in a pool.
553
+ */
554
+ VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
555
+ DEFINE_SELF(FieldDescriptor, self, _self);
556
+ upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
557
+ upb_fielddef_settype(mut_def, ruby_to_fieldtype(type));
558
+ return Qnil;
559
+ }
560
+
561
+ /*
562
+ * call-seq:
563
+ * FieldDescriptor.label => label
564
+ *
565
+ * Returns this field's label (i.e., plurality), as a Ruby symbol.
566
+ *
567
+ * Valid field labels are:
568
+ * :optional, :repeated
569
+ */
570
+ VALUE FieldDescriptor_label(VALUE _self) {
571
+ DEFINE_SELF(FieldDescriptor, self, _self);
572
+ switch (upb_fielddef_label(self->fielddef)) {
573
+ #define CONVERT(upb, ruby) \
574
+ case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby ));
575
+
576
+ CONVERT(OPTIONAL, optional);
577
+ CONVERT(REQUIRED, required);
578
+ CONVERT(REPEATED, repeated);
579
+
580
+ #undef CONVERT
581
+ }
582
+
583
+ return Qnil;
584
+ }
585
+
586
+ /*
587
+ * call-seq:
588
+ * FieldDescriptor.label = label
589
+ *
590
+ * Sets the label on this field. Cannot be called if field is part of a message
591
+ * type already in a pool.
592
+ */
593
+ VALUE FieldDescriptor_label_set(VALUE _self, VALUE label) {
594
+ DEFINE_SELF(FieldDescriptor, self, _self);
595
+ upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
596
+ if (TYPE(label) != T_SYMBOL) {
597
+ rb_raise(rb_eArgError, "Expected symbol for field label.");
598
+ }
599
+
600
+ upb_label_t upb_label = -1;
601
+
602
+ #define CONVERT(upb, ruby) \
603
+ if (SYM2ID(label) == rb_intern( # ruby )) { \
604
+ upb_label = UPB_LABEL_ ## upb; \
605
+ }
606
+
607
+ CONVERT(OPTIONAL, optional);
608
+ CONVERT(REQUIRED, required);
609
+ CONVERT(REPEATED, repeated);
610
+
611
+ #undef CONVERT
612
+
613
+ if (upb_label == -1) {
614
+ rb_raise(rb_eArgError, "Unknown field label.");
615
+ }
616
+
617
+ upb_fielddef_setlabel(mut_def, upb_label);
618
+
619
+ return Qnil;
620
+ }
621
+
622
+ /*
623
+ * call-seq:
624
+ * FieldDescriptor.number => number
625
+ *
626
+ * Returns the tag number for this field.
627
+ */
628
+ VALUE FieldDescriptor_number(VALUE _self) {
629
+ DEFINE_SELF(FieldDescriptor, self, _self);
630
+ return INT2NUM(upb_fielddef_number(self->fielddef));
631
+ }
632
+
633
+ /*
634
+ * call-seq:
635
+ * FieldDescriptor.number = number
636
+ *
637
+ * Sets the tag number for this field. Cannot be called if field is part of a
638
+ * message type already in a pool.
639
+ */
640
+ VALUE FieldDescriptor_number_set(VALUE _self, VALUE number) {
641
+ DEFINE_SELF(FieldDescriptor, self, _self);
642
+ upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
643
+ CHECK_UPB(upb_fielddef_setnumber(mut_def, NUM2INT(number), &status),
644
+ "Error setting field number");
645
+ return Qnil;
646
+ }
647
+
648
+ /*
649
+ * call-seq:
650
+ * FieldDescriptor.submsg_name => submsg_name
651
+ *
652
+ * Returns the name of the message or enum type corresponding to this field, if
653
+ * it is a message or enum field (respectively), or nil otherwise. This type
654
+ * name will be resolved within the context of the pool to which the containing
655
+ * message type is added.
656
+ */
657
+ VALUE FieldDescriptor_submsg_name(VALUE _self) {
658
+ DEFINE_SELF(FieldDescriptor, self, _self);
659
+ if (!upb_fielddef_hassubdef(self->fielddef)) {
660
+ return Qnil;
661
+ }
662
+ return rb_str_maybe_null(upb_fielddef_subdefname(self->fielddef));
663
+ }
664
+
665
+ /*
666
+ * call-seq:
667
+ * FieldDescriptor.submsg_name = submsg_name
668
+ *
669
+ * Sets the name of the message or enum type corresponding to this field, if it
670
+ * is a message or enum field (respectively). This type name will be resolved
671
+ * within the context of the pool to which the containing message type is added.
672
+ * Cannot be called on field that are not of message or enum type, or on fields
673
+ * that are part of a message type already added to a pool.
674
+ */
675
+ VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
676
+ DEFINE_SELF(FieldDescriptor, self, _self);
677
+ upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
678
+ if (!upb_fielddef_hassubdef(self->fielddef)) {
679
+ rb_raise(rb_eTypeError, "FieldDescriptor does not have subdef.");
680
+ }
681
+ const char* str = get_str(value);
682
+ CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
683
+ "Error setting submessage name");
684
+ return Qnil;
685
+ }
686
+
687
+ /*
688
+ * call-seq:
689
+ * FieldDescriptor.subtype => message_or_enum_descriptor
690
+ *
691
+ * Returns the message or enum descriptor corresponding to this field's type if
692
+ * it is a message or enum field, respectively, or nil otherwise. Cannot be
693
+ * called *until* the containing message type is added to a pool (and thus
694
+ * resolved).
695
+ */
696
+ VALUE FieldDescriptor_subtype(VALUE _self) {
697
+ DEFINE_SELF(FieldDescriptor, self, _self);
698
+ if (!upb_fielddef_hassubdef(self->fielddef)) {
699
+ return Qnil;
700
+ }
701
+ const upb_def* def = upb_fielddef_subdef(self->fielddef);
702
+ if (def == NULL) {
703
+ return Qnil;
704
+ }
705
+ return get_def_obj(def);
706
+ }
707
+
708
+ /*
709
+ * call-seq:
710
+ * FieldDescriptor.get(message) => value
711
+ *
712
+ * Returns the value set for this field on the given message. Raises an
713
+ * exception if message is of the wrong type.
714
+ */
715
+ VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
716
+ DEFINE_SELF(FieldDescriptor, self, _self);
717
+ MessageHeader* msg;
718
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
719
+ if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
720
+ rb_raise(rb_eTypeError, "get method called on wrong message type");
721
+ }
722
+ return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
723
+ }
724
+
725
+ /*
726
+ * call-seq:
727
+ * FieldDescriptor.set(message, value)
728
+ *
729
+ * Sets the value corresponding to this field to the given value on the given
730
+ * message. Raises an exception if message is of the wrong type. Performs the
731
+ * ordinary type-checks for field setting.
732
+ */
733
+ VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
734
+ DEFINE_SELF(FieldDescriptor, self, _self);
735
+ MessageHeader* msg;
736
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
737
+ if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
738
+ rb_raise(rb_eTypeError, "set method called on wrong message type");
739
+ }
740
+ layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
741
+ return Qnil;
742
+ }
743
+
744
+ // -----------------------------------------------------------------------------
745
+ // EnumDescriptor.
746
+ // -----------------------------------------------------------------------------
747
+
748
+ DEFINE_CLASS(EnumDescriptor, "Google::Protobuf::EnumDescriptor");
749
+
750
+ void EnumDescriptor_mark(void* _self) {
751
+ EnumDescriptor* self = _self;
752
+ rb_gc_mark(self->module);
753
+ }
754
+
755
+ void EnumDescriptor_free(void* _self) {
756
+ EnumDescriptor* self = _self;
757
+ upb_enumdef_unref(self->enumdef, &self->enumdef);
758
+ xfree(self);
759
+ }
760
+
761
+ /*
762
+ * call-seq:
763
+ * EnumDescriptor.new => enum_descriptor
764
+ *
765
+ * Creates a new, empty, enum descriptor. Must be added to a pool before the
766
+ * enum type can be used. The enum type may only be modified prior to adding to
767
+ * a pool.
768
+ */
769
+ VALUE EnumDescriptor_alloc(VALUE klass) {
770
+ EnumDescriptor* self = ALLOC(EnumDescriptor);
771
+ VALUE ret = TypedData_Wrap_Struct(klass, &_EnumDescriptor_type, self);
772
+ self->enumdef = upb_enumdef_new(&self->enumdef);
773
+ self->module = Qnil;
774
+ return ret;
775
+ }
776
+
777
+ void EnumDescriptor_register(VALUE module) {
778
+ VALUE klass = rb_define_class_under(
779
+ module, "EnumDescriptor", rb_cObject);
780
+ rb_define_alloc_func(klass, EnumDescriptor_alloc);
781
+ rb_define_method(klass, "name", EnumDescriptor_name, 0);
782
+ rb_define_method(klass, "name=", EnumDescriptor_name_set, 1);
783
+ rb_define_method(klass, "add_value", EnumDescriptor_add_value, 2);
784
+ rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
785
+ rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
786
+ rb_define_method(klass, "each", EnumDescriptor_each, 0);
787
+ rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
788
+ rb_include_module(klass, rb_mEnumerable);
789
+ cEnumDescriptor = klass;
790
+ rb_gc_register_address(&cEnumDescriptor);
791
+ }
792
+
793
+ /*
794
+ * call-seq:
795
+ * EnumDescriptor.name => name
796
+ *
797
+ * Returns the name of this enum type.
798
+ */
799
+ VALUE EnumDescriptor_name(VALUE _self) {
800
+ DEFINE_SELF(EnumDescriptor, self, _self);
801
+ return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
802
+ }
803
+
804
+ /*
805
+ * call-seq:
806
+ * EnumDescriptor.name = name
807
+ *
808
+ * Sets the name of this enum type. Cannot be called if the enum type has
809
+ * already been added to a pool.
810
+ */
811
+ VALUE EnumDescriptor_name_set(VALUE _self, VALUE str) {
812
+ DEFINE_SELF(EnumDescriptor, self, _self);
813
+ upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
814
+ const char* name = get_str(str);
815
+ CHECK_UPB(upb_enumdef_setfullname(mut_def, name, &status),
816
+ "Error setting EnumDescriptor name");
817
+ return Qnil;
818
+ }
819
+
820
+ /*
821
+ * call-seq:
822
+ * EnumDescriptor.add_value(key, value)
823
+ *
824
+ * Adds a new key => value mapping to this enum type. Key must be given as a
825
+ * Ruby symbol. Cannot be called if the enum type has already been added to a
826
+ * pool. Will raise an exception if the key or value is already in use.
827
+ */
828
+ VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number) {
829
+ DEFINE_SELF(EnumDescriptor, self, _self);
830
+ upb_enumdef* mut_def = check_enum_notfrozen(self->enumdef);
831
+ const char* name_str = rb_id2name(SYM2ID(name));
832
+ int32_t val = NUM2INT(number);
833
+ CHECK_UPB(upb_enumdef_addval(mut_def, name_str, val, &status),
834
+ "Error adding value to enum");
835
+ return Qnil;
836
+ }
837
+
838
+ /*
839
+ * call-seq:
840
+ * EnumDescriptor.lookup_name(name) => value
841
+ *
842
+ * Returns the numeric value corresponding to the given key name (as a Ruby
843
+ * symbol), or nil if none.
844
+ */
845
+ VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
846
+ DEFINE_SELF(EnumDescriptor, self, _self);
847
+ const char* name_str= rb_id2name(SYM2ID(name));
848
+ int32_t val = 0;
849
+ if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) {
850
+ return INT2NUM(val);
851
+ } else {
852
+ return Qnil;
853
+ }
854
+ }
855
+
856
+ /*
857
+ * call-seq:
858
+ * EnumDescriptor.lookup_value(name) => value
859
+ *
860
+ * Returns the key name (as a Ruby symbol) corresponding to the integer value,
861
+ * or nil if none.
862
+ */
863
+ VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
864
+ DEFINE_SELF(EnumDescriptor, self, _self);
865
+ int32_t val = NUM2INT(number);
866
+ const char* name = upb_enumdef_iton(self->enumdef, val);
867
+ if (name != NULL) {
868
+ return ID2SYM(rb_intern(name));
869
+ } else {
870
+ return Qnil;
871
+ }
872
+ }
873
+
874
+ /*
875
+ * call-seq:
876
+ * EnumDescriptor.each(&block)
877
+ *
878
+ * Iterates over key => value mappings in this enum's definition, yielding to
879
+ * the block with (key, value) arguments for each one.
880
+ */
881
+ VALUE EnumDescriptor_each(VALUE _self) {
882
+ DEFINE_SELF(EnumDescriptor, self, _self);
883
+
884
+ upb_enum_iter it;
885
+ for (upb_enum_begin(&it, self->enumdef);
886
+ !upb_enum_done(&it);
887
+ upb_enum_next(&it)) {
888
+ VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it)));
889
+ VALUE number = INT2NUM(upb_enum_iter_number(&it));
890
+ rb_yield_values(2, key, number);
891
+ }
892
+
893
+ return Qnil;
894
+ }
895
+
896
+ /*
897
+ * call-seq:
898
+ * EnumDescriptor.enummodule => module
899
+ *
900
+ * Returns the Ruby module corresponding to this enum type. Cannot be called
901
+ * until the enum descriptor has been added to a pool.
902
+ */
903
+ VALUE EnumDescriptor_enummodule(VALUE _self) {
904
+ DEFINE_SELF(EnumDescriptor, self, _self);
905
+ if (!upb_def_isfrozen((const upb_def*)self->enumdef)) {
906
+ rb_raise(rb_eRuntimeError,
907
+ "Cannot fetch enum module from an EnumDescriptor not yet "
908
+ "in a pool.");
909
+ }
910
+ if (self->module == Qnil) {
911
+ self->module = build_module_from_enumdesc(self);
912
+ }
913
+ return self->module;
914
+ }
915
+
916
+ // -----------------------------------------------------------------------------
917
+ // MessageBuilderContext.
918
+ // -----------------------------------------------------------------------------
919
+
920
+ DEFINE_CLASS(MessageBuilderContext,
921
+ "Google::Protobuf::Internal::MessageBuilderContext");
922
+
923
+ void MessageBuilderContext_mark(void* _self) {
924
+ MessageBuilderContext* self = _self;
925
+ rb_gc_mark(self->descriptor);
926
+ }
927
+
928
+ void MessageBuilderContext_free(void* _self) {
929
+ MessageBuilderContext* self = _self;
930
+ xfree(self);
931
+ }
932
+
933
+ VALUE MessageBuilderContext_alloc(VALUE klass) {
934
+ MessageBuilderContext* self = ALLOC(MessageBuilderContext);
935
+ VALUE ret = TypedData_Wrap_Struct(
936
+ klass, &_MessageBuilderContext_type, self);
937
+ self->descriptor = Qnil;
938
+ return ret;
939
+ }
940
+
941
+ void MessageBuilderContext_register(VALUE module) {
942
+ VALUE klass = rb_define_class_under(
943
+ module, "MessageBuilderContext", rb_cObject);
944
+ rb_define_alloc_func(klass, MessageBuilderContext_alloc);
945
+ rb_define_method(klass, "initialize",
946
+ MessageBuilderContext_initialize, 1);
947
+ rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
948
+ rb_define_method(klass, "required", MessageBuilderContext_required, -1);
949
+ rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
950
+ cMessageBuilderContext = klass;
951
+ rb_gc_register_address(&cMessageBuilderContext);
952
+ }
953
+
954
+ /*
955
+ * call-seq:
956
+ * MessageBuilderContext.new(desc) => context
957
+ *
958
+ * Create a new builder context around the given message descriptor. This class
959
+ * is intended to serve as a DSL context to be used with #instance_eval.
960
+ */
961
+ VALUE MessageBuilderContext_initialize(VALUE _self, VALUE msgdef) {
962
+ DEFINE_SELF(MessageBuilderContext, self, _self);
963
+ self->descriptor = msgdef;
964
+ return Qnil;
965
+ }
966
+
967
+ static VALUE msgdef_add_field(VALUE msgdef,
968
+ const char* label, VALUE name,
969
+ VALUE type, VALUE number,
970
+ VALUE type_class) {
971
+ VALUE fielddef = rb_class_new_instance(0, NULL, cFieldDescriptor);
972
+ VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
973
+
974
+ rb_funcall(fielddef, rb_intern("label="), 1, ID2SYM(rb_intern(label)));
975
+ rb_funcall(fielddef, rb_intern("name="), 1, name_str);
976
+ rb_funcall(fielddef, rb_intern("type="), 1, type);
977
+ rb_funcall(fielddef, rb_intern("number="), 1, number);
978
+
979
+ if (type_class != Qnil) {
980
+ if (TYPE(type_class) != T_STRING) {
981
+ rb_raise(rb_eArgError, "Expected string for type class");
982
+ }
983
+ // Make it an absolute type name by prepending a dot.
984
+ type_class = rb_str_append(rb_str_new2("."), type_class);
985
+ rb_funcall(fielddef, rb_intern("submsg_name="), 1, type_class);
986
+ }
987
+
988
+ rb_funcall(msgdef, rb_intern("add_field"), 1, fielddef);
989
+ return fielddef;
990
+ }
991
+
992
+ /*
993
+ * call-seq:
994
+ * MessageBuilderContext.optional(name, type, number, type_class = nil)
995
+ *
996
+ * Defines a new optional field on this message type with the given type, tag
997
+ * number, and type class (for message and enum fields). The type must be a Ruby
998
+ * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
999
+ * string, if present (as accepted by FieldDescriptor#submsg_name=).
1000
+ */
1001
+ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1002
+ DEFINE_SELF(MessageBuilderContext, self, _self);
1003
+
1004
+ if (argc < 3) {
1005
+ rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1006
+ }
1007
+ VALUE name = argv[0];
1008
+ VALUE type = argv[1];
1009
+ VALUE number = argv[2];
1010
+ VALUE type_class = (argc > 3) ? argv[3] : Qnil;
1011
+
1012
+ return msgdef_add_field(self->descriptor, "optional",
1013
+ name, type, number, type_class);
1014
+ }
1015
+
1016
+ /*
1017
+ * call-seq:
1018
+ * MessageBuilderContext.required(name, type, number, type_class = nil)
1019
+ *
1020
+ * Defines a new required field on this message type with the given type, tag
1021
+ * number, and type class (for message and enum fields). The type must be a Ruby
1022
+ * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1023
+ * string, if present (as accepted by FieldDescriptor#submsg_name=).
1024
+ *
1025
+ * Proto3 does not have required fields, but this method exists for
1026
+ * completeness. Any attempt to add a message type with required fields to a
1027
+ * pool will currently result in an error.
1028
+ */
1029
+ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1030
+ DEFINE_SELF(MessageBuilderContext, self, _self);
1031
+
1032
+ if (argc < 3) {
1033
+ rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1034
+ }
1035
+ VALUE name = argv[0];
1036
+ VALUE type = argv[1];
1037
+ VALUE number = argv[2];
1038
+ VALUE type_class = (argc > 3) ? argv[3] : Qnil;
1039
+
1040
+ return msgdef_add_field(self->descriptor, "required",
1041
+ name, type, number, type_class);
1042
+ }
1043
+
1044
+ /*
1045
+ * call-seq:
1046
+ * MessageBuilderContext.repeated(name, type, number, type_class = nil)
1047
+ *
1048
+ * Defines a new repeated field on this message type with the given type, tag
1049
+ * number, and type class (for message and enum fields). The type must be a Ruby
1050
+ * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1051
+ * string, if present (as accepted by FieldDescriptor#submsg_name=).
1052
+ */
1053
+ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1054
+ DEFINE_SELF(MessageBuilderContext, self, _self);
1055
+
1056
+ if (argc < 3) {
1057
+ rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1058
+ }
1059
+ VALUE name = argv[0];
1060
+ VALUE type = argv[1];
1061
+ VALUE number = argv[2];
1062
+ VALUE type_class = (argc > 3) ? argv[3] : Qnil;
1063
+
1064
+ return msgdef_add_field(self->descriptor, "repeated",
1065
+ name, type, number, type_class);
1066
+ }
1067
+
1068
+ // -----------------------------------------------------------------------------
1069
+ // EnumBuilderContext.
1070
+ // -----------------------------------------------------------------------------
1071
+
1072
+ DEFINE_CLASS(EnumBuilderContext,
1073
+ "Google::Protobuf::Internal::EnumBuilderContext");
1074
+
1075
+ void EnumBuilderContext_mark(void* _self) {
1076
+ EnumBuilderContext* self = _self;
1077
+ rb_gc_mark(self->enumdesc);
1078
+ }
1079
+
1080
+ void EnumBuilderContext_free(void* _self) {
1081
+ EnumBuilderContext* self = _self;
1082
+ xfree(self);
1083
+ }
1084
+
1085
+ VALUE EnumBuilderContext_alloc(VALUE klass) {
1086
+ EnumBuilderContext* self = ALLOC(EnumBuilderContext);
1087
+ VALUE ret = TypedData_Wrap_Struct(
1088
+ klass, &_EnumBuilderContext_type, self);
1089
+ self->enumdesc = Qnil;
1090
+ return ret;
1091
+ }
1092
+
1093
+ void EnumBuilderContext_register(VALUE module) {
1094
+ VALUE klass = rb_define_class_under(
1095
+ module, "EnumBuilderContext", rb_cObject);
1096
+ rb_define_alloc_func(klass, EnumBuilderContext_alloc);
1097
+ rb_define_method(klass, "initialize",
1098
+ EnumBuilderContext_initialize, 1);
1099
+ rb_define_method(klass, "value", EnumBuilderContext_value, 2);
1100
+ cEnumBuilderContext = klass;
1101
+ rb_gc_register_address(&cEnumBuilderContext);
1102
+ }
1103
+
1104
+ /*
1105
+ * call-seq:
1106
+ * EnumBuilderContext.new(enumdesc) => context
1107
+ *
1108
+ * Create a new builder context around the given enum descriptor. This class is
1109
+ * intended to serve as a DSL context to be used with #instance_eval.
1110
+ */
1111
+ VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdef) {
1112
+ DEFINE_SELF(EnumBuilderContext, self, _self);
1113
+ self->enumdesc = enumdef;
1114
+ return Qnil;
1115
+ }
1116
+
1117
+ static VALUE enumdef_add_value(VALUE enumdef,
1118
+ VALUE name, VALUE number) {
1119
+ rb_funcall(enumdef, rb_intern("add_value"), 2, name, number);
1120
+ return Qnil;
1121
+ }
1122
+
1123
+ /*
1124
+ * call-seq:
1125
+ * EnumBuilder.add_value(name, number)
1126
+ *
1127
+ * Adds the given name => number mapping to the enum type. Name must be a Ruby
1128
+ * symbol.
1129
+ */
1130
+ VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
1131
+ DEFINE_SELF(EnumBuilderContext, self, _self);
1132
+ return enumdef_add_value(self->enumdesc, name, number);
1133
+ }
1134
+
1135
+ // -----------------------------------------------------------------------------
1136
+ // Builder.
1137
+ // -----------------------------------------------------------------------------
1138
+
1139
+ DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
1140
+
1141
+ void Builder_mark(void* _self) {
1142
+ Builder* self = _self;
1143
+ rb_gc_mark(self->pending_list);
1144
+ }
1145
+
1146
+ void Builder_free(void* _self) {
1147
+ Builder* self = _self;
1148
+ xfree(self->defs);
1149
+ xfree(self);
1150
+ }
1151
+
1152
+ /*
1153
+ * call-seq:
1154
+ * Builder.new => builder
1155
+ *
1156
+ * Creates a new Builder. A Builder can accumulate a set of new message and enum
1157
+ * descriptors and atomically register them into a pool in a way that allows for
1158
+ * (co)recursive type references.
1159
+ */
1160
+ VALUE Builder_alloc(VALUE klass) {
1161
+ Builder* self = ALLOC(Builder);
1162
+ VALUE ret = TypedData_Wrap_Struct(
1163
+ klass, &_Builder_type, self);
1164
+ self->pending_list = rb_ary_new();
1165
+ self->defs = NULL;
1166
+ return ret;
1167
+ }
1168
+
1169
+ void Builder_register(VALUE module) {
1170
+ VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
1171
+ rb_define_alloc_func(klass, Builder_alloc);
1172
+ rb_define_method(klass, "add_message", Builder_add_message, 1);
1173
+ rb_define_method(klass, "add_enum", Builder_add_enum, 1);
1174
+ rb_define_method(klass, "finalize_to_pool", Builder_finalize_to_pool, 1);
1175
+ cBuilder = klass;
1176
+ rb_gc_register_address(&cBuilder);
1177
+ }
1178
+
1179
+ /*
1180
+ * call-seq:
1181
+ * Builder.add_message(name, &block)
1182
+ *
1183
+ * Creates a new, empty descriptor with the given name, and invokes the block in
1184
+ * the context of a MessageBuilderContext on that descriptor. The block can then
1185
+ * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
1186
+ * methods to define the message fields.
1187
+ *
1188
+ * This is the recommended, idiomatic way to build message definitions.
1189
+ */
1190
+ VALUE Builder_add_message(VALUE _self, VALUE name) {
1191
+ DEFINE_SELF(Builder, self, _self);
1192
+ VALUE msgdef = rb_class_new_instance(0, NULL, cDescriptor);
1193
+ VALUE ctx = rb_class_new_instance(1, &msgdef, cMessageBuilderContext);
1194
+ VALUE block = rb_block_proc();
1195
+ rb_funcall(msgdef, rb_intern("name="), 1, name);
1196
+ rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1197
+ rb_ary_push(self->pending_list, msgdef);
1198
+ return Qnil;
1199
+ }
1200
+
1201
+ /*
1202
+ * call-seq:
1203
+ * Builder.add_enum(name, &block)
1204
+ *
1205
+ * Creates a new, empty enum descriptor with the given name, and invokes the block in
1206
+ * the context of an EnumBuilderContext on that descriptor. The block can then
1207
+ * call EnumBuilderContext#add_value to define the enum values.
1208
+ *
1209
+ * This is the recommended, idiomatic way to build enum definitions.
1210
+ */
1211
+ VALUE Builder_add_enum(VALUE _self, VALUE name) {
1212
+ DEFINE_SELF(Builder, self, _self);
1213
+ VALUE enumdef = rb_class_new_instance(0, NULL, cEnumDescriptor);
1214
+ VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
1215
+ VALUE block = rb_block_proc();
1216
+ rb_funcall(enumdef, rb_intern("name="), 1, name);
1217
+ rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1218
+ rb_ary_push(self->pending_list, enumdef);
1219
+ return Qnil;
1220
+ }
1221
+
1222
+ static void validate_msgdef(const upb_msgdef* msgdef) {
1223
+ // Verify that no required fields exist. proto3 does not support these.
1224
+ upb_msg_iter it;
1225
+ for (upb_msg_begin(&it, msgdef); !upb_msg_done(&it); upb_msg_next(&it)) {
1226
+ const upb_fielddef* field = upb_msg_iter_field(&it);
1227
+ if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
1228
+ rb_raise(rb_eTypeError, "Required fields are unsupported in proto3.");
1229
+ }
1230
+ }
1231
+ }
1232
+
1233
+ static void validate_enumdef(const upb_enumdef* enumdef) {
1234
+ // Verify that an entry exists with integer value 0. (This is the default
1235
+ // value.)
1236
+ const char* lookup = upb_enumdef_iton(enumdef, 0);
1237
+ if (lookup == NULL) {
1238
+ rb_raise(rb_eTypeError,
1239
+ "Enum definition does not contain a value for '0'.");
1240
+ }
1241
+ }
1242
+
1243
+ /*
1244
+ * call-seq:
1245
+ * Builder.finalize_to_pool(pool)
1246
+ *
1247
+ * Adds all accumulated message and enum descriptors created in this builder
1248
+ * context to the given pool. The operation occurs atomically, and all
1249
+ * descriptors can refer to each other (including in cycles). This is the only
1250
+ * way to build (co)recursive message definitions.
1251
+ *
1252
+ * This method is usually called automatically by DescriptorPool#build after it
1253
+ * invokes the given user block in the context of the builder. The user should
1254
+ * not normally need to call this manually because a Builder is not normally
1255
+ * created manually.
1256
+ */
1257
+ VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb) {
1258
+ DEFINE_SELF(Builder, self, _self);
1259
+
1260
+ DescriptorPool* pool = ruby_to_DescriptorPool(pool_rb);
1261
+
1262
+ REALLOC_N(self->defs, upb_def*, RARRAY_LEN(self->pending_list));
1263
+
1264
+ for (int i = 0; i < RARRAY_LEN(self->pending_list); i++) {
1265
+ VALUE def_rb = rb_ary_entry(self->pending_list, i);
1266
+ if (CLASS_OF(def_rb) == cDescriptor) {
1267
+ self->defs[i] = (upb_def*)ruby_to_Descriptor(def_rb)->msgdef;
1268
+ validate_msgdef((const upb_msgdef*)self->defs[i]);
1269
+ } else if (CLASS_OF(def_rb) == cEnumDescriptor) {
1270
+ self->defs[i] = (upb_def*)ruby_to_EnumDescriptor(def_rb)->enumdef;
1271
+ validate_enumdef((const upb_enumdef*)self->defs[i]);
1272
+ }
1273
+ }
1274
+
1275
+ CHECK_UPB(upb_symtab_add(pool->symtab, (upb_def**)self->defs,
1276
+ RARRAY_LEN(self->pending_list), NULL, &status),
1277
+ "Unable to add defs to DescriptorPool");
1278
+
1279
+ for (int i = 0; i < RARRAY_LEN(self->pending_list); i++) {
1280
+ VALUE def_rb = rb_ary_entry(self->pending_list, i);
1281
+ add_def_obj(self->defs[i], def_rb);
1282
+ }
1283
+
1284
+ self->pending_list = rb_ary_new();
1285
+ return Qnil;
1286
+ }