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.definitions;
22 
23 alias DocumentUri = string;
24 
25 class Position
26 {
27     size_t line;
28     size_t character;
29 
30     this(size_t line = size_t.init, size_t character = size_t.init)
31     {
32         this.line = line;
33         this.character = character;
34     }
35 }
36 
37 class Range
38 {
39     Position start;
40     Position end;
41 
42     this(Position start = new Position(), Position end = new Position())
43     {
44         this.start = start;
45         this.end = end;
46     }
47 }
48 
49 class Location
50 {
51     DocumentUri uri;
52     Range range;
53 
54     this(DocumentUri uri = DocumentUri.init, Range range = new Range())
55     {
56         this.uri = uri;
57         this.range = range;
58     }
59 }
60 
61 class Diagnostic
62 {
63     import std.json : JSONValue;
64     import std.typecons : Nullable;
65 
66     Range range;
67     string message;
68     Nullable!DiagnosticSeverity severity;
69     Nullable!JSONValue code;
70     Nullable!string source;
71     Nullable!(DiagnosticRelatedInformation[]) relatedInformation;
72 
73     this(Range range = new Range(), string message = string.init,
74             Nullable!DiagnosticSeverity severity = Nullable!DiagnosticSeverity.init,
75             Nullable!JSONValue code = Nullable!JSONValue.init,
76             Nullable!string source = Nullable!string.init,
77             Nullable!(DiagnosticRelatedInformation[]) relatedInformation = Nullable!(
78                 DiagnosticRelatedInformation[]).init)
79     {
80         this.range = range;
81         this.message = message;
82         this.severity = severity;
83         this.code = code;
84         this.source = source;
85         this.relatedInformation = relatedInformation;
86     }
87 }
88 
89 enum DiagnosticSeverity : uint
90 {
91     error = 1,
92     warning = 2,
93     information = 3,
94     hint = 4
95 }
96 
97 class DiagnosticRelatedInformation
98 {
99     Location location;
100     string message;
101 
102     this(Location location = new Location(), string message = string.init)
103     {
104         this.location = location;
105         this.message = message;
106     }
107 }
108 
109 class Command
110 {
111     import std.json : JSONValue;
112     import std.typecons : Nullable;
113 
114     string title;
115     string command;
116     Nullable!(JSONValue[]) arguments;
117 
118     this(string title = string.init, string command = string.init,
119             Nullable!(JSONValue[]) arguments = Nullable!(JSONValue[]).init)
120     {
121         this.title = title;
122         this.command = command;
123         this.arguments = arguments;
124     }
125 }
126 
127 class TextEdit
128 {
129     Range range;
130     string newText;
131 
132     this(Range range = new Range(), string newText = string.init)
133     {
134         this.range = range;
135         this.newText = newText;
136     }
137 }
138 
139 class TextDocumentEdit
140 {
141     VersionedTextDocumentIdentifier textDocument;
142     TextEdit[] edits;
143 
144     this(VersionedTextDocumentIdentifier textDocument = new VersionedTextDocumentIdentifier(),
145             TextEdit[] edits = TextEdit[].init)
146     {
147         this.textDocument = textDocument;
148         this.edits = edits;
149     }
150 }
151 
152 class CreateFileOptions
153 {
154     import std.typecons : Nullable;
155 
156     Nullable!bool overwrite;
157     Nullable!bool ignoreIfExists;
158 
159     this(Nullable!bool overwrite = Nullable!bool.init,
160             Nullable!bool ignoreIfExists = Nullable!bool.init)
161     {
162         this.overwrite = overwrite;
163         this.ignoreIfExists = ignoreIfExists;
164     }
165 }
166 
167 class CreateFile
168 {
169     import std.typecons : Nullable;
170 
171     immutable string kind = "create";
172     string uri;
173     Nullable!CreateFileOptions options;
174 
175     this(string uri = string.init,
176             Nullable!CreateFileOptions options = Nullable!CreateFileOptions.init)
177     {
178         this.uri = uri;
179         this.options = options;
180     }
181 }
182 
183 class RenameFileOptions
184 {
185     import std.typecons : Nullable;
186 
187     Nullable!bool overwrite;
188     Nullable!bool ignoreIfExists;
189 
190     this(Nullable!bool overwrite = Nullable!bool.init,
191             Nullable!bool ignoreIfExists = Nullable!bool.init)
192     {
193         this.overwrite = overwrite;
194         this.ignoreIfExists = ignoreIfExists;
195     }
196 }
197 
198 class RenameFile
199 {
200     import std.typecons : Nullable;
201 
202     immutable string kind = "rename";
203     string oldUri;
204     string newUri;
205     Nullable!RenameFileOptions options;
206 
207     this(string oldUri = string.init, string newUri = string.init,
208             Nullable!RenameFileOptions options = Nullable!RenameFileOptions.init)
209     {
210         this.oldUri = oldUri;
211         this.newUri = newUri;
212         this.options = options;
213     }
214 }
215 
216 class DeleteFileOptions
217 {
218     import std.typecons : Nullable;
219 
220     Nullable!bool recursive;
221     Nullable!bool ignoreIfExists;
222 
223     this(Nullable!bool recursive = Nullable!bool.init,
224             Nullable!bool ignoreIfExists = Nullable!bool.init)
225     {
226         this.recursive = recursive;
227         this.ignoreIfExists = ignoreIfExists;
228     }
229 }
230 
231 class DeleteFile
232 {
233     import std.typecons : Nullable;
234 
235     immutable string kind = "delete";
236     string uri;
237     Nullable!DeleteFileOptions options;
238 
239     this(string uri = string.init,
240             Nullable!DeleteFileOptions options = Nullable!DeleteFileOptions.init)
241     {
242         this.uri = uri;
243         this.options = options;
244     }
245 }
246 
247 class WorkspaceEdit
248 {
249     import std.typecons : Nullable;
250 
251     Nullable!(TextEdit[][string]) changes;
252     Nullable!(TextDocumentEdit[]) documentChanges; // (TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[]
253 
254     this(Nullable!(TextEdit[][string]) changes = Nullable!(TextEdit[][string])
255             .init, Nullable!(TextDocumentEdit[]) documentChanges = Nullable!(
256                 TextDocumentEdit[]).init)
257     {
258         this.changes = changes;
259         this.documentChanges = documentChanges;
260     }
261 }
262 
263 class TextDocumentIdentifier
264 {
265     DocumentUri uri;
266 
267     this(DocumentUri uri = DocumentUri.init)
268     {
269         this.uri = uri;
270     }
271 }
272 
273 class TextDocumentItem : TextDocumentIdentifier
274 {
275     string languageId;
276     long version_;
277     string text;
278 
279     this(DocumentUri uri = DocumentUri.init, string languageId = string.init,
280             long version_ = long.init, string text = string.init)
281     {
282         super(uri);
283         this.languageId = languageId;
284         this.version_ = version_;
285         this.text = text;
286     }
287 }
288 
289 class VersionedTextDocumentIdentifier : TextDocumentIdentifier
290 {
291     import std.json : JSONValue;
292 
293     JSONValue version_;
294 
295     this(DocumentUri uri = DocumentUri.init, JSONValue version_ = JSONValue.init)
296     {
297         super(uri);
298         this.version_ = version_;
299     }
300 }
301 
302 class TextDocumentPositionParams
303 {
304     import dls.util.constructor : Constructor;
305 
306     TextDocumentIdentifier textDocument;
307     Position position;
308 
309     mixin Constructor!TextDocumentPositionParams;
310 }
311 
312 class DocumentFilter
313 {
314     import std.typecons : Nullable;
315 
316     Nullable!string languageId;
317     Nullable!string scheme;
318     Nullable!string pattern;
319 
320     this(Nullable!string languageId = Nullable!string.init,
321             Nullable!string scheme = Nullable!string.init,
322             Nullable!string pattern = Nullable!string.init)
323     {
324         this.languageId = languageId;
325         this.scheme = scheme;
326         this.pattern = pattern;
327     }
328 }
329 
330 alias DocumentSelector = DocumentFilter[];
331 
332 enum MarkupKind : string
333 {
334     plaintext = "plaintext",
335     markdown = "markdown"
336 }
337 
338 class MarkupContent
339 {
340     MarkupKind kind;
341     string value;
342 
343     this(MarkupKind kind = MarkupKind.init, string value = string.init)
344     {
345         this.kind = kind;
346         this.value = value;
347     }
348 }