//===--- ClangTidyCheck.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_CLANGTIDYCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H

#include "ClangTidyDiagnosticConsumer.h"
#include "ClangTidyOptions.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/Diagnostic.h"
#include <optional>
#include <type_traits>
#include <utility>
#include <vector>

namespace clang {

class SourceManager;

namespace tidy {

/// This class should be specialized by any enum type that needs to be converted
/// to and from an \ref llvm::StringRef.
template <class T> struct OptionEnumMapping {
  // Specializations of this struct must implement this function.
  static ArrayRef<std::pair<T, StringRef>> getEnumMapping() = delete;
};

/// Base class for all clang-tidy checks.
///
/// To implement a ``ClangTidyCheck``, write a subclass and override some of the
/// base class's methods. E.g. to implement a check that validates namespace
/// declarations, override ``registerMatchers``:
///
/// ~~~{.cpp}
/// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
///   Finder->addMatcher(namespaceDecl().bind("namespace"), this);
/// }
/// ~~~
///
/// and then override ``check(const MatchResult &Result)`` to do the actual
/// check for each match.
///
/// A new ``ClangTidyCheck`` instance is created per translation unit.
///
/// FIXME: Figure out whether carrying information from one TU to another is
/// useful/necessary.
class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
public:
  /// Initializes the check with \p CheckName and \p Context.
  ///
  /// Derived classes must implement the constructor with this signature or
  /// delegate it. If a check needs to read options, it can do this in the
  /// constructor using the Options.get() methods below.
  ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);

  /// Override this to disable registering matchers and PP callbacks if an
  /// invalid language version is being used.
  ///
  /// For example if a check is examining overloaded functions then this should
  /// be overridden to return false when the CPlusPlus flag is not set in
  /// \p LangOpts.
  virtual bool isLanguageVersionSupported(const LangOptions &LangOpts) const {
    return true;
  }

  /// Override this to register ``PPCallbacks`` in the preprocessor.
  ///
  /// This should be used for clang-tidy checks that analyze preprocessor-
  /// dependent properties, e.g. include directives and macro definitions.
  ///
  /// This will only be executed if the function isLanguageVersionSupported
  /// returns true.
  ///
  /// There are two Preprocessors to choose from that differ in how they handle
  /// modular #includes:
  ///  - PP is the real Preprocessor. It doesn't walk into modular #includes and
  ///    thus doesn't generate PPCallbacks for their contents.
  ///  - ModuleExpanderPP preprocesses the whole translation unit in the
  ///    non-modular mode, which allows it to generate PPCallbacks not only for
  ///    the main file and textual headers, but also for all transitively
  ///    included modular headers when the analysis runs with modules enabled.
  ///    When modules are not enabled ModuleExpanderPP just points to the real
  ///    preprocessor.
  virtual void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
                                   Preprocessor *ModuleExpanderPP) {}

  /// Override this to register AST matchers with \p Finder.
  ///
  /// This should be used by clang-tidy checks that analyze code properties that
  /// dependent on AST knowledge.
  ///
  /// You can register as many matchers as necessary with \p Finder. Usually,
  /// "this" will be used as callback, but you can also specify other callback
  /// classes. Thereby, different matchers can trigger different callbacks.
  ///
  /// This will only be executed if the function isLanguageVersionSupported
  /// returns true.
  ///
  /// If you need to merge information between the different matchers, you can
  /// store these as members of the derived class. However, note that all
  /// matches occur in the order of the AST traversal.
  virtual void registerMatchers(ast_matchers::MatchFinder *Finder) {}

  /// ``ClangTidyChecks`` that register ASTMatchers should do the actual
  /// work in here.
  virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {}

  /// Add a diagnostic with the check's name.
  DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
                         DiagnosticIDs::Level Level = DiagnosticIDs::Warning);

  /// Add a diagnostic with the check's name.
  DiagnosticBuilder diag(StringRef Description,
                         DiagnosticIDs::Level Level = DiagnosticIDs::Warning);

  /// Adds a diagnostic to report errors in the check's configuration.
  DiagnosticBuilder
  configurationDiag(StringRef Description,
                    DiagnosticIDs::Level Level = DiagnosticIDs::Warning) const;

  /// Should store all options supported by this check with their
  /// current values or default values for options that haven't been overridden.
  ///
  /// The check should use ``Options.store()`` to store each option it supports
  /// whether it has the default value or it has been overridden.
  virtual void storeOptions(ClangTidyOptions::OptionMap &Options) {}

  /// Provides access to the ``ClangTidyCheck`` options via check-local
  /// names.
  ///
  /// Methods of this class prepend ``CheckName + "."`` to translate check-local
  /// option names to global option names.
  class OptionsView {
    void diagnoseBadIntegerOption(const Twine &Lookup,
                                  StringRef Unparsed) const;
    void diagnoseBadBooleanOption(const Twine &Lookup,
                                  StringRef Unparsed) const;
    void diagnoseBadEnumOption(const Twine &Lookup, StringRef Unparsed,
                               StringRef Suggestion = StringRef()) const;

  public:
    /// Initializes the instance using \p CheckName + "." as a prefix.
    OptionsView(StringRef CheckName,
                const ClangTidyOptions::OptionMap &CheckOptions,
                ClangTidyContext *Context);

    /// Read a named option from the ``Context``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, return
    /// ``std::nullopt``.
    std::optional<StringRef> get(StringRef LocalName) const;

    /// Read a named option from the ``Context``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, returns
    /// \p Default.
    StringRef get(StringRef LocalName, StringRef Default) const;

    /// Read a named option from the ``Context``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, return ``std::nullopt``.
    std::optional<StringRef> getLocalOrGlobal(StringRef LocalName) const;

    /// Read a named option from the ``Context``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, returns \p Default.
    StringRef getLocalOrGlobal(StringRef LocalName, StringRef Default) const;

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present,
    ///  return ``std::nullopt``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return ``std::nullopt``.
    template <typename T>
    std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
    get(StringRef LocalName) const {
      if (std::optional<StringRef> Value = get(LocalName)) {
        T Result{};
        if (!StringRef(*Value).getAsInteger(10, Result))
          return Result;
        diagnoseBadIntegerOption(NamePrefix + LocalName, *Value);
      }
      return std::nullopt;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is `none`, `null`,
    /// `-1` or empty, return ``std::nullopt``. If the corresponding
    /// key is not present, return \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    template <typename T>
    std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
    get(StringRef LocalName, std::optional<T> Default) const {
      if (std::optional<StringRef> Value = get(LocalName)) {
        if (Value == "" || Value == "none" || Value == "null" ||
            (std::is_unsigned_v<T> && Value == "-1"))
          return std::nullopt;
        T Result{};
        if (!StringRef(*Value).getAsInteger(10, Result))
          return Result;
        diagnoseBadIntegerOption(NamePrefix + LocalName, *Value);
      }
      return Default;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, return
    /// \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    template <typename T>
    std::enable_if_t<std::is_integral_v<T>, T> get(StringRef LocalName,
                                                   T Default) const {
      return get<T>(LocalName).value_or(Default);
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, return ``std::nullopt``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return ``std::nullopt``.
    template <typename T>
    std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
    getLocalOrGlobal(StringRef LocalName) const {
      std::optional<StringRef> ValueOr = get(LocalName);
      bool IsGlobal = false;
      if (!ValueOr) {
        IsGlobal = true;
        ValueOr = getLocalOrGlobal(LocalName);
        if (!ValueOr)
          return std::nullopt;
      }
      T Result{};
      if (!StringRef(*ValueOr).getAsInteger(10, Result))
        return Result;
      diagnoseBadIntegerOption(
          IsGlobal ? Twine(LocalName) : NamePrefix + LocalName, *ValueOr);
      return std::nullopt;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, return \p Default. If the value value was found
    /// and equals ``none``, ``null``, ``-1`` or empty, return ``std::nullopt``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    template <typename T>
    std::enable_if_t<std::is_integral_v<T>, std::optional<T>>
    getLocalOrGlobal(StringRef LocalName, std::optional<T> Default) const {
      std::optional<StringRef> ValueOr = get(LocalName);
      bool IsGlobal = false;
      if (!ValueOr) {
        IsGlobal = true;
        ValueOr = getLocalOrGlobal(LocalName);
        if (!ValueOr)
          return Default;
      }
      T Result{};
      if (ValueOr == "" || ValueOr == "none" || ValueOr == "null" ||
          (std::is_unsigned_v<T> && ValueOr == "-1"))
        return std::nullopt;
      if (!StringRef(*ValueOr).getAsInteger(10, Result))
        return Result;
      diagnoseBadIntegerOption(
          IsGlobal ? Twine(LocalName) : NamePrefix + LocalName, *ValueOr);
      return Default;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, return \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    template <typename T>
    std::enable_if_t<std::is_integral_v<T>, T>
    getLocalOrGlobal(StringRef LocalName, T Default) const {
      return getLocalOrGlobal<T>(LocalName).value_or(Default);
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// enum type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, return
    /// ``std::nullopt``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return ``std::nullopt``.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum_v<T>, std::optional<T>>
    get(StringRef LocalName, bool IgnoreCase = false) const {
      if (std::optional<int64_t> ValueOr =
              getEnumInt(LocalName, typeEraseMapping<T>(), false, IgnoreCase))
        return static_cast<T>(*ValueOr);
      return std::nullopt;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// enum type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present,
    /// return \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum_v<T>, T> get(StringRef LocalName, T Default,
                                               bool IgnoreCase = false) const {
      return get<T>(LocalName, IgnoreCase).value_or(Default);
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// enum type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, returns ``std::nullopt``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return ``std::nullopt``.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum_v<T>, std::optional<T>>
    getLocalOrGlobal(StringRef LocalName, bool IgnoreCase = false) const {
      if (std::optional<int64_t> ValueOr =
              getEnumInt(LocalName, typeEraseMapping<T>(), true, IgnoreCase))
        return static_cast<T>(*ValueOr);
      return std::nullopt;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// enum type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either return \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum_v<T>, T>
    getLocalOrGlobal(StringRef LocalName, T Default,
                     bool IgnoreCase = false) const {
      return getLocalOrGlobal<T>(LocalName, IgnoreCase).value_or(Default);
    }

    /// Stores an option with the check-local name \p LocalName with
    /// string value \p Value to \p Options.
    void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
               StringRef Value) const;

    /// Stores an option with the check-local name \p LocalName with
    /// integer value \p Value to \p Options.
    template <typename T>
    std::enable_if_t<std::is_integral_v<T>>
    store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
          T Value) const {
      if constexpr (std::is_signed_v<T>)
        storeInt(Options, LocalName, Value);
      else
        storeUnsigned(Options, LocalName, Value);
    }

    /// Stores an option with the check-local name \p LocalName with
    /// integer value \p Value to \p Options. If the value is empty
    /// stores ``
    template <typename T>
    std::enable_if_t<std::is_integral_v<T>>
    store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
          std::optional<T> Value) const {
      if (Value)
        store(Options, LocalName, *Value);
      else
        store(Options, LocalName, "none");
    }

    /// Stores an option with the check-local name \p LocalName as the string
    /// representation of the Enum \p Value to \p Options.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum_v<T>>
    store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
          T Value) const {
      ArrayRef<std::pair<T, StringRef>> Mapping =
          OptionEnumMapping<T>::getEnumMapping();
      auto Iter = llvm::find_if(
          Mapping, [&](const std::pair<T, StringRef> &NameAndEnum) {
            return NameAndEnum.first == Value;
          });
      assert(Iter != Mapping.end() && "Unknown Case Value");
      store(Options, LocalName, Iter->second);
    }

  private:
    using NameAndValue = std::pair<int64_t, StringRef>;

    std::optional<int64_t> getEnumInt(StringRef LocalName,
                                      ArrayRef<NameAndValue> Mapping,
                                      bool CheckGlobal, bool IgnoreCase) const;

    template <typename T>
    std::enable_if_t<std::is_enum_v<T>, std::vector<NameAndValue>>
    typeEraseMapping() const {
      ArrayRef<std::pair<T, StringRef>> Mapping =
          OptionEnumMapping<T>::getEnumMapping();
      std::vector<NameAndValue> Result;
      Result.reserve(Mapping.size());
      for (auto &MappedItem : Mapping) {
        Result.emplace_back(static_cast<int64_t>(MappedItem.first),
                            MappedItem.second);
      }
      return Result;
    }

    void storeInt(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
                  int64_t Value) const;

    void storeUnsigned(ClangTidyOptions::OptionMap &Options,
                       StringRef LocalName, uint64_t Value) const;

    std::string NamePrefix;
    const ClangTidyOptions::OptionMap &CheckOptions;
    ClangTidyContext *Context;
  };

private:
  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
  std::string CheckName;
  ClangTidyContext *Context;

protected:
  OptionsView Options;
  /// Returns the main file name of the current translation unit.
  StringRef getCurrentMainFile() const { return Context->getCurrentFile(); }
  /// Returns the language options from the context.
  const LangOptions &getLangOpts() const { return Context->getLangOpts(); }
  /// Returns true when the check is run in a use case when only 1 fix will be
  /// applied at a time.
  bool areDiagsSelfContained() const {
    return Context->areDiagsSelfContained();
  }
  StringRef getID() const override { return CheckName; }
};

/// Read a named option from the ``Context`` and parse it as a bool.
///
/// Reads the option with the check-local name \p LocalName from the
/// ``CheckOptions``. If the corresponding key is not present, return
/// ``std::nullopt``.
///
/// If the corresponding key can't be parsed as a bool, emit a
/// diagnostic and return ``std::nullopt``.
template <>
std::optional<bool>
ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName) const;

/// Read a named option from the ``Context`` and parse it as a bool.
///
/// Reads the option with the check-local name \p LocalName from the
/// ``CheckOptions``. If the corresponding key is not present, return
/// \p Default.
///
/// If the corresponding key can't be parsed as a bool, emit a
/// diagnostic and return \p Default.
template <>
std::optional<bool>
ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName) const;

/// Stores an option with the check-local name \p LocalName with
/// bool value \p Value to \p Options.
template <>
void ClangTidyCheck::OptionsView::store<bool>(
    ClangTidyOptions::OptionMap &Options, StringRef LocalName,
    bool Value) const;


} // namespace tidy
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
