google-protobuf 3.25.6 → 4.31.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/convert.c +33 -15
  3. data/ext/google/protobuf_c/defs.c +558 -29
  4. data/ext/google/protobuf_c/extconf.rb +19 -3
  5. data/ext/google/protobuf_c/glue.c +79 -0
  6. data/ext/google/protobuf_c/map.c +74 -29
  7. data/ext/google/protobuf_c/map.h +7 -3
  8. data/ext/google/protobuf_c/message.c +115 -118
  9. data/ext/google/protobuf_c/message.h +2 -6
  10. data/ext/google/protobuf_c/protobuf.c +32 -18
  11. data/ext/google/protobuf_c/protobuf.h +3 -13
  12. data/ext/google/protobuf_c/repeated_field.c +58 -23
  13. data/ext/google/protobuf_c/repeated_field.h +6 -2
  14. data/ext/google/protobuf_c/ruby-upb.c +15425 -11560
  15. data/ext/google/protobuf_c/ruby-upb.h +9121 -5850
  16. data/ext/google/protobuf_c/shared_convert.c +7 -2
  17. data/ext/google/protobuf_c/shared_message.c +3 -32
  18. data/ext/google/protobuf_c/shared_message.h +0 -4
  19. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
  20. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
  21. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
  22. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
  23. data/lib/google/protobuf/any_pb.rb +2 -23
  24. data/lib/google/protobuf/api_pb.rb +2 -25
  25. data/lib/google/protobuf/descriptor_pb.rb +8 -24
  26. data/lib/google/protobuf/duration_pb.rb +2 -23
  27. data/lib/google/protobuf/empty_pb.rb +2 -23
  28. data/lib/google/protobuf/ffi/descriptor.rb +14 -4
  29. data/lib/google/protobuf/ffi/descriptor_pool.rb +5 -1
  30. data/lib/google/protobuf/ffi/enum_descriptor.rb +13 -1
  31. data/lib/google/protobuf/ffi/ffi.rb +7 -6
  32. data/lib/google/protobuf/ffi/field_descriptor.rb +29 -2
  33. data/lib/google/protobuf/ffi/file_descriptor.rb +39 -13
  34. data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
  35. data/lib/google/protobuf/ffi/internal/convert.rb +17 -30
  36. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +2 -1
  37. data/lib/google/protobuf/ffi/map.rb +52 -26
  38. data/lib/google/protobuf/ffi/message.rb +188 -67
  39. data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
  40. data/lib/google/protobuf/ffi/object_cache.rb +3 -3
  41. data/lib/google/protobuf/ffi/oneof_descriptor.rb +13 -1
  42. data/lib/google/protobuf/ffi/repeated_field.rb +47 -19
  43. data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
  44. data/lib/google/protobuf/field_mask_pb.rb +2 -23
  45. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  46. data/lib/google/protobuf/message_exts.rb +4 -0
  47. data/lib/google/protobuf/plugin_pb.rb +3 -25
  48. data/lib/google/protobuf/repeated_field.rb +4 -5
  49. data/lib/google/protobuf/source_context_pb.rb +2 -23
  50. data/lib/google/protobuf/struct_pb.rb +2 -23
  51. data/lib/google/protobuf/timestamp_pb.rb +2 -23
  52. data/lib/google/protobuf/type_pb.rb +2 -25
  53. data/lib/google/protobuf/wrappers_pb.rb +2 -23
  54. data/lib/google/protobuf.rb +1 -1
  55. data/lib/google/protobuf_ffi.rb +6 -4
  56. data/lib/google/protobuf_native.rb +0 -1
  57. data/lib/google/tasks/ffi.rake +1 -3
  58. metadata +36 -21
  59. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  60. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  61. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  62. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
  63. data/lib/google/protobuf/object_cache.rb +0 -97
@@ -7,7 +7,6 @@
7
7
 
8
8
  #include <ctype.h>
9
9
  #include <errno.h>
10
- #include <ruby/version.h>
11
10
 
12
11
  #include "convert.h"
13
12
  #include "message.h"
@@ -23,6 +22,9 @@ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def);
23
22
  static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def);
24
23
  static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def);
25
24
  static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def);
25
+ static VALUE get_servicedef_obj(VALUE descriptor_pool,
26
+ const upb_ServiceDef* def);
27
+ static VALUE get_methoddef_obj(VALUE descriptor_pool, const upb_MethodDef* def);
26
28
 
27
29
  // A distinct object that is not accessible from Ruby. We use this as a
28
30
  // constructor argument to enforce that certain objects cannot be created from
@@ -144,8 +146,8 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
144
146
  * call-seq:
145
147
  * DescriptorPool.lookup(name) => descriptor
146
148
  *
147
- * Finds a Descriptor, EnumDescriptor or FieldDescriptor by name and returns it,
148
- * or nil if none exists with the given name.
149
+ * Finds a Descriptor, EnumDescriptor, FieldDescriptor or ServiceDescriptor by
150
+ * name and returns it, or nil if none exists with the given name.
149
151
  */
150
152
  static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
151
153
  DescriptorPool* self = ruby_to_DescriptorPool(_self);
@@ -153,6 +155,8 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
153
155
  const upb_MessageDef* msgdef;
154
156
  const upb_EnumDef* enumdef;
155
157
  const upb_FieldDef* fielddef;
158
+ const upb_ServiceDef* servicedef;
159
+ const upb_FileDef* filedef;
156
160
 
157
161
  msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
158
162
  if (msgdef) {
@@ -169,6 +173,16 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
169
173
  return get_enumdef_obj(_self, enumdef);
170
174
  }
171
175
 
176
+ servicedef = upb_DefPool_FindServiceByName(self->symtab, name_str);
177
+ if (servicedef) {
178
+ return get_servicedef_obj(_self, servicedef);
179
+ }
180
+
181
+ filedef = upb_DefPool_FindFileByName(self->symtab, name_str);
182
+ if (filedef) {
183
+ return get_filedef_obj(_self, filedef);
184
+ }
185
+
172
186
  return Qnil;
173
187
  }
174
188
 
@@ -257,7 +271,20 @@ static VALUE decode_options(VALUE self, const char* option_type, int size,
257
271
  VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef);
258
272
  const Descriptor* desc = ruby_to_Descriptor(desc_rb);
259
273
 
260
- options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, true);
274
+ options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, false);
275
+
276
+ // Strip features from the options proto to keep it internal.
277
+ const upb_MessageDef* decoded_desc = NULL;
278
+ upb_Message* options = Message_GetMutable(options_rb, &decoded_desc);
279
+ PBRUBY_ASSERT(options != NULL);
280
+ PBRUBY_ASSERT(decoded_desc == msgdef);
281
+ const upb_FieldDef* field =
282
+ upb_MessageDef_FindFieldByName(decoded_desc, "features");
283
+ PBRUBY_ASSERT(field != NULL);
284
+ upb_Message_ClearFieldByDef(options, field);
285
+
286
+ Message_freeze(options_rb);
287
+
261
288
  rb_ivar_set(self, options_instancevar_interned, options_rb);
262
289
  return options_rb;
263
290
  }
@@ -430,6 +457,27 @@ static VALUE Descriptor_options(VALUE _self) {
430
457
  return message_options;
431
458
  }
432
459
 
460
+ /*
461
+ * call-seq:
462
+ * Descriptor.to_proto => DescriptorProto
463
+ *
464
+ * Returns the `DescriptorProto` of this `Descriptor`.
465
+ */
466
+ static VALUE Descriptor_to_proto(VALUE _self) {
467
+ Descriptor* self = ruby_to_Descriptor(_self);
468
+ upb_Arena* arena = upb_Arena_New();
469
+ google_protobuf_DescriptorProto* proto =
470
+ upb_MessageDef_ToProto(self->msgdef, arena);
471
+ size_t size;
472
+ const char* serialized =
473
+ google_protobuf_DescriptorProto_serialize(proto, arena, &size);
474
+ VALUE proto_class = rb_path2class("Google::Protobuf::DescriptorProto");
475
+ VALUE proto_rb =
476
+ Message_decode_bytes(size, serialized, 0, proto_class, false);
477
+ upb_Arena_Free(arena);
478
+ return proto_rb;
479
+ }
480
+
433
481
  static void Descriptor_register(VALUE module) {
434
482
  VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
435
483
  rb_define_alloc_func(klass, Descriptor_alloc);
@@ -442,6 +490,7 @@ static void Descriptor_register(VALUE module) {
442
490
  rb_define_method(klass, "name", Descriptor_name, 0);
443
491
  rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
444
492
  rb_define_method(klass, "options", Descriptor_options, 0);
493
+ rb_define_method(klass, "to_proto", Descriptor_to_proto, 0);
445
494
  rb_include_module(klass, rb_mEnumerable);
446
495
  rb_gc_register_address(&cDescriptor);
447
496
  cDescriptor = klass;
@@ -489,7 +538,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
489
538
  * call-seq:
490
539
  * FileDescriptor.new => file
491
540
  *
492
- * Returns a new file descriptor. The syntax must be set before it's passed
541
+ * Returns a new file descriptor. May
493
542
  * to a builder.
494
543
  */
495
544
  static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
@@ -519,28 +568,6 @@ static VALUE FileDescriptor_name(VALUE _self) {
519
568
  return name == NULL ? Qnil : rb_str_new2(name);
520
569
  }
521
570
 
522
- /*
523
- * call-seq:
524
- * FileDescriptor.syntax => syntax
525
- *
526
- * Returns this file descriptors syntax.
527
- *
528
- * Valid syntax versions are:
529
- * :proto2 or :proto3.
530
- */
531
- static VALUE FileDescriptor_syntax(VALUE _self) {
532
- FileDescriptor* self = ruby_to_FileDescriptor(_self);
533
-
534
- switch (upb_FileDef_Syntax(self->filedef)) {
535
- case kUpb_Syntax_Proto3:
536
- return ID2SYM(rb_intern("proto3"));
537
- case kUpb_Syntax_Proto2:
538
- return ID2SYM(rb_intern("proto2"));
539
- default:
540
- return Qnil;
541
- }
542
- }
543
-
544
571
  /*
545
572
  * call-seq:
546
573
  * FileDescriptor.options => options
@@ -559,13 +586,37 @@ static VALUE FileDescriptor_options(VALUE _self) {
559
586
  return file_options;
560
587
  }
561
588
 
589
+ /*
590
+ * call-seq:
591
+ * FileDescriptor.to_proto => FileDescriptorProto
592
+ *
593
+ * Returns the `FileDescriptorProto` of this `FileDescriptor`.
594
+ */
595
+ static VALUE FileDescriptor_to_proto(VALUE _self) {
596
+ FileDescriptor* self = ruby_to_FileDescriptor(_self);
597
+ upb_Arena* arena = upb_Arena_New();
598
+ google_protobuf_FileDescriptorProto* file_proto =
599
+ upb_FileDef_ToProto(self->filedef, arena);
600
+
601
+ size_t size;
602
+ const char* serialized =
603
+ google_protobuf_FileDescriptorProto_serialize(file_proto, arena, &size);
604
+
605
+ VALUE file_proto_class =
606
+ rb_path2class("Google::Protobuf::FileDescriptorProto");
607
+ VALUE proto_rb =
608
+ Message_decode_bytes(size, serialized, 0, file_proto_class, false);
609
+ upb_Arena_Free(arena);
610
+ return proto_rb;
611
+ }
612
+
562
613
  static void FileDescriptor_register(VALUE module) {
563
614
  VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject);
564
615
  rb_define_alloc_func(klass, FileDescriptor_alloc);
565
616
  rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
566
617
  rb_define_method(klass, "name", FileDescriptor_name, 0);
567
- rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
568
618
  rb_define_method(klass, "options", FileDescriptor_options, 0);
619
+ rb_define_method(klass, "to_proto", FileDescriptor_to_proto, 0);
569
620
  rb_gc_register_address(&cFileDescriptor);
570
621
  cFileDescriptor = klass;
571
622
  }
@@ -727,7 +778,7 @@ static VALUE FieldDescriptor__type(VALUE _self) {
727
778
  static VALUE FieldDescriptor_default(VALUE _self) {
728
779
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
729
780
  const upb_FieldDef* f = self->fielddef;
730
- upb_MessageValue default_val = {0};
781
+ upb_MessageValue default_val = upb_MessageValue_Zero();
731
782
  if (upb_FieldDef_IsSubMessage(f)) {
732
783
  return Qnil;
733
784
  } else if (!upb_FieldDef_IsRepeated(f)) {
@@ -736,6 +787,50 @@ static VALUE FieldDescriptor_default(VALUE _self) {
736
787
  return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
737
788
  }
738
789
 
790
+ /*
791
+ * call-seq:
792
+ * FieldDescriptor.has_presence? => bool
793
+ *
794
+ * Returns whether this field tracks presence.
795
+ */
796
+ static VALUE FieldDescriptor_has_presence(VALUE _self) {
797
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
798
+ return upb_FieldDef_HasPresence(self->fielddef) ? Qtrue : Qfalse;
799
+ }
800
+
801
+ /*
802
+ * call-seq:
803
+ * FieldDescriptor.required? => bool
804
+ *
805
+ * Returns whether this is a required field.
806
+ */
807
+ static VALUE FieldDescriptor_is_required(VALUE _self) {
808
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
809
+ return upb_FieldDef_IsRequired(self->fielddef) ? Qtrue : Qfalse;
810
+ }
811
+
812
+ /*
813
+ * call-seq:
814
+ * FieldDescriptor.repeated? => bool
815
+ *
816
+ * Returns whether this is a repeated field.
817
+ */
818
+ static VALUE FieldDescriptor_is_repeated(VALUE _self) {
819
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
820
+ return upb_FieldDef_IsRepeated(self->fielddef) ? Qtrue : Qfalse;
821
+ }
822
+
823
+ /*
824
+ * call-seq:
825
+ * FieldDescriptor.is_packed? => bool
826
+ *
827
+ * Returns whether this is a repeated field that uses packed encoding.
828
+ */
829
+ static VALUE FieldDescriptor_is_packed(VALUE _self) {
830
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
831
+ return upb_FieldDef_IsPacked(self->fielddef) ? Qtrue : Qfalse;
832
+ }
833
+
739
834
  /*
740
835
  * call-seq:
741
836
  * FieldDescriptor.json_name => json_name
@@ -750,6 +845,8 @@ static VALUE FieldDescriptor_json_name(VALUE _self) {
750
845
  }
751
846
 
752
847
  /*
848
+ * DEPRECATED: Use repeated? or required? instead.
849
+ *
753
850
  * call-seq:
754
851
  * FieldDescriptor.label => label
755
852
  *
@@ -936,6 +1033,27 @@ static VALUE FieldDescriptor_options(VALUE _self) {
936
1033
  return field_options;
937
1034
  }
938
1035
 
1036
+ /*
1037
+ * call-seq:
1038
+ * FieldDescriptor.to_proto => FieldDescriptorProto
1039
+ *
1040
+ * Returns the `FieldDescriptorProto` of this `FieldDescriptor`.
1041
+ */
1042
+ static VALUE FieldDescriptor_to_proto(VALUE _self) {
1043
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
1044
+ upb_Arena* arena = upb_Arena_New();
1045
+ google_protobuf_FieldDescriptorProto* proto =
1046
+ upb_FieldDef_ToProto(self->fielddef, arena);
1047
+ size_t size;
1048
+ const char* serialized =
1049
+ google_protobuf_FieldDescriptorProto_serialize(proto, arena, &size);
1050
+ VALUE proto_class = rb_path2class("Google::Protobuf::FieldDescriptorProto");
1051
+ VALUE proto_rb =
1052
+ Message_decode_bytes(size, serialized, 0, proto_class, false);
1053
+ upb_Arena_Free(arena);
1054
+ return proto_rb;
1055
+ }
1056
+
939
1057
  static void FieldDescriptor_register(VALUE module) {
940
1058
  VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
941
1059
  rb_define_alloc_func(klass, FieldDescriptor_alloc);
@@ -943,6 +1061,10 @@ static void FieldDescriptor_register(VALUE module) {
943
1061
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
944
1062
  rb_define_method(klass, "type", FieldDescriptor__type, 0);
945
1063
  rb_define_method(klass, "default", FieldDescriptor_default, 0);
1064
+ rb_define_method(klass, "has_presence?", FieldDescriptor_has_presence, 0);
1065
+ rb_define_method(klass, "required?", FieldDescriptor_is_required, 0);
1066
+ rb_define_method(klass, "repeated?", FieldDescriptor_is_repeated, 0);
1067
+ rb_define_method(klass, "is_packed?", FieldDescriptor_is_packed, 0);
946
1068
  rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
947
1069
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
948
1070
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
@@ -953,6 +1075,7 @@ static void FieldDescriptor_register(VALUE module) {
953
1075
  rb_define_method(klass, "get", FieldDescriptor_get, 1);
954
1076
  rb_define_method(klass, "set", FieldDescriptor_set, 2);
955
1077
  rb_define_method(klass, "options", FieldDescriptor_options, 0);
1078
+ rb_define_method(klass, "to_proto", FieldDescriptor_to_proto, 0);
956
1079
  rb_gc_register_address(&cFieldDescriptor);
957
1080
  cFieldDescriptor = klass;
958
1081
  }
@@ -1071,6 +1194,27 @@ static VALUE OneOfDescriptor_options(VALUE _self) {
1071
1194
  return oneof_options;
1072
1195
  }
1073
1196
 
1197
+ /*
1198
+ * call-seq:
1199
+ * OneofDescriptor.to_proto => OneofDescriptorProto
1200
+ *
1201
+ * Returns the `OneofDescriptorProto` of this `OneofDescriptor`.
1202
+ */
1203
+ static VALUE OneOfDescriptor_to_proto(VALUE _self) {
1204
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1205
+ upb_Arena* arena = upb_Arena_New();
1206
+ google_protobuf_OneofDescriptorProto* proto =
1207
+ upb_OneofDef_ToProto(self->oneofdef, arena);
1208
+ size_t size;
1209
+ const char* serialized =
1210
+ google_protobuf_OneofDescriptorProto_serialize(proto, arena, &size);
1211
+ VALUE proto_class = rb_path2class("Google::Protobuf::OneofDescriptorProto");
1212
+ VALUE proto_rb =
1213
+ Message_decode_bytes(size, serialized, 0, proto_class, false);
1214
+ upb_Arena_Free(arena);
1215
+ return proto_rb;
1216
+ }
1217
+
1074
1218
  static void OneofDescriptor_register(VALUE module) {
1075
1219
  VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
1076
1220
  rb_define_alloc_func(klass, OneofDescriptor_alloc);
@@ -1078,6 +1222,7 @@ static void OneofDescriptor_register(VALUE module) {
1078
1222
  rb_define_method(klass, "name", OneofDescriptor_name, 0);
1079
1223
  rb_define_method(klass, "each", OneofDescriptor_each, 0);
1080
1224
  rb_define_method(klass, "options", OneOfDescriptor_options, 0);
1225
+ rb_define_method(klass, "to_proto", OneOfDescriptor_to_proto, 0);
1081
1226
  rb_include_module(klass, rb_mEnumerable);
1082
1227
  rb_gc_register_address(&cOneofDescriptor);
1083
1228
  cOneofDescriptor = klass;
@@ -1163,6 +1308,17 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1163
1308
  upb_EnumDef_File(self->enumdef));
1164
1309
  }
1165
1310
 
1311
+ /*
1312
+ * call-seq:
1313
+ * EnumDescriptor.is_closed? => bool
1314
+ *
1315
+ * Returns whether this enum is open or closed.
1316
+ */
1317
+ static VALUE EnumDescriptor_is_closed(VALUE _self) {
1318
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1319
+ return upb_EnumDef_IsClosed(self->enumdef) ? Qtrue : Qfalse;
1320
+ }
1321
+
1166
1322
  /*
1167
1323
  * call-seq:
1168
1324
  * EnumDescriptor.name => name
@@ -1265,6 +1421,29 @@ static VALUE EnumDescriptor_options(VALUE _self) {
1265
1421
  return enum_options;
1266
1422
  }
1267
1423
 
1424
+ /*
1425
+ * call-seq:
1426
+ * EnumDescriptor.to_proto => EnumDescriptorProto
1427
+ *
1428
+ * Returns the `EnumDescriptorProto` of this `EnumDescriptor`.
1429
+ */
1430
+ static VALUE EnumDescriptor_to_proto(VALUE _self) {
1431
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1432
+ upb_Arena* arena = upb_Arena_New();
1433
+ google_protobuf_EnumDescriptorProto* proto =
1434
+ upb_EnumDef_ToProto(self->enumdef, arena);
1435
+
1436
+ size_t size;
1437
+ const char* serialized =
1438
+ google_protobuf_EnumDescriptorProto_serialize(proto, arena, &size);
1439
+
1440
+ VALUE proto_class = rb_path2class("Google::Protobuf::EnumDescriptorProto");
1441
+ VALUE proto_rb =
1442
+ Message_decode_bytes(size, serialized, 0, proto_class, false);
1443
+ upb_Arena_Free(arena);
1444
+ return proto_rb;
1445
+ }
1446
+
1268
1447
  static void EnumDescriptor_register(VALUE module) {
1269
1448
  VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
1270
1449
  rb_define_alloc_func(klass, EnumDescriptor_alloc);
@@ -1275,12 +1454,350 @@ static void EnumDescriptor_register(VALUE module) {
1275
1454
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1276
1455
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1277
1456
  rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1457
+ rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0);
1278
1458
  rb_define_method(klass, "options", EnumDescriptor_options, 0);
1459
+ rb_define_method(klass, "to_proto", EnumDescriptor_to_proto, 0);
1279
1460
  rb_include_module(klass, rb_mEnumerable);
1280
1461
  rb_gc_register_address(&cEnumDescriptor);
1281
1462
  cEnumDescriptor = klass;
1282
1463
  }
1283
1464
 
1465
+ // -----------------------------------------------------------------------------
1466
+ // ServiceDescriptor
1467
+ // -----------------------------------------------------------------------------
1468
+
1469
+ typedef struct {
1470
+ const upb_ServiceDef* servicedef;
1471
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
1472
+ // macro to update VALUE references, as to trigger write barriers.
1473
+ VALUE module; // begins as nil
1474
+ VALUE descriptor_pool; // Owns the upb_ServiceDef.
1475
+ } ServiceDescriptor;
1476
+
1477
+ static VALUE cServiceDescriptor = Qnil;
1478
+
1479
+ static void ServiceDescriptor_mark(void* _self) {
1480
+ ServiceDescriptor* self = _self;
1481
+ rb_gc_mark(self->module);
1482
+ rb_gc_mark(self->descriptor_pool);
1483
+ }
1484
+
1485
+ static const rb_data_type_t ServiceDescriptor_type = {
1486
+ "Google::Protobuf::ServicDescriptor",
1487
+ {ServiceDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1488
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1489
+ };
1490
+
1491
+ static ServiceDescriptor* ruby_to_ServiceDescriptor(VALUE val) {
1492
+ ServiceDescriptor* ret;
1493
+ TypedData_Get_Struct(val, ServiceDescriptor, &ServiceDescriptor_type, ret);
1494
+ return ret;
1495
+ }
1496
+
1497
+ static VALUE ServiceDescriptor_alloc(VALUE klass) {
1498
+ ServiceDescriptor* self = ALLOC(ServiceDescriptor);
1499
+ VALUE ret = TypedData_Wrap_Struct(klass, &ServiceDescriptor_type, self);
1500
+ self->servicedef = NULL;
1501
+ self->module = Qnil;
1502
+ self->descriptor_pool = Qnil;
1503
+ return ret;
1504
+ }
1505
+
1506
+ /*
1507
+ * call-seq:
1508
+ * ServiceDescriptor.new(c_only_cookie, ptr) => ServiceDescriptor
1509
+ *
1510
+ * Creates a descriptor wrapper object. May only be called from C.
1511
+ */
1512
+ static VALUE ServiceDescriptor_initialize(VALUE _self, VALUE cookie,
1513
+ VALUE descriptor_pool, VALUE ptr) {
1514
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1515
+
1516
+ if (cookie != c_only_cookie) {
1517
+ rb_raise(rb_eRuntimeError,
1518
+ "Descriptor objects may not be created from Ruby.");
1519
+ }
1520
+
1521
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1522
+ self->servicedef = (const upb_ServiceDef*)NUM2ULL(ptr);
1523
+
1524
+ return Qnil;
1525
+ }
1526
+
1527
+ /*
1528
+ * call-seq:
1529
+ * ServiceDescriptor.name => name
1530
+ *
1531
+ * Returns the name of this service.
1532
+ */
1533
+ static VALUE ServiceDescriptor_name(VALUE _self) {
1534
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1535
+ return rb_str_maybe_null(upb_ServiceDef_FullName(self->servicedef));
1536
+ }
1537
+
1538
+ /*
1539
+ * call-seq:
1540
+ * ServiceDescriptor.file_descriptor
1541
+ *
1542
+ * Returns the FileDescriptor object this service belongs to.
1543
+ */
1544
+ static VALUE ServiceDescriptor_file_descriptor(VALUE _self) {
1545
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1546
+ return get_filedef_obj(self->descriptor_pool,
1547
+ upb_ServiceDef_File(self->servicedef));
1548
+ }
1549
+
1550
+ /*
1551
+ * call-seq:
1552
+ * ServiceDescriptor.each(&block)
1553
+ *
1554
+ * Iterates over methods in this service, yielding to the block on each one.
1555
+ */
1556
+ static VALUE ServiceDescriptor_each(VALUE _self) {
1557
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1558
+
1559
+ int n = upb_ServiceDef_MethodCount(self->servicedef);
1560
+ for (int i = 0; i < n; i++) {
1561
+ const upb_MethodDef* method = upb_ServiceDef_Method(self->servicedef, i);
1562
+ VALUE obj = get_methoddef_obj(self->descriptor_pool, method);
1563
+ rb_yield(obj);
1564
+ }
1565
+ return Qnil;
1566
+ }
1567
+
1568
+ /*
1569
+ * call-seq:
1570
+ * ServiceDescriptor.options => options
1571
+ *
1572
+ * Returns the `ServiceOptions` for this `ServiceDescriptor`.
1573
+ */
1574
+ static VALUE ServiceDescriptor_options(VALUE _self) {
1575
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1576
+ const google_protobuf_ServiceOptions* opts =
1577
+ upb_ServiceDef_Options(self->servicedef);
1578
+ upb_Arena* arena = upb_Arena_New();
1579
+ size_t size;
1580
+ char* serialized =
1581
+ google_protobuf_ServiceOptions_serialize(opts, arena, &size);
1582
+ VALUE service_options = decode_options(_self, "ServiceOptions", size,
1583
+ serialized, self->descriptor_pool);
1584
+ upb_Arena_Free(arena);
1585
+ return service_options;
1586
+ }
1587
+
1588
+ /*
1589
+ * call-seq:
1590
+ * ServiceDescriptor.to_proto => ServiceDescriptorProto
1591
+ *
1592
+ * Returns the `ServiceDescriptorProto` of this `ServiceDescriptor`.
1593
+ */
1594
+ static VALUE ServiceDescriptor_to_proto(VALUE _self) {
1595
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1596
+ upb_Arena* arena = upb_Arena_New();
1597
+ google_protobuf_ServiceDescriptorProto* proto =
1598
+ upb_ServiceDef_ToProto(self->servicedef, arena);
1599
+ size_t size;
1600
+ const char* serialized =
1601
+ google_protobuf_ServiceDescriptorProto_serialize(proto, arena, &size);
1602
+ VALUE proto_class = rb_path2class("Google::Protobuf::ServiceDescriptorProto");
1603
+ VALUE proto_rb =
1604
+ Message_decode_bytes(size, serialized, 0, proto_class, false);
1605
+ upb_Arena_Free(arena);
1606
+ return proto_rb;
1607
+ }
1608
+
1609
+ static void ServiceDescriptor_register(VALUE module) {
1610
+ VALUE klass = rb_define_class_under(module, "ServiceDescriptor", rb_cObject);
1611
+ rb_define_alloc_func(klass, ServiceDescriptor_alloc);
1612
+ rb_define_method(klass, "initialize", ServiceDescriptor_initialize, 3);
1613
+ rb_define_method(klass, "name", ServiceDescriptor_name, 0);
1614
+ rb_define_method(klass, "each", ServiceDescriptor_each, 0);
1615
+ rb_define_method(klass, "file_descriptor", ServiceDescriptor_file_descriptor,
1616
+ 0);
1617
+ rb_define_method(klass, "options", ServiceDescriptor_options, 0);
1618
+ rb_define_method(klass, "to_proto", ServiceDescriptor_to_proto, 0);
1619
+ rb_include_module(klass, rb_mEnumerable);
1620
+ rb_gc_register_address(&cServiceDescriptor);
1621
+ cServiceDescriptor = klass;
1622
+ }
1623
+
1624
+ // -----------------------------------------------------------------------------
1625
+ // MethodDescriptor
1626
+ // -----------------------------------------------------------------------------
1627
+
1628
+ typedef struct {
1629
+ const upb_MethodDef* methoddef;
1630
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
1631
+ // macro to update VALUE references, as to trigger write barriers.
1632
+ VALUE module; // begins as nil
1633
+ VALUE descriptor_pool; // Owns the upb_MethodDef.
1634
+ } MethodDescriptor;
1635
+
1636
+ static VALUE cMethodDescriptor = Qnil;
1637
+
1638
+ static void MethodDescriptor_mark(void* _self) {
1639
+ MethodDescriptor* self = _self;
1640
+ rb_gc_mark(self->module);
1641
+ rb_gc_mark(self->descriptor_pool);
1642
+ }
1643
+
1644
+ static const rb_data_type_t MethodDescriptor_type = {
1645
+ "Google::Protobuf::MethodDescriptor",
1646
+ {MethodDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1647
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1648
+ };
1649
+
1650
+ static MethodDescriptor* ruby_to_MethodDescriptor(VALUE val) {
1651
+ MethodDescriptor* ret;
1652
+ TypedData_Get_Struct(val, MethodDescriptor, &MethodDescriptor_type, ret);
1653
+ return ret;
1654
+ }
1655
+
1656
+ static VALUE MethodDescriptor_alloc(VALUE klass) {
1657
+ MethodDescriptor* self = ALLOC(MethodDescriptor);
1658
+ VALUE ret = TypedData_Wrap_Struct(klass, &MethodDescriptor_type, self);
1659
+ self->methoddef = NULL;
1660
+ self->module = Qnil;
1661
+ self->descriptor_pool = Qnil;
1662
+ return ret;
1663
+ }
1664
+
1665
+ /*
1666
+ * call-seq:
1667
+ * MethodDescriptor.new(c_only_cookie, ptr) => MethodDescriptor
1668
+ *
1669
+ * Creates a descriptor wrapper object. May only be called from C.
1670
+ */
1671
+ static VALUE MethodDescriptor_initialize(VALUE _self, VALUE cookie,
1672
+ VALUE descriptor_pool, VALUE ptr) {
1673
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1674
+
1675
+ if (cookie != c_only_cookie) {
1676
+ rb_raise(rb_eRuntimeError,
1677
+ "Descriptor objects may not be created from Ruby.");
1678
+ }
1679
+
1680
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1681
+ self->methoddef = (const upb_MethodDef*)NUM2ULL(ptr);
1682
+
1683
+ return Qnil;
1684
+ }
1685
+
1686
+ /*
1687
+ * call-seq:
1688
+ * MethodDescriptor.name => name
1689
+ *
1690
+ * Returns the name of this method
1691
+ */
1692
+ static VALUE MethodDescriptor_name(VALUE _self) {
1693
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1694
+ return rb_str_maybe_null(upb_MethodDef_Name(self->methoddef));
1695
+ }
1696
+
1697
+ /*
1698
+ * call-seq:
1699
+ * MethodDescriptor.options => options
1700
+ *
1701
+ * Returns the `MethodOptions` for this `MethodDescriptor`.
1702
+ */
1703
+ static VALUE MethodDescriptor_options(VALUE _self) {
1704
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1705
+ const google_protobuf_MethodOptions* opts =
1706
+ upb_MethodDef_Options(self->methoddef);
1707
+ upb_Arena* arena = upb_Arena_New();
1708
+ size_t size;
1709
+ char* serialized =
1710
+ google_protobuf_MethodOptions_serialize(opts, arena, &size);
1711
+ VALUE method_options = decode_options(_self, "MethodOptions", size,
1712
+ serialized, self->descriptor_pool);
1713
+ upb_Arena_Free(arena);
1714
+ return method_options;
1715
+ }
1716
+
1717
+ /*
1718
+ * call-seq:
1719
+ * MethodDescriptor.input_type => Descriptor
1720
+ *
1721
+ * Returns the `Descriptor` for the request message type of this method
1722
+ */
1723
+ static VALUE MethodDescriptor_input_type(VALUE _self) {
1724
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1725
+ const upb_MessageDef* type = upb_MethodDef_InputType(self->methoddef);
1726
+ return get_msgdef_obj(self->descriptor_pool, type);
1727
+ }
1728
+
1729
+ /*
1730
+ * call-seq:
1731
+ * MethodDescriptor.output_type => Descriptor
1732
+ *
1733
+ * Returns the `Descriptor` for the response message type of this method
1734
+ */
1735
+ static VALUE MethodDescriptor_output_type(VALUE _self) {
1736
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1737
+ const upb_MessageDef* type = upb_MethodDef_OutputType(self->methoddef);
1738
+ return get_msgdef_obj(self->descriptor_pool, type);
1739
+ }
1740
+
1741
+ /*
1742
+ * call-seq:
1743
+ * MethodDescriptor.client_streaming => bool
1744
+ *
1745
+ * Returns whether or not this is a streaming request method
1746
+ */
1747
+ static VALUE MethodDescriptor_client_streaming(VALUE _self) {
1748
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1749
+ return upb_MethodDef_ClientStreaming(self->methoddef) ? Qtrue : Qfalse;
1750
+ }
1751
+
1752
+ /*
1753
+ * call-seq:
1754
+ * MethodDescriptor.to_proto => MethodDescriptorProto
1755
+ *
1756
+ * Returns the `MethodDescriptorProto` of this `MethodDescriptor`.
1757
+ */
1758
+ static VALUE MethodDescriptor_to_proto(VALUE _self) {
1759
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1760
+ upb_Arena* arena = upb_Arena_New();
1761
+ google_protobuf_MethodDescriptorProto* proto =
1762
+ upb_MethodDef_ToProto(self->methoddef, arena);
1763
+ size_t size;
1764
+ const char* serialized =
1765
+ google_protobuf_MethodDescriptorProto_serialize(proto, arena, &size);
1766
+ VALUE proto_class = rb_path2class("Google::Protobuf::MethodDescriptorProto");
1767
+ VALUE proto_rb =
1768
+ Message_decode_bytes(size, serialized, 0, proto_class, false);
1769
+ upb_Arena_Free(arena);
1770
+ return proto_rb;
1771
+ }
1772
+
1773
+ /*
1774
+ * call-seq:
1775
+ * MethodDescriptor.server_streaming => bool
1776
+ *
1777
+ * Returns whether or not this is a streaming response method
1778
+ */
1779
+ static VALUE MethodDescriptor_server_streaming(VALUE _self) {
1780
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1781
+ return upb_MethodDef_ServerStreaming(self->methoddef) ? Qtrue : Qfalse;
1782
+ }
1783
+
1784
+ static void MethodDescriptor_register(VALUE module) {
1785
+ VALUE klass = rb_define_class_under(module, "MethodDescriptor", rb_cObject);
1786
+ rb_define_alloc_func(klass, MethodDescriptor_alloc);
1787
+ rb_define_method(klass, "initialize", MethodDescriptor_initialize, 3);
1788
+ rb_define_method(klass, "name", MethodDescriptor_name, 0);
1789
+ rb_define_method(klass, "options", MethodDescriptor_options, 0);
1790
+ rb_define_method(klass, "input_type", MethodDescriptor_input_type, 0);
1791
+ rb_define_method(klass, "output_type", MethodDescriptor_output_type, 0);
1792
+ rb_define_method(klass, "client_streaming", MethodDescriptor_client_streaming,
1793
+ 0);
1794
+ rb_define_method(klass, "server_streaming", MethodDescriptor_server_streaming,
1795
+ 0);
1796
+ rb_define_method(klass, "to_proto", MethodDescriptor_to_proto, 0);
1797
+ rb_gc_register_address(&cMethodDescriptor);
1798
+ cMethodDescriptor = klass;
1799
+ }
1800
+
1284
1801
  static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
1285
1802
  DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
1286
1803
  VALUE key = ULL2NUM((intptr_t)ptr);
@@ -1322,6 +1839,16 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
1322
1839
  return get_def_obj(descriptor_pool, def, cOneofDescriptor);
1323
1840
  }
1324
1841
 
1842
+ static VALUE get_servicedef_obj(VALUE descriptor_pool,
1843
+ const upb_ServiceDef* def) {
1844
+ return get_def_obj(descriptor_pool, def, cServiceDescriptor);
1845
+ }
1846
+
1847
+ static VALUE get_methoddef_obj(VALUE descriptor_pool,
1848
+ const upb_MethodDef* def) {
1849
+ return get_def_obj(descriptor_pool, def, cMethodDescriptor);
1850
+ }
1851
+
1325
1852
  // -----------------------------------------------------------------------------
1326
1853
  // Shared functions
1327
1854
  // -----------------------------------------------------------------------------
@@ -1397,6 +1924,8 @@ void Defs_register(VALUE module) {
1397
1924
  FieldDescriptor_register(module);
1398
1925
  OneofDescriptor_register(module);
1399
1926
  EnumDescriptor_register(module);
1927
+ ServiceDescriptor_register(module);
1928
+ MethodDescriptor_register(module);
1400
1929
 
1401
1930
  rb_gc_register_address(&c_only_cookie);
1402
1931
  c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);