anchor.diff:  format_unknownsize_packed_field_encoder2(MsgName,
                                            #?gpb_field{name=FName,
                                                        fnum=FNum}=FDef,
  -                                        AnRes) ->
  +                                         AnRes) ->
       FnName = mk_field_encode_fn_name(MsgName, FDef),
       ElemEncoderFn = mk_field_encode_fn_name(
  -                      MsgName, FDef#?gpb_field{occurrence=required}),
  +                      MsgName,
  +                      FDef#?gpb_field{occurrence=required}),
       KeyBytes = key_to_binary_fields(FNum, bytes),
       PackedFnName = mk_fn(e_pfield_, MsgName, FName),
       ElemPath = [MsgName,FName,[]],
       Transl = find_translation(ElemPath, encode, AnRes),
       [gpb_codegen:format_fn(
          FnName,
  -       fun(Elems, Bin) when Elems =/= [] ->
  -               SubBin = '<encode-packed>'(Elems, <<>>),
  +       fun(Elems, Bin, TrUserData) when Elems =/= [] ->
  +               SubBin = '<encode-packed>'(Elems, <<>>, TrUserData),
                  Bin2 = <<Bin/binary, '<KeyBytes>'>>,
                  Bin3 = e_varint(byte_size(SubBin), Bin2),
                  <<Bin3/binary, SubBin/binary>>;
  -          ([], Bin) ->
  +          ([], Bin, _TrUserData) ->
                  Bin
          end,
          [splice_trees('<KeyBytes>', KeyBytes),
           replace_term('<encode-packed>', PackedFnName)]),
        gpb_codegen:format_fn(
          PackedFnName,
  -       fun([Value | Rest], Bin) ->
  -               Bin2 = '<encode-elem>'('Tr'(Value), Bin),
  -               call_self(Rest, Bin2);
  -          ([], Bin) ->
  +       fun([Value | Rest], Bin, TrUserData) ->
  +               Bin2 = '<encode-elem>'('Tr'(Value, TrUserData), Bin,
  +                                      'MaybeTrUserData'),
  +               call_self(Rest, Bin2, TrUserData);
  +          ([], Bin, _TrUserData) ->
                  Bin
          end,
          [replace_term('<encode-elem>', ElemEncoderFn),
  -        replace_term('Tr', Transl)])].
  +        replace_term('Tr', Transl),
  +        splice_trees('MaybeTrUserData',
  +                     maybe_userdata_param(FDef, ?expr(TrUserData)))])].
   
   format_type_encoders(AnRes) ->
       [format_varlength_field_encoders(AnRes),
  
positive.code:        encode_msg,
         fun(Msg, '<MsgName>', '<Opts>') ->
                 '<possibly-verify-msg>',
                 case '<MsgOrMsgName>' of
                     '<msg-match>' -> 'encode'(Msg)
                 end
         end,
         [replace_tree('<Opts>', case Verify of
                                     optionally -> ?expr(Opts);
                                     always     -> ?expr(_Opts);
                                     never      -> ?expr(_Opts)
                                 end),
          splice_trees('<possibly-verify-msg>',
                       case Verify of
  
negative.code:     FVars = [var_f_n(I) || I <- lists:seq(1, length(FNames))],
      BVars = [var_b_n(I) || I <- lists:seq(1, length(FNames)-1)] ++ [last],
      MsgVar = ?expr(M),
      TrUserDataVar = ?expr(TrUserData),
      {EncodeExprs, _} =
          lists:mapfoldl(
            fun({NewBVar, Field, FVar}, PrevBVar) when NewBVar /= last ->
                    Tr = mk_find_tr_fn(MsgName, Field, AnRes),
                    EncExpr = field_encode_expr(MsgName, MsgVar, Field, FVar,
                                                PrevBVar, TrUserDataVar,
                                                Defs, Tr, AnRes, Opts,
                                                p3_check_typedefaults),
                    E = ?expr('<NewB>' = '<encode-expr>',
                              [replace_tree('<NewB>', NewBVar),
  