-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathuser-worker.ts
70 lines (60 loc) · 2.66 KB
/
user-worker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { NotificationType } from 'vscode-languageserver/browser.js';
import { DocumentChange, createServerConnection } from './worker-utils.js';
import { LangiumServices, startLanguageServer } from 'langium/lsp';
import { DocumentState } from 'langium';
import { createServicesForGrammar } from 'langium/grammar';
import { PlaygroundValidator } from './user-validator.js';
// listen for messages to trigger starting the LS with a given grammar
addEventListener('message', async (event) => {
if (event.data.type && event.data.type === 'startWithGrammar') {
if (event.data.grammar === undefined) {
throw new Error('User worker was started without a grammar!');
}
await startWithGrammar(event.data.grammar as string);
}
});
const documentChangeNotification = new NotificationType<DocumentChange>('browser/DocumentChange');
/**
* Starts up a LS with a given grammar.
* Upon completion posts a message back to the main thread that it's done
*
* @param grammarText Grammar string to create an LS for
*/
async function startWithGrammar(grammarText: string): Promise<void> {
// create a fresh connection for the LS
const connection = createServerConnection();
// create shared services & serializer for the given grammar grammar
const { shared, serializer } = await createServicesForGrammar({
grammar: grammarText,
module: {
validation: {
DocumentValidator: (services: LangiumServices) => new PlaygroundValidator(services)
}
},
sharedModule: {
lsp: {
Connection: () => connection,
}
},
});
// listen for validated documents, and send the AST back to the language client
shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.Validated, documents => {
for (const document of documents) {
const json = serializer.JsonSerializer.serialize(document.parseResult.value);
connection.sendNotification(documentChangeNotification, {
uri: document.uri.toString(),
content: json,
diagnostics: document.diagnostics ?? []
});
}
});
// start the LS
startLanguageServer(shared);
// notify the main thread that the LS is ready
postMessage({ type: 'lsStartedWithGrammar' });
}