google-protobuf 3.25.5-x86-linux → 4.29.1-x86-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) 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 +368 -30
  4. data/ext/google/protobuf_c/extconf.rb +1 -1
  5. data/ext/google/protobuf_c/glue.c +16 -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 +120 -118
  9. data/ext/google/protobuf_c/message.h +2 -6
  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 +58 -23
  13. data/ext/google/protobuf_c/repeated_field.h +6 -2
  14. data/ext/google/protobuf_c/ruby-upb.c +13774 -11526
  15. data/ext/google/protobuf_c/ruby-upb.h +11200 -9050
  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/3.0/protobuf_c.so +0 -0
  23. data/lib/google/3.1/protobuf_c.so +0 -0
  24. data/lib/google/3.2/protobuf_c.so +0 -0
  25. data/lib/google/3.3/protobuf_c.so +0 -0
  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 +3 -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 +4 -4
  32. data/lib/google/protobuf/ffi/descriptor_pool.rb +3 -1
  33. data/lib/google/protobuf/ffi/enum_descriptor.rb +3 -1
  34. data/lib/google/protobuf/ffi/ffi.rb +8 -6
  35. data/lib/google/protobuf/ffi/field_descriptor.rb +13 -2
  36. data/lib/google/protobuf/ffi/file_descriptor.rb +3 -13
  37. data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
  38. data/lib/google/protobuf/ffi/internal/convert.rb +21 -30
  39. data/lib/google/protobuf/ffi/map.rb +50 -24
  40. data/lib/google/protobuf/ffi/message.rb +189 -66
  41. data/lib/google/protobuf/ffi/method_descriptor.rb +114 -0
  42. data/lib/google/protobuf/ffi/object_cache.rb +3 -3
  43. data/lib/google/protobuf/ffi/oneof_descriptor.rb +3 -1
  44. data/lib/google/protobuf/ffi/repeated_field.rb +47 -19
  45. data/lib/google/protobuf/ffi/service_descriptor.rb +107 -0
  46. data/lib/google/protobuf/field_mask_pb.rb +1 -22
  47. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  48. data/lib/google/protobuf/plugin_pb.rb +2 -24
  49. data/lib/google/protobuf/repeated_field.rb +4 -5
  50. data/lib/google/protobuf/source_context_pb.rb +1 -22
  51. data/lib/google/protobuf/struct_pb.rb +1 -22
  52. data/lib/google/protobuf/timestamp_pb.rb +1 -22
  53. data/lib/google/protobuf/type_pb.rb +1 -24
  54. data/lib/google/protobuf/wrappers_pb.rb +1 -22
  55. data/lib/google/protobuf.rb +1 -1
  56. data/lib/google/protobuf_ffi.rb +3 -2
  57. data/lib/google/protobuf_native.rb +0 -1
  58. data/lib/google/tasks/ffi.rake +1 -3
  59. metadata +25 -13
  60. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  61. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  62. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  63. data/lib/google/2.7/protobuf_c.so +0 -0
  64. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
  65. data/lib/google/protobuf/object_cache.rb +0 -97
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ac081ad3cea69498cc62542d51bee76920e378824d78009f315ce7af6be9923
4
- data.tar.gz: 840ab046c1c67627268dd6bf56b2cd5be4aa7f80b4d66546181cf9f0ac97f9ab
3
+ metadata.gz: ebb3e4e741e4105faf7de470a788fb10a4da63afe0fdd5ab6e22444d7f529d2a
4
+ data.tar.gz: 82ecf28b30f570d58e214a5c9bc6818b02a83050d9e23ab9b56813aab82f9a0b
5
5
  SHA512:
6
- metadata.gz: b64fea6efa5c3a3ea446adbeb213aa6d47881867f65b63a54f6c277240c15074441db7c353078c51e5d47047fc1b0947bd8260c89865bfe397a7cd4ba66935d7
7
- data.tar.gz: 8ab8790db6d588c5b9d0a9166fe99153c80db0d1ce23e3fe641c834507ec58d224ebb62655ff2383939b6d0759fbae314287c93bdc4ef307ecb8b7ca1455bd60
6
+ metadata.gz: 2d25851ea3c8d18d8ebc77102863884cc16a2ccb449f48aa98439e8fb3dbc14c590350a31103c064689d82ba69a0d1d3b60464975f0e4d8c2f3d35b7f1b96b38
7
+ data.tar.gz: d2c02c9717aa8f5d411ef58adf6c513cd7291810e1c1c1bdc692dfd8b8ca43fba6efddcdc1b5c9e60db5f48b2131bca5ceb2dc42e4a0282d8c369a3119a60e53
@@ -104,6 +104,41 @@ unknownval:
104
104
  rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
105
105
  }
106
106
 
107
+ VALUE Convert_CheckStringUtf8(VALUE str) {
108
+ VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
109
+
110
+ if (rb_obj_encoding(str) == utf8) {
111
+ // Note: Just because a string is marked as having UTF-8 encoding does
112
+ // not mean that it is *valid* UTF-8. We have to check separately
113
+ // whether it is valid.
114
+ if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {
115
+ // TODO: For now
116
+ // we only warn for this case. We will remove the warning and throw an
117
+ // exception below in the 30.x release
118
+
119
+ rb_warn(
120
+ "String is invalid UTF-8. This will be an error in a future "
121
+ "version.");
122
+ // VALUE exc = rb_const_get_at(
123
+ // rb_cEncoding, rb_intern("InvalidByteSequenceError"));
124
+ // rb_raise(exc, "String is invalid UTF-8");
125
+ }
126
+ } else {
127
+ // Note: this will not duplicate underlying string data unless
128
+ // necessary.
129
+ //
130
+ // This will throw an exception if the conversion cannot be performed:
131
+ // - Encoding::UndefinedConversionError if certain characters cannot be
132
+ // converted to UTF-8.
133
+ // - Encoding::InvalidByteSequenceError if certain characters were invalid
134
+ // in the source encoding.
135
+ str = rb_str_encode(str, utf8, 0, Qnil);
136
+ PBRUBY_ASSERT(rb_enc_str_coderange(str) != ENC_CODERANGE_BROKEN);
137
+ }
138
+
139
+ return str;
140
+ }
141
+
107
142
  upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
108
143
  TypeInfo type_info, upb_Arena* arena) {
109
144
  upb_MessageValue ret;
@@ -137,29 +172,18 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
137
172
  }
138
173
  break;
139
174
  }
140
- case kUpb_CType_String: {
141
- VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
175
+ case kUpb_CType_String:
142
176
  if (rb_obj_class(value) == rb_cSymbol) {
143
177
  value = rb_funcall(value, rb_intern("to_s"), 0);
144
- } else if (rb_obj_class(value) != rb_cString) {
178
+ } else if (!rb_obj_is_kind_of(value, rb_cString)) {
145
179
  rb_raise(cTypeError,
146
180
  "Invalid argument for string field '%s' (given %s).", name,
147
181
  rb_class2name(CLASS_OF(value)));
148
182
  }
149
183
 
150
- if (rb_obj_encoding(value) != utf8) {
151
- // Note: this will not duplicate underlying string data unless
152
- // necessary.
153
- value = rb_str_encode(value, utf8, 0, Qnil);
154
-
155
- if (rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
156
- rb_raise(rb_eEncodingError, "String is invalid UTF-8");
157
- }
158
- }
159
-
184
+ value = Convert_CheckStringUtf8(value);
160
185
  ret.str_val = Convert_StringData(value, arena);
161
186
  break;
162
- }
163
187
  case kUpb_CType_Bytes: {
164
188
  VALUE bytes = rb_enc_from_encoding(rb_ascii8bit_encoding());
165
189
  if (rb_obj_class(value) != rb_cString) {
@@ -204,11 +228,13 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
204
228
  ret.uint64_val = NUM2ULL(value);
205
229
  break;
206
230
  default:
207
- break;
231
+ rb_raise(cTypeError, "Convert_RubyToUpb(): Unexpected type %d",
232
+ (int)type_info.type);
208
233
  }
209
234
  break;
210
235
  default:
211
- break;
236
+ rb_raise(cTypeError,
237
+ "Convert_RubyToUpb(): Unexpected type %d", (int)type_info.type);
212
238
  }
213
239
 
214
240
  return ret;
@@ -296,7 +322,8 @@ bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2,
296
322
  if (upb_Status_IsOk(&status)) {
297
323
  return return_value;
298
324
  } else {
299
- rb_raise(rb_eRuntimeError, upb_Status_ErrorMessage(&status));
325
+ rb_raise(rb_eRuntimeError, "Msgval_IsEqual(): %s",
326
+ upb_Status_ErrorMessage(&status));
300
327
  }
301
328
  }
302
329
 
@@ -309,6 +336,7 @@ uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info,
309
336
  if (upb_Status_IsOk(&status)) {
310
337
  return return_value;
311
338
  } else {
312
- rb_raise(rb_eRuntimeError, upb_Status_ErrorMessage(&status));
339
+ rb_raise(rb_eRuntimeError, "Msgval_GetHash(): %s",
340
+ upb_Status_ErrorMessage(&status));
313
341
  }
314
342
  }
@@ -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
@@ -153,6 +155,7 @@ 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;
156
159
 
157
160
  msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
158
161
  if (msgdef) {
@@ -169,6 +172,11 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
169
172
  return get_enumdef_obj(_self, enumdef);
170
173
  }
171
174
 
175
+ servicedef = upb_DefPool_FindServiceByName(self->symtab, name_str);
176
+ if (servicedef) {
177
+ return get_servicedef_obj(_self, servicedef);
178
+ }
179
+
172
180
  return Qnil;
173
181
  }
174
182
 
@@ -257,7 +265,20 @@ static VALUE decode_options(VALUE self, const char* option_type, int size,
257
265
  VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef);
258
266
  const Descriptor* desc = ruby_to_Descriptor(desc_rb);
259
267
 
260
- options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, true);
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
+
261
282
  rb_ivar_set(self, options_instancevar_interned, options_rb);
262
283
  return options_rb;
263
284
  }
@@ -489,7 +510,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
489
510
  * call-seq:
490
511
  * FileDescriptor.new => file
491
512
  *
492
- * Returns a new file descriptor. The syntax must be set before it's passed
513
+ * Returns a new file descriptor. May
493
514
  * to a builder.
494
515
  */
495
516
  static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
@@ -519,28 +540,6 @@ static VALUE FileDescriptor_name(VALUE _self) {
519
540
  return name == NULL ? Qnil : rb_str_new2(name);
520
541
  }
521
542
 
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
543
  /*
545
544
  * call-seq:
546
545
  * FileDescriptor.options => options
@@ -564,7 +563,6 @@ static void FileDescriptor_register(VALUE module) {
564
563
  rb_define_alloc_func(klass, FileDescriptor_alloc);
565
564
  rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
566
565
  rb_define_method(klass, "name", FileDescriptor_name, 0);
567
- rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
568
566
  rb_define_method(klass, "options", FileDescriptor_options, 0);
569
567
  rb_gc_register_address(&cFileDescriptor);
570
568
  cFileDescriptor = klass;
@@ -727,7 +725,7 @@ static VALUE FieldDescriptor__type(VALUE _self) {
727
725
  static VALUE FieldDescriptor_default(VALUE _self) {
728
726
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
729
727
  const upb_FieldDef* f = self->fielddef;
730
- upb_MessageValue default_val = {0};
728
+ upb_MessageValue default_val = upb_MessageValue_Zero();
731
729
  if (upb_FieldDef_IsSubMessage(f)) {
732
730
  return Qnil;
733
731
  } else if (!upb_FieldDef_IsRepeated(f)) {
@@ -736,6 +734,28 @@ static VALUE FieldDescriptor_default(VALUE _self) {
736
734
  return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
737
735
  }
738
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
+
739
759
  /*
740
760
  * call-seq:
741
761
  * FieldDescriptor.json_name => json_name
@@ -862,7 +882,7 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
862
882
  static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
863
883
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
864
884
  const upb_MessageDef* m;
865
- const upb_MessageDef* msg = Message_Get(msg_rb, &m);
885
+ const upb_Message* msg = Message_Get(msg_rb, &m);
866
886
 
867
887
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
868
888
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -882,7 +902,7 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
882
902
  static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
883
903
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
884
904
  const upb_MessageDef* m;
885
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
905
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
886
906
 
887
907
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
888
908
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -903,7 +923,7 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
903
923
  static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
904
924
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
905
925
  const upb_MessageDef* m;
906
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
926
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
907
927
  upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
908
928
  upb_MessageValue msgval;
909
929
 
@@ -943,6 +963,8 @@ static void FieldDescriptor_register(VALUE module) {
943
963
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
944
964
  rb_define_method(klass, "type", FieldDescriptor__type, 0);
945
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);
946
968
  rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
947
969
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
948
970
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
@@ -1163,6 +1185,17 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1163
1185
  upb_EnumDef_File(self->enumdef));
1164
1186
  }
1165
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
+
1166
1199
  /*
1167
1200
  * call-seq:
1168
1201
  * EnumDescriptor.name => name
@@ -1275,12 +1308,305 @@ static void EnumDescriptor_register(VALUE module) {
1275
1308
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1276
1309
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1277
1310
  rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1311
+ rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0);
1278
1312
  rb_define_method(klass, "options", EnumDescriptor_options, 0);
1279
1313
  rb_include_module(klass, rb_mEnumerable);
1280
1314
  rb_gc_register_address(&cEnumDescriptor);
1281
1315
  cEnumDescriptor = klass;
1282
1316
  }
1283
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
+
1284
1610
  static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
1285
1611
  DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
1286
1612
  VALUE key = ULL2NUM((intptr_t)ptr);
@@ -1322,6 +1648,16 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
1322
1648
  return get_def_obj(descriptor_pool, def, cOneofDescriptor);
1323
1649
  }
1324
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
+
1325
1661
  // -----------------------------------------------------------------------------
1326
1662
  // Shared functions
1327
1663
  // -----------------------------------------------------------------------------
@@ -1397,6 +1733,8 @@ void Defs_register(VALUE module) {
1397
1733
  FieldDescriptor_register(module);
1398
1734
  OneofDescriptor_register(module);
1399
1735
  EnumDescriptor_register(module);
1736
+ ServiceDescriptor_register(module);
1737
+ MethodDescriptor_register(module);
1400
1738
 
1401
1739
  rb_gc_register_address(&c_only_cookie);
1402
1740
  c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);
@@ -22,7 +22,7 @@ $INCFLAGS += " -I$(srcdir)/third_party/utf8_range"
22
22
 
23
23
  $srcs = ["protobuf.c", "convert.c", "defs.c", "message.c",
24
24
  "repeated_field.c", "map.c", "ruby-upb.c", "wrap_memcpy.c",
25
- "naive.c", "range2-neon.c", "range2-sse.c", "shared_convert.c",
25
+ "utf8_range.c", "shared_convert.c",
26
26
  "shared_message.c"]
27
27
 
28
28
  create_makefile(ext_name)
@@ -54,3 +54,19 @@ char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef,
54
54
  char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size);
55
55
  return serialized;
56
56
  }
57
+
58
+ char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef,
59
+ size_t* size, upb_Arena* arena) {
60
+ const google_protobuf_ServiceOptions* opts =
61
+ upb_ServiceDef_Options(servicedef);
62
+ char* serialized =
63
+ google_protobuf_ServiceOptions_serialize(opts, arena, size);
64
+ return serialized;
65
+ }
66
+
67
+ char* MethodDescriptor_serialized_options(const upb_MethodDef* methoddef,
68
+ size_t* size, upb_Arena* arena) {
69
+ const google_protobuf_MethodOptions* opts = upb_MethodDef_Options(methoddef);
70
+ char* serialized = google_protobuf_MethodOptions_serialize(opts, arena, size);
71
+ return serialized;
72
+ }