//===--- ClangTidyDiagnosticConsumer.h - clang-tidy -------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H

#include "ClangTidyOptions.h"
#include "ClangTidyProfiling.h"
#include "FileExtensionsSet.h"
#include "NoLintDirectiveHandler.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Tooling/Core/Diagnostic.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Regex.h"
#include <optional>

namespace clang {

class ASTContext;
class SourceManager;

namespace tidy {
class CachedGlobList;

/// A detected error complete with information to display diagnostic and
/// automatic fix.
///
/// This is used as an intermediate format to transport Diagnostics without a
/// dependency on a SourceManager.
///
/// FIXME: Make Diagnostics flexible enough to support this directly.
struct ClangTidyError : tooling::Diagnostic {
  ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory,
                 bool IsWarningAsError);

  bool IsWarningAsError;
  std::vector<std::string> EnabledDiagnosticAliases;
};

/// Contains displayed and ignored diagnostic counters for a ClangTidy run.
struct ClangTidyStats {
  unsigned ErrorsDisplayed = 0;
  unsigned ErrorsIgnoredCheckFilter = 0;
  unsigned ErrorsIgnoredNOLINT = 0;
  unsigned ErrorsIgnoredNonUserCode = 0;
  unsigned ErrorsIgnoredLineFilter = 0;

  unsigned errorsIgnored() const {
    return ErrorsIgnoredNOLINT + ErrorsIgnoredCheckFilter +
           ErrorsIgnoredNonUserCode + ErrorsIgnoredLineFilter;
  }
};

/// Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
/// provided by this context.
///
/// A \c ClangTidyCheck always has access to the active context to report
/// warnings like:
/// \code
/// Context->Diag(Loc, "Single-argument constructors must be explicit")
///     << FixItHint::CreateInsertion(Loc, "explicit ");
/// \endcode
class ClangTidyContext {
public:
  /// Initializes \c ClangTidyContext instance.
  ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
                   bool AllowEnablingAnalyzerAlphaCheckers = false,
                   bool EnableModuleHeadersParsing = false);
  /// Sets the DiagnosticsEngine that diag() will emit diagnostics to.
  // FIXME: this is required initialization, and should be a constructor param.
  // Fix the context -> diag engine -> consumer -> context initialization cycle.
  void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine) {
    this->DiagEngine = DiagEngine;
  }

  ~ClangTidyContext();

  /// Report any errors detected using this method.
  ///
  /// This is still under heavy development and will likely change towards using
  /// tablegen'd diagnostic IDs.
  /// FIXME: Figure out a way to manage ID spaces.
  DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
                         StringRef Description,
                         DiagnosticIDs::Level Level = DiagnosticIDs::Warning);

  DiagnosticBuilder diag(StringRef CheckName, StringRef Description,
                         DiagnosticIDs::Level Level = DiagnosticIDs::Warning);

  DiagnosticBuilder diag(const tooling::Diagnostic &Error);

  /// Report any errors to do with reading the configuration using this method.
  DiagnosticBuilder
  configurationDiag(StringRef Message,
                    DiagnosticIDs::Level Level = DiagnosticIDs::Warning);

  /// Check whether a given diagnostic should be suppressed due to the presence
  /// of a "NOLINT" suppression comment.
  /// This is exposed so that other tools that present clang-tidy diagnostics
  /// (such as clangd) can respect the same suppression rules as clang-tidy.
  /// This does not handle suppression of notes following a suppressed
  /// diagnostic; that is left to the caller as it requires maintaining state in
  /// between calls to this function.
  /// If any NOLINT is malformed, e.g. a BEGIN without a subsequent END, output
  /// \param NoLintErrors will return an error about it.
  /// If \param AllowIO is false, the function does not attempt to read source
  /// files from disk which are not already mapped into memory; such files are
  /// treated as not containing a suppression comment.
  /// \param EnableNoLintBlocks controls whether to honor NOLINTBEGIN/NOLINTEND
  /// blocks; if false, only considers line-level disabling.
  bool
  shouldSuppressDiagnostic(DiagnosticsEngine::Level DiagLevel,
                           const Diagnostic &Info,
                           SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
                           bool AllowIO = true, bool EnableNoLintBlocks = true);

  /// Sets the \c SourceManager of the used \c DiagnosticsEngine.
  ///
  /// This is called from the \c ClangTidyCheck base class.
  void setSourceManager(SourceManager *SourceMgr);

  /// Should be called when starting to process new translation unit.
  void setCurrentFile(StringRef File);

  /// Returns the main file name of the current translation unit.
  StringRef getCurrentFile() const { return CurrentFile; }

  /// Sets ASTContext for the current translation unit.
  void setASTContext(ASTContext *Context);

  /// Gets the language options from the AST context.
  const LangOptions &getLangOpts() const { return LangOpts; }

  /// Returns the name of the clang-tidy check which produced this
  /// diagnostic ID.
  std::string getCheckName(unsigned DiagnosticID) const;

  /// Returns \c true if the check is enabled for the \c CurrentFile.
  ///
  /// The \c CurrentFile can be changed using \c setCurrentFile.
  bool isCheckEnabled(StringRef CheckName) const;

  /// Returns \c true if the check should be upgraded to error for the
  /// \c CurrentFile.
  bool treatAsError(StringRef CheckName) const;

  /// Returns global options.
  const ClangTidyGlobalOptions &getGlobalOptions() const;

  /// Returns options for \c CurrentFile.
  ///
  /// The \c CurrentFile can be changed using \c setCurrentFile.
  const ClangTidyOptions &getOptions() const;

  /// Returns options for \c File. Does not change or depend on
  /// \c CurrentFile.
  ClangTidyOptions getOptionsForFile(StringRef File) const;

  const FileExtensionsSet &getHeaderFileExtensions() const {
    return HeaderFileExtensions;
  }

  const FileExtensionsSet &getImplementationFileExtensions() const {
    return ImplementationFileExtensions;
  }

  /// Returns \c ClangTidyStats containing issued and ignored diagnostic
  /// counters.
  const ClangTidyStats &getStats() const { return Stats; }

  /// Control profile collection in clang-tidy.
  void setEnableProfiling(bool Profile);
  bool getEnableProfiling() const { return Profile; }

  /// Control storage of profile date.
  void setProfileStoragePrefix(StringRef ProfilePrefix);
  std::optional<ClangTidyProfiling::StorageParams>
  getProfileStorageParams() const;

  /// Should be called when starting to process new translation unit.
  void setCurrentBuildDirectory(StringRef BuildDirectory) {
    CurrentBuildDirectory = std::string(BuildDirectory);
  }

  /// Returns build directory of the current translation unit.
  const std::string &getCurrentBuildDirectory() const {
    return CurrentBuildDirectory;
  }

  /// If the experimental alpha checkers from the static analyzer can be
  /// enabled.
  bool canEnableAnalyzerAlphaCheckers() const {
    return AllowEnablingAnalyzerAlphaCheckers;
  }

  // This method determines whether preprocessor-level module header parsing is
  // enabled using the `--experimental-enable-module-headers-parsing` option.
  bool canEnableModuleHeadersParsing() const {
    return EnableModuleHeadersParsing;
  }

  void setSelfContainedDiags(bool Value) { SelfContainedDiags = Value; }

  bool areDiagsSelfContained() const { return SelfContainedDiags; }

  using DiagLevelAndFormatString = std::pair<DiagnosticIDs::Level, std::string>;
  DiagLevelAndFormatString getDiagLevelAndFormatString(unsigned DiagnosticID,
                                                       SourceLocation Loc) {
    return {
        static_cast<DiagnosticIDs::Level>(
            DiagEngine->getDiagnosticLevel(DiagnosticID, Loc)),
        std::string(
            DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID))};
  }

  void setOptionsCollector(llvm::StringSet<> *Collector) {
    OptionsCollector = Collector;
  }
  llvm::StringSet<> *getOptionsCollector() const { return OptionsCollector; }

private:
  // Writes to Stats.
  friend class ClangTidyDiagnosticConsumer;

  DiagnosticsEngine *DiagEngine = nullptr;
  std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;

  std::string CurrentFile;
  ClangTidyOptions CurrentOptions;

  std::unique_ptr<CachedGlobList> CheckFilter;
  std::unique_ptr<CachedGlobList> WarningAsErrorFilter;

  FileExtensionsSet HeaderFileExtensions;
  FileExtensionsSet ImplementationFileExtensions;

  LangOptions LangOpts;

  ClangTidyStats Stats;

  std::string CurrentBuildDirectory;

  llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;

  bool Profile = false;
  std::string ProfilePrefix;

  bool AllowEnablingAnalyzerAlphaCheckers;
  bool EnableModuleHeadersParsing;

  bool SelfContainedDiags = false;

  NoLintDirectiveHandler NoLintHandler;
  llvm::StringSet<> *OptionsCollector = nullptr;
};

/// Gets the Fix attached to \p Diagnostic.
/// If there isn't a Fix attached to the diagnostic and \p AnyFix is true, Check
/// to see if exactly one note has a Fix and return it. Otherwise return
/// nullptr.
const llvm::StringMap<tooling::Replacements> *
getFixIt(const tooling::Diagnostic &Diagnostic, bool AnyFix);

/// A diagnostic consumer that turns each \c Diagnostic into a
/// \c SourceManager-independent \c ClangTidyError.
// FIXME: If we move away from unit-tests, this can be moved to a private
// implementation file.
class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
public:
  /// \param EnableNolintBlocks Enables diagnostic-disabling inside blocks of
  /// code, delimited by NOLINTBEGIN and NOLINTEND.
  ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx,
                              DiagnosticsEngine *ExternalDiagEngine = nullptr,
                              bool RemoveIncompatibleErrors = true,
                              bool GetFixesFromNotes = false,
                              bool EnableNolintBlocks = true);

  // FIXME: The concept of converting between FixItHints and Replacements is
  // more generic and should be pulled out into a more useful Diagnostics
  // library.
  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                        const Diagnostic &Info) override;

  // Retrieve the diagnostics that were captured.
  std::vector<ClangTidyError> take();

private:
  void finalizeLastError();
  void removeIncompatibleErrors();
  void removeDuplicatedDiagnosticsOfAliasCheckers();

  /// Returns the \c HeaderFilter constructed for the options set in the
  /// context.
  llvm::Regex *getHeaderFilter();

  /// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
  /// according to the diagnostic \p Location.
  void checkFilters(SourceLocation Location, const SourceManager &Sources);
  bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;

  void forwardDiagnostic(const Diagnostic &Info);

  ClangTidyContext &Context;
  DiagnosticsEngine *ExternalDiagEngine;
  bool RemoveIncompatibleErrors;
  bool GetFixesFromNotes;
  bool EnableNolintBlocks;
  std::vector<ClangTidyError> Errors;
  std::unique_ptr<llvm::Regex> HeaderFilter;
  bool LastErrorRelatesToUserCode = false;
  bool LastErrorPassesLineFilter = false;
  bool LastErrorWasIgnored = false;
};

} // end namespace tidy
} // end namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
