//===-- clang-tools-extra/clang-tidy/NoLintDirectiveHandler.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 implements the NoLintDirectiveHandler class, which is used
///  to locate NOLINT comments in the file being analyzed, to decide whether a
///  diagnostic should be suppressed.
///
//===----------------------------------------------------------------------===//

#include "NoLintDirectiveHandler.h"
#include "GlobList.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Tooling/Core/Diagnostic.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
#include <cassert>
#include <cstddef>
#include <iterator>
#include <optional>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>

namespace clang::tidy {

//===----------------------------------------------------------------------===//
// NoLintType
//===----------------------------------------------------------------------===//

// The type - one of NOLINT[NEXTLINE/BEGIN/END].
enum class NoLintType { NoLint, NoLintNextLine, NoLintBegin, NoLintEnd };

// Convert a string like "NOLINTNEXTLINE" to its enum `Type::NoLintNextLine`.
// Return `std::nullopt` if the string is unrecognized.
static std::optional<NoLintType> strToNoLintType(StringRef Str) {
  auto Type = llvm::StringSwitch<std::optional<NoLintType>>(Str)
                  .Case("NOLINT", NoLintType::NoLint)
                  .Case("NOLINTNEXTLINE", NoLintType::NoLintNextLine)
                  .Case("NOLINTBEGIN", NoLintType::NoLintBegin)
                  .Case("NOLINTEND", NoLintType::NoLintEnd)
                  .Default(std::nullopt);
  return Type;
}

//===----------------------------------------------------------------------===//
// NoLintToken
//===----------------------------------------------------------------------===//

// Whitespace within a NOLINT's check list shall be ignored.
// "NOLINT( check1, check2 )" is equivalent to "NOLINT(check1,check2)".
// Return the check list with all extraneous whitespace removed.
static std::string trimWhitespace(StringRef Checks) {
  SmallVector<StringRef> Split;
  Checks.split(Split, ',');
  for (StringRef &Check : Split)
    Check = Check.trim();
  return llvm::join(Split, ",");
}

namespace {

// Record the presence of a NOLINT comment - its type, location, checks -
// as parsed from the file's character contents.
class NoLintToken {
public:
  // \param Checks:
  // - If unspecified (i.e. `None`) then ALL checks are suppressed - equivalent
  //   to NOLINT(*).
  // - An empty string means nothing is suppressed - equivalent to NOLINT().
  // - Negative globs ignored (which would effectively disable the suppression).
  NoLintToken(NoLintType Type, size_t Pos,
              const std::optional<std::string> &Checks)
      : Type(Type), Pos(Pos), ChecksGlob(std::make_unique<CachedGlobList>(
                                  Checks.value_or("*"),
                                  /*KeepNegativeGlobs=*/false)) {
    if (Checks)
      this->Checks = trimWhitespace(*Checks);
  }

  // The type - one of NOLINT[NEXTLINE/BEGIN/END].
  NoLintType Type;

  // The location of the first character, "N", in "NOLINT".
  size_t Pos;

  // If this NOLINT specifies checks, return the checks.
  std::optional<std::string> checks() const { return Checks; }

  // Whether this NOLINT applies to the provided check.
  bool suppresses(StringRef Check) const { return ChecksGlob->contains(Check); }

private:
  std::optional<std::string> Checks;
  std::unique_ptr<CachedGlobList> ChecksGlob;
};

} // namespace

// Consume the entire buffer and return all `NoLintToken`s that were found.
static SmallVector<NoLintToken> getNoLints(StringRef Buffer) {
  static constexpr llvm::StringLiteral NOLINT = "NOLINT";
  SmallVector<NoLintToken> NoLints;

  size_t Pos = 0;
  while (Pos < Buffer.size()) {
    // Find NOLINT:
    const size_t NoLintPos = Buffer.find(NOLINT, Pos);
    if (NoLintPos == StringRef::npos)
      break; // Buffer exhausted

    // Read [A-Z] characters immediately after "NOLINT", e.g. the "NEXTLINE" in
    // "NOLINTNEXTLINE".
    Pos = NoLintPos + NOLINT.size();
    while (Pos < Buffer.size() && llvm::isAlpha(Buffer[Pos]))
      ++Pos;

    // Is this a recognized NOLINT type?
    const std::optional<NoLintType> NoLintType =
        strToNoLintType(Buffer.slice(NoLintPos, Pos));
    if (!NoLintType)
      continue;

    // Get checks, if specified.
    std::optional<std::string> Checks;
    if (Pos < Buffer.size() && Buffer[Pos] == '(') {
      size_t ClosingBracket = Buffer.find_first_of("\n)", ++Pos);
      if (ClosingBracket != StringRef::npos && Buffer[ClosingBracket] == ')') {
        Checks = Buffer.slice(Pos, ClosingBracket).str();
        Pos = ClosingBracket + 1;
      }
    }

    NoLints.emplace_back(*NoLintType, NoLintPos, Checks);
  }

  return NoLints;
}

//===----------------------------------------------------------------------===//
// NoLintBlockToken
//===----------------------------------------------------------------------===//

namespace {

// Represents a source range within a pair of NOLINT(BEGIN/END) comments.
class NoLintBlockToken {
public:
  NoLintBlockToken(NoLintToken Begin, const NoLintToken &End)
      : Begin(std::move(Begin)), EndPos(End.Pos) {
    assert(this->Begin.Type == NoLintType::NoLintBegin);
    assert(End.Type == NoLintType::NoLintEnd);
    assert(this->Begin.Pos < End.Pos);
    assert(this->Begin.checks() == End.checks());
  }

  // Whether the provided diagnostic is within and is suppressible by this block
  // of NOLINT(BEGIN/END) comments.
  bool suppresses(size_t DiagPos, StringRef DiagName) const {
    return (Begin.Pos < DiagPos) && (DiagPos < EndPos) &&
           Begin.suppresses(DiagName);
  }

private:
  NoLintToken Begin;
  size_t EndPos;
};

} // namespace

// Match NOLINTBEGINs with their corresponding NOLINTENDs and move them into
// `NoLintBlockToken`s. If any BEGINs or ENDs are left over, they are moved to
// `UnmatchedTokens`.
static SmallVector<NoLintBlockToken>
formNoLintBlocks(SmallVector<NoLintToken> NoLints,
                 SmallVectorImpl<NoLintToken> &UnmatchedTokens) {
  SmallVector<NoLintBlockToken> CompletedBlocks;
  SmallVector<NoLintToken> Stack;

  // Nested blocks must be fully contained within their parent block. What this
  // means is that when you have a series of nested BEGIN tokens, the END tokens
  // shall appear in the reverse order, starting with the closing of the
  // inner-most block first, then the next level up, and so on. This is
  // essentially a last-in-first-out/stack system.
  for (NoLintToken &NoLint : NoLints) {
    if (NoLint.Type == NoLintType::NoLintBegin)
      // A new block is being started. Add it to the stack.
      Stack.emplace_back(std::move(NoLint));
    else if (NoLint.Type == NoLintType::NoLintEnd) {
      if (!Stack.empty() && Stack.back().checks() == NoLint.checks())
        // The previous block is being closed. Pop one element off the stack.
        CompletedBlocks.emplace_back(Stack.pop_back_val(), NoLint);
      else
        // Trying to close the wrong block.
        UnmatchedTokens.emplace_back(std::move(NoLint));
    }
  }

  llvm::move(Stack, std::back_inserter(UnmatchedTokens));
  return CompletedBlocks;
}

//===----------------------------------------------------------------------===//
// NoLintDirectiveHandler::Impl
//===----------------------------------------------------------------------===//

class NoLintDirectiveHandler::Impl {
public:
  bool shouldSuppress(DiagnosticsEngine::Level DiagLevel,
                      const Diagnostic &Diag, StringRef DiagName,
                      SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
                      bool AllowIO, bool EnableNoLintBlocks);

private:
  bool diagHasNoLintInMacro(const Diagnostic &Diag, StringRef DiagName,
                            SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
                            bool AllowIO, bool EnableNoLintBlocks);

  bool diagHasNoLint(StringRef DiagName, SourceLocation DiagLoc,
                     const SourceManager &SrcMgr,
                     SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
                     bool AllowIO, bool EnableNoLintBlocks);

  void generateCache(const SourceManager &SrcMgr, StringRef FileName,
                     FileID File, StringRef Buffer,
                     SmallVectorImpl<tooling::Diagnostic> &NoLintErrors);

  llvm::StringMap<SmallVector<NoLintBlockToken>> Cache;
};

bool NoLintDirectiveHandler::Impl::shouldSuppress(
    DiagnosticsEngine::Level DiagLevel, const Diagnostic &Diag,
    StringRef DiagName, SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
    bool AllowIO, bool EnableNoLintBlocks) {
  if (DiagLevel >= DiagnosticsEngine::Error)
    return false;
  return diagHasNoLintInMacro(Diag, DiagName, NoLintErrors, AllowIO,
                              EnableNoLintBlocks);
}

// Look at the macro's spelling location for a NOLINT. If none is found, keep
// looking up the call stack.
bool NoLintDirectiveHandler::Impl::diagHasNoLintInMacro(
    const Diagnostic &Diag, StringRef DiagName,
    SmallVectorImpl<tooling::Diagnostic> &NoLintErrors, bool AllowIO,
    bool EnableNoLintBlocks) {
  SourceLocation DiagLoc = Diag.getLocation();
  if (DiagLoc.isInvalid())
    return false;
  const SourceManager &SrcMgr = Diag.getSourceManager();
  while (true) {
    if (diagHasNoLint(DiagName, DiagLoc, SrcMgr, NoLintErrors, AllowIO,
                      EnableNoLintBlocks))
      return true;
    if (!DiagLoc.isMacroID())
      return false;
    DiagLoc = SrcMgr.getImmediateExpansionRange(DiagLoc).getBegin();
  }
  return false;
}

// Look behind and ahead for '\n' characters. These mark the start and end of
// this line.
static std::pair<size_t, size_t> getLineStartAndEnd(StringRef Buffer,
                                                    size_t From) {
  size_t StartPos = Buffer.find_last_of('\n', From) + 1;
  size_t EndPos = std::min(Buffer.find('\n', From), Buffer.size());
  return std::make_pair(StartPos, EndPos);
}

// Whether the line has a NOLINT of type = `Type` that can suppress the
// diagnostic `DiagName`.
static bool lineHasNoLint(StringRef Buffer,
                          std::pair<size_t, size_t> LineStartAndEnd,
                          NoLintType Type, StringRef DiagName) {
  // Get all NOLINTs on the line.
  Buffer = Buffer.slice(LineStartAndEnd.first, LineStartAndEnd.second);
  SmallVector<NoLintToken> NoLints = getNoLints(Buffer);

  // Do any of these NOLINTs match the desired type and diag name?
  return llvm::any_of(NoLints, [&](const NoLintToken &NoLint) {
    return NoLint.Type == Type && NoLint.suppresses(DiagName);
  });
}

// Whether the provided diagnostic is located within and is suppressible by a
// block of NOLINT(BEGIN/END) comments.
static bool withinNoLintBlock(ArrayRef<NoLintBlockToken> NoLintBlocks,
                              size_t DiagPos, StringRef DiagName) {
  return llvm::any_of(NoLintBlocks, [&](const NoLintBlockToken &NoLintBlock) {
    return NoLintBlock.suppresses(DiagPos, DiagName);
  });
}

// Get the file contents as a string.
static std::optional<StringRef> getBuffer(const SourceManager &SrcMgr,
                                          FileID File, bool AllowIO) {
  return AllowIO ? SrcMgr.getBufferDataOrNone(File)
                 : SrcMgr.getBufferDataIfLoaded(File);
}

// We will check for NOLINTs and NOLINTNEXTLINEs first. Checking for these is
// not so expensive (just need to parse the current and previous lines). Only if
// that fails do we look for NOLINT(BEGIN/END) blocks (which requires reading
// the entire file).
bool NoLintDirectiveHandler::Impl::diagHasNoLint(
    StringRef DiagName, SourceLocation DiagLoc, const SourceManager &SrcMgr,
    SmallVectorImpl<tooling::Diagnostic> &NoLintErrors, bool AllowIO,
    bool EnableNoLintBlocks) {
  // Translate the diagnostic's SourceLocation to a raw file + offset pair.
  FileID File;
  unsigned int Pos = 0;
  std::tie(File, Pos) = SrcMgr.getDecomposedSpellingLoc(DiagLoc);

  // We will only see NOLINTs in user-authored sources. No point reading the
  // file if it is a <built-in>.
  std::optional<StringRef> FileName = SrcMgr.getNonBuiltinFilenameForID(File);
  if (!FileName)
    return false;

  // Get file contents.
  std::optional<StringRef> Buffer = getBuffer(SrcMgr, File, AllowIO);
  if (!Buffer)
    return false;

  // Check if there's a NOLINT on this line.
  auto ThisLine = getLineStartAndEnd(*Buffer, Pos);
  if (lineHasNoLint(*Buffer, ThisLine, NoLintType::NoLint, DiagName))
    return true;

  // Check if there's a NOLINTNEXTLINE on the previous line.
  if (ThisLine.first > 0) {
    auto PrevLine = getLineStartAndEnd(*Buffer, ThisLine.first - 1);
    if (lineHasNoLint(*Buffer, PrevLine, NoLintType::NoLintNextLine, DiagName))
      return true;
  }

  // Check if this line is within a NOLINT(BEGIN/END) block.
  if (!EnableNoLintBlocks)
    return false;

  // Do we have cached NOLINT block locations for this file?
  if (Cache.count(*FileName) == 0)
    // Warning: heavy operation - need to read entire file.
    generateCache(SrcMgr, *FileName, File, *Buffer, NoLintErrors);

  return withinNoLintBlock(Cache[*FileName], Pos, DiagName);
}

// Construct a [clang-tidy-nolint] diagnostic to do with the unmatched
// NOLINT(BEGIN/END) pair.
static tooling::Diagnostic makeNoLintError(const SourceManager &SrcMgr,
                                           FileID File,
                                           const NoLintToken &NoLint) {
  tooling::Diagnostic Error;
  Error.DiagLevel = tooling::Diagnostic::Error;
  Error.DiagnosticName = "clang-tidy-nolint";
  StringRef Message =
      (NoLint.Type == NoLintType::NoLintBegin)
          ? ("unmatched 'NOLINTBEGIN' comment without a subsequent 'NOLINT"
             "END' comment")
          : ("unmatched 'NOLINTEND' comment without a previous 'NOLINT"
             "BEGIN' comment");
  SourceLocation Loc = SrcMgr.getComposedLoc(File, NoLint.Pos);
  Error.Message = tooling::DiagnosticMessage(Message, SrcMgr, Loc);
  return Error;
}

// Find all NOLINT(BEGIN/END) blocks in a file and store in the cache.
void NoLintDirectiveHandler::Impl::generateCache(
    const SourceManager &SrcMgr, StringRef FileName, FileID File,
    StringRef Buffer, SmallVectorImpl<tooling::Diagnostic> &NoLintErrors) {
  // Read entire file to get all NOLINTs.
  SmallVector<NoLintToken> NoLints = getNoLints(Buffer);

  // Match each BEGIN with its corresponding END.
  SmallVector<NoLintToken> UnmatchedTokens;
  Cache[FileName] = formNoLintBlocks(std::move(NoLints), UnmatchedTokens);

  // Raise error for any BEGIN/END left over.
  for (const NoLintToken &NoLint : UnmatchedTokens)
    NoLintErrors.emplace_back(makeNoLintError(SrcMgr, File, NoLint));
}

//===----------------------------------------------------------------------===//
// NoLintDirectiveHandler
//===----------------------------------------------------------------------===//

NoLintDirectiveHandler::NoLintDirectiveHandler()
    : PImpl(std::make_unique<Impl>()) {}

NoLintDirectiveHandler::~NoLintDirectiveHandler() = default;

bool NoLintDirectiveHandler::shouldSuppress(
    DiagnosticsEngine::Level DiagLevel, const Diagnostic &Diag,
    StringRef DiagName, SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
    bool AllowIO, bool EnableNoLintBlocks) {
  return PImpl->shouldSuppress(DiagLevel, Diag, DiagName, NoLintErrors, AllowIO,
                               EnableNoLintBlocks);
}

} // namespace clang::tidy
