google-protobuf 3.19.1 → 3.25.1

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

Potentially problematic release.


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

Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +121 -155
  4. data/ext/google/protobuf_c/convert.h +15 -37
  5. data/ext/google/protobuf_c/defs.c +362 -243
  6. data/ext/google/protobuf_c/defs.h +22 -47
  7. data/ext/google/protobuf_c/extconf.rb +13 -5
  8. data/ext/google/protobuf_c/glue.c +56 -0
  9. data/ext/google/protobuf_c/map.c +129 -137
  10. data/ext/google/protobuf_c/map.h +13 -36
  11. data/ext/google/protobuf_c/message.c +486 -389
  12. data/ext/google/protobuf_c/message.h +32 -47
  13. data/ext/google/protobuf_c/protobuf.c +101 -228
  14. data/ext/google/protobuf_c/protobuf.h +37 -42
  15. data/ext/google/protobuf_c/repeated_field.c +110 -113
  16. data/ext/google/protobuf_c/repeated_field.h +12 -34
  17. data/ext/google/protobuf_c/ruby-upb.c +12236 -6993
  18. data/ext/google/protobuf_c/ruby-upb.h +12127 -3787
  19. data/ext/google/protobuf_c/shared_convert.c +64 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +65 -0
  22. data/ext/google/protobuf_c/shared_message.h +25 -0
  23. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  24. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +92 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +157 -0
  26. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +170 -0
  27. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +21 -0
  28. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  29. data/lib/google/protobuf/any_pb.rb +24 -5
  30. data/lib/google/protobuf/api_pb.rb +26 -23
  31. data/lib/google/protobuf/descriptor_dsl.rb +8 -1
  32. data/lib/google/protobuf/descriptor_pb.rb +43 -225
  33. data/lib/google/protobuf/duration_pb.rb +24 -5
  34. data/lib/google/protobuf/empty_pb.rb +24 -3
  35. data/lib/google/protobuf/ffi/descriptor.rb +165 -0
  36. data/lib/google/protobuf/ffi/descriptor_pool.rb +75 -0
  37. data/lib/google/protobuf/ffi/enum_descriptor.rb +171 -0
  38. data/lib/google/protobuf/ffi/ffi.rb +213 -0
  39. data/lib/google/protobuf/ffi/field_descriptor.rb +319 -0
  40. data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
  41. data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
  42. data/lib/google/protobuf/ffi/internal/convert.rb +305 -0
  43. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  44. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  45. data/lib/google/protobuf/ffi/map.rb +407 -0
  46. data/lib/google/protobuf/ffi/message.rb +662 -0
  47. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  48. data/lib/google/protobuf/ffi/oneof_descriptor.rb +95 -0
  49. data/lib/google/protobuf/ffi/repeated_field.rb +383 -0
  50. data/lib/google/protobuf/field_mask_pb.rb +24 -4
  51. data/lib/google/protobuf/message_exts.rb +10 -28
  52. data/lib/google/protobuf/object_cache.rb +97 -0
  53. data/lib/google/protobuf/plugin_pb.rb +47 -0
  54. data/lib/google/protobuf/repeated_field.rb +18 -28
  55. data/lib/google/protobuf/source_context_pb.rb +24 -4
  56. data/lib/google/protobuf/struct_pb.rb +24 -20
  57. data/lib/google/protobuf/timestamp_pb.rb +24 -5
  58. data/lib/google/protobuf/type_pb.rb +26 -68
  59. data/lib/google/protobuf/well_known_types.rb +16 -40
  60. data/lib/google/protobuf/wrappers_pb.rb +24 -28
  61. data/lib/google/protobuf.rb +32 -50
  62. data/lib/google/protobuf_ffi.rb +50 -0
  63. data/lib/google/protobuf_native.rb +20 -0
  64. data/lib/google/tasks/ffi.rake +102 -0
  65. metadata +82 -20
  66. data/tests/basic.rb +0 -640
  67. data/tests/generated_code_test.rb +0 -23
  68. data/tests/stress.rb +0 -38
@@ -0,0 +1,319 @@
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2022 Google Inc. All rights reserved.
3
+ #
4
+ # Use of this source code is governed by a BSD-style
5
+ # license that can be found in the LICENSE file or at
6
+ # https://developers.google.com/open-source/licenses/bsd
7
+
8
+ module Google
9
+ module Protobuf
10
+ class FieldDescriptor
11
+ attr :field_def, :descriptor_pool
12
+
13
+ include Google::Protobuf::Internal::Convert
14
+
15
+ # FFI Interface methods and setup
16
+ extend ::FFI::DataConverter
17
+ native_type ::FFI::Type::POINTER
18
+
19
+ class << self
20
+ prepend Google::Protobuf::Internal::TypeSafety
21
+ include Google::Protobuf::Internal::PointerHelper
22
+
23
+ # @param value [FieldDescriptor] FieldDescriptor to convert to an FFI native type
24
+ # @param _ [Object] Unused
25
+ def to_native(value, _)
26
+ field_def_ptr = value.instance_variable_get(:@field_def)
27
+ warn "Underlying field_def was nil!" if field_def_ptr.nil?
28
+ raise "Underlying field_def was null!" if !field_def_ptr.nil? and field_def_ptr.null?
29
+ field_def_ptr
30
+ end
31
+
32
+ ##
33
+ # @param field_def [::FFI::Pointer] FieldDef pointer to be wrapped
34
+ # @param _ [Object] Unused
35
+ def from_native(field_def, _ = nil)
36
+ return nil if field_def.nil? or field_def.null?
37
+ file_def = Google::Protobuf::FFI.file_def_by_raw_field_def(field_def)
38
+ descriptor_from_file_def(file_def, field_def)
39
+ end
40
+ end
41
+
42
+ def self.new(*arguments, &block)
43
+ raise "Descriptor objects may not be created from Ruby."
44
+ end
45
+
46
+ def to_s
47
+ inspect
48
+ end
49
+
50
+ def inspect
51
+ "#{self.class.name}: #{name}"
52
+ end
53
+
54
+ def name
55
+ @name ||= Google::Protobuf::FFI.get_full_name(self)
56
+ end
57
+
58
+ def json_name
59
+ @json_name ||= Google::Protobuf::FFI.get_json_name(self)
60
+ end
61
+
62
+ def number
63
+ @number ||= Google::Protobuf::FFI.get_number(self)
64
+ end
65
+
66
+ def type
67
+ @type ||= Google::Protobuf::FFI.get_type(self)
68
+ end
69
+
70
+ def label
71
+ @label ||= Google::Protobuf::FFI::Label[Google::Protobuf::FFI.get_label(self)]
72
+ end
73
+
74
+ def default
75
+ return nil if Google::Protobuf::FFI.is_sub_message(self)
76
+ if Google::Protobuf::FFI.is_repeated(self)
77
+ message_value = Google::Protobuf::FFI::MessageValue.new
78
+ else
79
+ message_value = Google::Protobuf::FFI.get_default(self)
80
+ end
81
+ enum_def = Google::Protobuf::FFI.get_subtype_as_enum(self)
82
+ if enum_def.null?
83
+ convert_upb_to_ruby message_value, c_type
84
+ else
85
+ convert_upb_to_ruby message_value, c_type, enum_def
86
+ end
87
+ end
88
+
89
+ def submsg_name
90
+ if defined? @submsg_name
91
+ @submsg_name
92
+ else
93
+ @submsg_name = case c_type
94
+ when :enum
95
+ Google::Protobuf::FFI.get_enum_fullname Google::Protobuf::FFI.get_subtype_as_enum self
96
+ when :message
97
+ Google::Protobuf::FFI.get_message_fullname Google::Protobuf::FFI.get_subtype_as_message self
98
+ else
99
+ nil
100
+ end
101
+ end
102
+ end
103
+
104
+ ##
105
+ # Tests if this field has been set on the argument message.
106
+ #
107
+ # @param msg [Google::Protobuf::Message]
108
+ # @return [Object] Value of the field on this message.
109
+ # @raise [TypeError] If the field is not defined on this message.
110
+ def get(msg)
111
+ if msg.class.descriptor == Google::Protobuf::FFI.get_containing_message_def(self)
112
+ msg.send :get_field, self
113
+ else
114
+ raise TypeError.new "get method called on wrong message type"
115
+ end
116
+ end
117
+
118
+ def subtype
119
+ if defined? @subtype
120
+ @subtype
121
+ else
122
+ @subtype = case c_type
123
+ when :enum
124
+ Google::Protobuf::FFI.get_subtype_as_enum(self)
125
+ when :message
126
+ Google::Protobuf::FFI.get_subtype_as_message(self)
127
+ else
128
+ nil
129
+ end
130
+ end
131
+ end
132
+
133
+ ##
134
+ # Tests if this field has been set on the argument message.
135
+ #
136
+ # @param msg [Google::Protobuf::Message]
137
+ # @return [Boolean] True iff message has this field set
138
+ # @raise [TypeError] If this field does not exist on the message
139
+ # @raise [ArgumentError] If this field does not track presence
140
+ def has?(msg)
141
+ if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
142
+ raise TypeError.new "has method called on wrong message type"
143
+ end
144
+ unless has_presence?
145
+ raise ArgumentError.new "does not track presence"
146
+ end
147
+
148
+ Google::Protobuf::FFI.get_message_has msg.instance_variable_get(:@msg), self
149
+ end
150
+
151
+ ##
152
+ # Tests if this field tracks presence.
153
+ #
154
+ # @return [Boolean] True iff this field tracks presence
155
+ def has_presence?
156
+ @has_presence ||= Google::Protobuf::FFI.get_has_presence(self)
157
+ end
158
+
159
+ # @param msg [Google::Protobuf::Message]
160
+ def clear(msg)
161
+ if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
162
+ raise TypeError.new "clear method called on wrong message type"
163
+ end
164
+ Google::Protobuf::FFI.clear_message_field msg.instance_variable_get(:@msg), self
165
+ nil
166
+ end
167
+
168
+ ##
169
+ # call-seq:
170
+ # FieldDescriptor.set(message, value)
171
+ #
172
+ # Sets the value corresponding to this field to the given value on the given
173
+ # message. Raises an exception if message is of the wrong type. Performs the
174
+ # ordinary type-checks for field setting.
175
+ #
176
+ # @param msg [Google::Protobuf::Message]
177
+ # @param value [Object]
178
+ def set(msg, value)
179
+ if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
180
+ raise TypeError.new "set method called on wrong message type"
181
+ end
182
+ unless set_value_on_message value, msg.instance_variable_get(:@msg), msg.instance_variable_get(:@arena)
183
+ raise RuntimeError.new "allocation failed"
184
+ end
185
+ nil
186
+ end
187
+
188
+ def map?
189
+ @map ||= Google::Protobuf::FFI.is_map self
190
+ end
191
+
192
+ def repeated?
193
+ @repeated ||= Google::Protobuf::FFI.is_repeated self
194
+ end
195
+
196
+ def sub_message?
197
+ @sub_message ||= Google::Protobuf::FFI.is_sub_message self
198
+ end
199
+
200
+ def wrapper?
201
+ if defined? @wrapper
202
+ @wrapper
203
+ else
204
+ message_descriptor = Google::Protobuf::FFI.get_subtype_as_message(self)
205
+ @wrapper = message_descriptor.nil? ? false : message_descriptor.send(:wrapper?)
206
+ end
207
+ end
208
+
209
+ def options
210
+ @options ||= begin
211
+ size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
212
+ temporary_arena = Google::Protobuf::FFI.create_arena
213
+ buffer = Google::Protobuf::FFI.field_options(self, size_ptr, temporary_arena)
214
+ Google::Protobuf::FieldOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze)
215
+ end
216
+ end
217
+
218
+ private
219
+
220
+ def initialize(field_def, descriptor_pool)
221
+ @field_def = field_def
222
+ @descriptor_pool = descriptor_pool
223
+ end
224
+
225
+ def self.private_constructor(field_def, descriptor_pool)
226
+ instance = allocate
227
+ instance.send(:initialize, field_def, descriptor_pool)
228
+ instance
229
+ end
230
+
231
+ # TODO Can this be added to the public API?
232
+ def real_containing_oneof
233
+ @real_containing_oneof ||= Google::Protobuf::FFI.real_containing_oneof self
234
+ end
235
+
236
+ # Implementation details below are subject to breaking changes without
237
+ # warning and are intended for use only within the gem.
238
+
239
+ ##
240
+ # Sets the field this FieldDescriptor represents to the given value on the given message.
241
+ # @param value [Object] Value to be set
242
+ # @param msg [::FFI::Pointer] Pointer the the upb_Message
243
+ # @param arena [Arena] Arena of the message that owns msg
244
+ def set_value_on_message(value, msg, arena, wrap: false)
245
+ message_to_alter = msg
246
+ field_def_to_set = self
247
+ if map?
248
+ raise TypeError.new "Expected map" unless value.is_a? Google::Protobuf::Map
249
+ message_descriptor = subtype
250
+
251
+ key_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 1)
252
+ key_field_type = Google::Protobuf::FFI.get_type(key_field_def)
253
+ raise TypeError.new "Map key type does not match field's key type" unless key_field_type == value.send(:key_type)
254
+
255
+ value_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 2)
256
+ value_field_type = Google::Protobuf::FFI.get_type(value_field_def)
257
+ raise TypeError.new "Map value type does not match field's value type" unless value_field_type == value.send(:value_type)
258
+
259
+ raise TypeError.new "Map value type has wrong message/enum class" unless value_field_def.subtype == value.send(:descriptor)
260
+
261
+ arena.fuse(value.send(:arena))
262
+ message_value = Google::Protobuf::FFI::MessageValue.new
263
+ message_value[:map_val] = value.send(:map_ptr)
264
+ elsif repeated?
265
+ raise TypeError.new "Expected repeated field array" unless value.is_a? RepeatedField
266
+ raise TypeError.new "Repeated field array has wrong message/enum class" unless value.send(:type) == type
267
+ arena.fuse(value.send(:arena))
268
+ message_value = Google::Protobuf::FFI::MessageValue.new
269
+ message_value[:array_val] = value.send(:array)
270
+ else
271
+ if value.nil? and (sub_message? or !real_containing_oneof.nil?)
272
+ Google::Protobuf::FFI.clear_message_field message_to_alter, field_def_to_set
273
+ return true
274
+ end
275
+ if wrap
276
+ value_field_def = Google::Protobuf::FFI.get_field_by_number subtype, 1
277
+ type_for_conversion = Google::Protobuf::FFI.get_c_type(value_field_def)
278
+ raise RuntimeError.new "Not expecting to get a msg or enum when unwrapping" if [:enum, :message].include? type_for_conversion
279
+ message_value = convert_ruby_to_upb(value, arena, type_for_conversion, nil)
280
+ message_to_alter = Google::Protobuf::FFI.get_mutable_message(msg, self, arena)[:msg]
281
+ field_def_to_set = value_field_def
282
+ else
283
+ message_value = convert_ruby_to_upb(value, arena, c_type, subtype)
284
+ end
285
+ end
286
+ Google::Protobuf::FFI.set_message_field message_to_alter, field_def_to_set, message_value, arena
287
+ end
288
+
289
+ def c_type
290
+ @c_type ||= Google::Protobuf::FFI.get_c_type(self)
291
+ end
292
+ end
293
+
294
+ class FFI
295
+ # MessageDef
296
+ attach_function :get_field_by_index, :upb_MessageDef_Field, [Descriptor, :int], FieldDescriptor
297
+ attach_function :get_field_by_name, :upb_MessageDef_FindFieldByNameWithSize,[Descriptor, :string, :size_t], FieldDescriptor
298
+ attach_function :get_field_by_number, :upb_MessageDef_FindFieldByNumber, [Descriptor, :uint32_t], FieldDescriptor
299
+
300
+ # FieldDescriptor
301
+ attach_function :field_options, :FieldDescriptor_serialized_options, [FieldDescriptor, :pointer, Internal::Arena], :pointer
302
+ attach_function :get_containing_message_def, :upb_FieldDef_ContainingType, [FieldDescriptor], Descriptor
303
+ attach_function :get_c_type, :upb_FieldDef_CType, [FieldDescriptor], CType
304
+ attach_function :get_default, :upb_FieldDef_Default, [FieldDescriptor], MessageValue.by_value
305
+ attach_function :get_subtype_as_enum, :upb_FieldDef_EnumSubDef, [FieldDescriptor], EnumDescriptor
306
+ attach_function :get_has_presence, :upb_FieldDef_HasPresence, [FieldDescriptor], :bool
307
+ attach_function :is_map, :upb_FieldDef_IsMap, [FieldDescriptor], :bool
308
+ attach_function :is_repeated, :upb_FieldDef_IsRepeated, [FieldDescriptor], :bool
309
+ attach_function :is_sub_message, :upb_FieldDef_IsSubMessage, [FieldDescriptor], :bool
310
+ attach_function :get_json_name, :upb_FieldDef_JsonName, [FieldDescriptor], :string
311
+ attach_function :get_label, :upb_FieldDef_Label, [FieldDescriptor], Label
312
+ attach_function :get_subtype_as_message, :upb_FieldDef_MessageSubDef, [FieldDescriptor], Descriptor
313
+ attach_function :get_full_name, :upb_FieldDef_Name, [FieldDescriptor], :string
314
+ attach_function :get_number, :upb_FieldDef_Number, [FieldDescriptor], :uint32_t
315
+ attach_function :get_type, :upb_FieldDef_Type, [FieldDescriptor], FieldType
316
+ attach_function :file_def_by_raw_field_def, :upb_FieldDef_File, [:pointer], :FileDef
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,59 @@
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2022 Google Inc. All rights reserved.
3
+ #
4
+ # Use of this source code is governed by a BSD-style
5
+ # license that can be found in the LICENSE file or at
6
+ # https://developers.google.com/open-source/licenses/bsd
7
+
8
+ module Google
9
+ module Protobuf
10
+ class FFI
11
+ # FileDescriptor
12
+ attach_function :file_def_name, :upb_FileDef_Name, [:FileDef], :string
13
+ attach_function :file_def_syntax, :upb_FileDef_Syntax, [:FileDef], Syntax
14
+ attach_function :file_def_pool, :upb_FileDef_Pool, [:FileDef], :DefPool
15
+ attach_function :file_options, :FileDescriptor_serialized_options, [:FileDef, :pointer, Internal::Arena], :pointer
16
+ end
17
+
18
+ class FileDescriptor
19
+ attr :descriptor_pool, :file_def
20
+
21
+ def initialize(file_def, descriptor_pool)
22
+ @descriptor_pool = descriptor_pool
23
+ @file_def = file_def
24
+ end
25
+
26
+ def to_s
27
+ inspect
28
+ end
29
+
30
+ def inspect
31
+ "#{self.class.name}: #{name}"
32
+ end
33
+
34
+ def syntax
35
+ case Google::Protobuf::FFI.file_def_syntax(@file_def)
36
+ when :Proto3
37
+ :proto3
38
+ when :Proto2
39
+ :proto2
40
+ else
41
+ nil
42
+ end
43
+ end
44
+
45
+ def name
46
+ Google::Protobuf::FFI.file_def_name(@file_def)
47
+ end
48
+
49
+ def options
50
+ @options ||= begin
51
+ size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
52
+ temporary_arena = Google::Protobuf::FFI.create_arena
53
+ buffer = Google::Protobuf::FFI.file_options(@file_def, size_ptr, temporary_arena)
54
+ Google::Protobuf::FileOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,66 @@
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2022 Google Inc. All rights reserved.
3
+ #
4
+ # Use of this source code is governed by a BSD-style
5
+ # license that can be found in the LICENSE file or at
6
+ # https://developers.google.com/open-source/licenses/bsd
7
+
8
+ ##
9
+ # Implementation details below are subject to breaking changes without
10
+ # warning and are intended for use only within the gem.
11
+ module Google
12
+ module Protobuf
13
+ module Internal
14
+ class Arena
15
+ attr :pinned_messages
16
+
17
+ # FFI Interface methods and setup
18
+ extend ::FFI::DataConverter
19
+ native_type ::FFI::Type::POINTER
20
+
21
+ class << self
22
+ prepend Google::Protobuf::Internal::TypeSafety
23
+
24
+ # @param value [Arena] Arena to convert to an FFI native type
25
+ # @param _ [Object] Unused
26
+ def to_native(value, _)
27
+ value.instance_variable_get(:@arena) || ::FFI::Pointer::NULL
28
+ end
29
+
30
+ ##
31
+ # @param value [::FFI::Pointer] Arena pointer to be wrapped
32
+ # @param _ [Object] Unused
33
+ def from_native(value, _)
34
+ new(value)
35
+ end
36
+ end
37
+
38
+ def initialize(pointer)
39
+ @arena = ::FFI::AutoPointer.new(pointer, Google::Protobuf::FFI.method(:free_arena))
40
+ @pinned_messages = []
41
+ end
42
+
43
+ def fuse(other_arena)
44
+ return if other_arena == self
45
+ unless Google::Protobuf::FFI.fuse_arena(self, other_arena)
46
+ raise RuntimeError.new "Unable to fuse arenas. This should never happen since Ruby does not use initial blocks"
47
+ end
48
+ end
49
+
50
+ def pin(message)
51
+ pinned_messages.push message
52
+ end
53
+ end
54
+ end
55
+
56
+ class FFI
57
+ # Arena
58
+ attach_function :create_arena, :Arena_create, [], Internal::Arena
59
+ attach_function :fuse_arena, :upb_Arena_Fuse, [Internal::Arena, Internal::Arena], :bool
60
+ # Argument takes a :pointer rather than a typed Arena here due to
61
+ # implementation details of FFI::AutoPointer.
62
+ attach_function :free_arena, :upb_Arena_Free, [:pointer], :void
63
+ attach_function :arena_malloc, :upb_Arena_Malloc, [Internal::Arena, :size_t], :pointer
64
+ end
65
+ end
66
+ end