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