google-protobuf 3.25.0 → 4.29.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/convert.c +46 -18
  3. data/ext/google/protobuf_c/defs.c +499 -26
  4. data/ext/google/protobuf_c/extconf.rb +1 -1
  5. data/ext/google/protobuf_c/glue.c +53 -2
  6. data/ext/google/protobuf_c/map.c +82 -17
  7. data/ext/google/protobuf_c/map.h +9 -2
  8. data/ext/google/protobuf_c/message.c +144 -104
  9. data/ext/google/protobuf_c/message.h +8 -5
  10. data/ext/google/protobuf_c/protobuf.c +30 -17
  11. data/ext/google/protobuf_c/protobuf.h +3 -7
  12. data/ext/google/protobuf_c/repeated_field.c +64 -10
  13. data/ext/google/protobuf_c/repeated_field.h +8 -1
  14. data/ext/google/protobuf_c/ruby-upb.c +13774 -11526
  15. data/ext/google/protobuf_c/ruby-upb.h +11198 -9048
  16. data/ext/google/protobuf_c/shared_convert.c +10 -5
  17. data/ext/google/protobuf_c/shared_convert.h +2 -2
  18. data/ext/google/protobuf_c/shared_message.c +3 -31
  19. data/ext/google/protobuf_c/shared_message.h +0 -4
  20. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
  21. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
  22. data/lib/google/protobuf/any_pb.rb +1 -22
  23. data/lib/google/protobuf/api_pb.rb +1 -24
  24. data/lib/google/protobuf/descriptor_pb.rb +3 -23
  25. data/lib/google/protobuf/duration_pb.rb +1 -22
  26. data/lib/google/protobuf/empty_pb.rb +1 -22
  27. data/lib/google/protobuf/ffi/descriptor.rb +13 -2
  28. data/lib/google/protobuf/ffi/descriptor_pool.rb +16 -9
  29. data/lib/google/protobuf/ffi/enum_descriptor.rb +13 -1
  30. data/lib/google/protobuf/ffi/ffi.rb +8 -6
  31. data/lib/google/protobuf/ffi/field_descriptor.rb +37 -16
  32. data/lib/google/protobuf/ffi/file_descriptor.rb +13 -12
  33. data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
  34. data/lib/google/protobuf/ffi/internal/convert.rb +21 -30
  35. data/lib/google/protobuf/ffi/map.rb +50 -13
  36. data/lib/google/protobuf/ffi/message.rb +202 -58
  37. data/lib/google/protobuf/ffi/method_descriptor.rb +114 -0
  38. data/lib/google/protobuf/ffi/object_cache.rb +3 -3
  39. data/lib/google/protobuf/ffi/oneof_descriptor.rb +20 -11
  40. data/lib/google/protobuf/ffi/repeated_field.rb +50 -142
  41. data/lib/google/protobuf/ffi/service_descriptor.rb +107 -0
  42. data/lib/google/protobuf/field_mask_pb.rb +1 -22
  43. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  44. data/lib/google/protobuf/plugin_pb.rb +2 -24
  45. data/lib/google/protobuf/repeated_field.rb +4 -5
  46. data/lib/google/protobuf/source_context_pb.rb +1 -22
  47. data/lib/google/protobuf/struct_pb.rb +1 -22
  48. data/lib/google/protobuf/timestamp_pb.rb +1 -22
  49. data/lib/google/protobuf/type_pb.rb +1 -24
  50. data/lib/google/protobuf/wrappers_pb.rb +1 -22
  51. data/lib/google/protobuf.rb +1 -1
  52. data/lib/google/protobuf_ffi.rb +3 -2
  53. data/lib/google/protobuf_native.rb +0 -1
  54. data/lib/google/tasks/ffi.rake +1 -3
  55. metadata +25 -12
  56. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  57. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  58. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  59. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
  60. data/lib/google/protobuf/object_cache.rb +0 -97
@@ -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)
@@ -14,8 +14,59 @@
14
14
  upb_Arena* Arena_create() { return upb_Arena_Init(NULL, 0, &upb_alloc_global); }
15
15
 
16
16
  google_protobuf_FileDescriptorProto* FileDescriptorProto_parse(
17
- const char* serialized_file_proto, size_t length) {
18
- upb_Arena* arena = Arena_create();
17
+ const char* serialized_file_proto, size_t length, upb_Arena* arena) {
19
18
  return google_protobuf_FileDescriptorProto_parse(serialized_file_proto,
20
19
  length, arena);
21
20
  }
21
+
22
+ char* EnumDescriptor_serialized_options(const upb_EnumDef* enumdef,
23
+ size_t* size, upb_Arena* arena) {
24
+ const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(enumdef);
25
+ char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, size);
26
+ return serialized;
27
+ }
28
+
29
+ char* FileDescriptor_serialized_options(const upb_FileDef* filedef,
30
+ size_t* size, upb_Arena* arena) {
31
+ const google_protobuf_FileOptions* opts = upb_FileDef_Options(filedef);
32
+ char* serialized = google_protobuf_FileOptions_serialize(opts, arena, size);
33
+ return serialized;
34
+ }
35
+
36
+ char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size,
37
+ upb_Arena* arena) {
38
+ const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(msgdef);
39
+ char* serialized =
40
+ google_protobuf_MessageOptions_serialize(opts, arena, size);
41
+ return serialized;
42
+ }
43
+
44
+ char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef,
45
+ size_t* size, upb_Arena* arena) {
46
+ const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(oneofdef);
47
+ char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, size);
48
+ return serialized;
49
+ }
50
+
51
+ char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef,
52
+ size_t* size, upb_Arena* arena) {
53
+ const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(fielddef);
54
+ char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size);
55
+ return serialized;
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
 
@@ -61,9 +63,10 @@ static VALUE Map_alloc(VALUE klass) {
61
63
  return TypedData_Wrap_Struct(klass, &Map_type, self);
62
64
  }
63
65
 
64
- VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type, TypeInfo value_type,
65
- VALUE arena) {
66
+ VALUE Map_GetRubyWrapper(const upb_Map* map, upb_CType key_type,
67
+ TypeInfo value_type, VALUE arena) {
66
68
  PBRUBY_ASSERT(map);
69
+ PBRUBY_ASSERT(arena != Qnil);
67
70
 
68
71
  VALUE val = ObjectCache_Get(map);
69
72
 
@@ -81,7 +84,6 @@ VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type, TypeInfo value_type,
81
84
  }
82
85
  return ObjectCache_TryAdd(map, val);
83
86
  }
84
-
85
87
  return val;
86
88
  }
87
89
 
@@ -103,8 +105,9 @@ static TypeInfo Map_keyinfo(Map* self) {
103
105
  }
104
106
 
105
107
  static upb_Map* Map_GetMutable(VALUE _self) {
106
- rb_check_frozen(_self);
107
- return (upb_Map*)ruby_to_Map(_self)->map;
108
+ const upb_Map* map = ruby_to_Map(_self)->map;
109
+ Protobuf_CheckNotFrozen(_self, upb_Map_IsFrozen(map));
110
+ return (upb_Map*)map;
108
111
  }
109
112
 
110
113
  VALUE Map_CreateHash(const upb_Map* map, upb_CType key_type,
@@ -212,7 +215,7 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
212
215
  Map* self = ruby_to_Map(_self);
213
216
  Map* other = ruby_to_Map(hashmap);
214
217
  upb_Arena* arena = Arena_get(self->arena);
215
- upb_Message* self_msg = Map_GetMutable(_self);
218
+ upb_Map* self_map = Map_GetMutable(_self);
216
219
 
217
220
  Arena_fuse(other->arena, arena);
218
221
 
@@ -225,7 +228,7 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
225
228
  size_t iter = kUpb_Map_Begin;
226
229
  upb_MessageValue key, val;
227
230
  while (upb_Map_Next(other->map, &key, &val, &iter)) {
228
- upb_Map_Set(self_msg, key, val, arena);
231
+ upb_Map_Set(self_map, key, val, arena);
229
232
  }
230
233
  } else {
231
234
  rb_raise(rb_eArgError, "Unknown type merging into Map");
@@ -437,14 +440,14 @@ static VALUE Map_has_key(VALUE _self, VALUE key) {
437
440
  * nil if none was present. Throws an exception if the key is of the wrong type.
438
441
  */
439
442
  static VALUE Map_delete(VALUE _self, VALUE key) {
443
+ upb_Map* map = Map_GetMutable(_self);
440
444
  Map* self = ruby_to_Map(_self);
441
- rb_check_frozen(_self);
442
445
 
443
446
  upb_MessageValue key_upb =
444
447
  Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
445
448
  upb_MessageValue val_upb;
446
449
 
447
- if (upb_Map_Delete(self->map, key_upb, &val_upb)) {
450
+ if (upb_Map_Delete(map, key_upb, &val_upb)) {
448
451
  return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
449
452
  } else {
450
453
  return Qnil;
@@ -558,20 +561,81 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
558
561
 
559
562
  /*
560
563
  * call-seq:
561
- * Message.freeze => self
564
+ * Map.frozen? => bool
565
+ *
566
+ * Returns true if the map is frozen in either Ruby or the underlying
567
+ * representation. Freezes the Ruby map object if it is not already frozen in
568
+ * Ruby but it is frozen in the underlying representation.
569
+ */
570
+ VALUE Map_frozen(VALUE _self) {
571
+ Map* self = ruby_to_Map(_self);
572
+ if (!upb_Map_IsFrozen(self->map)) {
573
+ PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
574
+ return Qfalse;
575
+ }
576
+
577
+ // Lazily freeze the Ruby wrapper.
578
+ if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
579
+ return Qtrue;
580
+ }
581
+
582
+ /*
583
+ * call-seq:
584
+ * Map.freeze => self
562
585
  *
563
- * Freezes the message object. We have to intercept this so we can pin the
564
- * Ruby object into memory so we don't forget it's frozen.
586
+ * Freezes the map object. We have to intercept this so we can freeze the
587
+ * underlying representation, not just the Ruby wrapper.
565
588
  */
566
- static VALUE Map_freeze(VALUE _self) {
589
+ VALUE Map_freeze(VALUE _self) {
567
590
  Map* self = ruby_to_Map(_self);
568
- if (!RB_OBJ_FROZEN(_self)) {
569
- Arena_Pin(self->arena, _self);
570
- RB_OBJ_FREEZE(_self);
591
+ if (RB_OBJ_FROZEN(_self)) {
592
+ PBRUBY_ASSERT(upb_Map_IsFrozen(self->map));
593
+ return _self;
594
+ }
595
+
596
+ if (!upb_Map_IsFrozen(self->map)) {
597
+ if (self->value_type_info.type == kUpb_CType_Message) {
598
+ upb_Map_Freeze(
599
+ Map_GetMutable(_self),
600
+ upb_MessageDef_MiniTable(self->value_type_info.def.msgdef));
601
+ } else {
602
+ upb_Map_Freeze(Map_GetMutable(_self), NULL);
603
+ }
571
604
  }
605
+
606
+ RB_OBJ_FREEZE(_self);
607
+
572
608
  return _self;
573
609
  }
574
610
 
611
+ VALUE Map_EmptyFrozen(const upb_FieldDef* f) {
612
+ PBRUBY_ASSERT(upb_FieldDef_IsMap(f));
613
+ VALUE val = ObjectCache_Get(f);
614
+
615
+ if (val == Qnil) {
616
+ const upb_FieldDef* key_f = map_field_key(f);
617
+ const upb_FieldDef* val_f = map_field_value(f);
618
+ upb_CType key_type = upb_FieldDef_CType(key_f);
619
+ TypeInfo value_type_info = TypeInfo_get(val_f);
620
+ val = Map_alloc(cMap);
621
+ Map* self;
622
+ TypedData_Get_Struct(val, Map, &Map_type, self);
623
+ self->arena = Arena_new();
624
+ self->map =
625
+ upb_Map_New(Arena_get(self->arena), key_type, value_type_info.type);
626
+ self->key_type = key_type;
627
+ self->value_type_info = value_type_info;
628
+ if (self->value_type_info.type == kUpb_CType_Message) {
629
+ const upb_MessageDef* val_m = value_type_info.def.msgdef;
630
+ self->value_type_class = Descriptor_DefToClass(val_m);
631
+ }
632
+ return ObjectCache_TryAdd(f, Map_freeze(val));
633
+ }
634
+ PBRUBY_ASSERT(RB_OBJ_FROZEN(val));
635
+ PBRUBY_ASSERT(upb_Map_IsFrozen(ruby_to_Map(val)->map));
636
+ return val;
637
+ }
638
+
575
639
  /*
576
640
  * call-seq:
577
641
  * Map.hash => hash_value
@@ -658,6 +722,7 @@ void Map_register(VALUE module) {
658
722
  rb_define_method(klass, "clone", Map_dup, 0);
659
723
  rb_define_method(klass, "==", Map_eq, 1);
660
724
  rb_define_method(klass, "freeze", Map_freeze, 0);
725
+ rb_define_method(klass, "frozen?", Map_frozen, 0);
661
726
  rb_define_method(klass, "hash", Map_hash, 0);
662
727
  rb_define_method(klass, "to_h", Map_to_h, 0);
663
728
  rb_define_method(klass, "inspect", Map_inspect, 0);
@@ -11,10 +11,14 @@
11
11
  #include "protobuf.h"
12
12
  #include "ruby-upb.h"
13
13
 
14
+ // Returns a frozen sentinel Ruby wrapper object for an empty upb_Map with the
15
+ // key and value types specified by the field. Creates one if it doesn't exist.
16
+ VALUE Map_EmptyFrozen(const upb_FieldDef* f);
17
+
14
18
  // Returns a Ruby wrapper object for the given map, which will be created if
15
19
  // one does not exist already.
16
- VALUE Map_GetRubyWrapper(upb_Map *map, upb_CType key_type, TypeInfo value_type,
17
- VALUE arena);
20
+ VALUE Map_GetRubyWrapper(const upb_Map *map, upb_CType key_type,
21
+ TypeInfo value_type, VALUE arena);
18
22
 
19
23
  // Gets the underlying upb_Map for this Ruby map object, which must have
20
24
  // key/value type that match |field|. If this is not a map or the type doesn't
@@ -38,4 +42,7 @@ extern VALUE cMap;
38
42
  // Call at startup to register all types in this module.
39
43
  void Map_register(VALUE module);
40
44
 
45
+ // Recursively freeze map
46
+ VALUE Map_freeze(VALUE _self);
47
+
41
48
  #endif // RUBY_PROTOBUF_MAP_H_