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