google-protobuf 3.2.0 → 3.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 64664331db5349c6aa3d561c48a14a2bde6ca8c6
4
- data.tar.gz: 0b2236d07009e3132e1d12712cf4ecf8bea00cd2
2
+ SHA256:
3
+ metadata.gz: 4ce844d5328ba745c874ed5fa1c9f8f4047889d1975bcedec6506ed40acc42db
4
+ data.tar.gz: b87cbb4655c6e699eea3ca49fceacf6e2c430d97bf1e4929b5246ab716cea9ed
5
5
  SHA512:
6
- metadata.gz: 602616782077dbf5555478236ac4208e072fb26f1b29a162157155efd20143b5e24f8c3c98d3ab33d5115416c2b80ea9de623bd1e92903dc7f41fa090be5faa7
7
- data.tar.gz: c258e775288b7ea8b528e445cfc627bc5dfc12618436960b20499ab1cea2a984ff706100aae59af6db4c387023fe16b2dea4d61415aa50745e6ff6f8ab3e0d73
6
+ metadata.gz: 62c110973d025bac4502414fd8aeb03a1c63136f2b87970f976c27fdb891ccf621c12448ef9cd74ce58d97b3e60861d4a635f795d06ea8b9ec033e34a0378708
7
+ data.tar.gz: 4040bafd4439c62c50e06471e66e9c2ccb52220620d285e0961da85ad1abc7944bab77d51b9ec140cd733e732adf762ad1dee5886758a755c166804ade5e29e1
@@ -76,7 +76,7 @@ static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
76
76
  // -----------------------------------------------------------------------------
77
77
 
78
78
  #define DEFINE_CLASS(name, string_name) \
79
- VALUE c ## name; \
79
+ VALUE c ## name = Qnil; \
80
80
  const rb_data_type_t _ ## name ## _type = { \
81
81
  string_name, \
82
82
  { name ## _mark, name ## _free, NULL }, \
@@ -122,15 +122,15 @@ void DescriptorPool_register(VALUE module) {
122
122
  module, "DescriptorPool", rb_cObject);
123
123
  rb_define_alloc_func(klass, DescriptorPool_alloc);
124
124
  rb_define_method(klass, "add", DescriptorPool_add, 1);
125
- rb_define_method(klass, "build", DescriptorPool_build, 0);
125
+ rb_define_method(klass, "build", DescriptorPool_build, -1);
126
126
  rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
127
127
  rb_define_singleton_method(klass, "generated_pool",
128
128
  DescriptorPool_generated_pool, 0);
129
- cDescriptorPool = klass;
130
129
  rb_gc_register_address(&cDescriptorPool);
130
+ cDescriptorPool = klass;
131
131
 
132
- generated_pool = rb_class_new_instance(0, NULL, klass);
133
132
  rb_gc_register_address(&generated_pool);
133
+ generated_pool = rb_class_new_instance(0, NULL, klass);
134
134
  }
135
135
 
136
136
  static void add_descriptor_to_pool(DescriptorPool* self,
@@ -181,7 +181,7 @@ VALUE DescriptorPool_add(VALUE _self, VALUE def) {
181
181
  * Builder#add_enum within the block as appropriate. This is the recommended,
182
182
  * idiomatic way to define new message and enum types.
183
183
  */
184
- VALUE DescriptorPool_build(VALUE _self) {
184
+ VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
185
185
  VALUE ctx = rb_class_new_instance(0, NULL, cBuilder);
186
186
  VALUE block = rb_block_proc();
187
187
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
@@ -228,7 +228,6 @@ DEFINE_CLASS(Descriptor, "Google::Protobuf::Descriptor");
228
228
  void Descriptor_mark(void* _self) {
229
229
  Descriptor* self = _self;
230
230
  rb_gc_mark(self->klass);
231
- rb_gc_mark(self->typeclass_references);
232
231
  }
233
232
 
234
233
  void Descriptor_free(void* _self) {
@@ -283,7 +282,6 @@ VALUE Descriptor_alloc(VALUE klass) {
283
282
  self->pb_serialize_handlers = NULL;
284
283
  self->json_serialize_handlers = NULL;
285
284
  self->json_serialize_handlers_preserve = NULL;
286
- self->typeclass_references = rb_ary_new();
287
285
  return ret;
288
286
  }
289
287
 
@@ -291,6 +289,7 @@ void Descriptor_register(VALUE module) {
291
289
  VALUE klass = rb_define_class_under(
292
290
  module, "Descriptor", rb_cObject);
293
291
  rb_define_alloc_func(klass, Descriptor_alloc);
292
+ rb_define_method(klass, "initialize", Descriptor_initialize, 1);
294
293
  rb_define_method(klass, "each", Descriptor_each, 0);
295
294
  rb_define_method(klass, "lookup", Descriptor_lookup, 1);
296
295
  rb_define_method(klass, "add_field", Descriptor_add_field, 1);
@@ -300,9 +299,40 @@ void Descriptor_register(VALUE module) {
300
299
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
301
300
  rb_define_method(klass, "name", Descriptor_name, 0);
302
301
  rb_define_method(klass, "name=", Descriptor_name_set, 1);
302
+ rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
303
303
  rb_include_module(klass, rb_mEnumerable);
304
- cDescriptor = klass;
305
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));
306
336
  }
307
337
 
308
338
  /*
@@ -472,6 +502,142 @@ VALUE Descriptor_msgclass(VALUE _self) {
472
502
  return self->klass;
473
503
  }
474
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
+
475
641
  // -----------------------------------------------------------------------------
476
642
  // FieldDescriptor.
477
643
  // -----------------------------------------------------------------------------
@@ -511,6 +677,8 @@ void FieldDescriptor_register(VALUE module) {
511
677
  rb_define_method(klass, "name=", FieldDescriptor_name_set, 1);
512
678
  rb_define_method(klass, "type", FieldDescriptor_type, 0);
513
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);
514
682
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
515
683
  rb_define_method(klass, "label=", FieldDescriptor_label_set, 1);
516
684
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
@@ -518,10 +686,12 @@ void FieldDescriptor_register(VALUE module) {
518
686
  rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
519
687
  rb_define_method(klass, "submsg_name=", FieldDescriptor_submsg_name_set, 1);
520
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);
521
691
  rb_define_method(klass, "get", FieldDescriptor_get, 1);
522
692
  rb_define_method(klass, "set", FieldDescriptor_set, 2);
523
- cFieldDescriptor = klass;
524
693
  rb_gc_register_address(&cFieldDescriptor);
694
+ cFieldDescriptor = klass;
525
695
  }
526
696
 
527
697
  /*
@@ -693,6 +863,71 @@ VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
693
863
  return Qnil;
694
864
  }
695
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
+
696
931
  /*
697
932
  * call-seq:
698
933
  * FieldDescriptor.label => label
@@ -814,7 +1049,7 @@ VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
814
1049
  upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
815
1050
  const char* str = get_str(value);
816
1051
  if (!upb_fielddef_hassubdef(self->fielddef)) {
817
- rb_raise(rb_eTypeError, "FieldDescriptor does not have subdef.");
1052
+ rb_raise(cTypeError, "FieldDescriptor does not have subdef.");
818
1053
  }
819
1054
  CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
820
1055
  "Error setting submessage name");
@@ -856,11 +1091,49 @@ VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
856
1091
  MessageHeader* msg;
857
1092
  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
858
1093
  if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
859
- rb_raise(rb_eTypeError, "get method called on wrong message type");
1094
+ rb_raise(cTypeError, "get method called on wrong message type");
860
1095
  }
861
1096
  return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
862
1097
  }
863
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
+
864
1137
  /*
865
1138
  * call-seq:
866
1139
  * FieldDescriptor.set(message, value)
@@ -874,7 +1147,7 @@ VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
874
1147
  MessageHeader* msg;
875
1148
  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
876
1149
  if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
877
- rb_raise(rb_eTypeError, "set method called on wrong message type");
1150
+ rb_raise(cTypeError, "set method called on wrong message type");
878
1151
  }
879
1152
  layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
880
1153
  return Qnil;
@@ -918,8 +1191,8 @@ void OneofDescriptor_register(VALUE module) {
918
1191
  rb_define_method(klass, "add_field", OneofDescriptor_add_field, 1);
919
1192
  rb_define_method(klass, "each", OneofDescriptor_each, 0);
920
1193
  rb_include_module(klass, rb_mEnumerable);
921
- cOneofDescriptor = klass;
922
1194
  rb_gc_register_address(&cOneofDescriptor);
1195
+ cOneofDescriptor = klass;
923
1196
  }
924
1197
 
925
1198
  /*
@@ -1031,6 +1304,7 @@ void EnumDescriptor_register(VALUE module) {
1031
1304
  VALUE klass = rb_define_class_under(
1032
1305
  module, "EnumDescriptor", rb_cObject);
1033
1306
  rb_define_alloc_func(klass, EnumDescriptor_alloc);
1307
+ rb_define_method(klass, "initialize", EnumDescriptor_initialize, 1);
1034
1308
  rb_define_method(klass, "name", EnumDescriptor_name, 0);
1035
1309
  rb_define_method(klass, "name=", EnumDescriptor_name_set, 1);
1036
1310
  rb_define_method(klass, "add_value", EnumDescriptor_add_value, 2);
@@ -1038,9 +1312,39 @@ void EnumDescriptor_register(VALUE module) {
1038
1312
  rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
1039
1313
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1040
1314
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1315
+ rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1041
1316
  rb_include_module(klass, rb_mEnumerable);
1042
- cEnumDescriptor = klass;
1043
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));
1044
1348
  }
1045
1349
 
1046
1350
  /*
@@ -1204,8 +1508,8 @@ void MessageBuilderContext_register(VALUE module) {
1204
1508
  rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
1205
1509
  rb_define_method(klass, "map", MessageBuilderContext_map, -1);
1206
1510
  rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
1207
- cMessageBuilderContext = klass;
1208
1511
  rb_gc_register_address(&cMessageBuilderContext);
1512
+ cMessageBuilderContext = klass;
1209
1513
  }
1210
1514
 
1211
1515
  /*
@@ -1225,34 +1529,56 @@ VALUE MessageBuilderContext_initialize(VALUE _self,
1225
1529
  return Qnil;
1226
1530
  }
1227
1531
 
1228
- static VALUE msgdef_add_field(VALUE msgdef,
1532
+ static VALUE msgdef_add_field(VALUE msgdef_rb,
1229
1533
  const char* label, VALUE name,
1230
1534
  VALUE type, VALUE number,
1231
- VALUE type_class) {
1232
- VALUE fielddef = rb_class_new_instance(0, NULL, cFieldDescriptor);
1535
+ VALUE type_class,
1536
+ VALUE options) {
1537
+ VALUE fielddef_rb = rb_class_new_instance(0, NULL, cFieldDescriptor);
1233
1538
  VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1234
1539
 
1235
- rb_funcall(fielddef, rb_intern("label="), 1, ID2SYM(rb_intern(label)));
1236
- rb_funcall(fielddef, rb_intern("name="), 1, name_str);
1237
- rb_funcall(fielddef, rb_intern("type="), 1, type);
1238
- rb_funcall(fielddef, rb_intern("number="), 1, number);
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);
1239
1544
 
1240
1545
  if (type_class != Qnil) {
1241
- if (TYPE(type_class) != T_STRING) {
1242
- rb_raise(rb_eArgError, "Expected string for type class");
1243
- }
1546
+ Check_Type(type_class, T_STRING);
1547
+
1244
1548
  // Make it an absolute type name by prepending a dot.
1245
1549
  type_class = rb_str_append(rb_str_new2("."), type_class);
1246
- rb_funcall(fielddef, rb_intern("submsg_name="), 1, type_class);
1550
+ rb_funcall(fielddef_rb, rb_intern("submsg_name="), 1, type_class);
1247
1551
  }
1248
1552
 
1249
- rb_funcall(msgdef, rb_intern("add_field"), 1, fielddef);
1250
- return fielddef;
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;
1251
1576
  }
1252
1577
 
1253
1578
  /*
1254
1579
  * call-seq:
1255
- * MessageBuilderContext.optional(name, type, number, type_class = nil)
1580
+ * MessageBuilderContext.optional(name, type, number, type_class = nil,
1581
+ * options = nil)
1256
1582
  *
1257
1583
  * Defines a new optional field on this message type with the given type, tag
1258
1584
  * number, and type class (for message and enum fields). The type must be a Ruby
@@ -1261,23 +1587,26 @@ static VALUE msgdef_add_field(VALUE msgdef,
1261
1587
  */
1262
1588
  VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1263
1589
  DEFINE_SELF(MessageBuilderContext, self, _self);
1264
- VALUE name, type, number, type_class;
1590
+ VALUE name, type, number;
1591
+ VALUE type_class, options = Qnil;
1265
1592
 
1266
- if (argc < 3) {
1267
- rb_raise(rb_eArgError, "Expected at least 3 arguments.");
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;
1268
1600
  }
1269
- name = argv[0];
1270
- type = argv[1];
1271
- number = argv[2];
1272
- type_class = (argc > 3) ? argv[3] : Qnil;
1273
1601
 
1274
1602
  return msgdef_add_field(self->descriptor, "optional",
1275
- name, type, number, type_class);
1603
+ name, type, number, type_class, options);
1276
1604
  }
1277
1605
 
1278
1606
  /*
1279
1607
  * call-seq:
1280
- * MessageBuilderContext.required(name, type, number, type_class = nil)
1608
+ * MessageBuilderContext.required(name, type, number, type_class = nil,
1609
+ * options = nil)
1281
1610
  *
1282
1611
  * Defines a new required field on this message type with the given type, tag
1283
1612
  * number, and type class (for message and enum fields). The type must be a Ruby
@@ -1290,18 +1619,20 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1290
1619
  */
1291
1620
  VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1292
1621
  DEFINE_SELF(MessageBuilderContext, self, _self);
1293
- VALUE name, type, number, type_class;
1622
+ VALUE name, type, number;
1623
+ VALUE type_class, options = Qnil;
1294
1624
 
1295
- if (argc < 3) {
1296
- rb_raise(rb_eArgError, "Expected at least 3 arguments.");
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;
1297
1632
  }
1298
- name = argv[0];
1299
- type = argv[1];
1300
- number = argv[2];
1301
- type_class = (argc > 3) ? argv[3] : Qnil;
1302
1633
 
1303
1634
  return msgdef_add_field(self->descriptor, "required",
1304
- name, type, number, type_class);
1635
+ name, type, number, type_class, options);
1305
1636
  }
1306
1637
 
1307
1638
  /*
@@ -1326,7 +1657,7 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1326
1657
  type_class = (argc > 3) ? argv[3] : Qnil;
1327
1658
 
1328
1659
  return msgdef_add_field(self->descriptor, "repeated",
1329
- name, type, number, type_class);
1660
+ name, type, number, type_class, Qnil);
1330
1661
  }
1331
1662
 
1332
1663
  /*
@@ -1367,9 +1698,17 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1367
1698
  "type.");
1368
1699
  }
1369
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
+
1370
1707
  // Create a new message descriptor for the map entry message, and create a
1371
1708
  // repeated submessage field here with that type.
1372
- mapentry_desc = rb_class_new_instance(0, NULL, cDescriptor);
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);
1373
1712
  mapentry_desc_name = rb_funcall(self->descriptor, rb_intern("name"), 0);
1374
1713
  mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
1375
1714
  mapentry_desc_name = rb_str_cat2(mapentry_desc_name,
@@ -1412,8 +1751,8 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1412
1751
  {
1413
1752
  // Add the map-entry message type to the current builder, and use the type
1414
1753
  // to create the map field itself.
1415
- Builder* builder_self = ruby_to_Builder(self->builder);
1416
- rb_ary_push(builder_self->pending_list, mapentry_desc);
1754
+ Builder* builder = ruby_to_Builder(self->builder);
1755
+ rb_ary_push(builder->pending_list, mapentry_desc);
1417
1756
  }
1418
1757
 
1419
1758
  {
@@ -1493,8 +1832,8 @@ void OneofBuilderContext_register(VALUE module) {
1493
1832
  rb_define_method(klass, "initialize",
1494
1833
  OneofBuilderContext_initialize, 2);
1495
1834
  rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
1496
- cOneofBuilderContext = klass;
1497
1835
  rb_gc_register_address(&cOneofBuilderContext);
1836
+ cOneofBuilderContext = klass;
1498
1837
  }
1499
1838
 
1500
1839
  /*
@@ -1516,7 +1855,8 @@ VALUE OneofBuilderContext_initialize(VALUE _self,
1516
1855
 
1517
1856
  /*
1518
1857
  * call-seq:
1519
- * OneofBuilderContext.optional(name, type, number, type_class = nil)
1858
+ * OneofBuilderContext.optional(name, type, number, type_class = nil,
1859
+ * default_value = nil)
1520
1860
  *
1521
1861
  * Defines a new optional field in this oneof with the given type, tag number,
1522
1862
  * and type class (for message and enum fields). The type must be a Ruby symbol
@@ -1525,18 +1865,13 @@ VALUE OneofBuilderContext_initialize(VALUE _self,
1525
1865
  */
1526
1866
  VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1527
1867
  DEFINE_SELF(OneofBuilderContext, self, _self);
1528
- VALUE name, type, number, type_class;
1868
+ VALUE name, type, number;
1869
+ VALUE type_class, options = Qnil;
1529
1870
 
1530
- if (argc < 3) {
1531
- rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1532
- }
1533
- name = argv[0];
1534
- type = argv[1];
1535
- number = argv[2];
1536
- type_class = (argc > 3) ? argv[3] : Qnil;
1871
+ rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
1537
1872
 
1538
1873
  return msgdef_add_field(self->descriptor, "optional",
1539
- name, type, number, type_class);
1874
+ name, type, number, type_class, options);
1540
1875
  }
1541
1876
 
1542
1877
  // -----------------------------------------------------------------------------
@@ -1571,8 +1906,8 @@ void EnumBuilderContext_register(VALUE module) {
1571
1906
  rb_define_method(klass, "initialize",
1572
1907
  EnumBuilderContext_initialize, 1);
1573
1908
  rb_define_method(klass, "value", EnumBuilderContext_value, 2);
1574
- cEnumBuilderContext = klass;
1575
1909
  rb_gc_register_address(&cEnumBuilderContext);
1910
+ cEnumBuilderContext = klass;
1576
1911
  }
1577
1912
 
1578
1913
  /*
@@ -1606,6 +1941,112 @@ VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
1606
1941
  return enumdef_add_value(self->enumdesc, name, number);
1607
1942
  }
1608
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
+
1609
2050
  // -----------------------------------------------------------------------------
1610
2051
  // Builder.
1611
2052
  // -----------------------------------------------------------------------------
@@ -1615,6 +2056,7 @@ DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
1615
2056
  void Builder_mark(void* _self) {
1616
2057
  Builder* self = _self;
1617
2058
  rb_gc_mark(self->pending_list);
2059
+ rb_gc_mark(self->default_file_descriptor);
1618
2060
  }
1619
2061
 
1620
2062
  void Builder_free(void* _self) {
@@ -1635,35 +2077,78 @@ VALUE Builder_alloc(VALUE klass) {
1635
2077
  Builder* self = ALLOC(Builder);
1636
2078
  VALUE ret = TypedData_Wrap_Struct(
1637
2079
  klass, &_Builder_type, self);
1638
- self->pending_list = rb_ary_new();
2080
+ self->pending_list = Qnil;
1639
2081
  self->defs = NULL;
2082
+ self->default_file_descriptor = Qnil;
1640
2083
  return ret;
1641
2084
  }
1642
2085
 
1643
2086
  void Builder_register(VALUE module) {
1644
2087
  VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
1645
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);
1646
2091
  rb_define_method(klass, "add_message", Builder_add_message, 1);
1647
2092
  rb_define_method(klass, "add_enum", Builder_add_enum, 1);
1648
2093
  rb_define_method(klass, "finalize_to_pool", Builder_finalize_to_pool, 1);
1649
- cBuilder = klass;
1650
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;
1651
2135
  }
1652
2136
 
1653
2137
  /*
1654
2138
  * call-seq:
1655
2139
  * Builder.add_message(name, &block)
1656
2140
  *
1657
- * Creates a new, empty descriptor with the given name, and invokes the block in
1658
- * the context of a MessageBuilderContext on that descriptor. The block can then
1659
- * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
1660
- * methods to define the message fields.
2141
+ * Old and deprecated way to create a new descriptor.
2142
+ * See FileBuilderContext.add_message for the recommended way.
1661
2143
  *
1662
- * This is the recommended, idiomatic way to build message definitions.
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.
1663
2147
  */
1664
2148
  VALUE Builder_add_message(VALUE _self, VALUE name) {
1665
2149
  DEFINE_SELF(Builder, self, _self);
1666
- VALUE msgdef = rb_class_new_instance(0, NULL, cDescriptor);
2150
+ VALUE msgdef =
2151
+ rb_class_new_instance(1, &self->default_file_descriptor, cDescriptor);
1667
2152
  VALUE args[2] = { msgdef, _self };
1668
2153
  VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
1669
2154
  VALUE block = rb_block_proc();
@@ -1677,15 +2162,18 @@ VALUE Builder_add_message(VALUE _self, VALUE name) {
1677
2162
  * call-seq:
1678
2163
  * Builder.add_enum(name, &block)
1679
2164
  *
1680
- * Creates a new, empty enum descriptor with the given name, and invokes the
1681
- * block in the context of an EnumBuilderContext on that descriptor. The block
1682
- * can then call EnumBuilderContext#add_value to define the enum values.
2165
+ * Old and deprecated way to create a new enum descriptor.
2166
+ * See FileBuilderContext.add_enum for the recommended way.
1683
2167
  *
1684
- * This is the recommended, idiomatic way to build enum definitions.
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.
1685
2172
  */
1686
2173
  VALUE Builder_add_enum(VALUE _self, VALUE name) {
1687
2174
  DEFINE_SELF(Builder, self, _self);
1688
- VALUE enumdef = rb_class_new_instance(0, NULL, cEnumDescriptor);
2175
+ VALUE enumdef =
2176
+ rb_class_new_instance(1, &self->default_file_descriptor, cEnumDescriptor);
1689
2177
  VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
1690
2178
  VALUE block = rb_block_proc();
1691
2179
  rb_funcall(enumdef, rb_intern("name="), 1, name);
@@ -1694,7 +2182,7 @@ VALUE Builder_add_enum(VALUE _self, VALUE name) {
1694
2182
  return Qnil;
1695
2183
  }
1696
2184
 
1697
- static void validate_msgdef(const upb_msgdef* msgdef) {
2185
+ static void proto3_validate_msgdef(const upb_msgdef* msgdef) {
1698
2186
  // Verify that no required fields exist. proto3 does not support these.
1699
2187
  upb_msg_field_iter it;
1700
2188
  for (upb_msg_field_begin(&it, msgdef);
@@ -1702,17 +2190,17 @@ static void validate_msgdef(const upb_msgdef* msgdef) {
1702
2190
  upb_msg_field_next(&it)) {
1703
2191
  const upb_fielddef* field = upb_msg_iter_field(&it);
1704
2192
  if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
1705
- rb_raise(rb_eTypeError, "Required fields are unsupported in proto3.");
2193
+ rb_raise(cTypeError, "Required fields are unsupported in proto3.");
1706
2194
  }
1707
2195
  }
1708
2196
  }
1709
2197
 
1710
- static void validate_enumdef(const upb_enumdef* enumdef) {
2198
+ static void proto3_validate_enumdef(const upb_enumdef* enumdef) {
1711
2199
  // Verify that an entry exists with integer value 0. (This is the default
1712
2200
  // value.)
1713
2201
  const char* lookup = upb_enumdef_iton(enumdef, 0);
1714
2202
  if (lookup == NULL) {
1715
- rb_raise(rb_eTypeError,
2203
+ rb_raise(cTypeError,
1716
2204
  "Enum definition does not contain a value for '0'.");
1717
2205
  }
1718
2206
  }
@@ -1742,10 +2230,16 @@ VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb) {
1742
2230
  VALUE def_rb = rb_ary_entry(self->pending_list, i);
1743
2231
  if (CLASS_OF(def_rb) == cDescriptor) {
1744
2232
  self->defs[i] = (upb_def*)ruby_to_Descriptor(def_rb)->msgdef;
1745
- validate_msgdef((const upb_msgdef*)self->defs[i]);
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
+ }
1746
2237
  } else if (CLASS_OF(def_rb) == cEnumDescriptor) {
1747
2238
  self->defs[i] = (upb_def*)ruby_to_EnumDescriptor(def_rb)->enumdef;
1748
- validate_enumdef((const upb_enumdef*)self->defs[i]);
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
+ }
1749
2243
  }
1750
2244
  }
1751
2245