google-protobuf 3.21.2 → 4.29.1

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