1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 | exports.createMessageConnection = exports.ConnectionOptions = exports.MessageStrategy = exports.CancellationStrategy = exports.CancellationSenderStrategy = exports.CancellationReceiverStrategy = exports.RequestCancellationReceiverStrategy = exports.IdCancellationReceiverStrategy = exports.ConnectionStrategy = exports.ConnectionError = exports.ConnectionErrors = exports.LogTraceNotification = exports.SetTraceNotification = exports.TraceFormat = exports.TraceValues = exports.Trace = exports.NullLogger = exports.ProgressType = exports.ProgressToken = void 0;
|
8 | const ral_1 = require("./ral");
|
9 | const Is = require("./is");
|
10 | const messages_1 = require("./messages");
|
11 | const linkedMap_1 = require("./linkedMap");
|
12 | const events_1 = require("./events");
|
13 | const cancellation_1 = require("./cancellation");
|
14 | var CancelNotification;
|
15 | (function (CancelNotification) {
|
16 | CancelNotification.type = new messages_1.NotificationType('$/cancelRequest');
|
17 | })(CancelNotification || (CancelNotification = {}));
|
18 | var ProgressToken;
|
19 | (function (ProgressToken) {
|
20 | function is(value) {
|
21 | return typeof value === 'string' || typeof value === 'number';
|
22 | }
|
23 | ProgressToken.is = is;
|
24 | })(ProgressToken || (exports.ProgressToken = ProgressToken = {}));
|
25 | var ProgressNotification;
|
26 | (function (ProgressNotification) {
|
27 | ProgressNotification.type = new messages_1.NotificationType('$/progress');
|
28 | })(ProgressNotification || (ProgressNotification = {}));
|
29 | class ProgressType {
|
30 | constructor() {
|
31 | }
|
32 | }
|
33 | exports.ProgressType = ProgressType;
|
34 | var StarRequestHandler;
|
35 | (function (StarRequestHandler) {
|
36 | function is(value) {
|
37 | return Is.func(value);
|
38 | }
|
39 | StarRequestHandler.is = is;
|
40 | })(StarRequestHandler || (StarRequestHandler = {}));
|
41 | exports.NullLogger = Object.freeze({
|
42 | error: () => { },
|
43 | warn: () => { },
|
44 | info: () => { },
|
45 | log: () => { }
|
46 | });
|
47 | var Trace;
|
48 | (function (Trace) {
|
49 | Trace[Trace["Off"] = 0] = "Off";
|
50 | Trace[Trace["Messages"] = 1] = "Messages";
|
51 | Trace[Trace["Compact"] = 2] = "Compact";
|
52 | Trace[Trace["Verbose"] = 3] = "Verbose";
|
53 | })(Trace || (exports.Trace = Trace = {}));
|
54 | var TraceValues;
|
55 | (function (TraceValues) {
|
56 | |
57 |
|
58 |
|
59 | TraceValues.Off = 'off';
|
60 | |
61 |
|
62 |
|
63 | TraceValues.Messages = 'messages';
|
64 | |
65 |
|
66 |
|
67 | TraceValues.Compact = 'compact';
|
68 | |
69 |
|
70 |
|
71 | TraceValues.Verbose = 'verbose';
|
72 | })(TraceValues || (exports.TraceValues = TraceValues = {}));
|
73 | (function (Trace) {
|
74 | function fromString(value) {
|
75 | if (!Is.string(value)) {
|
76 | return Trace.Off;
|
77 | }
|
78 | value = value.toLowerCase();
|
79 | switch (value) {
|
80 | case 'off':
|
81 | return Trace.Off;
|
82 | case 'messages':
|
83 | return Trace.Messages;
|
84 | case 'compact':
|
85 | return Trace.Compact;
|
86 | case 'verbose':
|
87 | return Trace.Verbose;
|
88 | default:
|
89 | return Trace.Off;
|
90 | }
|
91 | }
|
92 | Trace.fromString = fromString;
|
93 | function toString(value) {
|
94 | switch (value) {
|
95 | case Trace.Off:
|
96 | return 'off';
|
97 | case Trace.Messages:
|
98 | return 'messages';
|
99 | case Trace.Compact:
|
100 | return 'compact';
|
101 | case Trace.Verbose:
|
102 | return 'verbose';
|
103 | default:
|
104 | return 'off';
|
105 | }
|
106 | }
|
107 | Trace.toString = toString;
|
108 | })(Trace || (exports.Trace = Trace = {}));
|
109 | var TraceFormat;
|
110 | (function (TraceFormat) {
|
111 | TraceFormat["Text"] = "text";
|
112 | TraceFormat["JSON"] = "json";
|
113 | })(TraceFormat || (exports.TraceFormat = TraceFormat = {}));
|
114 | (function (TraceFormat) {
|
115 | function fromString(value) {
|
116 | if (!Is.string(value)) {
|
117 | return TraceFormat.Text;
|
118 | }
|
119 | value = value.toLowerCase();
|
120 | if (value === 'json') {
|
121 | return TraceFormat.JSON;
|
122 | }
|
123 | else {
|
124 | return TraceFormat.Text;
|
125 | }
|
126 | }
|
127 | TraceFormat.fromString = fromString;
|
128 | })(TraceFormat || (exports.TraceFormat = TraceFormat = {}));
|
129 | var SetTraceNotification;
|
130 | (function (SetTraceNotification) {
|
131 | SetTraceNotification.type = new messages_1.NotificationType('$/setTrace');
|
132 | })(SetTraceNotification || (exports.SetTraceNotification = SetTraceNotification = {}));
|
133 | var LogTraceNotification;
|
134 | (function (LogTraceNotification) {
|
135 | LogTraceNotification.type = new messages_1.NotificationType('$/logTrace');
|
136 | })(LogTraceNotification || (exports.LogTraceNotification = LogTraceNotification = {}));
|
137 | var ConnectionErrors;
|
138 | (function (ConnectionErrors) {
|
139 | |
140 |
|
141 |
|
142 | ConnectionErrors[ConnectionErrors["Closed"] = 1] = "Closed";
|
143 | |
144 |
|
145 |
|
146 | ConnectionErrors[ConnectionErrors["Disposed"] = 2] = "Disposed";
|
147 | |
148 |
|
149 |
|
150 | ConnectionErrors[ConnectionErrors["AlreadyListening"] = 3] = "AlreadyListening";
|
151 | })(ConnectionErrors || (exports.ConnectionErrors = ConnectionErrors = {}));
|
152 | class ConnectionError extends Error {
|
153 | constructor(code, message) {
|
154 | super(message);
|
155 | this.code = code;
|
156 | Object.setPrototypeOf(this, ConnectionError.prototype);
|
157 | }
|
158 | }
|
159 | exports.ConnectionError = ConnectionError;
|
160 | var ConnectionStrategy;
|
161 | (function (ConnectionStrategy) {
|
162 | function is(value) {
|
163 | const candidate = value;
|
164 | return candidate && Is.func(candidate.cancelUndispatched);
|
165 | }
|
166 | ConnectionStrategy.is = is;
|
167 | })(ConnectionStrategy || (exports.ConnectionStrategy = ConnectionStrategy = {}));
|
168 | var IdCancellationReceiverStrategy;
|
169 | (function (IdCancellationReceiverStrategy) {
|
170 | function is(value) {
|
171 | const candidate = value;
|
172 | return candidate && (candidate.kind === undefined || candidate.kind === 'id') && Is.func(candidate.createCancellationTokenSource) && (candidate.dispose === undefined || Is.func(candidate.dispose));
|
173 | }
|
174 | IdCancellationReceiverStrategy.is = is;
|
175 | })(IdCancellationReceiverStrategy || (exports.IdCancellationReceiverStrategy = IdCancellationReceiverStrategy = {}));
|
176 | var RequestCancellationReceiverStrategy;
|
177 | (function (RequestCancellationReceiverStrategy) {
|
178 | function is(value) {
|
179 | const candidate = value;
|
180 | return candidate && candidate.kind === 'request' && Is.func(candidate.createCancellationTokenSource) && (candidate.dispose === undefined || Is.func(candidate.dispose));
|
181 | }
|
182 | RequestCancellationReceiverStrategy.is = is;
|
183 | })(RequestCancellationReceiverStrategy || (exports.RequestCancellationReceiverStrategy = RequestCancellationReceiverStrategy = {}));
|
184 | var CancellationReceiverStrategy;
|
185 | (function (CancellationReceiverStrategy) {
|
186 | CancellationReceiverStrategy.Message = Object.freeze({
|
187 | createCancellationTokenSource(_) {
|
188 | return new cancellation_1.CancellationTokenSource();
|
189 | }
|
190 | });
|
191 | function is(value) {
|
192 | return IdCancellationReceiverStrategy.is(value) || RequestCancellationReceiverStrategy.is(value);
|
193 | }
|
194 | CancellationReceiverStrategy.is = is;
|
195 | })(CancellationReceiverStrategy || (exports.CancellationReceiverStrategy = CancellationReceiverStrategy = {}));
|
196 | var CancellationSenderStrategy;
|
197 | (function (CancellationSenderStrategy) {
|
198 | CancellationSenderStrategy.Message = Object.freeze({
|
199 | sendCancellation(conn, id) {
|
200 | return conn.sendNotification(CancelNotification.type, { id });
|
201 | },
|
202 | cleanup(_) { }
|
203 | });
|
204 | function is(value) {
|
205 | const candidate = value;
|
206 | return candidate && Is.func(candidate.sendCancellation) && Is.func(candidate.cleanup);
|
207 | }
|
208 | CancellationSenderStrategy.is = is;
|
209 | })(CancellationSenderStrategy || (exports.CancellationSenderStrategy = CancellationSenderStrategy = {}));
|
210 | var CancellationStrategy;
|
211 | (function (CancellationStrategy) {
|
212 | CancellationStrategy.Message = Object.freeze({
|
213 | receiver: CancellationReceiverStrategy.Message,
|
214 | sender: CancellationSenderStrategy.Message
|
215 | });
|
216 | function is(value) {
|
217 | const candidate = value;
|
218 | return candidate && CancellationReceiverStrategy.is(candidate.receiver) && CancellationSenderStrategy.is(candidate.sender);
|
219 | }
|
220 | CancellationStrategy.is = is;
|
221 | })(CancellationStrategy || (exports.CancellationStrategy = CancellationStrategy = {}));
|
222 | var MessageStrategy;
|
223 | (function (MessageStrategy) {
|
224 | function is(value) {
|
225 | const candidate = value;
|
226 | return candidate && Is.func(candidate.handleMessage);
|
227 | }
|
228 | MessageStrategy.is = is;
|
229 | })(MessageStrategy || (exports.MessageStrategy = MessageStrategy = {}));
|
230 | var ConnectionOptions;
|
231 | (function (ConnectionOptions) {
|
232 | function is(value) {
|
233 | const candidate = value;
|
234 | return candidate && (CancellationStrategy.is(candidate.cancellationStrategy) || ConnectionStrategy.is(candidate.connectionStrategy) || MessageStrategy.is(candidate.messageStrategy));
|
235 | }
|
236 | ConnectionOptions.is = is;
|
237 | })(ConnectionOptions || (exports.ConnectionOptions = ConnectionOptions = {}));
|
238 | var ConnectionState;
|
239 | (function (ConnectionState) {
|
240 | ConnectionState[ConnectionState["New"] = 1] = "New";
|
241 | ConnectionState[ConnectionState["Listening"] = 2] = "Listening";
|
242 | ConnectionState[ConnectionState["Closed"] = 3] = "Closed";
|
243 | ConnectionState[ConnectionState["Disposed"] = 4] = "Disposed";
|
244 | })(ConnectionState || (ConnectionState = {}));
|
245 | function createMessageConnection(messageReader, messageWriter, _logger, options) {
|
246 | const logger = _logger !== undefined ? _logger : exports.NullLogger;
|
247 | let sequenceNumber = 0;
|
248 | let notificationSequenceNumber = 0;
|
249 | let unknownResponseSequenceNumber = 0;
|
250 | const version = '2.0';
|
251 | let starRequestHandler = undefined;
|
252 | const requestHandlers = new Map();
|
253 | let starNotificationHandler = undefined;
|
254 | const notificationHandlers = new Map();
|
255 | const progressHandlers = new Map();
|
256 | let timer;
|
257 | let messageQueue = new linkedMap_1.LinkedMap();
|
258 | let responsePromises = new Map();
|
259 | let knownCanceledRequests = new Set();
|
260 | let requestTokens = new Map();
|
261 | let trace = Trace.Off;
|
262 | let traceFormat = TraceFormat.Text;
|
263 | let tracer;
|
264 | let state = ConnectionState.New;
|
265 | const errorEmitter = new events_1.Emitter();
|
266 | const closeEmitter = new events_1.Emitter();
|
267 | const unhandledNotificationEmitter = new events_1.Emitter();
|
268 | const unhandledProgressEmitter = new events_1.Emitter();
|
269 | const disposeEmitter = new events_1.Emitter();
|
270 | const cancellationStrategy = (options && options.cancellationStrategy) ? options.cancellationStrategy : CancellationStrategy.Message;
|
271 | function createRequestQueueKey(id) {
|
272 | if (id === null) {
|
273 | throw new Error(`Can't send requests with id null since the response can't be correlated.`);
|
274 | }
|
275 | return 'req-' + id.toString();
|
276 | }
|
277 | function createResponseQueueKey(id) {
|
278 | if (id === null) {
|
279 | return 'res-unknown-' + (++unknownResponseSequenceNumber).toString();
|
280 | }
|
281 | else {
|
282 | return 'res-' + id.toString();
|
283 | }
|
284 | }
|
285 | function createNotificationQueueKey() {
|
286 | return 'not-' + (++notificationSequenceNumber).toString();
|
287 | }
|
288 | function addMessageToQueue(queue, message) {
|
289 | if (messages_1.Message.isRequest(message)) {
|
290 | queue.set(createRequestQueueKey(message.id), message);
|
291 | }
|
292 | else if (messages_1.Message.isResponse(message)) {
|
293 | queue.set(createResponseQueueKey(message.id), message);
|
294 | }
|
295 | else {
|
296 | queue.set(createNotificationQueueKey(), message);
|
297 | }
|
298 | }
|
299 | function cancelUndispatched(_message) {
|
300 | return undefined;
|
301 | }
|
302 | function isListening() {
|
303 | return state === ConnectionState.Listening;
|
304 | }
|
305 | function isClosed() {
|
306 | return state === ConnectionState.Closed;
|
307 | }
|
308 | function isDisposed() {
|
309 | return state === ConnectionState.Disposed;
|
310 | }
|
311 | function closeHandler() {
|
312 | if (state === ConnectionState.New || state === ConnectionState.Listening) {
|
313 | state = ConnectionState.Closed;
|
314 | closeEmitter.fire(undefined);
|
315 | }
|
316 |
|
317 | }
|
318 | function readErrorHandler(error) {
|
319 | errorEmitter.fire([error, undefined, undefined]);
|
320 | }
|
321 | function writeErrorHandler(data) {
|
322 | errorEmitter.fire(data);
|
323 | }
|
324 | messageReader.onClose(closeHandler);
|
325 | messageReader.onError(readErrorHandler);
|
326 | messageWriter.onClose(closeHandler);
|
327 | messageWriter.onError(writeErrorHandler);
|
328 | function triggerMessageQueue() {
|
329 | if (timer || messageQueue.size === 0) {
|
330 | return;
|
331 | }
|
332 | timer = (0, ral_1.default)().timer.setImmediate(() => {
|
333 | timer = undefined;
|
334 | processMessageQueue();
|
335 | });
|
336 | }
|
337 | function handleMessage(message) {
|
338 | if (messages_1.Message.isRequest(message)) {
|
339 | handleRequest(message);
|
340 | }
|
341 | else if (messages_1.Message.isNotification(message)) {
|
342 | handleNotification(message);
|
343 | }
|
344 | else if (messages_1.Message.isResponse(message)) {
|
345 | handleResponse(message);
|
346 | }
|
347 | else {
|
348 | handleInvalidMessage(message);
|
349 | }
|
350 | }
|
351 | function processMessageQueue() {
|
352 | if (messageQueue.size === 0) {
|
353 | return;
|
354 | }
|
355 | const message = messageQueue.shift();
|
356 | try {
|
357 | const messageStrategy = options?.messageStrategy;
|
358 | if (MessageStrategy.is(messageStrategy)) {
|
359 | messageStrategy.handleMessage(message, handleMessage);
|
360 | }
|
361 | else {
|
362 | handleMessage(message);
|
363 | }
|
364 | }
|
365 | finally {
|
366 | triggerMessageQueue();
|
367 | }
|
368 | }
|
369 | const callback = (message) => {
|
370 | try {
|
371 |
|
372 |
|
373 | if (messages_1.Message.isNotification(message) && message.method === CancelNotification.type.method) {
|
374 | const cancelId = message.params.id;
|
375 | const key = createRequestQueueKey(cancelId);
|
376 | const toCancel = messageQueue.get(key);
|
377 | if (messages_1.Message.isRequest(toCancel)) {
|
378 | const strategy = options?.connectionStrategy;
|
379 | const response = (strategy && strategy.cancelUndispatched) ? strategy.cancelUndispatched(toCancel, cancelUndispatched) : cancelUndispatched(toCancel);
|
380 | if (response && (response.error !== undefined || response.result !== undefined)) {
|
381 | messageQueue.delete(key);
|
382 | requestTokens.delete(cancelId);
|
383 | response.id = toCancel.id;
|
384 | traceSendingResponse(response, message.method, Date.now());
|
385 | messageWriter.write(response).catch(() => logger.error(`Sending response for canceled message failed.`));
|
386 | return;
|
387 | }
|
388 | }
|
389 | const cancellationToken = requestTokens.get(cancelId);
|
390 |
|
391 | if (cancellationToken !== undefined) {
|
392 | cancellationToken.cancel();
|
393 | traceReceivedNotification(message);
|
394 | return;
|
395 | }
|
396 | else {
|
397 |
|
398 |
|
399 | knownCanceledRequests.add(cancelId);
|
400 | }
|
401 | }
|
402 | addMessageToQueue(messageQueue, message);
|
403 | }
|
404 | finally {
|
405 | triggerMessageQueue();
|
406 | }
|
407 | };
|
408 | function handleRequest(requestMessage) {
|
409 | if (isDisposed()) {
|
410 |
|
411 |
|
412 | return;
|
413 | }
|
414 | function reply(resultOrError, method, startTime) {
|
415 | const message = {
|
416 | jsonrpc: version,
|
417 | id: requestMessage.id
|
418 | };
|
419 | if (resultOrError instanceof messages_1.ResponseError) {
|
420 | message.error = resultOrError.toJson();
|
421 | }
|
422 | else {
|
423 | message.result = resultOrError === undefined ? null : resultOrError;
|
424 | }
|
425 | traceSendingResponse(message, method, startTime);
|
426 | messageWriter.write(message).catch(() => logger.error(`Sending response failed.`));
|
427 | }
|
428 | function replyError(error, method, startTime) {
|
429 | const message = {
|
430 | jsonrpc: version,
|
431 | id: requestMessage.id,
|
432 | error: error.toJson()
|
433 | };
|
434 | traceSendingResponse(message, method, startTime);
|
435 | messageWriter.write(message).catch(() => logger.error(`Sending response failed.`));
|
436 | }
|
437 | function replySuccess(result, method, startTime) {
|
438 |
|
439 |
|
440 | if (result === undefined) {
|
441 | result = null;
|
442 | }
|
443 | const message = {
|
444 | jsonrpc: version,
|
445 | id: requestMessage.id,
|
446 | result: result
|
447 | };
|
448 | traceSendingResponse(message, method, startTime);
|
449 | messageWriter.write(message).catch(() => logger.error(`Sending response failed.`));
|
450 | }
|
451 | traceReceivedRequest(requestMessage);
|
452 | const element = requestHandlers.get(requestMessage.method);
|
453 | let type;
|
454 | let requestHandler;
|
455 | if (element) {
|
456 | type = element.type;
|
457 | requestHandler = element.handler;
|
458 | }
|
459 | const startTime = Date.now();
|
460 | if (requestHandler || starRequestHandler) {
|
461 | const tokenKey = requestMessage.id ?? String(Date.now());
|
462 | const cancellationSource = IdCancellationReceiverStrategy.is(cancellationStrategy.receiver)
|
463 | ? cancellationStrategy.receiver.createCancellationTokenSource(tokenKey)
|
464 | : cancellationStrategy.receiver.createCancellationTokenSource(requestMessage);
|
465 | if (requestMessage.id !== null && knownCanceledRequests.has(requestMessage.id)) {
|
466 | cancellationSource.cancel();
|
467 | }
|
468 | if (requestMessage.id !== null) {
|
469 | requestTokens.set(tokenKey, cancellationSource);
|
470 | }
|
471 | try {
|
472 | let handlerResult;
|
473 | if (requestHandler) {
|
474 | if (requestMessage.params === undefined) {
|
475 | if (type !== undefined && type.numberOfParams !== 0) {
|
476 | replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InvalidParams, `Request ${requestMessage.method} defines ${type.numberOfParams} params but received none.`), requestMessage.method, startTime);
|
477 | return;
|
478 | }
|
479 | handlerResult = requestHandler(cancellationSource.token);
|
480 | }
|
481 | else if (Array.isArray(requestMessage.params)) {
|
482 | if (type !== undefined && type.parameterStructures === messages_1.ParameterStructures.byName) {
|
483 | replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InvalidParams, `Request ${requestMessage.method} defines parameters by name but received parameters by position`), requestMessage.method, startTime);
|
484 | return;
|
485 | }
|
486 | handlerResult = requestHandler(...requestMessage.params, cancellationSource.token);
|
487 | }
|
488 | else {
|
489 | if (type !== undefined && type.parameterStructures === messages_1.ParameterStructures.byPosition) {
|
490 | replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InvalidParams, `Request ${requestMessage.method} defines parameters by position but received parameters by name`), requestMessage.method, startTime);
|
491 | return;
|
492 | }
|
493 | handlerResult = requestHandler(requestMessage.params, cancellationSource.token);
|
494 | }
|
495 | }
|
496 | else if (starRequestHandler) {
|
497 | handlerResult = starRequestHandler(requestMessage.method, requestMessage.params, cancellationSource.token);
|
498 | }
|
499 | const promise = handlerResult;
|
500 | if (!handlerResult) {
|
501 | requestTokens.delete(tokenKey);
|
502 | replySuccess(handlerResult, requestMessage.method, startTime);
|
503 | }
|
504 | else if (promise.then) {
|
505 | promise.then((resultOrError) => {
|
506 | requestTokens.delete(tokenKey);
|
507 | reply(resultOrError, requestMessage.method, startTime);
|
508 | }, error => {
|
509 | requestTokens.delete(tokenKey);
|
510 | if (error instanceof messages_1.ResponseError) {
|
511 | replyError(error, requestMessage.method, startTime);
|
512 | }
|
513 | else if (error && Is.string(error.message)) {
|
514 | replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime);
|
515 | }
|
516 | else {
|
517 | replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime);
|
518 | }
|
519 | });
|
520 | }
|
521 | else {
|
522 | requestTokens.delete(tokenKey);
|
523 | reply(handlerResult, requestMessage.method, startTime);
|
524 | }
|
525 | }
|
526 | catch (error) {
|
527 | requestTokens.delete(tokenKey);
|
528 | if (error instanceof messages_1.ResponseError) {
|
529 | reply(error, requestMessage.method, startTime);
|
530 | }
|
531 | else if (error && Is.string(error.message)) {
|
532 | replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime);
|
533 | }
|
534 | else {
|
535 | replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime);
|
536 | }
|
537 | }
|
538 | }
|
539 | else {
|
540 | replyError(new messages_1.ResponseError(messages_1.ErrorCodes.MethodNotFound, `Unhandled method ${requestMessage.method}`), requestMessage.method, startTime);
|
541 | }
|
542 | }
|
543 | function handleResponse(responseMessage) {
|
544 | if (isDisposed()) {
|
545 |
|
546 | return;
|
547 | }
|
548 | if (responseMessage.id === null) {
|
549 | if (responseMessage.error) {
|
550 | logger.error(`Received response message without id: Error is: \n${JSON.stringify(responseMessage.error, undefined, 4)}`);
|
551 | }
|
552 | else {
|
553 | logger.error(`Received response message without id. No further error information provided.`);
|
554 | }
|
555 | }
|
556 | else {
|
557 | const key = responseMessage.id;
|
558 | const responsePromise = responsePromises.get(key);
|
559 | traceReceivedResponse(responseMessage, responsePromise);
|
560 | if (responsePromise !== undefined) {
|
561 | responsePromises.delete(key);
|
562 | try {
|
563 | if (responseMessage.error) {
|
564 | const error = responseMessage.error;
|
565 | responsePromise.reject(new messages_1.ResponseError(error.code, error.message, error.data));
|
566 | }
|
567 | else if (responseMessage.result !== undefined) {
|
568 | responsePromise.resolve(responseMessage.result);
|
569 | }
|
570 | else {
|
571 | throw new Error('Should never happen.');
|
572 | }
|
573 | }
|
574 | catch (error) {
|
575 | if (error.message) {
|
576 | logger.error(`Response handler '${responsePromise.method}' failed with message: ${error.message}`);
|
577 | }
|
578 | else {
|
579 | logger.error(`Response handler '${responsePromise.method}' failed unexpectedly.`);
|
580 | }
|
581 | }
|
582 | }
|
583 | }
|
584 | }
|
585 | function handleNotification(message) {
|
586 | if (isDisposed()) {
|
587 |
|
588 | return;
|
589 | }
|
590 | let type = undefined;
|
591 | let notificationHandler;
|
592 | if (message.method === CancelNotification.type.method) {
|
593 | const cancelId = message.params.id;
|
594 | knownCanceledRequests.delete(cancelId);
|
595 | traceReceivedNotification(message);
|
596 | return;
|
597 | }
|
598 | else {
|
599 | const element = notificationHandlers.get(message.method);
|
600 | if (element) {
|
601 | notificationHandler = element.handler;
|
602 | type = element.type;
|
603 | }
|
604 | }
|
605 | if (notificationHandler || starNotificationHandler) {
|
606 | try {
|
607 | traceReceivedNotification(message);
|
608 | if (notificationHandler) {
|
609 | if (message.params === undefined) {
|
610 | if (type !== undefined) {
|
611 | if (type.numberOfParams !== 0 && type.parameterStructures !== messages_1.ParameterStructures.byName) {
|
612 | logger.error(`Notification ${message.method} defines ${type.numberOfParams} params but received none.`);
|
613 | }
|
614 | }
|
615 | notificationHandler();
|
616 | }
|
617 | else if (Array.isArray(message.params)) {
|
618 |
|
619 |
|
620 | const params = message.params;
|
621 | if (message.method === ProgressNotification.type.method && params.length === 2 && ProgressToken.is(params[0])) {
|
622 | notificationHandler({ token: params[0], value: params[1] });
|
623 | }
|
624 | else {
|
625 | if (type !== undefined) {
|
626 | if (type.parameterStructures === messages_1.ParameterStructures.byName) {
|
627 | logger.error(`Notification ${message.method} defines parameters by name but received parameters by position`);
|
628 | }
|
629 | if (type.numberOfParams !== message.params.length) {
|
630 | logger.error(`Notification ${message.method} defines ${type.numberOfParams} params but received ${params.length} arguments`);
|
631 | }
|
632 | }
|
633 | notificationHandler(...params);
|
634 | }
|
635 | }
|
636 | else {
|
637 | if (type !== undefined && type.parameterStructures === messages_1.ParameterStructures.byPosition) {
|
638 | logger.error(`Notification ${message.method} defines parameters by position but received parameters by name`);
|
639 | }
|
640 | notificationHandler(message.params);
|
641 | }
|
642 | }
|
643 | else if (starNotificationHandler) {
|
644 | starNotificationHandler(message.method, message.params);
|
645 | }
|
646 | }
|
647 | catch (error) {
|
648 | if (error.message) {
|
649 | logger.error(`Notification handler '${message.method}' failed with message: ${error.message}`);
|
650 | }
|
651 | else {
|
652 | logger.error(`Notification handler '${message.method}' failed unexpectedly.`);
|
653 | }
|
654 | }
|
655 | }
|
656 | else {
|
657 | unhandledNotificationEmitter.fire(message);
|
658 | }
|
659 | }
|
660 | function handleInvalidMessage(message) {
|
661 | if (!message) {
|
662 | logger.error('Received empty message.');
|
663 | return;
|
664 | }
|
665 | logger.error(`Received message which is neither a response nor a notification message:\n${JSON.stringify(message, null, 4)}`);
|
666 |
|
667 | const responseMessage = message;
|
668 | if (Is.string(responseMessage.id) || Is.number(responseMessage.id)) {
|
669 | const key = responseMessage.id;
|
670 | const responseHandler = responsePromises.get(key);
|
671 | if (responseHandler) {
|
672 | responseHandler.reject(new Error('The received response has neither a result nor an error property.'));
|
673 | }
|
674 | }
|
675 | }
|
676 | function stringifyTrace(params) {
|
677 | if (params === undefined || params === null) {
|
678 | return undefined;
|
679 | }
|
680 | switch (trace) {
|
681 | case Trace.Verbose:
|
682 | return JSON.stringify(params, null, 4);
|
683 | case Trace.Compact:
|
684 | return JSON.stringify(params);
|
685 | default:
|
686 | return undefined;
|
687 | }
|
688 | }
|
689 | function traceSendingRequest(message) {
|
690 | if (trace === Trace.Off || !tracer) {
|
691 | return;
|
692 | }
|
693 | if (traceFormat === TraceFormat.Text) {
|
694 | let data = undefined;
|
695 | if ((trace === Trace.Verbose || trace === Trace.Compact) && message.params) {
|
696 | data = `Params: ${stringifyTrace(message.params)}\n\n`;
|
697 | }
|
698 | tracer.log(`Sending request '${message.method} - (${message.id})'.`, data);
|
699 | }
|
700 | else {
|
701 | logLSPMessage('send-request', message);
|
702 | }
|
703 | }
|
704 | function traceSendingNotification(message) {
|
705 | if (trace === Trace.Off || !tracer) {
|
706 | return;
|
707 | }
|
708 | if (traceFormat === TraceFormat.Text) {
|
709 | let data = undefined;
|
710 | if (trace === Trace.Verbose || trace === Trace.Compact) {
|
711 | if (message.params) {
|
712 | data = `Params: ${stringifyTrace(message.params)}\n\n`;
|
713 | }
|
714 | else {
|
715 | data = 'No parameters provided.\n\n';
|
716 | }
|
717 | }
|
718 | tracer.log(`Sending notification '${message.method}'.`, data);
|
719 | }
|
720 | else {
|
721 | logLSPMessage('send-notification', message);
|
722 | }
|
723 | }
|
724 | function traceSendingResponse(message, method, startTime) {
|
725 | if (trace === Trace.Off || !tracer) {
|
726 | return;
|
727 | }
|
728 | if (traceFormat === TraceFormat.Text) {
|
729 | let data = undefined;
|
730 | if (trace === Trace.Verbose || trace === Trace.Compact) {
|
731 | if (message.error && message.error.data) {
|
732 | data = `Error data: ${stringifyTrace(message.error.data)}\n\n`;
|
733 | }
|
734 | else {
|
735 | if (message.result) {
|
736 | data = `Result: ${stringifyTrace(message.result)}\n\n`;
|
737 | }
|
738 | else if (message.error === undefined) {
|
739 | data = 'No result returned.\n\n';
|
740 | }
|
741 | }
|
742 | }
|
743 | tracer.log(`Sending response '${method} - (${message.id})'. Processing request took ${Date.now() - startTime}ms`, data);
|
744 | }
|
745 | else {
|
746 | logLSPMessage('send-response', message);
|
747 | }
|
748 | }
|
749 | function traceReceivedRequest(message) {
|
750 | if (trace === Trace.Off || !tracer) {
|
751 | return;
|
752 | }
|
753 | if (traceFormat === TraceFormat.Text) {
|
754 | let data = undefined;
|
755 | if ((trace === Trace.Verbose || trace === Trace.Compact) && message.params) {
|
756 | data = `Params: ${stringifyTrace(message.params)}\n\n`;
|
757 | }
|
758 | tracer.log(`Received request '${message.method} - (${message.id})'.`, data);
|
759 | }
|
760 | else {
|
761 | logLSPMessage('receive-request', message);
|
762 | }
|
763 | }
|
764 | function traceReceivedNotification(message) {
|
765 | if (trace === Trace.Off || !tracer || message.method === LogTraceNotification.type.method) {
|
766 | return;
|
767 | }
|
768 | if (traceFormat === TraceFormat.Text) {
|
769 | let data = undefined;
|
770 | if (trace === Trace.Verbose || trace === Trace.Compact) {
|
771 | if (message.params) {
|
772 | data = `Params: ${stringifyTrace(message.params)}\n\n`;
|
773 | }
|
774 | else {
|
775 | data = 'No parameters provided.\n\n';
|
776 | }
|
777 | }
|
778 | tracer.log(`Received notification '${message.method}'.`, data);
|
779 | }
|
780 | else {
|
781 | logLSPMessage('receive-notification', message);
|
782 | }
|
783 | }
|
784 | function traceReceivedResponse(message, responsePromise) {
|
785 | if (trace === Trace.Off || !tracer) {
|
786 | return;
|
787 | }
|
788 | if (traceFormat === TraceFormat.Text) {
|
789 | let data = undefined;
|
790 | if (trace === Trace.Verbose || trace === Trace.Compact) {
|
791 | if (message.error && message.error.data) {
|
792 | data = `Error data: ${stringifyTrace(message.error.data)}\n\n`;
|
793 | }
|
794 | else {
|
795 | if (message.result) {
|
796 | data = `Result: ${stringifyTrace(message.result)}\n\n`;
|
797 | }
|
798 | else if (message.error === undefined) {
|
799 | data = 'No result returned.\n\n';
|
800 | }
|
801 | }
|
802 | }
|
803 | if (responsePromise) {
|
804 | const error = message.error ? ` Request failed: ${message.error.message} (${message.error.code}).` : '';
|
805 | tracer.log(`Received response '${responsePromise.method} - (${message.id})' in ${Date.now() - responsePromise.timerStart}ms.${error}`, data);
|
806 | }
|
807 | else {
|
808 | tracer.log(`Received response ${message.id} without active response promise.`, data);
|
809 | }
|
810 | }
|
811 | else {
|
812 | logLSPMessage('receive-response', message);
|
813 | }
|
814 | }
|
815 | function logLSPMessage(type, message) {
|
816 | if (!tracer || trace === Trace.Off) {
|
817 | return;
|
818 | }
|
819 | const lspMessage = {
|
820 | isLSPMessage: true,
|
821 | type,
|
822 | message,
|
823 | timestamp: Date.now()
|
824 | };
|
825 | tracer.log(lspMessage);
|
826 | }
|
827 | function throwIfClosedOrDisposed() {
|
828 | if (isClosed()) {
|
829 | throw new ConnectionError(ConnectionErrors.Closed, 'Connection is closed.');
|
830 | }
|
831 | if (isDisposed()) {
|
832 | throw new ConnectionError(ConnectionErrors.Disposed, 'Connection is disposed.');
|
833 | }
|
834 | }
|
835 | function throwIfListening() {
|
836 | if (isListening()) {
|
837 | throw new ConnectionError(ConnectionErrors.AlreadyListening, 'Connection is already listening');
|
838 | }
|
839 | }
|
840 | function throwIfNotListening() {
|
841 | if (!isListening()) {
|
842 | throw new Error('Call listen() first.');
|
843 | }
|
844 | }
|
845 | function undefinedToNull(param) {
|
846 | if (param === undefined) {
|
847 | return null;
|
848 | }
|
849 | else {
|
850 | return param;
|
851 | }
|
852 | }
|
853 | function nullToUndefined(param) {
|
854 | if (param === null) {
|
855 | return undefined;
|
856 | }
|
857 | else {
|
858 | return param;
|
859 | }
|
860 | }
|
861 | function isNamedParam(param) {
|
862 | return param !== undefined && param !== null && !Array.isArray(param) && typeof param === 'object';
|
863 | }
|
864 | function computeSingleParam(parameterStructures, param) {
|
865 | switch (parameterStructures) {
|
866 | case messages_1.ParameterStructures.auto:
|
867 | if (isNamedParam(param)) {
|
868 | return nullToUndefined(param);
|
869 | }
|
870 | else {
|
871 | return [undefinedToNull(param)];
|
872 | }
|
873 | case messages_1.ParameterStructures.byName:
|
874 | if (!isNamedParam(param)) {
|
875 | throw new Error(`Received parameters by name but param is not an object literal.`);
|
876 | }
|
877 | return nullToUndefined(param);
|
878 | case messages_1.ParameterStructures.byPosition:
|
879 | return [undefinedToNull(param)];
|
880 | default:
|
881 | throw new Error(`Unknown parameter structure ${parameterStructures.toString()}`);
|
882 | }
|
883 | }
|
884 | function computeMessageParams(type, params) {
|
885 | let result;
|
886 | const numberOfParams = type.numberOfParams;
|
887 | switch (numberOfParams) {
|
888 | case 0:
|
889 | result = undefined;
|
890 | break;
|
891 | case 1:
|
892 | result = computeSingleParam(type.parameterStructures, params[0]);
|
893 | break;
|
894 | default:
|
895 | result = [];
|
896 | for (let i = 0; i < params.length && i < numberOfParams; i++) {
|
897 | result.push(undefinedToNull(params[i]));
|
898 | }
|
899 | if (params.length < numberOfParams) {
|
900 | for (let i = params.length; i < numberOfParams; i++) {
|
901 | result.push(null);
|
902 | }
|
903 | }
|
904 | break;
|
905 | }
|
906 | return result;
|
907 | }
|
908 | const connection = {
|
909 | sendNotification: (type, ...args) => {
|
910 | throwIfClosedOrDisposed();
|
911 | let method;
|
912 | let messageParams;
|
913 | if (Is.string(type)) {
|
914 | method = type;
|
915 | const first = args[0];
|
916 | let paramStart = 0;
|
917 | let parameterStructures = messages_1.ParameterStructures.auto;
|
918 | if (messages_1.ParameterStructures.is(first)) {
|
919 | paramStart = 1;
|
920 | parameterStructures = first;
|
921 | }
|
922 | let paramEnd = args.length;
|
923 | const numberOfParams = paramEnd - paramStart;
|
924 | switch (numberOfParams) {
|
925 | case 0:
|
926 | messageParams = undefined;
|
927 | break;
|
928 | case 1:
|
929 | messageParams = computeSingleParam(parameterStructures, args[paramStart]);
|
930 | break;
|
931 | default:
|
932 | if (parameterStructures === messages_1.ParameterStructures.byName) {
|
933 | throw new Error(`Received ${numberOfParams} parameters for 'by Name' notification parameter structure.`);
|
934 | }
|
935 | messageParams = args.slice(paramStart, paramEnd).map(value => undefinedToNull(value));
|
936 | break;
|
937 | }
|
938 | }
|
939 | else {
|
940 | const params = args;
|
941 | method = type.method;
|
942 | messageParams = computeMessageParams(type, params);
|
943 | }
|
944 | const notificationMessage = {
|
945 | jsonrpc: version,
|
946 | method: method,
|
947 | params: messageParams
|
948 | };
|
949 | traceSendingNotification(notificationMessage);
|
950 | return messageWriter.write(notificationMessage).catch((error) => {
|
951 | logger.error(`Sending notification failed.`);
|
952 | throw error;
|
953 | });
|
954 | },
|
955 | onNotification: (type, handler) => {
|
956 | throwIfClosedOrDisposed();
|
957 | let method;
|
958 | if (Is.func(type)) {
|
959 | starNotificationHandler = type;
|
960 | }
|
961 | else if (handler) {
|
962 | if (Is.string(type)) {
|
963 | method = type;
|
964 | notificationHandlers.set(type, { type: undefined, handler });
|
965 | }
|
966 | else {
|
967 | method = type.method;
|
968 | notificationHandlers.set(type.method, { type, handler });
|
969 | }
|
970 | }
|
971 | return {
|
972 | dispose: () => {
|
973 | if (method !== undefined) {
|
974 | notificationHandlers.delete(method);
|
975 | }
|
976 | else {
|
977 | starNotificationHandler = undefined;
|
978 | }
|
979 | }
|
980 | };
|
981 | },
|
982 | onProgress: (_type, token, handler) => {
|
983 | if (progressHandlers.has(token)) {
|
984 | throw new Error(`Progress handler for token ${token} already registered`);
|
985 | }
|
986 | progressHandlers.set(token, handler);
|
987 | return {
|
988 | dispose: () => {
|
989 | progressHandlers.delete(token);
|
990 | }
|
991 | };
|
992 | },
|
993 | sendProgress: (_type, token, value) => {
|
994 |
|
995 |
|
996 | return connection.sendNotification(ProgressNotification.type, { token, value });
|
997 | },
|
998 | onUnhandledProgress: unhandledProgressEmitter.event,
|
999 | sendRequest: (type, ...args) => {
|
1000 | throwIfClosedOrDisposed();
|
1001 | throwIfNotListening();
|
1002 | let method;
|
1003 | let messageParams;
|
1004 | let token = undefined;
|
1005 | if (Is.string(type)) {
|
1006 | method = type;
|
1007 | const first = args[0];
|
1008 | const last = args[args.length - 1];
|
1009 | let paramStart = 0;
|
1010 | let parameterStructures = messages_1.ParameterStructures.auto;
|
1011 | if (messages_1.ParameterStructures.is(first)) {
|
1012 | paramStart = 1;
|
1013 | parameterStructures = first;
|
1014 | }
|
1015 | let paramEnd = args.length;
|
1016 | if (cancellation_1.CancellationToken.is(last)) {
|
1017 | paramEnd = paramEnd - 1;
|
1018 | token = last;
|
1019 | }
|
1020 | const numberOfParams = paramEnd - paramStart;
|
1021 | switch (numberOfParams) {
|
1022 | case 0:
|
1023 | messageParams = undefined;
|
1024 | break;
|
1025 | case 1:
|
1026 | messageParams = computeSingleParam(parameterStructures, args[paramStart]);
|
1027 | break;
|
1028 | default:
|
1029 | if (parameterStructures === messages_1.ParameterStructures.byName) {
|
1030 | throw new Error(`Received ${numberOfParams} parameters for 'by Name' request parameter structure.`);
|
1031 | }
|
1032 | messageParams = args.slice(paramStart, paramEnd).map(value => undefinedToNull(value));
|
1033 | break;
|
1034 | }
|
1035 | }
|
1036 | else {
|
1037 | const params = args;
|
1038 | method = type.method;
|
1039 | messageParams = computeMessageParams(type, params);
|
1040 | const numberOfParams = type.numberOfParams;
|
1041 | token = cancellation_1.CancellationToken.is(params[numberOfParams]) ? params[numberOfParams] : undefined;
|
1042 | }
|
1043 | const id = sequenceNumber++;
|
1044 | let disposable;
|
1045 | if (token) {
|
1046 | disposable = token.onCancellationRequested(() => {
|
1047 | const p = cancellationStrategy.sender.sendCancellation(connection, id);
|
1048 | if (p === undefined) {
|
1049 | logger.log(`Received no promise from cancellation strategy when cancelling id ${id}`);
|
1050 | return Promise.resolve();
|
1051 | }
|
1052 | else {
|
1053 | return p.catch(() => {
|
1054 | logger.log(`Sending cancellation messages for id ${id} failed`);
|
1055 | });
|
1056 | }
|
1057 | });
|
1058 | }
|
1059 | const requestMessage = {
|
1060 | jsonrpc: version,
|
1061 | id: id,
|
1062 | method: method,
|
1063 | params: messageParams
|
1064 | };
|
1065 | traceSendingRequest(requestMessage);
|
1066 | if (typeof cancellationStrategy.sender.enableCancellation === 'function') {
|
1067 | cancellationStrategy.sender.enableCancellation(requestMessage);
|
1068 | }
|
1069 | return new Promise(async (resolve, reject) => {
|
1070 | const resolveWithCleanup = (r) => {
|
1071 | resolve(r);
|
1072 | cancellationStrategy.sender.cleanup(id);
|
1073 | disposable?.dispose();
|
1074 | };
|
1075 | const rejectWithCleanup = (r) => {
|
1076 | reject(r);
|
1077 | cancellationStrategy.sender.cleanup(id);
|
1078 | disposable?.dispose();
|
1079 | };
|
1080 | const responsePromise = { method: method, timerStart: Date.now(), resolve: resolveWithCleanup, reject: rejectWithCleanup };
|
1081 | try {
|
1082 | responsePromises.set(id, responsePromise);
|
1083 | await messageWriter.write(requestMessage);
|
1084 | }
|
1085 | catch (error) {
|
1086 |
|
1087 |
|
1088 | responsePromises.delete(id);
|
1089 | responsePromise.reject(new messages_1.ResponseError(messages_1.ErrorCodes.MessageWriteError, error.message ? error.message : 'Unknown reason'));
|
1090 | logger.error(`Sending request failed.`);
|
1091 | throw error;
|
1092 | }
|
1093 | });
|
1094 | },
|
1095 | onRequest: (type, handler) => {
|
1096 | throwIfClosedOrDisposed();
|
1097 | let method = null;
|
1098 | if (StarRequestHandler.is(type)) {
|
1099 | method = undefined;
|
1100 | starRequestHandler = type;
|
1101 | }
|
1102 | else if (Is.string(type)) {
|
1103 | method = null;
|
1104 | if (handler !== undefined) {
|
1105 | method = type;
|
1106 | requestHandlers.set(type, { handler: handler, type: undefined });
|
1107 | }
|
1108 | }
|
1109 | else {
|
1110 | if (handler !== undefined) {
|
1111 | method = type.method;
|
1112 | requestHandlers.set(type.method, { type, handler });
|
1113 | }
|
1114 | }
|
1115 | return {
|
1116 | dispose: () => {
|
1117 | if (method === null) {
|
1118 | return;
|
1119 | }
|
1120 | if (method !== undefined) {
|
1121 | requestHandlers.delete(method);
|
1122 | }
|
1123 | else {
|
1124 | starRequestHandler = undefined;
|
1125 | }
|
1126 | }
|
1127 | };
|
1128 | },
|
1129 | hasPendingResponse: () => {
|
1130 | return responsePromises.size > 0;
|
1131 | },
|
1132 | trace: async (_value, _tracer, sendNotificationOrTraceOptions) => {
|
1133 | let _sendNotification = false;
|
1134 | let _traceFormat = TraceFormat.Text;
|
1135 | if (sendNotificationOrTraceOptions !== undefined) {
|
1136 | if (Is.boolean(sendNotificationOrTraceOptions)) {
|
1137 | _sendNotification = sendNotificationOrTraceOptions;
|
1138 | }
|
1139 | else {
|
1140 | _sendNotification = sendNotificationOrTraceOptions.sendNotification || false;
|
1141 | _traceFormat = sendNotificationOrTraceOptions.traceFormat || TraceFormat.Text;
|
1142 | }
|
1143 | }
|
1144 | trace = _value;
|
1145 | traceFormat = _traceFormat;
|
1146 | if (trace === Trace.Off) {
|
1147 | tracer = undefined;
|
1148 | }
|
1149 | else {
|
1150 | tracer = _tracer;
|
1151 | }
|
1152 | if (_sendNotification && !isClosed() && !isDisposed()) {
|
1153 | await connection.sendNotification(SetTraceNotification.type, { value: Trace.toString(_value) });
|
1154 | }
|
1155 | },
|
1156 | onError: errorEmitter.event,
|
1157 | onClose: closeEmitter.event,
|
1158 | onUnhandledNotification: unhandledNotificationEmitter.event,
|
1159 | onDispose: disposeEmitter.event,
|
1160 | end: () => {
|
1161 | messageWriter.end();
|
1162 | },
|
1163 | dispose: () => {
|
1164 | if (isDisposed()) {
|
1165 | return;
|
1166 | }
|
1167 | state = ConnectionState.Disposed;
|
1168 | disposeEmitter.fire(undefined);
|
1169 | const error = new messages_1.ResponseError(messages_1.ErrorCodes.PendingResponseRejected, 'Pending response rejected since connection got disposed');
|
1170 | for (const promise of responsePromises.values()) {
|
1171 | promise.reject(error);
|
1172 | }
|
1173 | responsePromises = new Map();
|
1174 | requestTokens = new Map();
|
1175 | knownCanceledRequests = new Set();
|
1176 | messageQueue = new linkedMap_1.LinkedMap();
|
1177 |
|
1178 | if (Is.func(messageWriter.dispose)) {
|
1179 | messageWriter.dispose();
|
1180 | }
|
1181 | if (Is.func(messageReader.dispose)) {
|
1182 | messageReader.dispose();
|
1183 | }
|
1184 | },
|
1185 | listen: () => {
|
1186 | throwIfClosedOrDisposed();
|
1187 | throwIfListening();
|
1188 | state = ConnectionState.Listening;
|
1189 | messageReader.listen(callback);
|
1190 | },
|
1191 | inspect: () => {
|
1192 |
|
1193 | (0, ral_1.default)().console.log('inspect');
|
1194 | }
|
1195 | };
|
1196 | connection.onNotification(LogTraceNotification.type, (params) => {
|
1197 | if (trace === Trace.Off || !tracer) {
|
1198 | return;
|
1199 | }
|
1200 | const verbose = trace === Trace.Verbose || trace === Trace.Compact;
|
1201 | tracer.log(params.message, verbose ? params.verbose : undefined);
|
1202 | });
|
1203 | connection.onNotification(ProgressNotification.type, (params) => {
|
1204 | const handler = progressHandlers.get(params.token);
|
1205 | if (handler) {
|
1206 | handler(params.value);
|
1207 | }
|
1208 | else {
|
1209 | unhandledProgressEmitter.fire(params);
|
1210 | }
|
1211 | });
|
1212 | return connection;
|
1213 | }
|
1214 | exports.createMessageConnection = createMessageConnection;
|