//===--- CodeComplete.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
//
//===----------------------------------------------------------------------===//
//
// Code completion provides suggestions for what the user might type next.
// After "std::string S; S." we might suggest members of std::string.
// Signature help describes the parameters of a function as you type them.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H

#include "ASTSignals.h"
#include "Compiler.h"
#include "Protocol.h"
#include "Quality.h"
#include "index/Index.h"
#include "index/Symbol.h"
#include "index/SymbolOrigin.h"
#include "support/Markup.h"
#include "support/Path.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/CodeCompleteOptions.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <functional>
#include <future>

namespace clang {
class NamedDecl;
namespace clangd {
struct PreambleData;
struct CodeCompletion;

struct CodeCompleteOptions {
  /// Returns options that can be passed to clang's completion engine.
  clang::CodeCompleteOptions getClangCompleteOpts() const;

  /// When true, completion items will contain expandable code snippets in
  /// completion (e.g.  `return ${1:expression}` or `foo(${1:int a}, ${2:int
  /// b})).
  bool EnableSnippets = false;

  /// Include results that are not legal completions in the current context.
  /// For example, private members are usually inaccessible.
  bool IncludeIneligibleResults = false;

  /// Combine overloads into a single completion item where possible.
  /// If none, the implementation may choose an appropriate behavior.
  /// (In practice, ClangdLSPServer enables bundling if the client claims
  /// to supports signature help).
  llvm::Optional<bool> BundleOverloads;

  /// Limit the number of results returned (0 means no limit).
  /// If more results are available, we set CompletionList.isIncomplete.
  size_t Limit = 0;

  /// Whether to present doc comments as plain-text or markdown.
  MarkupKind DocumentationFormat = MarkupKind::PlainText;

  enum IncludeInsertion {
    IWYU,
    NeverInsert,
  } InsertIncludes = IncludeInsertion::IWYU;

  /// A visual indicator to prepend to the completion label to indicate whether
  /// completion result would trigger an #include insertion or not.
  struct IncludeInsertionIndicator {
    std::string Insert = "•";
    std::string NoInsert = " ";
  } IncludeIndicator;

  /// Expose origins of completion items in the label (for debugging).
  bool ShowOrigins = false;

  // Populated internally by clangd, do not set.
  /// If `Index` is set, it is used to augment the code completion
  /// results.
  /// FIXME(ioeric): we might want a better way to pass the index around inside
  /// clangd.
  const SymbolIndex *Index = nullptr;

  const ASTSignals *MainFileSignals = nullptr;
  /// Include completions that require small corrections, e.g. change '.' to
  /// '->' on member access etc.
  bool IncludeFixIts = false;

  /// Whether to generate snippets for function arguments on code-completion.
  /// Needs snippets to be enabled as well.
  bool EnableFunctionArgSnippets = true;

  /// Whether to include index symbols that are not defined in the scopes
  /// visible from the code completion point. This applies in contexts without
  /// explicit scope qualifiers.
  ///
  /// Such completions can insert scope qualifiers.
  bool AllScopes = false;

  /// Whether to use the clang parser, or fallback to text-based completion
  /// (using identifiers in the current file and symbol indexes).
  enum CodeCompletionParse {
    /// Block until we can run the parser (e.g. preamble is built).
    /// Return an error if this fails.
    AlwaysParse,
    /// Run the parser if inputs (preamble) are ready.
    /// Otherwise, use text-based completion.
    ParseIfReady,
    /// Always use text-based completion.
    NeverParse,
  } RunParser = ParseIfReady;

  /// Callback invoked on all CompletionCandidate after they are scored and
  /// before they are ranked (by -Score). Thus the results are yielded in
  /// arbitrary order.
  ///
  /// This callbacks allows capturing various internal structures used by clangd
  /// during code completion. Eg: Symbol quality and relevance signals.
  std::function<void(const CodeCompletion &, const SymbolQualitySignals &,
                     const SymbolRelevanceSignals &, float Score)>
      RecordCCResult;

  /// Model to use for ranking code completion candidates.
  enum CodeCompletionRankingModel {
    Heuristics,
    DecisionForest,
  } RankingModel = DecisionForest;

  /// Callback used to score a CompletionCandidate if DecisionForest ranking
  /// model is enabled.
  /// This allows us to inject experimental models and compare them with
  /// baseline model using A/B testing.
  std::function<DecisionForestScores(
      const SymbolQualitySignals &, const SymbolRelevanceSignals &, float Base)>
      DecisionForestScorer = &evaluateDecisionForest;
  /// Weight for combining NameMatch and Prediction of DecisionForest.
  /// CompletionScore is NameMatch * pow(Base, Prediction).
  /// The optimal value of Base largely depends on the semantics of the model
  /// and prediction score (e.g. algorithm used during training, number of
  /// trees, etc.). Usually if the range of Prediciton is [-20, 20] then a Base
  /// in [1.2, 1.7] works fine.
  /// Semantics: E.g. For Base = 1.3, if the Prediciton score reduces by 2.6
  /// points then completion score reduces by 50% or 1.3^(-2.6).
  float DecisionForestBase = 1.3f;
};

// Semi-structured representation of a code-complete suggestion for our C++ API.
// We don't use the LSP structures here (unlike most features) as we want
// to expose more data to allow for more precise testing and evaluation.
struct CodeCompletion {
  // The unqualified name of the symbol or other completion item.
  std::string Name;
  // The name of the symbol for filtering and sorting purposes. Typically the
  // same as `Name`, but may be different e.g. for ObjC methods, `Name` is the
  // first selector fragment but the `FilterText` is the entire selector.
  std::string FilterText;
  // The scope qualifier for the symbol name. e.g. "ns1::ns2::"
  // Empty for non-symbol completions. Not inserted, but may be displayed.
  std::string Scope;
  // Text that must be inserted before the name, and displayed (e.g. base::).
  std::string RequiredQualifier;
  // Details to be displayed following the name. Not inserted.
  std::string Signature;
  // Text to be inserted following the name, in snippet format.
  std::string SnippetSuffix;
  // Type to be displayed for this completion.
  std::string ReturnType;
  // The parsed documentation comment.
  llvm::Optional<markup::Document> Documentation;
  CompletionItemKind Kind = CompletionItemKind::Missing;
  // This completion item may represent several symbols that can be inserted in
  // the same way, such as function overloads. In this case BundleSize > 1, and
  // the following fields are summaries:
  //  - Signature is e.g. "(...)" for functions.
  //  - SnippetSuffix is similarly e.g. "(${0})".
  //  - ReturnType may be empty
  //  - Documentation may be from one symbol, or a combination of several
  // Other fields should apply equally to all bundled completions.
  unsigned BundleSize = 1;
  SymbolOrigin Origin = SymbolOrigin::Unknown;

  struct IncludeCandidate {
    // The header through which this symbol could be included.
    // Quoted string as expected by an #include directive, e.g. "<memory>".
    // Empty for non-symbol completions, or when not known.
    std::string Header;
    // Present if Header should be inserted to use this item.
    llvm::Optional<TextEdit> Insertion;
  };
  // All possible include headers ranked by preference. By default, the first
  // include is used.
  // If we've bundled together overloads that have different sets of includes,
  // thse includes may not be accurate for all of them.
  llvm::SmallVector<IncludeCandidate, 1> Includes;

  /// Holds information about small corrections that needs to be done. Like
  /// converting '->' to '.' on member access.
  std::vector<TextEdit> FixIts;

  /// Holds the range of the token we are going to replace with this completion.
  Range CompletionTokenRange;

  // Scores are used to rank completion items.
  struct Scores {
    // The score that items are ranked by.
    float Total = 0.f;

    // The finalScore with the fuzzy name match score excluded.
    // When filtering client-side, editors should calculate the new fuzzy score,
    // whose scale is 0-1 (with 1 = prefix match, special case 2 = exact match),
    // and recompute finalScore = fuzzyScore * symbolScore.
    float ExcludingName = 0.f;

    // Component scores that contributed to the final score:

    // Quality describes how important we think this candidate is,
    // independent of the query.
    // e.g. symbols with lots of incoming references have higher quality.
    float Quality = 0.f;
    // Relevance describes how well this candidate matched the query.
    // e.g. symbols from nearby files have higher relevance.
    float Relevance = 0.f;
  };
  Scores Score;

  /// Indicates if this item is deprecated.
  bool Deprecated = false;

  // Serialize this to an LSP completion item. This is a lossy operation.
  CompletionItem render(const CodeCompleteOptions &) const;
};
raw_ostream &operator<<(raw_ostream &, const CodeCompletion &);
struct CodeCompleteResult {
  std::vector<CodeCompletion> Completions;
  bool HasMore = false;
  CodeCompletionContext::Kind Context = CodeCompletionContext::CCC_Other;
  // The text that is being directly completed.
  // Example: foo.pb^ -> foo.push_back()
  //              ~~
  // Typically matches the textEdit.range of Completions, but not guaranteed to.
  llvm::Optional<Range> CompletionRange;
  // Usually the source will be parsed with a real C++ parser.
  // But heuristics may be used instead if e.g. the preamble is not ready.
  bool RanParser = true;
};
raw_ostream &operator<<(raw_ostream &, const CodeCompleteResult &);

/// A speculative and asynchronous fuzzy find index request (based on cached
/// request) that can be sent before parsing sema. This would reduce completion
/// latency if the speculation succeeds.
struct SpeculativeFuzzyFind {
  /// A cached request from past code completions.
  /// Set by caller of `codeComplete()`.
  llvm::Optional<FuzzyFindRequest> CachedReq;
  /// The actual request used by `codeComplete()`.
  /// Set by `codeComplete()`. This can be used by callers to update cache.
  llvm::Optional<FuzzyFindRequest> NewReq;
  /// The result is consumed by `codeComplete()` if speculation succeeded.
  /// NOTE: the destructor will wait for the async call to finish.
  std::future<SymbolSlab> Result;
};

/// Gets code completions at a specified \p Pos in \p FileName.
///
/// If \p Preamble is nullptr, this runs code completion without compiling the
/// code.
///
/// If \p SpecFuzzyFind is set, a speculative and asynchronous fuzzy find index
/// request (based on cached request) will be run before parsing sema. In case
/// the speculative result is used by code completion (e.g. speculation failed),
/// the speculative result is not consumed, and `SpecFuzzyFind` is only
/// destroyed when the async request finishes.
CodeCompleteResult codeComplete(PathRef FileName, Position Pos,
                                const PreambleData *Preamble,
                                const ParseInputs &ParseInput,
                                CodeCompleteOptions Opts,
                                SpeculativeFuzzyFind *SpecFuzzyFind = nullptr);

/// Get signature help at a specified \p Pos in \p FileName.
SignatureHelp signatureHelp(PathRef FileName, Position Pos,
                            const PreambleData &Preamble,
                            const ParseInputs &ParseInput,
                            MarkupKind DocumentationFormat);

// For index-based completion, we only consider:
//   * symbols in namespaces or translation unit scopes (e.g. no class
//     members, no locals)
//   * enum constants in unscoped enum decl (e.g. "red" in "enum {red};")
//   * primary templates (no specializations)
// For the other cases, we let Clang do the completion because it does not
// need any non-local information and it will be much better at following
// lookup rules. Other symbols still appear in the index for other purposes,
// like workspace/symbols or textDocument/definition, but are not used for code
// completion.
bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx);

// Text immediately before the completion point that should be completed.
// This is heuristically derived from the source code, and is used when:
//   - semantic analysis fails
//   - semantic analysis may be slow, and we speculatively query the index
struct CompletionPrefix {
  // The unqualified partial name.
  // If there is none, begin() == end() == completion position.
  llvm::StringRef Name;
  // The spelled scope qualifier, such as Foo::.
  // If there is none, begin() == end() == Name.begin().
  llvm::StringRef Qualifier;
};
// Heuristically parses before Offset to determine what should be completed.
CompletionPrefix guessCompletionPrefix(llvm::StringRef Content,
                                       unsigned Offset);

// Whether it makes sense to complete at the point based on typed characters.
// For instance, we implicitly trigger at `a->^` but not at `a>^`.
bool allowImplicitCompletion(llvm::StringRef Content, unsigned Offset);

} // namespace clangd
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
