google-protobuf 3.24.4-java → 3.25.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/glue.c +21 -0
  4. data/ext/google/protobuf_c/message.c +1388 -0
  5. data/ext/google/protobuf_c/message.h +79 -0
  6. data/ext/google/protobuf_c/protobuf.c +343 -0
  7. data/ext/google/protobuf_c/protobuf.h +112 -0
  8. data/ext/google/protobuf_c/ruby-upb.c +14414 -0
  9. data/ext/google/protobuf_c/ruby-upb.h +13044 -0
  10. data/ext/google/protobuf_c/shared_convert.c +64 -0
  11. data/ext/google/protobuf_c/shared_convert.h +26 -0
  12. data/ext/google/protobuf_c/shared_message.c +65 -0
  13. data/ext/google/protobuf_c/shared_message.h +25 -0
  14. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  15. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +92 -0
  16. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +157 -0
  17. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +170 -0
  18. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +21 -0
  19. data/lib/google/protobuf/any_pb.rb +1 -1
  20. data/lib/google/protobuf/api_pb.rb +1 -1
  21. data/lib/google/protobuf/descriptor_pb.rb +6 -3
  22. data/lib/google/protobuf/duration_pb.rb +1 -1
  23. data/lib/google/protobuf/empty_pb.rb +1 -1
  24. data/lib/google/protobuf/ffi/descriptor.rb +154 -0
  25. data/lib/google/protobuf/ffi/descriptor_pool.rb +70 -0
  26. data/lib/google/protobuf/ffi/enum_descriptor.rb +161 -0
  27. data/lib/google/protobuf/ffi/ffi.rb +213 -0
  28. data/lib/google/protobuf/ffi/field_descriptor.rb +309 -0
  29. data/lib/google/protobuf/ffi/file_descriptor.rb +48 -0
  30. data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
  31. data/lib/google/protobuf/ffi/internal/convert.rb +305 -0
  32. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  33. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  34. data/lib/google/protobuf/ffi/map.rb +396 -0
  35. data/lib/google/protobuf/ffi/message.rb +641 -0
  36. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  37. data/lib/google/protobuf/ffi/oneof_descriptor.rb +88 -0
  38. data/lib/google/protobuf/ffi/repeated_field.rb +503 -0
  39. data/lib/google/protobuf/field_mask_pb.rb +1 -1
  40. data/lib/google/protobuf/message_exts.rb +3 -26
  41. data/lib/google/protobuf/object_cache.rb +3 -26
  42. data/lib/google/protobuf/plugin_pb.rb +1 -1
  43. data/lib/google/protobuf/repeated_field.rb +3 -26
  44. data/lib/google/protobuf/source_context_pb.rb +1 -1
  45. data/lib/google/protobuf/struct_pb.rb +1 -1
  46. data/lib/google/protobuf/timestamp_pb.rb +1 -1
  47. data/lib/google/protobuf/type_pb.rb +1 -1
  48. data/lib/google/protobuf/well_known_types.rb +3 -26
  49. data/lib/google/protobuf/wrappers_pb.rb +1 -1
  50. data/lib/google/protobuf.rb +26 -45
  51. data/lib/google/protobuf_ffi.rb +50 -0
  52. data/lib/google/protobuf_java.jar +0 -0
  53. data/lib/google/protobuf_native.rb +20 -0
  54. data/lib/google/tasks/ffi.rake +102 -0
  55. metadata +110 -4
@@ -0,0 +1,396 @@
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
+ # Map
12
+ attach_function :map_clear, :upb_Map_Clear, [:Map], :void
13
+ attach_function :map_delete, :upb_Map_Delete, [:Map, MessageValue.by_value, MessageValue.by_ref], :bool
14
+ attach_function :map_get, :upb_Map_Get, [:Map, MessageValue.by_value, MessageValue.by_ref], :bool
15
+ attach_function :create_map, :upb_Map_New, [Internal::Arena, CType, CType], :Map
16
+ attach_function :map_size, :upb_Map_Size, [:Map], :size_t
17
+ attach_function :map_set, :upb_Map_Set, [:Map, MessageValue.by_value, MessageValue.by_value, Internal::Arena], :bool
18
+
19
+ # MapIterator
20
+ attach_function :map_next, :upb_MapIterator_Next, [:Map, :pointer], :bool
21
+ attach_function :map_done, :upb_MapIterator_Done, [:Map, :size_t], :bool
22
+ attach_function :map_key, :upb_MapIterator_Key, [:Map, :size_t], MessageValue.by_value
23
+ attach_function :map_value, :upb_MapIterator_Value, [:Map, :size_t], MessageValue.by_value
24
+ end
25
+ class Map
26
+ include Enumerable
27
+ ##
28
+ # call-seq:
29
+ # Map.new(key_type, value_type, value_typeclass = nil, init_hashmap = {})
30
+ # => new map
31
+ #
32
+ # Allocates a new Map container. This constructor may be called with 2, 3, or 4
33
+ # arguments. The first two arguments are always present and are symbols (taking
34
+ # on the same values as field-type symbols in message descriptors) that
35
+ # indicate the type of the map key and value fields.
36
+ #
37
+ # The supported key types are: :int32, :int64, :uint32, :uint64, :bool,
38
+ # :string, :bytes.
39
+ #
40
+ # The supported value types are: :int32, :int64, :uint32, :uint64, :bool,
41
+ # :string, :bytes, :enum, :message.
42
+ #
43
+ # The third argument, value_typeclass, must be present if value_type is :enum
44
+ # or :message. As in RepeatedField#new, this argument must be a message class
45
+ # (for :message) or enum module (for :enum).
46
+ #
47
+ # The last argument, if present, provides initial content for map. Note that
48
+ # this may be an ordinary Ruby hashmap or another Map instance with identical
49
+ # key and value types. Also note that this argument may be present whether or
50
+ # not value_typeclass is present (and it is unambiguously separate from
51
+ # value_typeclass because value_typeclass's presence is strictly determined by
52
+ # value_type). The contents of this initial hashmap or Map instance are
53
+ # shallow-copied into the new Map: the original map is unmodified, but
54
+ # references to underlying objects will be shared if the value type is a
55
+ # message type.
56
+ def self.new(key_type, value_type, value_typeclass = nil, init_hashmap = {})
57
+ instance = allocate
58
+ # TODO This argument mangling doesn't agree with the type signature,
59
+ # but does align with the text of the comments and is required to make unit tests pass.
60
+ if init_hashmap.empty? and ![:enum, :message].include?(value_type)
61
+ init_hashmap = value_typeclass
62
+ value_typeclass = nil
63
+ end
64
+ instance.send(:initialize, key_type, value_type, value_type_class: value_typeclass, initial_values: init_hashmap)
65
+ instance
66
+ end
67
+
68
+ ##
69
+ # call-seq:
70
+ # Map.keys => [list_of_keys]
71
+ #
72
+ # Returns the list of keys contained in the map, in unspecified order.
73
+ def keys
74
+ return_value = []
75
+ internal_iterator do |iterator|
76
+ key_message_value = Google::Protobuf::FFI.map_key(@map_ptr, iterator)
77
+ return_value << convert_upb_to_ruby(key_message_value, key_type)
78
+ end
79
+ return_value
80
+ end
81
+
82
+ ##
83
+ # call-seq:
84
+ # Map.values => [list_of_values]
85
+ #
86
+ # Returns the list of values contained in the map, in unspecified order.
87
+ def values
88
+ return_value = []
89
+ internal_iterator do |iterator|
90
+ value_message_value = Google::Protobuf::FFI.map_value(@map_ptr, iterator)
91
+ return_value << convert_upb_to_ruby(value_message_value, value_type, descriptor, arena)
92
+ end
93
+ return_value
94
+ end
95
+
96
+ ##
97
+ # call-seq:
98
+ # Map.[](key) => value
99
+ #
100
+ # Accesses the element at the given key. Throws an exception if the key type is
101
+ # incorrect. Returns nil when the key is not present in the map.
102
+ def [](key)
103
+ value = Google::Protobuf::FFI::MessageValue.new
104
+ key_message_value = convert_ruby_to_upb(key, arena, key_type, nil)
105
+ if Google::Protobuf::FFI.map_get(@map_ptr, key_message_value, value)
106
+ convert_upb_to_ruby(value, value_type, descriptor, arena)
107
+ end
108
+ end
109
+
110
+ ##
111
+ # call-seq:
112
+ # Map.[]=(key, value) => value
113
+ #
114
+ # Inserts or overwrites the value at the given key with the given new value.
115
+ # Throws an exception if the key type is incorrect. Returns the new value that
116
+ # was just inserted.
117
+ def []=(key, value)
118
+ raise FrozenError.new "can't modify frozen #{self.class}" if frozen?
119
+ key_message_value = convert_ruby_to_upb(key, arena, key_type, nil)
120
+ value_message_value = convert_ruby_to_upb(value, arena, value_type, descriptor)
121
+ Google::Protobuf::FFI.map_set(@map_ptr, key_message_value, value_message_value, arena)
122
+ value
123
+ end
124
+
125
+ def has_key?(key)
126
+ key_message_value = convert_ruby_to_upb(key, arena, key_type, nil)
127
+ Google::Protobuf::FFI.map_get(@map_ptr, key_message_value, nil)
128
+ end
129
+
130
+ ##
131
+ # call-seq:
132
+ # Map.delete(key) => old_value
133
+ #
134
+ # Deletes the value at the given key, if any, returning either the old value or
135
+ # nil if none was present. Throws an exception if the key is of the wrong type.
136
+ def delete(key)
137
+ raise FrozenError.new "can't modify frozen #{self.class}" if frozen?
138
+ value = Google::Protobuf::FFI::MessageValue.new
139
+ key_message_value = convert_ruby_to_upb(key, arena, key_type, nil)
140
+ if Google::Protobuf::FFI.map_delete(@map_ptr, key_message_value, value)
141
+ convert_upb_to_ruby(value, value_type, descriptor, arena)
142
+ else
143
+ nil
144
+ end
145
+ end
146
+
147
+ def clear
148
+ raise FrozenError.new "can't modify frozen #{self.class}" if frozen?
149
+ Google::Protobuf::FFI.map_clear(@map_ptr)
150
+ nil
151
+ end
152
+
153
+ def length
154
+ Google::Protobuf::FFI.map_size(@map_ptr)
155
+ end
156
+ alias size length
157
+
158
+ ##
159
+ # call-seq:
160
+ # Map.dup => new_map
161
+ #
162
+ # Duplicates this map with a shallow copy. References to all non-primitive
163
+ # element objects (e.g., submessages) are shared.
164
+ def dup
165
+ internal_dup
166
+ end
167
+ alias clone dup
168
+
169
+ ##
170
+ # call-seq:
171
+ # Map.==(other) => boolean
172
+ #
173
+ # Compares this map to another. Maps are equal if they have identical key sets,
174
+ # and for each key, the values in both maps compare equal. Elements are
175
+ # compared as per normal Ruby semantics, by calling their :== methods (or
176
+ # performing a more efficient comparison for primitive types).
177
+ #
178
+ # Maps with dissimilar key types or value types/typeclasses are never equal,
179
+ # even if value comparison (for example, between integers and floats) would
180
+ # have otherwise indicated that every element has equal value.
181
+ def ==(other)
182
+ if other.is_a? Hash
183
+ other = self.class.send(:private_constructor, key_type, value_type, descriptor, initial_values: other)
184
+ elsif !other.is_a? Google::Protobuf::Map
185
+ return false
186
+ end
187
+
188
+ return true if object_id == other.object_id
189
+ return false if key_type != other.send(:key_type) or value_type != other.send(:value_type) or descriptor != other.send(:descriptor) or length != other.length
190
+ other_map_ptr = other.send(:map_ptr)
191
+ each_msg_val do |key_message_value, value_message_value|
192
+ other_value = Google::Protobuf::FFI::MessageValue.new
193
+ return false unless Google::Protobuf::FFI.map_get(other_map_ptr, key_message_value, other_value)
194
+ return false unless Google::Protobuf::FFI.message_value_equal(value_message_value, other_value, value_type, descriptor)
195
+ end
196
+ true
197
+ end
198
+
199
+ def hash
200
+ return_value = 0
201
+ each_msg_val do |key_message_value, value_message_value|
202
+ return_value = Google::Protobuf::FFI.message_value_hash(key_message_value, key_type, nil, return_value)
203
+ return_value = Google::Protobuf::FFI.message_value_hash(value_message_value, value_type, descriptor, return_value)
204
+ end
205
+ return_value
206
+ end
207
+
208
+ ##
209
+ # call-seq:
210
+ # Map.to_h => {}
211
+ #
212
+ # Returns a Ruby Hash object containing all the values within the map
213
+ def to_h
214
+ return {} if map_ptr.nil? or map_ptr.null?
215
+ return_value = {}
216
+ each_msg_val do |key_message_value, value_message_value|
217
+ hash_key = convert_upb_to_ruby(key_message_value, key_type)
218
+ hash_value = scalar_create_hash(value_message_value, value_type, msg_or_enum_descriptor: descriptor)
219
+ return_value[hash_key] = hash_value
220
+ end
221
+ return_value
222
+ end
223
+
224
+ def inspect
225
+ key_value_pairs = []
226
+ each_msg_val do |key_message_value, value_message_value|
227
+ key_string = convert_upb_to_ruby(key_message_value, key_type).inspect
228
+ if value_type == :message
229
+ sub_msg_descriptor = Google::Protobuf::FFI.get_subtype_as_message(descriptor)
230
+ value_string = sub_msg_descriptor.msgclass.send(:inspect_internal, value_message_value[:msg_val])
231
+ else
232
+ value_string = convert_upb_to_ruby(value_message_value, value_type, descriptor).inspect
233
+ end
234
+ key_value_pairs << "#{key_string}=>#{value_string}"
235
+ end
236
+ "{#{key_value_pairs.join(", ")}}"
237
+ end
238
+
239
+ ##
240
+ # call-seq:
241
+ # Map.merge(other_map) => map
242
+ #
243
+ # Copies key/value pairs from other_map into a copy of this map. If a key is
244
+ # set in other_map and this map, the value from other_map overwrites the value
245
+ # in the new copy of this map. Returns the new copy of this map with merged
246
+ # contents.
247
+ def merge(other)
248
+ internal_merge(other)
249
+ end
250
+
251
+ ##
252
+ # call-seq:
253
+ # Map.each(&block)
254
+ #
255
+ # Invokes &block on each |key, value| pair in the map, in unspecified order.
256
+ # Note that Map also includes Enumerable; map thus acts like a normal Ruby
257
+ # sequence.
258
+ def each &block
259
+ each_msg_val do |key_message_value, value_message_value|
260
+ key_value = convert_upb_to_ruby(key_message_value, key_type)
261
+ value_value = convert_upb_to_ruby(value_message_value, value_type, descriptor, arena)
262
+ yield key_value, value_value
263
+ end
264
+ nil
265
+ end
266
+
267
+ private
268
+ attr :arena, :map_ptr, :key_type, :value_type, :descriptor, :name
269
+
270
+ include Google::Protobuf::Internal::Convert
271
+
272
+ def internal_iterator
273
+ iter = ::FFI::MemoryPointer.new(:size_t, 1)
274
+ iter.write(:size_t, Google::Protobuf::FFI::Upb_Map_Begin)
275
+ while Google::Protobuf::FFI.map_next(@map_ptr, iter) do
276
+ iter_size_t = iter.read(:size_t)
277
+ yield iter_size_t
278
+ end
279
+ end
280
+
281
+ def each_msg_val &block
282
+ internal_iterator do |iterator|
283
+ key_message_value = Google::Protobuf::FFI.map_key(@map_ptr, iterator)
284
+ value_message_value = Google::Protobuf::FFI.map_value(@map_ptr, iterator)
285
+ yield key_message_value, value_message_value
286
+ end
287
+ end
288
+
289
+ def internal_dup
290
+ instance = self.class.send(:private_constructor, key_type, value_type, descriptor, arena: arena)
291
+ new_map_ptr = instance.send(:map_ptr)
292
+ each_msg_val do |key_message_value, value_message_value|
293
+ Google::Protobuf::FFI.map_set(new_map_ptr, key_message_value, value_message_value, arena)
294
+ end
295
+ instance
296
+ end
297
+
298
+ def internal_merge_into_self(other)
299
+ case other
300
+ when Hash
301
+ other.each do |key, value|
302
+ key_message_value = convert_ruby_to_upb(key, arena, key_type, nil)
303
+ value_message_value = convert_ruby_to_upb(value, arena, value_type, descriptor)
304
+ Google::Protobuf::FFI.map_set(@map_ptr, key_message_value, value_message_value, arena)
305
+ end
306
+ when Google::Protobuf::Map
307
+ unless key_type == other.send(:key_type) and value_type == other.send(:value_type) and descriptor == other.descriptor
308
+ raise ArgumentError.new "Attempt to merge Map with mismatching types" #TODO Improve error message by adding type information
309
+ end
310
+ arena.fuse(other.send(:arena))
311
+ iter = ::FFI::MemoryPointer.new(:size_t, 1)
312
+ iter.write(:size_t, Google::Protobuf::FFI::Upb_Map_Begin)
313
+ other.send(:each_msg_val) do |key_message_value, value_message_value|
314
+ Google::Protobuf::FFI.map_set(@map_ptr, key_message_value, value_message_value, arena)
315
+ end
316
+ else
317
+ raise ArgumentError.new "Unknown type merging into Map" #TODO improve this error message by including type information
318
+ end
319
+ self
320
+ end
321
+
322
+ def internal_merge(other)
323
+ internal_dup.internal_merge_into_self(other)
324
+ end
325
+
326
+ def initialize(key_type, value_type, value_type_class: nil, initial_values: nil, arena: nil, map: nil, descriptor: nil, name: nil)
327
+ @name = name || 'Map'
328
+
329
+ unless [:int32, :int64, :uint32, :uint64, :bool, :string, :bytes].include? key_type
330
+ raise ArgumentError.new "Invalid key type for map." #TODO improve error message to include what type was passed
331
+ end
332
+ @key_type = key_type
333
+
334
+ unless [:int32, :int64, :uint32, :uint64, :bool, :string, :bytes, :enum, :message].include? value_type
335
+ raise ArgumentError.new "Invalid value type for map." #TODO improve error message to include what type was passed
336
+ end
337
+ @value_type = value_type
338
+
339
+ if !descriptor.nil?
340
+ raise ArgumentError "Expected descriptor to be a Descriptor or EnumDescriptor" unless [EnumDescriptor, Descriptor].include? descriptor.class
341
+ @descriptor = descriptor
342
+ elsif [:message, :enum].include? value_type
343
+ raise ArgumentError.new "Expected at least 3 arguments for message/enum." if value_type_class.nil?
344
+ descriptor = value_type_class.respond_to?(:descriptor) ? value_type_class.descriptor : nil
345
+ raise ArgumentError.new "Type class #{value_type_class} has no descriptor. Please pass a class or enum as returned by the DescriptorPool." if descriptor.nil?
346
+ @descriptor = descriptor
347
+ else
348
+ @descriptor = nil
349
+ end
350
+
351
+ @arena = arena || Google::Protobuf::FFI.create_arena
352
+ @map_ptr = map || Google::Protobuf::FFI.create_map(@arena, @key_type, @value_type)
353
+
354
+ internal_merge_into_self(initial_values) unless initial_values.nil?
355
+
356
+ # Should always be the last expression of the initializer to avoid
357
+ # leaking references to this object before construction is complete.
358
+ OBJECT_CACHE.try_add(@map_ptr.address, self)
359
+ end
360
+
361
+ # @param field [FieldDescriptor] Descriptor of the field where the RepeatedField will be assigned
362
+ # @param values [Hash|Map] Initial value; may be nil or empty
363
+ # @param arena [Arena] Owning message's arena
364
+ def self.construct_for_field(field, arena, value: nil, map: nil)
365
+ raise ArgumentError.new "Expected Hash object as initializer value for map field '#{field.name}' (given #{value.class})." unless value.nil? or value.is_a? Hash
366
+ instance = allocate
367
+ raise ArgumentError.new "Expected field with type :message, instead got #{field.class}" unless field.type == :message
368
+ message_descriptor = field.send(:subtype)
369
+ key_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 1)
370
+ key_field_type = Google::Protobuf::FFI.get_type(key_field_def)
371
+
372
+ value_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 2)
373
+ value_field_type = Google::Protobuf::FFI.get_type(value_field_def)
374
+ instance.send(:initialize, key_field_type, value_field_type, initial_values: value, name: field.name, arena: arena, map: map, descriptor: value_field_def.subtype)
375
+ instance
376
+ end
377
+
378
+ def self.private_constructor(key_type, value_type, descriptor, initial_values: nil, arena: nil)
379
+ instance = allocate
380
+ instance.send(:initialize, key_type, value_type, descriptor: descriptor, initial_values: initial_values, arena: arena)
381
+ instance
382
+ end
383
+
384
+ extend Google::Protobuf::Internal::Convert
385
+
386
+ def self.deep_copy(map)
387
+ instance = allocate
388
+ instance.send(:initialize, map.send(:key_type), map.send(:value_type), descriptor: map.send(:descriptor))
389
+ map.send(:each_msg_val) do |key_message_value, value_message_value|
390
+ Google::Protobuf::FFI.map_set(instance.send(:map_ptr), key_message_value, message_value_deep_copy(value_message_value, map.send(:value_type), map.send(:descriptor), instance.send(:arena)), instance.send(:arena))
391
+ end
392
+ instance
393
+ end
394
+ end
395
+ end
396
+ end