google-protobuf 3.25.8 → 4.31.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/convert.c +33 -15
  3. data/ext/google/protobuf_c/defs.c +558 -29
  4. data/ext/google/protobuf_c/extconf.rb +19 -3
  5. data/ext/google/protobuf_c/glue.c +79 -0
  6. data/ext/google/protobuf_c/map.c +74 -29
  7. data/ext/google/protobuf_c/map.h +7 -3
  8. data/ext/google/protobuf_c/message.c +115 -118
  9. data/ext/google/protobuf_c/message.h +2 -6
  10. data/ext/google/protobuf_c/protobuf.c +32 -18
  11. data/ext/google/protobuf_c/protobuf.h +3 -13
  12. data/ext/google/protobuf_c/repeated_field.c +58 -23
  13. data/ext/google/protobuf_c/repeated_field.h +6 -2
  14. data/ext/google/protobuf_c/ruby-upb.c +15425 -11560
  15. data/ext/google/protobuf_c/ruby-upb.h +9121 -5850
  16. data/ext/google/protobuf_c/shared_convert.c +7 -2
  17. data/ext/google/protobuf_c/shared_message.c +3 -32
  18. data/ext/google/protobuf_c/shared_message.h +0 -4
  19. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
  20. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
  21. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
  22. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
  23. data/lib/google/protobuf/any_pb.rb +2 -23
  24. data/lib/google/protobuf/api_pb.rb +2 -25
  25. data/lib/google/protobuf/descriptor_pb.rb +8 -24
  26. data/lib/google/protobuf/duration_pb.rb +2 -23
  27. data/lib/google/protobuf/empty_pb.rb +2 -23
  28. data/lib/google/protobuf/ffi/descriptor.rb +14 -4
  29. data/lib/google/protobuf/ffi/descriptor_pool.rb +5 -1
  30. data/lib/google/protobuf/ffi/enum_descriptor.rb +13 -1
  31. data/lib/google/protobuf/ffi/ffi.rb +7 -6
  32. data/lib/google/protobuf/ffi/field_descriptor.rb +29 -2
  33. data/lib/google/protobuf/ffi/file_descriptor.rb +39 -13
  34. data/lib/google/protobuf/ffi/internal/arena.rb +0 -6
  35. data/lib/google/protobuf/ffi/internal/convert.rb +17 -30
  36. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +2 -1
  37. data/lib/google/protobuf/ffi/map.rb +52 -26
  38. data/lib/google/protobuf/ffi/message.rb +188 -67
  39. data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
  40. data/lib/google/protobuf/ffi/object_cache.rb +3 -3
  41. data/lib/google/protobuf/ffi/oneof_descriptor.rb +13 -1
  42. data/lib/google/protobuf/ffi/repeated_field.rb +47 -19
  43. data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
  44. data/lib/google/protobuf/field_mask_pb.rb +2 -23
  45. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  46. data/lib/google/protobuf/message_exts.rb +4 -0
  47. data/lib/google/protobuf/plugin_pb.rb +3 -25
  48. data/lib/google/protobuf/repeated_field.rb +4 -5
  49. data/lib/google/protobuf/source_context_pb.rb +2 -23
  50. data/lib/google/protobuf/struct_pb.rb +2 -23
  51. data/lib/google/protobuf/timestamp_pb.rb +2 -23
  52. data/lib/google/protobuf/type_pb.rb +2 -25
  53. data/lib/google/protobuf/wrappers_pb.rb +2 -23
  54. data/lib/google/protobuf.rb +1 -1
  55. data/lib/google/protobuf_ffi.rb +6 -4
  56. data/lib/google/protobuf_native.rb +0 -1
  57. data/lib/google/tasks/ffi.rake +1 -3
  58. metadata +36 -21
  59. data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
  60. data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
  61. data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
  62. data/lib/google/protobuf/descriptor_dsl.rb +0 -465
  63. data/lib/google/protobuf/object_cache.rb +0 -97
@@ -21,7 +21,7 @@ module Google
21
21
  Upb_Map_Begin = -1
22
22
 
23
23
  ## Encoding Status
24
- Upb_Status_MaxMessage = 127
24
+ Upb_Status_MaxMessage = 511
25
25
  Upb_Encode_Deterministic = 1
26
26
  Upb_Encode_SkipUnknown = 2
27
27
 
@@ -36,6 +36,10 @@ module Google
36
36
  ## JSON Decoding options
37
37
  Upb_JsonDecode_IgnoreUnknown = 1
38
38
 
39
+ ## JSON Decoding results
40
+ Upb_JsonDecodeResult_Ok = 0
41
+ Upb_JsonDecodeResult_Error = 2
42
+
39
43
  typedef :pointer, :Array
40
44
  typedef :pointer, :DefPool
41
45
  typedef :pointer, :EnumValueDef
@@ -95,11 +99,6 @@ module Google
95
99
  :repeated
96
100
  )
97
101
 
98
- Syntax = enum(
99
- :Proto2, 2,
100
- :Proto3
101
- )
102
-
103
102
  # All the different kind of well known type messages. For simplicity of check,
104
103
  # number wrappers and string wrappers are grouped together. Make sure the
105
104
  # order and merber of these groups are not changed.
@@ -190,6 +189,8 @@ module Google
190
189
  :str_val, StringView
191
190
  end
192
191
 
192
+ Upb_Message_Begin = -1
193
+
193
194
  class MutableMessageValue < ::FFI::Union
194
195
  layout :map, :Map,
195
196
  :msg, :Message,
@@ -67,8 +67,9 @@ module Google
67
67
  @type ||= Google::Protobuf::FFI.get_type(self)
68
68
  end
69
69
 
70
+ # DEPRECATED: Use required? or repeated? instead.
70
71
  def label
71
- @label ||= Google::Protobuf::FFI::Label[Google::Protobuf::FFI.get_label(self)]
72
+ @label ||= Google::Protobuf::FFI.get_label(self)
72
73
  end
73
74
 
74
75
  def default
@@ -156,6 +157,14 @@ module Google
156
157
  @has_presence ||= Google::Protobuf::FFI.get_has_presence(self)
157
158
  end
158
159
 
160
+ ##
161
+ # Tests if this is a repeated field that uses packed encoding.
162
+ #
163
+ # @return [Boolean] True iff this field is packed
164
+ def is_packed?
165
+ @is_packed ||= Google::Protobuf::FFI.get_is_packed(self)
166
+ end
167
+
159
168
  # @param msg [Google::Protobuf::Message]
160
169
  def clear(msg)
161
170
  if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
@@ -189,6 +198,10 @@ module Google
189
198
  @map ||= Google::Protobuf::FFI.is_map self
190
199
  end
191
200
 
201
+ def required?
202
+ @required ||= Google::Protobuf::FFI.is_required self
203
+ end
204
+
192
205
  def repeated?
193
206
  @repeated ||= Google::Protobuf::FFI.is_repeated self
194
207
  end
@@ -211,7 +224,18 @@ module Google
211
224
  size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
212
225
  temporary_arena = Google::Protobuf::FFI.create_arena
213
226
  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)
227
+ opts = Google::Protobuf::FieldOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze)
228
+ opts.clear_features()
229
+ opts.freeze
230
+ end
231
+ end
232
+
233
+ def to_proto
234
+ @to_proto ||= begin
235
+ size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
236
+ temporary_arena = Google::Protobuf::FFI.create_arena
237
+ buffer = Google::Protobuf::FFI.field_to_proto(self, size_ptr, temporary_arena)
238
+ Google::Protobuf::FieldDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze)
215
239
  end
216
240
  end
217
241
 
@@ -304,7 +328,9 @@ module Google
304
328
  attach_function :get_default, :upb_FieldDef_Default, [FieldDescriptor], MessageValue.by_value
305
329
  attach_function :get_subtype_as_enum, :upb_FieldDef_EnumSubDef, [FieldDescriptor], EnumDescriptor
306
330
  attach_function :get_has_presence, :upb_FieldDef_HasPresence, [FieldDescriptor], :bool
331
+ attach_function :get_is_packed, :upb_FieldDef_IsPacked, [FieldDescriptor], :bool
307
332
  attach_function :is_map, :upb_FieldDef_IsMap, [FieldDescriptor], :bool
333
+ attach_function :is_required, :upb_FieldDef_IsRequired, [FieldDescriptor], :bool
308
334
  attach_function :is_repeated, :upb_FieldDef_IsRepeated, [FieldDescriptor], :bool
309
335
  attach_function :is_sub_message, :upb_FieldDef_IsSubMessage, [FieldDescriptor], :bool
310
336
  attach_function :get_json_name, :upb_FieldDef_JsonName, [FieldDescriptor], :string
@@ -314,6 +340,7 @@ module Google
314
340
  attach_function :get_number, :upb_FieldDef_Number, [FieldDescriptor], :uint32_t
315
341
  attach_function :get_type, :upb_FieldDef_Type, [FieldDescriptor], FieldType
316
342
  attach_function :file_def_by_raw_field_def, :upb_FieldDef_File, [:pointer], :FileDef
343
+ attach_function :field_to_proto, :FieldDescriptor_serialized_to_proto,[FieldDescriptor, :pointer, Internal::Arena], :pointer
317
344
  end
318
345
  end
319
346
  end
@@ -10,14 +10,40 @@ module Google
10
10
  class FFI
11
11
  # FileDescriptor
12
12
  attach_function :file_def_name, :upb_FileDef_Name, [:FileDef], :string
13
- attach_function :file_def_syntax, :upb_FileDef_Syntax, [:FileDef], Syntax
14
13
  attach_function :file_def_pool, :upb_FileDef_Pool, [:FileDef], :DefPool
15
14
  attach_function :file_options, :FileDescriptor_serialized_options, [:FileDef, :pointer, Internal::Arena], :pointer
15
+ attach_function :file_to_proto, :FileDescriptor_serialized_to_proto, [:FileDef, :pointer, Internal::Arena], :pointer
16
16
  end
17
17
 
18
18
  class FileDescriptor
19
19
  attr :descriptor_pool, :file_def
20
20
 
21
+ # FFI Interface methods and setup
22
+ extend ::FFI::DataConverter
23
+ native_type ::FFI::Type::POINTER
24
+
25
+ class << self
26
+ prepend Google::Protobuf::Internal::TypeSafety
27
+ include Google::Protobuf::Internal::PointerHelper
28
+
29
+ # @param value [FileDescriptor] FileDescriptor to convert to an FFI native type
30
+ # @param _ [Object] Unused
31
+ def to_native(value, _)
32
+ file_def_ptr = value.nil? ? nil : value.instance_variable_get(:@file_def)
33
+ return ::FFI::Pointer::NULL if file_def_ptr.nil?
34
+ raise "Underlying file_def was null!" if file_def_ptr.null?
35
+ file_def_ptr
36
+ end
37
+
38
+ ##
39
+ # @param file_def [::FFI::Pointer] FileDef pointer to be wrapped
40
+ # @param _ [Object] Unused
41
+ def from_native(file_def, _ = nil)
42
+ return nil if file_def.nil? or file_def.null?
43
+ descriptor_from_file_def(file_def)
44
+ end
45
+ end
46
+
21
47
  def initialize(file_def, descriptor_pool)
22
48
  @descriptor_pool = descriptor_pool
23
49
  @file_def = file_def
@@ -31,17 +57,6 @@ module Google
31
57
  "#{self.class.name}: #{name}"
32
58
  end
33
59
 
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
60
  def name
46
61
  Google::Protobuf::FFI.file_def_name(@file_def)
47
62
  end
@@ -51,7 +66,18 @@ module Google
51
66
  size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
52
67
  temporary_arena = Google::Protobuf::FFI.create_arena
53
68
  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)
69
+ opts = Google::Protobuf::FileOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze)
70
+ opts.clear_features()
71
+ opts.freeze
72
+ end
73
+ end
74
+
75
+ def to_proto
76
+ @to_proto ||= begin
77
+ size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
78
+ temporary_arena = Google::Protobuf::FFI.create_arena
79
+ buffer = Google::Protobuf::FFI.file_to_proto(@file_def, size_ptr, temporary_arena)
80
+ Google::Protobuf::FileDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze)
55
81
  end
56
82
  end
57
83
  end
@@ -12,8 +12,6 @@ module Google
12
12
  module Protobuf
13
13
  module Internal
14
14
  class Arena
15
- attr :pinned_messages
16
-
17
15
  # FFI Interface methods and setup
18
16
  extend ::FFI::DataConverter
19
17
  native_type ::FFI::Type::POINTER
@@ -46,10 +44,6 @@ module Google
46
44
  raise RuntimeError.new "Unable to fuse arenas. This should never happen since Ruby does not use initial blocks"
47
45
  end
48
46
  end
49
-
50
- def pin(message)
51
- pinned_messages.push message
52
- end
53
47
  end
54
48
  end
55
49
 
@@ -32,12 +32,15 @@ module Google
32
32
  raise TypeError.new "Invalid argument for boolean field '#{name}' (given #{value.class})." unless [TrueClass, FalseClass].include? value.class
33
33
  return_value[:bool_val] = value
34
34
  when :string
35
- raise TypeError.new "Invalid argument for string field '#{name}' (given #{value.class})." unless [Symbol, String].include? value.class
36
- begin
35
+ raise TypeError.new "Invalid argument for string field '#{name}' (given #{value.class})." unless value.is_a?(String) or value.is_a?(Symbol)
36
+ value = value.to_s if value.is_a?(Symbol)
37
+ if value.encoding == Encoding::UTF_8
38
+ unless value.valid_encoding?
39
+ raise Encoding::InvalidByteSequenceError.new "String is invalid UTF-8"
40
+ end
41
+ string_value = value
42
+ else
37
43
  string_value = value.to_s.encode("UTF-8")
38
- rescue Encoding::UndefinedConversionError
39
- # TODO - why not include the field name here?
40
- raise Encoding::UndefinedConversionError.new "String is invalid UTF-8"
41
44
  end
42
45
  return_value[:str_val][:size] = string_value.bytesize
43
46
  return_value[:str_val][:data] = Google::Protobuf::FFI.arena_malloc(arena, string_value.bytesize)
@@ -70,7 +73,7 @@ module Google
70
73
  case wkt
71
74
  when :Timestamp
72
75
  raise TypeError.new "Invalid type #{value.class} to assign to submessage field '#{name}'." unless value.kind_of? Time
73
- new_message = Google::Protobuf::FFI.new_message_from_def msg_or_enum_def, arena
76
+ new_message = Google::Protobuf::FFI.new_message_from_def Google::Protobuf::FFI.get_mini_table(msg_or_enum_def), arena
74
77
  sec = Google::Protobuf::FFI::MessageValue.new
75
78
  sec[:int64_val] = value.tv_sec
76
79
  sec_field_def = Google::Protobuf::FFI.get_field_by_number msg_or_enum_def, 1
@@ -82,7 +85,7 @@ module Google
82
85
  return_value[:msg_val] = new_message
83
86
  when :Duration
84
87
  raise TypeError.new "Invalid type #{value.class} to assign to submessage field '#{name}'." unless value.kind_of? Numeric
85
- new_message = Google::Protobuf::FFI.new_message_from_def msg_or_enum_def, arena
88
+ new_message = Google::Protobuf::FFI.new_message_from_def Google::Protobuf::FFI.get_mini_table(msg_or_enum_def), arena
86
89
  sec = Google::Protobuf::FFI::MessageValue.new
87
90
  sec[:int64_val] = value
88
91
  sec_field_def = Google::Protobuf::FFI.get_field_by_number msg_or_enum_def, 1
@@ -190,39 +193,23 @@ module Google
190
193
  def to_h_internal(msg, message_descriptor)
191
194
  return nil if msg.nil? or msg.null?
192
195
  hash = {}
193
- is_proto2 = Google::Protobuf::FFI.message_def_syntax(message_descriptor) == :Proto2
194
- message_descriptor.each do |field_descriptor|
195
- # TODO: Legacy behavior, remove when we fix the is_proto2 differences.
196
- if !is_proto2 and
197
- field_descriptor.sub_message? and
198
- !field_descriptor.repeated? and
199
- !Google::Protobuf::FFI.get_message_has(msg, field_descriptor)
200
- hash[field_descriptor.name.to_sym] = nil
201
- next
202
- end
203
-
204
- # Do not include fields that are not present (oneof or optional fields).
205
- if is_proto2 and field_descriptor.has_presence? and !Google::Protobuf::FFI.get_message_has(msg, field_descriptor)
206
- next
207
- end
196
+ iter = ::FFI::MemoryPointer.new(:size_t, 1)
197
+ iter.write(:size_t, Google::Protobuf::FFI::Upb_Message_Begin)
198
+ message_value = Google::Protobuf::FFI::MessageValue.new
199
+ field_def_ptr = ::FFI::MemoryPointer.new :pointer
208
200
 
209
- message_value = Google::Protobuf::FFI.get_message_value msg, field_descriptor
201
+ while Google::Protobuf::FFI::message_next(msg, message_descriptor, nil, field_def_ptr, message_value, iter) do
202
+ field_descriptor = FieldDescriptor.from_native field_def_ptr.get_pointer(0)
210
203
 
211
- # Proto2 omits empty map/repeated fields also.
212
204
  if field_descriptor.map?
213
205
  hash_entry = map_create_hash(message_value[:map_val], field_descriptor)
214
206
  elsif field_descriptor.repeated?
215
- array = message_value[:array_val]
216
- if is_proto2 and (array.null? || Google::Protobuf::FFI.array_size(array).zero?)
217
- next
218
- end
219
- hash_entry = repeated_field_create_array(array, field_descriptor, field_descriptor.type)
207
+ hash_entry = repeated_field_create_array(message_value[:array_val], field_descriptor, field_descriptor.type)
220
208
  else
221
209
  hash_entry = scalar_create_hash(message_value, field_descriptor.type, field_descriptor: field_descriptor)
222
210
  end
223
211
 
224
212
  hash[field_descriptor.name.to_sym] = hash_entry
225
-
226
213
  end
227
214
 
228
215
  hash
@@ -13,7 +13,8 @@ module Google
13
13
  # the pool, and either retrieve the wrapper object for the given pointer
14
14
  # or create one. Assumes that the caller is the wrapper class for the
15
15
  # given pointer and that it implements `private_constructor`.
16
- def descriptor_from_file_def(file_def, pointer)
16
+ def descriptor_from_file_def(file_def, pointer = nil)
17
+ pointer = file_def if pointer.nil?
17
18
  raise RuntimeError.new "FileDef is nil" if file_def.nil?
18
19
  raise RuntimeError.new "FileDef is null" if file_def.null?
19
20
  pool_def = Google::Protobuf::FFI.file_def_pool file_def
@@ -9,18 +9,20 @@ module Google
9
9
  module Protobuf
10
10
  class FFI
11
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
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
18
20
 
19
21
  # 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
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
24
26
  end
25
27
  class Map
26
28
  include Enumerable
@@ -155,6 +157,37 @@ module Google
155
157
  end
156
158
  alias size length
157
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
+
158
191
  ##
159
192
  # call-seq:
160
193
  # Map.dup => new_map
@@ -199,8 +232,8 @@ module Google
199
232
  def hash
200
233
  return_value = 0
201
234
  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)
235
+ return_value += Google::Protobuf::FFI.message_value_hash(key_message_value, key_type, nil, 0)
236
+ return_value += Google::Protobuf::FFI.message_value_hash(value_message_value, value_type, descriptor, 0)
204
237
  end
205
238
  return_value
206
239
  end
@@ -269,17 +302,6 @@ module Google
269
302
 
270
303
  include Google::Protobuf::Internal::Convert
271
304
 
272
- def internal_deep_freeze
273
- freeze
274
- if value_type == :message
275
- internal_iterator do |iterator|
276
- value_message_value = Google::Protobuf::FFI.map_value(@map_ptr, iterator)
277
- convert_upb_to_ruby(value_message_value, value_type, descriptor, arena).send :internal_deep_freeze
278
- end
279
- end
280
- self
281
- end
282
-
283
305
  def internal_iterator
284
306
  iter = ::FFI::MemoryPointer.new(:size_t, 1)
285
307
  iter.write(:size_t, Google::Protobuf::FFI::Upb_Map_Begin)
@@ -369,10 +391,14 @@ module Google
369
391
  OBJECT_CACHE.try_add(@map_ptr.address, self)
370
392
  end
371
393
 
372
- # @param field [FieldDescriptor] Descriptor of the field where the RepeatedField will be assigned
373
- # @param values [Hash|Map] Initial value; may be nil or empty
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
374
398
  # @param arena [Arena] Owning message's arena
375
- def self.construct_for_field(field, arena, value: nil, map: nil)
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)
376
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
377
403
  instance = allocate
378
404
  raise ArgumentError.new "Expected field with type :message, instead got #{field.class}" unless field.type == :message