google-protobuf 3.23.3 → 4.27.1

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

Potentially problematic release.


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

Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +28 -72
  4. data/ext/google/protobuf_c/convert.h +3 -28
  5. data/ext/google/protobuf_c/defs.c +512 -60
  6. data/ext/google/protobuf_c/defs.h +3 -28
  7. data/ext/google/protobuf_c/extconf.rb +2 -1
  8. data/ext/google/protobuf_c/glue.c +72 -0
  9. data/ext/google/protobuf_c/map.c +28 -36
  10. data/ext/google/protobuf_c/map.h +6 -28
  11. data/ext/google/protobuf_c/message.c +88 -143
  12. data/ext/google/protobuf_c/message.h +10 -32
  13. data/ext/google/protobuf_c/protobuf.c +49 -175
  14. data/ext/google/protobuf_c/protobuf.h +24 -32
  15. data/ext/google/protobuf_c/repeated_field.c +23 -33
  16. data/ext/google/protobuf_c/repeated_field.h +6 -28
  17. data/ext/google/protobuf_c/ruby-upb.c +13046 -10690
  18. data/ext/google/protobuf_c/ruby-upb.h +8405 -5836
  19. data/ext/google/protobuf_c/shared_convert.c +69 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +37 -0
  22. data/ext/google/protobuf_c/shared_message.h +21 -0
  23. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
  24. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
  25. data/ext/google/protobuf_c/wrap_memcpy.c +3 -26
  26. data/lib/google/protobuf/any_pb.rb +1 -22
  27. data/lib/google/protobuf/api_pb.rb +1 -24
  28. data/lib/google/protobuf/descriptor_pb.rb +14 -23
  29. data/lib/google/protobuf/duration_pb.rb +1 -22
  30. data/lib/google/protobuf/empty_pb.rb +1 -22
  31. data/lib/google/protobuf/ffi/descriptor.rb +166 -0
  32. data/lib/google/protobuf/ffi/descriptor_pool.rb +77 -0
  33. data/lib/google/protobuf/ffi/enum_descriptor.rb +173 -0
  34. data/lib/google/protobuf/ffi/ffi.rb +210 -0
  35. data/lib/google/protobuf/ffi/field_descriptor.rb +330 -0
  36. data/lib/google/protobuf/ffi/file_descriptor.rb +49 -0
  37. data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
  38. data/lib/google/protobuf/ffi/internal/convert.rb +289 -0
  39. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  40. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  41. data/lib/google/protobuf/ffi/map.rb +409 -0
  42. data/lib/google/protobuf/ffi/message.rb +659 -0
  43. data/lib/google/protobuf/ffi/method_descriptor.rb +114 -0
  44. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  45. data/lib/google/protobuf/ffi/oneof_descriptor.rb +97 -0
  46. data/lib/google/protobuf/ffi/repeated_field.rb +385 -0
  47. data/lib/google/protobuf/ffi/service_descriptor.rb +107 -0
  48. data/lib/google/protobuf/field_mask_pb.rb +1 -22
  49. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  50. data/lib/google/protobuf/message_exts.rb +3 -26
  51. data/lib/google/protobuf/plugin_pb.rb +2 -24
  52. data/lib/google/protobuf/repeated_field.rb +7 -31
  53. data/lib/google/protobuf/source_context_pb.rb +1 -22
  54. data/lib/google/protobuf/struct_pb.rb +1 -22
  55. data/lib/google/protobuf/timestamp_pb.rb +1 -22
  56. data/lib/google/protobuf/type_pb.rb +1 -24
  57. data/lib/google/protobuf/well_known_types.rb +5 -34
  58. data/lib/google/protobuf/wrappers_pb.rb +1 -22
  59. data/lib/google/protobuf.rb +27 -45
  60. data/lib/google/protobuf_ffi.rb +51 -0
  61. data/lib/google/protobuf_native.rb +19 -0
  62. data/lib/google/tasks/ffi.rake +100 -0
  63. metadata +89 -8
  64. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  65. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  66. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  67. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
@@ -1,32 +1,9 @@
1
1
  // Protocol Buffers - Google's data interchange format
2
2
  // Copyright 2014 Google Inc. All rights reserved.
3
- // https://developers.google.com/protocol-buffers/
4
3
  //
5
- // Redistribution and use in source and binary forms, with or without
6
- // modification, are permitted provided that the following conditions are
7
- // met:
8
- //
9
- // * Redistributions of source code must retain the above copyright
10
- // notice, this list of conditions and the following disclaimer.
11
- // * Redistributions in binary form must reproduce the above
12
- // copyright notice, this list of conditions and the following disclaimer
13
- // in the documentation and/or other materials provided with the
14
- // distribution.
15
- // * Neither the name of Google Inc. nor the names of its
16
- // contributors may be used to endorse or promote products derived from
17
- // this software without specific prior written permission.
18
- //
19
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4
+ // Use of this source code is governed by a BSD-style
5
+ // license that can be found in the LICENSE file or at
6
+ // https://developers.google.com/open-source/licenses/bsd
30
7
 
31
8
  #include <ctype.h>
32
9
  #include <errno.h>
@@ -46,6 +23,9 @@ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def);
46
23
  static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def);
47
24
  static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def);
48
25
  static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def);
26
+ static VALUE get_servicedef_obj(VALUE descriptor_pool,
27
+ const upb_ServiceDef* def);
28
+ static VALUE get_methoddef_obj(VALUE descriptor_pool, const upb_MethodDef* def);
49
29
 
50
30
  // A distinct object that is not accessible from Ruby. We use this as a
51
31
  // constructor argument to enforce that certain objects cannot be created from
@@ -67,12 +47,14 @@ static VALUE rb_str_maybe_null(const char* s) {
67
47
  }
68
48
  return rb_str_new2(s);
69
49
  }
70
-
50
+ static ID options_instancevar_interned;
71
51
  // -----------------------------------------------------------------------------
72
52
  // DescriptorPool.
73
53
  // -----------------------------------------------------------------------------
74
54
 
75
55
  typedef struct {
56
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
57
+ // macro to update VALUE references, as to trigger write barriers.
76
58
  VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor.
77
59
  upb_DefPool* symtab;
78
60
  } DescriptorPool;
@@ -97,7 +79,7 @@ static void DescriptorPool_free(void* _self) {
97
79
  static const rb_data_type_t DescriptorPool_type = {
98
80
  "Google::Protobuf::DescriptorPool",
99
81
  {DescriptorPool_mark, DescriptorPool_free, NULL},
100
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
82
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
101
83
  };
102
84
 
103
85
  static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
@@ -125,11 +107,9 @@ static VALUE DescriptorPool_alloc(VALUE klass) {
125
107
  self->def_to_descriptor = Qnil;
126
108
  ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self);
127
109
 
128
- self->def_to_descriptor = rb_hash_new();
110
+ RB_OBJ_WRITE(ret, &self->def_to_descriptor, rb_hash_new());
129
111
  self->symtab = upb_DefPool_New();
130
- ObjectCache_Add(self->symtab, ret);
131
-
132
- return ret;
112
+ return ObjectCache_TryAdd(self->symtab, ret);
133
113
  }
134
114
 
135
115
  /*
@@ -167,25 +147,37 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self,
167
147
  * call-seq:
168
148
  * DescriptorPool.lookup(name) => descriptor
169
149
  *
170
- * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
171
- * exists with the given name.
150
+ * Finds a Descriptor, EnumDescriptor or FieldDescriptor by name and returns it,
151
+ * or nil if none exists with the given name.
172
152
  */
173
153
  static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
174
154
  DescriptorPool* self = ruby_to_DescriptorPool(_self);
175
155
  const char* name_str = get_str(name);
176
156
  const upb_MessageDef* msgdef;
177
157
  const upb_EnumDef* enumdef;
158
+ const upb_FieldDef* fielddef;
159
+ const upb_ServiceDef* servicedef;
178
160
 
179
161
  msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
180
162
  if (msgdef) {
181
163
  return get_msgdef_obj(_self, msgdef);
182
164
  }
183
165
 
166
+ fielddef = upb_DefPool_FindExtensionByName(self->symtab, name_str);
167
+ if (fielddef) {
168
+ return get_fielddef_obj(_self, fielddef);
169
+ }
170
+
184
171
  enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str);
185
172
  if (enumdef) {
186
173
  return get_enumdef_obj(_self, enumdef);
187
174
  }
188
175
 
176
+ servicedef = upb_DefPool_FindServiceByName(self->symtab, name_str);
177
+ if (servicedef) {
178
+ return get_servicedef_obj(_self, servicedef);
179
+ }
180
+
189
181
  return Qnil;
190
182
  }
191
183
 
@@ -215,6 +207,7 @@ static void DescriptorPool_register(VALUE module) {
215
207
 
216
208
  rb_gc_register_address(&generated_pool);
217
209
  generated_pool = rb_class_new_instance(0, NULL, klass);
210
+ options_instancevar_interned = rb_intern("options");
218
211
  }
219
212
 
220
213
  // -----------------------------------------------------------------------------
@@ -249,6 +242,48 @@ static Descriptor* ruby_to_Descriptor(VALUE val) {
249
242
  return ret;
250
243
  }
251
244
 
245
+ // Decode and return a frozen instance of a Descriptor Option for the given pool
246
+ static VALUE decode_options(VALUE self, const char* option_type, int size,
247
+ const char* bytes, VALUE descriptor_pool) {
248
+ VALUE options_rb = rb_ivar_get(self, options_instancevar_interned);
249
+ if (options_rb != Qnil) {
250
+ return options_rb;
251
+ }
252
+
253
+ static const char* prefix = "google.protobuf.";
254
+ char fullname
255
+ [/*strlen(prefix)*/ 16 +
256
+ /*strln(longest option type supported e.g. "MessageOptions")*/ 14 +
257
+ /*null terminator*/ 1];
258
+
259
+ snprintf(fullname, sizeof(fullname), "%s%s", prefix, option_type);
260
+ const upb_MessageDef* msgdef = upb_DefPool_FindMessageByName(
261
+ ruby_to_DescriptorPool(descriptor_pool)->symtab, fullname);
262
+ if (!msgdef) {
263
+ rb_raise(rb_eRuntimeError, "Cannot find %s in DescriptorPool", option_type);
264
+ }
265
+
266
+ VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef);
267
+ const Descriptor* desc = ruby_to_Descriptor(desc_rb);
268
+
269
+ options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, false);
270
+
271
+ // Strip features from the options proto to keep it internal.
272
+ const upb_MessageDef* decoded_desc = NULL;
273
+ upb_Message* options = Message_GetMutable(options_rb, &decoded_desc);
274
+ PBRUBY_ASSERT(options != NULL);
275
+ PBRUBY_ASSERT(decoded_desc == msgdef);
276
+ const upb_FieldDef* field =
277
+ upb_MessageDef_FindFieldByName(decoded_desc, "features");
278
+ PBRUBY_ASSERT(field != NULL);
279
+ upb_Message_ClearFieldByDef(options, field);
280
+
281
+ Message_freeze(options_rb);
282
+
283
+ rb_ivar_set(self, options_instancevar_interned, options_rb);
284
+ return options_rb;
285
+ }
286
+
252
287
  /*
253
288
  * call-seq:
254
289
  * Descriptor.new => descriptor
@@ -397,6 +432,26 @@ static VALUE Descriptor_msgclass(VALUE _self) {
397
432
  return self->klass;
398
433
  }
399
434
 
435
+ /*
436
+ * call-seq:
437
+ * Descriptor.options => options
438
+ *
439
+ * Returns the `MessageOptions` for this `Descriptor`.
440
+ */
441
+ static VALUE Descriptor_options(VALUE _self) {
442
+ Descriptor* self = ruby_to_Descriptor(_self);
443
+ const google_protobuf_MessageOptions* opts =
444
+ upb_MessageDef_Options(self->msgdef);
445
+ upb_Arena* arena = upb_Arena_New();
446
+ size_t size;
447
+ char* serialized =
448
+ google_protobuf_MessageOptions_serialize(opts, arena, &size);
449
+ VALUE message_options = decode_options(_self, "MessageOptions", size,
450
+ serialized, self->descriptor_pool);
451
+ upb_Arena_Free(arena);
452
+ return message_options;
453
+ }
454
+
400
455
  static void Descriptor_register(VALUE module) {
401
456
  VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject);
402
457
  rb_define_alloc_func(klass, Descriptor_alloc);
@@ -408,6 +463,7 @@ static void Descriptor_register(VALUE module) {
408
463
  rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
409
464
  rb_define_method(klass, "name", Descriptor_name, 0);
410
465
  rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
466
+ rb_define_method(klass, "options", Descriptor_options, 0);
411
467
  rb_include_module(klass, rb_mEnumerable);
412
468
  rb_gc_register_address(&cDescriptor);
413
469
  cDescriptor = klass;
@@ -455,7 +511,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
455
511
  * call-seq:
456
512
  * FileDescriptor.new => file
457
513
  *
458
- * Returns a new file descriptor. The syntax must be set before it's passed
514
+ * Returns a new file descriptor. May
459
515
  * to a builder.
460
516
  */
461
517
  static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
@@ -487,24 +543,20 @@ static VALUE FileDescriptor_name(VALUE _self) {
487
543
 
488
544
  /*
489
545
  * call-seq:
490
- * FileDescriptor.syntax => syntax
546
+ * FileDescriptor.options => options
491
547
  *
492
- * Returns this file descriptors syntax.
493
- *
494
- * Valid syntax versions are:
495
- * :proto2 or :proto3.
548
+ * Returns the `FileOptions` for this `FileDescriptor`.
496
549
  */
497
- static VALUE FileDescriptor_syntax(VALUE _self) {
550
+ static VALUE FileDescriptor_options(VALUE _self) {
498
551
  FileDescriptor* self = ruby_to_FileDescriptor(_self);
499
-
500
- switch (upb_FileDef_Syntax(self->filedef)) {
501
- case kUpb_Syntax_Proto3:
502
- return ID2SYM(rb_intern("proto3"));
503
- case kUpb_Syntax_Proto2:
504
- return ID2SYM(rb_intern("proto2"));
505
- default:
506
- return Qnil;
507
- }
552
+ const google_protobuf_FileOptions* opts = upb_FileDef_Options(self->filedef);
553
+ upb_Arena* arena = upb_Arena_New();
554
+ size_t size;
555
+ char* serialized = google_protobuf_FileOptions_serialize(opts, arena, &size);
556
+ VALUE file_options = decode_options(_self, "FileOptions", size, serialized,
557
+ self->descriptor_pool);
558
+ upb_Arena_Free(arena);
559
+ return file_options;
508
560
  }
509
561
 
510
562
  static void FileDescriptor_register(VALUE module) {
@@ -512,7 +564,7 @@ static void FileDescriptor_register(VALUE module) {
512
564
  rb_define_alloc_func(klass, FileDescriptor_alloc);
513
565
  rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
514
566
  rb_define_method(klass, "name", FileDescriptor_name, 0);
515
- rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
567
+ rb_define_method(klass, "options", FileDescriptor_options, 0);
516
568
  rb_gc_register_address(&cFileDescriptor);
517
569
  cFileDescriptor = klass;
518
570
  }
@@ -563,7 +615,7 @@ static VALUE FieldDescriptor_alloc(VALUE klass) {
563
615
 
564
616
  /*
565
617
  * call-seq:
566
- * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
618
+ * FieldDescriptor.new(c_only_cookie, pool, ptr) => FieldDescriptor
567
619
  *
568
620
  * Creates a descriptor wrapper object. May only be called from C.
569
621
  */
@@ -601,7 +653,7 @@ upb_CType ruby_to_fieldtype(VALUE type) {
601
653
 
602
654
  #define CONVERT(upb, ruby) \
603
655
  if (SYM2ID(type) == rb_intern(#ruby)) { \
604
- return kUpb_CType_##upb; \
656
+ return kUpb_CType_##upb; \
605
657
  }
606
658
 
607
659
  CONVERT(Float, float);
@@ -624,7 +676,7 @@ upb_CType ruby_to_fieldtype(VALUE type) {
624
676
 
625
677
  static VALUE descriptortype_to_ruby(upb_FieldType type) {
626
678
  switch (type) {
627
- #define CONVERT(upb, ruby) \
679
+ #define CONVERT(upb, ruby) \
628
680
  case kUpb_FieldType_##upb: \
629
681
  return ID2SYM(rb_intern(#ruby));
630
682
  CONVERT(Float, float);
@@ -683,6 +735,28 @@ static VALUE FieldDescriptor_default(VALUE _self) {
683
735
  return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
684
736
  }
685
737
 
738
+ /*
739
+ * call-seq:
740
+ * FieldDescriptor.has_presence? => bool
741
+ *
742
+ * Returns whether this field tracks presence.
743
+ */
744
+ static VALUE FieldDescriptor_has_presence(VALUE _self) {
745
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
746
+ return upb_FieldDef_HasPresence(self->fielddef) ? Qtrue : Qfalse;
747
+ }
748
+
749
+ /*
750
+ * call-seq:
751
+ * FieldDescriptor.is_packed? => bool
752
+ *
753
+ * Returns whether this is a repeated field that uses packed encoding.
754
+ */
755
+ static VALUE FieldDescriptor_is_packed(VALUE _self) {
756
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
757
+ return upb_FieldDef_IsPacked(self->fielddef) ? Qtrue : Qfalse;
758
+ }
759
+
686
760
  /*
687
761
  * call-seq:
688
762
  * FieldDescriptor.json_name => json_name
@@ -709,7 +783,7 @@ static VALUE FieldDescriptor_label(VALUE _self) {
709
783
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
710
784
  switch (upb_FieldDef_Label(self->fielddef)) {
711
785
  #define CONVERT(upb, ruby) \
712
- case kUpb_Label_##upb: \
786
+ case kUpb_Label_##upb: \
713
787
  return ID2SYM(rb_intern(#ruby));
714
788
 
715
789
  CONVERT(Optional, optional);
@@ -809,7 +883,7 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
809
883
  static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
810
884
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
811
885
  const upb_MessageDef* m;
812
- const upb_MessageDef* msg = Message_Get(msg_rb, &m);
886
+ const upb_Message* msg = Message_Get(msg_rb, &m);
813
887
 
814
888
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
815
889
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -829,7 +903,7 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
829
903
  static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
830
904
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
831
905
  const upb_MessageDef* m;
832
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
906
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
833
907
 
834
908
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
835
909
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -850,7 +924,7 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
850
924
  static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
851
925
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
852
926
  const upb_MessageDef* m;
853
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
927
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
854
928
  upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
855
929
  upb_MessageValue msgval;
856
930
 
@@ -864,6 +938,25 @@ static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
864
938
  return Qnil;
865
939
  }
866
940
 
941
+ /*
942
+ * call-seq:
943
+ * FieldDescriptor.options => options
944
+ *
945
+ * Returns the `FieldOptions` for this `FieldDescriptor`.
946
+ */
947
+ static VALUE FieldDescriptor_options(VALUE _self) {
948
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
949
+ const google_protobuf_FieldOptions* opts =
950
+ upb_FieldDef_Options(self->fielddef);
951
+ upb_Arena* arena = upb_Arena_New();
952
+ size_t size;
953
+ char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, &size);
954
+ VALUE field_options = decode_options(_self, "FieldOptions", size, serialized,
955
+ self->descriptor_pool);
956
+ upb_Arena_Free(arena);
957
+ return field_options;
958
+ }
959
+
867
960
  static void FieldDescriptor_register(VALUE module) {
868
961
  VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject);
869
962
  rb_define_alloc_func(klass, FieldDescriptor_alloc);
@@ -871,6 +964,8 @@ static void FieldDescriptor_register(VALUE module) {
871
964
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
872
965
  rb_define_method(klass, "type", FieldDescriptor__type, 0);
873
966
  rb_define_method(klass, "default", FieldDescriptor_default, 0);
967
+ rb_define_method(klass, "has_presence?", FieldDescriptor_has_presence, 0);
968
+ rb_define_method(klass, "is_packed?", FieldDescriptor_is_packed, 0);
874
969
  rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
875
970
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
876
971
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
@@ -880,6 +975,7 @@ static void FieldDescriptor_register(VALUE module) {
880
975
  rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
881
976
  rb_define_method(klass, "get", FieldDescriptor_get, 1);
882
977
  rb_define_method(klass, "set", FieldDescriptor_set, 2);
978
+ rb_define_method(klass, "options", FieldDescriptor_options, 0);
883
979
  rb_gc_register_address(&cFieldDescriptor);
884
980
  cFieldDescriptor = klass;
885
981
  }
@@ -979,12 +1075,32 @@ static VALUE OneofDescriptor_each(VALUE _self) {
979
1075
  return Qnil;
980
1076
  }
981
1077
 
1078
+ /*
1079
+ * call-seq:
1080
+ * OneofDescriptor.options => options
1081
+ *
1082
+ * Returns the `OneofOptions` for this `OneofDescriptor`.
1083
+ */
1084
+ static VALUE OneOfDescriptor_options(VALUE _self) {
1085
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1086
+ const google_protobuf_OneofOptions* opts =
1087
+ upb_OneofDef_Options(self->oneofdef);
1088
+ upb_Arena* arena = upb_Arena_New();
1089
+ size_t size;
1090
+ char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, &size);
1091
+ VALUE oneof_options = decode_options(_self, "OneofOptions", size, serialized,
1092
+ self->descriptor_pool);
1093
+ upb_Arena_Free(arena);
1094
+ return oneof_options;
1095
+ }
1096
+
982
1097
  static void OneofDescriptor_register(VALUE module) {
983
1098
  VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject);
984
1099
  rb_define_alloc_func(klass, OneofDescriptor_alloc);
985
1100
  rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
986
1101
  rb_define_method(klass, "name", OneofDescriptor_name, 0);
987
1102
  rb_define_method(klass, "each", OneofDescriptor_each, 0);
1103
+ rb_define_method(klass, "options", OneOfDescriptor_options, 0);
988
1104
  rb_include_module(klass, rb_mEnumerable);
989
1105
  rb_gc_register_address(&cOneofDescriptor);
990
1106
  cOneofDescriptor = klass;
@@ -1070,6 +1186,17 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1070
1186
  upb_EnumDef_File(self->enumdef));
1071
1187
  }
1072
1188
 
1189
+ /*
1190
+ * call-seq:
1191
+ * EnumDescriptor.is_closed? => bool
1192
+ *
1193
+ * Returns whether this enum is open or closed.
1194
+ */
1195
+ static VALUE EnumDescriptor_is_closed(VALUE _self) {
1196
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1197
+ return upb_EnumDef_IsClosed(self->enumdef) ? Qtrue : Qfalse;
1198
+ }
1199
+
1073
1200
  /*
1074
1201
  * call-seq:
1075
1202
  * EnumDescriptor.name => name
@@ -1091,7 +1218,7 @@ static VALUE EnumDescriptor_name(VALUE _self) {
1091
1218
  static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1092
1219
  EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1093
1220
  const char* name_str = rb_id2name(SYM2ID(name));
1094
- const upb_EnumValueDef *ev =
1221
+ const upb_EnumValueDef* ev =
1095
1222
  upb_EnumDef_FindValueByName(self->enumdef, name_str);
1096
1223
  if (ev) {
1097
1224
  return INT2NUM(upb_EnumValueDef_Number(ev));
@@ -1110,7 +1237,8 @@ static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1110
1237
  static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1111
1238
  EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1112
1239
  int32_t val = NUM2INT(number);
1113
- const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(self->enumdef, val);
1240
+ const upb_EnumValueDef* ev =
1241
+ upb_EnumDef_FindValueByNumber(self->enumdef, val);
1114
1242
  if (ev) {
1115
1243
  return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev)));
1116
1244
  } else {
@@ -1153,6 +1281,24 @@ static VALUE EnumDescriptor_enummodule(VALUE _self) {
1153
1281
  return self->module;
1154
1282
  }
1155
1283
 
1284
+ /*
1285
+ * call-seq:
1286
+ * EnumDescriptor.options => options
1287
+ *
1288
+ * Returns the `EnumOptions` for this `EnumDescriptor`.
1289
+ */
1290
+ static VALUE EnumDescriptor_options(VALUE _self) {
1291
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1292
+ const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(self->enumdef);
1293
+ upb_Arena* arena = upb_Arena_New();
1294
+ size_t size;
1295
+ char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, &size);
1296
+ VALUE enum_options = decode_options(_self, "EnumOptions", size, serialized,
1297
+ self->descriptor_pool);
1298
+ upb_Arena_Free(arena);
1299
+ return enum_options;
1300
+ }
1301
+
1156
1302
  static void EnumDescriptor_register(VALUE module) {
1157
1303
  VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject);
1158
1304
  rb_define_alloc_func(klass, EnumDescriptor_alloc);
@@ -1163,11 +1309,305 @@ static void EnumDescriptor_register(VALUE module) {
1163
1309
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1164
1310
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1165
1311
  rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1312
+ rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0);
1313
+ rb_define_method(klass, "options", EnumDescriptor_options, 0);
1166
1314
  rb_include_module(klass, rb_mEnumerable);
1167
1315
  rb_gc_register_address(&cEnumDescriptor);
1168
1316
  cEnumDescriptor = klass;
1169
1317
  }
1170
1318
 
1319
+ // -----------------------------------------------------------------------------
1320
+ // ServiceDescriptor
1321
+ // -----------------------------------------------------------------------------
1322
+
1323
+ typedef struct {
1324
+ const upb_ServiceDef* servicedef;
1325
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
1326
+ // macro to update VALUE references, as to trigger write barriers.
1327
+ VALUE module; // begins as nil
1328
+ VALUE descriptor_pool; // Owns the upb_ServiceDef.
1329
+ } ServiceDescriptor;
1330
+
1331
+ static VALUE cServiceDescriptor = Qnil;
1332
+
1333
+ static void ServiceDescriptor_mark(void* _self) {
1334
+ ServiceDescriptor* self = _self;
1335
+ rb_gc_mark(self->module);
1336
+ rb_gc_mark(self->descriptor_pool);
1337
+ }
1338
+
1339
+ static const rb_data_type_t ServiceDescriptor_type = {
1340
+ "Google::Protobuf::ServicDescriptor",
1341
+ {ServiceDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1342
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1343
+ };
1344
+
1345
+ static ServiceDescriptor* ruby_to_ServiceDescriptor(VALUE val) {
1346
+ ServiceDescriptor* ret;
1347
+ TypedData_Get_Struct(val, ServiceDescriptor, &ServiceDescriptor_type, ret);
1348
+ return ret;
1349
+ }
1350
+
1351
+ static VALUE ServiceDescriptor_alloc(VALUE klass) {
1352
+ ServiceDescriptor* self = ALLOC(ServiceDescriptor);
1353
+ VALUE ret = TypedData_Wrap_Struct(klass, &ServiceDescriptor_type, self);
1354
+ self->servicedef = NULL;
1355
+ self->module = Qnil;
1356
+ self->descriptor_pool = Qnil;
1357
+ return ret;
1358
+ }
1359
+
1360
+ /*
1361
+ * call-seq:
1362
+ * ServiceDescriptor.new(c_only_cookie, ptr) => ServiceDescriptor
1363
+ *
1364
+ * Creates a descriptor wrapper object. May only be called from C.
1365
+ */
1366
+ static VALUE ServiceDescriptor_initialize(VALUE _self, VALUE cookie,
1367
+ VALUE descriptor_pool, VALUE ptr) {
1368
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1369
+
1370
+ if (cookie != c_only_cookie) {
1371
+ rb_raise(rb_eRuntimeError,
1372
+ "Descriptor objects may not be created from Ruby.");
1373
+ }
1374
+
1375
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1376
+ self->servicedef = (const upb_ServiceDef*)NUM2ULL(ptr);
1377
+
1378
+ return Qnil;
1379
+ }
1380
+
1381
+ /*
1382
+ * call-seq:
1383
+ * ServiceDescriptor.name => name
1384
+ *
1385
+ * Returns the name of this service.
1386
+ */
1387
+ static VALUE ServiceDescriptor_name(VALUE _self) {
1388
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1389
+ return rb_str_maybe_null(upb_ServiceDef_FullName(self->servicedef));
1390
+ }
1391
+
1392
+ /*
1393
+ * call-seq:
1394
+ * ServiceDescriptor.file_descriptor
1395
+ *
1396
+ * Returns the FileDescriptor object this service belongs to.
1397
+ */
1398
+ static VALUE ServiceDescriptor_file_descriptor(VALUE _self) {
1399
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1400
+ return get_filedef_obj(self->descriptor_pool,
1401
+ upb_ServiceDef_File(self->servicedef));
1402
+ }
1403
+
1404
+ /*
1405
+ * call-seq:
1406
+ * ServiceDescriptor.each(&block)
1407
+ *
1408
+ * Iterates over methods in this service, yielding to the block on each one.
1409
+ */
1410
+ static VALUE ServiceDescriptor_each(VALUE _self) {
1411
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1412
+
1413
+ int n = upb_ServiceDef_MethodCount(self->servicedef);
1414
+ for (int i = 0; i < n; i++) {
1415
+ const upb_MethodDef* method = upb_ServiceDef_Method(self->servicedef, i);
1416
+ VALUE obj = get_methoddef_obj(self->descriptor_pool, method);
1417
+ rb_yield(obj);
1418
+ }
1419
+ return Qnil;
1420
+ }
1421
+
1422
+ /*
1423
+ * call-seq:
1424
+ * ServiceDescriptor.options => options
1425
+ *
1426
+ * Returns the `ServiceOptions` for this `ServiceDescriptor`.
1427
+ */
1428
+ static VALUE ServiceDescriptor_options(VALUE _self) {
1429
+ ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self);
1430
+ const google_protobuf_ServiceOptions* opts =
1431
+ upb_ServiceDef_Options(self->servicedef);
1432
+ upb_Arena* arena = upb_Arena_New();
1433
+ size_t size;
1434
+ char* serialized =
1435
+ google_protobuf_ServiceOptions_serialize(opts, arena, &size);
1436
+ VALUE service_options = decode_options(_self, "ServiceOptions", size,
1437
+ serialized, self->descriptor_pool);
1438
+ upb_Arena_Free(arena);
1439
+ return service_options;
1440
+ }
1441
+
1442
+ static void ServiceDescriptor_register(VALUE module) {
1443
+ VALUE klass = rb_define_class_under(module, "ServiceDescriptor", rb_cObject);
1444
+ rb_define_alloc_func(klass, ServiceDescriptor_alloc);
1445
+ rb_define_method(klass, "initialize", ServiceDescriptor_initialize, 3);
1446
+ rb_define_method(klass, "name", ServiceDescriptor_name, 0);
1447
+ rb_define_method(klass, "each", ServiceDescriptor_each, 0);
1448
+ rb_define_method(klass, "file_descriptor", ServiceDescriptor_file_descriptor,
1449
+ 0);
1450
+ rb_define_method(klass, "options", ServiceDescriptor_options, 0);
1451
+ rb_include_module(klass, rb_mEnumerable);
1452
+ rb_gc_register_address(&cServiceDescriptor);
1453
+ cServiceDescriptor = klass;
1454
+ }
1455
+
1456
+ // -----------------------------------------------------------------------------
1457
+ // MethodDescriptor
1458
+ // -----------------------------------------------------------------------------
1459
+
1460
+ typedef struct {
1461
+ const upb_MethodDef* methoddef;
1462
+ // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
1463
+ // macro to update VALUE references, as to trigger write barriers.
1464
+ VALUE module; // begins as nil
1465
+ VALUE descriptor_pool; // Owns the upb_MethodDef.
1466
+ } MethodDescriptor;
1467
+
1468
+ static VALUE cMethodDescriptor = Qnil;
1469
+
1470
+ static void MethodDescriptor_mark(void* _self) {
1471
+ MethodDescriptor* self = _self;
1472
+ rb_gc_mark(self->module);
1473
+ rb_gc_mark(self->descriptor_pool);
1474
+ }
1475
+
1476
+ static const rb_data_type_t MethodDescriptor_type = {
1477
+ "Google::Protobuf::MethodDescriptor",
1478
+ {MethodDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1479
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
1480
+ };
1481
+
1482
+ static MethodDescriptor* ruby_to_MethodDescriptor(VALUE val) {
1483
+ MethodDescriptor* ret;
1484
+ TypedData_Get_Struct(val, MethodDescriptor, &MethodDescriptor_type, ret);
1485
+ return ret;
1486
+ }
1487
+
1488
+ static VALUE MethodDescriptor_alloc(VALUE klass) {
1489
+ MethodDescriptor* self = ALLOC(MethodDescriptor);
1490
+ VALUE ret = TypedData_Wrap_Struct(klass, &MethodDescriptor_type, self);
1491
+ self->methoddef = NULL;
1492
+ self->module = Qnil;
1493
+ self->descriptor_pool = Qnil;
1494
+ return ret;
1495
+ }
1496
+
1497
+ /*
1498
+ * call-seq:
1499
+ * MethodDescriptor.new(c_only_cookie, ptr) => MethodDescriptor
1500
+ *
1501
+ * Creates a descriptor wrapper object. May only be called from C.
1502
+ */
1503
+ static VALUE MethodDescriptor_initialize(VALUE _self, VALUE cookie,
1504
+ VALUE descriptor_pool, VALUE ptr) {
1505
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1506
+
1507
+ if (cookie != c_only_cookie) {
1508
+ rb_raise(rb_eRuntimeError,
1509
+ "Descriptor objects may not be created from Ruby.");
1510
+ }
1511
+
1512
+ RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool);
1513
+ self->methoddef = (const upb_ServiceDef*)NUM2ULL(ptr);
1514
+
1515
+ return Qnil;
1516
+ }
1517
+
1518
+ /*
1519
+ * call-seq:
1520
+ * MethodDescriptor.name => name
1521
+ *
1522
+ * Returns the name of this method
1523
+ */
1524
+ static VALUE MethodDescriptor_name(VALUE _self) {
1525
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1526
+ return rb_str_maybe_null(upb_MethodDef_Name(self->methoddef));
1527
+ }
1528
+
1529
+ /*
1530
+ * call-seq:
1531
+ * MethodDescriptor.options => options
1532
+ *
1533
+ * Returns the `MethodOptions` for this `MethodDescriptor`.
1534
+ */
1535
+ static VALUE MethodDescriptor_options(VALUE _self) {
1536
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1537
+ const google_protobuf_MethodOptions* opts =
1538
+ upb_MethodDef_Options(self->methoddef);
1539
+ upb_Arena* arena = upb_Arena_New();
1540
+ size_t size;
1541
+ char* serialized =
1542
+ google_protobuf_MethodOptions_serialize(opts, arena, &size);
1543
+ VALUE method_options = decode_options(_self, "MethodOptions", size,
1544
+ serialized, self->descriptor_pool);
1545
+ upb_Arena_Free(arena);
1546
+ return method_options;
1547
+ }
1548
+
1549
+ /*
1550
+ * call-seq:
1551
+ * MethodDescriptor.input_type => Descriptor
1552
+ *
1553
+ * Returns the `Descriptor` for the request message type of this method
1554
+ */
1555
+ static VALUE MethodDescriptor_input_type(VALUE _self) {
1556
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1557
+ const upb_MessageDef* type = upb_MethodDef_InputType(self->methoddef);
1558
+ return get_msgdef_obj(self->descriptor_pool, type);
1559
+ }
1560
+
1561
+ /*
1562
+ * call-seq:
1563
+ * MethodDescriptor.output_type => Descriptor
1564
+ *
1565
+ * Returns the `Descriptor` for the response message type of this method
1566
+ */
1567
+ static VALUE MethodDescriptor_output_type(VALUE _self) {
1568
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1569
+ const upb_MessageDef* type = upb_MethodDef_OutputType(self->methoddef);
1570
+ return get_msgdef_obj(self->descriptor_pool, type);
1571
+ }
1572
+
1573
+ /*
1574
+ * call-seq:
1575
+ * MethodDescriptor.client_streaming => bool
1576
+ *
1577
+ * Returns whether or not this is a streaming request method
1578
+ */
1579
+ static VALUE MethodDescriptor_client_streaming(VALUE _self) {
1580
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1581
+ return upb_MethodDef_ClientStreaming(self->methoddef) ? Qtrue : Qfalse;
1582
+ }
1583
+
1584
+ /*
1585
+ * call-seq:
1586
+ * MethodDescriptor.server_streaming => bool
1587
+ *
1588
+ * Returns whether or not this is a streaming response method
1589
+ */
1590
+ static VALUE MethodDescriptor_server_streaming(VALUE _self) {
1591
+ MethodDescriptor* self = ruby_to_MethodDescriptor(_self);
1592
+ return upb_MethodDef_ServerStreaming(self->methoddef) ? Qtrue : Qfalse;
1593
+ }
1594
+
1595
+ static void MethodDescriptor_register(VALUE module) {
1596
+ VALUE klass = rb_define_class_under(module, "MethodDescriptor", rb_cObject);
1597
+ rb_define_alloc_func(klass, MethodDescriptor_alloc);
1598
+ rb_define_method(klass, "initialize", MethodDescriptor_initialize, 3);
1599
+ rb_define_method(klass, "name", MethodDescriptor_name, 0);
1600
+ rb_define_method(klass, "options", MethodDescriptor_options, 0);
1601
+ rb_define_method(klass, "input_type", MethodDescriptor_input_type, 0);
1602
+ rb_define_method(klass, "output_type", MethodDescriptor_output_type, 0);
1603
+ rb_define_method(klass, "client_streaming", MethodDescriptor_client_streaming,
1604
+ 0);
1605
+ rb_define_method(klass, "server_streaming", MethodDescriptor_server_streaming,
1606
+ 0);
1607
+ rb_gc_register_address(&cMethodDescriptor);
1608
+ cMethodDescriptor = klass;
1609
+ }
1610
+
1171
1611
  static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
1172
1612
  DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
1173
1613
  VALUE key = ULL2NUM((intptr_t)ptr);
@@ -1209,6 +1649,16 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
1209
1649
  return get_def_obj(descriptor_pool, def, cOneofDescriptor);
1210
1650
  }
1211
1651
 
1652
+ static VALUE get_servicedef_obj(VALUE descriptor_pool,
1653
+ const upb_ServiceDef* def) {
1654
+ return get_def_obj(descriptor_pool, def, cServiceDescriptor);
1655
+ }
1656
+
1657
+ static VALUE get_methoddef_obj(VALUE descriptor_pool,
1658
+ const upb_MethodDef* def) {
1659
+ return get_def_obj(descriptor_pool, def, cMethodDescriptor);
1660
+ }
1661
+
1212
1662
  // -----------------------------------------------------------------------------
1213
1663
  // Shared functions
1214
1664
  // -----------------------------------------------------------------------------
@@ -1284,6 +1734,8 @@ void Defs_register(VALUE module) {
1284
1734
  FieldDescriptor_register(module);
1285
1735
  OneofDescriptor_register(module);
1286
1736
  EnumDescriptor_register(module);
1737
+ ServiceDescriptor_register(module);
1738
+ MethodDescriptor_register(module);
1287
1739
 
1288
1740
  rb_gc_register_address(&c_only_cookie);
1289
1741
  c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);