anchor.diff:          options         = undefined,
           oneof_decl      = oneof_decl(AllOneofs)
          }
  -     || {{msg,MsgName}, Fields} <- Defs].
  -
  -field_defs_to_mgstype_fields(Fields, AllOneofs) ->
  -    lists:append([field_def_to_msgtype_field(Field, AllOneofs)
  +     || {{msg,MsgName}, Fields} <- Defs] ++
  +        [#'DescriptorProto'{
  +            name            = atom_to_ustring(MsgName),
  +            field           = field_defs_to_mgstype_fields(
  +                                Fields, AllOneofs, MapTypesToPseudoMsgNames),
  +            extension       = [],
  +            nested_type     = [],
  +            enum_type       = [],
  +            extension_range = [],
  +            options         = #'MessageOptions'{map_entry=true},
  +            oneof_decl      = []
  +           }
  +         || {{msg,MsgName}, Fields} <- MapPseudoMsgs].
  +
  +field_defs_to_mgstype_fields(Fields, AllOneofs, MapTypesToPseudoMsgNames) ->
  +    lists:append([field_def_to_msgtype_field(Field, AllOneofs,
  +                                             MapTypesToPseudoMsgNames)
                     || Field <- Fields]).
   
   field_def_to_msgtype_field(#?gpb_field{name=FName,
  
positive.code:     #'FileDescriptorSet'{file = [defs_to_descr_2(Name, Defs)]}.
  
  defs_to_descr_2(Name, Defs) ->
      #'FileDescriptorProto'{
         name             = Name,      %% string() | undefined
         package          = defs_to_package(Defs),
         dependency       = [],        %% [string()]
         message_type     = defs_to_msgtype(Defs),
         enum_type        = defs_to_enumtype(Defs),
         service          = defs_to_service(Defs),
         extension        = [],        %% [#'FieldDescriptorProto'{}]
  
negative.code: oneof_decl(AllOneofs) ->
      [#'OneofDescriptorProto'{name=atom_to_ustring(Name)} || Name <- AllOneofs].
  
  compute_map_field_pseudo_msgs(Defs) ->
      AllMapTypes = find_all_map_types(Defs),
      MapTypePseudoMsgNames = invent_unused_msg_names(Defs, length(AllMapTypes)),
      ToName = lists:zip(AllMapTypes, MapTypePseudoMsgNames),
      ToMapT = lists:zip(MapTypePseudoMsgNames, AllMapTypes),
      {dict:from_list(ToName),
       [{{msg, Name}, gpb:map_item_pseudo_fields(KeyType, ValueType)}
        || {Name, {map, KeyType, ValueType}} <- ToMapT]}.
  
  find_all_map_types(Defs) ->
      lists:sort(
        sets:to_list(
          lists:foldl(
            fun({{msg,_}, Fields}, Acc) ->
                    lists:foldl(fun(#?gpb_field{type={map,_,_}=T}, Acc2) ->
                                        sets:add_element(T, Acc2);
                                   (_, Acc2) ->
                                        Acc2
                                end,
                                Acc,
                                Fields);
               (_, Acc) ->
                    Acc
            end,
            sets:new(),
            Defs))).
  
  invent_unused_msg_names(Defs, N) ->
      AllMsgNames = sets:from_list([Name || {{msg,Name}, _Fields} <- Defs]),
      Base = "MapFieldEntry",
      invent_unused_msg_names_aux(Base, 1, N, AllMsgNames).
  
  invent_unused_msg_names_aux(Base, I, N, AllMsgNames) ->
      NewNames = sets:from_list([list_to_atom(?ff("~s_~w_~w", [Base, I, J]))
                                 || J <- lists:seq(1,N)]),
      case sets:is_disjoint(NewNames, AllMsgNames) of
          true  -> sets:to_list(NewNames);
          false -> invent_unused_msg_names_aux(Base, I+1, N, AllMsgNames)
      end.
  
  atom_to_ustring(A) ->
      Utf8Str = atom_to_list(A),
      unicode:characters_to_list(list_to_binary(Utf8Str), utf8).
  