1 /*
2  *Copyright (C) 2018 Laurent Tréguier
3  *
4  *This file is part of DLS.
5  *
6  *DLS is free software: you can redistribute it and/or modify
7  *it under the terms of the GNU General Public License as published by
8  *the Free Software Foundation, either version 3 of the License, or
9  *(at your option) any later version.
10  *
11  *DLS is distributed in the hope that it will be useful,
12  *but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *GNU General Public License for more details.
15  *
16  *You should have received a copy of the GNU General Public License
17  *along with DLS.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 module dls.protocol.interfaces.general;
22 
23 private class WithDynamicRegistration
24 {
25     import std.typecons : Nullable;
26 
27     Nullable!bool dynamicRegistration;
28 }
29 
30 class InitializeParams
31 {
32     import dls.protocol.definitions : DocumentUri;
33     import dls.protocol.interfaces.workspace : WorkspaceFolder;
34     import dls.util.constructor : Constructor;
35     import std.typecons : Nullable;
36 
37     static enum Trace : string
38     {
39         off = "off",
40         messages = "messages",
41         verbose = "verbose"
42     }
43 
44     static class InitializationOptions
45     {
46         static class Capabilities
47         {
48             bool hover = true;
49             bool completion = true;
50             bool definition = true;
51             bool typeDefinition = true;
52             bool references = true;
53             bool documentHighlight = true;
54             bool documentSymbol = true;
55             bool workspaceSymbol = true;
56             bool documentFormatting = true;
57             bool rename = true;
58         }
59 
60         bool autoUpdate = true;
61         Capabilities capabilities;
62 
63         mixin Constructor!InitializationOptions;
64     }
65 
66     Nullable!ulong processId;
67     Nullable!string rootPath;
68     Nullable!DocumentUri rootUri;
69     Nullable!InitializationOptions initializationOptions;
70     ClientCapabilities capabilities;
71     Nullable!Trace trace;
72     Nullable!(WorkspaceFolder[]) workspaceFolders;
73 
74     mixin Constructor!InitializeParams;
75 }
76 
77 enum ResourceOperationKind : string
78 {
79     create = "create",
80     rename = "rename",
81     delete_ = "delete"
82 }
83 
84 enum FailureHandlingKind : string
85 {
86     abort = "abort",
87     transactional = "transactional",
88     textOnlyTransactional = "textOnlyTransactional",
89     undo = "undo"
90 }
91 
92 class WorkspaceClientCapabilities
93 {
94     import std.typecons : Nullable;
95 
96     static class WorkspaceEdit
97     {
98         Nullable!bool documentChanges;
99         Nullable!(ResourceOperationKind[]) resourceOperations;
100         Nullable!FailureHandlingKind failureHandling;
101     }
102 
103     static class Symbol : WithDynamicRegistration
104     {
105         static class SymbolKind
106         {
107             import dls.protocol.interfaces.text_document : SymbolKind;
108 
109             Nullable!(SymbolKind[]) valueSet;
110         }
111 
112         Nullable!SymbolKind symbolKind;
113     }
114 
115     Nullable!bool applyEdit;
116     Nullable!WorkspaceEdit workspaceEdit;
117     Nullable!WithDynamicRegistration didChangeConfiguration;
118     Nullable!WithDynamicRegistration didChangeWatchedFiles;
119     Nullable!Symbol symbol;
120     Nullable!WithDynamicRegistration executeCommand;
121     Nullable!bool workspaceFolders;
122     Nullable!bool configuration;
123 }
124 
125 class TextDocumentClientCapabilities
126 {
127     import std.typecons : Nullable;
128 
129     static class Synchronisation : WithDynamicRegistration
130     {
131         Nullable!bool willSave;
132         Nullable!bool willSaveWaitUntil;
133         Nullable!bool didSave;
134     }
135 
136     static class Completion : WithDynamicRegistration
137     {
138         static class CompletionItem
139         {
140             import dls.protocol.definitions : MarkupKind;
141 
142             Nullable!bool snippetSupport;
143             Nullable!bool commitCharactersSupport;
144             Nullable!(MarkupKind[]) documentationFormat;
145             Nullable!bool deprecatedSupport;
146             Nullable!bool preselectSupport;
147         }
148 
149         static class CompletionItemKind
150         {
151             import dls.protocol.interfaces.text_document : CompletionItemKind;
152 
153             Nullable!(CompletionItemKind[]) valueSet;
154         }
155 
156         Nullable!CompletionItem completionItem;
157         Nullable!CompletionItemKind completionItemKind;
158         Nullable!bool contextSupport;
159     }
160 
161     static class Hover : WithDynamicRegistration
162     {
163         import dls.protocol.definitions : MarkupKind;
164 
165         Nullable!(MarkupKind[]) contentFormat;
166     }
167 
168     static class SignatureHelp : WithDynamicRegistration
169     {
170         static class SignatureInformation
171         {
172             import dls.protocol.definitions : MarkupKind;
173 
174             Nullable!(MarkupKind[]) documentationFormat;
175         }
176 
177         Nullable!SignatureInformation signatureHelp;
178     }
179 
180     static class DocumentSymbol : WithDynamicRegistration
181     {
182         static class SymbolKind
183         {
184             import dls.protocol.interfaces.text_document : SymbolKind;
185 
186             Nullable!(SymbolKind[]) valueSet;
187         }
188 
189         Nullable!SymbolKind symbolKind;
190         Nullable!bool hierarchicalDocumentSymbolSupport;
191     }
192 
193     static class CodeAction : WithDynamicRegistration
194     {
195         static class CodeActionLiteralSupport
196         {
197             import dls.util.constructor : Constructor;
198 
199             static class CodeActionKind
200             {
201                 import dls.protocol.interfaces.text_document : CodeActionKind;
202 
203                 CodeActionKind[] valueSet;
204             }
205 
206             CodeActionKind codeActionKind;
207 
208             mixin Constructor!CodeActionLiteralSupport;
209         }
210 
211         Nullable!CodeActionLiteralSupport codeActionLiteralSupport;
212     }
213 
214     static class Rename : WithDynamicRegistration
215     {
216         Nullable!bool prepareSupport;
217     }
218 
219     static class PublishDiagnostics
220     {
221         Nullable!bool relatedInformation;
222     }
223 
224     static class FoldingRange : WithDynamicRegistration
225     {
226         Nullable!size_t rangeLimit;
227         Nullable!bool lineFoldingOnly;
228     }
229 
230     Nullable!Synchronisation synchronisation;
231     Nullable!Completion completion;
232     Nullable!Hover hover;
233     Nullable!SignatureHelp signatureHelp;
234     Nullable!WithDynamicRegistration references;
235     Nullable!WithDynamicRegistration documentHighlight;
236     Nullable!DocumentSymbol documentSymbol;
237     Nullable!WithDynamicRegistration formatting;
238     Nullable!WithDynamicRegistration rangeFormatting;
239     Nullable!WithDynamicRegistration onTypeFormatting;
240     Nullable!WithDynamicRegistration definition;
241     Nullable!WithDynamicRegistration typeDefinition;
242     Nullable!WithDynamicRegistration implementation;
243     Nullable!CodeAction codeAction;
244     Nullable!WithDynamicRegistration codeLens;
245     Nullable!WithDynamicRegistration documentLink;
246     Nullable!WithDynamicRegistration colorProvider;
247     Nullable!Rename rename;
248     Nullable!PublishDiagnostics publishDiagnostics;
249     Nullable!FoldingRange foldingRange;
250 }
251 
252 class ClientCapabilities
253 {
254     import std.json : JSONValue;
255     import std.typecons : Nullable;
256 
257     Nullable!WorkspaceClientCapabilities workspace;
258     Nullable!TextDocumentClientCapabilities textDocument;
259     Nullable!JSONValue experimental;
260 }
261 
262 class InitializeResult
263 {
264     ServerCapabilities capabilities;
265 
266     this(ServerCapabilities capabilities = new ServerCapabilities())
267     {
268         this.capabilities = capabilities;
269     }
270 }
271 
272 class InitializeErrorData
273 {
274     bool retry;
275 }
276 
277 enum TextDocumentSyncKind : uint
278 {
279     none = 0,
280     full = 1,
281     incremental = 2
282 }
283 
284 private class OptionsBase
285 {
286     import std.typecons : Nullable;
287 
288     Nullable!bool resolveProvider;
289 
290     this(Nullable!bool resolveProvider = Nullable!bool.init)
291     {
292         this.resolveProvider = resolveProvider;
293     }
294 }
295 
296 class CompletionOptions : OptionsBase
297 {
298     import std.typecons : Nullable;
299 
300     Nullable!(string[]) triggerCharacters;
301 
302     this(Nullable!bool resolveProvider = Nullable!bool.init,
303             Nullable!(string[]) triggerCharacters = Nullable!(string[]).init)
304     {
305         super(resolveProvider);
306         this.triggerCharacters = triggerCharacters;
307     }
308 }
309 
310 class SignatureHelpOptions
311 {
312     import std.typecons : Nullable;
313 
314     Nullable!(string[]) triggerCharacters;
315 
316     this(Nullable!(string[]) triggerCharacters = Nullable!(string[]).init)
317     {
318         this.triggerCharacters = triggerCharacters;
319     }
320 }
321 
322 class CodeActionOptions
323 {
324     import dls.protocol.interfaces.text_document : CodeActionKind;
325     import std.typecons : Nullable;
326 
327     Nullable!(CodeActionKind[]) codeActionKinds;
328 
329     this(Nullable!(CodeActionKind[]) codeActionKinds = Nullable!(CodeActionKind[]).init)
330     {
331         this.codeActionKinds = codeActionKinds;
332     }
333 }
334 
335 alias CodeLensOptions = OptionsBase;
336 
337 class DocumentOnTypeFormattingOptions
338 {
339     import std.typecons : Nullable;
340 
341     string firstTriggerCharacter;
342     Nullable!(string[]) moreTriggerCharacter;
343 
344     this(string firstTriggerCharacter = string.init,
345             Nullable!(string[]) moreTriggerCharacter = Nullable!(string[]).init)
346     {
347         this.firstTriggerCharacter = firstTriggerCharacter;
348         this.moreTriggerCharacter = moreTriggerCharacter;
349     }
350 }
351 
352 class RenameOptions
353 {
354     import std.typecons : Nullable;
355 
356     Nullable!bool prepareProvider;
357 
358     this(Nullable!bool prepareProvider = Nullable!bool.init)
359     {
360         this.prepareProvider = prepareProvider;
361     }
362 }
363 
364 alias DocumentLinkOptions = OptionsBase;
365 
366 class ExecuteCommandOptions
367 {
368     string[] commands;
369 
370     this(string[] commands = string[].init)
371     {
372         this.commands = commands;
373     }
374 }
375 
376 class SaveOptions
377 {
378     import std.typecons : Nullable;
379 
380     Nullable!bool includeText;
381 
382     this(Nullable!bool includeText = Nullable!bool.init)
383     {
384         this.includeText = includeText;
385     }
386 }
387 
388 class ColorProviderOptions
389 {
390 }
391 
392 class FoldingRangeProviderOptions
393 {
394 }
395 
396 class TextDocumentSyncOptions
397 {
398     import std.typecons : Nullable;
399 
400     Nullable!bool openClose;
401     Nullable!TextDocumentSyncKind change;
402     Nullable!bool willSave;
403     Nullable!bool willSaveWaitUntil;
404     Nullable!SaveOptions save;
405 
406     this(Nullable!bool openClose = Nullable!bool.init,
407             Nullable!TextDocumentSyncKind change = Nullable!TextDocumentSyncKind.init,
408             Nullable!bool willSave = Nullable!bool.init, Nullable!bool willSaveWaitUntil = Nullable!bool.init,
409             Nullable!SaveOptions save = Nullable!SaveOptions.init)
410     {
411         this.openClose = openClose;
412         this.change = change;
413         this.willSave = willSave;
414         this.willSaveWaitUntil = willSaveWaitUntil;
415         this.save = save;
416     }
417 }
418 
419 class StaticRegistrationOptions
420 {
421     import std.typecons : Nullable;
422 
423     Nullable!string id;
424 
425     this(Nullable!string id = Nullable!string.init)
426     {
427         this.id = id;
428     }
429 }
430 
431 class ServerCapabilities
432 {
433     import std.json : JSONValue;
434     import std.typecons : Nullable;
435 
436     static class Workspace
437     {
438         static class WorkspaceFolders
439         {
440             Nullable!bool supported;
441             Nullable!JSONValue changeNotifications;
442 
443             this(Nullable!bool supported = Nullable!bool.init,
444                     Nullable!JSONValue changeNotifications = Nullable!JSONValue.init)
445             {
446                 this.supported = supported;
447                 this.changeNotifications = changeNotifications;
448             }
449         }
450 
451         Nullable!WorkspaceFolders workspaceFolders;
452 
453         this(Nullable!WorkspaceFolders workspaceFolders = Nullable!WorkspaceFolders.init)
454         {
455             this.workspaceFolders = workspaceFolders;
456         }
457     }
458 
459     Nullable!TextDocumentSyncOptions textDocumentSync; // TODO: add TextDocumentSyncKind compatibility
460     Nullable!bool hoverProvider;
461     Nullable!CompletionOptions completionProvider;
462     Nullable!SignatureHelpOptions signatureHelpProvider;
463     Nullable!bool definitionProvider;
464     Nullable!bool typeDefinitionProvider;
465     Nullable!JSONValue implementationProvider;
466     Nullable!bool referencesProvider;
467     Nullable!bool documentHighlightProvider;
468     Nullable!bool documentSymbolProvider;
469     Nullable!bool workspaceSymbolProvider;
470     Nullable!JSONValue codeActionProvider;
471     Nullable!CodeLensOptions codeLensProvider;
472     Nullable!bool documentFormattingProvider;
473     Nullable!bool documentRangeFormattingProvider;
474     Nullable!DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
475     Nullable!RenameOptions renameProvider;
476     Nullable!DocumentLinkOptions documentLinkProvider;
477     Nullable!JSONValue colorProvider;
478     Nullable!JSONValue foldingRangeProvider;
479     Nullable!ExecuteCommandOptions executeCommandProvider;
480     Nullable!Workspace workspace;
481     Nullable!JSONValue experimental;
482 }
483 
484 class CancelParams
485 {
486     import std.json : JSONValue;
487 
488     JSONValue id;
489 }