//===- ModuleMapFile.cpp - ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file handles parsing of modulemap files into a simple AST.
///
//===----------------------------------------------------------------------===//

#include "clang/Lex/ModuleMapFile.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
#include <optional>

using namespace clang;
using namespace modulemap;

namespace {
struct MMToken {
  enum TokenKind {
    Comma,
    ConfigMacros,
    Conflict,
    EndOfFile,
    HeaderKeyword,
    Identifier,
    Exclaim,
    ExcludeKeyword,
    ExplicitKeyword,
    ExportKeyword,
    ExportAsKeyword,
    ExternKeyword,
    FrameworkKeyword,
    LinkKeyword,
    ModuleKeyword,
    Period,
    PrivateKeyword,
    UmbrellaKeyword,
    UseKeyword,
    RequiresKeyword,
    Star,
    StringLiteral,
    IntegerLiteral,
    TextualKeyword,
    LBrace,
    RBrace,
    LSquare,
    RSquare
  } Kind;

  SourceLocation::UIntTy Location;
  unsigned StringLength;
  union {
    // If Kind != IntegerLiteral.
    const char *StringData;

    // If Kind == IntegerLiteral.
    uint64_t IntegerValue;
  };

  void clear() {
    Kind = EndOfFile;
    Location = 0;
    StringLength = 0;
    StringData = nullptr;
  }

  bool is(TokenKind K) const { return Kind == K; }

  SourceLocation getLocation() const {
    return SourceLocation::getFromRawEncoding(Location);
  }

  uint64_t getInteger() const {
    return Kind == IntegerLiteral ? IntegerValue : 0;
  }

  StringRef getString() const {
    return Kind == IntegerLiteral ? StringRef()
                                  : StringRef(StringData, StringLength);
  }
};

struct ModuleMapFileParser {
  // External context
  Lexer &L;
  DiagnosticsEngine &Diags;

  /// Parsed representation of the module map file
  ModuleMapFile MMF{};

  bool HadError = false;

  /// The current token.
  MMToken Tok{};

  bool parseTopLevelDecls();
  std::optional<ModuleDecl> parseModuleDecl(bool TopLevel);
  std::optional<ExternModuleDecl> parseExternModuleDecl();
  std::optional<ConfigMacrosDecl> parseConfigMacrosDecl();
  std::optional<ConflictDecl> parseConflictDecl();
  std::optional<ExportDecl> parseExportDecl();
  std::optional<ExportAsDecl> parseExportAsDecl();
  std::optional<UseDecl> parseUseDecl();
  std::optional<RequiresDecl> parseRequiresDecl();
  std::optional<HeaderDecl> parseHeaderDecl(MMToken::TokenKind LeadingToken,
                                            SourceLocation LeadingLoc);
  std::optional<ExcludeDecl> parseExcludeDecl(clang::SourceLocation LeadingLoc);
  std::optional<UmbrellaDirDecl>
  parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
  std::optional<LinkDecl> parseLinkDecl();

  SourceLocation consumeToken();
  void skipUntil(MMToken::TokenKind K);
  bool parseModuleId(ModuleId &Id);
  bool parseOptionalAttributes(ModuleAttributes &Attrs);

  SourceLocation getLocation() const { return Tok.getLocation(); };
};

std::string formatModuleId(const ModuleId &Id) {
  std::string result;
  {
    llvm::raw_string_ostream OS(result);

    for (unsigned I = 0, N = Id.size(); I != N; ++I) {
      if (I)
        OS << ".";
      OS << Id[I].first;
    }
  }

  return result;
}
} // end anonymous namespace

std::optional<ModuleMapFile>
modulemap::parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir,
                          SourceManager &SM, DiagnosticsEngine &Diags,
                          bool IsSystem, unsigned *Offset) {
  std::optional<llvm::MemoryBufferRef> Buffer = SM.getBufferOrNone(ID);
  LangOptions LOpts;
  LOpts.LangStd = clang::LangStandard::lang_c99;
  Lexer L(SM.getLocForStartOfFile(ID), LOpts, Buffer->getBufferStart(),
          Buffer->getBufferStart() + (Offset ? *Offset : 0),
          Buffer->getBufferEnd());
  SourceLocation Start = L.getSourceLocation();

  ModuleMapFileParser Parser{L, Diags};
  bool Failed = Parser.parseTopLevelDecls();

  if (Offset) {
    auto Loc = SM.getDecomposedLoc(Parser.getLocation());
    assert(Loc.first == ID && "stopped in a different file?");
    *Offset = Loc.second;
  }

  if (Failed)
    return std::nullopt;
  Parser.MMF.ID = ID;
  Parser.MMF.Dir = Dir;
  Parser.MMF.Start = Start;
  Parser.MMF.IsSystem = IsSystem;
  return std::move(Parser.MMF);
}

bool ModuleMapFileParser::parseTopLevelDecls() {
  Tok.clear();
  consumeToken();
  do {
    switch (Tok.Kind) {
    case MMToken::EndOfFile:
      return HadError;
    case MMToken::ExternKeyword: {
      std::optional<ExternModuleDecl> EMD = parseExternModuleDecl();
      if (EMD)
        MMF.Decls.push_back(std::move(*EMD));
      break;
    }
    case MMToken::ExplicitKeyword:
    case MMToken::ModuleKeyword:
    case MMToken::FrameworkKeyword: {
      std::optional<ModuleDecl> MD = parseModuleDecl(true);
      if (MD)
        MMF.Decls.push_back(std::move(*MD));
      break;
    }
    case MMToken::Comma:
    case MMToken::ConfigMacros:
    case MMToken::Conflict:
    case MMToken::Exclaim:
    case MMToken::ExcludeKeyword:
    case MMToken::ExportKeyword:
    case MMToken::ExportAsKeyword:
    case MMToken::HeaderKeyword:
    case MMToken::Identifier:
    case MMToken::LBrace:
    case MMToken::LinkKeyword:
    case MMToken::LSquare:
    case MMToken::Period:
    case MMToken::PrivateKeyword:
    case MMToken::RBrace:
    case MMToken::RSquare:
    case MMToken::RequiresKeyword:
    case MMToken::Star:
    case MMToken::StringLiteral:
    case MMToken::IntegerLiteral:
    case MMToken::TextualKeyword:
    case MMToken::UmbrellaKeyword:
    case MMToken::UseKeyword:
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
      HadError = true;
      consumeToken();
      break;
    }
  } while (true);
}

/// Parse a module declaration.
///
///   module-declaration:
///     'extern' 'module' module-id string-literal
///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
///       { module-member* }
///
///   module-member:
///     requires-declaration
///     header-declaration
///     submodule-declaration
///     export-declaration
///     export-as-declaration
///     link-declaration
///
///   submodule-declaration:
///     module-declaration
///     inferred-submodule-declaration
std::optional<ModuleDecl> ModuleMapFileParser::parseModuleDecl(bool TopLevel) {
  assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
         Tok.is(MMToken::FrameworkKeyword));

  ModuleDecl MDecl;

  SourceLocation ExplicitLoc;
  MDecl.Explicit = false;
  MDecl.Framework = false;

  // Parse 'explicit' keyword, if present.
  if (Tok.is(MMToken::ExplicitKeyword)) {
    MDecl.Location = ExplicitLoc = consumeToken();
    MDecl.Explicit = true;
  }

  // Parse 'framework' keyword, if present.
  if (Tok.is(MMToken::FrameworkKeyword)) {
    SourceLocation FrameworkLoc = consumeToken();
    if (!MDecl.Location.isValid())
      MDecl.Location = FrameworkLoc;
    MDecl.Framework = true;
  }

  // Parse 'module' keyword.
  if (!Tok.is(MMToken::ModuleKeyword)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
    consumeToken();
    HadError = true;
    return std::nullopt;
  }
  SourceLocation ModuleLoc = consumeToken();
  if (!MDecl.Location.isValid())
    MDecl.Location = ModuleLoc; // 'module' keyword

  // If we have a wildcard for the module name, this is an inferred submodule.
  // We treat it as a normal module at this point.
  if (Tok.is(MMToken::Star)) {
    SourceLocation StarLoc = consumeToken();
    MDecl.Id.push_back({"*", StarLoc});
    if (TopLevel && !MDecl.Framework) {
      Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
      HadError = true;
      return std::nullopt;
    }
  } else {
    // Parse the module name.
    if (parseModuleId(MDecl.Id)) {
      HadError = true;
      return std::nullopt;
    }
    if (!TopLevel) {
      if (MDecl.Id.size() > 1) {
        Diags.Report(MDecl.Id.front().second,
                     diag::err_mmap_nested_submodule_id)
            << SourceRange(MDecl.Id.front().second, MDecl.Id.back().second);

        HadError = true;
      }
    } else if (MDecl.Id.size() == 1 && MDecl.Explicit) {
      // Top-level modules can't be explicit.
      Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
      MDecl.Explicit = false;
      HadError = true;
    }
  }

  // Parse the optional attribute list.
  if (parseOptionalAttributes(MDecl.Attrs))
    return std::nullopt;

  // Parse the opening brace.
  if (!Tok.is(MMToken::LBrace)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
        << MDecl.Id.back().first;
    HadError = true;
    return std::nullopt;
  }
  SourceLocation LBraceLoc = consumeToken();

  bool Done = false;
  do {
    std::optional<Decl> SubDecl;
    switch (Tok.Kind) {
    case MMToken::EndOfFile:
    case MMToken::RBrace:
      Done = true;
      break;

    case MMToken::ConfigMacros:
      // Only top-level modules can have configuration macros.
      if (!TopLevel)
        Diags.Report(Tok.getLocation(), diag::err_mmap_config_macro_submodule);
      SubDecl = parseConfigMacrosDecl();
      break;

    case MMToken::Conflict:
      SubDecl = parseConflictDecl();
      break;

    case MMToken::ExternKeyword:
      SubDecl = parseExternModuleDecl();
      break;

    case MMToken::ExplicitKeyword:
    case MMToken::FrameworkKeyword:
    case MMToken::ModuleKeyword:
      SubDecl = parseModuleDecl(false);
      break;

    case MMToken::ExportKeyword:
      SubDecl = parseExportDecl();
      break;

    case MMToken::ExportAsKeyword:
      if (!TopLevel) {
        Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
        parseExportAsDecl();
      } else
        SubDecl = parseExportAsDecl();
      break;

    case MMToken::UseKeyword:
      SubDecl = parseUseDecl();
      break;

    case MMToken::RequiresKeyword:
      SubDecl = parseRequiresDecl();
      break;

    case MMToken::TextualKeyword:
      SubDecl = parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
      break;

    case MMToken::UmbrellaKeyword: {
      SourceLocation UmbrellaLoc = consumeToken();
      if (Tok.is(MMToken::HeaderKeyword))
        SubDecl = parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
      else
        SubDecl = parseUmbrellaDirDecl(UmbrellaLoc);
      break;
    }

    case MMToken::ExcludeKeyword: {
      SourceLocation ExcludeLoc = consumeToken();
      if (Tok.is(MMToken::HeaderKeyword))
        SubDecl = parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
      else
        SubDecl = parseExcludeDecl(ExcludeLoc);
      break;
    }

    case MMToken::PrivateKeyword:
      SubDecl = parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
      break;

    case MMToken::HeaderKeyword:
      SubDecl = parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
      break;

    case MMToken::LinkKeyword:
      SubDecl = parseLinkDecl();
      break;

    default:
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
      consumeToken();
      break;
    }
    if (SubDecl)
      MDecl.Decls.push_back(std::move(*SubDecl));
  } while (!Done);

  if (Tok.is(MMToken::RBrace))
    consumeToken();
  else {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
    Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
    HadError = true;
  }
  return std::move(MDecl);
}

std::optional<ExternModuleDecl> ModuleMapFileParser::parseExternModuleDecl() {
  assert(Tok.is(MMToken::ExternKeyword));
  ExternModuleDecl EMD;
  EMD.Location = consumeToken(); // 'extern' keyword

  // Parse 'module' keyword.
  if (!Tok.is(MMToken::ModuleKeyword)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
    consumeToken();
    HadError = true;
    return std::nullopt;
  }
  consumeToken(); // 'module' keyword

  // Parse the module name.
  if (parseModuleId(EMD.Id)) {
    HadError = true;
    return std::nullopt;
  }

  // Parse the referenced module map file name.
  if (!Tok.is(MMToken::StringLiteral)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
    HadError = true;
    return std::nullopt;
  }
  EMD.Path = Tok.getString();
  consumeToken(); // filename

  return std::move(EMD);
}

/// Parse a configuration macro declaration.
///
///   module-declaration:
///     'config_macros' attributes[opt] config-macro-list?
///
///   config-macro-list:
///     identifier (',' identifier)?
std::optional<ConfigMacrosDecl> ModuleMapFileParser::parseConfigMacrosDecl() {
  assert(Tok.is(MMToken::ConfigMacros));
  ConfigMacrosDecl CMDecl;
  CMDecl.Location = consumeToken();

  // Parse the optional attributes.
  ModuleAttributes Attrs;
  if (parseOptionalAttributes(Attrs))
    return std::nullopt;

  CMDecl.Exhaustive = Attrs.IsExhaustive;

  // If we don't have an identifier, we're done.
  // FIXME: Support macros with the same name as a keyword here.
  if (!Tok.is(MMToken::Identifier))
    return std::nullopt;

  // Consume the first identifier.
  CMDecl.Macros.push_back(Tok.getString());
  consumeToken();

  do {
    // If there's a comma, consume it.
    if (!Tok.is(MMToken::Comma))
      break;
    consumeToken();

    // We expect to see a macro name here.
    // FIXME: Support macros with the same name as a keyword here.
    if (!Tok.is(MMToken::Identifier)) {
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
      return std::nullopt;
    }

    // Consume the macro name.
    CMDecl.Macros.push_back(Tok.getString());
    consumeToken();
  } while (true);
  return std::move(CMDecl);
}

/// Parse a conflict declaration.
///
///   module-declaration:
///     'conflict' module-id ',' string-literal
std::optional<ConflictDecl> ModuleMapFileParser::parseConflictDecl() {
  assert(Tok.is(MMToken::Conflict));
  ConflictDecl CD;
  CD.Location = consumeToken();

  // Parse the module-id.
  if (parseModuleId(CD.Id))
    return std::nullopt;

  // Parse the ','.
  if (!Tok.is(MMToken::Comma)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
        << SourceRange(CD.Location);
    return std::nullopt;
  }
  consumeToken();

  // Parse the message.
  if (!Tok.is(MMToken::StringLiteral)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
        << formatModuleId(CD.Id);
    return std::nullopt;
  }
  CD.Message = Tok.getString();
  consumeToken();
  return std::move(CD);
}

/// Parse a module export declaration.
///
///   export-declaration:
///     'export' wildcard-module-id
///
///   wildcard-module-id:
///     identifier
///     '*'
///     identifier '.' wildcard-module-id
std::optional<ExportDecl> ModuleMapFileParser::parseExportDecl() {
  assert(Tok.is(MMToken::ExportKeyword));
  ExportDecl ED;
  ED.Location = consumeToken();

  // Parse the module-id with an optional wildcard at the end.
  ED.Wildcard = false;
  do {
    // FIXME: Support string-literal module names here.
    if (Tok.is(MMToken::Identifier)) {
      ED.Id.push_back(
          std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
      consumeToken();

      if (Tok.is(MMToken::Period)) {
        consumeToken();
        continue;
      }

      break;
    }

    if (Tok.is(MMToken::Star)) {
      ED.Wildcard = true;
      consumeToken();
      break;
    }

    Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
    HadError = true;
    return std::nullopt;
  } while (true);

  return std::move(ED);
}

/// Parse a module export_as declaration.
///
///   export-as-declaration:
///     'export_as' identifier
std::optional<ExportAsDecl> ModuleMapFileParser::parseExportAsDecl() {
  assert(Tok.is(MMToken::ExportAsKeyword));
  ExportAsDecl EAD;
  EAD.Location = consumeToken();

  if (!Tok.is(MMToken::Identifier)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
    HadError = true;
    return std::nullopt;
  }

  if (parseModuleId(EAD.Id))
    return std::nullopt;
  if (EAD.Id.size() > 1)
    Diags.Report(EAD.Id[1].second, diag::err_mmap_qualified_export_as);
  return std::move(EAD);
}

/// Parse a module use declaration.
///
///   use-declaration:
///     'use' wildcard-module-id
std::optional<UseDecl> ModuleMapFileParser::parseUseDecl() {
  assert(Tok.is(MMToken::UseKeyword));
  UseDecl UD;
  UD.Location = consumeToken();
  if (parseModuleId(UD.Id))
    return std::nullopt;
  return std::move(UD);
}

/// Parse a requires declaration.
///
///   requires-declaration:
///     'requires' feature-list
///
///   feature-list:
///     feature ',' feature-list
///     feature
///
///   feature:
///     '!'[opt] identifier
std::optional<RequiresDecl> ModuleMapFileParser::parseRequiresDecl() {
  assert(Tok.is(MMToken::RequiresKeyword));
  RequiresDecl RD;
  RD.Location = consumeToken();

  // Parse the feature-list.
  do {
    bool RequiredState = true;
    if (Tok.is(MMToken::Exclaim)) {
      RequiredState = false;
      consumeToken();
    }

    if (!Tok.is(MMToken::Identifier)) {
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
      HadError = true;
      return std::nullopt;
    }

    // Consume the feature name.
    RequiresFeature RF;
    RF.Feature = Tok.getString();
    RF.Location = consumeToken();
    RF.RequiredState = RequiredState;

    RD.Features.push_back(std::move(RF));

    if (!Tok.is(MMToken::Comma))
      break;

    // Consume the comma.
    consumeToken();
  } while (true);
  return std::move(RD);
}

/// Parse a header declaration.
///
///   header-declaration:
///     'textual'[opt] 'header' string-literal
///     'private' 'textual'[opt] 'header' string-literal
///     'exclude' 'header' string-literal
///     'umbrella' 'header' string-literal
std::optional<HeaderDecl>
ModuleMapFileParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
                                     clang::SourceLocation LeadingLoc) {
  HeaderDecl HD;
  HD.Private = false;
  HD.Excluded = false;
  HD.Textual = false;
  // We've already consumed the first token.
  HD.Location = LeadingLoc;

  if (LeadingToken == MMToken::PrivateKeyword) {
    HD.Private = true;
    // 'private' may optionally be followed by 'textual'.
    if (Tok.is(MMToken::TextualKeyword)) {
      HD.Textual = true;
      LeadingToken = Tok.Kind;
      consumeToken();
    }
  } else if (LeadingToken == MMToken::ExcludeKeyword)
    HD.Excluded = true;
  else if (LeadingToken == MMToken::TextualKeyword)
    HD.Textual = true;

  if (LeadingToken != MMToken::HeaderKeyword) {
    if (!Tok.is(MMToken::HeaderKeyword)) {
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
          << (LeadingToken == MMToken::PrivateKeyword   ? "private"
              : LeadingToken == MMToken::ExcludeKeyword ? "exclude"
              : LeadingToken == MMToken::TextualKeyword ? "textual"
                                                        : "umbrella");
      return std::nullopt;
    }
    consumeToken();
  }

  // Parse the header name.
  if (!Tok.is(MMToken::StringLiteral)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) << "header";
    HadError = true;
    return std::nullopt;
  }
  HD.Path = Tok.getString();
  HD.PathLoc = consumeToken();
  HD.Umbrella = LeadingToken == MMToken::UmbrellaKeyword;

  // If we were given stat information, parse it so we can skip looking for
  // the file.
  if (Tok.is(MMToken::LBrace)) {
    SourceLocation LBraceLoc = consumeToken();

    while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
      enum Attribute { Size, ModTime, Unknown };
      StringRef Str = Tok.getString();
      SourceLocation Loc = consumeToken();
      switch (llvm::StringSwitch<Attribute>(Str)
                  .Case("size", Size)
                  .Case("mtime", ModTime)
                  .Default(Unknown)) {
      case Size:
        if (HD.Size)
          Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
        if (!Tok.is(MMToken::IntegerLiteral)) {
          Diags.Report(Tok.getLocation(),
                       diag::err_mmap_invalid_header_attribute_value)
              << Str;
          skipUntil(MMToken::RBrace);
          break;
        }
        HD.Size = Tok.getInteger();
        consumeToken();
        break;

      case ModTime:
        if (HD.MTime)
          Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
        if (!Tok.is(MMToken::IntegerLiteral)) {
          Diags.Report(Tok.getLocation(),
                       diag::err_mmap_invalid_header_attribute_value)
              << Str;
          skipUntil(MMToken::RBrace);
          break;
        }
        HD.MTime = Tok.getInteger();
        consumeToken();
        break;

      case Unknown:
        Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
        skipUntil(MMToken::RBrace);
        break;
      }
    }

    if (Tok.is(MMToken::RBrace))
      consumeToken();
    else {
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
      Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
      HadError = true;
    }
  }
  return std::move(HD);
}

/// Parse an exclude declaration.
///
/// exclude-declaration:
///   'exclude' identifier
std::optional<ExcludeDecl>
ModuleMapFileParser::parseExcludeDecl(clang::SourceLocation LeadingLoc) {
  // FIXME: Support string-literal module names here.
  if (!Tok.is(MMToken::Identifier)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
    HadError = true;
    return std::nullopt;
  }

  ExcludeDecl ED;
  ED.Location = LeadingLoc;
  ED.Module = Tok.getString();
  consumeToken();
  return std::move(ED);
}

/// Parse an umbrella directory declaration.
///
///   umbrella-dir-declaration:
///     umbrella string-literal
std::optional<UmbrellaDirDecl>
ModuleMapFileParser::parseUmbrellaDirDecl(clang::SourceLocation UmbrellaLoc) {
  UmbrellaDirDecl UDD;
  UDD.Location = UmbrellaLoc;
  // Parse the directory name.
  if (!Tok.is(MMToken::StringLiteral)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
        << "umbrella";
    HadError = true;
    return std::nullopt;
  }

  UDD.Path = Tok.getString();
  consumeToken();
  return std::move(UDD);
}

/// Parse a link declaration.
///
///   module-declaration:
///     'link' 'framework'[opt] string-literal
std::optional<LinkDecl> ModuleMapFileParser::parseLinkDecl() {
  assert(Tok.is(MMToken::LinkKeyword));
  LinkDecl LD;
  LD.Location = consumeToken();

  // Parse the optional 'framework' keyword.
  LD.Framework = false;
  if (Tok.is(MMToken::FrameworkKeyword)) {
    consumeToken();
    LD.Framework = true;
  }

  // Parse the library name
  if (!Tok.is(MMToken::StringLiteral)) {
    Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
        << LD.Framework << SourceRange(LD.Location);
    HadError = true;
    return std::nullopt;
  }

  LD.Library = Tok.getString();
  consumeToken();
  return std::move(LD);
}

SourceLocation ModuleMapFileParser::consumeToken() {
  SourceLocation Result = Tok.getLocation();

retry:
  Tok.clear();
  Token LToken;
  L.LexFromRawLexer(LToken);
  Tok.Location = LToken.getLocation().getRawEncoding();
  switch (LToken.getKind()) {
  case tok::raw_identifier: {
    StringRef RI = LToken.getRawIdentifier();
    Tok.StringData = RI.data();
    Tok.StringLength = RI.size();
    Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
                   .Case("config_macros", MMToken::ConfigMacros)
                   .Case("conflict", MMToken::Conflict)
                   .Case("exclude", MMToken::ExcludeKeyword)
                   .Case("explicit", MMToken::ExplicitKeyword)
                   .Case("export", MMToken::ExportKeyword)
                   .Case("export_as", MMToken::ExportAsKeyword)
                   .Case("extern", MMToken::ExternKeyword)
                   .Case("framework", MMToken::FrameworkKeyword)
                   .Case("header", MMToken::HeaderKeyword)
                   .Case("link", MMToken::LinkKeyword)
                   .Case("module", MMToken::ModuleKeyword)
                   .Case("private", MMToken::PrivateKeyword)
                   .Case("requires", MMToken::RequiresKeyword)
                   .Case("textual", MMToken::TextualKeyword)
                   .Case("umbrella", MMToken::UmbrellaKeyword)
                   .Case("use", MMToken::UseKeyword)
                   .Default(MMToken::Identifier);
    break;
  }

  case tok::comma:
    Tok.Kind = MMToken::Comma;
    break;

  case tok::eof:
    Tok.Kind = MMToken::EndOfFile;
    break;

  case tok::l_brace:
    Tok.Kind = MMToken::LBrace;
    break;

  case tok::l_square:
    Tok.Kind = MMToken::LSquare;
    break;

  case tok::period:
    Tok.Kind = MMToken::Period;
    break;

  case tok::r_brace:
    Tok.Kind = MMToken::RBrace;
    break;

  case tok::r_square:
    Tok.Kind = MMToken::RSquare;
    break;

  case tok::star:
    Tok.Kind = MMToken::Star;
    break;

  case tok::exclaim:
    Tok.Kind = MMToken::Exclaim;
    break;

  case tok::string_literal: {
    if (LToken.hasUDSuffix()) {
      Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
      HadError = true;
      goto retry;
    }

    // Form the token.
    Tok.Kind = MMToken::StringLiteral;
    Tok.StringData = LToken.getLiteralData() + 1;
    Tok.StringLength = LToken.getLength() - 2;
    break;
  }

  case tok::numeric_constant: {
    // We don't support any suffixes or other complications.
    uint64_t Value;
    if (StringRef(LToken.getLiteralData(), LToken.getLength())
            .getAsInteger(0, Value)) {
      Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
      HadError = true;
      goto retry;
    }

    Tok.Kind = MMToken::IntegerLiteral;
    Tok.IntegerValue = Value;
    break;
  }

  case tok::comment:
    goto retry;

  case tok::hash:
    // A module map can be terminated prematurely by
    //   #pragma clang module contents
    // When building the module, we'll treat the rest of the file as the
    // contents of the module.
    {
      auto NextIsIdent = [&](StringRef Str) -> bool {
        L.LexFromRawLexer(LToken);
        return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
               LToken.getRawIdentifier() == Str;
      };
      if (NextIsIdent("pragma") && NextIsIdent("clang") &&
          NextIsIdent("module") && NextIsIdent("contents")) {
        Tok.Kind = MMToken::EndOfFile;
        break;
      }
    }
    [[fallthrough]];

  default:
    Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
    HadError = true;
    goto retry;
  }

  return Result;
}

void ModuleMapFileParser::skipUntil(MMToken::TokenKind K) {
  unsigned braceDepth = 0;
  unsigned squareDepth = 0;
  do {
    switch (Tok.Kind) {
    case MMToken::EndOfFile:
      return;

    case MMToken::LBrace:
      if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
        return;

      ++braceDepth;
      break;

    case MMToken::LSquare:
      if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
        return;

      ++squareDepth;
      break;

    case MMToken::RBrace:
      if (braceDepth > 0)
        --braceDepth;
      else if (Tok.is(K))
        return;
      break;

    case MMToken::RSquare:
      if (squareDepth > 0)
        --squareDepth;
      else if (Tok.is(K))
        return;
      break;

    default:
      if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
        return;
      break;
    }

    consumeToken();
  } while (true);
}

/// Parse a module-id.
///
///   module-id:
///     identifier
///     identifier '.' module-id
///
/// \returns true if an error occurred, false otherwise.
bool ModuleMapFileParser::parseModuleId(ModuleId &Id) {
  Id.clear();
  do {
    if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
      Id.push_back(
          std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
      consumeToken();
    } else {
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
      return true;
    }

    if (!Tok.is(MMToken::Period))
      break;

    consumeToken();
  } while (true);

  return false;
}

/// Parse optional attributes.
///
///   attributes:
///     attribute attributes
///     attribute
///
///   attribute:
///     [ identifier ]
///
/// \param Attrs Will be filled in with the parsed attributes.
///
/// \returns true if an error occurred, false otherwise.
bool ModuleMapFileParser::parseOptionalAttributes(ModuleAttributes &Attrs) {
  bool Error = false;

  while (Tok.is(MMToken::LSquare)) {
    // Consume the '['.
    SourceLocation LSquareLoc = consumeToken();

    // Check whether we have an attribute name here.
    if (!Tok.is(MMToken::Identifier)) {
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
      skipUntil(MMToken::RSquare);
      if (Tok.is(MMToken::RSquare))
        consumeToken();
      Error = true;
    }

    /// Enumerates the known attributes.
    enum AttributeKind {
      /// An unknown attribute.
      AT_unknown,

      /// The 'system' attribute.
      AT_system,

      /// The 'extern_c' attribute.
      AT_extern_c,

      /// The 'exhaustive' attribute.
      AT_exhaustive,

      /// The 'no_undeclared_includes' attribute.
      AT_no_undeclared_includes
    };

    // Decode the attribute name.
    AttributeKind Attribute =
        llvm::StringSwitch<AttributeKind>(Tok.getString())
            .Case("exhaustive", AT_exhaustive)
            .Case("extern_c", AT_extern_c)
            .Case("no_undeclared_includes", AT_no_undeclared_includes)
            .Case("system", AT_system)
            .Default(AT_unknown);
    switch (Attribute) {
    case AT_unknown:
      Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
          << Tok.getString();
      break;

    case AT_system:
      Attrs.IsSystem = true;
      break;

    case AT_extern_c:
      Attrs.IsExternC = true;
      break;

    case AT_exhaustive:
      Attrs.IsExhaustive = true;
      break;

    case AT_no_undeclared_includes:
      Attrs.NoUndeclaredIncludes = true;
      break;
    }
    consumeToken();

    // Consume the ']'.
    if (!Tok.is(MMToken::RSquare)) {
      Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
      Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
      skipUntil(MMToken::RSquare);
      Error = true;
    }

    if (Tok.is(MMToken::RSquare))
      consumeToken();
  }

  if (Error)
    HadError = true;

  return Error;
}

static void dumpModule(const ModuleDecl &MD, llvm::raw_ostream &out, int depth);

static void dumpExternModule(const ExternModuleDecl &EMD,
                             llvm::raw_ostream &out, int depth) {
  out.indent(depth * 2);
  out << "extern module " << formatModuleId(EMD.Id) << " \"" << EMD.Path
      << "\"\n";
}

static void dumpDecls(ArrayRef<Decl> Decls, llvm::raw_ostream &out, int depth) {
  for (const auto &Decl : Decls) {
    std::visit(llvm::makeVisitor(
                   [&](const RequiresDecl &RD) {
                     out.indent(depth * 2);
                     out << "requires\n";
                   },
                   [&](const HeaderDecl &HD) {
                     out.indent(depth * 2);
                     if (HD.Private)
                       out << "private ";
                     if (HD.Textual)
                       out << "textual ";
                     if (HD.Excluded)
                       out << "excluded ";
                     if (HD.Umbrella)
                       out << "umbrella ";
                     out << "header \"" << HD.Path << "\"\n";
                   },
                   [&](const UmbrellaDirDecl &UDD) {
                     out.indent(depth * 2);
                     out << "umbrella\n";
                   },
                   [&](const ModuleDecl &MD) { dumpModule(MD, out, depth); },
                   [&](const ExcludeDecl &ED) {
                     out.indent(depth * 2);
                     out << "exclude " << ED.Module << "\n";
                   },
                   [&](const ExportDecl &ED) {
                     out.indent(depth * 2);
                     out << "export "
                         << (ED.Wildcard ? "*" : formatModuleId(ED.Id)) << "\n";
                   },
                   [&](const ExportAsDecl &EAD) {
                     out.indent(depth * 2);
                     out << "export as\n";
                   },
                   [&](const ExternModuleDecl &EMD) {
                     dumpExternModule(EMD, out, depth);
                   },
                   [&](const UseDecl &UD) {
                     out.indent(depth * 2);
                     out << "use\n";
                   },
                   [&](const LinkDecl &LD) {
                     out.indent(depth * 2);
                     out << "link\n";
                   },
                   [&](const ConfigMacrosDecl &CMD) {
                     out.indent(depth * 2);
                     out << "config_macros ";
                     if (CMD.Exhaustive)
                       out << "[exhaustive] ";
                     for (auto Macro : CMD.Macros) {
                       out << Macro << " ";
                     }
                     out << "\n";
                   },
                   [&](const ConflictDecl &CD) {
                     out.indent(depth * 2);
                     out << "conflicts\n";
                   }),
               Decl);
  }
}

static void dumpModule(const ModuleDecl &MD, llvm::raw_ostream &out,
                       int depth) {
  out.indent(depth * 2);
  out << "module " << formatModuleId(MD.Id) << "\n";
  dumpDecls(MD.Decls, out, depth + 1);
}

void ModuleMapFile::dump(llvm::raw_ostream &out) const {
  for (const auto &Decl : Decls) {
    std::visit(
        llvm::makeVisitor([&](const ModuleDecl &MD) { dumpModule(MD, out, 0); },
                          [&](const ExternModuleDecl &EMD) {
                            dumpExternModule(EMD, out, 0);
                          }),
        Decl);
  }
}
