aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src/main/js/xtext/XtextClient.ts
diff options
context:
space:
mode:
Diffstat (limited to 'language-web/src/main/js/xtext/XtextClient.ts')
-rw-r--r--language-web/src/main/js/xtext/XtextClient.ts83
1 files changed, 83 insertions, 0 deletions
diff --git a/language-web/src/main/js/xtext/XtextClient.ts b/language-web/src/main/js/xtext/XtextClient.ts
new file mode 100644
index 00000000..28f3d0cc
--- /dev/null
+++ b/language-web/src/main/js/xtext/XtextClient.ts
@@ -0,0 +1,83 @@
1import type {
2 CompletionContext,
3 CompletionResult,
4} from '@codemirror/autocomplete';
5import type { Transaction } from '@codemirror/state';
6
7import type { EditorStore } from '../editor/EditorStore';
8import { ContentAssistService } from './ContentAssistService';
9import { HighlightingService } from './HighlightingService';
10import { OccurrencesService } from './OccurrencesService';
11import { UpdateService } from './UpdateService';
12import { getLogger } from '../utils/logger';
13import { ValidationService } from './ValidationService';
14import { XtextWebSocketClient } from './XtextWebSocketClient';
15
16const log = getLogger('xtext.XtextClient');
17
18export class XtextClient {
19 private readonly webSocketClient: XtextWebSocketClient;
20
21 private readonly updateService: UpdateService;
22
23 private readonly contentAssistService: ContentAssistService;
24
25 private readonly highlightingService: HighlightingService;
26
27 private readonly validationService: ValidationService;
28
29 private readonly occurrencesService: OccurrencesService;
30
31 constructor(store: EditorStore) {
32 this.webSocketClient = new XtextWebSocketClient(
33 () => this.updateService.onReconnect(),
34 (resource, stateId, service, push) => this.onPush(resource, stateId, service, push),
35 );
36 this.updateService = new UpdateService(store, this.webSocketClient);
37 this.contentAssistService = new ContentAssistService(this.updateService);
38 this.highlightingService = new HighlightingService(store, this.updateService);
39 this.validationService = new ValidationService(store, this.updateService);
40 this.occurrencesService = new OccurrencesService(
41 store,
42 this.webSocketClient,
43 this.updateService,
44 );
45 }
46
47 onTransaction(transaction: Transaction): void {
48 // `ContentAssistService.prototype.onTransaction` needs the dirty change desc
49 // _before_ the current edit, so we call it before `updateService`.
50 this.contentAssistService.onTransaction(transaction);
51 this.updateService.onTransaction(transaction);
52 this.occurrencesService.onTransaction(transaction);
53 }
54
55 private onPush(resource: string, stateId: string, service: string, push: unknown) {
56 const { resourceName, xtextStateId } = this.updateService;
57 if (resource !== resourceName) {
58 log.error('Unknown resource name: expected:', resourceName, 'got:', resource);
59 return;
60 }
61 if (stateId !== xtextStateId) {
62 log.error('Unexpected xtext state id: expected:', xtextStateId, 'got:', stateId);
63 // The current push message might be stale (referring to a previous state),
64 // so this is not neccessarily an error and there is no need to force-reconnect.
65 return;
66 }
67 switch (service) {
68 case 'highlight':
69 this.highlightingService.onPush(push);
70 return;
71 case 'validate':
72 this.validationService.onPush(push);
73 return;
74 default:
75 log.error('Unknown push service:', service);
76 break;
77 }
78 }
79
80 contentAssist(context: CompletionContext): Promise<CompletionResult> {
81 return this.contentAssistService.contentAssist(context);
82 }
83}