diff options
Diffstat (limited to 'language-web/src/main/js/xtext/XtextClient.ts')
-rw-r--r-- | language-web/src/main/js/xtext/XtextClient.ts | 83 |
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 @@ | |||
1 | import type { | ||
2 | CompletionContext, | ||
3 | CompletionResult, | ||
4 | } from '@codemirror/autocomplete'; | ||
5 | import type { Transaction } from '@codemirror/state'; | ||
6 | |||
7 | import type { EditorStore } from '../editor/EditorStore'; | ||
8 | import { ContentAssistService } from './ContentAssistService'; | ||
9 | import { HighlightingService } from './HighlightingService'; | ||
10 | import { OccurrencesService } from './OccurrencesService'; | ||
11 | import { UpdateService } from './UpdateService'; | ||
12 | import { getLogger } from '../utils/logger'; | ||
13 | import { ValidationService } from './ValidationService'; | ||
14 | import { XtextWebSocketClient } from './XtextWebSocketClient'; | ||
15 | |||
16 | const log = getLogger('xtext.XtextClient'); | ||
17 | |||
18 | export 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 | } | ||