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