anchor.diff:      NeedsFixed64  = needs_f_enc(fixed64, AnRes),
       NeedsSFixed64 = needs_f_enc(sfixed64, AnRes),
       NeedsDouble   = needs_f_enc(double, AnRes),
  -    [[format_fixed_encoder(fixed32,  32, 'little')        || NeedsFixed32],
  -     [format_fixed_encoder(sfixed32, 32, 'little-signed') || NeedsSFixed32],
  -     [format_fixed_encoder(float,    32, 'little-float')  || NeedsFloat],
  -     [format_fixed_encoder(fixed64,  64, 'little')        || NeedsFixed64],
  -     [format_fixed_encoder(sfixed64, 64, 'little-signed') || NeedsSFixed64],
  -     [format_fixed_encoder(double,   64, 'little-float')  || NeedsDouble]].
  +    [[format_fixed_encoder(fixed32,  32, [little])        || NeedsFixed32],
  +     [format_fixed_encoder(sfixed32, 32, [little,signed]) || NeedsSFixed32],
  +     [format_fixed_encoder(float,    32, [little,float])  || NeedsFloat],
  +     [format_fixed_encoder(fixed64,  64, [little])        || NeedsFixed64],
  +     [format_fixed_encoder(sfixed64, 64, [little,signed]) || NeedsSFixed64],
  +     [format_fixed_encoder(double,   64, [little,float])  || NeedsDouble]].
   
   needs_f_enc(FixedType, #anres{used_types=UsedTypes, fixlen_types=FTypes}) ->
       %% If a fixlength-type occurs _only_ as a packed repeated field,
  
positive.code: possibly_format_mfield_encoder(MsgName, #field{type={msg,SubMsg}}=FieldDef,
                                 AnRes) ->
      FnName = mk_field_encode_fn_name(MsgName, FieldDef),
      case is_msgsize_known_at_compiletime(SubMsg, AnRes) of
          no ->
              [f("~p(Msg, Bin) ->~n", [FnName]),
               f("    SubBin = ~p(Msg, <<>>),~n", [mk_fn(e_msg_, SubMsg)]),
               f("    Bin2 = e_varint(byte_size(SubBin), Bin),~n"),
               f("    <<Bin2/binary, SubBin/binary>>.~n~n")];
          {yes, MsgSize} when MsgSize > 0 ->
              MsgSizeTxt = varint_to_byte_text(MsgSize),
              [f("~p(Msg, Bin) ->~n", [FnName]),
               f("    Bin2 = <<Bin/binary, ~s>>,~n", [MsgSizeTxt]),
               f("    ~p(Msg, Bin2).~n~n", [mk_fn(e_msg_, SubMsg)])];
          {yes, 0} ->
              %% special case, there will not be any e_msg_<MsgName>/2 function
              %% generated, so don't call it.
              [f("~p(_Msg, Bin) ->~n", [FnName]),
               f("    <<Bin/binary, 0>>.~n~n")]
      end;
  possibly_format_mfield_encoder(_MsgName, _FieldDef, _Defs) ->
      [].
  
  is_msgsize_known_at_compiletime(MsgName, #anres{known_msg_size=MsgSizes}) ->
      case dict:fetch(MsgName, MsgSizes) of
          MsgSize when is_integer(MsgSize) ->
              {yes, MsgSize};
  
negative.code:     FnName = mk_field_encode_fn_name(MsgName, FDef),
      ElemEncoderFn = mk_field_encode_fn_name(MsgName,
                                              FDef#field{occurrence=required}),
      KeyBytes = key_to_binary_fields(FNum, Type),
      gpb_codegen:format_fn(
        FnName,
        fun([Elem | Rest], Bin) ->
                Bin2 = <<Bin/binary, '<KeyBytes>'>>,
                Bin3 = '<encode-elem>'(Elem, Bin2),
                call_self(Rest, Bin3);
           ([], Bin) ->
                Bin
        end,
        [splice_trees('<KeyBytes>', KeyBytes),
         replace_term('<encode-elem>', ElemEncoderFn)]).
  
  format_packed_field_encoder2(MsgName, #field{type=Type}=FDef) ->
      case packed_byte_size_can_be_computed(Type) of
          {yes, BitLen, BitType} ->
              format_knownsize_packed_field_encoder2(MsgName, FDef,
                                                     BitLen, BitType);
          no ->
              format_unknownsize_packed_field_encoder2(MsgName, FDef)
      end.
  
  packed_byte_size_can_be_computed(fixed32)  -> {yes, 32, [little]};
  packed_byte_size_can_be_computed(sfixed32) -> {yes, 32, [little,signed]};
  packed_byte_size_can_be_computed(float)    -> {yes, 32, [little,float]};
  packed_byte_size_can_be_computed(fixed64)  -> {yes, 64, [little]};
  packed_byte_size_can_be_computed(sfixed64) -> {yes, 64, [little,signed]};
  packed_byte_size_can_be_computed(double)   -> {yes, 64, [little,float]};
  packed_byte_size_can_be_computed(_)        -> no.
  
  format_knownsize_packed_field_encoder2(MsgName, #field{name=FName,
                                                         fnum=FNum}=FDef,
                                        BitLen, BitType) ->
      FnName = mk_field_encode_fn_name(MsgName, FDef),
      KeyBytes = key_to_binary_fields(FNum, bytes),
      PackedFnName = mk_fn(e_pfield_, MsgName, FName),
      [gpb_codegen:format_fn(
         FnName,
         fun(Elems, Bin) when Elems =/= [] ->
                 Bin2 = <<Bin/binary, '<KeyBytes>'>>,
                 Bin3 = e_varint(length(Elems) * '<ElemLen>', Bin2),
                 '<encode-packed>'(Elems, Bin3);
            ([], Bin) ->
                 Bin
         end,
         [splice_trees('<KeyBytes>', KeyBytes),
          replace_term('<ElemLen>', BitLen div 8),
          replace_term('<encode-packed>', PackedFnName)]),
       gpb_codegen:format_fn(
         PackedFnName,
         fun([Value | Rest], Bin) ->
                 Bin2 = <<Bin/binary, Value:'<Size>'/'<BitType>'>>,
                 call_self(Rest, Bin2);
            ([], Bin) ->
                 Bin
         end,
         [replace_term('<Size>', BitLen),
          splice_trees('<BitType>', [erl_syntax:atom(T) || T <- BitType])])].
  
  format_unknownsize_packed_field_encoder2(MsgName, #field{name=FName,
                                                           fnum=FNum}=FDef) ->
      FnName = mk_field_encode_fn_name(MsgName, FDef),
      ElemEncoderFn = mk_field_encode_fn_name(MsgName,
                                              FDef#field{occurrence=required}),
      KeyBytes = key_to_binary_fields(FNum, bytes),
      PackedFnName = mk_fn(e_pfield_, MsgName, FName),
      [gpb_codegen:format_fn(
         FnName,
         fun(Elems, Bin) when Elems =/= [] ->
                 SubBin = '<encode-packed>'(Elems, <<>>),
                 Bin2 = <<Bin/binary, '<KeyBytes>'>>,
                 Bin3 = e_varint(byte_size(SubBin), Bin2),
                 <<Bin3/binary, SubBin/binary>>;
            ([], Bin) ->
                 Bin
         end,
         [splice_trees('<KeyBytes>', KeyBytes),
          replace_term('<encode-packed>', PackedFnName)]),
       gpb_codegen:format_fn(
         PackedFnName,
         fun([Value | Rest], Bin) ->
                 Bin2 = '<encode-elem>'(Value, Bin),
                 call_self(Rest, Bin2);
            ([], Bin) ->
                 Bin
         end,
         [replace_term('<encode-elem>', ElemEncoderFn)])].
  
  format_type_encoders(AnRes) ->
      [format_varlength_field_encoders(AnRes),
  