google-protobuf 3.6.1-x86-linux → 3.7.0.rc.2-x86-linux

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
2
  SHA256:
3
- metadata.gz: 7667454cd59977c5a272e88c81870cdb5d5f6d4a342a6b19c573e20ff3baedff
4
- data.tar.gz: 668ef17b67ea46d1eeb5991dc3a3e68787e09321f639098f55ec1b0ae4a2571e
3
+ metadata.gz: e0183028f344c564be9a2fbf355480d5a243fbfd94e6f05ad667bd03e8dddc2d
4
+ data.tar.gz: e239fbb4c245297a15d02e7869cd08e0c9fb279be4abeb8bac1e8212b95f734b
5
5
  SHA512:
6
- metadata.gz: 302763ef3c277294e212a2e3ca266f3f68eb3286e04199d5e69bccd1e0da37239d95047a79d128b790191ee3a2953f5426e70d8b09f77c45bca53f6091f0d3d0
7
- data.tar.gz: cf18bafe8865c96138ee45bfb04b17f3c382da9cba6d86d880f6fb83433f0624570167e6eb2c9a3e54c85a2975b7e8fa9d94cf1f26854df67b6e85a11aa75a99
6
+ metadata.gz: 43f53e07e9082fab03df455744c1015c50793ef5b226d60899eeb04a1807caccd389adb3d6c5a2ed91377697428430987469b874b0594265f0516fa7150fcd7d
7
+ data.tar.gz: 8008979be53debfc257d1010a05cbd0813be9edd3abfe0ffe7e4b5e0db8f5660bd55bcbc52f1b6399997de6a89d68ce7ecd635232f9df64426d72fbee356ccf9
@@ -122,7 +122,7 @@ 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);
@@ -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);
@@ -289,6 +289,7 @@ void Descriptor_register(VALUE module) {
289
289
  VALUE klass = rb_define_class_under(
290
290
  module, "Descriptor", rb_cObject);
291
291
  rb_define_alloc_func(klass, Descriptor_alloc);
292
+ rb_define_method(klass, "initialize", Descriptor_initialize, 1);
292
293
  rb_define_method(klass, "each", Descriptor_each, 0);
293
294
  rb_define_method(klass, "lookup", Descriptor_lookup, 1);
294
295
  rb_define_method(klass, "add_field", Descriptor_add_field, 1);
@@ -298,11 +299,42 @@ void Descriptor_register(VALUE module) {
298
299
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
299
300
  rb_define_method(klass, "name", Descriptor_name, 0);
300
301
  rb_define_method(klass, "name=", Descriptor_name_set, 1);
302
+ rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
301
303
  rb_include_module(klass, rb_mEnumerable);
302
304
  rb_gc_register_address(&cDescriptor);
303
305
  cDescriptor = klass;
304
306
  }
305
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
+
306
338
  /*
307
339
  * call-seq:
308
340
  * Descriptor.name => name
@@ -470,6 +502,142 @@ VALUE Descriptor_msgclass(VALUE _self) {
470
502
  return self->klass;
471
503
  }
472
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
+
473
641
  // -----------------------------------------------------------------------------
474
642
  // FieldDescriptor.
475
643
  // -----------------------------------------------------------------------------
@@ -509,6 +677,8 @@ void FieldDescriptor_register(VALUE module) {
509
677
  rb_define_method(klass, "name=", FieldDescriptor_name_set, 1);
510
678
  rb_define_method(klass, "type", FieldDescriptor_type, 0);
511
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);
512
682
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
513
683
  rb_define_method(klass, "label=", FieldDescriptor_label_set, 1);
514
684
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
@@ -516,6 +686,8 @@ void FieldDescriptor_register(VALUE module) {
516
686
  rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
517
687
  rb_define_method(klass, "submsg_name=", FieldDescriptor_submsg_name_set, 1);
518
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);
519
691
  rb_define_method(klass, "get", FieldDescriptor_get, 1);
520
692
  rb_define_method(klass, "set", FieldDescriptor_set, 2);
521
693
  rb_gc_register_address(&cFieldDescriptor);
@@ -691,6 +863,71 @@ VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
691
863
  return Qnil;
692
864
  }
693
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
+
694
931
  /*
695
932
  * call-seq:
696
933
  * FieldDescriptor.label => label
@@ -812,7 +1049,7 @@ VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
812
1049
  upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
813
1050
  const char* str = get_str(value);
814
1051
  if (!upb_fielddef_hassubdef(self->fielddef)) {
815
- rb_raise(rb_eTypeError, "FieldDescriptor does not have subdef.");
1052
+ rb_raise(cTypeError, "FieldDescriptor does not have subdef.");
816
1053
  }
817
1054
  CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
818
1055
  "Error setting submessage name");
@@ -854,11 +1091,49 @@ VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
854
1091
  MessageHeader* msg;
855
1092
  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
856
1093
  if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
857
- rb_raise(rb_eTypeError, "get method called on wrong message type");
1094
+ rb_raise(cTypeError, "get method called on wrong message type");
858
1095
  }
859
1096
  return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
860
1097
  }
861
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
+
862
1137
  /*
863
1138
  * call-seq:
864
1139
  * FieldDescriptor.set(message, value)
@@ -872,7 +1147,7 @@ VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
872
1147
  MessageHeader* msg;
873
1148
  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
874
1149
  if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
875
- rb_raise(rb_eTypeError, "set method called on wrong message type");
1150
+ rb_raise(cTypeError, "set method called on wrong message type");
876
1151
  }
877
1152
  layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
878
1153
  return Qnil;
@@ -1029,6 +1304,7 @@ void EnumDescriptor_register(VALUE module) {
1029
1304
  VALUE klass = rb_define_class_under(
1030
1305
  module, "EnumDescriptor", rb_cObject);
1031
1306
  rb_define_alloc_func(klass, EnumDescriptor_alloc);
1307
+ rb_define_method(klass, "initialize", EnumDescriptor_initialize, 1);
1032
1308
  rb_define_method(klass, "name", EnumDescriptor_name, 0);
1033
1309
  rb_define_method(klass, "name=", EnumDescriptor_name_set, 1);
1034
1310
  rb_define_method(klass, "add_value", EnumDescriptor_add_value, 2);
@@ -1036,11 +1312,41 @@ void EnumDescriptor_register(VALUE module) {
1036
1312
  rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
1037
1313
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1038
1314
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1315
+ rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1039
1316
  rb_include_module(klass, rb_mEnumerable);
1040
1317
  rb_gc_register_address(&cEnumDescriptor);
1041
1318
  cEnumDescriptor = klass;
1042
1319
  }
1043
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
+
1044
1350
  /*
1045
1351
  * call-seq:
1046
1352
  * EnumDescriptor.name => name
@@ -1223,34 +1529,56 @@ VALUE MessageBuilderContext_initialize(VALUE _self,
1223
1529
  return Qnil;
1224
1530
  }
1225
1531
 
1226
- static VALUE msgdef_add_field(VALUE msgdef,
1532
+ static VALUE msgdef_add_field(VALUE msgdef_rb,
1227
1533
  const char* label, VALUE name,
1228
1534
  VALUE type, VALUE number,
1229
- VALUE type_class) {
1230
- 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);
1231
1538
  VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
1232
1539
 
1233
- rb_funcall(fielddef, rb_intern("label="), 1, ID2SYM(rb_intern(label)));
1234
- rb_funcall(fielddef, rb_intern("name="), 1, name_str);
1235
- rb_funcall(fielddef, rb_intern("type="), 1, type);
1236
- rb_funcall(fielddef, rb_intern("number="), 1, number);
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);
1237
1544
 
1238
1545
  if (type_class != Qnil) {
1239
- if (TYPE(type_class) != T_STRING) {
1240
- rb_raise(rb_eArgError, "Expected string for type class");
1241
- }
1546
+ Check_Type(type_class, T_STRING);
1547
+
1242
1548
  // Make it an absolute type name by prepending a dot.
1243
1549
  type_class = rb_str_append(rb_str_new2("."), type_class);
1244
- rb_funcall(fielddef, rb_intern("submsg_name="), 1, type_class);
1550
+ rb_funcall(fielddef_rb, rb_intern("submsg_name="), 1, type_class);
1245
1551
  }
1246
1552
 
1247
- rb_funcall(msgdef, rb_intern("add_field"), 1, fielddef);
1248
- 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;
1249
1576
  }
1250
1577
 
1251
1578
  /*
1252
1579
  * call-seq:
1253
- * MessageBuilderContext.optional(name, type, number, type_class = nil)
1580
+ * MessageBuilderContext.optional(name, type, number, type_class = nil,
1581
+ * options = nil)
1254
1582
  *
1255
1583
  * Defines a new optional field on this message type with the given type, tag
1256
1584
  * number, and type class (for message and enum fields). The type must be a Ruby
@@ -1259,23 +1587,26 @@ static VALUE msgdef_add_field(VALUE msgdef,
1259
1587
  */
1260
1588
  VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1261
1589
  DEFINE_SELF(MessageBuilderContext, self, _self);
1262
- VALUE name, type, number, type_class;
1590
+ VALUE name, type, number;
1591
+ VALUE type_class, options = Qnil;
1263
1592
 
1264
- if (argc < 3) {
1265
- 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;
1266
1600
  }
1267
- name = argv[0];
1268
- type = argv[1];
1269
- number = argv[2];
1270
- type_class = (argc > 3) ? argv[3] : Qnil;
1271
1601
 
1272
1602
  return msgdef_add_field(self->descriptor, "optional",
1273
- name, type, number, type_class);
1603
+ name, type, number, type_class, options);
1274
1604
  }
1275
1605
 
1276
1606
  /*
1277
1607
  * call-seq:
1278
- * MessageBuilderContext.required(name, type, number, type_class = nil)
1608
+ * MessageBuilderContext.required(name, type, number, type_class = nil,
1609
+ * options = nil)
1279
1610
  *
1280
1611
  * Defines a new required field on this message type with the given type, tag
1281
1612
  * number, and type class (for message and enum fields). The type must be a Ruby
@@ -1288,18 +1619,20 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1288
1619
  */
1289
1620
  VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1290
1621
  DEFINE_SELF(MessageBuilderContext, self, _self);
1291
- VALUE name, type, number, type_class;
1622
+ VALUE name, type, number;
1623
+ VALUE type_class, options = Qnil;
1292
1624
 
1293
- if (argc < 3) {
1294
- 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;
1295
1632
  }
1296
- name = argv[0];
1297
- type = argv[1];
1298
- number = argv[2];
1299
- type_class = (argc > 3) ? argv[3] : Qnil;
1300
1633
 
1301
1634
  return msgdef_add_field(self->descriptor, "required",
1302
- name, type, number, type_class);
1635
+ name, type, number, type_class, options);
1303
1636
  }
1304
1637
 
1305
1638
  /*
@@ -1324,7 +1657,7 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1324
1657
  type_class = (argc > 3) ? argv[3] : Qnil;
1325
1658
 
1326
1659
  return msgdef_add_field(self->descriptor, "repeated",
1327
- name, type, number, type_class);
1660
+ name, type, number, type_class, Qnil);
1328
1661
  }
1329
1662
 
1330
1663
  /*
@@ -1365,9 +1698,17 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1365
1698
  "type.");
1366
1699
  }
1367
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
+
1368
1707
  // Create a new message descriptor for the map entry message, and create a
1369
1708
  // repeated submessage field here with that type.
1370
- 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);
1371
1712
  mapentry_desc_name = rb_funcall(self->descriptor, rb_intern("name"), 0);
1372
1713
  mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
1373
1714
  mapentry_desc_name = rb_str_cat2(mapentry_desc_name,
@@ -1410,8 +1751,8 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1410
1751
  {
1411
1752
  // Add the map-entry message type to the current builder, and use the type
1412
1753
  // to create the map field itself.
1413
- Builder* builder_self = ruby_to_Builder(self->builder);
1414
- rb_ary_push(builder_self->pending_list, mapentry_desc);
1754
+ Builder* builder = ruby_to_Builder(self->builder);
1755
+ rb_ary_push(builder->pending_list, mapentry_desc);
1415
1756
  }
1416
1757
 
1417
1758
  {
@@ -1514,7 +1855,8 @@ VALUE OneofBuilderContext_initialize(VALUE _self,
1514
1855
 
1515
1856
  /*
1516
1857
  * call-seq:
1517
- * OneofBuilderContext.optional(name, type, number, type_class = nil)
1858
+ * OneofBuilderContext.optional(name, type, number, type_class = nil,
1859
+ * default_value = nil)
1518
1860
  *
1519
1861
  * Defines a new optional field in this oneof with the given type, tag number,
1520
1862
  * and type class (for message and enum fields). The type must be a Ruby symbol
@@ -1523,18 +1865,13 @@ VALUE OneofBuilderContext_initialize(VALUE _self,
1523
1865
  */
1524
1866
  VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1525
1867
  DEFINE_SELF(OneofBuilderContext, self, _self);
1526
- VALUE name, type, number, type_class;
1868
+ VALUE name, type, number;
1869
+ VALUE type_class, options = Qnil;
1527
1870
 
1528
- if (argc < 3) {
1529
- rb_raise(rb_eArgError, "Expected at least 3 arguments.");
1530
- }
1531
- name = argv[0];
1532
- type = argv[1];
1533
- number = argv[2];
1534
- type_class = (argc > 3) ? argv[3] : Qnil;
1871
+ rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);
1535
1872
 
1536
1873
  return msgdef_add_field(self->descriptor, "optional",
1537
- name, type, number, type_class);
1874
+ name, type, number, type_class, options);
1538
1875
  }
1539
1876
 
1540
1877
  // -----------------------------------------------------------------------------
@@ -1604,6 +1941,112 @@ VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
1604
1941
  return enumdef_add_value(self->enumdesc, name, number);
1605
1942
  }
1606
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
+
1607
2050
  // -----------------------------------------------------------------------------
1608
2051
  // Builder.
1609
2052
  // -----------------------------------------------------------------------------
@@ -1613,6 +2056,7 @@ DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
1613
2056
  void Builder_mark(void* _self) {
1614
2057
  Builder* self = _self;
1615
2058
  rb_gc_mark(self->pending_list);
2059
+ rb_gc_mark(self->default_file_descriptor);
1616
2060
  }
1617
2061
 
1618
2062
  void Builder_free(void* _self) {
@@ -1635,15 +2079,17 @@ VALUE Builder_alloc(VALUE klass) {
1635
2079
  klass, &_Builder_type, self);
1636
2080
  self->pending_list = Qnil;
1637
2081
  self->defs = NULL;
2082
+ self->default_file_descriptor = Qnil;
1638
2083
  return ret;
1639
2084
  }
1640
2085
 
1641
2086
  void Builder_register(VALUE module) {
1642
2087
  VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
1643
- rb_define_alloc_func(klass, Builder_alloc);
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);
1644
2091
  rb_define_method(klass, "add_message", Builder_add_message, 1);
1645
2092
  rb_define_method(klass, "add_enum", Builder_add_enum, 1);
1646
- rb_define_method(klass, "initialize", Builder_initialize, 0);
1647
2093
  rb_define_method(klass, "finalize_to_pool", Builder_finalize_to_pool, 1);
1648
2094
  rb_gc_register_address(&cBuilder);
1649
2095
  cBuilder = klass;
@@ -1651,13 +2097,40 @@ void Builder_register(VALUE module) {
1651
2097
 
1652
2098
  /*
1653
2099
  * call-seq:
1654
- * Builder.new(d) => builder
2100
+ * Builder.new
1655
2101
  *
1656
- * Create a new message builder.
2102
+ * Initializes a new builder.
1657
2103
  */
1658
2104
  VALUE Builder_initialize(VALUE _self) {
1659
2105
  DEFINE_SELF(Builder, self, _self);
1660
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));
1661
2134
  return Qnil;
1662
2135
  }
1663
2136
 
@@ -1665,16 +2138,17 @@ VALUE Builder_initialize(VALUE _self) {
1665
2138
  * call-seq:
1666
2139
  * Builder.add_message(name, &block)
1667
2140
  *
1668
- * Creates a new, empty descriptor with the given name, and invokes the block in
1669
- * the context of a MessageBuilderContext on that descriptor. The block can then
1670
- * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
1671
- * methods to define the message fields.
2141
+ * Old and deprecated way to create a new descriptor.
2142
+ * See FileBuilderContext.add_message for the recommended way.
1672
2143
  *
1673
- * 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.
1674
2147
  */
1675
2148
  VALUE Builder_add_message(VALUE _self, VALUE name) {
1676
2149
  DEFINE_SELF(Builder, self, _self);
1677
- VALUE msgdef = rb_class_new_instance(0, NULL, cDescriptor);
2150
+ VALUE msgdef =
2151
+ rb_class_new_instance(1, &self->default_file_descriptor, cDescriptor);
1678
2152
  VALUE args[2] = { msgdef, _self };
1679
2153
  VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
1680
2154
  VALUE block = rb_block_proc();
@@ -1688,15 +2162,18 @@ VALUE Builder_add_message(VALUE _self, VALUE name) {
1688
2162
  * call-seq:
1689
2163
  * Builder.add_enum(name, &block)
1690
2164
  *
1691
- * Creates a new, empty enum descriptor with the given name, and invokes the
1692
- * block in the context of an EnumBuilderContext on that descriptor. The block
1693
- * can then call EnumBuilderContext#add_value to define the enum values.
2165
+ * Old and deprecated way to create a new enum descriptor.
2166
+ * See FileBuilderContext.add_enum for the recommended way.
1694
2167
  *
1695
- * 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.
1696
2172
  */
1697
2173
  VALUE Builder_add_enum(VALUE _self, VALUE name) {
1698
2174
  DEFINE_SELF(Builder, self, _self);
1699
- VALUE enumdef = rb_class_new_instance(0, NULL, cEnumDescriptor);
2175
+ VALUE enumdef =
2176
+ rb_class_new_instance(1, &self->default_file_descriptor, cEnumDescriptor);
1700
2177
  VALUE ctx = rb_class_new_instance(1, &enumdef, cEnumBuilderContext);
1701
2178
  VALUE block = rb_block_proc();
1702
2179
  rb_funcall(enumdef, rb_intern("name="), 1, name);
@@ -1705,7 +2182,7 @@ VALUE Builder_add_enum(VALUE _self, VALUE name) {
1705
2182
  return Qnil;
1706
2183
  }
1707
2184
 
1708
- static void validate_msgdef(const upb_msgdef* msgdef) {
2185
+ static void proto3_validate_msgdef(const upb_msgdef* msgdef) {
1709
2186
  // Verify that no required fields exist. proto3 does not support these.
1710
2187
  upb_msg_field_iter it;
1711
2188
  for (upb_msg_field_begin(&it, msgdef);
@@ -1713,17 +2190,17 @@ static void validate_msgdef(const upb_msgdef* msgdef) {
1713
2190
  upb_msg_field_next(&it)) {
1714
2191
  const upb_fielddef* field = upb_msg_iter_field(&it);
1715
2192
  if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
1716
- rb_raise(rb_eTypeError, "Required fields are unsupported in proto3.");
2193
+ rb_raise(cTypeError, "Required fields are unsupported in proto3.");
1717
2194
  }
1718
2195
  }
1719
2196
  }
1720
2197
 
1721
- static void validate_enumdef(const upb_enumdef* enumdef) {
2198
+ static void proto3_validate_enumdef(const upb_enumdef* enumdef) {
1722
2199
  // Verify that an entry exists with integer value 0. (This is the default
1723
2200
  // value.)
1724
2201
  const char* lookup = upb_enumdef_iton(enumdef, 0);
1725
2202
  if (lookup == NULL) {
1726
- rb_raise(rb_eTypeError,
2203
+ rb_raise(cTypeError,
1727
2204
  "Enum definition does not contain a value for '0'.");
1728
2205
  }
1729
2206
  }
@@ -1753,10 +2230,16 @@ VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb) {
1753
2230
  VALUE def_rb = rb_ary_entry(self->pending_list, i);
1754
2231
  if (CLASS_OF(def_rb) == cDescriptor) {
1755
2232
  self->defs[i] = (upb_def*)ruby_to_Descriptor(def_rb)->msgdef;
1756
- 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
+ }
1757
2237
  } else if (CLASS_OF(def_rb) == cEnumDescriptor) {
1758
2238
  self->defs[i] = (upb_def*)ruby_to_EnumDescriptor(def_rb)->enumdef;
1759
- 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
+ }
1760
2243
  }
1761
2244
  }
1762
2245