anchor.diff:      FNames = get_field_names(MsgDef),
       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),
       {EncodeExprs, _} =
           lists:mapfoldl(
             fun({NewBVar, Field, FVar}, PrevBVar) when NewBVar /= last ->
  -                  EncExpr = field_encode_expr(MsgName, Field, FVar, PrevBVar),
  +                  EncExpr = field_encode_expr(MsgName, MsgVar, Field, FVar,
  +                                              PrevBVar, Opts),
                     E = ?expr('<NewB>' = '<encode-expr>',
                               [replace_tree('<NewB>', NewBVar),
                                replace_tree('<encode-expr>', EncExpr)]),
                     {E, NewBVar};
                ({last, Field, FVar}, PrevBVar) ->
  -                  EncExpr = field_encode_expr(MsgName, Field, FVar, PrevBVar),
  +                  EncExpr = field_encode_expr(MsgName, MsgVar, Field, FVar,
  +                                              PrevBVar, Opts),
                     {EncExpr, dummy}
             end,
             ?expr(Bin),
             lists:zip3(BVars, MsgDef, FVars)),
       FnName = mk_fn(e_msg_, MsgName),
  +    FieldMatching =
  +        case get_mapping_and_unset_by_opts(Opts) of
  +            X when X == records;
  +                   X == {maps, present_undefined} ->
  +                mapping_match(MsgName, lists:zip(FNames, FVars), Opts);
  +            {maps, omitted} ->
  +                FMap = zip_for_non_opt_fields(MsgDef, FVars),
  +                if length(FMap) == length(FNames) ->
  +                        map_match(FMap);
  +                   length(FMap) < length(FNames) ->
  +                        ?expr('mapmatch' = 'M',
  +                              [replace_tree('mapmatch', map_match(FMap)),
  +                               replace_tree('M', MsgVar)])
  +                end
  +        end,
       [gpb_codegen:format_fn(
          FnName,
          fun(Msg) ->
  
positive.code:        fun('<msg-matching>', Bin) ->
                 '<encode-param-exprs>'
         end,
         [replace_tree('<msg-matching>',
                       mapping_match(MsgName, lists:zip(FNames, FVars), Opts)),
          splice_trees('<encode-param-exprs>', EncodeExprs)])].
  
  get_field_names(MsgDef) ->
  
negative.code:         true  -> maps
      end.
  
  get_mapping_and_unset_by_opts(Opts) ->
      case get_records_or_maps_by_opts(Opts) of
          records ->
              records;
          maps ->
              Default = present_undefined,
              {maps, proplists:get_value(maps_unset_optional, Opts, Default)}
      end.
  
  %% records
  record_match(RName, Fields) -> record_create_or_match(RName, Fields).
  