@@ -233,8 +233,17 @@ defmodule Protobuf.Decoder do
233233 % FieldProps { type: type , map?: map? , oneof: oneof , name_atom: name_atom , repeated?: repeated? } =
234234 prop
235235
236- embedded_msg = decode ( bin , type )
237- val = if map? , do: % { embedded_msg . key => embedded_msg . value } , else: embedded_msg
236+ embed_msg = decode ( bin , type )
237+
238+ val =
239+ if map? do
240+ key = if is_nil ( embed_msg . key ) , do: map_default ( prop , :key ) , else: embed_msg . key
241+ value = if is_nil ( embed_msg . value ) , do: map_default ( prop , :value ) , else: embed_msg . value
242+ % { key => value }
243+ else
244+ embed_msg
245+ end
246+
238247 val = if oneof , do: { name_atom , val } , else: val
239248
240249 cond do
@@ -255,6 +264,15 @@ defmodule Protobuf.Decoder do
255264 end
256265 end
257266
267+ defp map_default ( prop , key_or_value ) do
268+ prop . type . __message_props__ ( ) . field_props
269+ |> Enum . find ( fn { _key , field_props } -> field_props . name_atom == key_or_value end )
270+ |> then ( fn { _key , field_props } ->
271+ # Conformance only works when we use proto3 defaults here, even for proto2...
272+ Protobuf.DSL . field_default ( :proto3 , field_props )
273+ end )
274+ end
275+
258276 defp deep_merge ( _oneof1 = { tag1 , val1 } , oneof2 = { tag2 , val2 } , props ) do
259277 if tag1 == tag2 do
260278 # If the field is a oneof, we merge its value and keep the tag.
0 commit comments