@@ -233,8 +233,17 @@ defmodule Protobuf.Decoder do
233
233
% FieldProps { type: type , map?: map? , oneof: oneof , name_atom: name_atom , repeated?: repeated? } =
234
234
prop
235
235
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
+
238
247
val = if oneof , do: { name_atom , val } , else: val
239
248
240
249
cond do
@@ -255,6 +264,15 @@ defmodule Protobuf.Decoder do
255
264
end
256
265
end
257
266
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
+
258
276
defp deep_merge ( _oneof1 = { tag1 , val1 } , oneof2 = { tag2 , val2 } , props ) do
259
277
if tag1 == tag2 do
260
278
# If the field is a oneof, we merge its value and keep the tag.
0 commit comments