google-protobuf 3.25.4 → 4.27.2

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

Potentially problematic release.


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

Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/convert.c +7 -4
  3. data/ext/google/protobuf_c/defs.c +367 -28
  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 +12 -19
  7. data/ext/google/protobuf_c/map.h +1 -1
  8. data/ext/google/protobuf_c/message.c +43 -90
  9. data/ext/google/protobuf_c/message.h +1 -5
  10. data/ext/google/protobuf_c/protobuf.c +19 -6
  11. data/ext/google/protobuf_c/repeated_field.c +6 -15
  12. data/ext/google/protobuf_c/repeated_field.h +1 -1
  13. data/ext/google/protobuf_c/ruby-upb.c +12684 -10768
  14. data/ext/google/protobuf_c/ruby-upb.h +6889 -5584
  15. data/ext/google/protobuf_c/shared_convert.c +10 -5
  16. data/ext/google/protobuf_c/shared_convert.h +2 -2
  17. data/ext/google/protobuf_c/shared_message.c +3 -31
  18. data/ext/google/protobuf_c/shared_message.h +0 -4
  19. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
  20. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
  21. data/lib/google/protobuf/any_pb.rb +1 -22
  22. data/lib/google/protobuf/api_pb.rb +1 -24
  23. data/lib/google/protobuf/descriptor_pb.rb +3 -23
  24. data/lib/google/protobuf/duration_pb.rb +1 -22
  25. data/lib/google/protobuf/empty_pb.rb +1 -22
  26. data/lib/google/protobuf/ffi/descriptor.rb +4 -3
  27. data/lib/google/protobuf/ffi/descriptor_pool.rb +3 -1
  28. data/lib/google/protobuf/ffi/enum_descriptor.rb +3 -1
  29. data/lib/google/protobuf/ffi/ffi.rb +3 -6
  30. data/lib/google/protobuf/ffi/field_descriptor.rb +13 -2
  31. data/lib/google/protobuf/ffi/file_descriptor.rb +3 -13
  32. data/lib/google/protobuf/ffi/internal/convert.rb +8 -24
  33. data/lib/google/protobuf/ffi/map.rb +13 -11
  34. data/lib/google/protobuf/ffi/message.rb +10 -13
  35. data/lib/google/protobuf/ffi/method_descriptor.rb +114 -0
  36. data/lib/google/protobuf/ffi/object_cache.rb +3 -3
  37. data/lib/google/protobuf/ffi/oneof_descriptor.rb +3 -1
  38. data/lib/google/protobuf/ffi/repeated_field.rb +12 -10
  39. data/lib/google/protobuf/ffi/service_descriptor.rb +107 -0
  40. data/lib/google/protobuf/field_mask_pb.rb +1 -22
  41. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  42. data/lib/google/protobuf/plugin_pb.rb +2 -24
  43. data/lib/google/protobuf/repeated_field.rb +4 -5
  44. data/lib/google/protobuf/source_context_pb.rb +1 -22
  45. data/lib/google/protobuf/struct_pb.rb +1 -22
  46. data/lib/google/protobuf/timestamp_pb.rb +1 -22
  47. data/lib/google/protobuf/type_pb.rb +1 -24
  48. data/lib/google/protobuf/wrappers_pb.rb +1 -22
  49. data/lib/google/protobuf.rb +1 -1
  50. data/lib/google/protobuf_ffi.rb +3 -2
  51. data/lib/google/protobuf_native.rb +0 -1
  52. data/lib/google/tasks/ffi.rake +1 -3
  53. metadata +25 -12
  54. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  55. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  56. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  57. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
  58. data/lib/google/protobuf/object_cache.rb +0 -97
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93e5b9509fd83614f67e64e548403efa453aa2b96566e51bacb2b2924e2ce0a8
4
- data.tar.gz: 874a9fc79fb08067d173543074eaa2681d1fbb95bb498c1b2514a12d2c997d2a
3
+ metadata.gz: ed0702b2b37613a87f420424018e9f4ac5f04c8ecd24bbbe8eef896742165146
4
+ data.tar.gz: a0fe013361c732b9dcb6430dc92444869303426b4670921a8dc08f4178528bc9
5
5
  SHA512:
6
- metadata.gz: aee86bdbbaa95cb4732701e9d41f9eee4ce113dcfd977c8f0d0d9621bc97cfafd6fddd1d9a744aa669b65aeb96f56467c10cfe4617b278658eda3c3236435128
7
- data.tar.gz: 6ca8f30e91477eb09040f01510608b67d6716251958cdfae6e41f78b94ea5bdf633c321cf204a144c89dc3c07c0115e1927bafcdc6509a570f2f43b7160b888d
6
+ metadata.gz: 9f908beee8408e633869c417a2397d319acc629fc5255f18da568647d76fc680711280be57055a4bbf1444fe0789dc730416e8f17142044102ac90d6dad2fe23
7
+ data.tar.gz: 032c01bfe89544c82f9028468e8db1a22129dfa2dc0132d52a39b1b5b2bbe4481b610484c4df7510d0c0df117027ad5171fa67efabc94e364d8ec69034bb8139
@@ -141,7 +141,7 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
141
141
  VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
142
142
  if (rb_obj_class(value) == rb_cSymbol) {
143
143
  value = rb_funcall(value, rb_intern("to_s"), 0);
144
- } else if (rb_obj_class(value) != rb_cString) {
144
+ } else if (!rb_obj_is_kind_of(value, rb_cString)) {
145
145
  rb_raise(cTypeError,
146
146
  "Invalid argument for string field '%s' (given %s).", name,
147
147
  rb_class2name(CLASS_OF(value)));
@@ -208,7 +208,8 @@ upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name,
208
208
  }
209
209
  break;
210
210
  default:
211
- break;
211
+ rb_raise(cTypeError,
212
+ "Convert_RubyToUpb(): Unexpected type %d", (int)type_info.type);
212
213
  }
213
214
 
214
215
  return ret;
@@ -296,7 +297,8 @@ bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2,
296
297
  if (upb_Status_IsOk(&status)) {
297
298
  return return_value;
298
299
  } else {
299
- rb_raise(rb_eRuntimeError, upb_Status_ErrorMessage(&status));
300
+ rb_raise(rb_eRuntimeError, "Msgval_IsEqual(): %s",
301
+ upb_Status_ErrorMessage(&status));
300
302
  }
301
303
  }
302
304
 
@@ -309,6 +311,7 @@ uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info,
309
311
  if (upb_Status_IsOk(&status)) {
310
312
  return return_value;
311
313
  } else {
312
- rb_raise(rb_eRuntimeError, upb_Status_ErrorMessage(&status));
314
+ rb_raise(rb_eRuntimeError, "Msgval_GetHash(): %s",
315
+ upb_Status_ErrorMessage(&status));
313
316
  }
314
317
  }
@@ -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;
@@ -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_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
+
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
+ }
@@ -38,9 +38,11 @@ static void Map_mark(void* _self) {
38
38
  rb_gc_mark(self->arena);
39
39
  }
40
40
 
41
+ static size_t Map_memsize(const void* _self) { return sizeof(Map); }
42
+
41
43
  const rb_data_type_t Map_type = {
42
44
  "Google::Protobuf::Map",
43
- {Map_mark, RUBY_DEFAULT_FREE, NULL},
45
+ {Map_mark, RUBY_DEFAULT_FREE, Map_memsize},
44
46
  .flags = RUBY_TYPED_FREE_IMMEDIATELY,
45
47
  };
46
48
 
@@ -212,7 +214,7 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
212
214
  Map* self = ruby_to_Map(_self);
213
215
  Map* other = ruby_to_Map(hashmap);
214
216
  upb_Arena* arena = Arena_get(self->arena);
215
- upb_Message* self_msg = Map_GetMutable(_self);
217
+ upb_Map* self_map = Map_GetMutable(_self);
216
218
 
217
219
  Arena_fuse(other->arena, arena);
218
220
 
@@ -225,7 +227,7 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
225
227
  size_t iter = kUpb_Map_Begin;
226
228
  upb_MessageValue key, val;
227
229
  while (upb_Map_Next(other->map, &key, &val, &iter)) {
228
- upb_Map_Set(self_msg, key, val, arena);
230
+ upb_Map_Set(self_map, key, val, arena);
229
231
  }
230
232
  } else {
231
233
  rb_raise(rb_eArgError, "Unknown type merging into Map");
@@ -444,7 +446,7 @@ static VALUE Map_delete(VALUE _self, VALUE key) {
444
446
  Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
445
447
  upb_MessageValue val_upb;
446
448
 
447
- if (upb_Map_Delete(self->map, key_upb, &val_upb)) {
449
+ if (upb_Map_Delete(Map_GetMutable(_self), key_upb, &val_upb)) {
448
450
  return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
449
451
  } else {
450
452
  return Qnil;
@@ -563,22 +565,13 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
563
565
  * Freezes the message object. We have to intercept this so we can pin the
564
566
  * Ruby object into memory so we don't forget it's frozen.
565
567
  */
566
- static VALUE Map_freeze(VALUE _self) {
568
+ VALUE Map_freeze(VALUE _self) {
567
569
  Map* self = ruby_to_Map(_self);
568
- if (!RB_OBJ_FROZEN(_self)) {
569
- Arena_Pin(self->arena, _self);
570
- RB_OBJ_FREEZE(_self);
571
- }
572
- return _self;
573
- }
574
570
 
575
- /*
576
- * Deep freezes the map and values recursively.
577
- * Internal use only.
578
- */
579
- VALUE Map_internal_deep_freeze(VALUE _self) {
580
- Map* self = ruby_to_Map(_self);
581
- Map_freeze(_self);
571
+ if (RB_OBJ_FROZEN(_self)) return _self;
572
+ Arena_Pin(self->arena, _self);
573
+ RB_OBJ_FREEZE(_self);
574
+
582
575
  if (self->value_type_info.type == kUpb_CType_Message) {
583
576
  size_t iter = kUpb_Map_Begin;
584
577
  upb_MessageValue key, val;
@@ -586,7 +579,7 @@ VALUE Map_internal_deep_freeze(VALUE _self) {
586
579
  while (upb_Map_Next(self->map, &key, &val, &iter)) {
587
580
  VALUE val_val =
588
581
  Convert_UpbToRuby(val, self->value_type_info, self->arena);
589
- Message_internal_deep_freeze(val_val);
582
+ Message_freeze(val_val);
590
583
  }
591
584
  }
592
585
  return _self;
@@ -39,6 +39,6 @@ extern VALUE cMap;
39
39
  void Map_register(VALUE module);
40
40
 
41
41
  // Recursively freeze map
42
- VALUE Map_internal_deep_freeze(VALUE _self);
42
+ VALUE Map_freeze(VALUE _self);
43
43
 
44
44
  #endif // RUBY_PROTOBUF_MAP_H_