1 //===--- Protocol.h - Language Server Protocol Implementation ---*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains structs based on the LSP specification at
10 // https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md
11 //
12 // This is not meant to be a complete implementation, new interfaces are added
13 // when they're needed.
14 //
15 // Each struct has a toJSON and fromJSON function, that converts between
16 // the struct and a JSON representation. (See JSON.h)
17 //
18 // Some structs also have operator<< serialization. This is for debugging and
19 // tests, and is not generally machine-readable.
20 //
21 //===----------------------------------------------------------------------===//
22
23 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H
24 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROTOCOL_H
25
26 #include "URI.h"
27 #include "index/SymbolID.h"
28 #include "support/MemoryTree.h"
29 #include "clang/Index/IndexSymbol.h"
30 #include "llvm/ADT/Optional.h"
31 #include "llvm/Support/JSON.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include <bitset>
34 #include <memory>
35 #include <string>
36 #include <vector>
37
38 namespace clang {
39 namespace clangd {
40
41 enum class ErrorCode {
42 // Defined by JSON RPC.
43 ParseError = -32700,
44 InvalidRequest = -32600,
45 MethodNotFound = -32601,
46 InvalidParams = -32602,
47 InternalError = -32603,
48
49 ServerNotInitialized = -32002,
50 UnknownErrorCode = -32001,
51
52 // Defined by the protocol.
53 RequestCancelled = -32800,
54 ContentModified = -32801,
55 };
56 // Models an LSP error as an llvm::Error.
57 class LSPError : public llvm::ErrorInfo<LSPError> {
58 public:
59 std::string Message;
60 ErrorCode Code;
61 static char ID;
62
LSPError(std::string Message,ErrorCode Code)63 LSPError(std::string Message, ErrorCode Code)
64 : Message(std::move(Message)), Code(Code) {}
65
log(llvm::raw_ostream & OS)66 void log(llvm::raw_ostream &OS) const override {
67 OS << int(Code) << ": " << Message;
68 }
convertToErrorCode()69 std::error_code convertToErrorCode() const override {
70 return llvm::inconvertibleErrorCode();
71 }
72 };
73
74 // URI in "file" scheme for a file.
75 struct URIForFile {
76 URIForFile() = default;
77
78 /// Canonicalizes \p AbsPath via URI.
79 ///
80 /// File paths in URIForFile can come from index or local AST. Path from
81 /// index goes through URI transformation, and the final path is resolved by
82 /// URI scheme and could potentially be different from the original path.
83 /// Hence, we do the same transformation for all paths.
84 ///
85 /// Files can be referred to by several paths (e.g. in the presence of links).
86 /// Which one we prefer may depend on where we're coming from. \p TUPath is a
87 /// hint, and should usually be the main entrypoint file we're processing.
88 static URIForFile canonicalize(llvm::StringRef AbsPath,
89 llvm::StringRef TUPath);
90
91 static llvm::Expected<URIForFile> fromURI(const URI &U,
92 llvm::StringRef HintPath);
93
94 /// Retrieves absolute path to the file.
fileURIForFile95 llvm::StringRef file() const { return File; }
96
97 explicit operator bool() const { return !File.empty(); }
uriURIForFile98 std::string uri() const { return URI::createFile(File).toString(); }
99
100 friend bool operator==(const URIForFile &LHS, const URIForFile &RHS) {
101 return LHS.File == RHS.File;
102 }
103
104 friend bool operator!=(const URIForFile &LHS, const URIForFile &RHS) {
105 return !(LHS == RHS);
106 }
107
108 friend bool operator<(const URIForFile &LHS, const URIForFile &RHS) {
109 return LHS.File < RHS.File;
110 }
111
112 private:
URIForFileURIForFile113 explicit URIForFile(std::string &&File) : File(std::move(File)) {}
114
115 std::string File;
116 };
117
118 /// Serialize/deserialize \p URIForFile to/from a string URI.
119 llvm::json::Value toJSON(const URIForFile &U);
120 bool fromJSON(const llvm::json::Value &, URIForFile &, llvm::json::Path);
121
122 struct TextDocumentIdentifier {
123 /// The text document's URI.
124 URIForFile uri;
125 };
126 llvm::json::Value toJSON(const TextDocumentIdentifier &);
127 bool fromJSON(const llvm::json::Value &, TextDocumentIdentifier &,
128 llvm::json::Path);
129
130 struct VersionedTextDocumentIdentifier : public TextDocumentIdentifier {
131 /// The version number of this document. If a versioned text document
132 /// identifier is sent from the server to the client and the file is not open
133 /// in the editor (the server has not received an open notification before)
134 /// the server can send `null` to indicate that the version is known and the
135 /// content on disk is the master (as speced with document content ownership).
136 ///
137 /// The version number of a document will increase after each change,
138 /// including undo/redo. The number doesn't need to be consecutive.
139 ///
140 /// clangd extension: versions are optional, and synthesized if missing.
141 llvm::Optional<std::int64_t> version;
142 };
143 llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &);
144 bool fromJSON(const llvm::json::Value &, VersionedTextDocumentIdentifier &,
145 llvm::json::Path);
146
147 struct Position {
148 /// Line position in a document (zero-based).
149 int line = 0;
150
151 /// Character offset on a line in a document (zero-based).
152 /// WARNING: this is in UTF-16 codepoints, not bytes or characters!
153 /// Use the functions in SourceCode.h to construct/interpret Positions.
154 int character = 0;
155
156 friend bool operator==(const Position &LHS, const Position &RHS) {
157 return std::tie(LHS.line, LHS.character) ==
158 std::tie(RHS.line, RHS.character);
159 }
160 friend bool operator!=(const Position &LHS, const Position &RHS) {
161 return !(LHS == RHS);
162 }
163 friend bool operator<(const Position &LHS, const Position &RHS) {
164 return std::tie(LHS.line, LHS.character) <
165 std::tie(RHS.line, RHS.character);
166 }
167 friend bool operator<=(const Position &LHS, const Position &RHS) {
168 return std::tie(LHS.line, LHS.character) <=
169 std::tie(RHS.line, RHS.character);
170 }
171 };
172 bool fromJSON(const llvm::json::Value &, Position &, llvm::json::Path);
173 llvm::json::Value toJSON(const Position &);
174 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Position &);
175
176 struct Range {
177 /// The range's start position.
178 Position start;
179
180 /// The range's end position.
181 Position end;
182
183 friend bool operator==(const Range &LHS, const Range &RHS) {
184 return std::tie(LHS.start, LHS.end) == std::tie(RHS.start, RHS.end);
185 }
186 friend bool operator!=(const Range &LHS, const Range &RHS) {
187 return !(LHS == RHS);
188 }
189 friend bool operator<(const Range &LHS, const Range &RHS) {
190 return std::tie(LHS.start, LHS.end) < std::tie(RHS.start, RHS.end);
191 }
192
containsRange193 bool contains(Position Pos) const { return start <= Pos && Pos < end; }
containsRange194 bool contains(Range Rng) const {
195 return start <= Rng.start && Rng.end <= end;
196 }
197 };
198 bool fromJSON(const llvm::json::Value &, Range &, llvm::json::Path);
199 llvm::json::Value toJSON(const Range &);
200 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Range &);
201
202 struct Location {
203 /// The text document's URI.
204 URIForFile uri;
205 Range range;
206
207 friend bool operator==(const Location &LHS, const Location &RHS) {
208 return LHS.uri == RHS.uri && LHS.range == RHS.range;
209 }
210
211 friend bool operator!=(const Location &LHS, const Location &RHS) {
212 return !(LHS == RHS);
213 }
214
215 friend bool operator<(const Location &LHS, const Location &RHS) {
216 return std::tie(LHS.uri, LHS.range) < std::tie(RHS.uri, RHS.range);
217 }
218 };
219 llvm::json::Value toJSON(const Location &);
220 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Location &);
221
222 struct TextEdit {
223 /// The range of the text document to be manipulated. To insert
224 /// text into a document create a range where start === end.
225 Range range;
226
227 /// The string to be inserted. For delete operations use an
228 /// empty string.
229 std::string newText;
230 };
231 inline bool operator==(const TextEdit &L, const TextEdit &R) {
232 return std::tie(L.newText, L.range) == std::tie(R.newText, R.range);
233 }
234 bool fromJSON(const llvm::json::Value &, TextEdit &, llvm::json::Path);
235 llvm::json::Value toJSON(const TextEdit &);
236 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TextEdit &);
237
238 struct TextDocumentItem {
239 /// The text document's URI.
240 URIForFile uri;
241
242 /// The text document's language identifier.
243 std::string languageId;
244
245 /// The version number of this document (it will strictly increase after each
246 /// change, including undo/redo.
247 ///
248 /// clangd extension: versions are optional, and synthesized if missing.
249 llvm::Optional<int64_t> version;
250
251 /// The content of the opened text document.
252 std::string text;
253 };
254 bool fromJSON(const llvm::json::Value &, TextDocumentItem &, llvm::json::Path);
255
256 enum class TraceLevel {
257 Off = 0,
258 Messages = 1,
259 Verbose = 2,
260 };
261 bool fromJSON(const llvm::json::Value &E, TraceLevel &Out, llvm::json::Path);
262
263 struct NoParams {};
toJSON(const NoParams &)264 inline llvm::json::Value toJSON(const NoParams &) { return nullptr; }
fromJSON(const llvm::json::Value &,NoParams &,llvm::json::Path)265 inline bool fromJSON(const llvm::json::Value &, NoParams &, llvm::json::Path) {
266 return true;
267 }
268 using InitializedParams = NoParams;
269
270 /// Defines how the host (editor) should sync document changes to the language
271 /// server.
272 enum class TextDocumentSyncKind {
273 /// Documents should not be synced at all.
274 None = 0,
275
276 /// Documents are synced by always sending the full content of the document.
277 Full = 1,
278
279 /// Documents are synced by sending the full content on open. After that
280 /// only incremental updates to the document are send.
281 Incremental = 2,
282 };
283
284 /// The kind of a completion entry.
285 enum class CompletionItemKind {
286 Missing = 0,
287 Text = 1,
288 Method = 2,
289 Function = 3,
290 Constructor = 4,
291 Field = 5,
292 Variable = 6,
293 Class = 7,
294 Interface = 8,
295 Module = 9,
296 Property = 10,
297 Unit = 11,
298 Value = 12,
299 Enum = 13,
300 Keyword = 14,
301 Snippet = 15,
302 Color = 16,
303 File = 17,
304 Reference = 18,
305 Folder = 19,
306 EnumMember = 20,
307 Constant = 21,
308 Struct = 22,
309 Event = 23,
310 Operator = 24,
311 TypeParameter = 25,
312 };
313 bool fromJSON(const llvm::json::Value &, CompletionItemKind &,
314 llvm::json::Path);
315 constexpr auto CompletionItemKindMin =
316 static_cast<size_t>(CompletionItemKind::Text);
317 constexpr auto CompletionItemKindMax =
318 static_cast<size_t>(CompletionItemKind::TypeParameter);
319 using CompletionItemKindBitset = std::bitset<CompletionItemKindMax + 1>;
320 bool fromJSON(const llvm::json::Value &, CompletionItemKindBitset &,
321 llvm::json::Path);
322 CompletionItemKind
323 adjustKindToCapability(CompletionItemKind Kind,
324 CompletionItemKindBitset &SupportedCompletionItemKinds);
325
326 /// A symbol kind.
327 enum class SymbolKind {
328 File = 1,
329 Module = 2,
330 Namespace = 3,
331 Package = 4,
332 Class = 5,
333 Method = 6,
334 Property = 7,
335 Field = 8,
336 Constructor = 9,
337 Enum = 10,
338 Interface = 11,
339 Function = 12,
340 Variable = 13,
341 Constant = 14,
342 String = 15,
343 Number = 16,
344 Boolean = 17,
345 Array = 18,
346 Object = 19,
347 Key = 20,
348 Null = 21,
349 EnumMember = 22,
350 Struct = 23,
351 Event = 24,
352 Operator = 25,
353 TypeParameter = 26
354 };
355 bool fromJSON(const llvm::json::Value &, SymbolKind &, llvm::json::Path);
356 constexpr auto SymbolKindMin = static_cast<size_t>(SymbolKind::File);
357 constexpr auto SymbolKindMax = static_cast<size_t>(SymbolKind::TypeParameter);
358 using SymbolKindBitset = std::bitset<SymbolKindMax + 1>;
359 bool fromJSON(const llvm::json::Value &, SymbolKindBitset &, llvm::json::Path);
360 SymbolKind adjustKindToCapability(SymbolKind Kind,
361 SymbolKindBitset &supportedSymbolKinds);
362
363 // Convert a index::SymbolKind to clangd::SymbolKind (LSP)
364 // Note, some are not perfect matches and should be improved when this LSP
365 // issue is addressed:
366 // https://github.com/Microsoft/language-server-protocol/issues/344
367 SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind);
368
369 // Determines the encoding used to measure offsets and lengths of source in LSP.
370 enum class OffsetEncoding {
371 // Any string is legal on the wire. Unrecognized encodings parse as this.
372 UnsupportedEncoding,
373 // Length counts code units of UTF-16 encoded text. (Standard LSP behavior).
374 UTF16,
375 // Length counts bytes of UTF-8 encoded text. (Clangd extension).
376 UTF8,
377 // Length counts codepoints in unicode text. (Clangd extension).
378 UTF32,
379 };
380 llvm::json::Value toJSON(const OffsetEncoding &);
381 bool fromJSON(const llvm::json::Value &, OffsetEncoding &, llvm::json::Path);
382 llvm::raw_ostream &operator<<(llvm::raw_ostream &, OffsetEncoding);
383
384 // Describes the content type that a client supports in various result literals
385 // like `Hover`, `ParameterInfo` or `CompletionItem`.
386 enum class MarkupKind {
387 PlainText,
388 Markdown,
389 };
390 bool fromJSON(const llvm::json::Value &, MarkupKind &, llvm::json::Path);
391 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MarkupKind);
392
393 // This struct doesn't mirror LSP!
394 // The protocol defines deeply nested structures for client capabilities.
395 // Instead of mapping them all, this just parses out the bits we care about.
396 struct ClientCapabilities {
397 /// The supported set of SymbolKinds for workspace/symbol.
398 /// workspace.symbol.symbolKind.valueSet
399 llvm::Optional<SymbolKindBitset> WorkspaceSymbolKinds;
400
401 /// Whether the client accepts diagnostics with codeActions attached inline.
402 /// textDocument.publishDiagnostics.codeActionsInline.
403 bool DiagnosticFixes = false;
404
405 /// Whether the client accepts diagnostics with related locations.
406 /// textDocument.publishDiagnostics.relatedInformation.
407 bool DiagnosticRelatedInformation = false;
408
409 /// Whether the client accepts diagnostics with category attached to it
410 /// using the "category" extension.
411 /// textDocument.publishDiagnostics.categorySupport
412 bool DiagnosticCategory = false;
413
414 /// Client supports snippets as insert text.
415 /// textDocument.completion.completionItem.snippetSupport
416 bool CompletionSnippets = false;
417
418 /// Client supports completions with additionalTextEdit near the cursor.
419 /// This is a clangd extension. (LSP says this is for unrelated text only).
420 /// textDocument.completion.editsNearCursor
421 bool CompletionFixes = false;
422
423 /// Client supports hierarchical document symbols.
424 /// textDocument.documentSymbol.hierarchicalDocumentSymbolSupport
425 bool HierarchicalDocumentSymbol = false;
426
427 /// Client supports signature help.
428 /// textDocument.signatureHelp
429 bool HasSignatureHelp = false;
430
431 /// Client supports processing label offsets instead of a simple label string.
432 /// textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport
433 bool OffsetsInSignatureHelp = false;
434
435 /// The supported set of CompletionItemKinds for textDocument/completion.
436 /// textDocument.completion.completionItemKind.valueSet
437 llvm::Optional<CompletionItemKindBitset> CompletionItemKinds;
438
439 /// The documentation format that should be used for textDocument/completion.
440 /// textDocument.completion.completionItem.documentationFormat
441 MarkupKind CompletionDocumentationFormat = MarkupKind::PlainText;
442
443 /// Client supports CodeAction return value for textDocument/codeAction.
444 /// textDocument.codeAction.codeActionLiteralSupport.
445 bool CodeActionStructure = false;
446
447 /// Client advertises support for the semanticTokens feature.
448 /// We support the textDocument/semanticTokens request in any case.
449 /// textDocument.semanticTokens
450 bool SemanticTokens = false;
451 /// Client supports Theia semantic highlighting extension.
452 /// https://github.com/microsoft/vscode-languageserver-node/pull/367
453 /// clangd no longer supports this, we detect it just to log a warning.
454 /// textDocument.semanticHighlightingCapabilities.semanticHighlighting
455 bool TheiaSemanticHighlighting = false;
456
457 /// Supported encodings for LSP character offsets. (clangd extension).
458 llvm::Optional<std::vector<OffsetEncoding>> offsetEncoding;
459
460 /// The content format that should be used for Hover requests.
461 /// textDocument.hover.contentEncoding
462 MarkupKind HoverContentFormat = MarkupKind::PlainText;
463
464 /// The client supports testing for validity of rename operations
465 /// before execution.
466 bool RenamePrepareSupport = false;
467
468 /// The client supports progress notifications.
469 /// window.workDoneProgress
470 bool WorkDoneProgress = false;
471
472 /// The client supports implicit $/progress work-done progress streams,
473 /// without a preceding window/workDoneProgress/create.
474 /// This is a clangd extension.
475 /// window.implicitWorkDoneProgressCreate
476 bool ImplicitProgressCreation = false;
477
478 /// Whether the client claims to cancel stale requests.
479 /// general.staleRequestSupport.cancel
480 bool CancelsStaleRequests = false;
481
482 /// Whether the client implementation supports a refresh request sent from the
483 /// server to the client.
484 bool SemanticTokenRefreshSupport = false;
485 };
486 bool fromJSON(const llvm::json::Value &, ClientCapabilities &,
487 llvm::json::Path);
488
489 /// Clangd extension that's used in the 'compilationDatabaseChanges' in
490 /// workspace/didChangeConfiguration to record updates to the in-memory
491 /// compilation database.
492 struct ClangdCompileCommand {
493 std::string workingDirectory;
494 std::vector<std::string> compilationCommand;
495 };
496 bool fromJSON(const llvm::json::Value &, ClangdCompileCommand &,
497 llvm::json::Path);
498
499 /// Clangd extension: parameters configurable at any time, via the
500 /// `workspace/didChangeConfiguration` notification.
501 /// LSP defines this type as `any`.
502 struct ConfigurationSettings {
503 // Changes to the in-memory compilation database.
504 // The key of the map is a file name.
505 std::map<std::string, ClangdCompileCommand> compilationDatabaseChanges;
506 };
507 bool fromJSON(const llvm::json::Value &, ConfigurationSettings &,
508 llvm::json::Path);
509
510 /// Clangd extension: parameters configurable at `initialize` time.
511 /// LSP defines this type as `any`.
512 struct InitializationOptions {
513 // What we can change throught the didChangeConfiguration request, we can
514 // also set through the initialize request (initializationOptions field).
515 ConfigurationSettings ConfigSettings;
516
517 llvm::Optional<std::string> compilationDatabasePath;
518 // Additional flags to be included in the "fallback command" used when
519 // the compilation database doesn't describe an opened file.
520 // The command used will be approximately `clang $FILE $fallbackFlags`.
521 std::vector<std::string> fallbackFlags;
522
523 /// Clients supports show file status for textDocument/clangd.fileStatus.
524 bool FileStatus = false;
525 };
526 bool fromJSON(const llvm::json::Value &, InitializationOptions &,
527 llvm::json::Path);
528
529 struct InitializeParams {
530 /// The process Id of the parent process that started
531 /// the server. Is null if the process has not been started by another
532 /// process. If the parent process is not alive then the server should exit
533 /// (see exit notification) its process.
534 llvm::Optional<int> processId;
535
536 /// The rootPath of the workspace. Is null
537 /// if no folder is open.
538 ///
539 /// @deprecated in favour of rootUri.
540 llvm::Optional<std::string> rootPath;
541
542 /// The rootUri of the workspace. Is null if no
543 /// folder is open. If both `rootPath` and `rootUri` are set
544 /// `rootUri` wins.
545 llvm::Optional<URIForFile> rootUri;
546
547 // User provided initialization options.
548 // initializationOptions?: any;
549
550 /// The capabilities provided by the client (editor or tool)
551 ClientCapabilities capabilities;
552 /// The same data as capabilities, but not parsed (to expose to modules).
553 llvm::json::Object rawCapabilities;
554
555 /// The initial trace setting. If omitted trace is disabled ('off').
556 llvm::Optional<TraceLevel> trace;
557
558 /// User-provided initialization options.
559 InitializationOptions initializationOptions;
560 };
561 bool fromJSON(const llvm::json::Value &, InitializeParams &, llvm::json::Path);
562
563 struct WorkDoneProgressCreateParams {
564 /// The token to be used to report progress.
565 llvm::json::Value token = nullptr;
566 };
567 llvm::json::Value toJSON(const WorkDoneProgressCreateParams &P);
568
569 template <typename T> struct ProgressParams {
570 /// The progress token provided by the client or server.
571 llvm::json::Value token = nullptr;
572
573 /// The progress data.
574 T value;
575 };
toJSON(const ProgressParams<T> & P)576 template <typename T> llvm::json::Value toJSON(const ProgressParams<T> &P) {
577 return llvm::json::Object{{"token", P.token}, {"value", P.value}};
578 }
579 /// To start progress reporting a $/progress notification with the following
580 /// payload must be sent.
581 struct WorkDoneProgressBegin {
582 /// Mandatory title of the progress operation. Used to briefly inform about
583 /// the kind of operation being performed.
584 ///
585 /// Examples: "Indexing" or "Linking dependencies".
586 std::string title;
587
588 /// Controls if a cancel button should show to allow the user to cancel the
589 /// long-running operation. Clients that don't support cancellation are
590 /// allowed to ignore the setting.
591 bool cancellable = false;
592
593 /// Optional progress percentage to display (value 100 is considered 100%).
594 /// If not provided infinite progress is assumed and clients are allowed
595 /// to ignore the `percentage` value in subsequent in report notifications.
596 ///
597 /// The value should be steadily rising. Clients are free to ignore values
598 /// that are not following this rule.
599 ///
600 /// Clangd implementation note: we only send nonzero percentages in
601 /// the WorkProgressReport. 'true' here means percentages will be used.
602 bool percentage = false;
603 };
604 llvm::json::Value toJSON(const WorkDoneProgressBegin &);
605
606 /// Reporting progress is done using the following payload.
607 struct WorkDoneProgressReport {
608 /// Mandatory title of the progress operation. Used to briefly inform about
609 /// the kind of operation being performed.
610 ///
611 /// Examples: "Indexing" or "Linking dependencies".
612 std::string title;
613
614 /// Controls enablement state of a cancel button. This property is only valid
615 /// if a cancel button got requested in the `WorkDoneProgressStart` payload.
616 ///
617 /// Clients that don't support cancellation or don't support control
618 /// the button's enablement state are allowed to ignore the setting.
619 llvm::Optional<bool> cancellable;
620
621 /// Optional, more detailed associated progress message. Contains
622 /// complementary information to the `title`.
623 ///
624 /// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
625 /// If unset, the previous progress message (if any) is still valid.
626 llvm::Optional<std::string> message;
627
628 /// Optional progress percentage to display (value 100 is considered 100%).
629 /// If not provided infinite progress is assumed and clients are allowed
630 /// to ignore the `percentage` value in subsequent in report notifications.
631 ///
632 /// The value should be steadily rising. Clients are free to ignore values
633 /// that are not following this rule.
634 llvm::Optional<unsigned> percentage;
635 };
636 llvm::json::Value toJSON(const WorkDoneProgressReport &);
637 //
638 /// Signals the end of progress reporting.
639 struct WorkDoneProgressEnd {
640 /// Optional, a final message indicating to for example indicate the outcome
641 /// of the operation.
642 llvm::Optional<std::string> message;
643 };
644 llvm::json::Value toJSON(const WorkDoneProgressEnd &);
645
646 enum class MessageType {
647 /// An error message.
648 Error = 1,
649 /// A warning message.
650 Warning = 2,
651 /// An information message.
652 Info = 3,
653 /// A log message.
654 Log = 4,
655 };
656 llvm::json::Value toJSON(const MessageType &);
657
658 /// The show message notification is sent from a server to a client to ask the
659 /// client to display a particular message in the user interface.
660 struct ShowMessageParams {
661 /// The message type.
662 MessageType type = MessageType::Info;
663 /// The actual message.
664 std::string message;
665 };
666 llvm::json::Value toJSON(const ShowMessageParams &);
667
668 struct DidOpenTextDocumentParams {
669 /// The document that was opened.
670 TextDocumentItem textDocument;
671 };
672 bool fromJSON(const llvm::json::Value &, DidOpenTextDocumentParams &,
673 llvm::json::Path);
674
675 struct DidCloseTextDocumentParams {
676 /// The document that was closed.
677 TextDocumentIdentifier textDocument;
678 };
679 bool fromJSON(const llvm::json::Value &, DidCloseTextDocumentParams &,
680 llvm::json::Path);
681
682 struct DidSaveTextDocumentParams {
683 /// The document that was saved.
684 TextDocumentIdentifier textDocument;
685 };
686 bool fromJSON(const llvm::json::Value &, DidSaveTextDocumentParams &,
687 llvm::json::Path);
688
689 struct TextDocumentContentChangeEvent {
690 /// The range of the document that changed.
691 llvm::Optional<Range> range;
692
693 /// The length of the range that got replaced.
694 llvm::Optional<int> rangeLength;
695
696 /// The new text of the range/document.
697 std::string text;
698 };
699 bool fromJSON(const llvm::json::Value &, TextDocumentContentChangeEvent &,
700 llvm::json::Path);
701
702 struct DidChangeTextDocumentParams {
703 /// The document that did change. The version number points
704 /// to the version after all provided content changes have
705 /// been applied.
706 VersionedTextDocumentIdentifier textDocument;
707
708 /// The actual content changes.
709 std::vector<TextDocumentContentChangeEvent> contentChanges;
710
711 /// Forces diagnostics to be generated, or to not be generated, for this
712 /// version of the file. If not set, diagnostics are eventually consistent:
713 /// either they will be provided for this version or some subsequent one.
714 /// This is a clangd extension.
715 llvm::Optional<bool> wantDiagnostics;
716
717 /// Force a complete rebuild of the file, ignoring all cached state. Slow!
718 /// This is useful to defeat clangd's assumption that missing headers will
719 /// stay missing.
720 /// This is a clangd extension.
721 bool forceRebuild = false;
722 };
723 bool fromJSON(const llvm::json::Value &, DidChangeTextDocumentParams &,
724 llvm::json::Path);
725
726 enum class FileChangeType {
727 /// The file got created.
728 Created = 1,
729 /// The file got changed.
730 Changed = 2,
731 /// The file got deleted.
732 Deleted = 3
733 };
734 bool fromJSON(const llvm::json::Value &E, FileChangeType &Out,
735 llvm::json::Path);
736
737 struct FileEvent {
738 /// The file's URI.
739 URIForFile uri;
740 /// The change type.
741 FileChangeType type = FileChangeType::Created;
742 };
743 bool fromJSON(const llvm::json::Value &, FileEvent &, llvm::json::Path);
744
745 struct DidChangeWatchedFilesParams {
746 /// The actual file events.
747 std::vector<FileEvent> changes;
748 };
749 bool fromJSON(const llvm::json::Value &, DidChangeWatchedFilesParams &,
750 llvm::json::Path);
751
752 struct DidChangeConfigurationParams {
753 ConfigurationSettings settings;
754 };
755 bool fromJSON(const llvm::json::Value &, DidChangeConfigurationParams &,
756 llvm::json::Path);
757
758 // Note: we do not parse FormattingOptions for *FormattingParams.
759 // In general, we use a clang-format style detected from common mechanisms
760 // (.clang-format files and the -fallback-style flag).
761 // It would be possible to override these with FormatOptions, but:
762 // - the protocol makes FormatOptions mandatory, so many clients set them to
763 // useless values, and we can't tell when to respect them
764 // - we also format in other places, where FormatOptions aren't available.
765
766 struct DocumentRangeFormattingParams {
767 /// The document to format.
768 TextDocumentIdentifier textDocument;
769
770 /// The range to format
771 Range range;
772 };
773 bool fromJSON(const llvm::json::Value &, DocumentRangeFormattingParams &,
774 llvm::json::Path);
775
776 struct DocumentOnTypeFormattingParams {
777 /// The document to format.
778 TextDocumentIdentifier textDocument;
779
780 /// The position at which this request was sent.
781 Position position;
782
783 /// The character that has been typed.
784 std::string ch;
785 };
786 bool fromJSON(const llvm::json::Value &, DocumentOnTypeFormattingParams &,
787 llvm::json::Path);
788
789 struct DocumentFormattingParams {
790 /// The document to format.
791 TextDocumentIdentifier textDocument;
792 };
793 bool fromJSON(const llvm::json::Value &, DocumentFormattingParams &,
794 llvm::json::Path);
795
796 struct DocumentSymbolParams {
797 // The text document to find symbols in.
798 TextDocumentIdentifier textDocument;
799 };
800 bool fromJSON(const llvm::json::Value &, DocumentSymbolParams &,
801 llvm::json::Path);
802
803 /// Represents a related message and source code location for a diagnostic.
804 /// This should be used to point to code locations that cause or related to a
805 /// diagnostics, e.g when duplicating a symbol in a scope.
806 struct DiagnosticRelatedInformation {
807 /// The location of this related diagnostic information.
808 Location location;
809 /// The message of this related diagnostic information.
810 std::string message;
811 };
812 llvm::json::Value toJSON(const DiagnosticRelatedInformation &);
813
814 struct CodeAction;
815 struct Diagnostic {
816 /// The range at which the message applies.
817 Range range;
818
819 /// The diagnostic's severity. Can be omitted. If omitted it is up to the
820 /// client to interpret diagnostics as error, warning, info or hint.
821 int severity = 0;
822
823 /// The diagnostic's code. Can be omitted.
824 std::string code;
825
826 /// A human-readable string describing the source of this
827 /// diagnostic, e.g. 'typescript' or 'super lint'.
828 std::string source;
829
830 /// The diagnostic's message.
831 std::string message;
832
833 /// An array of related diagnostic information, e.g. when symbol-names within
834 /// a scope collide all definitions can be marked via this property.
835 llvm::Optional<std::vector<DiagnosticRelatedInformation>> relatedInformation;
836
837 /// The diagnostic's category. Can be omitted.
838 /// An LSP extension that's used to send the name of the category over to the
839 /// client. The category typically describes the compilation stage during
840 /// which the issue was produced, e.g. "Semantic Issue" or "Parse Issue".
841 llvm::Optional<std::string> category;
842
843 /// Clangd extension: code actions related to this diagnostic.
844 /// Only with capability textDocument.publishDiagnostics.codeActionsInline.
845 /// (These actions can also be obtained using textDocument/codeAction).
846 llvm::Optional<std::vector<CodeAction>> codeActions;
847
848 /// A data entry field that is preserved between a
849 /// `textDocument/publishDiagnostics` notification
850 /// and`textDocument/codeAction` request.
851 /// Mutating users should associate their data with a unique key they can use
852 /// to retrieve later on.
853 llvm::json::Object data;
854 };
855 llvm::json::Value toJSON(const Diagnostic &);
856
857 /// A LSP-specific comparator used to find diagnostic in a container like
858 /// std:map.
859 /// We only use the required fields of Diagnostic to do the comparison to avoid
860 /// any regression issues from LSP clients (e.g. VScode), see
861 /// https://git.io/vbr29
862 struct LSPDiagnosticCompare {
operatorLSPDiagnosticCompare863 bool operator()(const Diagnostic &LHS, const Diagnostic &RHS) const {
864 return std::tie(LHS.range, LHS.message) < std::tie(RHS.range, RHS.message);
865 }
866 };
867 bool fromJSON(const llvm::json::Value &, Diagnostic &, llvm::json::Path);
868 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Diagnostic &);
869
870 struct PublishDiagnosticsParams {
871 /// The URI for which diagnostic information is reported.
872 URIForFile uri;
873 /// An array of diagnostic information items.
874 std::vector<Diagnostic> diagnostics;
875 /// The version number of the document the diagnostics are published for.
876 llvm::Optional<int64_t> version;
877 };
878 llvm::json::Value toJSON(const PublishDiagnosticsParams &);
879
880 struct CodeActionContext {
881 /// An array of diagnostics known on the client side overlapping the range
882 /// provided to the `textDocument/codeAction` request. They are provided so
883 /// that the server knows which errors are currently presented to the user for
884 /// the given range. There is no guarantee that these accurately reflect the
885 /// error state of the resource. The primary parameter to compute code actions
886 /// is the provided range.
887 std::vector<Diagnostic> diagnostics;
888
889 /// Requested kind of actions to return.
890 ///
891 /// Actions not of this kind are filtered out by the client before being
892 /// shown. So servers can omit computing them.
893 std::vector<std::string> only;
894 };
895 bool fromJSON(const llvm::json::Value &, CodeActionContext &, llvm::json::Path);
896
897 struct CodeActionParams {
898 /// The document in which the command was invoked.
899 TextDocumentIdentifier textDocument;
900
901 /// The range for which the command was invoked.
902 Range range;
903
904 /// Context carrying additional information.
905 CodeActionContext context;
906 };
907 bool fromJSON(const llvm::json::Value &, CodeActionParams &, llvm::json::Path);
908
909 struct WorkspaceEdit {
910 /// Holds changes to existing resources.
911 std::map<std::string, std::vector<TextEdit>> changes;
912
913 /// Note: "documentChanges" is not currently used because currently there is
914 /// no support for versioned edits.
915 };
916 bool fromJSON(const llvm::json::Value &, WorkspaceEdit &, llvm::json::Path);
917 llvm::json::Value toJSON(const WorkspaceEdit &WE);
918
919 /// Arguments for the 'applyTweak' command. The server sends these commands as a
920 /// response to the textDocument/codeAction request. The client can later send a
921 /// command back to the server if the user requests to execute a particular code
922 /// tweak.
923 struct TweakArgs {
924 /// A file provided by the client on a textDocument/codeAction request.
925 URIForFile file;
926 /// A selection provided by the client on a textDocument/codeAction request.
927 Range selection;
928 /// ID of the tweak that should be executed. Corresponds to Tweak::id().
929 std::string tweakID;
930 };
931 bool fromJSON(const llvm::json::Value &, TweakArgs &, llvm::json::Path);
932 llvm::json::Value toJSON(const TweakArgs &A);
933
934 struct ExecuteCommandParams {
935 /// The identifier of the actual command handler.
936 std::string command;
937
938 // This is `arguments?: []any` in LSP.
939 // All clangd's commands accept a single argument (or none => null).
940 llvm::json::Value argument = nullptr;
941 };
942 bool fromJSON(const llvm::json::Value &, ExecuteCommandParams &,
943 llvm::json::Path);
944
945 struct Command : public ExecuteCommandParams {
946 std::string title;
947 };
948 llvm::json::Value toJSON(const Command &C);
949
950 /// A code action represents a change that can be performed in code, e.g. to fix
951 /// a problem or to refactor code.
952 ///
953 /// A CodeAction must set either `edit` and/or a `command`. If both are
954 /// supplied, the `edit` is applied first, then the `command` is executed.
955 struct CodeAction {
956 /// A short, human-readable, title for this code action.
957 std::string title;
958
959 /// The kind of the code action.
960 /// Used to filter code actions.
961 llvm::Optional<std::string> kind;
962 const static llvm::StringLiteral QUICKFIX_KIND;
963 const static llvm::StringLiteral REFACTOR_KIND;
964 const static llvm::StringLiteral INFO_KIND;
965
966 /// The diagnostics that this code action resolves.
967 llvm::Optional<std::vector<Diagnostic>> diagnostics;
968
969 /// Marks this as a preferred action. Preferred actions are used by the
970 /// `auto fix` command and can be targeted by keybindings.
971 /// A quick fix should be marked preferred if it properly addresses the
972 /// underlying error. A refactoring should be marked preferred if it is the
973 /// most reasonable choice of actions to take.
974 bool isPreferred = false;
975
976 /// The workspace edit this code action performs.
977 llvm::Optional<WorkspaceEdit> edit;
978
979 /// A command this code action executes. If a code action provides an edit
980 /// and a command, first the edit is executed and then the command.
981 llvm::Optional<Command> command;
982 };
983 llvm::json::Value toJSON(const CodeAction &);
984
985 /// Represents programming constructs like variables, classes, interfaces etc.
986 /// that appear in a document. Document symbols can be hierarchical and they
987 /// have two ranges: one that encloses its definition and one that points to its
988 /// most interesting range, e.g. the range of an identifier.
989 struct DocumentSymbol {
990 /// The name of this symbol.
991 std::string name;
992
993 /// More detail for this symbol, e.g the signature of a function.
994 std::string detail;
995
996 /// The kind of this symbol.
997 SymbolKind kind;
998
999 /// Indicates if this symbol is deprecated.
1000 bool deprecated = false;
1001
1002 /// The range enclosing this symbol not including leading/trailing whitespace
1003 /// but everything else like comments. This information is typically used to
1004 /// determine if the clients cursor is inside the symbol to reveal in the
1005 /// symbol in the UI.
1006 Range range;
1007
1008 /// The range that should be selected and revealed when this symbol is being
1009 /// picked, e.g the name of a function. Must be contained by the `range`.
1010 Range selectionRange;
1011
1012 /// Children of this symbol, e.g. properties of a class.
1013 std::vector<DocumentSymbol> children;
1014 };
1015 llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentSymbol &S);
1016 llvm::json::Value toJSON(const DocumentSymbol &S);
1017
1018 /// Represents information about programming constructs like variables, classes,
1019 /// interfaces etc.
1020 struct SymbolInformation {
1021 /// The name of this symbol.
1022 std::string name;
1023
1024 /// The kind of this symbol.
1025 SymbolKind kind;
1026
1027 /// The location of this symbol.
1028 Location location;
1029
1030 /// The name of the symbol containing this symbol.
1031 std::string containerName;
1032
1033 /// The score that clangd calculates to rank the returned symbols.
1034 /// This excludes the fuzzy-matching score between `name` and the query.
1035 /// (Specifically, the last ::-separated component).
1036 /// This can be used to re-rank results as the user types, using client-side
1037 /// fuzzy-matching (that score should be multiplied with this one).
1038 /// This is a clangd extension, set only for workspace/symbol responses.
1039 llvm::Optional<float> score;
1040 };
1041 llvm::json::Value toJSON(const SymbolInformation &);
1042 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolInformation &);
1043
1044 /// Represents information about identifier.
1045 /// This is returned from textDocument/symbolInfo, which is a clangd extension.
1046 struct SymbolDetails {
1047 std::string name;
1048
1049 std::string containerName;
1050
1051 /// Unified Symbol Resolution identifier
1052 /// This is an opaque string uniquely identifying a symbol.
1053 /// Unlike SymbolID, it is variable-length and somewhat human-readable.
1054 /// It is a common representation across several clang tools.
1055 /// (See USRGeneration.h)
1056 std::string USR;
1057
1058 SymbolID ID;
1059 };
1060 llvm::json::Value toJSON(const SymbolDetails &);
1061 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolDetails &);
1062 bool operator==(const SymbolDetails &, const SymbolDetails &);
1063
1064 /// The parameters of a Workspace Symbol Request.
1065 struct WorkspaceSymbolParams {
1066 /// A query string to filter symbols by.
1067 /// Clients may send an empty string here to request all the symbols.
1068 std::string query;
1069
1070 /// Max results to return, overriding global default. 0 means no limit.
1071 /// Clangd extension.
1072 llvm::Optional<int> limit;
1073 };
1074 bool fromJSON(const llvm::json::Value &, WorkspaceSymbolParams &,
1075 llvm::json::Path);
1076
1077 struct ApplyWorkspaceEditParams {
1078 WorkspaceEdit edit;
1079 };
1080 llvm::json::Value toJSON(const ApplyWorkspaceEditParams &);
1081
1082 struct ApplyWorkspaceEditResponse {
1083 bool applied = true;
1084 llvm::Optional<std::string> failureReason;
1085 };
1086 bool fromJSON(const llvm::json::Value &, ApplyWorkspaceEditResponse &,
1087 llvm::json::Path);
1088
1089 struct TextDocumentPositionParams {
1090 /// The text document.
1091 TextDocumentIdentifier textDocument;
1092
1093 /// The position inside the text document.
1094 Position position;
1095 };
1096 bool fromJSON(const llvm::json::Value &, TextDocumentPositionParams &,
1097 llvm::json::Path);
1098
1099 enum class CompletionTriggerKind {
1100 /// Completion was triggered by typing an identifier (24x7 code
1101 /// complete), manual invocation (e.g Ctrl+Space) or via API.
1102 Invoked = 1,
1103 /// Completion was triggered by a trigger character specified by
1104 /// the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
1105 TriggerCharacter = 2,
1106 /// Completion was re-triggered as the current completion list is incomplete.
1107 TriggerTriggerForIncompleteCompletions = 3
1108 };
1109
1110 struct CompletionContext {
1111 /// How the completion was triggered.
1112 CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked;
1113 /// The trigger character (a single character) that has trigger code complete.
1114 /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
1115 std::string triggerCharacter;
1116 };
1117 bool fromJSON(const llvm::json::Value &, CompletionContext &, llvm::json::Path);
1118
1119 struct CompletionParams : TextDocumentPositionParams {
1120 CompletionContext context;
1121
1122 /// Max results to return, overriding global default. 0 means no limit.
1123 /// Clangd extension.
1124 llvm::Optional<int> limit;
1125 };
1126 bool fromJSON(const llvm::json::Value &, CompletionParams &, llvm::json::Path);
1127
1128 struct MarkupContent {
1129 MarkupKind kind = MarkupKind::PlainText;
1130 std::string value;
1131 };
1132 llvm::json::Value toJSON(const MarkupContent &MC);
1133
1134 struct Hover {
1135 /// The hover's content
1136 MarkupContent contents;
1137
1138 /// An optional range is a range inside a text document
1139 /// that is used to visualize a hover, e.g. by changing the background color.
1140 llvm::Optional<Range> range;
1141 };
1142 llvm::json::Value toJSON(const Hover &H);
1143
1144 /// Defines whether the insert text in a completion item should be interpreted
1145 /// as plain text or a snippet.
1146 enum class InsertTextFormat {
1147 Missing = 0,
1148 /// The primary text to be inserted is treated as a plain string.
1149 PlainText = 1,
1150 /// The primary text to be inserted is treated as a snippet.
1151 ///
1152 /// A snippet can define tab stops and placeholders with `$1`, `$2`
1153 /// and `${3:foo}`. `$0` defines the final tab stop, it defaults to the end
1154 /// of the snippet. Placeholders with equal identifiers are linked, that is
1155 /// typing in one will update others too.
1156 ///
1157 /// See also:
1158 /// https//github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
1159 Snippet = 2,
1160 };
1161
1162 struct CompletionItem {
1163 /// The label of this completion item. By default also the text that is
1164 /// inserted when selecting this completion.
1165 std::string label;
1166
1167 /// The kind of this completion item. Based of the kind an icon is chosen by
1168 /// the editor.
1169 CompletionItemKind kind = CompletionItemKind::Missing;
1170
1171 /// A human-readable string with additional information about this item, like
1172 /// type or symbol information.
1173 std::string detail;
1174
1175 /// A human-readable string that represents a doc-comment.
1176 llvm::Optional<MarkupContent> documentation;
1177
1178 /// A string that should be used when comparing this item with other items.
1179 /// When `falsy` the label is used.
1180 std::string sortText;
1181
1182 /// A string that should be used when filtering a set of completion items.
1183 /// When `falsy` the label is used.
1184 std::string filterText;
1185
1186 /// A string that should be inserted to a document when selecting this
1187 /// completion. When `falsy` the label is used.
1188 std::string insertText;
1189
1190 /// The format of the insert text. The format applies to both the `insertText`
1191 /// property and the `newText` property of a provided `textEdit`.
1192 InsertTextFormat insertTextFormat = InsertTextFormat::Missing;
1193
1194 /// An edit which is applied to a document when selecting this completion.
1195 /// When an edit is provided `insertText` is ignored.
1196 ///
1197 /// Note: The range of the edit must be a single line range and it must
1198 /// contain the position at which completion has been requested.
1199 llvm::Optional<TextEdit> textEdit;
1200
1201 /// An optional array of additional text edits that are applied when selecting
1202 /// this completion. Edits must not overlap with the main edit nor with
1203 /// themselves.
1204 std::vector<TextEdit> additionalTextEdits;
1205
1206 /// Indicates if this item is deprecated.
1207 bool deprecated = false;
1208
1209 /// The score that clangd calculates to rank the returned completions.
1210 /// This excludes the fuzzy-match between `filterText` and the partial word.
1211 /// This can be used to re-rank results as the user types, using client-side
1212 /// fuzzy-matching (that score should be multiplied with this one).
1213 /// This is a clangd extension.
1214 float score = 0.f;
1215
1216 // TODO: Add custom commitCharacters for some of the completion items. For
1217 // example, it makes sense to use () only for the functions.
1218 // TODO(krasimir): The following optional fields defined by the language
1219 // server protocol are unsupported:
1220 //
1221 // data?: any - A data entry field that is preserved on a completion item
1222 // between a completion and a completion resolve request.
1223 };
1224 llvm::json::Value toJSON(const CompletionItem &);
1225 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CompletionItem &);
1226
1227 bool operator<(const CompletionItem &, const CompletionItem &);
1228
1229 /// Represents a collection of completion items to be presented in the editor.
1230 struct CompletionList {
1231 /// The list is not complete. Further typing should result in recomputing the
1232 /// list.
1233 bool isIncomplete = false;
1234
1235 /// The completion items.
1236 std::vector<CompletionItem> items;
1237 };
1238 llvm::json::Value toJSON(const CompletionList &);
1239
1240 /// A single parameter of a particular signature.
1241 struct ParameterInformation {
1242
1243 /// The label of this parameter. Ignored when labelOffsets is set.
1244 std::string labelString;
1245
1246 /// Inclusive start and exclusive end offsets withing the containing signature
1247 /// label.
1248 /// Offsets are computed by lspLength(), which counts UTF-16 code units by
1249 /// default but that can be overriden, see its documentation for details.
1250 llvm::Optional<std::pair<unsigned, unsigned>> labelOffsets;
1251
1252 /// The documentation of this parameter. Optional.
1253 std::string documentation;
1254 };
1255 llvm::json::Value toJSON(const ParameterInformation &);
1256
1257 /// Represents the signature of something callable.
1258 struct SignatureInformation {
1259
1260 /// The label of this signature. Mandatory.
1261 std::string label;
1262
1263 /// The documentation of this signature. Optional.
1264 std::string documentation;
1265
1266 /// The parameters of this signature.
1267 std::vector<ParameterInformation> parameters;
1268 };
1269 llvm::json::Value toJSON(const SignatureInformation &);
1270 llvm::raw_ostream &operator<<(llvm::raw_ostream &,
1271 const SignatureInformation &);
1272
1273 /// Represents the signature of a callable.
1274 struct SignatureHelp {
1275
1276 /// The resulting signatures.
1277 std::vector<SignatureInformation> signatures;
1278
1279 /// The active signature.
1280 int activeSignature = 0;
1281
1282 /// The active parameter of the active signature.
1283 int activeParameter = 0;
1284
1285 /// Position of the start of the argument list, including opening paren. e.g.
1286 /// foo("first arg", "second arg",
1287 /// ^-argListStart ^-cursor
1288 /// This is a clangd-specific extension, it is only available via C++ API and
1289 /// not currently serialized for the LSP.
1290 Position argListStart;
1291 };
1292 llvm::json::Value toJSON(const SignatureHelp &);
1293
1294 struct RenameParams {
1295 /// The document that was opened.
1296 TextDocumentIdentifier textDocument;
1297
1298 /// The position at which this request was sent.
1299 Position position;
1300
1301 /// The new name of the symbol.
1302 std::string newName;
1303 };
1304 bool fromJSON(const llvm::json::Value &, RenameParams &, llvm::json::Path);
1305
1306 enum class DocumentHighlightKind { Text = 1, Read = 2, Write = 3 };
1307
1308 /// A document highlight is a range inside a text document which deserves
1309 /// special attention. Usually a document highlight is visualized by changing
1310 /// the background color of its range.
1311
1312 struct DocumentHighlight {
1313 /// The range this highlight applies to.
1314 Range range;
1315
1316 /// The highlight kind, default is DocumentHighlightKind.Text.
1317 DocumentHighlightKind kind = DocumentHighlightKind::Text;
1318
1319 friend bool operator<(const DocumentHighlight &LHS,
1320 const DocumentHighlight &RHS) {
1321 int LHSKind = static_cast<int>(LHS.kind);
1322 int RHSKind = static_cast<int>(RHS.kind);
1323 return std::tie(LHS.range, LHSKind) < std::tie(RHS.range, RHSKind);
1324 }
1325
1326 friend bool operator==(const DocumentHighlight &LHS,
1327 const DocumentHighlight &RHS) {
1328 return LHS.kind == RHS.kind && LHS.range == RHS.range;
1329 }
1330 };
1331 llvm::json::Value toJSON(const DocumentHighlight &DH);
1332 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const DocumentHighlight &);
1333
1334 enum class TypeHierarchyDirection { Children = 0, Parents = 1, Both = 2 };
1335 bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out,
1336 llvm::json::Path);
1337
1338 /// The type hierarchy params is an extension of the
1339 /// `TextDocumentPositionsParams` with optional properties which can be used to
1340 /// eagerly resolve the item when requesting from the server.
1341 struct TypeHierarchyParams : public TextDocumentPositionParams {
1342 /// The hierarchy levels to resolve. `0` indicates no level.
1343 int resolve = 0;
1344
1345 /// The direction of the hierarchy levels to resolve.
1346 TypeHierarchyDirection direction = TypeHierarchyDirection::Parents;
1347 };
1348 bool fromJSON(const llvm::json::Value &, TypeHierarchyParams &,
1349 llvm::json::Path);
1350
1351 struct TypeHierarchyItem {
1352 /// The human readable name of the hierarchy item.
1353 std::string name;
1354
1355 /// Optional detail for the hierarchy item. It can be, for instance, the
1356 /// signature of a function or method.
1357 llvm::Optional<std::string> detail;
1358
1359 /// The kind of the hierarchy item. For instance, class or interface.
1360 SymbolKind kind;
1361
1362 /// `true` if the hierarchy item is deprecated. Otherwise, `false`.
1363 bool deprecated = false;
1364
1365 /// The URI of the text document where this type hierarchy item belongs to.
1366 URIForFile uri;
1367
1368 /// The range enclosing this type hierarchy item not including
1369 /// leading/trailing whitespace but everything else like comments. This
1370 /// information is typically used to determine if the client's cursor is
1371 /// inside the type hierarch item to reveal in the symbol in the UI.
1372 Range range;
1373
1374 /// The range that should be selected and revealed when this type hierarchy
1375 /// item is being picked, e.g. the name of a function. Must be contained by
1376 /// the `range`.
1377 Range selectionRange;
1378
1379 /// If this type hierarchy item is resolved, it contains the direct parents.
1380 /// Could be empty if the item does not have direct parents. If not defined,
1381 /// the parents have not been resolved yet.
1382 llvm::Optional<std::vector<TypeHierarchyItem>> parents;
1383
1384 /// If this type hierarchy item is resolved, it contains the direct children
1385 /// of the current item. Could be empty if the item does not have any
1386 /// descendants. If not defined, the children have not been resolved.
1387 llvm::Optional<std::vector<TypeHierarchyItem>> children;
1388
1389 /// An optional 'data' field, which can be used to identify a type hierarchy
1390 /// item in a resolve request.
1391 llvm::Optional<std::string> data;
1392 };
1393 llvm::json::Value toJSON(const TypeHierarchyItem &);
1394 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TypeHierarchyItem &);
1395 bool fromJSON(const llvm::json::Value &, TypeHierarchyItem &, llvm::json::Path);
1396
1397 /// Parameters for the `typeHierarchy/resolve` request.
1398 struct ResolveTypeHierarchyItemParams {
1399 /// The item to resolve.
1400 TypeHierarchyItem item;
1401
1402 /// The hierarchy levels to resolve. `0` indicates no level.
1403 int resolve;
1404
1405 /// The direction of the hierarchy levels to resolve.
1406 TypeHierarchyDirection direction;
1407 };
1408 bool fromJSON(const llvm::json::Value &, ResolveTypeHierarchyItemParams &,
1409 llvm::json::Path);
1410
1411 enum class SymbolTag { Deprecated = 1 };
1412 llvm::json::Value toJSON(SymbolTag);
1413
1414 /// The parameter of a `textDocument/prepareCallHierarchy` request.
1415 struct CallHierarchyPrepareParams : public TextDocumentPositionParams {};
1416
1417 /// Represents programming constructs like functions or constructors
1418 /// in the context of call hierarchy.
1419 struct CallHierarchyItem {
1420 /// The name of this item.
1421 std::string name;
1422
1423 /// The kind of this item.
1424 SymbolKind kind;
1425
1426 /// Tags for this item.
1427 std::vector<SymbolTag> tags;
1428
1429 /// More detaill for this item, e.g. the signature of a function.
1430 std::string detail;
1431
1432 /// The resource identifier of this item.
1433 URIForFile uri;
1434
1435 /// The range enclosing this symbol not including leading / trailing
1436 /// whitespace but everything else, e.g. comments and code.
1437 Range range;
1438
1439 /// The range that should be selected and revealed when this symbol
1440 /// is being picked, e.g. the name of a function.
1441 /// Must be contained by `Rng`.
1442 Range selectionRange;
1443
1444 /// An optional 'data' field, which can be used to identify a call
1445 /// hierarchy item in an incomingCalls or outgoingCalls request.
1446 std::string data;
1447 };
1448 llvm::json::Value toJSON(const CallHierarchyItem &);
1449 bool fromJSON(const llvm::json::Value &, CallHierarchyItem &, llvm::json::Path);
1450
1451 /// The parameter of a `callHierarchy/incomingCalls` request.
1452 struct CallHierarchyIncomingCallsParams {
1453 CallHierarchyItem item;
1454 };
1455 bool fromJSON(const llvm::json::Value &, CallHierarchyIncomingCallsParams &,
1456 llvm::json::Path);
1457
1458 /// Represents an incoming call, e.g. a caller of a method or constructor.
1459 struct CallHierarchyIncomingCall {
1460 /// The item that makes the call.
1461 CallHierarchyItem from;
1462
1463 /// The range at which the calls appear.
1464 /// This is relative to the caller denoted by `From`.
1465 std::vector<Range> fromRanges;
1466 };
1467 llvm::json::Value toJSON(const CallHierarchyIncomingCall &);
1468
1469 /// The parameter of a `callHierarchy/outgoingCalls` request.
1470 struct CallHierarchyOutgoingCallsParams {
1471 CallHierarchyItem item;
1472 };
1473 bool fromJSON(const llvm::json::Value &, CallHierarchyOutgoingCallsParams &,
1474 llvm::json::Path);
1475
1476 /// Represents an outgoing call, e.g. calling a getter from a method or
1477 /// a method from a constructor etc.
1478 struct CallHierarchyOutgoingCall {
1479 /// The item that is called.
1480 CallHierarchyItem to;
1481
1482 /// The range at which this item is called.
1483 /// This is the range relative to the caller, and not `To`.
1484 std::vector<Range> fromRanges;
1485 };
1486 llvm::json::Value toJSON(const CallHierarchyOutgoingCall &);
1487
1488 /// The parameter of a `textDocument/inlayHints` request.
1489 struct InlayHintsParams {
1490 /// The text document for which inlay hints are requested.
1491 TextDocumentIdentifier textDocument;
1492 };
1493 bool fromJSON(const llvm::json::Value &, InlayHintsParams &, llvm::json::Path);
1494
1495 /// A set of predefined hint kinds.
1496 enum class InlayHintKind {
1497 /// The hint corresponds to parameter information.
1498 /// An example of a parameter hint is a hint in this position:
1499 /// func(^arg);
1500 /// which shows the name of the corresponding parameter.
1501 ParameterHint,
1502
1503 /// The hint corresponds to information about a deduced type.
1504 /// An example of a type hint is a hint in this position:
1505 /// auto var ^ = expr;
1506 /// which shows the deduced type of the variable.
1507 TypeHint,
1508
1509 /// Other ideas for hints that are not currently implemented:
1510 ///
1511 /// * Chaining hints, showing the types of intermediate expressions
1512 /// in a chain of function calls.
1513 /// * Hints indicating implicit conversions or implicit constructor calls.
1514 };
1515 llvm::json::Value toJSON(InlayHintKind);
1516
1517 /// An annotation to be displayed inline next to a range of source code.
1518 struct InlayHint {
1519 /// The range of source code to which the hint applies.
1520 /// We provide the entire range, rather than just the endpoint
1521 /// relevant to `position` (e.g. the start of the range for
1522 /// InlayHintPosition::Before), to give clients the flexibility
1523 /// to make choices like only displaying the hint while the cursor
1524 /// is over the range, rather than displaying it all the time.
1525 Range range;
1526
1527 /// The type of hint.
1528 InlayHintKind kind;
1529
1530 /// The label that is displayed in the editor.
1531 std::string label;
1532 };
1533 llvm::json::Value toJSON(const InlayHint &);
1534
1535 struct ReferenceContext {
1536 /// Include the declaration of the current symbol.
1537 bool includeDeclaration = false;
1538 };
1539
1540 struct ReferenceParams : public TextDocumentPositionParams {
1541 ReferenceContext context;
1542 };
1543 bool fromJSON(const llvm::json::Value &, ReferenceParams &, llvm::json::Path);
1544
1545 /// Clangd extension: indicates the current state of the file in clangd,
1546 /// sent from server via the `textDocument/clangd.fileStatus` notification.
1547 struct FileStatus {
1548 /// The text document's URI.
1549 URIForFile uri;
1550 /// The human-readable string presents the current state of the file, can be
1551 /// shown in the UI (e.g. status bar).
1552 std::string state;
1553 // FIXME: add detail messages.
1554 };
1555 llvm::json::Value toJSON(const FileStatus &);
1556
1557 /// Specifies a single semantic token in the document.
1558 /// This struct is not part of LSP, which just encodes lists of tokens as
1559 /// arrays of numbers directly.
1560 struct SemanticToken {
1561 /// token line number, relative to the previous token
1562 unsigned deltaLine = 0;
1563 /// token start character, relative to the previous token
1564 /// (relative to 0 or the previous token's start if they are on the same line)
1565 unsigned deltaStart = 0;
1566 /// the length of the token. A token cannot be multiline
1567 unsigned length = 0;
1568 /// will be looked up in `SemanticTokensLegend.tokenTypes`
1569 unsigned tokenType = 0;
1570 /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers`
1571 unsigned tokenModifiers = 0;
1572 };
1573 bool operator==(const SemanticToken &, const SemanticToken &);
1574
1575 /// A versioned set of tokens.
1576 struct SemanticTokens {
1577 // An optional result id. If provided and clients support delta updating
1578 // the client will include the result id in the next semantic token request.
1579 // A server can then instead of computing all semantic tokens again simply
1580 // send a delta.
1581 std::string resultId;
1582
1583 /// The actual tokens.
1584 std::vector<SemanticToken> tokens; // encoded as a flat integer array.
1585 };
1586 llvm::json::Value toJSON(const SemanticTokens &);
1587
1588 /// Body of textDocument/semanticTokens/full request.
1589 struct SemanticTokensParams {
1590 /// The text document.
1591 TextDocumentIdentifier textDocument;
1592 };
1593 bool fromJSON(const llvm::json::Value &, SemanticTokensParams &,
1594 llvm::json::Path);
1595
1596 /// Body of textDocument/semanticTokens/full/delta request.
1597 /// Requests the changes in semantic tokens since a previous response.
1598 struct SemanticTokensDeltaParams {
1599 /// The text document.
1600 TextDocumentIdentifier textDocument;
1601 /// The previous result id.
1602 std::string previousResultId;
1603 };
1604 bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R,
1605 llvm::json::Path);
1606
1607 /// Describes a a replacement of a contiguous range of semanticTokens.
1608 struct SemanticTokensEdit {
1609 // LSP specifies `start` and `deleteCount` which are relative to the array
1610 // encoding of the previous tokens.
1611 // We use token counts instead, and translate when serializing this struct.
1612 unsigned startToken = 0;
1613 unsigned deleteTokens = 0;
1614 std::vector<SemanticToken> tokens; // encoded as a flat integer array
1615 };
1616 llvm::json::Value toJSON(const SemanticTokensEdit &);
1617
1618 /// This models LSP SemanticTokensDelta | SemanticTokens, which is the result of
1619 /// textDocument/semanticTokens/full/delta.
1620 struct SemanticTokensOrDelta {
1621 std::string resultId;
1622 /// Set if we computed edits relative to a previous set of tokens.
1623 llvm::Optional<std::vector<SemanticTokensEdit>> edits;
1624 /// Set if we computed a fresh set of tokens.
1625 llvm::Optional<std::vector<SemanticToken>> tokens; // encoded as integer array
1626 };
1627 llvm::json::Value toJSON(const SemanticTokensOrDelta &);
1628
1629 struct SelectionRangeParams {
1630 /// The text document.
1631 TextDocumentIdentifier textDocument;
1632
1633 /// The positions inside the text document.
1634 std::vector<Position> positions;
1635 };
1636 bool fromJSON(const llvm::json::Value &, SelectionRangeParams &,
1637 llvm::json::Path);
1638
1639 struct SelectionRange {
1640 /**
1641 * The range of this selection range.
1642 */
1643 Range range;
1644 /**
1645 * The parent selection range containing this range. Therefore `parent.range`
1646 * must contain `this.range`.
1647 */
1648 std::unique_ptr<SelectionRange> parent;
1649 };
1650 llvm::json::Value toJSON(const SelectionRange &);
1651
1652 /// Parameters for the document link request.
1653 struct DocumentLinkParams {
1654 /// The document to provide document links for.
1655 TextDocumentIdentifier textDocument;
1656 };
1657 bool fromJSON(const llvm::json::Value &, DocumentLinkParams &,
1658 llvm::json::Path);
1659
1660 /// A range in a text document that links to an internal or external resource,
1661 /// like another text document or a web site.
1662 struct DocumentLink {
1663 /// The range this link applies to.
1664 Range range;
1665
1666 /// The uri this link points to. If missing a resolve request is sent later.
1667 URIForFile target;
1668
1669 // TODO(forster): The following optional fields defined by the language
1670 // server protocol are unsupported:
1671 //
1672 // data?: any - A data entry field that is preserved on a document link
1673 // between a DocumentLinkRequest and a
1674 // DocumentLinkResolveRequest.
1675
1676 friend bool operator==(const DocumentLink &LHS, const DocumentLink &RHS) {
1677 return LHS.range == RHS.range && LHS.target == RHS.target;
1678 }
1679
1680 friend bool operator!=(const DocumentLink &LHS, const DocumentLink &RHS) {
1681 return !(LHS == RHS);
1682 }
1683 };
1684 llvm::json::Value toJSON(const DocumentLink &DocumentLink);
1685
1686 // FIXME(kirillbobyrev): Add FoldingRangeClientCapabilities so we can support
1687 // per-line-folding editors.
1688 struct FoldingRangeParams {
1689 TextDocumentIdentifier textDocument;
1690 };
1691 bool fromJSON(const llvm::json::Value &, FoldingRangeParams &,
1692 llvm::json::Path);
1693
1694 /// Stores information about a region of code that can be folded.
1695 struct FoldingRange {
1696 unsigned startLine = 0;
1697 unsigned startCharacter;
1698 unsigned endLine = 0;
1699 unsigned endCharacter;
1700 llvm::Optional<std::string> kind;
1701 };
1702 llvm::json::Value toJSON(const FoldingRange &Range);
1703
1704 /// Keys starting with an underscore(_) represent leaves, e.g. _total or _self
1705 /// for memory usage of whole subtree or only that specific node in bytes. All
1706 /// other keys represents children. An example:
1707 /// {
1708 /// "_self": 0,
1709 /// "_total": 8,
1710 /// "child1": {
1711 /// "_self": 4,
1712 /// "_total": 4,
1713 /// }
1714 /// "child2": {
1715 /// "_self": 2,
1716 /// "_total": 4,
1717 /// "child_deep": {
1718 /// "_self": 2,
1719 /// "_total": 2,
1720 /// }
1721 /// }
1722 /// }
1723 llvm::json::Value toJSON(const MemoryTree &MT);
1724
1725 /// Payload for textDocument/ast request.
1726 /// This request is a clangd extension.
1727 struct ASTParams {
1728 /// The text document.
1729 TextDocumentIdentifier textDocument;
1730
1731 /// The position of the node to be dumped.
1732 /// The highest-level node that entirely contains the range will be returned.
1733 /// If no range is given, the root translation unit node will be returned.
1734 llvm::Optional<Range> range;
1735 };
1736 bool fromJSON(const llvm::json::Value &, ASTParams &, llvm::json::Path);
1737
1738 /// Simplified description of a clang AST node.
1739 /// This is clangd's internal representation of C++ code.
1740 struct ASTNode {
1741 /// The general kind of node, such as "expression"
1742 /// Corresponds to the base AST node type such as Expr.
1743 std::string role;
1744 /// The specific kind of node this is, such as "BinaryOperator".
1745 /// This is usually a concrete node class (with Expr etc suffix dropped).
1746 /// When there's no hierarchy (e.g. TemplateName), the variant (NameKind).
1747 std::string kind;
1748 /// Brief additional information, such as "||" for the particular operator.
1749 /// The information included depends on the node kind, and may be empty.
1750 std::string detail;
1751 /// A one-line dump of detailed information about the node.
1752 /// This includes role/kind/description information, but is rather cryptic.
1753 /// It is similar to the output from `clang -Xclang -ast-dump`.
1754 /// May be empty for certain types of nodes.
1755 std::string arcana;
1756 /// The range of the original source file covered by this node.
1757 /// May be missing for implicit nodes, or those created by macro expansion.
1758 llvm::Optional<Range> range;
1759 /// Nodes nested within this one, such as the operands of a BinaryOperator.
1760 std::vector<ASTNode> children;
1761 };
1762 llvm::json::Value toJSON(const ASTNode &);
1763 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ASTNode &);
1764
1765 } // namespace clangd
1766 } // namespace clang
1767
1768 namespace llvm {
1769 template <> struct format_provider<clang::clangd::Position> {
1770 static void format(const clang::clangd::Position &Pos, raw_ostream &OS,
1771 StringRef Style) {
1772 assert(Style.empty() && "style modifiers for this type are not supported");
1773 OS << Pos;
1774 }
1775 };
1776 } // namespace llvm
1777
1778 #endif
1779