google-protobuf 3.25.5 → 4.28.3

Sign up to get free protection for your applications and to get access to all the features.
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 +368 -29
  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 +106 -114
  9. data/ext/google/protobuf_c/message.h +2 -6
  10. data/ext/google/protobuf_c/protobuf.c +30 -15
  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 +13047 -10836
  15. data/ext/google/protobuf_c/ruby-upb.h +11114 -9028
  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 +4 -4
  28. data/lib/google/protobuf/ffi/descriptor_pool.rb +3 -1
  29. data/lib/google/protobuf/ffi/enum_descriptor.rb +3 -1
  30. data/lib/google/protobuf/ffi/ffi.rb +3 -6
  31. data/lib/google/protobuf/ffi/field_descriptor.rb +13 -2
  32. data/lib/google/protobuf/ffi/file_descriptor.rb +3 -13
  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 -24
  36. data/lib/google/protobuf/ffi/message.rb +183 -64
  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 +3 -1
  40. data/lib/google/protobuf/ffi/repeated_field.rb +47 -19
  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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 634d898bbe3be4cc53cdd85c2bb7774be145905c391514519b32ce409f1781d9
4
- data.tar.gz: ee14834c2b11e87c437dbe005ac5518505770324b2202da40a732eaa2c9a5ff6
3
+ metadata.gz: 89810f0fea0c365b6862bc16275aa7da8ef73c5923d82fed89ef9af70cc18850
4
+ data.tar.gz: fd9e7a43e25c88e31978b90384f7e5e693d90ffa13a026da771c20ec7faaabfa
5
5
  SHA512:
6
- metadata.gz: 1baa4d20ce995a96ba0916a7d4ed0847e25645062d7b3e9ba655aae55f0224f9d7b6355b7a5f5d52a8f5100879cd46a21c077a5e4521ca3fd42f2751184a21e9
7
- data.tar.gz: 2dc9e891af8d7c553476b9cfa29525746067b8200bf7c8f221da461376446b2c6a62050223d5e9b9f6a6af488c75d3b536fb3f40125069cc50851b06a1a8f748
6
+ metadata.gz: bc5619f68ea52e4fa1deba15b2b87a016bbdb6ad49089d3e9e3c30b3cd1eb9e67ac1f0cc84a55503d2feb2eec92401fcdd4159b6aa99a4f4acb81c106ba91448
7
+ data.tar.gz: ce47defb15aec14aeb2f6117982530e5b0ec53138c0f9805cfe9c83f677e8aba37d7f1e6f787b411f396928f2b8053d8567ee48281611c481a7d128ea711dd16
@@ -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
  }
@@ -23,6 +23,9 @@ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def);
23
23
  static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def);
24
24
  static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def);
25
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);
26
29
 
27
30
  // A distinct object that is not accessible from Ruby. We use this as a
28
31
  // constructor argument to enforce that certain objects cannot be created from
@@ -153,6 +156,7 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
153
156
  const upb_MessageDef* msgdef;
154
157
  const upb_EnumDef* enumdef;
155
158
  const upb_FieldDef* fielddef;
159
+ const upb_ServiceDef* servicedef;
156
160
 
157
161
  msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str);
158
162
  if (msgdef) {
@@ -169,6 +173,11 @@ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
169
173
  return get_enumdef_obj(_self, enumdef);
170
174
  }
171
175
 
176
+ servicedef = upb_DefPool_FindServiceByName(self->symtab, name_str);
177
+ if (servicedef) {
178
+ return get_servicedef_obj(_self, servicedef);
179
+ }
180
+
172
181
  return Qnil;
173
182
  }
174
183
 
@@ -257,7 +266,20 @@ static VALUE decode_options(VALUE self, const char* option_type, int size,
257
266
  VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef);
258
267
  const Descriptor* desc = ruby_to_Descriptor(desc_rb);
259
268
 
260
- options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, true);
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
+
261
283
  rb_ivar_set(self, options_instancevar_interned, options_rb);
262
284
  return options_rb;
263
285
  }
@@ -489,7 +511,7 @@ static VALUE FileDescriptor_alloc(VALUE klass) {
489
511
  * call-seq:
490
512
  * FileDescriptor.new => file
491
513
  *
492
- * Returns a new file descriptor. The syntax must be set before it's passed
514
+ * Returns a new file descriptor. May
493
515
  * to a builder.
494
516
  */
495
517
  static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
@@ -519,28 +541,6 @@ static VALUE FileDescriptor_name(VALUE _self) {
519
541
  return name == NULL ? Qnil : rb_str_new2(name);
520
542
  }
521
543
 
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
544
  /*
545
545
  * call-seq:
546
546
  * FileDescriptor.options => options
@@ -564,7 +564,6 @@ static void FileDescriptor_register(VALUE module) {
564
564
  rb_define_alloc_func(klass, FileDescriptor_alloc);
565
565
  rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
566
566
  rb_define_method(klass, "name", FileDescriptor_name, 0);
567
- rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
568
567
  rb_define_method(klass, "options", FileDescriptor_options, 0);
569
568
  rb_gc_register_address(&cFileDescriptor);
570
569
  cFileDescriptor = klass;
@@ -727,7 +726,7 @@ static VALUE FieldDescriptor__type(VALUE _self) {
727
726
  static VALUE FieldDescriptor_default(VALUE _self) {
728
727
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
729
728
  const upb_FieldDef* f = self->fielddef;
730
- upb_MessageValue default_val = {0};
729
+ upb_MessageValue default_val = upb_MessageValue_Zero();
731
730
  if (upb_FieldDef_IsSubMessage(f)) {
732
731
  return Qnil;
733
732
  } else if (!upb_FieldDef_IsRepeated(f)) {
@@ -736,6 +735,28 @@ static VALUE FieldDescriptor_default(VALUE _self) {
736
735
  return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
737
736
  }
738
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
+
739
760
  /*
740
761
  * call-seq:
741
762
  * FieldDescriptor.json_name => json_name
@@ -862,7 +883,7 @@ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
862
883
  static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
863
884
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
864
885
  const upb_MessageDef* m;
865
- const upb_MessageDef* msg = Message_Get(msg_rb, &m);
886
+ const upb_Message* msg = Message_Get(msg_rb, &m);
866
887
 
867
888
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
868
889
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -882,7 +903,7 @@ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
882
903
  static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
883
904
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
884
905
  const upb_MessageDef* m;
885
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
906
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
886
907
 
887
908
  if (m != upb_FieldDef_ContainingType(self->fielddef)) {
888
909
  rb_raise(cTypeError, "has method called on wrong message type");
@@ -903,7 +924,7 @@ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
903
924
  static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
904
925
  FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
905
926
  const upb_MessageDef* m;
906
- upb_MessageDef* msg = Message_GetMutable(msg_rb, &m);
927
+ upb_Message* msg = Message_GetMutable(msg_rb, &m);
907
928
  upb_Arena* arena = Arena_get(Message_GetArena(msg_rb));
908
929
  upb_MessageValue msgval;
909
930
 
@@ -943,6 +964,8 @@ static void FieldDescriptor_register(VALUE module) {
943
964
  rb_define_method(klass, "name", FieldDescriptor_name, 0);
944
965
  rb_define_method(klass, "type", FieldDescriptor__type, 0);
945
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);
946
969
  rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
947
970
  rb_define_method(klass, "label", FieldDescriptor_label, 0);
948
971
  rb_define_method(klass, "number", FieldDescriptor_number, 0);
@@ -1163,6 +1186,17 @@ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1163
1186
  upb_EnumDef_File(self->enumdef));
1164
1187
  }
1165
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
+
1166
1200
  /*
1167
1201
  * call-seq:
1168
1202
  * EnumDescriptor.name => name
@@ -1275,12 +1309,305 @@ static void EnumDescriptor_register(VALUE module) {
1275
1309
  rb_define_method(klass, "each", EnumDescriptor_each, 0);
1276
1310
  rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1277
1311
  rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1312
+ rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0);
1278
1313
  rb_define_method(klass, "options", EnumDescriptor_options, 0);
1279
1314
  rb_include_module(klass, rb_mEnumerable);
1280
1315
  rb_gc_register_address(&cEnumDescriptor);
1281
1316
  cEnumDescriptor = klass;
1282
1317
  }
1283
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_MethodDef*)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
+
1284
1611
  static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
1285
1612
  DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
1286
1613
  VALUE key = ULL2NUM((intptr_t)ptr);
@@ -1322,6 +1649,16 @@ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) {
1322
1649
  return get_def_obj(descriptor_pool, def, cOneofDescriptor);
1323
1650
  }
1324
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
+
1325
1662
  // -----------------------------------------------------------------------------
1326
1663
  // Shared functions
1327
1664
  // -----------------------------------------------------------------------------
@@ -1397,6 +1734,8 @@ void Defs_register(VALUE module) {
1397
1734
  FieldDescriptor_register(module);
1398
1735
  OneofDescriptor_register(module);
1399
1736
  EnumDescriptor_register(module);
1737
+ ServiceDescriptor_register(module);
1738
+ MethodDescriptor_register(module);
1400
1739
 
1401
1740
  rb_gc_register_address(&c_only_cookie);
1402
1741
  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
+ }