google-protobuf 3.25.0 → 4.29.2

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/convert.c +46 -18
  3. data/ext/google/protobuf_c/defs.c +499 -26
  4. data/ext/google/protobuf_c/extconf.rb +1 -1
  5. data/ext/google/protobuf_c/glue.c +53 -2
  6. data/ext/google/protobuf_c/map.c +82 -17
  7. data/ext/google/protobuf_c/map.h +9 -2
  8. data/ext/google/protobuf_c/message.c +144 -104
  9. data/ext/google/protobuf_c/message.h +8 -5
  10. data/ext/google/protobuf_c/protobuf.c +30 -17
  11. data/ext/google/protobuf_c/protobuf.h +3 -7
  12. data/ext/google/protobuf_c/repeated_field.c +64 -10
  13. data/ext/google/protobuf_c/repeated_field.h +8 -1
  14. data/ext/google/protobuf_c/ruby-upb.c +13774 -11526
  15. data/ext/google/protobuf_c/ruby-upb.h +11198 -9048
  16. data/ext/google/protobuf_c/shared_convert.c +10 -5
  17. data/ext/google/protobuf_c/shared_convert.h +2 -2
  18. data/ext/google/protobuf_c/shared_message.c +3 -31
  19. data/ext/google/protobuf_c/shared_message.h +0 -4
  20. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
  21. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
  22. data/lib/google/protobuf/any_pb.rb +1 -22
  23. data/lib/google/protobuf/api_pb.rb +1 -24
  24. data/lib/google/protobuf/descriptor_pb.rb +3 -23
  25. data/lib/google/protobuf/duration_pb.rb +1 -22
  26. data/lib/google/protobuf/empty_pb.rb +1 -22
  27. data/lib/google/protobuf/ffi/descriptor.rb +13 -2
  28. data/lib/google/protobuf/ffi/descriptor_pool.rb +16 -9
  29. data/lib/google/protobuf/ffi/enum_descriptor.rb +13 -1
  30. data/lib/google/protobuf/ffi/ffi.rb +8 -6
  31. data/lib/google/protobuf/ffi/field_descriptor.rb +37 -16
  32. data/lib/google/protobuf/ffi/file_descriptor.rb +13 -12
  33. data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
  34. data/lib/google/protobuf/ffi/internal/convert.rb +21 -30
  35. data/lib/google/protobuf/ffi/map.rb +50 -13
  36. data/lib/google/protobuf/ffi/message.rb +202 -58
  37. data/lib/google/protobuf/ffi/method_descriptor.rb +114 -0
  38. data/lib/google/protobuf/ffi/object_cache.rb +3 -3
  39. data/lib/google/protobuf/ffi/oneof_descriptor.rb +20 -11
  40. data/lib/google/protobuf/ffi/repeated_field.rb +50 -142
  41. data/lib/google/protobuf/ffi/service_descriptor.rb +107 -0
  42. data/lib/google/protobuf/field_mask_pb.rb +1 -22
  43. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  44. data/lib/google/protobuf/plugin_pb.rb +2 -24
  45. data/lib/google/protobuf/repeated_field.rb +4 -5
  46. data/lib/google/protobuf/source_context_pb.rb +1 -22
  47. data/lib/google/protobuf/struct_pb.rb +1 -22
  48. data/lib/google/protobuf/timestamp_pb.rb +1 -22
  49. data/lib/google/protobuf/type_pb.rb +1 -24
  50. data/lib/google/protobuf/wrappers_pb.rb +1 -22
  51. data/lib/google/protobuf.rb +1 -1
  52. data/lib/google/protobuf_ffi.rb +3 -2
  53. data/lib/google/protobuf_native.rb +0 -1
  54. data/lib/google/tasks/ffi.rake +1 -3
  55. metadata +25 -12
  56. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  57. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  58. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  59. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
  60. 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
@@ -44,7 +46,7 @@ static VALUE rb_str_maybe_null(const char* s) {
44
46
  }
45
47
  return rb_str_new2(s);
46
48
  }
47
-
49
+ static ID options_instancevar_interned;
48
50
  // -----------------------------------------------------------------------------
49
51
  // DescriptorPool.
50
52
  // -----------------------------------------------------------------------------
@@ -144,25 +146,37 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
144
146
  * call-seq:
145
147
  * DescriptorPool.lookup(name) => descriptor
146
148
  *
147
- * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
148
- * exists with the given name.
149
+ * Finds a Descriptor, EnumDescriptor or FieldDescriptor by name and returns it,
150
+ * 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);
152
154
  const char* name_str = get_str(name);
153
155
  const upb_MessageDef* msgdef;
154
156
  const upb_EnumDef* enumdef;
157
+ const upb_FieldDef* fielddef;
158
+ const upb_ServiceDef* servicedef;
155
159
 
156
160
  msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
157
161
  if (msgdef) {
158
162
  return get_msgdef_obj(_self, msgdef);
159
163
  }
160
164
 
165
+ fielddef = upb_DefPool_FindExtensionByName(self->symtab, name_str);
166
+ if (fielddef) {
167
+ return get_fielddef_obj(_self, fielddef);
168
+ }
169
+
161
170
  enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str);
162
171
  if (enumdef) {
163
172
  return get_enumdef_obj(_self, enumdef);
164
173
  }
165
174
 
175
+ servicedef = upb_DefPool_FindServiceByName(self->symtab, name_str);
176
+ if (servicedef) {
177
+ return get_servicedef_obj(_self, servicedef);
178
+ }
179
+
166
180
  return Qnil;
167
181
  }
168
182
 
@@ -192,6 +206,7 @@ static void DescriptorPool_register(VALUE module) {
192
206
 
193
207
  rb_gc_register_address(&generated_pool);
194
208
  generated_pool = rb_class_new_instance(0, NULL, klass);
209
+ options_instancevar_interned = rb_intern("options");
195
210
  }
196
211
 
197
212
  // -----------------------------------------------------------------------------
@@ -226,6 +241,48 @@ static Descriptor* ruby_to_Descriptor(VALUE val) {
226
241
  return ret;
227
242
  }
228
243
 
244
+ // Decode and return a frozen instance of a Descriptor Option for the given pool
245
+ static VALUE decode_options(VALUE self, const char* option_type, int size,
246
+ const char* bytes, VALUE descriptor_pool) {
247
+ VALUE options_rb = rb_ivar_get(self, options_instancevar_interned);
248
+ if (options_rb != Qnil) {
249
+ return options_rb;
250
+ }
251
+
252
+ static const char* prefix = "google.protobuf.";
253
+ char fullname
254
+ [/*strlen(prefix)*/ 16 +
255
+ /*strln(longest option type supported e.g. "MessageOptions")*/ 14 +
256
+ /*null terminator*/ 1];
257
+
258
+ snprintf(fullname, sizeof(fullname), "%s%s", prefix, option_type);
259
+ const upb_MessageDef* msgdef = upb_DefPool_FindMessageByName(
260
+ ruby_to_DescriptorPool(descriptor_pool)->symtab, fullname);
261
+ if (!msgdef) {
262
+ rb_raise(rb_eRuntimeError, "Cannot find %s in DescriptorPool", option_type);
263
+ }
264
+
265
+ VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef);
266
+ const Descriptor* desc = ruby_to_Descriptor(desc_rb);
267
+
268
+ options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, false);
269
+
270
+ // Strip features from the options proto to keep it internal.
271
+ const upb_MessageDef* decoded_desc = NULL;
272
+ upb_Message* options = Message_GetMutable(options_rb, &decoded_desc);
273
+ PBRUBY_ASSERT(options != NULL);
274
+ PBRUBY_ASSERT(decoded_desc == msgdef);
275
+ const upb_FieldDef* field =
276
+ upb_MessageDef_FindFieldByName(decoded_desc, "features");
277
+ PBRUBY_ASSERT(field != NULL);
278
+ upb_Message_ClearFieldByDef(options, field);
279
+
280
+ Message_freeze(options_rb);
281
+
282
+ rb_ivar_set(self, options_instancevar_interned, options_rb);
283
+ return options_rb;
284
+ }
285
+
229
286
  /*
230
287
  * call-seq:
231
288
  * Descriptor.new => descriptor
@@ -374,6 +431,26 @@ static VALUE Descriptor_msgclass(VALUE _self) {
374
431
  return self->klass;
375
432
  }
376
433
 
434
+ /*
435
+ * call-seq:
436
+ * Descriptor.options => options
437
+ *
438
+ * Returns the `MessageOptions` for this `Descriptor`.
439
+ */
440
+ static VALUE Descriptor_options(VALUE _self) {
441
+ Descriptor* self = ruby_to_Descriptor(_self);
442
+ const google_protobuf_MessageOptions* opts =
443
+ upb_MessageDef_Options(self->msgdef);
444
+ upb_Arena* arena = upb_Arena_New();
445
+ size_t size;
446
+ char* serialized =
447
+ google_protobuf_MessageOptions_serialize(opts, arena, &size);
448
+ VALUE message_options = decode_options(_self, "MessageOptions", size,
449
+ serialized, self->descriptor_pool);
450
+ upb_Arena_Free(arena);
451
+ return message_options;
452
+ }
453
+
377
454
  static void Descriptor_register(VALUE module) {
378
455
  VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
379
456
  rb_define_alloc_func(klass, Descriptor_alloc);
@@ -385,6 +462,7 @@ static void Descriptor_register(VALUE module) {
385
462
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
386
463
  rb_define_method(klass, "name", Descriptor_name, 0);
387
464
  rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
465
+ rb_define_method(klass, "options", Descriptor_options, 0);
388
466
  rb_include_module(klass, rb_mEnumerable);
389
467
  rb_gc_register_address(&cDescriptor);
390
468
  cDescriptor = klass;
@@ -432,7 +510,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
432
510
  * call-seq:
433
511
  * FileDescriptor.new => file
434
512
  *
435
- * Returns a new file descriptor. The syntax must be set before it's passed
513
+ * Returns a new file descriptor. May
436
514
  * to a builder.
437
515
  */
438
516
  static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
@@ -464,24 +542,20 @@ static VALUE FileDescriptor_name(VALUE _self) {
464
542
 
465
543
  /*
466
544
  * call-seq:
467
- * FileDescriptor.syntax => syntax
468
- *
469
- * Returns this file descriptors syntax.
545
+ * FileDescriptor.options => options
470
546
  *
471
- * Valid syntax versions are:
472
- * :proto2 or :proto3.
547
+ * Returns the `FileOptions` for this `FileDescriptor`.
473
548
  */
474
- static VALUE FileDescriptor_syntax(VALUE _self) {
549
+ static VALUE FileDescriptor_options(VALUE _self) {
475
550
  FileDescriptor* self = ruby_to_FileDescriptor(_self);
476
-
477
- switch (upb_FileDef_Syntax(self->filedef)) {
478
- case kUpb_Syntax_Proto3:
479
- return ID2SYM(rb_intern("proto3"));
480
- case kUpb_Syntax_Proto2:
481
- return ID2SYM(rb_intern("proto2"));
482
- default:
483
- return Qnil;
484
- }
551
+ const google_protobuf_FileOptions* opts = upb_FileDef_Options(self->filedef);
552
+ upb_Arena* arena = upb_Arena_New();
553
+ size_t size;
554
+ char* serialized = google_protobuf_FileOptions_serialize(opts, arena, &size);
555
+ VALUE file_options = decode_options(_self, "FileOptions", size, serialized,
556
+ self->descriptor_pool);
557
+ upb_Arena_Free(arena);
558
+ return file_options;
485
559
  }
486
560
 
487
561
  static void FileDescriptor_register(VALUE module) {
@@ -489,7 +563,7 @@ static void FileDescriptor_register(VALUE module) {
489
563
  rb_define_alloc_func(klass, FileDescriptor_alloc);
490
564
  rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
491
565
  rb_define_method(klass, "name", FileDescriptor_name, 0);
492
- rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
566
+ rb_define_method(klass, "options", FileDescriptor_options, 0);
493
567
  rb_gc_register_address(&cFileDescriptor);
494
568
  cFileDescriptor = klass;
495
569
  }
@@ -540,7 +614,7 @@ static VALUE FieldDescriptor_alloc(VALUE klass) {
540
614
 
541
615
  /*
542
616
  * call-seq:
543
- * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
617
+ * FieldDescriptor.new(c_only_cookie, pool, ptr) => FieldDescriptor
544
618
  *
545
619
  * Creates a descriptor wrapper object. May only be called from C.
546
620
  */
@@ -651,7 +725,7 @@ static VALUE FieldDescriptor__type(VALUE _self) {
651
725
  static VALUE FieldDescriptor_default(VALUE _self) {
652
726
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
653
727
  const upb_FieldDef* f = self->fielddef;
654
- upb_MessageValue default_val = {0};
728
+ upb_MessageValue default_val = upb_MessageValue_Zero();
655
729
  if (upb_FieldDef_IsSubMessage(f)) {
656
730
  return Qnil;
657
731
  } else if (!upb_FieldDef_IsRepeated(f)) {
@@ -660,6 +734,28 @@ static VALUE FieldDescriptor_default(VALUE _self) {
660
734
  return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
661
735
  }
662
736
 
737
+ /*
738
+ * call-seq:
739
+ * FieldDescriptor.has_presence? => bool
740
+ *
741
+ * Returns whether this field tracks presence.
742
+ */
743
+ static VALUE FieldDescriptor_has_presence(VALUE _self) {
744
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
745
+ return upb_FieldDef_HasPresence(self->fielddef) ? Qtrue : Qfalse;
746
+ }
747
+
748
+ /*
749
+ * call-seq:
750
+ * FieldDescriptor.is_packed? => bool
751
+ *
752
+ * Returns whether this is a repeated field that uses packed encoding.
753
+ */
754
+ static VALUE FieldDescriptor_is_packed(VALUE _self) {
755
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
756
+ return upb_FieldDef_IsPacked(self->fielddef) ? Qtrue : Qfalse;
757
+ }
758
+
663
759
  /*
664
760
  * call-seq:
665
761
  * FieldDescriptor.json_name => json_name
@@ -786,7 +882,7 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
786
882
  static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
787
883
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
788
884
  const upb_MessageDef* m;
789
- const upb_MessageDef* msg = Message_Get(msg_rb, &m);
885
+ const upb_Message* msg = Message_Get(msg_rb, &m);
790
886
 
791
887
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
792
888
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -806,7 +902,7 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
806
902
  static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
807
903
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
808
904
  const upb_MessageDef* m;
809
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
905
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
810
906
 
811
907
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
812
908
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -827,7 +923,7 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
827
923
  static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
828
924
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
829
925
  const upb_MessageDef* m;
830
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
926
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
831
927
  upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
832
928
  upb_MessageValue msgval;
833
929
 
@@ -841,6 +937,25 @@ static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
841
937
  return Qnil;
842
938
  }
843
939
 
940
+ /*
941
+ * call-seq:
942
+ * FieldDescriptor.options => options
943
+ *
944
+ * Returns the `FieldOptions` for this `FieldDescriptor`.
945
+ */
946
+ static VALUE FieldDescriptor_options(VALUE _self) {
947
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
948
+ const google_protobuf_FieldOptions* opts =
949
+ upb_FieldDef_Options(self->fielddef);
950
+ upb_Arena* arena = upb_Arena_New();
951
+ size_t size;
952
+ char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, &size);
953
+ VALUE field_options = decode_options(_self, "FieldOptions", size, serialized,
954
+ self->descriptor_pool);
955
+ upb_Arena_Free(arena);
956
+ return field_options;
957
+ }
958
+
844
959
  static void FieldDescriptor_register(VALUE module) {
845
960
  VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
846
961
  rb_define_alloc_func(klass, FieldDescriptor_alloc);
@@ -848,6 +963,8 @@ static void FieldDescriptor_register(VALUE module) {
848
963
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
849
964
  rb_define_method(klass, "type", FieldDescriptor__type, 0);
850
965
  rb_define_method(klass, "default", FieldDescriptor_default, 0);
966
+ rb_define_method(klass, "has_presence?", FieldDescriptor_has_presence, 0);
967
+ rb_define_method(klass, "is_packed?", FieldDescriptor_is_packed, 0);
851
968
  rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
852
969
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
853
970
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
@@ -857,6 +974,7 @@ static void FieldDescriptor_register(VALUE module) {
857
974
  rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
858
975
  rb_define_method(klass, "get", FieldDescriptor_get, 1);
859
976
  rb_define_method(klass, "set", FieldDescriptor_set, 2);
977
+ rb_define_method(klass, "options", FieldDescriptor_options, 0);
860
978
  rb_gc_register_address(&cFieldDescriptor);
861
979
  cFieldDescriptor = klass;
862
980
  }
@@ -956,12 +1074,32 @@ static VALUE OneofDescriptor_each(VALUE _self) {
956
1074
  return Qnil;
957
1075
  }
958
1076
 
1077
+ /*
1078
+ * call-seq:
1079
+ * OneofDescriptor.options => options
1080
+ *
1081
+ * Returns the `OneofOptions` for this `OneofDescriptor`.
1082
+ */
1083
+ static VALUE OneOfDescriptor_options(VALUE _self) {
1084
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1085
+ const google_protobuf_OneofOptions* opts =
1086
+ upb_OneofDef_Options(self->oneofdef);
1087
+ upb_Arena* arena = upb_Arena_New();
1088
+ size_t size;
1089
+ char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, &size);
1090
+ VALUE oneof_options = decode_options(_self, "OneofOptions", size, serialized,
1091
+ self->descriptor_pool);
1092
+ upb_Arena_Free(arena);
1093
+ return oneof_options;
1094
+ }
1095
+
959
1096
  static void OneofDescriptor_register(VALUE module) {
960
1097
  VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
961
1098
  rb_define_alloc_func(klass, OneofDescriptor_alloc);
962
1099
  rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
963
1100
  rb_define_method(klass, "name", OneofDescriptor_name, 0);
964
1101
  rb_define_method(klass, "each", OneofDescriptor_each, 0);
1102
+ rb_define_method(klass, "options", OneOfDescriptor_options, 0);
965
1103
  rb_include_module(klass, rb_mEnumerable);
966
1104
  rb_gc_register_address(&cOneofDescriptor);
967
1105
  cOneofDescriptor = klass;
@@ -1047,6 +1185,17 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1047
1185
  upb_EnumDef_File(self->enumdef));
1048
1186
  }
1049
1187
 
1188
+ /*
1189
+ * call-seq:
1190
+ * EnumDescriptor.is_closed? => bool
1191
+ *
1192
+ * Returns whether this enum is open or closed.
1193
+ */
1194
+ static VALUE EnumDescriptor_is_closed(VALUE _self) {
1195
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1196
+ return upb_EnumDef_IsClosed(self->enumdef) ? Qtrue : Qfalse;
1197
+ }
1198
+
1050
1199
  /*
1051
1200
  * call-seq:
1052
1201
  * EnumDescriptor.name => name
@@ -1131,6 +1280,24 @@ static VALUE EnumDescriptor_enummodule(VALUE _self) {
1131
1280
  return self->module;
1132
1281
  }
1133
1282
 
1283
+ /*
1284
+ * call-seq:
1285
+ * EnumDescriptor.options => options
1286
+ *
1287
+ * Returns the `EnumOptions` for this `EnumDescriptor`.
1288
+ */
1289
+ static VALUE EnumDescriptor_options(VALUE _self) {
1290
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1291
+ const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(self->enumdef);
1292
+ upb_Arena* arena = upb_Arena_New();
1293
+ size_t size;
1294
+ char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, &size);
1295
+ VALUE enum_options = decode_options(_self, "EnumOptions", size, serialized,
1296
+ self->descriptor_pool);
1297
+ upb_Arena_Free(arena);
1298
+ return enum_options;
1299
+ }
1300
+
1134
1301
  static void EnumDescriptor_register(VALUE module) {
1135
1302
  VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
1136
1303
  rb_define_alloc_func(klass, EnumDescriptor_alloc);
@@ -1141,11 +1308,305 @@ static void EnumDescriptor_register(VALUE module) {
1141
1308
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1142
1309
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1143
1310
  rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1311
+ rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0);
1312
+ rb_define_method(klass, "options", EnumDescriptor_options, 0);
1144
1313
  rb_include_module(klass, rb_mEnumerable);
1145
1314
  rb_gc_register_address(&cEnumDescriptor);
1146
1315
  cEnumDescriptor = klass;
1147
1316
  }
1148
1317
 
1318
+ // -----------------------------------------------------------------------------
1319
+ // ServiceDescriptor
1320
+ // -----------------------------------------------------------------------------
1321
+
1322
+ typedef struct {
1323
+ const upb_ServiceDef* servicedef;
1324
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
1325
+ // macro to update VALUE references, as to trigger write barriers.
1326
+ VALUE module; // begins as nil
1327
+ VALUE descriptor_pool; // Owns the upb_ServiceDef.
1328
+ } ServiceDescriptor;
1329
+
1330
+ static VALUE cServiceDescriptor = Qnil;
1331
+
1332
+ static void ServiceDescriptor_mark(void* _self) {
1333
+ ServiceDescriptor* self = _self;
1334
+ rb_gc_mark(self->module);
1335
+ rb_gc_mark(self->descriptor_pool);
1336
+ }
1337
+
1338
+ static const rb_data_type_t ServiceDescriptor_type = {
1339
+ "Google::Protobuf::ServicDescriptor",
1340
+ {ServiceDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1341
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1342
+ };
1343
+
1344
+ static ServiceDescriptor* ruby_to_ServiceDescriptor(VALUE val) {
1345
+ ServiceDescriptor* ret;
1346
+ TypedData_Get_Struct(val, ServiceDescriptor, &ServiceDescriptor_type, ret);
1347
+ return ret;
1348
+ }
1349
+
1350
+ static VALUE ServiceDescriptor_alloc(VALUE klass) {
1351
+ ServiceDescriptor* self = ALLOC(ServiceDescriptor);
1352
+ VALUE ret = TypedData_Wrap_Struct(klass, &ServiceDescriptor_type, self);
1353
+ self->servicedef = NULL;
1354
+ self->module = Qnil;
1355
+ self->descriptor_pool = Qnil;
1356
+ return ret;
1357
+ }
1358
+
1359
+ /*
1360
+ * call-seq:
1361
+ * ServiceDescriptor.new(c_only_cookie, ptr) => ServiceDescriptor
1362
+ *
1363
+ * Creates a descriptor wrapper object. May only be called from C.
1364
+ */
1365
+ static VALUE ServiceDescriptor_initialize(VALUE _self, VALUE cookie,
1366
+ VALUE descriptor_pool, VALUE ptr) {
1367
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1368
+
1369
+ if (cookie != c_only_cookie) {
1370
+ rb_raise(rb_eRuntimeError,
1371
+ "Descriptor objects may not be created from Ruby.");
1372
+ }
1373
+
1374
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1375
+ self->servicedef = (const upb_ServiceDef*)NUM2ULL(ptr);
1376
+
1377
+ return Qnil;
1378
+ }
1379
+
1380
+ /*
1381
+ * call-seq:
1382
+ * ServiceDescriptor.name => name
1383
+ *
1384
+ * Returns the name of this service.
1385
+ */
1386
+ static VALUE ServiceDescriptor_name(VALUE _self) {
1387
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1388
+ return rb_str_maybe_null(upb_ServiceDef_FullName(self->servicedef));
1389
+ }
1390
+
1391
+ /*
1392
+ * call-seq:
1393
+ * ServiceDescriptor.file_descriptor
1394
+ *
1395
+ * Returns the FileDescriptor object this service belongs to.
1396
+ */
1397
+ static VALUE ServiceDescriptor_file_descriptor(VALUE _self) {
1398
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1399
+ return get_filedef_obj(self->descriptor_pool,
1400
+ upb_ServiceDef_File(self->servicedef));
1401
+ }
1402
+
1403
+ /*
1404
+ * call-seq:
1405
+ * ServiceDescriptor.each(&block)
1406
+ *
1407
+ * Iterates over methods in this service, yielding to the block on each one.
1408
+ */
1409
+ static VALUE ServiceDescriptor_each(VALUE _self) {
1410
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1411
+
1412
+ int n = upb_ServiceDef_MethodCount(self->servicedef);
1413
+ for (int i = 0; i < n; i++) {
1414
+ const upb_MethodDef* method = upb_ServiceDef_Method(self->servicedef, i);
1415
+ VALUE obj = get_methoddef_obj(self->descriptor_pool, method);
1416
+ rb_yield(obj);
1417
+ }
1418
+ return Qnil;
1419
+ }
1420
+
1421
+ /*
1422
+ * call-seq:
1423
+ * ServiceDescriptor.options => options
1424
+ *
1425
+ * Returns the `ServiceOptions` for this `ServiceDescriptor`.
1426
+ */
1427
+ static VALUE ServiceDescriptor_options(VALUE _self) {
1428
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1429
+ const google_protobuf_ServiceOptions* opts =
1430
+ upb_ServiceDef_Options(self->servicedef);
1431
+ upb_Arena* arena = upb_Arena_New();
1432
+ size_t size;
1433
+ char* serialized =
1434
+ google_protobuf_ServiceOptions_serialize(opts, arena, &size);
1435
+ VALUE service_options = decode_options(_self, "ServiceOptions", size,
1436
+ serialized, self->descriptor_pool);
1437
+ upb_Arena_Free(arena);
1438
+ return service_options;
1439
+ }
1440
+
1441
+ static void ServiceDescriptor_register(VALUE module) {
1442
+ VALUE klass = rb_define_class_under(module, "ServiceDescriptor", rb_cObject);
1443
+ rb_define_alloc_func(klass, ServiceDescriptor_alloc);
1444
+ rb_define_method(klass, "initialize", ServiceDescriptor_initialize, 3);
1445
+ rb_define_method(klass, "name", ServiceDescriptor_name, 0);
1446
+ rb_define_method(klass, "each", ServiceDescriptor_each, 0);
1447
+ rb_define_method(klass, "file_descriptor", ServiceDescriptor_file_descriptor,
1448
+ 0);
1449
+ rb_define_method(klass, "options", ServiceDescriptor_options, 0);
1450
+ rb_include_module(klass, rb_mEnumerable);
1451
+ rb_gc_register_address(&cServiceDescriptor);
1452
+ cServiceDescriptor = klass;
1453
+ }
1454
+
1455
+ // -----------------------------------------------------------------------------
1456
+ // MethodDescriptor
1457
+ // -----------------------------------------------------------------------------
1458
+
1459
+ typedef struct {
1460
+ const upb_MethodDef* methoddef;
1461
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
1462
+ // macro to update VALUE references, as to trigger write barriers.
1463
+ VALUE module; // begins as nil
1464
+ VALUE descriptor_pool; // Owns the upb_MethodDef.
1465
+ } MethodDescriptor;
1466
+
1467
+ static VALUE cMethodDescriptor = Qnil;
1468
+
1469
+ static void MethodDescriptor_mark(void* _self) {
1470
+ MethodDescriptor* self = _self;
1471
+ rb_gc_mark(self->module);
1472
+ rb_gc_mark(self->descriptor_pool);
1473
+ }
1474
+
1475
+ static const rb_data_type_t MethodDescriptor_type = {
1476
+ "Google::Protobuf::MethodDescriptor",
1477
+ {MethodDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1478
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1479
+ };
1480
+
1481
+ static MethodDescriptor* ruby_to_MethodDescriptor(VALUE val) {
1482
+ MethodDescriptor* ret;
1483
+ TypedData_Get_Struct(val, MethodDescriptor, &MethodDescriptor_type, ret);
1484
+ return ret;
1485
+ }
1486
+
1487
+ static VALUE MethodDescriptor_alloc(VALUE klass) {
1488
+ MethodDescriptor* self = ALLOC(MethodDescriptor);
1489
+ VALUE ret = TypedData_Wrap_Struct(klass, &MethodDescriptor_type, self);
1490
+ self->methoddef = NULL;
1491
+ self->module = Qnil;
1492
+ self->descriptor_pool = Qnil;
1493
+ return ret;
1494
+ }
1495
+
1496
+ /*
1497
+ * call-seq:
1498
+ * MethodDescriptor.new(c_only_cookie, ptr) => MethodDescriptor
1499
+ *
1500
+ * Creates a descriptor wrapper object. May only be called from C.
1501
+ */
1502
+ static VALUE MethodDescriptor_initialize(VALUE _self, VALUE cookie,
1503
+ VALUE descriptor_pool, VALUE ptr) {
1504
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1505
+
1506
+ if (cookie != c_only_cookie) {
1507
+ rb_raise(rb_eRuntimeError,
1508
+ "Descriptor objects may not be created from Ruby.");
1509
+ }
1510
+
1511
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1512
+ self->methoddef = (const upb_MethodDef*)NUM2ULL(ptr);
1513
+
1514
+ return Qnil;
1515
+ }
1516
+
1517
+ /*
1518
+ * call-seq:
1519
+ * MethodDescriptor.name => name
1520
+ *
1521
+ * Returns the name of this method
1522
+ */
1523
+ static VALUE MethodDescriptor_name(VALUE _self) {
1524
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1525
+ return rb_str_maybe_null(upb_MethodDef_Name(self->methoddef));
1526
+ }
1527
+
1528
+ /*
1529
+ * call-seq:
1530
+ * MethodDescriptor.options => options
1531
+ *
1532
+ * Returns the `MethodOptions` for this `MethodDescriptor`.
1533
+ */
1534
+ static VALUE MethodDescriptor_options(VALUE _self) {
1535
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1536
+ const google_protobuf_MethodOptions* opts =
1537
+ upb_MethodDef_Options(self->methoddef);
1538
+ upb_Arena* arena = upb_Arena_New();
1539
+ size_t size;
1540
+ char* serialized =
1541
+ google_protobuf_MethodOptions_serialize(opts, arena, &size);
1542
+ VALUE method_options = decode_options(_self, "MethodOptions", size,
1543
+ serialized, self->descriptor_pool);
1544
+ upb_Arena_Free(arena);
1545
+ return method_options;
1546
+ }
1547
+
1548
+ /*
1549
+ * call-seq:
1550
+ * MethodDescriptor.input_type => Descriptor
1551
+ *
1552
+ * Returns the `Descriptor` for the request message type of this method
1553
+ */
1554
+ static VALUE MethodDescriptor_input_type(VALUE _self) {
1555
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1556
+ const upb_MessageDef* type = upb_MethodDef_InputType(self->methoddef);
1557
+ return get_msgdef_obj(self->descriptor_pool, type);
1558
+ }
1559
+
1560
+ /*
1561
+ * call-seq:
1562
+ * MethodDescriptor.output_type => Descriptor
1563
+ *
1564
+ * Returns the `Descriptor` for the response message type of this method
1565
+ */
1566
+ static VALUE MethodDescriptor_output_type(VALUE _self) {
1567
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1568
+ const upb_MessageDef* type = upb_MethodDef_OutputType(self->methoddef);
1569
+ return get_msgdef_obj(self->descriptor_pool, type);
1570
+ }
1571
+
1572
+ /*
1573
+ * call-seq:
1574
+ * MethodDescriptor.client_streaming => bool
1575
+ *
1576
+ * Returns whether or not this is a streaming request method
1577
+ */
1578
+ static VALUE MethodDescriptor_client_streaming(VALUE _self) {
1579
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1580
+ return upb_MethodDef_ClientStreaming(self->methoddef) ? Qtrue : Qfalse;
1581
+ }
1582
+
1583
+ /*
1584
+ * call-seq:
1585
+ * MethodDescriptor.server_streaming => bool
1586
+ *
1587
+ * Returns whether or not this is a streaming response method
1588
+ */
1589
+ static VALUE MethodDescriptor_server_streaming(VALUE _self) {
1590
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1591
+ return upb_MethodDef_ServerStreaming(self->methoddef) ? Qtrue : Qfalse;
1592
+ }
1593
+
1594
+ static void MethodDescriptor_register(VALUE module) {
1595
+ VALUE klass = rb_define_class_under(module, "MethodDescriptor", rb_cObject);
1596
+ rb_define_alloc_func(klass, MethodDescriptor_alloc);
1597
+ rb_define_method(klass, "initialize", MethodDescriptor_initialize, 3);
1598
+ rb_define_method(klass, "name", MethodDescriptor_name, 0);
1599
+ rb_define_method(klass, "options", MethodDescriptor_options, 0);
1600
+ rb_define_method(klass, "input_type", MethodDescriptor_input_type, 0);
1601
+ rb_define_method(klass, "output_type", MethodDescriptor_output_type, 0);
1602
+ rb_define_method(klass, "client_streaming", MethodDescriptor_client_streaming,
1603
+ 0);
1604
+ rb_define_method(klass, "server_streaming", MethodDescriptor_server_streaming,
1605
+ 0);
1606
+ rb_gc_register_address(&cMethodDescriptor);
1607
+ cMethodDescriptor = klass;
1608
+ }
1609
+
1149
1610
  static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
1150
1611
  DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
1151
1612
  VALUE key = ULL2NUM((intptr_t)ptr);
@@ -1187,6 +1648,16 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
1187
1648
  return get_def_obj(descriptor_pool, def, cOneofDescriptor);
1188
1649
  }
1189
1650
 
1651
+ static VALUE get_servicedef_obj(VALUE descriptor_pool,
1652
+ const upb_ServiceDef* def) {
1653
+ return get_def_obj(descriptor_pool, def, cServiceDescriptor);
1654
+ }
1655
+
1656
+ static VALUE get_methoddef_obj(VALUE descriptor_pool,
1657
+ const upb_MethodDef* def) {
1658
+ return get_def_obj(descriptor_pool, def, cMethodDescriptor);
1659
+ }
1660
+
1190
1661
  // -----------------------------------------------------------------------------
1191
1662
  // Shared functions
1192
1663
  // -----------------------------------------------------------------------------
@@ -1262,6 +1733,8 @@ void Defs_register(VALUE module) {
1262
1733
  FieldDescriptor_register(module);
1263
1734
  OneofDescriptor_register(module);
1264
1735
  EnumDescriptor_register(module);
1736
+ ServiceDescriptor_register(module);
1737
+ MethodDescriptor_register(module);
1265
1738
 
1266
1739
  rb_gc_register_address(&c_only_cookie);
1267
1740
  c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);