protected registerLanguageProvider()

in client/src/common/semanticTokens.ts [126:220]


	protected registerLanguageProvider(options: SemanticTokensRegistrationOptions): [vscode.Disposable, SemanticTokensProviders] {
		const selector = options.documentSelector!;
		const fullProvider = Is.boolean(options.full) ? options.full : options.full !== undefined;
		const hasEditProvider = options.full !== undefined && typeof options.full !== 'boolean' && options.full.delta === true;
		const eventEmitter: vscode.EventEmitter<void> = new vscode.EventEmitter<void>();
		const documentProvider: vscode.DocumentSemanticTokensProvider | undefined = fullProvider
			? {
				onDidChangeSemanticTokens: eventEmitter.event,
				provideDocumentSemanticTokens: (document, token) => {
					if ($DocumentSelector.skipCellTextDocument(selector, document)) {
						return undefined;
					}
					const client = this._client;
					const middleware = client.clientOptions.middleware! as Middleware & SemanticTokensMiddleware;
					const provideDocumentSemanticTokens: DocumentSemanticsTokensSignature = (document, token) => {
						const params: SemanticTokensParams =  {
							textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
						};
						return client.sendRequest(SemanticTokensRequest.type, params, token).then((result) => {
							return client.protocol2CodeConverter.asSemanticTokens(result);
						}, (error: any) => {
							return client.handleFailedRequest(SemanticTokensRequest.type, token, error, null);
						});
					};
					return middleware.provideDocumentSemanticTokens
						? middleware.provideDocumentSemanticTokens(document, token, provideDocumentSemanticTokens)
						: provideDocumentSemanticTokens(document, token);
				},
				provideDocumentSemanticTokensEdits: hasEditProvider
					? (document, previousResultId, token) => {
						if ($DocumentSelector.skipCellTextDocument(selector, document)) {
							return undefined;
						}
						const client = this._client;
						const middleware = client.clientOptions.middleware! as Middleware & SemanticTokensMiddleware;
						const provideDocumentSemanticTokensEdits: DocumentSemanticsTokensEditsSignature = (document, previousResultId, token) => {
							const params: SemanticTokensDeltaParams =  {
								textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
								previousResultId
							};
							return client.sendRequest(SemanticTokensDeltaRequest.type, params, token).then((result) => {
								if (SemanticTokens.is(result)) {
									return client.protocol2CodeConverter.asSemanticTokens(result);
								} else {
									return client.protocol2CodeConverter.asSemanticTokensEdits(result);
								}
							}, (error: any) => {
								return client.handleFailedRequest(SemanticTokensDeltaRequest.type, token, error, null);
							});
						};
						return middleware.provideDocumentSemanticTokensEdits
							? middleware.provideDocumentSemanticTokensEdits(document, previousResultId, token, provideDocumentSemanticTokensEdits)
							: provideDocumentSemanticTokensEdits(document, previousResultId, token);
					}
					: undefined
			}
			: undefined;

		const hasRangeProvider: boolean = options.range === true;
		const rangeProvider: vscode.DocumentRangeSemanticTokensProvider | undefined = hasRangeProvider
			? {
				provideDocumentRangeSemanticTokens: (document: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken) => {
					const client = this._client;
					const middleware = client.clientOptions.middleware! as Middleware & SemanticTokensMiddleware;
					const provideDocumentRangeSemanticTokens: DocumentRangeSemanticTokensSignature = (document, range, token) => {
						const params: SemanticTokensRangeParams = {
							textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
							range: client.code2ProtocolConverter.asRange(range)
						};
						return client.sendRequest(SemanticTokensRangeRequest.type, params, token).then((result) => {
							return client.protocol2CodeConverter.asSemanticTokens(result);
						}, (error: any) => {
							return client.handleFailedRequest(SemanticTokensRangeRequest.type, token, error, null);
						});
					};
					return middleware.provideDocumentRangeSemanticTokens
						? middleware.provideDocumentRangeSemanticTokens(document, range, token, provideDocumentRangeSemanticTokens)
						: provideDocumentRangeSemanticTokens(document, range, token);
				}
			}
			: undefined;

		const disposables: vscode.Disposable[] = [];
		const client = this._client;
		const legend: vscode.SemanticTokensLegend = client.protocol2CodeConverter.asSemanticTokensLegend(options.legend);
		const textDocumentSelectors = $DocumentSelector.asTextDocumentFilters(selector);
		if (documentProvider !== undefined) {
			disposables.push(vscode.languages.registerDocumentSemanticTokensProvider(textDocumentSelectors, documentProvider, legend));
		}
		if (rangeProvider !== undefined) {
			disposables.push(vscode.languages.registerDocumentRangeSemanticTokensProvider(textDocumentSelectors, rangeProvider, legend));
		}

		return [new vscode.Disposable(() => disposables.forEach(item => item.dispose())), { range: rangeProvider, full: documentProvider, onDidChangeSemanticTokensEmitter: eventEmitter }];
	}