//===--- Protocol.h - Language Server Protocol Implementation ---*- 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
//
//===----------------------------------------------------------------------===//
//
// This file contains structs based on the LSP specification at
// https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md
//
// This is not meant to be a complete implementation, new interfaces are added
// when they're needed.
//
// Each struct has a toJSON and fromJSON function, that converts between
// the struct and a JSON representation. (See JSON.h)
//
// Some structs also have operator<< serialization. This is for debugging and
// tests, and is not generally machine-readable.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H

#include "URI.h"
#include "index/SymbolID.h"
#include "support/MemoryTree.h"
#include "clang/Index/IndexSymbol.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/raw_ostream.h"
#include <bitset>
#include <memory>
#include <string>
#include <vector>

namespace clang {
namespace clangd {

enum class ErrorCode {
  // Defined by JSON RPC.
  ParseError = -32700,
  InvalidRequest = -32600,
  MethodNotFound = -32601,
  InvalidParams = -32602,
  InternalError = -32603,

  ServerNotInitialized = -32002,
  UnknownErrorCode = -32001,

  // Defined by the protocol.
  RequestCancelled = -32800,
  ContentModified = -32801,
};
// Models an LSP error as an llvm::Error.
class LSPError : public llvm::ErrorInfo<LSPError> {
public:
  std::string Message;
  ErrorCode Code;
  static char ID;

  LSPError(std::string Message, ErrorCode Code)
      : Message(std::move(Message)), Code(Code) {}

  void log(llvm::raw_ostream &OS) const override {
    OS << int(Code) << ": " << Message;
  }
  std::error_code convertToErrorCode() const override {
    return llvm::inconvertibleErrorCode();
  }
};

// URI in "file" scheme for a file.
struct URIForFile {
  URIForFile() = default;

  /// Canonicalizes \p AbsPath via URI.
  ///
  /// File paths in URIForFile can come from index or local AST. Path from
  /// index goes through URI transformation, and the final path is resolved by
  /// URI scheme and could potentially be different from the original path.
  /// Hence, we do the same transformation for all paths.
  ///
  /// Files can be referred to by several paths (e.g. in the presence of links).
  /// Which one we prefer may depend on where we're coming from. \p TUPath is a
  /// hint, and should usually be the main entrypoint file we're processing.
  static URIForFile canonicalize(llvm::StringRef AbsPath,
                                 llvm::StringRef TUPath);

  static llvm::Expected<URIForFile> fromURI(const URI &U,
                                            llvm::StringRef HintPath);

  /// Retrieves absolute path to the file.
  llvm::StringRef file() const { return File; }

  explicit operator bool() const { return !File.empty(); }
  std::string uri() const { return URI::createFile(File).toString(); }

  friend bool operator==(const URIForFile &LHS, const URIForFile &RHS) {
    return LHS.File == RHS.File;
  }

  friend bool operator!=(const URIForFile &LHS, const URIForFile &RHS) {
    return !(LHS == RHS);
  }

  friend bool operator<(const URIForFile &LHS, const URIForFile &RHS) {
    return LHS.File < RHS.File;
  }

private:
  explicit URIForFile(std::string &&File) : File(std::move(File)) {}

  std::string File;
};

/// Serialize/deserialize \p URIForFile to/from a string URI.
llvm::json::Value toJSON(const URIForFile &U);
bool fromJSON(const llvm::json::Value &, URIForFile &, llvm::json::Path);

struct TextDocumentIdentifier {
  /// The text document's URI.
  URIForFile uri;
};
llvm::json::Value toJSON(const TextDocumentIdentifier &);
bool fromJSON(const llvm::json::Value &, TextDocumentIdentifier &,
              llvm::json::Path);

struct VersionedTextDocumentIdentifier : public TextDocumentIdentifier {
  /// The version number of this document. If a versioned text document
  /// identifier is sent from the server to the client and the file is not open
  /// in the editor (the server has not received an open notification before)
  /// the server can send `null` to indicate that the version is known and the
  /// content on disk is the master (as speced with document content ownership).
  ///
  /// The version number of a document will increase after each change,
  /// including undo/redo. The number doesn't need to be consecutive.
  ///
  /// clangd extension: versions are optional, and synthesized if missing.
  llvm::Optional<std::int64_t> version;
};
llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &);
bool fromJSON(const llvm::json::Value &, VersionedTextDocumentIdentifier &,
              llvm::json::Path);

struct Position {
  /// Line position in a document (zero-based).
  int line = 0;

  /// Character offset on a line in a document (zero-based).
  /// WARNING: this is in UTF-16 codepoints, not bytes or characters!
  /// Use the functions in SourceCode.h to construct/interpret Positions.
  int character = 0;

  friend bool operator==(const Position &LHS, const Position &RHS) {
    return std::tie(LHS.line, LHS.character) ==
           std::tie(RHS.line, RHS.character);
  }
  friend bool operator!=(const Position &LHS, const Position &RHS) {
    return !(LHS == RHS);
  }
  friend bool operator<(const Position &LHS, const Position &RHS) {
    return std::tie(LHS.line, LHS.character) <
           std::tie(RHS.line, RHS.character);
  }
  friend bool operator<=(const Position &LHS, const Position &RHS) {
    return std::tie(LHS.line, LHS.character) <=
           std::tie(RHS.line, RHS.character);
  }
};
bool fromJSON(const llvm::json::Value &, Position &, llvm::json::Path);
llvm::json::Value toJSON(const Position &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Position &);

struct Range {
  /// The range's start position.
  Position start;

  /// The range's end position.
  Position end;

  friend bool operator==(const Range &LHS, const Range &RHS) {
    return std::tie(LHS.start, LHS.end) == std::tie(RHS.start, RHS.end);
  }
  friend bool operator!=(const Range &LHS, const Range &RHS) {
    return !(LHS == RHS);
  }
  friend bool operator<(const Range &LHS, const Range &RHS) {
    return std::tie(LHS.start, LHS.end) < std::tie(RHS.start, RHS.end);
  }

  bool contains(Position Pos) const { return start <= Pos && Pos < end; }
  bool contains(Range Rng) const {
    return start <= Rng.start && Rng.end <= end;
  }
};
bool fromJSON(const llvm::json::Value &, Range &, llvm::json::Path);
llvm::json::Value toJSON(const Range &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Range &);

struct Location {
  /// The text document's URI.
  URIForFile uri;
  Range range;

  friend bool operator==(const Location &LHS, const Location &RHS) {
    return LHS.uri == RHS.uri && LHS.range == RHS.range;
  }

  friend bool operator!=(const Location &LHS, const Location &RHS) {
    return !(LHS == RHS);
  }

  friend bool operator<(const Location &LHS, const Location &RHS) {
    return std::tie(LHS.uri, LHS.range) < std::tie(RHS.uri, RHS.range);
  }
};
llvm::json::Value toJSON(const Location &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Location &);

struct TextEdit {
  /// The range of the text document to be manipulated. To insert
  /// text into a document create a range where start === end.
  Range range;

  /// The string to be inserted. For delete operations use an
  /// empty string.
  std::string newText;
};
inline bool operator==(const TextEdit &L, const TextEdit &R) {
  return std::tie(L.newText, L.range) == std::tie(R.newText, R.range);
}
bool fromJSON(const llvm::json::Value &, TextEdit &, llvm::json::Path);
llvm::json::Value toJSON(const TextEdit &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TextEdit &);

struct TextDocumentItem {
  /// The text document's URI.
  URIForFile uri;

  /// The text document's language identifier.
  std::string languageId;

  /// The version number of this document (it will strictly increase after each
  /// change, including undo/redo.
  ///
  /// clangd extension: versions are optional, and synthesized if missing.
  llvm::Optional<int64_t> version;

  /// The content of the opened text document.
  std::string text;
};
bool fromJSON(const llvm::json::Value &, TextDocumentItem &, llvm::json::Path);

enum class TraceLevel {
  Off = 0,
  Messages = 1,
  Verbose = 2,
};
bool fromJSON(const llvm::json::Value &E, TraceLevel &Out, llvm::json::Path);

struct NoParams {};
inline llvm::json::Value toJSON(const NoParams &) { return nullptr; }
inline bool fromJSON(const llvm::json::Value &, NoParams &, llvm::json::Path) {
  return true;
}
using InitializedParams = NoParams;

/// Defines how the host (editor) should sync document changes to the language
/// server.
enum class TextDocumentSyncKind {
  /// Documents should not be synced at all.
  None = 0,

  /// Documents are synced by always sending the full content of the document.
  Full = 1,

  /// Documents are synced by sending the full content on open.  After that
  /// only incremental updates to the document are send.
  Incremental = 2,
};

/// The kind of a completion entry.
enum class CompletionItemKind {
  Missing = 0,
  Text = 1,
  Method = 2,
  Function = 3,
  Constructor = 4,
  Field = 5,
  Variable = 6,
  Class = 7,
  Interface = 8,
  Module = 9,
  Property = 10,
  Unit = 11,
  Value = 12,
  Enum = 13,
  Keyword = 14,
  Snippet = 15,
  Color = 16,
  File = 17,
  Reference = 18,
  Folder = 19,
  EnumMember = 20,
  Constant = 21,
  Struct = 22,
  Event = 23,
  Operator = 24,
  TypeParameter = 25,
};
bool fromJSON(const llvm::json::Value &, CompletionItemKind &,
              llvm::json::Path);
constexpr auto CompletionItemKindMin =
    static_cast<size_t>(CompletionItemKind::Text);
constexpr auto CompletionItemKindMax =
    static_cast<size_t>(CompletionItemKind::TypeParameter);
using CompletionItemKindBitset = std::bitset<CompletionItemKindMax + 1>;
bool fromJSON(const llvm::json::Value &, CompletionItemKindBitset &,
              llvm::json::Path);
CompletionItemKind
adjustKindToCapability(CompletionItemKind Kind,
                       CompletionItemKindBitset &SupportedCompletionItemKinds);

/// A symbol kind.
enum class SymbolKind {
  File = 1,
  Module = 2,
  Namespace = 3,
  Package = 4,
  Class = 5,
  Method = 6,
  Property = 7,
  Field = 8,
  Constructor = 9,
  Enum = 10,
  Interface = 11,
  Function = 12,
  Variable = 13,
  Constant = 14,
  String = 15,
  Number = 16,
  Boolean = 17,
  Array = 18,
  Object = 19,
  Key = 20,
  Null = 21,
  EnumMember = 22,
  Struct = 23,
  Event = 24,
  Operator = 25,
  TypeParameter = 26
};
bool fromJSON(const llvm::json::Value &, SymbolKind &, llvm::json::Path);
constexpr auto SymbolKindMin = static_cast<size_t>(SymbolKind::File);
constexpr auto SymbolKindMax = static_cast<size_t>(SymbolKind::TypeParameter);
using SymbolKindBitset = std::bitset<SymbolKindMax + 1>;
bool fromJSON(const llvm::json::Value &, SymbolKindBitset &, llvm::json::Path);
SymbolKind adjustKindToCapability(SymbolKind Kind,
                                  SymbolKindBitset &supportedSymbolKinds);

// Convert a index::SymbolKind to clangd::SymbolKind (LSP)
// Note, some are not perfect matches and should be improved when this LSP
// issue is addressed:
// https://github.com/Microsoft/language-server-protocol/issues/344
SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind);

// Determines the encoding used to measure offsets and lengths of source in LSP.
enum class OffsetEncoding {
  // Any string is legal on the wire. Unrecognized encodings parse as this.
  UnsupportedEncoding,
  // Length counts code units of UTF-16 encoded text. (Standard LSP behavior).
  UTF16,
  // Length counts bytes of UTF-8 encoded text. (Clangd extension).
  UTF8,
  // Length counts codepoints in unicode text. (Clangd extension).
  UTF32,
};
llvm::json::Value toJSON(const OffsetEncoding &);
bool fromJSON(const llvm::json::Value &, OffsetEncoding &, llvm::json::Path);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, OffsetEncoding);

// Describes the content type that a client supports in various result literals
// like `Hover`, `ParameterInfo` or `CompletionItem`.
enum class MarkupKind {
  PlainText,
  Markdown,
};
bool fromJSON(const llvm::json::Value &, MarkupKind &, llvm::json::Path);
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MarkupKind);

// This struct doesn't mirror LSP!
// The protocol defines deeply nested structures for client capabilities.
// Instead of mapping them all, this just parses out the bits we care about.
struct ClientCapabilities {
  /// The supported set of SymbolKinds for workspace/symbol.
  /// workspace.symbol.symbolKind.valueSet
  llvm::Optional<SymbolKindBitset> WorkspaceSymbolKinds;

  /// Whether the client accepts diagnostics with codeActions attached inline.
  /// textDocument.publishDiagnostics.codeActionsInline.
  bool DiagnosticFixes = false;

  /// Whether the client accepts diagnostics with related locations.
  /// textDocument.publishDiagnostics.relatedInformation.
  bool DiagnosticRelatedInformation = false;

  /// Whether the client accepts diagnostics with category attached to it
  /// using the "category" extension.
  /// textDocument.publishDiagnostics.categorySupport
  bool DiagnosticCategory = false;

  /// Client supports snippets as insert text.
  /// textDocument.completion.completionItem.snippetSupport
  bool CompletionSnippets = false;

  /// Client supports completions with additionalTextEdit near the cursor.
  /// This is a clangd extension. (LSP says this is for unrelated text only).
  /// textDocument.completion.editsNearCursor
  bool CompletionFixes = false;

  /// Client supports hierarchical document symbols.
  /// textDocument.documentSymbol.hierarchicalDocumentSymbolSupport
  bool HierarchicalDocumentSymbol = false;

  /// Client supports signature help.
  /// textDocument.signatureHelp
  bool HasSignatureHelp = false;

  /// Client supports processing label offsets instead of a simple label string.
  /// textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport
  bool OffsetsInSignatureHelp = false;

  /// The supported set of CompletionItemKinds for textDocument/completion.
  /// textDocument.completion.completionItemKind.valueSet
  llvm::Optional<CompletionItemKindBitset> CompletionItemKinds;

  /// The documentation format that should be used for textDocument/completion.
  /// textDocument.completion.completionItem.documentationFormat
  MarkupKind CompletionDocumentationFormat = MarkupKind::PlainText;

  /// Client supports CodeAction return value for textDocument/codeAction.
  /// textDocument.codeAction.codeActionLiteralSupport.
  bool CodeActionStructure = false;

  /// Client advertises support for the semanticTokens feature.
  /// We support the textDocument/semanticTokens request in any case.
  /// textDocument.semanticTokens
  bool SemanticTokens = false;
  /// Client supports Theia semantic highlighting extension.
  /// https://github.com/microsoft/vscode-languageserver-node/pull/367
  /// clangd no longer supports this, we detect it just to log a warning.
  /// textDocument.semanticHighlightingCapabilities.semanticHighlighting
  bool TheiaSemanticHighlighting = false;

  /// Supported encodings for LSP character offsets. (clangd extension).
  llvm::Optional<std::vector<OffsetEncoding>> offsetEncoding;

  /// The content format that should be used for Hover requests.
  /// textDocument.hover.contentEncoding
  MarkupKind HoverContentFormat = MarkupKind::PlainText;

  /// The client supports testing for validity of rename operations
  /// before execution.
  bool RenamePrepareSupport = false;

  /// The client supports progress notifications.
  /// window.workDoneProgress
  bool WorkDoneProgress = false;

  /// The client supports implicit $/progress work-done progress streams,
  /// without a preceding window/workDoneProgress/create.
  /// This is a clangd extension.
  /// window.implicitWorkDoneProgressCreate
  bool ImplicitProgressCreation = false;

  /// Whether the client claims to cancel stale requests.
  /// general.staleRequestSupport.cancel
  bool CancelsStaleRequests = false;

  /// Whether the client implementation supports a refresh request sent from the
  /// server to the client.
  bool SemanticTokenRefreshSupport = false;
};
bool fromJSON(const llvm::json::Value &, ClientCapabilities &,
              llvm::json::Path);

/// Clangd extension that's used in the 'compilationDatabaseChanges' in
/// workspace/didChangeConfiguration to record updates to the in-memory
/// compilation database.
struct ClangdCompileCommand {
  std::string workingDirectory;
  std::vector<std::string> compilationCommand;
};
bool fromJSON(const llvm::json::Value &, ClangdCompileCommand &,
              llvm::json::Path);

/// Clangd extension: parameters configurable at any time, via the
/// `workspace/didChangeConfiguration` notification.
/// LSP defines this type as `any`.
struct ConfigurationSettings {
  // Changes to the in-memory compilation database.
  // The key of the map is a file name.
  std::map<std::string, ClangdCompileCommand> compilationDatabaseChanges;
};
bool fromJSON(const llvm::json::Value &, ConfigurationSettings &,
              llvm::json::Path);

/// Clangd extension: parameters configurable at `initialize` time.
/// LSP defines this type as `any`.
struct InitializationOptions {
  // What we can change throught the didChangeConfiguration request, we can
  // also set through the initialize request (initializationOptions field).
  ConfigurationSettings ConfigSettings;

  llvm::Optional<std::string> compilationDatabasePath;
  // Additional flags to be included in the "fallback command" used when
  // the compilation database doesn't describe an opened file.
  // The command used will be approximately `clang $FILE $fallbackFlags`.
  std::vector<std::string> fallbackFlags;

  /// Clients supports show file status for textDocument/clangd.fileStatus.
  bool FileStatus = false;
};
bool fromJSON(const llvm::json::Value &, InitializationOptions &,
              llvm::json::Path);

struct InitializeParams {
  /// The process Id of the parent process that started
  /// the server. Is null if the process has not been started by another
  /// process. If the parent process is not alive then the server should exit
  /// (see exit notification) its process.
  llvm::Optional<int> processId;

  /// The rootPath of the workspace. Is null
  /// if no folder is open.
  ///
  /// @deprecated in favour of rootUri.
  llvm::Optional<std::string> rootPath;

  /// The rootUri of the workspace. Is null if no
  /// folder is open. If both `rootPath` and `rootUri` are set
  /// `rootUri` wins.
  llvm::Optional<URIForFile> rootUri;

  // User provided initialization options.
  // initializationOptions?: any;

  /// The capabilities provided by the client (editor or tool)
  ClientCapabilities capabilities;
  /// The same data as capabilities, but not parsed (to expose to modules).
  llvm::json::Object rawCapabilities;

  /// The initial trace setting. If omitted trace is disabled ('off').
  llvm::Optional<TraceLevel> trace;

  /// User-provided initialization options.
  InitializationOptions initializationOptions;
};
bool fromJSON(const llvm::json::Value &, InitializeParams &, llvm::json::Path);

struct WorkDoneProgressCreateParams {
  /// The token to be used to report progress.
  llvm::json::Value token = nullptr;
};
llvm::json::Value toJSON(const WorkDoneProgressCreateParams &P);

template <typename T> struct ProgressParams {
  /// The progress token provided by the client or server.
  llvm::json::Value token = nullptr;

  /// The progress data.
  T value;
};
template <typename T> llvm::json::Value toJSON(const ProgressParams<T> &P) {
  return llvm::json::Object{{"token", P.token}, {"value", P.value}};
}
/// To start progress reporting a $/progress notification with the following
/// payload must be sent.
struct WorkDoneProgressBegin {
  /// Mandatory title of the progress operation. Used to briefly inform about
  /// the kind of operation being performed.
  ///
  /// Examples: "Indexing" or "Linking dependencies".
  std::string title;

  /// Controls if a cancel button should show to allow the user to cancel the
  /// long-running operation. Clients that don't support cancellation are
  /// allowed to ignore the setting.
  bool cancellable = false;

  /// Optional progress percentage to display (value 100 is considered 100%).
  /// If not provided infinite progress is assumed and clients are allowed
  /// to ignore the `percentage` value in subsequent in report notifications.
  ///
  /// The value should be steadily rising. Clients are free to ignore values
  /// that are not following this rule.
  ///
  /// Clangd implementation note: we only send nonzero percentages in
  /// the WorkProgressReport. 'true' here means percentages will be used.
  bool percentage = false;
};
llvm::json::Value toJSON(const WorkDoneProgressBegin &);

/// Reporting progress is done using the following payload.
struct WorkDoneProgressReport {
  /// Mandatory title of the progress operation. Used to briefly inform about
  /// the kind of operation being performed.
  ///
  /// Examples: "Indexing" or "Linking dependencies".
  std::string title;

  /// Controls enablement state of a cancel button. This property is only valid
  /// if a cancel button got requested in the `WorkDoneProgressStart` payload.
  ///
  /// Clients that don't support cancellation or don't support control
  /// the button's enablement state are allowed to ignore the setting.
  llvm::Optional<bool> cancellable;

  /// Optional, more detailed associated progress message. Contains
  /// complementary information to the `title`.
  ///
  /// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
  /// If unset, the previous progress message (if any) is still valid.
  llvm::Optional<std::string> message;

  /// Optional progress percentage to display (value 100 is considered 100%).
  /// If not provided infinite progress is assumed and clients are allowed
  /// to ignore the `percentage` value in subsequent in report notifications.
  ///
  /// The value should be steadily rising. Clients are free to ignore values
  /// that are not following this rule.
  llvm::Optional<double> percentage;
};
llvm::json::Value toJSON(const WorkDoneProgressReport &);
//
/// Signals the end of progress reporting.
struct WorkDoneProgressEnd {
  /// Optional, a final message indicating to for example indicate the outcome
  /// of the operation.
  llvm::Optional<std::string> message;
};
llvm::json::Value toJSON(const WorkDoneProgressEnd &);

enum class MessageType {
  /// An error message.
  Error = 1,
  /// A warning message.
  Warning = 2,
  /// An information message.
  Info = 3,
  /// A log message.
  Log = 4,
};
llvm::json::Value toJSON(const MessageType &);

/// The show message notification is sent from a server to a client to ask the
/// client to display a particular message in the user interface.
struct ShowMessageParams {
  /// The message type.
  MessageType type = MessageType::Info;
  /// The actual message.
  std::string message;
};
llvm::json::Value toJSON(const ShowMessageParams &);

struct DidOpenTextDocumentParams {
  /// The document that was opened.
  TextDocumentItem textDocument;
};
bool fromJSON(const llvm::json::Value &, DidOpenTextDocumentParams &,
              llvm::json::Path);

struct DidCloseTextDocumentParams {
  /// The document that was closed.
  TextDocumentIdentifier textDocument;
};
bool fromJSON(const llvm::json::Value &, DidCloseTextDocumentParams &,
              llvm::json::Path);

struct DidSaveTextDocumentParams {
  /// The document that was saved.
  TextDocumentIdentifier textDocument;
};
bool fromJSON(const llvm::json::Value &, DidSaveTextDocumentParams &,
              llvm::json::Path);

struct TextDocumentContentChangeEvent {
  /// The range of the document that changed.
  llvm::Optional<Range> range;

  /// The length of the range that got replaced.
  llvm::Optional<int> rangeLength;

  /// The new text of the range/document.
  std::string text;
};
bool fromJSON(const llvm::json::Value &, TextDocumentContentChangeEvent &,
              llvm::json::Path);

struct DidChangeTextDocumentParams {
  /// The document that did change. The version number points
  /// to the version after all provided content changes have
  /// been applied.
  VersionedTextDocumentIdentifier textDocument;

  /// The actual content changes.
  std::vector<TextDocumentContentChangeEvent> contentChanges;

  /// Forces diagnostics to be generated, or to not be generated, for this
  /// version of the file. If not set, diagnostics are eventually consistent:
  /// either they will be provided for this version or some subsequent one.
  /// This is a clangd extension.
  llvm::Optional<bool> wantDiagnostics;

  /// Force a complete rebuild of the file, ignoring all cached state. Slow!
  /// This is useful to defeat clangd's assumption that missing headers will
  /// stay missing.
  /// This is a clangd extension.
  bool forceRebuild = false;
};
bool fromJSON(const llvm::json::Value &, DidChangeTextDocumentParams &,
              llvm::json::Path);

enum class FileChangeType {
  /// The file got created.
  Created = 1,
  /// The file got changed.
  Changed = 2,
  /// The file got deleted.
  Deleted = 3
};
bool fromJSON(const llvm::json::Value &E, FileChangeType &Out,
              llvm::json::Path);

struct FileEvent {
  /// The file's URI.
  URIForFile uri;
  /// The change type.
  FileChangeType type = FileChangeType::Created;
};
bool fromJSON(const llvm::json::Value &, FileEvent &, llvm::json::Path);

struct DidChangeWatchedFilesParams {
  /// The actual file events.
  std::vector<FileEvent> changes;
};
bool fromJSON(const llvm::json::Value &, DidChangeWatchedFilesParams &,
              llvm::json::Path);

struct DidChangeConfigurationParams {
  ConfigurationSettings settings;
};
bool fromJSON(const llvm::json::Value &, DidChangeConfigurationParams &,
              llvm::json::Path);

// Note: we do not parse FormattingOptions for *FormattingParams.
// In general, we use a clang-format style detected from common mechanisms
// (.clang-format files and the -fallback-style flag).
// It would be possible to override these with FormatOptions, but:
//  - the protocol makes FormatOptions mandatory, so many clients set them to
//    useless values, and we can't tell when to respect them
// - we also format in other places, where FormatOptions aren't available.

struct DocumentRangeFormattingParams {
  /// The document to format.
  TextDocumentIdentifier textDocument;

  /// The range to format
  Range range;
};
bool fromJSON(const llvm::json::Value &, DocumentRangeFormattingParams &,
              llvm::json::Path);

struct DocumentOnTypeFormattingParams {
  /// The document to format.
  TextDocumentIdentifier textDocument;

  /// The position at which this request was sent.
  Position position;

  /// The character that has been typed.
  std::string ch;
};
bool fromJSON(const llvm::json::Value &, DocumentOnTypeFormattingParams &,
              llvm::json::Path);

struct DocumentFormattingParams {
  /// The document to format.
  TextDocumentIdentifier textDocument;
};
bool fromJSON(const llvm::json::Value &, DocumentFormattingParams &,
              llvm::json::Path);

struct DocumentSymbolParams {
  // The text document to find symbols in.
  TextDocumentIdentifier textDocument;
};
bool fromJSON(const llvm::json::Value &, DocumentSymbolParams &,
              llvm::json::Path);

/// Represents a related message and source code location for a diagnostic.
/// This should be used to point to code locations that cause or related to a
/// diagnostics, e.g when duplicating a symbol in a scope.
struct DiagnosticRelatedInformation {
  /// The location of this related diagnostic information.
  Location location;
  /// The message of this related diagnostic information.
  std::string message;
};
llvm::json::Value toJSON(const DiagnosticRelatedInformation &);

struct CodeAction;
struct Diagnostic {
  /// The range at which the message applies.
  Range range;

  /// The diagnostic's severity. Can be omitted. If omitted it is up to the
  /// client to interpret diagnostics as error, warning, info or hint.
  int severity = 0;

  /// The diagnostic's code. Can be omitted.
  std::string code;

  /// A human-readable string describing the source of this
  /// diagnostic, e.g. 'typescript' or 'super lint'.
  std::string source;

  /// The diagnostic's message.
  std::string message;

  /// An array of related diagnostic information, e.g. when symbol-names within
  /// a scope collide all definitions can be marked via this property.
  llvm::Optional<std::vector<DiagnosticRelatedInformation>> relatedInformation;

  /// The diagnostic's category. Can be omitted.
  /// An LSP extension that's used to send the name of the category over to the
  /// client. The category typically describes the compilation stage during
  /// which the issue was produced, e.g. "Semantic Issue" or "Parse Issue".
  llvm::Optional<std::string> category;

  /// Clangd extension: code actions related to this diagnostic.
  /// Only with capability textDocument.publishDiagnostics.codeActionsInline.
  /// (These actions can also be obtained using textDocument/codeAction).
  llvm::Optional<std::vector<CodeAction>> codeActions;

  /// A data entry field that is preserved between a
  /// `textDocument/publishDiagnostics` notification
  /// and`textDocument/codeAction` request.
  /// Mutating users should associate their data with a unique key they can use
  /// to retrieve later on.
  llvm::json::Object data;
};
llvm::json::Value toJSON(const Diagnostic &);

/// A LSP-specific comparator used to find diagnostic in a container like
/// std:map.
/// We only use the required fields of Diagnostic to do the comparison to avoid
/// any regression issues from LSP clients (e.g. VScode), see
/// https://git.io/vbr29
struct LSPDiagnosticCompare {
  bool operator()(const Diagnostic &LHS, const Diagnostic &RHS) const {
    return std::tie(LHS.range, LHS.message) < std::tie(RHS.range, RHS.message);
  }
};
bool fromJSON(const llvm::json::Value &, Diagnostic &, llvm::json::Path);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Diagnostic &);

struct PublishDiagnosticsParams {
  /// The URI for which diagnostic information is reported.
  URIForFile uri;
  /// An array of diagnostic information items.
  std::vector<Diagnostic> diagnostics;
  /// The version number of the document the diagnostics are published for.
  llvm::Optional<int64_t> version;
};
llvm::json::Value toJSON(const PublishDiagnosticsParams &);

struct CodeActionContext {
  /// An array of diagnostics known on the client side overlapping the range
  /// provided to the `textDocument/codeAction` request. They are provided so
  /// that the server knows which errors are currently presented to the user for
  /// the given range. There is no guarantee that these accurately reflect the
  /// error state of the resource. The primary parameter to compute code actions
  /// is the provided range.
  std::vector<Diagnostic> diagnostics;

  /// Requested kind of actions to return.
  ///
  /// Actions not of this kind are filtered out by the client before being
  /// shown. So servers can omit computing them.
  std::vector<std::string> only;
};
bool fromJSON(const llvm::json::Value &, CodeActionContext &, llvm::json::Path);

struct CodeActionParams {
  /// The document in which the command was invoked.
  TextDocumentIdentifier textDocument;

  /// The range for which the command was invoked.
  Range range;

  /// Context carrying additional information.
  CodeActionContext context;
};
bool fromJSON(const llvm::json::Value &, CodeActionParams &, llvm::json::Path);

struct WorkspaceEdit {
  /// Holds changes to existing resources.
  llvm::Optional<std::map<std::string, std::vector<TextEdit>>> changes;

  /// Note: "documentChanges" is not currently used because currently there is
  /// no support for versioned edits.
};
bool fromJSON(const llvm::json::Value &, WorkspaceEdit &, llvm::json::Path);
llvm::json::Value toJSON(const WorkspaceEdit &WE);

/// Arguments for the 'applyTweak' command. The server sends these commands as a
/// response to the textDocument/codeAction request. The client can later send a
/// command back to the server if the user requests to execute a particular code
/// tweak.
struct TweakArgs {
  /// A file provided by the client on a textDocument/codeAction request.
  URIForFile file;
  /// A selection provided by the client on a textDocument/codeAction request.
  Range selection;
  /// ID of the tweak that should be executed. Corresponds to Tweak::id().
  std::string tweakID;
};
bool fromJSON(const llvm::json::Value &, TweakArgs &, llvm::json::Path);
llvm::json::Value toJSON(const TweakArgs &A);

struct ExecuteCommandParams {
  /// The identifier of the actual command handler.
  std::string command;

  // This is `arguments?: []any` in LSP.
  // All clangd's commands accept a single argument (or none => null).
  llvm::json::Value argument = nullptr;
};
bool fromJSON(const llvm::json::Value &, ExecuteCommandParams &,
              llvm::json::Path);

struct Command : public ExecuteCommandParams {
  std::string title;
};
llvm::json::Value toJSON(const Command &C);

/// A code action represents a change that can be performed in code, e.g. to fix
/// a problem or to refactor code.
///
/// A CodeAction must set either `edit` and/or a `command`. If both are
/// supplied, the `edit` is applied first, then the `command` is executed.
struct CodeAction {
  /// A short, human-readable, title for this code action.
  std::string title;

  /// The kind of the code action.
  /// Used to filter code actions.
  llvm::Optional<std::string> kind;
  const static llvm::StringLiteral QUICKFIX_KIND;
  const static llvm::StringLiteral REFACTOR_KIND;
  const static llvm::StringLiteral INFO_KIND;

  /// The diagnostics that this code action resolves.
  llvm::Optional<std::vector<Diagnostic>> diagnostics;

  /// Marks this as a preferred action. Preferred actions are used by the
  /// `auto fix` command and can be targeted by keybindings.
  /// A quick fix should be marked preferred if it properly addresses the
  /// underlying error. A refactoring should be marked preferred if it is the
  /// most reasonable choice of actions to take.
  bool isPreferred = false;

  /// The workspace edit this code action performs.
  llvm::Optional<WorkspaceEdit> edit;

  /// A command this code action executes. If a code action provides an edit
  /// and a command, first the edit is executed and then the command.
  llvm::Optional<Command> command;
};
llvm::json::Value toJSON(const CodeAction &);

/// Represents programming constructs like variables, classes, interfaces etc.
/// that appear in a document. Document symbols can be hierarchical and they
/// have two ranges: one that encloses its definition and one that points to its
/// most interesting range, e.g. the range of an identifier.
struct DocumentSymbol {
  /// The name of this symbol.
  std::string name;

  /// More detail for this symbol, e.g the signature of a function.
  std::string detail;

  /// The kind of this symbol.
  SymbolKind kind;

  /// Indicates if this symbol is deprecated.
  bool deprecated = false;

  /// The range enclosing this symbol not including leading/trailing whitespace
  /// but everything else like comments. This information is typically used to
  /// determine if the clients cursor is inside the symbol to reveal in the
  /// symbol in the UI.
  Range range;

  /// The range that should be selected and revealed when this symbol is being
  /// picked, e.g the name of a function. Must be contained by the `range`.
  Range selectionRange;

  /// Children of this symbol, e.g. properties of a class.
  std::vector<DocumentSymbol> children;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentSymbol &S);
llvm::json::Value toJSON(const DocumentSymbol &S);

/// Represents information about programming constructs like variables, classes,
/// interfaces etc.
struct SymbolInformation {
  /// The name of this symbol.
  std::string name;

  /// The kind of this symbol.
  SymbolKind kind;

  /// The location of this symbol.
  Location location;

  /// The name of the symbol containing this symbol.
  std::string containerName;

  /// The score that clangd calculates to rank the returned symbols.
  /// This excludes the fuzzy-matching score between `name` and the query.
  /// (Specifically, the last ::-separated component).
  /// This can be used to re-rank results as the user types, using client-side
  /// fuzzy-matching (that score should be multiplied with this one).
  /// This is a clangd extension, set only for workspace/symbol responses.
  llvm::Optional<float> score;
};
llvm::json::Value toJSON(const SymbolInformation &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolInformation &);

/// Represents information about identifier.
/// This is returned from textDocument/symbolInfo, which is a clangd extension.
struct SymbolDetails {
  std::string name;

  std::string containerName;

  /// Unified Symbol Resolution identifier
  /// This is an opaque string uniquely identifying a symbol.
  /// Unlike SymbolID, it is variable-length and somewhat human-readable.
  /// It is a common representation across several clang tools.
  /// (See USRGeneration.h)
  std::string USR;

  SymbolID ID;
};
llvm::json::Value toJSON(const SymbolDetails &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolDetails &);
bool operator==(const SymbolDetails &, const SymbolDetails &);

/// The parameters of a Workspace Symbol Request.
struct WorkspaceSymbolParams {
  /// A query string to filter symbols by.
  /// Clients may send an empty string here to request all the symbols.
  std::string query;

  /// Max results to return, overriding global default. 0 means no limit.
  /// Clangd extension.
  llvm::Optional<int> limit;
};
bool fromJSON(const llvm::json::Value &, WorkspaceSymbolParams &,
              llvm::json::Path);

struct ApplyWorkspaceEditParams {
  WorkspaceEdit edit;
};
llvm::json::Value toJSON(const ApplyWorkspaceEditParams &);

struct ApplyWorkspaceEditResponse {
  bool applied = true;
  llvm::Optional<std::string> failureReason;
};
bool fromJSON(const llvm::json::Value &, ApplyWorkspaceEditResponse &,
              llvm::json::Path);

struct TextDocumentPositionParams {
  /// The text document.
  TextDocumentIdentifier textDocument;

  /// The position inside the text document.
  Position position;
};
bool fromJSON(const llvm::json::Value &, TextDocumentPositionParams &,
              llvm::json::Path);

enum class CompletionTriggerKind {
  /// Completion was triggered by typing an identifier (24x7 code
  /// complete), manual invocation (e.g Ctrl+Space) or via API.
  Invoked = 1,
  /// Completion was triggered by a trigger character specified by
  /// the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
  TriggerCharacter = 2,
  /// Completion was re-triggered as the current completion list is incomplete.
  TriggerTriggerForIncompleteCompletions = 3
};

struct CompletionContext {
  /// How the completion was triggered.
  CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked;
  /// The trigger character (a single character) that has trigger code complete.
  /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
  std::string triggerCharacter;
};
bool fromJSON(const llvm::json::Value &, CompletionContext &, llvm::json::Path);

struct CompletionParams : TextDocumentPositionParams {
  CompletionContext context;

  /// Max results to return, overriding global default. 0 means no limit.
  /// Clangd extension.
  llvm::Optional<int> limit;
};
bool fromJSON(const llvm::json::Value &, CompletionParams &, llvm::json::Path);

struct MarkupContent {
  MarkupKind kind = MarkupKind::PlainText;
  std::string value;
};
llvm::json::Value toJSON(const MarkupContent &MC);

struct Hover {
  /// The hover's content
  MarkupContent contents;

  /// An optional range is a range inside a text document
  /// that is used to visualize a hover, e.g. by changing the background color.
  llvm::Optional<Range> range;
};
llvm::json::Value toJSON(const Hover &H);

/// Defines whether the insert text in a completion item should be interpreted
/// as plain text or a snippet.
enum class InsertTextFormat {
  Missing = 0,
  /// The primary text to be inserted is treated as a plain string.
  PlainText = 1,
  /// The primary text to be inserted is treated as a snippet.
  ///
  /// A snippet can define tab stops and placeholders with `$1`, `$2`
  /// and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end
  /// of the snippet. Placeholders with equal identifiers are linked, that is
  /// typing in one will update others too.
  ///
  /// See also:
  /// https//github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
  Snippet = 2,
};

struct CompletionItem {
  /// The label of this completion item. By default also the text that is
  /// inserted when selecting this completion.
  std::string label;

  /// The kind of this completion item. Based of the kind an icon is chosen by
  /// the editor.
  CompletionItemKind kind = CompletionItemKind::Missing;

  /// A human-readable string with additional information about this item, like
  /// type or symbol information.
  std::string detail;

  /// A human-readable string that represents a doc-comment.
  llvm::Optional<MarkupContent> documentation;

  /// A string that should be used when comparing this item with other items.
  /// When `falsy` the label is used.
  std::string sortText;

  /// A string that should be used when filtering a set of completion items.
  /// When `falsy` the label is used.
  std::string filterText;

  /// A string that should be inserted to a document when selecting this
  /// completion. When `falsy` the label is used.
  std::string insertText;

  /// The format of the insert text. The format applies to both the `insertText`
  /// property and the `newText` property of a provided `textEdit`.
  InsertTextFormat insertTextFormat = InsertTextFormat::Missing;

  /// An edit which is applied to a document when selecting this completion.
  /// When an edit is provided `insertText` is ignored.
  ///
  /// Note: The range of the edit must be a single line range and it must
  /// contain the position at which completion has been requested.
  llvm::Optional<TextEdit> textEdit;

  /// An optional array of additional text edits that are applied when selecting
  /// this completion. Edits must not overlap with the main edit nor with
  /// themselves.
  std::vector<TextEdit> additionalTextEdits;

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

  /// The score that clangd calculates to rank the returned completions.
  /// This excludes the fuzzy-match between `filterText` and the partial word.
  /// This can be used to re-rank results as the user types, using client-side
  /// fuzzy-matching (that score should be multiplied with this one).
  /// This is a clangd extension.
  float score = 0.f;

  // TODO: Add custom commitCharacters for some of the completion items. For
  // example, it makes sense to use () only for the functions.
  // TODO(krasimir): The following optional fields defined by the language
  // server protocol are unsupported:
  //
  // data?: any - A data entry field that is preserved on a completion item
  //              between a completion and a completion resolve request.
};
llvm::json::Value toJSON(const CompletionItem &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CompletionItem &);

bool operator<(const CompletionItem &, const CompletionItem &);

/// Represents a collection of completion items to be presented in the editor.
struct CompletionList {
  /// The list is not complete. Further typing should result in recomputing the
  /// list.
  bool isIncomplete = false;

  /// The completion items.
  std::vector<CompletionItem> items;
};
llvm::json::Value toJSON(const CompletionList &);

/// A single parameter of a particular signature.
struct ParameterInformation {

  /// The label of this parameter. Ignored when labelOffsets is set.
  std::string labelString;

  /// Inclusive start and exclusive end offsets withing the containing signature
  /// label.
  /// Offsets are computed by lspLength(), which counts UTF-16 code units by
  /// default but that can be overriden, see its documentation for details.
  llvm::Optional<std::pair<unsigned, unsigned>> labelOffsets;

  /// The documentation of this parameter. Optional.
  std::string documentation;
};
llvm::json::Value toJSON(const ParameterInformation &);

/// Represents the signature of something callable.
struct SignatureInformation {

  /// The label of this signature. Mandatory.
  std::string label;

  /// The documentation of this signature. Optional.
  std::string documentation;

  /// The parameters of this signature.
  std::vector<ParameterInformation> parameters;
};
llvm::json::Value toJSON(const SignatureInformation &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &,
                              const SignatureInformation &);

/// Represents the signature of a callable.
struct SignatureHelp {

  /// The resulting signatures.
  std::vector<SignatureInformation> signatures;

  /// The active signature.
  int activeSignature = 0;

  /// The active parameter of the active signature.
  int activeParameter = 0;

  /// Position of the start of the argument list, including opening paren. e.g.
  /// foo("first arg",   "second arg",
  ///    ^-argListStart   ^-cursor
  /// This is a clangd-specific extension, it is only available via C++ API and
  /// not currently serialized for the LSP.
  Position argListStart;
};
llvm::json::Value toJSON(const SignatureHelp &);

struct RenameParams {
  /// The document that was opened.
  TextDocumentIdentifier textDocument;

  /// The position at which this request was sent.
  Position position;

  /// The new name of the symbol.
  std::string newName;
};
bool fromJSON(const llvm::json::Value &, RenameParams &, llvm::json::Path);

enum class DocumentHighlightKind { Text = 1, Read = 2, Write = 3 };

/// A document highlight is a range inside a text document which deserves
/// special attention. Usually a document highlight is visualized by changing
/// the background color of its range.

struct DocumentHighlight {
  /// The range this highlight applies to.
  Range range;

  /// The highlight kind, default is DocumentHighlightKind.Text.
  DocumentHighlightKind kind = DocumentHighlightKind::Text;

  friend bool operator<(const DocumentHighlight &LHS,
                        const DocumentHighlight &RHS) {
    int LHSKind = static_cast<int>(LHS.kind);
    int RHSKind = static_cast<int>(RHS.kind);
    return std::tie(LHS.range, LHSKind) < std::tie(RHS.range, RHSKind);
  }

  friend bool operator==(const DocumentHighlight &LHS,
                         const DocumentHighlight &RHS) {
    return LHS.kind == RHS.kind && LHS.range == RHS.range;
  }
};
llvm::json::Value toJSON(const DocumentHighlight &DH);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const DocumentHighlight &);

enum class TypeHierarchyDirection { Children = 0, Parents = 1, Both = 2 };
bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out,
              llvm::json::Path);

/// The type hierarchy params is an extension of the
/// `TextDocumentPositionsParams` with optional properties which can be used to
/// eagerly resolve the item when requesting from the server.
struct TypeHierarchyParams : public TextDocumentPositionParams {
  /// The hierarchy levels to resolve. `0` indicates no level.
  int resolve = 0;

  /// The direction of the hierarchy levels to resolve.
  TypeHierarchyDirection direction = TypeHierarchyDirection::Parents;
};
bool fromJSON(const llvm::json::Value &, TypeHierarchyParams &,
              llvm::json::Path);

struct TypeHierarchyItem {
  /// The human readable name of the hierarchy item.
  std::string name;

  /// Optional detail for the hierarchy item. It can be, for instance, the
  /// signature of a function or method.
  llvm::Optional<std::string> detail;

  /// The kind of the hierarchy item. For instance, class or interface.
  SymbolKind kind;

  /// `true` if the hierarchy item is deprecated. Otherwise, `false`.
  bool deprecated = false;

  /// The URI of the text document where this type hierarchy item belongs to.
  URIForFile uri;

  /// The range enclosing this type hierarchy item not including
  /// leading/trailing whitespace but everything else like comments. This
  /// information is typically used to determine if the client's cursor is
  /// inside the type hierarch item to reveal in the symbol in the UI.
  Range range;

  /// The range that should be selected and revealed when this type hierarchy
  /// item is being picked, e.g. the name of a function. Must be contained by
  /// the `range`.
  Range selectionRange;

  /// If this type hierarchy item is resolved, it contains the direct parents.
  /// Could be empty if the item does not have direct parents. If not defined,
  /// the parents have not been resolved yet.
  llvm::Optional<std::vector<TypeHierarchyItem>> parents;

  /// If this type hierarchy item is resolved, it contains the direct children
  /// of the current item. Could be empty if the item does not have any
  /// descendants. If not defined, the children have not been resolved.
  llvm::Optional<std::vector<TypeHierarchyItem>> children;

  /// An optional 'data' field, which can be used to identify a type hierarchy
  /// item in a resolve request.
  llvm::Optional<std::string> data;
};
llvm::json::Value toJSON(const TypeHierarchyItem &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TypeHierarchyItem &);
bool fromJSON(const llvm::json::Value &, TypeHierarchyItem &, llvm::json::Path);

/// Parameters for the `typeHierarchy/resolve` request.
struct ResolveTypeHierarchyItemParams {
  /// The item to resolve.
  TypeHierarchyItem item;

  /// The hierarchy levels to resolve. `0` indicates no level.
  int resolve;

  /// The direction of the hierarchy levels to resolve.
  TypeHierarchyDirection direction;
};
bool fromJSON(const llvm::json::Value &, ResolveTypeHierarchyItemParams &,
              llvm::json::Path);

enum class SymbolTag { Deprecated = 1 };
llvm::json::Value toJSON(SymbolTag);

/// The parameter of a `textDocument/prepareCallHierarchy` request.
struct CallHierarchyPrepareParams : public TextDocumentPositionParams {};

/// Represents programming constructs like functions or constructors
/// in the context of call hierarchy.
struct CallHierarchyItem {
  /// The name of this item.
  std::string name;

  /// The kind of this item.
  SymbolKind kind;

  /// Tags for this item.
  std::vector<SymbolTag> tags;

  /// More detaill for this item, e.g. the signature of a function.
  std::string detail;

  /// The resource identifier of this item.
  URIForFile uri;

  /// The range enclosing this symbol not including leading / trailing
  /// whitespace but everything else, e.g. comments and code.
  Range range;

  /// The range that should be selected and revealed when this symbol
  /// is being picked, e.g. the name of a function.
  /// Must be contained by `Rng`.
  Range selectionRange;

  /// An optional 'data' field, which can be used to identify a call
  /// hierarchy item in an incomingCalls or outgoingCalls request.
  std::string data;
};
llvm::json::Value toJSON(const CallHierarchyItem &);
bool fromJSON(const llvm::json::Value &, CallHierarchyItem &, llvm::json::Path);

/// The parameter of a `callHierarchy/incomingCalls` request.
struct CallHierarchyIncomingCallsParams {
  CallHierarchyItem item;
};
bool fromJSON(const llvm::json::Value &, CallHierarchyIncomingCallsParams &,
              llvm::json::Path);

/// Represents an incoming call, e.g. a caller of a method or constructor.
struct CallHierarchyIncomingCall {
  /// The item that makes the call.
  CallHierarchyItem from;

  /// The range at which the calls appear.
  /// This is relative to the caller denoted by `From`.
  std::vector<Range> fromRanges;
};
llvm::json::Value toJSON(const CallHierarchyIncomingCall &);

/// The parameter of a `callHierarchy/outgoingCalls` request.
struct CallHierarchyOutgoingCallsParams {
  CallHierarchyItem item;
};
bool fromJSON(const llvm::json::Value &, CallHierarchyOutgoingCallsParams &,
              llvm::json::Path);

/// Represents an outgoing call, e.g. calling a getter from a method or
/// a method from a constructor etc.
struct CallHierarchyOutgoingCall {
  /// The item that is called.
  CallHierarchyItem to;

  /// The range at which this item is called.
  /// This is the range relative to the caller, and not `To`.
  std::vector<Range> fromRanges;
};
llvm::json::Value toJSON(const CallHierarchyOutgoingCall &);

/// The parameter of a `textDocument/inlayHints` request.
struct InlayHintsParams {
  /// The text document for which inlay hints are requested.
  TextDocumentIdentifier textDocument;
};
bool fromJSON(const llvm::json::Value &, InlayHintsParams &, llvm::json::Path);

/// A set of predefined hint kinds.
enum class InlayHintKind {
  /// The hint corresponds to parameter information.
  /// An example of a parameter hint is a hint in this position:
  ///    func(^arg);
  /// which shows the name of the corresponding parameter.
  ParameterHint,

  /// Other ideas for hints that are not currently implemented:
  ///
  /// * Type hints, showing deduced types.
  /// * Chaining hints, showing the types of intermediate expressions
  ///   in a chain of function calls.
  /// * Hints indicating implicit conversions or implicit constructor calls.
};
llvm::json::Value toJSON(InlayHintKind);

/// An annotation to be displayed inline next to a range of source code.
struct InlayHint {
  /// The range of source code to which the hint applies.
  /// We provide the entire range, rather than just the endpoint
  /// relevant to `position` (e.g. the start of the range for
  /// InlayHintPosition::Before), to give clients the flexibility
  /// to make choices like only displaying the hint while the cursor
  /// is over the range, rather than displaying it all the time.
  Range range;

  /// The type of hint.
  InlayHintKind kind;

  /// The label that is displayed in the editor.
  std::string label;
};
llvm::json::Value toJSON(const InlayHint &);

struct ReferenceContext {
  /// Include the declaration of the current symbol.
  bool includeDeclaration = false;
};

struct ReferenceParams : public TextDocumentPositionParams {
  ReferenceContext context;
};
bool fromJSON(const llvm::json::Value &, ReferenceParams &, llvm::json::Path);

/// Clangd extension: indicates the current state of the file in clangd,
/// sent from server via the `textDocument/clangd.fileStatus` notification.
struct FileStatus {
  /// The text document's URI.
  URIForFile uri;
  /// The human-readable string presents the current state of the file, can be
  /// shown in the UI (e.g. status bar).
  std::string state;
  // FIXME: add detail messages.
};
llvm::json::Value toJSON(const FileStatus &);

/// Specifies a single semantic token in the document.
/// This struct is not part of LSP, which just encodes lists of tokens as
/// arrays of numbers directly.
struct SemanticToken {
  /// token line number, relative to the previous token
  unsigned deltaLine = 0;
  /// token start character, relative to the previous token
  /// (relative to 0 or the previous token's start if they are on the same line)
  unsigned deltaStart = 0;
  /// the length of the token. A token cannot be multiline
  unsigned length = 0;
  /// will be looked up in `SemanticTokensLegend.tokenTypes`
  unsigned tokenType = 0;
  /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers`
  unsigned tokenModifiers = 0;
};
bool operator==(const SemanticToken &, const SemanticToken &);

/// A versioned set of tokens.
struct SemanticTokens {
  // An optional result id. If provided and clients support delta updating
  // the client will include the result id in the next semantic token request.
  // A server can then instead of computing all semantic tokens again simply
  // send a delta.
  std::string resultId;

  /// The actual tokens.
  std::vector<SemanticToken> tokens; // encoded as a flat integer array.
};
llvm::json::Value toJSON(const SemanticTokens &);

/// Body of textDocument/semanticTokens/full request.
struct SemanticTokensParams {
  /// The text document.
  TextDocumentIdentifier textDocument;
};
bool fromJSON(const llvm::json::Value &, SemanticTokensParams &,
              llvm::json::Path);

/// Body of textDocument/semanticTokens/full/delta request.
/// Requests the changes in semantic tokens since a previous response.
struct SemanticTokensDeltaParams {
  /// The text document.
  TextDocumentIdentifier textDocument;
  /// The previous result id.
  std::string previousResultId;
};
bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R,
              llvm::json::Path);

/// Describes a a replacement of a contiguous range of semanticTokens.
struct SemanticTokensEdit {
  // LSP specifies `start` and `deleteCount` which are relative to the array
  // encoding of the previous tokens.
  // We use token counts instead, and translate when serializing this struct.
  unsigned startToken = 0;
  unsigned deleteTokens = 0;
  std::vector<SemanticToken> tokens; // encoded as a flat integer array
};
llvm::json::Value toJSON(const SemanticTokensEdit &);

/// This models LSP SemanticTokensDelta | SemanticTokens, which is the result of
/// textDocument/semanticTokens/full/delta.
struct SemanticTokensOrDelta {
  std::string resultId;
  /// Set if we computed edits relative to a previous set of tokens.
  llvm::Optional<std::vector<SemanticTokensEdit>> edits;
  /// Set if we computed a fresh set of tokens.
  llvm::Optional<std::vector<SemanticToken>> tokens; // encoded as integer array
};
llvm::json::Value toJSON(const SemanticTokensOrDelta &);

struct SelectionRangeParams {
  /// The text document.
  TextDocumentIdentifier textDocument;

  /// The positions inside the text document.
  std::vector<Position> positions;
};
bool fromJSON(const llvm::json::Value &, SelectionRangeParams &,
              llvm::json::Path);

struct SelectionRange {
  /**
   * The range of this selection range.
   */
  Range range;
  /**
   * The parent selection range containing this range. Therefore `parent.range`
   * must contain `this.range`.
   */
  std::unique_ptr<SelectionRange> parent;
};
llvm::json::Value toJSON(const SelectionRange &);

/// Parameters for the document link request.
struct DocumentLinkParams {
  /// The document to provide document links for.
  TextDocumentIdentifier textDocument;
};
bool fromJSON(const llvm::json::Value &, DocumentLinkParams &,
              llvm::json::Path);

/// A range in a text document that links to an internal or external resource,
/// like another text document or a web site.
struct DocumentLink {
  /// The range this link applies to.
  Range range;

  /// The uri this link points to. If missing a resolve request is sent later.
  URIForFile target;

  // TODO(forster): The following optional fields defined by the language
  // server protocol are unsupported:
  //
  // data?: any - A data entry field that is preserved on a document link
  //              between a DocumentLinkRequest and a
  //              DocumentLinkResolveRequest.

  friend bool operator==(const DocumentLink &LHS, const DocumentLink &RHS) {
    return LHS.range == RHS.range && LHS.target == RHS.target;
  }

  friend bool operator!=(const DocumentLink &LHS, const DocumentLink &RHS) {
    return !(LHS == RHS);
  }
};
llvm::json::Value toJSON(const DocumentLink &DocumentLink);

// FIXME(kirillbobyrev): Add FoldingRangeClientCapabilities so we can support
// per-line-folding editors.
struct FoldingRangeParams {
  TextDocumentIdentifier textDocument;
};
bool fromJSON(const llvm::json::Value &, FoldingRangeParams &,
              llvm::json::Path);

/// Stores information about a region of code that can be folded.
struct FoldingRange {
  unsigned startLine = 0;
  unsigned startCharacter;
  unsigned endLine = 0;
  unsigned endCharacter;
  llvm::Optional<std::string> kind;
};
llvm::json::Value toJSON(const FoldingRange &Range);

/// Keys starting with an underscore(_) represent leaves, e.g. _total or _self
/// for memory usage of whole subtree or only that specific node in bytes. All
/// other keys represents children. An example:
///   {
///     "_self": 0,
///     "_total": 8,
///     "child1": {
///       "_self": 4,
///       "_total": 4,
///     }
///     "child2": {
///       "_self": 2,
///       "_total": 4,
///       "child_deep": {
///         "_self": 2,
///         "_total": 2,
///       }
///     }
///   }
llvm::json::Value toJSON(const MemoryTree &MT);

/// Payload for textDocument/ast request.
/// This request is a clangd extension.
struct ASTParams {
  /// The text document.
  TextDocumentIdentifier textDocument;

  /// The position of the node to be dumped.
  /// The highest-level node that entirely contains the range will be returned.
  /// If no range is given, the root translation unit node will be returned.
  llvm::Optional<Range> range;
};
bool fromJSON(const llvm::json::Value &, ASTParams &, llvm::json::Path);

/// Simplified description of a clang AST node.
/// This is clangd's internal representation of C++ code.
struct ASTNode {
  /// The general kind of node, such as "expression"
  /// Corresponds to the base AST node type such as Expr.
  std::string role;
  /// The specific kind of node this is, such as "BinaryOperator".
  /// This is usually a concrete node class (with Expr etc suffix dropped).
  /// When there's no hierarchy (e.g. TemplateName), the variant (NameKind).
  std::string kind;
  /// Brief additional information, such as "||" for the particular operator.
  /// The information included depends on the node kind, and may be empty.
  std::string detail;
  /// A one-line dump of detailed information about the node.
  /// This includes role/kind/description information, but is rather cryptic.
  /// It is similar to the output from `clang -Xclang -ast-dump`.
  /// May be empty for certain types of nodes.
  std::string arcana;
  /// The range of the original source file covered by this node.
  /// May be missing for implicit nodes, or those created by macro expansion.
  llvm::Optional<Range> range;
  /// Nodes nested within this one, such as the operands of a BinaryOperator.
  std::vector<ASTNode> children;
};
llvm::json::Value toJSON(const ASTNode &);
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ASTNode &);

} // namespace clangd
} // namespace clang

namespace llvm {
template <> struct format_provider<clang::clangd::Position> {
  static void format(const clang::clangd::Position &Pos, raw_ostream &OS,
                     StringRef Style) {
    assert(Style.empty() && "style modifiers for this type are not supported");
    OS << Pos;
  }
};
} // namespace llvm

#endif
