anchor.diff:                SubMsgNames).
   
   format_sint_encoder() ->
  -    [f("e_type_sint(Value, Bin) when Value >= 0 ->~n"),
  -     f("    e_varint(Value * 2, Bin);~n"),
  -     f("e_type_sint(Value, Bin) ->~n"),
  -     f("    e_varint(Value * -2 - 1, Bin).~n~n")].
  +    gpb_codegen:format_fn(
  +      e_type_sint,
  +      fun(Value, Bin) when Value >= 0 ->
  +              e_varint(Value * 2, Bin);
  +         (Value, Bin) ->
  +              e_varint(Value * -2 - 1, Bin)
  +      end).
   
   format_int_encoder(Type, BitLen) ->
  -    FnName = mk_fn(e_type_, Type),
  -    [f("~p(Value, Bin) when 0 =< Value, Value =< 127 ->~n", [FnName]),
  -     f("    <<Bin/binary, Value>>; %% fast path~n"),
  -     f("~p(Value, Bin) ->~n", [FnName]),
  -     f("    <<N:~w/unsigned-native>> = <<Value:~w/signed-native>>,~n",
  -       [BitLen, BitLen]),
  -     f("    e_varint(N, Bin).~n~n")].
  +    gpb_codegen:format_fn(
  +      mk_fn(e_type_, Type),
  +      fun(Value, Bin) when 0 =< Value, Value =< 127 ->
  +              <<Bin/binary, Value>>; %% fast path
  +         (Value, Bin) ->
  +              <<N:'<Sz>'/unsigned-native>> = <<Value:'<Sz>'/signed-native>>,
  +              e_varint(N, Bin)
  +      end,
  +      [replace_term('<Sz>', BitLen)]).
   
   format_bool_encoder() ->
  -    [f("e_type_bool(true, Bin)  -> <<Bin/binary, 1>>;~n"),
  -     f("e_type_bool(false, Bin) -> <<Bin/binary, 0>>.~n~n")].
  +    gpb_codegen:format_fn(
  +      e_type_bool,
  +      fun(true, Bin)  -> <<Bin/binary, 1>>;
  +         (false, Bin) -> <<Bin/binary, 0>>
  +      end).
   
   format_fixed_encoder(Type, BitLen, BitType) ->
  -    FnName = mk_fn(e_type_, Type),
  -    [f("~p(Value, Bin) ->~n", [FnName]),
  -     f("    <<Bin/binary, Value:~p/~s>>.~n~n", [BitLen, BitType])].
  +    gpb_codegen:format_fn(
  +      mk_fn(e_type_, Type),
  +      fun(Value, Bin) ->
  +              <<Bin/binary, Value:'<Sz>'/'<T>'>>
  +      end,
  +      [replace_term('<Sz>', BitLen),
  +       splice_trees('<T>', [erl_syntax:atom(T) || T <- BitType])]).
   
   format_string_encoder() ->
  -    [f("e_type_string(S, Bin) ->~n"),
  -     f("    Utf8 = unicode:characters_to_binary(S),~n"),
  -     f("    Bin2 = e_varint(byte_size(Utf8), Bin),~n"),
  -     f("    <<Bin2/binary, Utf8/binary>>.~n~n")].
  +    gpb_codegen:format_fn(
  +      e_type_string,
  +      fun(S, Bin) ->
  +              Utf8 = unicode:characters_to_binary(S),
  +              Bin2 = e_varint(byte_size(Utf8), Bin),
  +              <<Bin2/binary, Utf8/binary>>
  +      end).
   
   format_bytes_encoder() ->
  -    [f("e_type_bytes(Bytes, Bin) ->~n"),
  -     f("    Bin2 = e_varint(byte_size(Bytes), Bin),~n"),
  -     f("    <<Bin2/binary, Bytes/binary>>.~n~n")].
  +    gpb_codegen:format_fn(
  +      e_type_bytes,
  +      fun(Bytes, Bin) ->
  +              Bin2 = e_varint(byte_size(Bytes), Bin),
  +              <<Bin2/binary, Bytes/binary>>
  +      end).
   
   format_varint_encoder() ->
  -    [f("e_varint(N, Bin) when N =< 127 ->~n"),
  -     f("    <<Bin/binary, N>>;~n"),
  -     f("e_varint(N, Bin) ->~n"),
  -     f("    Bin2 = <<Bin/binary, (N band 127 bor 128)>>,~n"),
  -     f("    e_varint(N bsr 7, Bin2).~n~n")].
  +    gpb_codegen:format_fn(
  +      e_varint,
  +      fun(N, Bin) when N =< 127 ->
  +              <<Bin/binary, N>>;
  +         (N, Bin) ->
  +              Bin2 = <<Bin/binary, (N band 127 bor 128)>>,
  +              call_self(N bsr 7, Bin2)
  +      end).
   
   %% -- decoders -----------------------------------------------------
   
  
positive.code:     [erl_syntax:binary_field(?expr('<n>', [replace_term('<n>', N)]), [])
       || N <- binary_to_list(gpb:encode_varint(IntValue))].
  
  varint_to_byte_text(N) ->
      Bin = gpb:encode_varint(N),
      string:join([integer_to_list(B) || <<B:8>> <= Bin], ",").
  
  format_msg_encoders(Defs) ->
      [format_msg_encoder(MsgName, MsgDef) || {{msg, MsgName}, MsgDef} <- Defs].
  
  
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),
  