google-protobuf 3.14.0 → 4.26.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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +317 -0
  4. data/ext/google/protobuf_c/convert.h +50 -0
  5. data/ext/google/protobuf_c/defs.c +759 -1709
  6. data/ext/google/protobuf_c/defs.h +82 -0
  7. data/ext/google/protobuf_c/extconf.rb +15 -8
  8. data/ext/google/protobuf_c/glue.c +56 -0
  9. data/ext/google/protobuf_c/map.c +328 -485
  10. data/ext/google/protobuf_c/map.h +44 -0
  11. data/ext/google/protobuf_c/message.c +1061 -530
  12. data/ext/google/protobuf_c/message.h +86 -0
  13. data/ext/google/protobuf_c/protobuf.c +314 -94
  14. data/ext/google/protobuf_c/protobuf.h +66 -621
  15. data/ext/google/protobuf_c/repeated_field.c +314 -353
  16. data/ext/google/protobuf_c/repeated_field.h +41 -0
  17. data/ext/google/protobuf_c/ruby-upb.c +15407 -0
  18. data/ext/google/protobuf_c/ruby-upb.h +13966 -0
  19. data/ext/google/protobuf_c/shared_convert.c +66 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +67 -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/utf8_range.c +467 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +22 -0
  26. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  27. data/lib/google/protobuf/any_pb.rb +6 -8
  28. data/lib/google/protobuf/api_pb.rb +7 -26
  29. data/lib/google/protobuf/descriptor_pb.rb +65 -0
  30. data/lib/google/protobuf/duration_pb.rb +6 -8
  31. data/lib/google/protobuf/empty_pb.rb +6 -6
  32. data/lib/google/protobuf/ffi/descriptor.rb +164 -0
  33. data/lib/google/protobuf/ffi/descriptor_pool.rb +75 -0
  34. data/lib/google/protobuf/ffi/enum_descriptor.rb +171 -0
  35. data/lib/google/protobuf/ffi/ffi.rb +215 -0
  36. data/lib/google/protobuf/ffi/field_descriptor.rb +328 -0
  37. data/lib/google/protobuf/ffi/file_descriptor.rb +47 -0
  38. data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
  39. data/lib/google/protobuf/ffi/internal/convert.rb +289 -0
  40. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  41. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  42. data/lib/google/protobuf/ffi/map.rb +409 -0
  43. data/lib/google/protobuf/ffi/message.rb +659 -0
  44. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  45. data/lib/google/protobuf/ffi/oneof_descriptor.rb +95 -0
  46. data/lib/google/protobuf/ffi/repeated_field.rb +385 -0
  47. data/lib/google/protobuf/field_mask_pb.rb +6 -7
  48. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  49. data/lib/google/protobuf/message_exts.rb +10 -28
  50. data/lib/google/protobuf/plugin_pb.rb +25 -0
  51. data/lib/google/protobuf/repeated_field.rb +19 -30
  52. data/lib/google/protobuf/source_context_pb.rb +6 -7
  53. data/lib/google/protobuf/struct_pb.rb +6 -23
  54. data/lib/google/protobuf/timestamp_pb.rb +6 -8
  55. data/lib/google/protobuf/type_pb.rb +7 -71
  56. data/lib/google/protobuf/well_known_types.rb +17 -36
  57. data/lib/google/protobuf/wrappers_pb.rb +6 -31
  58. data/lib/google/protobuf.rb +32 -118
  59. data/lib/google/protobuf_ffi.rb +49 -0
  60. data/lib/google/protobuf_native.rb +19 -0
  61. data/lib/google/tasks/ffi.rake +100 -0
  62. metadata +88 -37
  63. data/ext/google/protobuf_c/encode_decode.c +0 -1795
  64. data/ext/google/protobuf_c/storage.c +0 -1198
  65. data/ext/google/protobuf_c/upb.c +0 -13817
  66. data/ext/google/protobuf_c/upb.h +0 -6777
  67. data/tests/basic.rb +0 -543
  68. data/tests/generated_code_test.rb +0 -23
  69. data/tests/stress.rb +0 -38
@@ -0,0 +1,328 @@
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
+ ##
160
+ # Tests if this is a repeated field that uses packed encoding.
161
+ #
162
+ # @return [Boolean] True iff this field is packed
163
+ def is_packed?
164
+ @is_packed ||= Google::Protobuf::FFI.get_is_packed(self)
165
+ end
166
+
167
+ # @param msg [Google::Protobuf::Message]
168
+ def clear(msg)
169
+ if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
170
+ raise TypeError.new "clear method called on wrong message type"
171
+ end
172
+ Google::Protobuf::FFI.clear_message_field msg.instance_variable_get(:@msg), self
173
+ nil
174
+ end
175
+
176
+ ##
177
+ # call-seq:
178
+ # FieldDescriptor.set(message, value)
179
+ #
180
+ # Sets the value corresponding to this field to the given value on the given
181
+ # message. Raises an exception if message is of the wrong type. Performs the
182
+ # ordinary type-checks for field setting.
183
+ #
184
+ # @param msg [Google::Protobuf::Message]
185
+ # @param value [Object]
186
+ def set(msg, value)
187
+ if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
188
+ raise TypeError.new "set method called on wrong message type"
189
+ end
190
+ unless set_value_on_message value, msg.instance_variable_get(:@msg), msg.instance_variable_get(:@arena)
191
+ raise RuntimeError.new "allocation failed"
192
+ end
193
+ nil
194
+ end
195
+
196
+ def map?
197
+ @map ||= Google::Protobuf::FFI.is_map self
198
+ end
199
+
200
+ def repeated?
201
+ @repeated ||= Google::Protobuf::FFI.is_repeated self
202
+ end
203
+
204
+ def sub_message?
205
+ @sub_message ||= Google::Protobuf::FFI.is_sub_message self
206
+ end
207
+
208
+ def wrapper?
209
+ if defined? @wrapper
210
+ @wrapper
211
+ else
212
+ message_descriptor = Google::Protobuf::FFI.get_subtype_as_message(self)
213
+ @wrapper = message_descriptor.nil? ? false : message_descriptor.send(:wrapper?)
214
+ end
215
+ end
216
+
217
+ def options
218
+ @options ||= begin
219
+ size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
220
+ temporary_arena = Google::Protobuf::FFI.create_arena
221
+ buffer = Google::Protobuf::FFI.field_options(self, size_ptr, temporary_arena)
222
+ Google::Protobuf::FieldOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).freeze
223
+ end
224
+ end
225
+
226
+ private
227
+
228
+ def initialize(field_def, descriptor_pool)
229
+ @field_def = field_def
230
+ @descriptor_pool = descriptor_pool
231
+ end
232
+
233
+ def self.private_constructor(field_def, descriptor_pool)
234
+ instance = allocate
235
+ instance.send(:initialize, field_def, descriptor_pool)
236
+ instance
237
+ end
238
+
239
+ # TODO Can this be added to the public API?
240
+ def real_containing_oneof
241
+ @real_containing_oneof ||= Google::Protobuf::FFI.real_containing_oneof self
242
+ end
243
+
244
+ # Implementation details below are subject to breaking changes without
245
+ # warning and are intended for use only within the gem.
246
+
247
+ ##
248
+ # Sets the field this FieldDescriptor represents to the given value on the given message.
249
+ # @param value [Object] Value to be set
250
+ # @param msg [::FFI::Pointer] Pointer the the upb_Message
251
+ # @param arena [Arena] Arena of the message that owns msg
252
+ def set_value_on_message(value, msg, arena, wrap: false)
253
+ message_to_alter = msg
254
+ field_def_to_set = self
255
+ if map?
256
+ raise TypeError.new "Expected map" unless value.is_a? Google::Protobuf::Map
257
+ message_descriptor = subtype
258
+
259
+ key_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 1)
260
+ key_field_type = Google::Protobuf::FFI.get_type(key_field_def)
261
+ raise TypeError.new "Map key type does not match field's key type" unless key_field_type == value.send(:key_type)
262
+
263
+ value_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 2)
264
+ value_field_type = Google::Protobuf::FFI.get_type(value_field_def)
265
+ raise TypeError.new "Map value type does not match field's value type" unless value_field_type == value.send(:value_type)
266
+
267
+ raise TypeError.new "Map value type has wrong message/enum class" unless value_field_def.subtype == value.send(:descriptor)
268
+
269
+ arena.fuse(value.send(:arena))
270
+ message_value = Google::Protobuf::FFI::MessageValue.new
271
+ message_value[:map_val] = value.send(:map_ptr)
272
+ elsif repeated?
273
+ raise TypeError.new "Expected repeated field array" unless value.is_a? RepeatedField
274
+ raise TypeError.new "Repeated field array has wrong message/enum class" unless value.send(:type) == type
275
+ arena.fuse(value.send(:arena))
276
+ message_value = Google::Protobuf::FFI::MessageValue.new
277
+ message_value[:array_val] = value.send(:array)
278
+ else
279
+ if value.nil? and (sub_message? or !real_containing_oneof.nil?)
280
+ Google::Protobuf::FFI.clear_message_field message_to_alter, field_def_to_set
281
+ return true
282
+ end
283
+ if wrap
284
+ value_field_def = Google::Protobuf::FFI.get_field_by_number subtype, 1
285
+ type_for_conversion = Google::Protobuf::FFI.get_c_type(value_field_def)
286
+ raise RuntimeError.new "Not expecting to get a msg or enum when unwrapping" if [:enum, :message].include? type_for_conversion
287
+ message_value = convert_ruby_to_upb(value, arena, type_for_conversion, nil)
288
+ message_to_alter = Google::Protobuf::FFI.get_mutable_message(msg, self, arena)[:msg]
289
+ field_def_to_set = value_field_def
290
+ else
291
+ message_value = convert_ruby_to_upb(value, arena, c_type, subtype)
292
+ end
293
+ end
294
+ Google::Protobuf::FFI.set_message_field message_to_alter, field_def_to_set, message_value, arena
295
+ end
296
+
297
+ def c_type
298
+ @c_type ||= Google::Protobuf::FFI.get_c_type(self)
299
+ end
300
+ end
301
+
302
+ class FFI
303
+ # MessageDef
304
+ attach_function :get_field_by_index, :upb_MessageDef_Field, [Descriptor, :int], FieldDescriptor
305
+ attach_function :get_field_by_name, :upb_MessageDef_FindFieldByNameWithSize,[Descriptor, :string, :size_t], FieldDescriptor
306
+ attach_function :get_field_by_number, :upb_MessageDef_FindFieldByNumber, [Descriptor, :uint32_t], FieldDescriptor
307
+
308
+ # FieldDescriptor
309
+ attach_function :field_options, :FieldDescriptor_serialized_options, [FieldDescriptor, :pointer, Internal::Arena], :pointer
310
+ attach_function :get_containing_message_def, :upb_FieldDef_ContainingType, [FieldDescriptor], Descriptor
311
+ attach_function :get_c_type, :upb_FieldDef_CType, [FieldDescriptor], CType
312
+ attach_function :get_default, :upb_FieldDef_Default, [FieldDescriptor], MessageValue.by_value
313
+ attach_function :get_subtype_as_enum, :upb_FieldDef_EnumSubDef, [FieldDescriptor], EnumDescriptor
314
+ attach_function :get_has_presence, :upb_FieldDef_HasPresence, [FieldDescriptor], :bool
315
+ attach_function :get_is_packed, :upb_FieldDef_IsPacked, [FieldDescriptor], :bool
316
+ attach_function :is_map, :upb_FieldDef_IsMap, [FieldDescriptor], :bool
317
+ attach_function :is_repeated, :upb_FieldDef_IsRepeated, [FieldDescriptor], :bool
318
+ attach_function :is_sub_message, :upb_FieldDef_IsSubMessage, [FieldDescriptor], :bool
319
+ attach_function :get_json_name, :upb_FieldDef_JsonName, [FieldDescriptor], :string
320
+ attach_function :get_label, :upb_FieldDef_Label, [FieldDescriptor], Label
321
+ attach_function :get_subtype_as_message, :upb_FieldDef_MessageSubDef, [FieldDescriptor], Descriptor
322
+ attach_function :get_full_name, :upb_FieldDef_Name, [FieldDescriptor], :string
323
+ attach_function :get_number, :upb_FieldDef_Number, [FieldDescriptor], :uint32_t
324
+ attach_function :get_type, :upb_FieldDef_Type, [FieldDescriptor], FieldType
325
+ attach_function :file_def_by_raw_field_def, :upb_FieldDef_File, [:pointer], :FileDef
326
+ end
327
+ end
328
+ end
@@ -0,0 +1,47 @@
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_pool, :upb_FileDef_Pool, [:FileDef], :DefPool
14
+ attach_function :file_options, :FileDescriptor_serialized_options, [:FileDef, :pointer, Internal::Arena], :pointer
15
+ end
16
+
17
+ class FileDescriptor
18
+ attr :descriptor_pool, :file_def
19
+
20
+ def initialize(file_def, descriptor_pool)
21
+ @descriptor_pool = descriptor_pool
22
+ @file_def = file_def
23
+ end
24
+
25
+ def to_s
26
+ inspect
27
+ end
28
+
29
+ def inspect
30
+ "#{self.class.name}: #{name}"
31
+ end
32
+
33
+ def name
34
+ Google::Protobuf::FFI.file_def_name(@file_def)
35
+ end
36
+
37
+ def options
38
+ @options ||= begin
39
+ size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
40
+ temporary_arena = Google::Protobuf::FFI.create_arena
41
+ buffer = Google::Protobuf::FFI.file_options(@file_def, size_ptr, temporary_arena)
42
+ Google::Protobuf::FileOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).freeze
43
+ end
44
+ end
45
+ end
46
+ end
47
+ 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