1 //===--- Protocol.h - Language Server Protocol Implementation ---*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains structs based on the LSP specification at
10 // https://github.com/Microsoft/language-server-protocol/blob/main/protocol.md
12 // This is not meant to be a complete implementation, new interfaces are added
13 // when they're needed.
15 // Each struct has a toJSON and fromJSON function, that converts between
16 // the struct and a JSON representation. (See JSON.h)
18 // Some structs also have operator<< serialization. This is for debugging and
19 // tests, and is not generally machine-readable.
21 //===----------------------------------------------------------------------===//
23 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H
24 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H
27 #include "index/SymbolID.h"
28 #include "support/MemoryTree.h"
29 #include "clang/Index/IndexSymbol.h"
30 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/Support/JSON.h"
32 #include "llvm/Support/raw_ostream.h"
39 // This file is using the LSP syntax for identifier names which is different
40 // from the LLVM coding standard. To avoid the clang-tidy warnings, we're
41 // disabling one check here.
42 // NOLINTBEGIN(readability-identifier-naming)
47 enum class ErrorCode
{
48 // Defined by JSON RPC.
50 InvalidRequest
= -32600,
51 MethodNotFound
= -32601,
52 InvalidParams
= -32602,
53 InternalError
= -32603,
55 ServerNotInitialized
= -32002,
56 UnknownErrorCode
= -32001,
58 // Defined by the protocol.
59 RequestCancelled
= -32800,
60 ContentModified
= -32801,
62 // Models an LSP error as an llvm::Error.
63 class LSPError
: public llvm::ErrorInfo
<LSPError
> {
69 LSPError(std::string Message
, ErrorCode Code
)
70 : Message(std::move(Message
)), Code(Code
) {}
72 void log(llvm::raw_ostream
&OS
) const override
{
73 OS
<< int(Code
) << ": " << Message
;
75 std::error_code
convertToErrorCode() const override
{
76 return llvm::inconvertibleErrorCode();
80 bool fromJSON(const llvm::json::Value
&, SymbolID
&, llvm::json::Path
);
81 llvm::json::Value
toJSON(const SymbolID
&);
83 // URI in "file" scheme for a file.
85 URIForFile() = default;
87 /// Canonicalizes \p AbsPath via URI.
89 /// File paths in URIForFile can come from index or local AST. Path from
90 /// index goes through URI transformation, and the final path is resolved by
91 /// URI scheme and could potentially be different from the original path.
92 /// Hence, we do the same transformation for all paths.
94 /// Files can be referred to by several paths (e.g. in the presence of links).
95 /// Which one we prefer may depend on where we're coming from. \p TUPath is a
96 /// hint, and should usually be the main entrypoint file we're processing.
97 static URIForFile
canonicalize(llvm::StringRef AbsPath
,
98 llvm::StringRef TUPath
);
100 static llvm::Expected
<URIForFile
> fromURI(const URI
&U
,
101 llvm::StringRef HintPath
);
103 /// Retrieves absolute path to the file.
104 llvm::StringRef
file() const { return File
; }
106 explicit operator bool() const { return !File
.empty(); }
107 std::string
uri() const { return URI::createFile(File
).toString(); }
109 friend bool operator==(const URIForFile
&LHS
, const URIForFile
&RHS
) {
110 return LHS
.File
== RHS
.File
;
113 friend bool operator!=(const URIForFile
&LHS
, const URIForFile
&RHS
) {
114 return !(LHS
== RHS
);
117 friend bool operator<(const URIForFile
&LHS
, const URIForFile
&RHS
) {
118 return LHS
.File
< RHS
.File
;
122 explicit URIForFile(std::string
&&File
) : File(std::move(File
)) {}
127 /// Serialize/deserialize \p URIForFile to/from a string URI.
128 llvm::json::Value
toJSON(const URIForFile
&U
);
129 bool fromJSON(const llvm::json::Value
&, URIForFile
&, llvm::json::Path
);
131 struct TextDocumentIdentifier
{
132 /// The text document's URI.
135 llvm::json::Value
toJSON(const TextDocumentIdentifier
&);
136 bool fromJSON(const llvm::json::Value
&, TextDocumentIdentifier
&,
139 struct VersionedTextDocumentIdentifier
: public TextDocumentIdentifier
{
140 /// The version number of this document. If a versioned text document
141 /// identifier is sent from the server to the client and the file is not open
142 /// in the editor (the server has not received an open notification before)
143 /// the server can send `null` to indicate that the version is known and the
144 /// content on disk is the master (as speced with document content ownership).
146 /// The version number of a document will increase after each change,
147 /// including undo/redo. The number doesn't need to be consecutive.
149 /// clangd extension: versions are optional, and synthesized if missing.
150 std::optional
<std::int64_t> version
;
152 llvm::json::Value
toJSON(const VersionedTextDocumentIdentifier
&);
153 bool fromJSON(const llvm::json::Value
&, VersionedTextDocumentIdentifier
&,
157 /// Line position in a document (zero-based).
160 /// Character offset on a line in a document (zero-based).
161 /// WARNING: this is in UTF-16 codepoints, not bytes or characters!
162 /// Use the functions in SourceCode.h to construct/interpret Positions.
165 friend bool operator==(const Position
&LHS
, const Position
&RHS
) {
166 return std::tie(LHS
.line
, LHS
.character
) ==
167 std::tie(RHS
.line
, RHS
.character
);
169 friend bool operator!=(const Position
&LHS
, const Position
&RHS
) {
170 return !(LHS
== RHS
);
172 friend bool operator<(const Position
&LHS
, const Position
&RHS
) {
173 return std::tie(LHS
.line
, LHS
.character
) <
174 std::tie(RHS
.line
, RHS
.character
);
176 friend bool operator<=(const Position
&LHS
, const Position
&RHS
) {
177 return std::tie(LHS
.line
, LHS
.character
) <=
178 std::tie(RHS
.line
, RHS
.character
);
181 bool fromJSON(const llvm::json::Value
&, Position
&, llvm::json::Path
);
182 llvm::json::Value
toJSON(const Position
&);
183 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const Position
&);
186 /// The range's start position.
189 /// The range's end position.
192 friend bool operator==(const Range
&LHS
, const Range
&RHS
) {
193 return std::tie(LHS
.start
, LHS
.end
) == std::tie(RHS
.start
, RHS
.end
);
195 friend bool operator!=(const Range
&LHS
, const Range
&RHS
) {
196 return !(LHS
== RHS
);
198 friend bool operator<(const Range
&LHS
, const Range
&RHS
) {
199 return std::tie(LHS
.start
, LHS
.end
) < std::tie(RHS
.start
, RHS
.end
);
202 bool contains(Position Pos
) const { return start
<= Pos
&& Pos
< end
; }
203 bool contains(Range Rng
) const {
204 return start
<= Rng
.start
&& Rng
.end
<= end
;
207 bool fromJSON(const llvm::json::Value
&, Range
&, llvm::json::Path
);
208 llvm::json::Value
toJSON(const Range
&);
209 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const Range
&);
212 /// The text document's URI.
216 friend bool operator==(const Location
&LHS
, const Location
&RHS
) {
217 return LHS
.uri
== RHS
.uri
&& LHS
.range
== RHS
.range
;
220 friend bool operator!=(const Location
&LHS
, const Location
&RHS
) {
221 return !(LHS
== RHS
);
224 friend bool operator<(const Location
&LHS
, const Location
&RHS
) {
225 return std::tie(LHS
.uri
, LHS
.range
) < std::tie(RHS
.uri
, RHS
.range
);
228 llvm::json::Value
toJSON(const Location
&);
229 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const Location
&);
231 /// Extends Locations returned by textDocument/references with extra info.
232 /// This is a clangd extension: LSP uses `Location`.
233 struct ReferenceLocation
: Location
{
234 /// clangd extension: contains the name of the function or class in which the
236 std::optional
<std::string
> containerName
;
238 llvm::json::Value
toJSON(const ReferenceLocation
&);
239 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const ReferenceLocation
&);
241 using ChangeAnnotationIdentifier
= std::string
;
242 // A combination of a LSP standard TextEdit and AnnotatedTextEdit.
244 /// The range of the text document to be manipulated. To insert
245 /// text into a document create a range where start === end.
248 /// The string to be inserted. For delete operations use an
252 /// The actual annotation identifier (optional)
253 /// If empty, then this field is nullopt.
254 ChangeAnnotationIdentifier annotationId
= "";
256 inline bool operator==(const TextEdit
&L
, const TextEdit
&R
) {
257 return std::tie(L
.newText
, L
.range
, L
.annotationId
) ==
258 std::tie(R
.newText
, R
.range
, L
.annotationId
);
260 bool fromJSON(const llvm::json::Value
&, TextEdit
&, llvm::json::Path
);
261 llvm::json::Value
toJSON(const TextEdit
&);
262 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const TextEdit
&);
264 struct ChangeAnnotation
{
265 /// A human-readable string describing the actual change. The string
266 /// is rendered prominent in the user interface.
269 /// A flag which indicates that user confirmation is needed
270 /// before applying the change.
271 std::optional
<bool> needsConfirmation
;
273 /// A human-readable string which is rendered less prominent in
274 /// the user interface.
275 std::string description
;
277 bool fromJSON(const llvm::json::Value
&, ChangeAnnotation
&, llvm::json::Path
);
278 llvm::json::Value
toJSON(const ChangeAnnotation
&);
280 struct TextDocumentEdit
{
281 /// The text document to change.
282 VersionedTextDocumentIdentifier textDocument
;
284 /// The edits to be applied.
285 /// FIXME: support the AnnotatedTextEdit variant.
286 std::vector
<TextEdit
> edits
;
288 bool fromJSON(const llvm::json::Value
&, TextDocumentEdit
&, llvm::json::Path
);
289 llvm::json::Value
toJSON(const TextDocumentEdit
&);
291 struct TextDocumentItem
{
292 /// The text document's URI.
295 /// The text document's language identifier.
296 std::string languageId
;
298 /// The version number of this document (it will strictly increase after each
299 /// change, including undo/redo.
301 /// clangd extension: versions are optional, and synthesized if missing.
302 std::optional
<int64_t> version
;
304 /// The content of the opened text document.
307 bool fromJSON(const llvm::json::Value
&, TextDocumentItem
&, llvm::json::Path
);
309 enum class TraceLevel
{
314 bool fromJSON(const llvm::json::Value
&E
, TraceLevel
&Out
, llvm::json::Path
);
317 inline llvm::json::Value
toJSON(const NoParams
&) { return nullptr; }
318 inline bool fromJSON(const llvm::json::Value
&, NoParams
&, llvm::json::Path
) {
321 using InitializedParams
= NoParams
;
323 /// Defines how the host (editor) should sync document changes to the language
325 enum class TextDocumentSyncKind
{
326 /// Documents should not be synced at all.
329 /// Documents are synced by always sending the full content of the document.
332 /// Documents are synced by sending the full content on open. After that
333 /// only incremental updates to the document are send.
337 /// The kind of a completion entry.
338 enum class CompletionItemKind
{
366 bool fromJSON(const llvm::json::Value
&, CompletionItemKind
&,
368 constexpr auto CompletionItemKindMin
=
369 static_cast<size_t>(CompletionItemKind::Text
);
370 constexpr auto CompletionItemKindMax
=
371 static_cast<size_t>(CompletionItemKind::TypeParameter
);
372 using CompletionItemKindBitset
= std::bitset
<CompletionItemKindMax
+ 1>;
373 bool fromJSON(const llvm::json::Value
&, CompletionItemKindBitset
&,
376 adjustKindToCapability(CompletionItemKind Kind
,
377 CompletionItemKindBitset
&SupportedCompletionItemKinds
);
380 enum class SymbolKind
{
408 bool fromJSON(const llvm::json::Value
&, SymbolKind
&, llvm::json::Path
);
409 constexpr auto SymbolKindMin
= static_cast<size_t>(SymbolKind::File
);
410 constexpr auto SymbolKindMax
= static_cast<size_t>(SymbolKind::TypeParameter
);
411 using SymbolKindBitset
= std::bitset
<SymbolKindMax
+ 1>;
412 bool fromJSON(const llvm::json::Value
&, SymbolKindBitset
&, llvm::json::Path
);
413 SymbolKind
adjustKindToCapability(SymbolKind Kind
,
414 SymbolKindBitset
&supportedSymbolKinds
);
416 // Convert a index::SymbolKind to clangd::SymbolKind (LSP)
417 // Note, some are not perfect matches and should be improved when this LSP
418 // issue is addressed:
419 // https://github.com/Microsoft/language-server-protocol/issues/344
420 SymbolKind
indexSymbolKindToSymbolKind(index::SymbolKind Kind
);
422 // Determines the encoding used to measure offsets and lengths of source in LSP.
423 enum class OffsetEncoding
{
424 // Any string is legal on the wire. Unrecognized encodings parse as this.
426 // Length counts code units of UTF-16 encoded text. (Standard LSP behavior).
428 // Length counts bytes of UTF-8 encoded text. (Clangd extension).
430 // Length counts codepoints in unicode text. (Clangd extension).
433 llvm::json::Value
toJSON(const OffsetEncoding
&);
434 bool fromJSON(const llvm::json::Value
&, OffsetEncoding
&, llvm::json::Path
);
435 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, OffsetEncoding
);
437 // Describes the content type that a client supports in various result literals
438 // like `Hover`, `ParameterInfo` or `CompletionItem`.
439 enum class MarkupKind
{
443 bool fromJSON(const llvm::json::Value
&, MarkupKind
&, llvm::json::Path
);
444 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
, MarkupKind
);
446 // This struct doesn't mirror LSP!
447 // The protocol defines deeply nested structures for client capabilities.
448 // Instead of mapping them all, this just parses out the bits we care about.
449 struct ClientCapabilities
{
450 /// The supported set of SymbolKinds for workspace/symbol.
451 /// workspace.symbol.symbolKind.valueSet
452 std::optional
<SymbolKindBitset
> WorkspaceSymbolKinds
;
454 /// Whether the client accepts diagnostics with codeActions attached inline.
455 /// This is a clangd extension.
456 /// textDocument.publishDiagnostics.codeActionsInline.
457 bool DiagnosticFixes
= false;
459 /// Whether the client accepts diagnostics with related locations.
460 /// textDocument.publishDiagnostics.relatedInformation.
461 bool DiagnosticRelatedInformation
= false;
463 /// Whether the client accepts diagnostics with category attached to it
464 /// using the "category" extension.
465 /// textDocument.publishDiagnostics.categorySupport
466 bool DiagnosticCategory
= false;
468 /// Client supports snippets as insert text.
469 /// textDocument.completion.completionItem.snippetSupport
470 bool CompletionSnippets
= false;
472 /// Client supports completions with additionalTextEdit near the cursor.
473 /// This is a clangd extension. (LSP says this is for unrelated text only).
474 /// textDocument.completion.editsNearCursor
475 bool CompletionFixes
= false;
477 /// Client supports displaying a container string for results of
478 /// textDocument/reference (clangd extension)
479 /// textDocument.references.container
480 bool ReferenceContainer
= false;
482 /// Client supports hierarchical document symbols.
483 /// textDocument.documentSymbol.hierarchicalDocumentSymbolSupport
484 bool HierarchicalDocumentSymbol
= false;
486 /// Client supports signature help.
487 /// textDocument.signatureHelp
488 bool HasSignatureHelp
= false;
490 /// Client signals that it only supports folding complete lines.
491 /// Client will ignore specified `startCharacter` and `endCharacter`
492 /// properties in a FoldingRange.
493 /// textDocument.foldingRange.lineFoldingOnly
494 bool LineFoldingOnly
= false;
496 /// Client supports processing label offsets instead of a simple label string.
497 /// textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport
498 bool OffsetsInSignatureHelp
= false;
500 /// The documentation format that should be used for
501 /// textDocument/signatureHelp.
502 /// textDocument.signatureHelp.signatureInformation.documentationFormat
503 MarkupKind SignatureHelpDocumentationFormat
= MarkupKind::PlainText
;
505 /// The supported set of CompletionItemKinds for textDocument/completion.
506 /// textDocument.completion.completionItemKind.valueSet
507 std::optional
<CompletionItemKindBitset
> CompletionItemKinds
;
509 /// The documentation format that should be used for textDocument/completion.
510 /// textDocument.completion.completionItem.documentationFormat
511 MarkupKind CompletionDocumentationFormat
= MarkupKind::PlainText
;
513 /// The client has support for completion item label details.
514 /// textDocument.completion.completionItem.labelDetailsSupport.
515 bool CompletionLabelDetail
= false;
517 /// Client supports CodeAction return value for textDocument/codeAction.
518 /// textDocument.codeAction.codeActionLiteralSupport.
519 bool CodeActionStructure
= false;
521 /// Client advertises support for the semanticTokens feature.
522 /// We support the textDocument/semanticTokens request in any case.
523 /// textDocument.semanticTokens
524 bool SemanticTokens
= false;
525 /// Client supports Theia semantic highlighting extension.
526 /// https://github.com/microsoft/vscode-languageserver-node/pull/367
527 /// clangd no longer supports this, we detect it just to log a warning.
528 /// textDocument.semanticHighlightingCapabilities.semanticHighlighting
529 bool TheiaSemanticHighlighting
= false;
531 /// Supported encodings for LSP character offsets. (clangd extension).
532 std::optional
<std::vector
<OffsetEncoding
>> offsetEncoding
;
534 /// The content format that should be used for Hover requests.
535 /// textDocument.hover.contentEncoding
536 MarkupKind HoverContentFormat
= MarkupKind::PlainText
;
538 /// The client supports testing for validity of rename operations
539 /// before execution.
540 bool RenamePrepareSupport
= false;
542 /// The client supports progress notifications.
543 /// window.workDoneProgress
544 bool WorkDoneProgress
= false;
546 /// The client supports implicit $/progress work-done progress streams,
547 /// without a preceding window/workDoneProgress/create.
548 /// This is a clangd extension.
549 /// window.implicitWorkDoneProgressCreate
550 bool ImplicitProgressCreation
= false;
552 /// Whether the client claims to cancel stale requests.
553 /// general.staleRequestSupport.cancel
554 bool CancelsStaleRequests
= false;
556 /// Whether the client implementation supports a refresh request sent from the
557 /// server to the client.
558 bool SemanticTokenRefreshSupport
= false;
560 /// The client supports versioned document changes for WorkspaceEdit.
561 bool DocumentChanges
= false;
563 /// The client supports change annotations on text edits,
564 bool ChangeAnnotation
= false;
566 /// Whether the client supports the textDocument/inactiveRegions
567 /// notification. This is a clangd extension.
568 /// textDocument.inactiveRegionsCapabilities.inactiveRegions
569 bool InactiveRegions
= false;
571 bool fromJSON(const llvm::json::Value
&, ClientCapabilities
&,
574 /// Clangd extension that's used in the 'compilationDatabaseChanges' in
575 /// workspace/didChangeConfiguration to record updates to the in-memory
576 /// compilation database.
577 struct ClangdCompileCommand
{
578 std::string workingDirectory
;
579 std::vector
<std::string
> compilationCommand
;
581 bool fromJSON(const llvm::json::Value
&, ClangdCompileCommand
&,
584 /// Clangd extension: parameters configurable at any time, via the
585 /// `workspace/didChangeConfiguration` notification.
586 /// LSP defines this type as `any`.
587 struct ConfigurationSettings
{
588 // Changes to the in-memory compilation database.
589 // The key of the map is a file name.
590 std::map
<std::string
, ClangdCompileCommand
> compilationDatabaseChanges
;
592 bool fromJSON(const llvm::json::Value
&, ConfigurationSettings
&,
595 /// Clangd extension: parameters configurable at `initialize` time.
596 /// LSP defines this type as `any`.
597 struct InitializationOptions
{
598 // What we can change through the didChangeConfiguration request, we can
599 // also set through the initialize request (initializationOptions field).
600 ConfigurationSettings ConfigSettings
;
602 std::optional
<std::string
> compilationDatabasePath
;
603 // Additional flags to be included in the "fallback command" used when
604 // the compilation database doesn't describe an opened file.
605 // The command used will be approximately `clang $FILE $fallbackFlags`.
606 std::vector
<std::string
> fallbackFlags
;
608 /// Clients supports show file status for textDocument/clangd.fileStatus.
609 bool FileStatus
= false;
611 bool fromJSON(const llvm::json::Value
&, InitializationOptions
&,
614 struct InitializeParams
{
615 /// The process Id of the parent process that started
616 /// the server. Is null if the process has not been started by another
617 /// process. If the parent process is not alive then the server should exit
618 /// (see exit notification) its process.
619 std::optional
<int> processId
;
621 /// The rootPath of the workspace. Is null
622 /// if no folder is open.
624 /// @deprecated in favour of rootUri.
625 std::optional
<std::string
> rootPath
;
627 /// The rootUri of the workspace. Is null if no
628 /// folder is open. If both `rootPath` and `rootUri` are set
630 std::optional
<URIForFile
> rootUri
;
632 // User provided initialization options.
633 // initializationOptions?: any;
635 /// The capabilities provided by the client (editor or tool)
636 ClientCapabilities capabilities
;
637 /// The same data as capabilities, but not parsed (to expose to modules).
638 llvm::json::Object rawCapabilities
;
640 /// The initial trace setting. If omitted trace is disabled ('off').
641 std::optional
<TraceLevel
> trace
;
643 /// User-provided initialization options.
644 InitializationOptions initializationOptions
;
646 bool fromJSON(const llvm::json::Value
&, InitializeParams
&, llvm::json::Path
);
648 struct WorkDoneProgressCreateParams
{
649 /// The token to be used to report progress.
650 llvm::json::Value token
= nullptr;
652 llvm::json::Value
toJSON(const WorkDoneProgressCreateParams
&P
);
654 template <typename T
> struct ProgressParams
{
655 /// The progress token provided by the client or server.
656 llvm::json::Value token
= nullptr;
658 /// The progress data.
661 template <typename T
> llvm::json::Value
toJSON(const ProgressParams
<T
> &P
) {
662 return llvm::json::Object
{{"token", P
.token
}, {"value", P
.value
}};
664 /// To start progress reporting a $/progress notification with the following
665 /// payload must be sent.
666 struct WorkDoneProgressBegin
{
667 /// Mandatory title of the progress operation. Used to briefly inform about
668 /// the kind of operation being performed.
670 /// Examples: "Indexing" or "Linking dependencies".
673 /// Controls if a cancel button should show to allow the user to cancel the
674 /// long-running operation. Clients that don't support cancellation are
675 /// allowed to ignore the setting.
676 bool cancellable
= false;
678 /// Optional progress percentage to display (value 100 is considered 100%).
679 /// If not provided infinite progress is assumed and clients are allowed
680 /// to ignore the `percentage` value in subsequent in report notifications.
682 /// The value should be steadily rising. Clients are free to ignore values
683 /// that are not following this rule.
685 /// Clangd implementation note: we only send nonzero percentages in
686 /// the WorkProgressReport. 'true' here means percentages will be used.
687 bool percentage
= false;
689 llvm::json::Value
toJSON(const WorkDoneProgressBegin
&);
691 /// Reporting progress is done using the following payload.
692 struct WorkDoneProgressReport
{
693 /// Mandatory title of the progress operation. Used to briefly inform about
694 /// the kind of operation being performed.
696 /// Examples: "Indexing" or "Linking dependencies".
699 /// Controls enablement state of a cancel button. This property is only valid
700 /// if a cancel button got requested in the `WorkDoneProgressStart` payload.
702 /// Clients that don't support cancellation or don't support control
703 /// the button's enablement state are allowed to ignore the setting.
704 std::optional
<bool> cancellable
;
706 /// Optional, more detailed associated progress message. Contains
707 /// complementary information to the `title`.
709 /// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
710 /// If unset, the previous progress message (if any) is still valid.
711 std::optional
<std::string
> message
;
713 /// Optional progress percentage to display (value 100 is considered 100%).
714 /// If not provided infinite progress is assumed and clients are allowed
715 /// to ignore the `percentage` value in subsequent in report notifications.
717 /// The value should be steadily rising. Clients are free to ignore values
718 /// that are not following this rule.
719 std::optional
<unsigned> percentage
;
721 llvm::json::Value
toJSON(const WorkDoneProgressReport
&);
723 /// Signals the end of progress reporting.
724 struct WorkDoneProgressEnd
{
725 /// Optional, a final message indicating to for example indicate the outcome
726 /// of the operation.
727 std::optional
<std::string
> message
;
729 llvm::json::Value
toJSON(const WorkDoneProgressEnd
&);
731 enum class MessageType
{
732 /// An error message.
734 /// A warning message.
736 /// An information message.
741 llvm::json::Value
toJSON(const MessageType
&);
743 /// The show message notification is sent from a server to a client to ask the
744 /// client to display a particular message in the user interface.
745 struct ShowMessageParams
{
746 /// The message type.
747 MessageType type
= MessageType::Info
;
748 /// The actual message.
751 llvm::json::Value
toJSON(const ShowMessageParams
&);
753 struct DidOpenTextDocumentParams
{
754 /// The document that was opened.
755 TextDocumentItem textDocument
;
757 bool fromJSON(const llvm::json::Value
&, DidOpenTextDocumentParams
&,
760 struct DidCloseTextDocumentParams
{
761 /// The document that was closed.
762 TextDocumentIdentifier textDocument
;
764 bool fromJSON(const llvm::json::Value
&, DidCloseTextDocumentParams
&,
767 struct DidSaveTextDocumentParams
{
768 /// The document that was saved.
769 TextDocumentIdentifier textDocument
;
771 bool fromJSON(const llvm::json::Value
&, DidSaveTextDocumentParams
&,
774 struct TextDocumentContentChangeEvent
{
775 /// The range of the document that changed.
776 std::optional
<Range
> range
;
778 /// The length of the range that got replaced.
779 std::optional
<int> rangeLength
;
781 /// The new text of the range/document.
784 bool fromJSON(const llvm::json::Value
&, TextDocumentContentChangeEvent
&,
787 struct DidChangeTextDocumentParams
{
788 /// The document that did change. The version number points
789 /// to the version after all provided content changes have
791 VersionedTextDocumentIdentifier textDocument
;
793 /// The actual content changes.
794 std::vector
<TextDocumentContentChangeEvent
> contentChanges
;
796 /// Forces diagnostics to be generated, or to not be generated, for this
797 /// version of the file. If not set, diagnostics are eventually consistent:
798 /// either they will be provided for this version or some subsequent one.
799 /// This is a clangd extension.
800 std::optional
<bool> wantDiagnostics
;
802 /// Force a complete rebuild of the file, ignoring all cached state. Slow!
803 /// This is useful to defeat clangd's assumption that missing headers will
805 /// This is a clangd extension.
806 bool forceRebuild
= false;
808 bool fromJSON(const llvm::json::Value
&, DidChangeTextDocumentParams
&,
811 enum class FileChangeType
{
812 /// The file got created.
814 /// The file got changed.
816 /// The file got deleted.
819 bool fromJSON(const llvm::json::Value
&E
, FileChangeType
&Out
,
826 FileChangeType type
= FileChangeType::Created
;
828 bool fromJSON(const llvm::json::Value
&, FileEvent
&, llvm::json::Path
);
830 struct DidChangeWatchedFilesParams
{
831 /// The actual file events.
832 std::vector
<FileEvent
> changes
;
834 bool fromJSON(const llvm::json::Value
&, DidChangeWatchedFilesParams
&,
837 struct DidChangeConfigurationParams
{
838 ConfigurationSettings settings
;
840 bool fromJSON(const llvm::json::Value
&, DidChangeConfigurationParams
&,
843 // Note: we do not parse FormattingOptions for *FormattingParams.
844 // In general, we use a clang-format style detected from common mechanisms
845 // (.clang-format files and the -fallback-style flag).
846 // It would be possible to override these with FormatOptions, but:
847 // - the protocol makes FormatOptions mandatory, so many clients set them to
848 // useless values, and we can't tell when to respect them
849 // - we also format in other places, where FormatOptions aren't available.
851 struct DocumentRangeFormattingParams
{
852 /// The document to format.
853 TextDocumentIdentifier textDocument
;
855 /// The range to format
858 bool fromJSON(const llvm::json::Value
&, DocumentRangeFormattingParams
&,
861 struct DocumentOnTypeFormattingParams
{
862 /// The document to format.
863 TextDocumentIdentifier textDocument
;
865 /// The position at which this request was sent.
868 /// The character that has been typed.
871 bool fromJSON(const llvm::json::Value
&, DocumentOnTypeFormattingParams
&,
874 struct DocumentFormattingParams
{
875 /// The document to format.
876 TextDocumentIdentifier textDocument
;
878 bool fromJSON(const llvm::json::Value
&, DocumentFormattingParams
&,
881 struct DocumentSymbolParams
{
882 // The text document to find symbols in.
883 TextDocumentIdentifier textDocument
;
885 bool fromJSON(const llvm::json::Value
&, DocumentSymbolParams
&,
888 /// Represents a related message and source code location for a diagnostic.
889 /// This should be used to point to code locations that cause or related to a
890 /// diagnostics, e.g when duplicating a symbol in a scope.
891 struct DiagnosticRelatedInformation
{
892 /// The location of this related diagnostic information.
894 /// The message of this related diagnostic information.
897 llvm::json::Value
toJSON(const DiagnosticRelatedInformation
&);
900 /// Unused or unnecessary code.
902 /// Clients are allowed to render diagnostics with this tag faded out instead
903 /// of having an error squiggle.
905 /// Deprecated or obsolete code.
907 /// Clients are allowed to rendered diagnostics with this tag strike through.
910 llvm::json::Value
toJSON(DiagnosticTag Tag
);
912 /// Structure to capture a description for an error code.
913 struct CodeDescription
{
914 /// An URI to open with more information about the diagnostic error.
917 llvm::json::Value
toJSON(const CodeDescription
&);
921 /// The range at which the message applies.
924 /// The diagnostic's severity. Can be omitted. If omitted it is up to the
925 /// client to interpret diagnostics as error, warning, info or hint.
928 /// The diagnostic's code. Can be omitted.
931 /// An optional property to describe the error code.
932 std::optional
<CodeDescription
> codeDescription
;
934 /// A human-readable string describing the source of this
935 /// diagnostic, e.g. 'typescript' or 'super lint'.
938 /// The diagnostic's message.
941 /// Additional metadata about the diagnostic.
942 llvm::SmallVector
<DiagnosticTag
, 1> tags
;
944 /// An array of related diagnostic information, e.g. when symbol-names within
945 /// a scope collide all definitions can be marked via this property.
946 std::optional
<std::vector
<DiagnosticRelatedInformation
>> relatedInformation
;
948 /// The diagnostic's category. Can be omitted.
949 /// An LSP extension that's used to send the name of the category over to the
950 /// client. The category typically describes the compilation stage during
951 /// which the issue was produced, e.g. "Semantic Issue" or "Parse Issue".
952 std::optional
<std::string
> category
;
954 /// Clangd extension: code actions related to this diagnostic.
955 /// Only with capability textDocument.publishDiagnostics.codeActionsInline.
956 /// (These actions can also be obtained using textDocument/codeAction).
957 std::optional
<std::vector
<CodeAction
>> codeActions
;
959 /// A data entry field that is preserved between a
960 /// `textDocument/publishDiagnostics` notification
961 /// and `textDocument/codeAction` request.
962 /// Mutating users should associate their data with a unique key they can use
963 /// to retrieve later on.
964 llvm::json::Object data
;
966 llvm::json::Value
toJSON(const Diagnostic
&);
968 bool fromJSON(const llvm::json::Value
&, Diagnostic
&, llvm::json::Path
);
969 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const Diagnostic
&);
971 struct PublishDiagnosticsParams
{
972 /// The URI for which diagnostic information is reported.
974 /// An array of diagnostic information items.
975 std::vector
<Diagnostic
> diagnostics
;
976 /// The version number of the document the diagnostics are published for.
977 std::optional
<int64_t> version
;
979 llvm::json::Value
toJSON(const PublishDiagnosticsParams
&);
981 struct CodeActionContext
{
982 /// An array of diagnostics known on the client side overlapping the range
983 /// provided to the `textDocument/codeAction` request. They are provided so
984 /// that the server knows which errors are currently presented to the user for
985 /// the given range. There is no guarantee that these accurately reflect the
986 /// error state of the resource. The primary parameter to compute code actions
987 /// is the provided range.
988 std::vector
<Diagnostic
> diagnostics
;
990 /// Requested kind of actions to return.
992 /// Actions not of this kind are filtered out by the client before being
993 /// shown. So servers can omit computing them.
994 std::vector
<std::string
> only
;
996 bool fromJSON(const llvm::json::Value
&, CodeActionContext
&, llvm::json::Path
);
998 struct CodeActionParams
{
999 /// The document in which the command was invoked.
1000 TextDocumentIdentifier textDocument
;
1002 /// The range for which the command was invoked.
1005 /// Context carrying additional information.
1006 CodeActionContext context
;
1008 bool fromJSON(const llvm::json::Value
&, CodeActionParams
&, llvm::json::Path
);
1010 /// The edit should either provide changes or documentChanges. If the client
1011 /// can handle versioned document edits and if documentChanges are present,
1012 /// the latter are preferred over changes.
1013 struct WorkspaceEdit
{
1014 /// Holds changes to existing resources.
1015 std::optional
<std::map
<std::string
, std::vector
<TextEdit
>>> changes
;
1016 /// Versioned document edits.
1018 /// If a client neither supports `documentChanges` nor
1019 /// `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
1020 /// using the `changes` property are supported.
1021 std::optional
<std::vector
<TextDocumentEdit
>> documentChanges
;
1023 /// A map of change annotations that can be referenced in
1024 /// AnnotatedTextEdit.
1025 std::map
<std::string
, ChangeAnnotation
> changeAnnotations
;
1027 bool fromJSON(const llvm::json::Value
&, WorkspaceEdit
&, llvm::json::Path
);
1028 llvm::json::Value
toJSON(const WorkspaceEdit
&WE
);
1030 /// Arguments for the 'applyTweak' command. The server sends these commands as a
1031 /// response to the textDocument/codeAction request. The client can later send a
1032 /// command back to the server if the user requests to execute a particular code
1035 /// A file provided by the client on a textDocument/codeAction request.
1037 /// A selection provided by the client on a textDocument/codeAction request.
1039 /// ID of the tweak that should be executed. Corresponds to Tweak::id().
1040 std::string tweakID
;
1042 bool fromJSON(const llvm::json::Value
&, TweakArgs
&, llvm::json::Path
);
1043 llvm::json::Value
toJSON(const TweakArgs
&A
);
1045 struct ExecuteCommandParams
{
1046 /// The identifier of the actual command handler.
1047 std::string command
;
1049 // This is `arguments?: []any` in LSP.
1050 // All clangd's commands accept a single argument (or none => null).
1051 llvm::json::Value argument
= nullptr;
1053 bool fromJSON(const llvm::json::Value
&, ExecuteCommandParams
&,
1056 struct Command
: public ExecuteCommandParams
{
1059 llvm::json::Value
toJSON(const Command
&C
);
1061 /// A code action represents a change that can be performed in code, e.g. to fix
1062 /// a problem or to refactor code.
1064 /// A CodeAction must set either `edit` and/or a `command`. If both are
1065 /// supplied, the `edit` is applied first, then the `command` is executed.
1067 /// A short, human-readable, title for this code action.
1070 /// The kind of the code action.
1071 /// Used to filter code actions.
1072 std::optional
<std::string
> kind
;
1073 const static llvm::StringLiteral QUICKFIX_KIND
;
1074 const static llvm::StringLiteral REFACTOR_KIND
;
1075 const static llvm::StringLiteral INFO_KIND
;
1077 /// The diagnostics that this code action resolves.
1078 std::optional
<std::vector
<Diagnostic
>> diagnostics
;
1080 /// Marks this as a preferred action. Preferred actions are used by the
1081 /// `auto fix` command and can be targeted by keybindings.
1082 /// A quick fix should be marked preferred if it properly addresses the
1083 /// underlying error. A refactoring should be marked preferred if it is the
1084 /// most reasonable choice of actions to take.
1085 bool isPreferred
= false;
1087 /// The workspace edit this code action performs.
1088 std::optional
<WorkspaceEdit
> edit
;
1090 /// A command this code action executes. If a code action provides an edit
1091 /// and a command, first the edit is executed and then the command.
1092 std::optional
<Command
> command
;
1094 llvm::json::Value
toJSON(const CodeAction
&);
1096 /// Represents programming constructs like variables, classes, interfaces etc.
1097 /// that appear in a document. Document symbols can be hierarchical and they
1098 /// have two ranges: one that encloses its definition and one that points to its
1099 /// most interesting range, e.g. the range of an identifier.
1100 struct DocumentSymbol
{
1101 /// The name of this symbol.
1104 /// More detail for this symbol, e.g the signature of a function.
1107 /// The kind of this symbol.
1110 /// Indicates if this symbol is deprecated.
1111 bool deprecated
= false;
1113 /// The range enclosing this symbol not including leading/trailing whitespace
1114 /// but everything else like comments. This information is typically used to
1115 /// determine if the clients cursor is inside the symbol to reveal in the
1116 /// symbol in the UI.
1119 /// The range that should be selected and revealed when this symbol is being
1120 /// picked, e.g the name of a function. Must be contained by the `range`.
1121 Range selectionRange
;
1123 /// Children of this symbol, e.g. properties of a class.
1124 std::vector
<DocumentSymbol
> children
;
1126 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&O
, const DocumentSymbol
&S
);
1127 llvm::json::Value
toJSON(const DocumentSymbol
&S
);
1129 /// Represents information about programming constructs like variables, classes,
1131 struct SymbolInformation
{
1132 /// The name of this symbol.
1135 /// The kind of this symbol.
1138 /// The location of this symbol.
1141 /// The name of the symbol containing this symbol.
1142 std::string containerName
;
1144 /// The score that clangd calculates to rank the returned symbols.
1145 /// This excludes the fuzzy-matching score between `name` and the query.
1146 /// (Specifically, the last ::-separated component).
1147 /// This can be used to re-rank results as the user types, using client-side
1148 /// fuzzy-matching (that score should be multiplied with this one).
1149 /// This is a clangd extension, set only for workspace/symbol responses.
1150 std::optional
<float> score
;
1152 llvm::json::Value
toJSON(const SymbolInformation
&);
1153 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const SymbolInformation
&);
1155 /// Represents information about identifier.
1156 /// This is returned from textDocument/symbolInfo, which is a clangd extension.
1157 struct SymbolDetails
{
1160 std::string containerName
;
1162 /// Unified Symbol Resolution identifier
1163 /// This is an opaque string uniquely identifying a symbol.
1164 /// Unlike SymbolID, it is variable-length and somewhat human-readable.
1165 /// It is a common representation across several clang tools.
1166 /// (See USRGeneration.h)
1171 std::optional
<Location
> declarationRange
;
1173 std::optional
<Location
> definitionRange
;
1175 llvm::json::Value
toJSON(const SymbolDetails
&);
1176 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const SymbolDetails
&);
1177 bool operator==(const SymbolDetails
&, const SymbolDetails
&);
1179 /// The parameters of a Workspace Symbol Request.
1180 struct WorkspaceSymbolParams
{
1181 /// A query string to filter symbols by.
1182 /// Clients may send an empty string here to request all the symbols.
1185 /// Max results to return, overriding global default. 0 means no limit.
1186 /// Clangd extension.
1187 std::optional
<int> limit
;
1189 bool fromJSON(const llvm::json::Value
&, WorkspaceSymbolParams
&,
1192 struct ApplyWorkspaceEditParams
{
1195 llvm::json::Value
toJSON(const ApplyWorkspaceEditParams
&);
1197 struct ApplyWorkspaceEditResponse
{
1198 bool applied
= true;
1199 std::optional
<std::string
> failureReason
;
1201 bool fromJSON(const llvm::json::Value
&, ApplyWorkspaceEditResponse
&,
1204 struct TextDocumentPositionParams
{
1205 /// The text document.
1206 TextDocumentIdentifier textDocument
;
1208 /// The position inside the text document.
1211 bool fromJSON(const llvm::json::Value
&, TextDocumentPositionParams
&,
1214 enum class CompletionTriggerKind
{
1215 /// Completion was triggered by typing an identifier (24x7 code
1216 /// complete), manual invocation (e.g Ctrl+Space) or via API.
1218 /// Completion was triggered by a trigger character specified by
1219 /// the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
1220 TriggerCharacter
= 2,
1221 /// Completion was re-triggered as the current completion list is incomplete.
1222 TriggerTriggerForIncompleteCompletions
= 3
1225 struct CompletionContext
{
1226 /// How the completion was triggered.
1227 CompletionTriggerKind triggerKind
= CompletionTriggerKind::Invoked
;
1228 /// The trigger character (a single character) that has trigger code complete.
1229 /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
1230 std::string triggerCharacter
;
1232 bool fromJSON(const llvm::json::Value
&, CompletionContext
&, llvm::json::Path
);
1234 struct CompletionParams
: TextDocumentPositionParams
{
1235 CompletionContext context
;
1237 /// Max results to return, overriding global default. 0 means no limit.
1238 /// Clangd extension.
1239 std::optional
<int> limit
;
1241 bool fromJSON(const llvm::json::Value
&, CompletionParams
&, llvm::json::Path
);
1243 struct MarkupContent
{
1244 MarkupKind kind
= MarkupKind::PlainText
;
1247 llvm::json::Value
toJSON(const MarkupContent
&MC
);
1250 /// The hover's content
1251 MarkupContent contents
;
1253 /// An optional range is a range inside a text document
1254 /// that is used to visualize a hover, e.g. by changing the background color.
1255 std::optional
<Range
> range
;
1257 llvm::json::Value
toJSON(const Hover
&H
);
1259 /// Defines whether the insert text in a completion item should be interpreted
1260 /// as plain text or a snippet.
1261 enum class InsertTextFormat
{
1263 /// The primary text to be inserted is treated as a plain string.
1265 /// The primary text to be inserted is treated as a snippet.
1267 /// A snippet can define tab stops and placeholders with `$1`, `$2`
1268 /// and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end
1269 /// of the snippet. Placeholders with equal identifiers are linked, that is
1270 /// typing in one will update others too.
1273 /// https://github.com/Microsoft/vscode/blob/main/src/vs/editor/contrib/snippet/snippet.md
1277 /// Additional details for a completion item label.
1278 struct CompletionItemLabelDetails
{
1279 /// An optional string which is rendered less prominently directly after label
1280 /// without any spacing. Should be used for function signatures or type
1284 /// An optional string which is rendered less prominently after
1285 /// CompletionItemLabelDetails.detail. Should be used for fully qualified
1286 /// names or file path.
1287 std::string description
;
1289 llvm::json::Value
toJSON(const CompletionItemLabelDetails
&);
1291 struct CompletionItem
{
1292 /// The label of this completion item. By default also the text that is
1293 /// inserted when selecting this completion.
1296 /// Additional details for the label.
1297 std::optional
<CompletionItemLabelDetails
> labelDetails
;
1299 /// The kind of this completion item. Based of the kind an icon is chosen by
1301 CompletionItemKind kind
= CompletionItemKind::Missing
;
1303 /// A human-readable string with additional information about this item, like
1304 /// type or symbol information.
1307 /// A human-readable string that represents a doc-comment.
1308 std::optional
<MarkupContent
> documentation
;
1310 /// A string that should be used when comparing this item with other items.
1311 /// When `falsy` the label is used.
1312 std::string sortText
;
1314 /// A string that should be used when filtering a set of completion items.
1315 /// When `falsy` the label is used.
1316 std::string filterText
;
1318 /// A string that should be inserted to a document when selecting this
1319 /// completion. When `falsy` the label is used.
1320 std::string insertText
;
1322 /// The format of the insert text. The format applies to both the `insertText`
1323 /// property and the `newText` property of a provided `textEdit`.
1324 InsertTextFormat insertTextFormat
= InsertTextFormat::Missing
;
1326 /// An edit which is applied to a document when selecting this completion.
1327 /// When an edit is provided `insertText` is ignored.
1329 /// Note: The range of the edit must be a single line range and it must
1330 /// contain the position at which completion has been requested.
1331 std::optional
<TextEdit
> textEdit
;
1333 /// An optional array of additional text edits that are applied when selecting
1334 /// this completion. Edits must not overlap with the main edit nor with
1336 std::vector
<TextEdit
> additionalTextEdits
;
1338 /// Indicates if this item is deprecated.
1339 bool deprecated
= false;
1341 /// The score that clangd calculates to rank the returned completions.
1342 /// This excludes the fuzzy-match between `filterText` and the partial word.
1343 /// This can be used to re-rank results as the user types, using client-side
1344 /// fuzzy-matching (that score should be multiplied with this one).
1345 /// This is a clangd extension.
1348 // TODO: Add custom commitCharacters for some of the completion items. For
1349 // example, it makes sense to use () only for the functions.
1350 // TODO(krasimir): The following optional fields defined by the language
1351 // server protocol are unsupported:
1353 // data?: any - A data entry field that is preserved on a completion item
1354 // between a completion and a completion resolve request.
1356 llvm::json::Value
toJSON(const CompletionItem
&);
1357 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const CompletionItem
&);
1359 /// Remove the labelDetails field (for clients that don't support it).
1360 /// Places the information into other fields of the completion item.
1361 void removeCompletionLabelDetails(CompletionItem
&);
1363 bool operator<(const CompletionItem
&, const CompletionItem
&);
1365 /// Represents a collection of completion items to be presented in the editor.
1366 struct CompletionList
{
1367 /// The list is not complete. Further typing should result in recomputing the
1369 bool isIncomplete
= false;
1371 /// The completion items.
1372 std::vector
<CompletionItem
> items
;
1374 llvm::json::Value
toJSON(const CompletionList
&);
1376 /// A single parameter of a particular signature.
1377 struct ParameterInformation
{
1379 /// The label of this parameter. Ignored when labelOffsets is set.
1380 std::string labelString
;
1382 /// Inclusive start and exclusive end offsets withing the containing signature
1384 /// Offsets are computed by lspLength(), which counts UTF-16 code units by
1385 /// default but that can be overriden, see its documentation for details.
1386 std::optional
<std::pair
<unsigned, unsigned>> labelOffsets
;
1388 /// The documentation of this parameter. Optional.
1389 std::string documentation
;
1391 llvm::json::Value
toJSON(const ParameterInformation
&);
1393 /// Represents the signature of something callable.
1394 struct SignatureInformation
{
1396 /// The label of this signature. Mandatory.
1399 /// The documentation of this signature. Optional.
1400 MarkupContent documentation
;
1402 /// The parameters of this signature.
1403 std::vector
<ParameterInformation
> parameters
;
1405 llvm::json::Value
toJSON(const SignatureInformation
&);
1406 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&,
1407 const SignatureInformation
&);
1409 /// Represents the signature of a callable.
1410 struct SignatureHelp
{
1412 /// The resulting signatures.
1413 std::vector
<SignatureInformation
> signatures
;
1415 /// The active signature.
1416 int activeSignature
= 0;
1418 /// The active parameter of the active signature.
1419 int activeParameter
= 0;
1421 /// Position of the start of the argument list, including opening paren. e.g.
1422 /// foo("first arg", "second arg",
1423 /// ^-argListStart ^-cursor
1424 /// This is a clangd-specific extension, it is only available via C++ API and
1425 /// not currently serialized for the LSP.
1426 Position argListStart
;
1428 llvm::json::Value
toJSON(const SignatureHelp
&);
1430 struct RenameParams
{
1431 /// The document that was opened.
1432 TextDocumentIdentifier textDocument
;
1434 /// The position at which this request was sent.
1437 /// The new name of the symbol.
1438 std::string newName
;
1440 bool fromJSON(const llvm::json::Value
&, RenameParams
&, llvm::json::Path
);
1441 llvm::json::Value
toJSON(const RenameParams
&);
1443 struct PrepareRenameResult
{
1444 /// Range of the string to rename.
1446 /// Placeholder text to use in the editor if non-empty.
1447 std::string placeholder
;
1449 llvm::json::Value
toJSON(const PrepareRenameResult
&PRR
);
1451 enum class DocumentHighlightKind
{ Text
= 1, Read
= 2, Write
= 3 };
1453 /// A document highlight is a range inside a text document which deserves
1454 /// special attention. Usually a document highlight is visualized by changing
1455 /// the background color of its range.
1457 struct DocumentHighlight
{
1458 /// The range this highlight applies to.
1461 /// The highlight kind, default is DocumentHighlightKind.Text.
1462 DocumentHighlightKind kind
= DocumentHighlightKind::Text
;
1464 friend bool operator<(const DocumentHighlight
&LHS
,
1465 const DocumentHighlight
&RHS
) {
1466 int LHSKind
= static_cast<int>(LHS
.kind
);
1467 int RHSKind
= static_cast<int>(RHS
.kind
);
1468 return std::tie(LHS
.range
, LHSKind
) < std::tie(RHS
.range
, RHSKind
);
1471 friend bool operator==(const DocumentHighlight
&LHS
,
1472 const DocumentHighlight
&RHS
) {
1473 return LHS
.kind
== RHS
.kind
&& LHS
.range
== RHS
.range
;
1476 llvm::json::Value
toJSON(const DocumentHighlight
&DH
);
1477 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const DocumentHighlight
&);
1479 enum class TypeHierarchyDirection
{ Children
= 0, Parents
= 1, Both
= 2 };
1480 bool fromJSON(const llvm::json::Value
&E
, TypeHierarchyDirection
&Out
,
1483 /// The type hierarchy params is an extension of the
1484 /// `TextDocumentPositionsParams` with optional properties which can be used to
1485 /// eagerly resolve the item when requesting from the server.
1486 struct TypeHierarchyPrepareParams
: public TextDocumentPositionParams
{
1487 /// The hierarchy levels to resolve. `0` indicates no level.
1488 /// This is a clangd extension.
1491 /// The direction of the hierarchy levels to resolve.
1492 /// This is a clangd extension.
1493 TypeHierarchyDirection direction
= TypeHierarchyDirection::Parents
;
1495 bool fromJSON(const llvm::json::Value
&, TypeHierarchyPrepareParams
&,
1498 struct TypeHierarchyItem
{
1499 /// The name of this item.
1502 /// The kind of this item.
1505 /// More detail for this item, e.g. the signature of a function.
1506 std::optional
<std::string
> detail
;
1508 /// The resource identifier of this item.
1511 /// The range enclosing this symbol not including leading/trailing whitespace
1512 /// but everything else, e.g. comments and code.
1515 /// The range that should be selected and revealed when this symbol is being
1516 /// picked, e.g. the name of a function. Must be contained by the `range`.
1517 Range selectionRange
;
1519 /// Used to resolve a client provided item back.
1520 struct ResolveParams
{
1522 /// std::nullopt means parents aren't resolved and empty is no parents.
1523 std::optional
<std::vector
<ResolveParams
>> parents
;
1525 /// A data entry field that is preserved between a type hierarchy prepare and
1526 /// supertypes or subtypes requests. It could also be used to identify the
1527 /// type hierarchy in the server, helping improve the performance on resolving
1528 /// supertypes and subtypes.
1531 /// `true` if the hierarchy item is deprecated. Otherwise, `false`.
1532 /// This is a clangd exntesion.
1533 bool deprecated
= false;
1535 /// This is a clangd exntesion.
1536 std::optional
<std::vector
<TypeHierarchyItem
>> parents
;
1538 /// If this type hierarchy item is resolved, it contains the direct children
1539 /// of the current item. Could be empty if the item does not have any
1540 /// descendants. If not defined, the children have not been resolved.
1541 /// This is a clangd exntesion.
1542 std::optional
<std::vector
<TypeHierarchyItem
>> children
;
1544 llvm::json::Value
toJSON(const TypeHierarchyItem::ResolveParams
&);
1545 bool fromJSON(const TypeHierarchyItem::ResolveParams
&);
1546 llvm::json::Value
toJSON(const TypeHierarchyItem
&);
1547 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const TypeHierarchyItem
&);
1548 bool fromJSON(const llvm::json::Value
&, TypeHierarchyItem
&, llvm::json::Path
);
1550 /// Parameters for the `typeHierarchy/resolve` request.
1551 struct ResolveTypeHierarchyItemParams
{
1552 /// The item to resolve.
1553 TypeHierarchyItem item
;
1555 /// The hierarchy levels to resolve. `0` indicates no level.
1558 /// The direction of the hierarchy levels to resolve.
1559 TypeHierarchyDirection direction
;
1561 bool fromJSON(const llvm::json::Value
&, ResolveTypeHierarchyItemParams
&,
1564 enum class SymbolTag
{ Deprecated
= 1 };
1565 llvm::json::Value
toJSON(SymbolTag
);
1567 /// The parameter of a `textDocument/prepareCallHierarchy` request.
1568 struct CallHierarchyPrepareParams
: public TextDocumentPositionParams
{};
1570 /// Represents programming constructs like functions or constructors
1571 /// in the context of call hierarchy.
1572 struct CallHierarchyItem
{
1573 /// The name of this item.
1576 /// The kind of this item.
1579 /// Tags for this item.
1580 std::vector
<SymbolTag
> tags
;
1582 /// More detaill for this item, e.g. the signature of a function.
1585 /// The resource identifier of this item.
1588 /// The range enclosing this symbol not including leading / trailing
1589 /// whitespace but everything else, e.g. comments and code.
1592 /// The range that should be selected and revealed when this symbol
1593 /// is being picked, e.g. the name of a function.
1594 /// Must be contained by `Rng`.
1595 Range selectionRange
;
1597 /// An optional 'data' field, which can be used to identify a call
1598 /// hierarchy item in an incomingCalls or outgoingCalls request.
1601 llvm::json::Value
toJSON(const CallHierarchyItem
&);
1602 bool fromJSON(const llvm::json::Value
&, CallHierarchyItem
&, llvm::json::Path
);
1604 /// The parameter of a `callHierarchy/incomingCalls` request.
1605 struct CallHierarchyIncomingCallsParams
{
1606 CallHierarchyItem item
;
1608 bool fromJSON(const llvm::json::Value
&, CallHierarchyIncomingCallsParams
&,
1611 /// Represents an incoming call, e.g. a caller of a method or constructor.
1612 struct CallHierarchyIncomingCall
{
1613 /// The item that makes the call.
1614 CallHierarchyItem from
;
1616 /// The range at which the calls appear.
1617 /// This is relative to the caller denoted by `From`.
1618 std::vector
<Range
> fromRanges
;
1620 llvm::json::Value
toJSON(const CallHierarchyIncomingCall
&);
1622 /// The parameter of a `callHierarchy/outgoingCalls` request.
1623 struct CallHierarchyOutgoingCallsParams
{
1624 CallHierarchyItem item
;
1626 bool fromJSON(const llvm::json::Value
&, CallHierarchyOutgoingCallsParams
&,
1629 /// Represents an outgoing call, e.g. calling a getter from a method or
1630 /// a method from a constructor etc.
1631 struct CallHierarchyOutgoingCall
{
1632 /// The item that is called.
1633 CallHierarchyItem to
;
1635 /// The range at which this item is called.
1636 /// This is the range relative to the caller, and not `To`.
1637 std::vector
<Range
> fromRanges
;
1639 llvm::json::Value
toJSON(const CallHierarchyOutgoingCall
&);
1641 /// A parameter literal used in inlay hint requests.
1642 struct InlayHintsParams
{
1643 /// The text document.
1644 TextDocumentIdentifier textDocument
;
1646 /// The visible document range for which inlay hints should be computed.
1648 /// std::nullopt is a clangd extension, which hints for computing hints on the
1650 std::optional
<Range
> range
;
1652 bool fromJSON(const llvm::json::Value
&, InlayHintsParams
&, llvm::json::Path
);
1654 /// Inlay hint kinds.
1655 enum class InlayHintKind
{
1656 /// An inlay hint that for a type annotation.
1658 /// An example of a type hint is a hint in this position:
1659 /// auto var ^ = expr;
1660 /// which shows the deduced type of the variable.
1663 /// An inlay hint that is for a parameter.
1665 /// An example of a parameter hint is a hint in this position:
1667 /// which shows the name of the corresponding parameter.
1670 /// A hint before an element of an aggregate braced initializer list,
1671 /// indicating what it is initializing.
1673 /// Uses designator syntax, e.g. `.first:`.
1674 /// This is a clangd extension.
1677 /// A hint after function, type or namespace definition, indicating the
1678 /// defined symbol name of the definition.
1680 /// An example of a decl name hint in this position:
1683 /// Uses comment-like syntax like "// func".
1684 /// This is a clangd extension.
1687 /// An inlay hint that is for a default argument.
1689 /// An example of a parameter hint for a default argument:
1690 /// void foo(bool A = true);
1692 /// Adds an inlay hint "A: true".
1693 /// This is a clangd extension.
1694 DefaultArgument
= 6,
1696 /// Other ideas for hints that are not currently implemented:
1698 /// * Chaining hints, showing the types of intermediate expressions
1699 /// in a chain of function calls.
1700 /// * Hints indicating implicit conversions or implicit constructor calls.
1702 llvm::json::Value
toJSON(const InlayHintKind
&);
1704 /// An inlay hint label part allows for interactive and composite labels
1706 struct InlayHintLabelPart
{
1708 InlayHintLabelPart() = default;
1710 InlayHintLabelPart(std::string value
,
1711 std::optional
<Location
> location
= std::nullopt
)
1712 : value(std::move(value
)), location(std::move(location
)) {}
1714 /// The value of this label part.
1717 /// The tooltip text when you hover over this label part. Depending on
1718 /// the client capability `inlayHint.resolveSupport`, clients might resolve
1719 /// this property late using the resolve request.
1720 std::optional
<MarkupContent
> tooltip
;
1722 /// An optional source code location that represents this
1725 /// The editor will use this location for the hover and for code navigation
1726 /// features: This part will become a clickable link that resolves to the
1727 /// definition of the symbol at the given location (not necessarily the
1728 /// location itself), it shows the hover that shows at the given location,
1729 /// and it shows a context menu with further code navigation commands.
1731 /// Depending on the client capability `inlayHint.resolveSupport` clients
1732 /// might resolve this property late using the resolve request.
1733 std::optional
<Location
> location
;
1735 /// An optional command for this label part.
1737 /// Depending on the client capability `inlayHint.resolveSupport` clients
1738 /// might resolve this property late using the resolve request.
1739 std::optional
<Command
> command
;
1741 llvm::json::Value
toJSON(const InlayHintLabelPart
&);
1742 bool operator==(const InlayHintLabelPart
&, const InlayHintLabelPart
&);
1743 bool operator<(const InlayHintLabelPart
&, const InlayHintLabelPart
&);
1744 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const InlayHintLabelPart
&);
1746 /// Inlay hint information.
1748 /// The position of this hint.
1751 /// The label of this hint. A human readable string or an array of
1752 /// InlayHintLabelPart label parts.
1754 /// *Note* that neither the string nor the label part can be empty.
1755 std::vector
<InlayHintLabelPart
> label
;
1757 /// The kind of this hint. Can be omitted in which case the client should fall
1758 /// back to a reasonable default.
1761 /// Render padding before the hint.
1763 /// Note: Padding should use the editor's background color, not the
1764 /// background color of the hint itself. That means padding can be used
1765 /// to visually align/separate an inlay hint.
1766 bool paddingLeft
= false;
1768 /// Render padding after the hint.
1770 /// Note: Padding should use the editor's background color, not the
1771 /// background color of the hint itself. That means padding can be used
1772 /// to visually align/separate an inlay hint.
1773 bool paddingRight
= false;
1775 /// The range of source code to which the hint applies.
1777 /// For example, a parameter hint may have the argument as its range.
1778 /// The range allows clients more flexibility of when/how to display the hint.
1779 /// This is an (unserialized) clangd extension.
1782 /// Join the label[].value together.
1783 std::string
joinLabels() const;
1785 llvm::json::Value
toJSON(const InlayHint
&);
1786 bool operator==(const InlayHint
&, const InlayHint
&);
1787 bool operator<(const InlayHint
&, const InlayHint
&);
1788 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, InlayHintKind
);
1790 struct ReferenceContext
{
1791 /// Include the declaration of the current symbol.
1792 bool includeDeclaration
= false;
1795 struct ReferenceParams
: public TextDocumentPositionParams
{
1796 ReferenceContext context
;
1798 bool fromJSON(const llvm::json::Value
&, ReferenceParams
&, llvm::json::Path
);
1800 /// Clangd extension: indicates the current state of the file in clangd,
1801 /// sent from server via the `textDocument/clangd.fileStatus` notification.
1803 /// The text document's URI.
1805 /// The human-readable string presents the current state of the file, can be
1806 /// shown in the UI (e.g. status bar).
1808 // FIXME: add detail messages.
1810 llvm::json::Value
toJSON(const FileStatus
&);
1812 /// Specifies a single semantic token in the document.
1813 /// This struct is not part of LSP, which just encodes lists of tokens as
1814 /// arrays of numbers directly.
1815 struct SemanticToken
{
1816 /// token line number, relative to the previous token
1817 unsigned deltaLine
= 0;
1818 /// token start character, relative to the previous token
1819 /// (relative to 0 or the previous token's start if they are on the same line)
1820 unsigned deltaStart
= 0;
1821 /// the length of the token. A token cannot be multiline
1822 unsigned length
= 0;
1823 /// will be looked up in `SemanticTokensLegend.tokenTypes`
1824 unsigned tokenType
= 0;
1825 /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers`
1826 unsigned tokenModifiers
= 0;
1828 bool operator==(const SemanticToken
&, const SemanticToken
&);
1830 /// A versioned set of tokens.
1831 struct SemanticTokens
{
1832 // An optional result id. If provided and clients support delta updating
1833 // the client will include the result id in the next semantic token request.
1834 // A server can then instead of computing all semantic tokens again simply
1836 std::string resultId
;
1838 /// The actual tokens.
1839 std::vector
<SemanticToken
> tokens
; // encoded as a flat integer array.
1841 llvm::json::Value
toJSON(const SemanticTokens
&);
1843 /// Body of textDocument/semanticTokens/full request.
1844 struct SemanticTokensParams
{
1845 /// The text document.
1846 TextDocumentIdentifier textDocument
;
1848 bool fromJSON(const llvm::json::Value
&, SemanticTokensParams
&,
1851 /// Body of textDocument/semanticTokens/full/delta request.
1852 /// Requests the changes in semantic tokens since a previous response.
1853 struct SemanticTokensDeltaParams
{
1854 /// The text document.
1855 TextDocumentIdentifier textDocument
;
1856 /// The previous result id.
1857 std::string previousResultId
;
1859 bool fromJSON(const llvm::json::Value
&Params
, SemanticTokensDeltaParams
&R
,
1862 /// Describes a replacement of a contiguous range of semanticTokens.
1863 struct SemanticTokensEdit
{
1864 // LSP specifies `start` and `deleteCount` which are relative to the array
1865 // encoding of the previous tokens.
1866 // We use token counts instead, and translate when serializing this struct.
1867 unsigned startToken
= 0;
1868 unsigned deleteTokens
= 0;
1869 std::vector
<SemanticToken
> tokens
; // encoded as a flat integer array
1871 llvm::json::Value
toJSON(const SemanticTokensEdit
&);
1873 /// This models LSP SemanticTokensDelta | SemanticTokens, which is the result of
1874 /// textDocument/semanticTokens/full/delta.
1875 struct SemanticTokensOrDelta
{
1876 std::string resultId
;
1877 /// Set if we computed edits relative to a previous set of tokens.
1878 std::optional
<std::vector
<SemanticTokensEdit
>> edits
;
1879 /// Set if we computed a fresh set of tokens.
1880 std::optional
<std::vector
<SemanticToken
>> tokens
; // encoded as integer array
1882 llvm::json::Value
toJSON(const SemanticTokensOrDelta
&);
1884 /// Parameters for the inactive regions (server-side) push notification.
1885 /// This is a clangd extension.
1886 struct InactiveRegionsParams
{
1887 /// The textdocument these inactive regions belong to.
1888 TextDocumentIdentifier TextDocument
;
1889 /// The inactive regions that should be sent.
1890 std::vector
<Range
> InactiveRegions
;
1892 llvm::json::Value
toJSON(const InactiveRegionsParams
&InactiveRegions
);
1894 struct SelectionRangeParams
{
1895 /// The text document.
1896 TextDocumentIdentifier textDocument
;
1898 /// The positions inside the text document.
1899 std::vector
<Position
> positions
;
1901 bool fromJSON(const llvm::json::Value
&, SelectionRangeParams
&,
1904 struct SelectionRange
{
1906 * The range of this selection range.
1910 * The parent selection range containing this range. Therefore `parent.range`
1911 * must contain `this.range`.
1913 std::unique_ptr
<SelectionRange
> parent
;
1915 llvm::json::Value
toJSON(const SelectionRange
&);
1917 /// Parameters for the document link request.
1918 struct DocumentLinkParams
{
1919 /// The document to provide document links for.
1920 TextDocumentIdentifier textDocument
;
1922 bool fromJSON(const llvm::json::Value
&, DocumentLinkParams
&,
1925 /// A range in a text document that links to an internal or external resource,
1926 /// like another text document or a web site.
1927 struct DocumentLink
{
1928 /// The range this link applies to.
1931 /// The uri this link points to. If missing a resolve request is sent later.
1934 // TODO(forster): The following optional fields defined by the language
1935 // server protocol are unsupported:
1937 // data?: any - A data entry field that is preserved on a document link
1938 // between a DocumentLinkRequest and a
1939 // DocumentLinkResolveRequest.
1941 friend bool operator==(const DocumentLink
&LHS
, const DocumentLink
&RHS
) {
1942 return LHS
.range
== RHS
.range
&& LHS
.target
== RHS
.target
;
1945 friend bool operator!=(const DocumentLink
&LHS
, const DocumentLink
&RHS
) {
1946 return !(LHS
== RHS
);
1949 llvm::json::Value
toJSON(const DocumentLink
&DocumentLink
);
1951 // FIXME(kirillbobyrev): Add FoldingRangeClientCapabilities so we can support
1952 // per-line-folding editors.
1953 struct FoldingRangeParams
{
1954 TextDocumentIdentifier textDocument
;
1956 bool fromJSON(const llvm::json::Value
&, FoldingRangeParams
&,
1959 /// Stores information about a region of code that can be folded.
1960 struct FoldingRange
{
1961 unsigned startLine
= 0;
1962 unsigned startCharacter
;
1963 unsigned endLine
= 0;
1964 unsigned endCharacter
;
1966 const static llvm::StringLiteral REGION_KIND
;
1967 const static llvm::StringLiteral COMMENT_KIND
;
1968 const static llvm::StringLiteral IMPORT_KIND
;
1971 llvm::json::Value
toJSON(const FoldingRange
&Range
);
1973 /// Keys starting with an underscore(_) represent leaves, e.g. _total or _self
1974 /// for memory usage of whole subtree or only that specific node in bytes. All
1975 /// other keys represents children. An example:
1992 llvm::json::Value
toJSON(const MemoryTree
&MT
);
1994 /// Payload for textDocument/ast request.
1995 /// This request is a clangd extension.
1997 /// The text document.
1998 TextDocumentIdentifier textDocument
;
2000 /// The position of the node to be dumped.
2001 /// The highest-level node that entirely contains the range will be returned.
2002 /// If no range is given, the root translation unit node will be returned.
2003 std::optional
<Range
> range
;
2005 bool fromJSON(const llvm::json::Value
&, ASTParams
&, llvm::json::Path
);
2007 /// Simplified description of a clang AST node.
2008 /// This is clangd's internal representation of C++ code.
2010 /// The general kind of node, such as "expression"
2011 /// Corresponds to the base AST node type such as Expr.
2013 /// The specific kind of node this is, such as "BinaryOperator".
2014 /// This is usually a concrete node class (with Expr etc suffix dropped).
2015 /// When there's no hierarchy (e.g. TemplateName), the variant (NameKind).
2017 /// Brief additional information, such as "||" for the particular operator.
2018 /// The information included depends on the node kind, and may be empty.
2020 /// A one-line dump of detailed information about the node.
2021 /// This includes role/kind/description information, but is rather cryptic.
2022 /// It is similar to the output from `clang -Xclang -ast-dump`.
2023 /// May be empty for certain types of nodes.
2025 /// The range of the original source file covered by this node.
2026 /// May be missing for implicit nodes, or those created by macro expansion.
2027 std::optional
<Range
> range
;
2028 /// Nodes nested within this one, such as the operands of a BinaryOperator.
2029 std::vector
<ASTNode
> children
;
2031 llvm::json::Value
toJSON(const ASTNode
&);
2032 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const ASTNode
&);
2034 } // namespace clangd
2035 } // namespace clang
2039 template <> struct DenseMapInfo
<clang::clangd::Range
> {
2040 using Range
= clang::clangd::Range
;
2041 static inline Range
getEmptyKey() {
2042 static clang::clangd::Position Tomb
{-1, -1};
2043 static Range R
{Tomb
, Tomb
};
2046 static inline Range
getTombstoneKey() {
2047 static clang::clangd::Position Tomb
{-2, -2};
2048 static Range R
{Tomb
, Tomb
};
2051 static unsigned getHashValue(const Range
&Val
) {
2052 return llvm::hash_combine(Val
.start
.line
, Val
.start
.character
, Val
.end
.line
,
2055 static bool isEqual(const Range
&LHS
, const Range
&RHS
) {
2056 return std::tie(LHS
.start
, LHS
.end
) == std::tie(RHS
.start
, RHS
.end
);
2060 template <> struct format_provider
<clang::clangd::Position
> {
2061 static void format(const clang::clangd::Position
&Pos
, raw_ostream
&OS
,
2063 assert(Style
.empty() && "style modifiers for this type are not supported");
2069 // NOLINTEND(readability-identifier-naming)