anchor.diff:    ?f("-type '~s'() :: ~s.", [Enum,
       string:join(["'"++atom_to_list(EName)++"'" || {EName, _} <- Enumeration], " | ")]).
   
  -format_export_types(false, _Defs) -> "";
  -format_export_types(true, Defs) ->
  +format_record_typespec(records, Msg, _Fields, _Defs) ->
  +  ?f("-type '~s'() :: #~s{}.", [Msg, Msg]);
  +format_record_typespec(maps, Msg, Fields, Defs) ->
  +  ?f("-type '~s'() :: ~n"
  +     "      #{~s~n"
  +     "       }.",
  +      [Msg, outdent_first(format_hfields(7 + 1, Fields,
  +                                         [{maps, true}, {type_specs, true}], Defs))]).
  +
  +format_export_types(false, _, _Defs) -> "";
  +format_export_types(true, MapsOrRecords, Defs) ->
     iolist_to_binary(
  -    [string:join([format_enum_typespec(Enum, Enumeration)
  +    ["%% enumerate types\n",
  +     string:join([format_enum_typespec(Enum, Enumeration)
                       || {{enum, Enum}, Enumeration} <- Defs],
                   "\n"),
       "\n",
        ?f("-export_type([~s]).",
  -        [string:join(["'"++atom_to_list(Enum)++"'/0" || {{enum, Enum}, _} <- Defs], ", ")]),
  +        [string:join(["'"++atom_to_list(Enum)++"'/0"
  +                    || {{enum, Enum}, _} <- Defs], ", ")]),
  +    "\n\n",
  +    "%% message types\n",
  +    string:join([format_record_typespec(MapsOrRecords, Msg, Fields, Defs)
  +                    || {{msg, Msg}, Fields} <- Defs],
  +                "\n"),
  +    "\n",
  +     ?f("-export_type([~s]).",
  +        [string:join(["'"++atom_to_list(Msg)++"'/0"
  +                    || {{msg, Msg}, _} <- Defs], ", ")]),
        "\n"]).
   
   %% -- hrl -----------------------------------------------------
  
positive.code:                         PossibleNifCode,Opts,Reason})
               end
               || Ts <- FormToks],
      {AttrForms, CodeForms} = split_forms_at_first_code(Forms),
      FieldDef = field_record_to_attr_form(),
      OneofDef = oneof_record_to_attr_form(),
      RpcDef   = rpc_record_to_attr_form(),
      RecordBaseDefs = [FieldDef, OneofDef, RpcDef],
      MsgRecordForms = msgdefs_to_record_attrs(MsgDefs),
      AllForms = AttrForms ++ RecordBaseDefs ++ MsgRecordForms ++ CodeForms,
      combine_erl_and_possible_nif(compile:forms(AllForms, Opts),
                                   PossibleNifCode).
  
  
negative.code:        [?f("-export([descriptor/0]).~n") || get_gen_descriptor_by_opts(Opts)],
         ?f("-export([gpb_version_as_string/0, gpb_version_as_list/0]).~n"),
         "\n",
         [["-on_load(load_nif/0).\n",
           "-export([load_nif/0]). %% for debugging of nif loading\n",
           "\n"]
  