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