//===--- Diagnostics.h -------------------------------------------*- 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_CLANGD_DIAGNOSTICS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H

#include "Protocol.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/SourceMgr.h"
#include <cassert>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

namespace clang {
namespace tidy {
class ClangTidyContext;
} // namespace tidy
namespace clangd {

struct ClangdDiagnosticOptions {
  /// If true, Clangd uses an LSP extension to embed the fixes with the
  /// diagnostics that are sent to the client.
  bool EmbedFixesInDiagnostics = false;

  /// If true, Clangd uses the relatedInformation field to include other
  /// locations (in particular attached notes).
  /// Otherwise, these are flattened into the diagnostic message.
  bool EmitRelatedLocations = false;

  /// If true, Clangd uses an LSP extension to send the diagnostic's
  /// category to the client. The category typically describes the compilation
  /// stage during which the issue was produced, e.g. "Semantic Issue" or "Parse
  /// Issue".
  bool SendDiagnosticCategory = false;

  /// If true, Clangd will add a number of available fixes to the diagnostic's
  /// message.
  bool DisplayFixesCount = true;
};

/// Contains basic information about a diagnostic.
struct DiagBase {
  std::string Message;
  // Intended to be used only in error messages.
  // May be relative, absolute or even artificially constructed.
  std::string File;
  // Absolute path to containing file, if available.
  std::optional<std::string> AbsFile;

  clangd::Range Range;
  DiagnosticsEngine::Level Severity = DiagnosticsEngine::Note;
  std::string Category;
  // Since File is only descriptive, we store a separate flag to distinguish
  // diags from the main file.
  bool InsideMainFile = false;
  unsigned ID = 0; // e.g. member of clang::diag, or clang-tidy assigned ID.
  // Feature modules can make use of this field to propagate data from a
  // diagnostic to a CodeAction request. Each module should only append to the
  // list.
  llvm::json::Object OpaqueData;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const DiagBase &D);

/// Represents a single fix-it that editor can apply to fix the error.
struct Fix {
  /// Message for the fix-it.
  std::string Message;
  /// TextEdits from clang's fix-its. Must be non-empty.
  llvm::SmallVector<TextEdit, 1> Edits;

  /// Annotations for the Edits.
  llvm::SmallVector<std::pair<ChangeAnnotationIdentifier, ChangeAnnotation>>
      Annotations;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Fix &F);

/// Represents a note for the diagnostic. Severity of notes can only be 'note'
/// or 'remark'.
struct Note : DiagBase {};

/// A top-level diagnostic that may have Notes and Fixes.
struct Diag : DiagBase {
  std::string Name; // if ID was recognized.
  // The source of this diagnostic.
  enum DiagSource {
    Unknown,
    Clang,
    ClangTidy,
    Clangd,
    ClangdConfig,
  } Source = Unknown;
  /// Elaborate on the problem, usually pointing to a related piece of code.
  std::vector<Note> Notes;
  /// *Alternative* fixes for this diagnostic, one should be chosen.
  std::vector<Fix> Fixes;
  llvm::SmallVector<DiagnosticTag, 1> Tags;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diag &D);

Diag toDiag(const llvm::SMDiagnostic &, Diag::DiagSource Source);

/// Conversion to LSP diagnostics. Formats the error message of each diagnostic
/// to include all its notes. Notes inside main file are also provided as
/// separate diagnostics with their corresponding fixits. Notes outside main
/// file do not have a corresponding LSP diagnostic, but can still be included
/// as part of their main diagnostic's message.
void toLSPDiags(
    const Diag &D, const URIForFile &File, const ClangdDiagnosticOptions &Opts,
    llvm::function_ref<void(clangd::Diagnostic, llvm::ArrayRef<Fix>)> OutFn);

/// Convert from clang diagnostic level to LSP severity.
int getSeverity(DiagnosticsEngine::Level L);

/// Returns a URI providing more information about a particular diagnostic.
std::optional<std::string> getDiagnosticDocURI(Diag::DiagSource, unsigned ID,
                                               llvm::StringRef Name);

/// StoreDiags collects the diagnostics that can later be reported by
/// clangd. It groups all notes for a diagnostic into a single Diag
/// and filters out diagnostics that don't mention the main file (i.e. neither
/// the diag itself nor its notes are in the main file).
class StoreDiags : public DiagnosticConsumer {
public:
  // The ClangTidyContext populates Source and Name for clang-tidy diagnostics.
  std::vector<Diag> take(const clang::tidy::ClangTidyContext *Tidy = nullptr);

  void BeginSourceFile(const LangOptions &Opts,
                       const Preprocessor *PP) override;
  void EndSourceFile() override;
  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                        const clang::Diagnostic &Info) override;

  /// When passed a main diagnostic, returns fixes to add to it.
  /// When passed a note diagnostic, returns fixes to replace it with.
  using DiagFixer = std::function<std::vector<Fix>(DiagnosticsEngine::Level,
                                                   const clang::Diagnostic &)>;
  using LevelAdjuster = std::function<DiagnosticsEngine::Level(
      DiagnosticsEngine::Level, const clang::Diagnostic &)>;
  using DiagCallback =
      std::function<void(const clang::Diagnostic &, clangd::Diag &)>;
  /// If set, possibly adds fixes for diagnostics using \p Fixer.
  void contributeFixes(DiagFixer Fixer) { this->Fixer = Fixer; }
  /// If set, this allows the client of this class to adjust the level of
  /// diagnostics, such as promoting warnings to errors, or ignoring
  /// diagnostics.
  void setLevelAdjuster(LevelAdjuster Adjuster) { this->Adjuster = Adjuster; }
  /// Invokes a callback every time a diagnostics is completely formed. Handler
  /// of the callback can also mutate the diagnostic.
  void setDiagCallback(DiagCallback CB) { DiagCB = std::move(CB); }

private:
  void flushLastDiag();

  DiagFixer Fixer = nullptr;
  LevelAdjuster Adjuster = nullptr;
  DiagCallback DiagCB = nullptr;
  std::vector<Diag> Output;
  std::optional<LangOptions> LangOpts;
  std::optional<Diag> LastDiag;
  std::optional<FullSourceLoc> LastDiagLoc;  // Valid only when LastDiag is set.
  bool LastDiagOriginallyError = false;      // Valid only when LastDiag is set.
  SourceManager *OrigSrcMgr = nullptr;

  llvm::DenseSet<std::pair<unsigned, unsigned>> IncludedErrorLocations;
};

/// Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
bool isDiagnosticSuppressed(const clang::Diagnostic &Diag,
                            const llvm::StringSet<> &Suppressed,
                            const LangOptions &);
/// Take a user-specified diagnostic code, and convert it to a normalized form
/// stored in the config and consumed by isDiagnosticsSuppressed.
///
/// (This strips err_ and -W prefix so we can match with or without them.)
llvm::StringRef normalizeSuppressedCode(llvm::StringRef);

} // namespace clangd
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H
