Class: Protobug::Field::MapField

Inherits:
MessageField show all
Defined in:
lib/protobug/field.rb

Constant Summary collapse

SUPER_INITIALIZE =
instance_method(:initialize).super_method

Constants inherited from Protobug::Field

PACKABLE_WIRE_TYPES

Instance Attribute Summary

Attributes inherited from MessageField

#message_type

Attributes inherited from Protobug::Field

#adder, #cardinality, #clearer, #haser, #ivar, #json_name, #name, #number, #oneof, #setter

Instance Method Summary collapse

Methods inherited from MessageField

#binary_decode_one, #binary_encode_one, #json_decode_one, #json_encode_one, #wire_type

Methods inherited from Protobug::Field

#binary_decode, #json_key_encode, #method_definitions, #optional?, #packed?, #pretty_print, #proto3_optional?, #to_text, #validate!

Constructor Details

#initialize(number, name, key_type:, value_type:, json_name: name, oneof: nil, enum_type: nil, message_type: nil) ⇒ MapField

rubocop:disable Lint/MissingSuper,



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/protobug/field.rb', line 275

def initialize(number, name, key_type:, value_type:, json_name: name, oneof: nil, # rubocop:disable Lint/MissingSuper,
               enum_type: nil, message_type: nil)
  SUPER_INITIALIZE.bind_call(
    self, number, name,
    cardinality: :repeated,
    json_name: json_name,
    oneof: oneof
  )

  @map_class = Class.new do
    extend Protobug::Message

    optional(1, "key", type: key_type, proto3_optional: false)
    value_type_kwargs = { enum_type: enum_type, message_type: message_type }
    value_type_kwargs.compact!
    optional(2, "value", type: value_type, **value_type_kwargs, proto3_optional: false)
  end
end

Instance Method Details

#adder_method_definition(str) ⇒ Object



351
352
353
354
355
356
357
358
359
360
# File 'lib/protobug/field.rb', line 351

def adder_method_definition(str)
  str << "def #{adder}(msg)\n"
  str << "  existing = #{ivar}\n"
  str << "  if ::Protobug::UNSET == existing\n"
  str << "    existing = {}\n"
  str << "    #{ivar} = existing\n"
  str << "  end\n"
  str << "  existing[msg.key] = msg.value\n"
  str << "end\n"
end

#binary_encode(value, outbuf) ⇒ Object



306
307
308
309
310
311
312
313
# File 'lib/protobug/field.rb', line 306

def binary_encode(value, outbuf)
  value.each_with_object(@map_class.new) do |(k, v), entry|
    entry.key = k
    entry.value = v
    BinaryEncoding.encode_varint (number << 3) | wire_type, outbuf
    BinaryEncoding.encode_length @map_class.encode(entry), outbuf
  end
end

#defaultObject



298
299
300
# File 'lib/protobug/field.rb', line 298

def default
  {}
end

#json_decode(value, message, ignore_unknown_fields, registry) ⇒ Object



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/protobug/field.rb', line 322

def json_decode(value, message, ignore_unknown_fields, registry)
  return if value.nil?

  unless value.is_a?(Hash)
    raise DecodeError,
          "expected Hash for #{inspect}, got #{value.inspect}"
  end

  value.each do |k, v|
    entry = @map_class.decode_json_hash(
      { "key" => k, "value" => v },
      registry: registry,
      ignore_unknown_fields: ignore_unknown_fields
    )
    # can't use haser because default values should also be counted...
    if UNSET == entry.instance_variable_get(:@value)
      next if ignore_unknown_fields && @map_class.fields_by_name.fetch("value").is_a?(EnumField)

      raise DecodeError, "nil values are not allowed in map #{name} in #{message.class}"
    end

    message.send(adder, entry)
  end
end

#json_encode(value, print_unknown_fields:) ⇒ Object



315
316
317
318
319
320
# File 'lib/protobug/field.rb', line 315

def json_encode(value, print_unknown_fields:)
  value.to_h do |k, v|
    value = @map_class.fields_by_name["value"].json_encode(v, print_unknown_fields: print_unknown_fields)
    [json_key_encode(k), value]
  end
end

#repeatedObject



294
295
296
# File 'lib/protobug/field.rb', line 294

def repeated
  true
end

#repeated?Boolean

Returns:

  • (Boolean)


302
303
304
# File 'lib/protobug/field.rb', line 302

def repeated?
  true
end

#type_lookup(_registry) ⇒ Object



347
348
349
# File 'lib/protobug/field.rb', line 347

def type_lookup(_registry)
  @map_class
end