@@ -63,17 +63,38 @@ defmodule Protox.DefineDecoder do
6363 make_parse_key_value_body ( fields , vars , opts )
6464
6565 unknown_fields_name = Keyword . fetch! ( opts , :unknown_fields_name )
66+ finish_decode = make_finish_decode ( fields , vars . msg , unknown_fields_name )
6667
6768 quote do
6869 @ spec parse_key_value ( binary ( ) , struct ( ) ) :: struct ( )
6970 defp parse_key_value ( << >> , msg ) do
70- % { msg | unquote ( unknown_fields_name ) => Enum . reverse ( msg . unquote ( unknown_fields_name ) ) }
71+ unquote ( finish_decode )
7172 end
7273
7374 defp parse_key_value ( bytes , msg ) , do: unquote ( parse_key_value_body )
7475 end
7576 end
7677
78+ defp make_finish_decode ( fields , msg_var , unknown_fields_name ) do
79+ repeated_field_names =
80+ fields
81+ |> Enum . filter ( & ( & 1 . kind in [ :packed , :unpacked ] ) )
82+ |> Enum . map ( & & 1 . name )
83+ |> Enum . uniq ( )
84+
85+ updates =
86+ Enum . map ( repeated_field_names , fn field_name ->
87+ { field_name , quote ( do: Enum . reverse ( unquote ( msg_var ) . unquote ( field_name ) ) ) }
88+ end ) ++
89+ [
90+ { unknown_fields_name , quote ( do: Enum . reverse ( unquote ( msg_var ) . unquote ( unknown_fields_name ) ) ) }
91+ ]
92+
93+ quote do
94+ % { unquote ( msg_var ) | unquote_splicing ( updates ) }
95+ end
96+ end
97+
7798 defp make_parse_key_value_body ( fields , vars , opts ) do
7899 # Fragment to parse unknown fields. Those are identified with an unknown tag.
79100 unknown_tag_clause =
@@ -312,6 +333,19 @@ defmodule Protox.DefineDecoder do
312333 quote ( do: { unquote ( field . name ) , unquote ( value ) } )
313334 end
314335
336+ defp make_update_field ( value , % Field { kind: kind } = field , vars , wrap_value ) when kind in [ :packed , :unpacked ] do
337+ update_value =
338+ if wrap_value do
339+ quote ( do: [ unquote ( value ) | unquote ( vars . msg ) . unquote ( field . name ) ] )
340+ else
341+ quote ( do: Enum . reverse ( unquote ( value ) , unquote ( vars . msg ) . unquote ( field . name ) ) )
342+ end
343+
344+ quote do
345+ { unquote ( field . name ) , unquote ( update_value ) }
346+ end
347+ end
348+
315349 defp make_update_field ( value , % Field { } = field , vars , wrap_value ) do
316350 value = maybe_wrap ( value , wrap_value )
317351
0 commit comments