//===- CodeCompleteConsumer.h - Code Completion Interface -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the CodeCompleteConsumer class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H

#include "clang-c/Index.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Sema/CodeCompleteOptions.h"
#include "clang/Sema/DeclSpec.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
#include <memory>
#include <string>
#include <utility>

namespace clang {

class ASTContext;
class Decl;
class DeclContext;
class FunctionDecl;
class FunctionTemplateDecl;
class IdentifierInfo;
class LangOptions;
class NamedDecl;
class NestedNameSpecifier;
class Preprocessor;
class RawComment;
class Sema;
class UsingShadowDecl;

/// Default priority values for code-completion results based
/// on their kind.
enum {
  /// Priority for the next initialization in a constructor initializer
  /// list.
  CCP_NextInitializer = 7,

  /// Priority for an enumeration constant inside a switch whose
  /// condition is of the enumeration type.
  CCP_EnumInCase = 7,

  /// Priority for a send-to-super completion.
  CCP_SuperCompletion = 20,

  /// Priority for a declaration that is in the local scope.
  CCP_LocalDeclaration = 34,

  /// Priority for a member declaration found from the current
  /// method or member function.
  CCP_MemberDeclaration = 35,

  /// Priority for a language keyword (that isn't any of the other
  /// categories).
  CCP_Keyword = 40,

  /// Priority for a code pattern.
  CCP_CodePattern = 40,

  /// Priority for a non-type declaration.
  CCP_Declaration = 50,

  /// Priority for a type.
  CCP_Type = CCP_Declaration,

  /// Priority for a constant value (e.g., enumerator).
  CCP_Constant = 65,

  /// Priority for a preprocessor macro.
  CCP_Macro = 70,

  /// Priority for a nested-name-specifier.
  CCP_NestedNameSpecifier = 75,

  /// Priority for a result that isn't likely to be what the user wants,
  /// but is included for completeness.
  CCP_Unlikely = 80,

  /// Priority for the Objective-C "_cmd" implicit parameter.
  CCP_ObjC_cmd = CCP_Unlikely
};

/// Priority value deltas that are added to code-completion results
/// based on the context of the result.
enum {
  /// The result is in a base class.
  CCD_InBaseClass = 2,

  /// The result is a C++ non-static member function whose qualifiers
  /// exactly match the object type on which the member function can be called.
  CCD_ObjectQualifierMatch = -1,

  /// The selector of the given message exactly matches the selector
  /// of the current method, which might imply that some kind of delegation
  /// is occurring.
  CCD_SelectorMatch = -3,

  /// Adjustment to the "bool" type in Objective-C, where the typedef
  /// "BOOL" is preferred.
  CCD_bool_in_ObjC = 1,

  /// Adjustment for KVC code pattern priorities when it doesn't look
  /// like the
  CCD_ProbablyNotObjCCollection = 15,

  /// An Objective-C method being used as a property.
  CCD_MethodAsProperty = 2,

  /// An Objective-C block property completed as a setter with a
  /// block placeholder.
  CCD_BlockPropertySetter = 3
};

/// Priority value factors by which we will divide or multiply the
/// priority of a code-completion result.
enum {
  /// Divide by this factor when a code-completion result's type exactly
  /// matches the type we expect.
  CCF_ExactTypeMatch = 4,

  /// Divide by this factor when a code-completion result's type is
  /// similar to the type we expect (e.g., both arithmetic types, both
  /// Objective-C object pointer types).
  CCF_SimilarTypeMatch = 2
};

/// A simplified classification of types used when determining
/// "similar" types for code completion.
enum SimplifiedTypeClass {
  STC_Arithmetic,
  STC_Array,
  STC_Block,
  STC_Function,
  STC_ObjectiveC,
  STC_Other,
  STC_Pointer,
  STC_Record,
  STC_Void
};

/// Determine the simplified type class of the given canonical type.
SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T);

/// Determine the type that this declaration will have if it is used
/// as a type or in an expression.
QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND);

/// Determine the priority to be given to a macro code completion result
/// with the given name.
///
/// \param MacroName The name of the macro.
///
/// \param LangOpts Options describing the current language dialect.
///
/// \param PreferredTypeIsPointer Whether the preferred type for the context
/// of this macro is a pointer type.
unsigned getMacroUsagePriority(StringRef MacroName,
                               const LangOptions &LangOpts,
                               bool PreferredTypeIsPointer = false);

/// Determine the libclang cursor kind associated with the given
/// declaration.
CXCursorKind getCursorKindForDecl(const Decl *D);

/// The context in which code completion occurred, so that the
/// code-completion consumer can process the results accordingly.
class CodeCompletionContext {
public:
  enum Kind {
    /// An unspecified code-completion context.
    CCC_Other,

    /// An unspecified code-completion context where we should also add
    /// macro completions.
    CCC_OtherWithMacros,

    /// Code completion occurred within a "top-level" completion context,
    /// e.g., at namespace or global scope.
    CCC_TopLevel,

    /// Code completion occurred within an Objective-C interface,
    /// protocol, or category interface.
    CCC_ObjCInterface,

    /// Code completion occurred within an Objective-C implementation
    /// or category implementation.
    CCC_ObjCImplementation,

    /// Code completion occurred within the instance variable list of
    /// an Objective-C interface, implementation, or category implementation.
    CCC_ObjCIvarList,

    /// Code completion occurred within a class, struct, or union.
    CCC_ClassStructUnion,

    /// Code completion occurred where a statement (or declaration) is
    /// expected in a function, method, or block.
    CCC_Statement,

    /// Code completion occurred where an expression is expected.
    CCC_Expression,

    /// Code completion occurred where an Objective-C message receiver
    /// is expected.
    CCC_ObjCMessageReceiver,

    /// Code completion occurred on the right-hand side of a member
    /// access expression using the dot operator.
    ///
    /// The results of this completion are the members of the type being
    /// accessed. The type itself is available via
    /// \c CodeCompletionContext::getType().
    CCC_DotMemberAccess,

    /// Code completion occurred on the right-hand side of a member
    /// access expression using the arrow operator.
    ///
    /// The results of this completion are the members of the type being
    /// accessed. The type itself is available via
    /// \c CodeCompletionContext::getType().
    CCC_ArrowMemberAccess,

    /// Code completion occurred on the right-hand side of an Objective-C
    /// property access expression.
    ///
    /// The results of this completion are the members of the type being
    /// accessed. The type itself is available via
    /// \c CodeCompletionContext::getType().
    CCC_ObjCPropertyAccess,

    /// Code completion occurred after the "enum" keyword, to indicate
    /// an enumeration name.
    CCC_EnumTag,

    /// Code completion occurred after the "union" keyword, to indicate
    /// a union name.
    CCC_UnionTag,

    /// Code completion occurred after the "struct" or "class" keyword,
    /// to indicate a struct or class name.
    CCC_ClassOrStructTag,

    /// Code completion occurred where a protocol name is expected.
    CCC_ObjCProtocolName,

    /// Code completion occurred where a namespace or namespace alias
    /// is expected.
    CCC_Namespace,

    /// Code completion occurred where a type name is expected.
    CCC_Type,

    /// Code completion occurred where a new name is expected.
    CCC_Name,

    /// Code completion occurred where a new name is expected and a
    /// qualified name is permissible.
    CCC_PotentiallyQualifiedName,

    /// Code completion occurred where an macro is being defined.
    CCC_MacroName,

    /// Code completion occurred where a macro name is expected
    /// (without any arguments, in the case of a function-like macro).
    CCC_MacroNameUse,

    /// Code completion occurred within a preprocessor expression.
    CCC_PreprocessorExpression,

    /// Code completion occurred where a preprocessor directive is
    /// expected.
    CCC_PreprocessorDirective,

    /// Code completion occurred in a context where natural language is
    /// expected, e.g., a comment or string literal.
    ///
    /// This context usually implies that no completions should be added,
    /// unless they come from an appropriate natural-language dictionary.
    CCC_NaturalLanguage,

    /// Code completion for a selector, as in an \@selector expression.
    CCC_SelectorName,

    /// Code completion within a type-qualifier list.
    CCC_TypeQualifiers,

    /// Code completion in a parenthesized expression, which means that
    /// we may also have types here in C and Objective-C (as well as in C++).
    CCC_ParenthesizedExpression,

    /// Code completion where an Objective-C instance message is
    /// expected.
    CCC_ObjCInstanceMessage,

    /// Code completion where an Objective-C class message is expected.
    CCC_ObjCClassMessage,

    /// Code completion where the name of an Objective-C class is
    /// expected.
    CCC_ObjCInterfaceName,

    /// Code completion where an Objective-C category name is expected.
    CCC_ObjCCategoryName,

    /// Code completion inside the filename part of a #include directive.
    CCC_IncludedFile,

    /// An unknown context, in which we are recovering from a parsing
    /// error and don't know which completions we should give.
    CCC_Recovery
  };

  using VisitedContextSet = llvm::SmallPtrSet<DeclContext *, 8>;

private:
  Kind CCKind;

  /// The type that would prefer to see at this point (e.g., the type
  /// of an initializer or function parameter).
  QualType PreferredType;

  /// The type of the base object in a member access expression.
  QualType BaseType;

  /// The identifiers for Objective-C selector parts.
  ArrayRef<IdentifierInfo *> SelIdents;

  /// The scope specifier that comes before the completion token e.g.
  /// "a::b::"
  llvm::Optional<CXXScopeSpec> ScopeSpecifier;

  /// A set of declaration contexts visited by Sema when doing lookup for
  /// code completion.
  VisitedContextSet VisitedContexts;

public:
  /// Construct a new code-completion context of the given kind.
  CodeCompletionContext(Kind CCKind) : CCKind(CCKind), SelIdents(None) {}

  /// Construct a new code-completion context of the given kind.
  CodeCompletionContext(Kind CCKind, QualType T,
                        ArrayRef<IdentifierInfo *> SelIdents = None)
      : CCKind(CCKind), SelIdents(SelIdents) {
    if (CCKind == CCC_DotMemberAccess || CCKind == CCC_ArrowMemberAccess ||
        CCKind == CCC_ObjCPropertyAccess || CCKind == CCC_ObjCClassMessage ||
        CCKind == CCC_ObjCInstanceMessage)
      BaseType = T;
    else
      PreferredType = T;
  }

  /// Retrieve the kind of code-completion context.
  Kind getKind() const { return CCKind; }

  /// Retrieve the type that this expression would prefer to have, e.g.,
  /// if the expression is a variable initializer or a function argument, the
  /// type of the corresponding variable or function parameter.
  QualType getPreferredType() const { return PreferredType; }

  /// Retrieve the type of the base object in a member-access
  /// expression.
  QualType getBaseType() const { return BaseType; }

  /// Retrieve the Objective-C selector identifiers.
  ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; }

  /// Determines whether we want C++ constructors as results within this
  /// context.
  bool wantConstructorResults() const;

  /// Sets the scope specifier that comes before the completion token.
  /// This is expected to be set in code completions on qualfied specifiers
  /// (e.g. "a::b::").
  void setCXXScopeSpecifier(CXXScopeSpec SS) {
    this->ScopeSpecifier = std::move(SS);
  }

  /// Adds a visited context.
  void addVisitedContext(DeclContext *Ctx) {
    VisitedContexts.insert(Ctx);
  }

  /// Retrieves all visited contexts.
  const VisitedContextSet &getVisitedContexts() const {
    return VisitedContexts;
  }

  llvm::Optional<const CXXScopeSpec *> getCXXScopeSpecifier() {
    if (ScopeSpecifier)
      return ScopeSpecifier.getPointer();
    return llvm::None;
  }
};

/// Get string representation of \p Kind, useful for for debugging.
llvm::StringRef getCompletionKindString(CodeCompletionContext::Kind Kind);

/// A "string" used to describe how code completion can
/// be performed for an entity.
///
/// A code completion string typically shows how a particular entity can be
/// used. For example, the code completion string for a function would show
/// the syntax to call it, including the parentheses, placeholders for the
/// arguments, etc.
class CodeCompletionString {
public:
  /// The different kinds of "chunks" that can occur within a code
  /// completion string.
  enum ChunkKind {
    /// The piece of text that the user is expected to type to
    /// match the code-completion string, typically a keyword or the name of a
    /// declarator or macro.
    CK_TypedText,

    /// A piece of text that should be placed in the buffer, e.g.,
    /// parentheses or a comma in a function call.
    CK_Text,

    /// A code completion string that is entirely optional. For example,
    /// an optional code completion string that describes the default arguments
    /// in a function call.
    CK_Optional,

    /// A string that acts as a placeholder for, e.g., a function
    /// call argument.
    CK_Placeholder,

    /// A piece of text that describes something about the result but
    /// should not be inserted into the buffer.
    CK_Informative,
    /// A piece of text that describes the type of an entity or, for
    /// functions and methods, the return type.
    CK_ResultType,

    /// A piece of text that describes the parameter that corresponds
    /// to the code-completion location within a function call, message send,
    /// macro invocation, etc.
    CK_CurrentParameter,

    /// A left parenthesis ('(').
    CK_LeftParen,

    /// A right parenthesis (')').
    CK_RightParen,

    /// A left bracket ('[').
    CK_LeftBracket,

    /// A right bracket (']').
    CK_RightBracket,

    /// A left brace ('{').
    CK_LeftBrace,

    /// A right brace ('}').
    CK_RightBrace,

    /// A left angle bracket ('<').
    CK_LeftAngle,

    /// A right angle bracket ('>').
    CK_RightAngle,

    /// A comma separator (',').
    CK_Comma,

    /// A colon (':').
    CK_Colon,

    /// A semicolon (';').
    CK_SemiColon,

    /// An '=' sign.
    CK_Equal,

    /// Horizontal whitespace (' ').
    CK_HorizontalSpace,

    /// Vertical whitespace ('\\n' or '\\r\\n', depending on the
    /// platform).
    CK_VerticalSpace
  };

  /// One piece of the code completion string.
  struct Chunk {
    /// The kind of data stored in this piece of the code completion
    /// string.
    ChunkKind Kind = CK_Text;

    union {
      /// The text string associated with a CK_Text, CK_Placeholder,
      /// CK_Informative, or CK_Comma chunk.
      /// The string is owned by the chunk and will be deallocated
      /// (with delete[]) when the chunk is destroyed.
      const char *Text;

      /// The code completion string associated with a CK_Optional chunk.
      /// The optional code completion string is owned by the chunk, and will
      /// be deallocated (with delete) when the chunk is destroyed.
      CodeCompletionString *Optional;
    };

    Chunk() : Text(nullptr) {}

    explicit Chunk(ChunkKind Kind, const char *Text = "");

    /// Create a new text chunk.
    static Chunk CreateText(const char *Text);

    /// Create a new optional chunk.
    static Chunk CreateOptional(CodeCompletionString *Optional);

    /// Create a new placeholder chunk.
    static Chunk CreatePlaceholder(const char *Placeholder);

    /// Create a new informative chunk.
    static Chunk CreateInformative(const char *Informative);

    /// Create a new result type chunk.
    static Chunk CreateResultType(const char *ResultType);

    /// Create a new current-parameter chunk.
    static Chunk CreateCurrentParameter(const char *CurrentParameter);
  };

private:
  friend class CodeCompletionBuilder;
  friend class CodeCompletionResult;

  /// The number of chunks stored in this string.
  unsigned NumChunks : 16;

  /// The number of annotations for this code-completion result.
  unsigned NumAnnotations : 16;

  /// The priority of this code-completion string.
  unsigned Priority : 16;

  /// The availability of this code-completion result.
  unsigned Availability : 2;

  /// The name of the parent context.
  StringRef ParentName;

  /// A brief documentation comment attached to the declaration of
  /// entity being completed by this result.
  const char *BriefComment;

  CodeCompletionString(const Chunk *Chunks, unsigned NumChunks,
                       unsigned Priority, CXAvailabilityKind Availability,
                       const char **Annotations, unsigned NumAnnotations,
                       StringRef ParentName,
                       const char *BriefComment);
  ~CodeCompletionString() = default;

public:
  CodeCompletionString(const CodeCompletionString &) = delete;
  CodeCompletionString &operator=(const CodeCompletionString &) = delete;

  using iterator = const Chunk *;

  iterator begin() const { return reinterpret_cast<const Chunk *>(this + 1); }
  iterator end() const { return begin() + NumChunks; }
  bool empty() const { return NumChunks == 0; }
  unsigned size() const { return NumChunks; }

  const Chunk &operator[](unsigned I) const {
    assert(I < size() && "Chunk index out-of-range");
    return begin()[I];
  }

  /// Returns the text in the TypedText chunk.
  const char *getTypedText() const;

  /// Retrieve the priority of this code completion result.
  unsigned getPriority() const { return Priority; }

  /// Retrieve the availability of this code completion result.
  unsigned getAvailability() const { return Availability; }

  /// Retrieve the number of annotations for this code completion result.
  unsigned getAnnotationCount() const;

  /// Retrieve the annotation string specified by \c AnnotationNr.
  const char *getAnnotation(unsigned AnnotationNr) const;

  /// Retrieve the name of the parent context.
  StringRef getParentContextName() const {
    return ParentName;
  }

  const char *getBriefComment() const {
    return BriefComment;
  }

  /// Retrieve a string representation of the code completion string,
  /// which is mainly useful for debugging.
  std::string getAsString() const;
};

/// An allocator used specifically for the purpose of code completion.
class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
public:
  /// Copy the given string into this allocator.
  const char *CopyString(const Twine &String);
};

/// Allocator for a cached set of global code completions.
class GlobalCodeCompletionAllocator : public CodeCompletionAllocator {};

class CodeCompletionTUInfo {
  llvm::DenseMap<const DeclContext *, StringRef> ParentNames;
  std::shared_ptr<GlobalCodeCompletionAllocator> AllocatorRef;

public:
  explicit CodeCompletionTUInfo(
      std::shared_ptr<GlobalCodeCompletionAllocator> Allocator)
      : AllocatorRef(std::move(Allocator)) {}

  std::shared_ptr<GlobalCodeCompletionAllocator> getAllocatorRef() const {
    return AllocatorRef;
  }

  CodeCompletionAllocator &getAllocator() const {
    assert(AllocatorRef);
    return *AllocatorRef;
  }

  StringRef getParentName(const DeclContext *DC);
};

} // namespace clang

namespace llvm {

template <> struct isPodLike<clang::CodeCompletionString::Chunk> {
  static const bool value = true;
};

} // namespace llvm

namespace clang {

/// A builder class used to construct new code-completion strings.
class CodeCompletionBuilder {
public:
  using Chunk = CodeCompletionString::Chunk;

private:
  CodeCompletionAllocator &Allocator;
  CodeCompletionTUInfo &CCTUInfo;
  unsigned Priority = 0;
  CXAvailabilityKind Availability = CXAvailability_Available;
  StringRef ParentName;
  const char *BriefComment = nullptr;

  /// The chunks stored in this string.
  SmallVector<Chunk, 4> Chunks;

  SmallVector<const char *, 2> Annotations;

public:
  CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
                        CodeCompletionTUInfo &CCTUInfo)
      : Allocator(Allocator), CCTUInfo(CCTUInfo) {}

  CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
                        CodeCompletionTUInfo &CCTUInfo,
                        unsigned Priority, CXAvailabilityKind Availability)
      : Allocator(Allocator), CCTUInfo(CCTUInfo), Priority(Priority),
        Availability(Availability) {}

  /// Retrieve the allocator into which the code completion
  /// strings should be allocated.
  CodeCompletionAllocator &getAllocator() const { return Allocator; }

  CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }

  /// Take the resulting completion string.
  ///
  /// This operation can only be performed once.
  CodeCompletionString *TakeString();

  /// Add a new typed-text chunk.
  void AddTypedTextChunk(const char *Text);

  /// Add a new text chunk.
  void AddTextChunk(const char *Text);

  /// Add a new optional chunk.
  void AddOptionalChunk(CodeCompletionString *Optional);

  /// Add a new placeholder chunk.
  void AddPlaceholderChunk(const char *Placeholder);

  /// Add a new informative chunk.
  void AddInformativeChunk(const char *Text);

  /// Add a new result-type chunk.
  void AddResultTypeChunk(const char *ResultType);

  /// Add a new current-parameter chunk.
  void AddCurrentParameterChunk(const char *CurrentParameter);

  /// Add a new chunk.
  void AddChunk(CodeCompletionString::ChunkKind CK, const char *Text = "");

  void AddAnnotation(const char *A) { Annotations.push_back(A); }

  /// Add the parent context information to this code completion.
  void addParentContext(const DeclContext *DC);

  const char *getBriefComment() const { return BriefComment; }
  void addBriefComment(StringRef Comment);

  StringRef getParentName() const { return ParentName; }
};

/// Captures a result of code completion.
class CodeCompletionResult {
public:
  /// Describes the kind of result generated.
  enum ResultKind {
    /// Refers to a declaration.
    RK_Declaration = 0,

    /// Refers to a keyword or symbol.
    RK_Keyword,

    /// Refers to a macro.
    RK_Macro,

    /// Refers to a precomputed pattern.
    RK_Pattern
  };

  /// When Kind == RK_Declaration or RK_Pattern, the declaration we are
  /// referring to. In the latter case, the declaration might be NULL.
  const NamedDecl *Declaration = nullptr;

  union {
    /// When Kind == RK_Keyword, the string representing the keyword
    /// or symbol's spelling.
    const char *Keyword;

    /// When Kind == RK_Pattern, the code-completion string that
    /// describes the completion text to insert.
    CodeCompletionString *Pattern;

    /// When Kind == RK_Macro, the identifier that refers to a macro.
    const IdentifierInfo *Macro;
  };

  /// The priority of this particular code-completion result.
  unsigned Priority;

  /// Specifies which parameter (of a function, Objective-C method,
  /// macro, etc.) we should start with when formatting the result.
  unsigned StartParameter = 0;

  /// The kind of result stored here.
  ResultKind Kind;

  /// The cursor kind that describes this result.
  CXCursorKind CursorKind;

  /// The availability of this result.
  CXAvailabilityKind Availability = CXAvailability_Available;

  /// Fix-its that *must* be applied before inserting the text for the
  /// corresponding completion.
  ///
  /// By default, CodeCompletionBuilder only returns completions with empty
  /// fix-its. Extra completions with non-empty fix-its should be explicitly
  /// requested by setting CompletionOptions::IncludeFixIts.
  ///
  /// For the clients to be able to compute position of the cursor after
  /// applying fix-its, the following conditions are guaranteed to hold for
  /// RemoveRange of the stored fix-its:
  ///  - Ranges in the fix-its are guaranteed to never contain the completion
  ///  point (or identifier under completion point, if any) inside them, except
  ///  at the start or at the end of the range.
  ///  - If a fix-it range starts or ends with completion point (or starts or
  ///  ends after the identifier under completion point), it will contain at
  ///  least one character. It allows to unambiguously recompute completion
  ///  point after applying the fix-it.
  ///
  /// The intuition is that provided fix-its change code around the identifier
  /// we complete, but are not allowed to touch the identifier itself or the
  /// completion point. One example of completions with corrections are the ones
  /// replacing '.' with '->' and vice versa:
  ///
  /// std::unique_ptr<std::vector<int>> vec_ptr;
  /// In 'vec_ptr.^', one of the completions is 'push_back', it requires
  /// replacing '.' with '->'.
  /// In 'vec_ptr->^', one of the completions is 'release', it requires
  /// replacing '->' with '.'.
  std::vector<FixItHint> FixIts;

  /// Whether this result is hidden by another name.
  bool Hidden : 1;

  /// Whether this result was found via lookup into a base class.
  bool QualifierIsInformative : 1;

  /// Whether this declaration is the beginning of a
  /// nested-name-specifier and, therefore, should be followed by '::'.
  bool StartsNestedNameSpecifier : 1;

  /// Whether all parameters (of a function, Objective-C
  /// method, etc.) should be considered "informative".
  bool AllParametersAreInformative : 1;

  /// Whether we're completing a declaration of the given entity,
  /// rather than a use of that entity.
  bool DeclaringEntity : 1;

  /// If the result should have a nested-name-specifier, this is it.
  /// When \c QualifierIsInformative, the nested-name-specifier is
  /// informative rather than required.
  NestedNameSpecifier *Qualifier = nullptr;

  /// If this Decl was unshadowed by using declaration, this can store a
  /// pointer to the UsingShadowDecl which was used in the unshadowing process.
  /// This information can be used to uprank CodeCompletionResults / which have
  /// corresponding `using decl::qualified::name;` nearby.
  const UsingShadowDecl *ShadowDecl = nullptr;

  /// If the result is RK_Macro, this can store the information about the macro
  /// definition. This should be set in most cases but can be missing when
  /// the macro has been undefined.
  const MacroInfo *MacroDefInfo = nullptr;

  /// Build a result that refers to a declaration.
  CodeCompletionResult(const NamedDecl *Declaration, unsigned Priority,
                       NestedNameSpecifier *Qualifier = nullptr,
                       bool QualifierIsInformative = false,
                       bool Accessible = true,
                       std::vector<FixItHint> FixIts = std::vector<FixItHint>())
      : Declaration(Declaration), Priority(Priority), Kind(RK_Declaration),
        FixIts(std::move(FixIts)), Hidden(false),
        QualifierIsInformative(QualifierIsInformative),
        StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
        DeclaringEntity(false), Qualifier(Qualifier) {
    // FIXME: Add assert to check FixIts range requirements.
    computeCursorKindAndAvailability(Accessible);
  }

  /// Build a result that refers to a keyword or symbol.
  CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword)
      : Keyword(Keyword), Priority(Priority), Kind(RK_Keyword),
        CursorKind(CXCursor_NotImplemented), Hidden(false),
        QualifierIsInformative(false), StartsNestedNameSpecifier(false),
        AllParametersAreInformative(false), DeclaringEntity(false) {}

  /// Build a result that refers to a macro.
  CodeCompletionResult(const IdentifierInfo *Macro,
                       const MacroInfo *MI = nullptr,
                       unsigned Priority = CCP_Macro)
      : Macro(Macro), Priority(Priority), Kind(RK_Macro),
        CursorKind(CXCursor_MacroDefinition), Hidden(false),
        QualifierIsInformative(false), StartsNestedNameSpecifier(false),
        AllParametersAreInformative(false), DeclaringEntity(false),
        MacroDefInfo(MI) {}

  /// Build a result that refers to a pattern.
  CodeCompletionResult(CodeCompletionString *Pattern,
                       unsigned Priority = CCP_CodePattern,
                       CXCursorKind CursorKind = CXCursor_NotImplemented,
                   CXAvailabilityKind Availability = CXAvailability_Available,
                       const NamedDecl *D = nullptr)
      : Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern),
        CursorKind(CursorKind), Availability(Availability), Hidden(false),
        QualifierIsInformative(false), StartsNestedNameSpecifier(false),
        AllParametersAreInformative(false), DeclaringEntity(false) {}

  /// Build a result that refers to a pattern with an associated
  /// declaration.
  CodeCompletionResult(CodeCompletionString *Pattern, const NamedDecl *D,
                       unsigned Priority)
      : Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern),
        Hidden(false), QualifierIsInformative(false),
        StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
        DeclaringEntity(false) {
    computeCursorKindAndAvailability();
  }

  /// Retrieve the declaration stored in this result. This might be nullptr if
  /// Kind is RK_Pattern.
  const NamedDecl *getDeclaration() const {
    assert(((Kind == RK_Declaration) || (Kind == RK_Pattern)) &&
           "Not a declaration or pattern result");
    return Declaration;
  }

  /// Retrieve the keyword stored in this result.
  const char *getKeyword() const {
    assert(Kind == RK_Keyword && "Not a keyword result");
    return Keyword;
  }

  /// Create a new code-completion string that describes how to insert
  /// this result into a program.
  ///
  /// \param S The semantic analysis that created the result.
  ///
  /// \param Allocator The allocator that will be used to allocate the
  /// string itself.
  CodeCompletionString *CreateCodeCompletionString(Sema &S,
                                         const CodeCompletionContext &CCContext,
                                           CodeCompletionAllocator &Allocator,
                                           CodeCompletionTUInfo &CCTUInfo,
                                           bool IncludeBriefComments);
  CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx,
                                                   Preprocessor &PP,
                                         const CodeCompletionContext &CCContext,
                                           CodeCompletionAllocator &Allocator,
                                           CodeCompletionTUInfo &CCTUInfo,
                                           bool IncludeBriefComments);
  /// Creates a new code-completion string for the macro result. Similar to the
  /// above overloads, except this only requires preprocessor information.
  /// The result kind must be `RK_Macro`.
  CodeCompletionString *
  CreateCodeCompletionStringForMacro(Preprocessor &PP,
                                     CodeCompletionAllocator &Allocator,
                                     CodeCompletionTUInfo &CCTUInfo);

  /// Retrieve the name that should be used to order a result.
  ///
  /// If the name needs to be constructed as a string, that string will be
  /// saved into Saved and the returned StringRef will refer to it.
  StringRef getOrderedName(std::string &Saved) const;

private:
  void computeCursorKindAndAvailability(bool Accessible = true);
};

bool operator<(const CodeCompletionResult &X, const CodeCompletionResult &Y);

inline bool operator>(const CodeCompletionResult &X,
                      const CodeCompletionResult &Y) {
  return Y < X;
}

inline bool operator<=(const CodeCompletionResult &X,
                      const CodeCompletionResult &Y) {
  return !(Y < X);
}

inline bool operator>=(const CodeCompletionResult &X,
                       const CodeCompletionResult &Y) {
  return !(X < Y);
}

raw_ostream &operator<<(raw_ostream &OS,
                              const CodeCompletionString &CCS);

/// Abstract interface for a consumer of code-completion
/// information.
class CodeCompleteConsumer {
protected:
  const CodeCompleteOptions CodeCompleteOpts;

  /// Whether the output format for the code-completion consumer is
  /// binary.
  bool OutputIsBinary;

public:
  class OverloadCandidate {
  public:
    /// Describes the type of overload candidate.
    enum CandidateKind {
      /// The candidate is a function declaration.
      CK_Function,

      /// The candidate is a function template.
      CK_FunctionTemplate,

      /// The "candidate" is actually a variable, expression, or block
      /// for which we only have a function prototype.
      CK_FunctionType
    };

  private:
    /// The kind of overload candidate.
    CandidateKind Kind;

    union {
      /// The function overload candidate, available when
      /// Kind == CK_Function.
      FunctionDecl *Function;

      /// The function template overload candidate, available when
      /// Kind == CK_FunctionTemplate.
      FunctionTemplateDecl *FunctionTemplate;

      /// The function type that describes the entity being called,
      /// when Kind == CK_FunctionType.
      const FunctionType *Type;
    };

  public:
    OverloadCandidate(FunctionDecl *Function)
        : Kind(CK_Function), Function(Function) {}

    OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
        : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) {}

    OverloadCandidate(const FunctionType *Type)
        : Kind(CK_FunctionType), Type(Type) {}

    /// Determine the kind of overload candidate.
    CandidateKind getKind() const { return Kind; }

    /// Retrieve the function overload candidate or the templated
    /// function declaration for a function template.
    FunctionDecl *getFunction() const;

    /// Retrieve the function template overload candidate.
    FunctionTemplateDecl *getFunctionTemplate() const {
      assert(getKind() == CK_FunctionTemplate && "Not a function template");
      return FunctionTemplate;
    }

    /// Retrieve the function type of the entity, regardless of how the
    /// function is stored.
    const FunctionType *getFunctionType() const;

    /// Create a new code-completion string that describes the function
    /// signature of this overload candidate.
    CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
                                                Sema &S,
                                      CodeCompletionAllocator &Allocator,
                                      CodeCompletionTUInfo &CCTUInfo,
                                      bool IncludeBriefComments) const;
  };

  CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
                       bool OutputIsBinary)
      : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary) {}

  /// Whether the code-completion consumer wants to see macros.
  bool includeMacros() const {
    return CodeCompleteOpts.IncludeMacros;
  }

  /// Whether the code-completion consumer wants to see code patterns.
  bool includeCodePatterns() const {
    return CodeCompleteOpts.IncludeCodePatterns;
  }

  /// Whether to include global (top-level) declaration results.
  bool includeGlobals() const { return CodeCompleteOpts.IncludeGlobals; }

  /// Whether to include declarations in namespace contexts (including
  /// the global namespace). If this is false, `includeGlobals()` will be
  /// ignored.
  bool includeNamespaceLevelDecls() const {
    return CodeCompleteOpts.IncludeNamespaceLevelDecls;
  }

  /// Whether to include brief documentation comments within the set of
  /// code completions returned.
  bool includeBriefComments() const {
    return CodeCompleteOpts.IncludeBriefComments;
  }

  /// Whether to include completion items with small fix-its, e.g. change
  /// '.' to '->' on member access, etc.
  bool includeFixIts() const { return CodeCompleteOpts.IncludeFixIts; }

  /// Hint whether to load data from the external AST in order to provide
  /// full results. If false, declarations from the preamble may be omitted.
  bool loadExternal() const {
    return CodeCompleteOpts.LoadExternal;
  }

  /// Determine whether the output of this consumer is binary.
  bool isOutputBinary() const { return OutputIsBinary; }

  /// Deregisters and destroys this code-completion consumer.
  virtual ~CodeCompleteConsumer();

  /// \name Code-completion filtering
  /// Check if the result should be filtered out.
  virtual bool isResultFilteredOut(StringRef Filter,
                                   CodeCompletionResult Results) {
    return false;
  }

  /// \name Code-completion callbacks
  //@{
  /// Process the finalized code-completion results.
  virtual void ProcessCodeCompleteResults(Sema &S,
                                          CodeCompletionContext Context,
                                          CodeCompletionResult *Results,
                                          unsigned NumResults) {}

  /// \param S the semantic-analyzer object for which code-completion is being
  /// done.
  ///
  /// \param CurrentArg the index of the current argument.
  ///
  /// \param Candidates an array of overload candidates.
  ///
  /// \param NumCandidates the number of overload candidates
  ///
  /// \param OpenParLoc location of the opening parenthesis of the argument
  ///        list.
  virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
                                         OverloadCandidate *Candidates,
                                         unsigned NumCandidates,
                                         SourceLocation OpenParLoc) {}
  //@}

  /// Retrieve the allocator that will be used to allocate
  /// code completion strings.
  virtual CodeCompletionAllocator &getAllocator() = 0;

  virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() = 0;
};

/// Get the documentation comment used to produce
/// CodeCompletionString::BriefComment for RK_Declaration.
const RawComment *getCompletionComment(const ASTContext &Ctx,
                                       const NamedDecl *Decl);

/// Get the documentation comment used to produce
/// CodeCompletionString::BriefComment for RK_Pattern.
const RawComment *getPatternCompletionComment(const ASTContext &Ctx,
                                              const NamedDecl *Decl);

/// Get the documentation comment used to produce
/// CodeCompletionString::BriefComment for OverloadCandidate.
const RawComment *
getParameterComment(const ASTContext &Ctx,
                    const CodeCompleteConsumer::OverloadCandidate &Result,
                    unsigned ArgIndex);

/// A simple code-completion consumer that prints the results it
/// receives in a simple format.
class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
  /// The raw output stream.
  raw_ostream &OS;

  CodeCompletionTUInfo CCTUInfo;

public:
  /// Create a new printing code-completion consumer that prints its
  /// results to the given raw output stream.
  PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
                               raw_ostream &OS)
      : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS),
        CCTUInfo(std::make_shared<GlobalCodeCompletionAllocator>()) {}

  /// Prints the finalized code-completion results.
  void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
                                  CodeCompletionResult *Results,
                                  unsigned NumResults) override;

  void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
                                 OverloadCandidate *Candidates,
                                 unsigned NumCandidates,
                                 SourceLocation OpenParLoc) override;

  bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override;

  CodeCompletionAllocator &getAllocator() override {
    return CCTUInfo.getAllocator();
  }

  CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
