extensions/html-language-features/server/src/modes/semanticTokens.ts/newSemanticTokenProvider
export function newSemanticTokenProvider(languageModes: LanguageModes): SemanticTokenProvider {

	// combined legend across modes
	const legend: { types: string[], modifiers: string[] } = { types: [], modifiers: [] };
	const legendMappings: { [modeId: string]: LegendMapping } = {};

	for (let mode of languageModes.getAllModes()) {
		if (mode.getSemanticTokenLegend && mode.getSemanticTokens) {
			const modeLegend = mode.getSemanticTokenLegend();
			legendMappings[mode.getId()] = { types: createMapping(modeLegend.types, legend.types), modifiers: createMapping(modeLegend.modifiers, legend.modifiers) };
		}
	}

	return {
		legend,
		async getSemanticTokens(document: TextDocument, ranges?: Range[]): Promise<number[]> {
			const allTokens: SemanticTokenData[] = [];
			for (let mode of languageModes.getAllModesInDocument(document)) {
				if (mode.getSemanticTokens) {
					const mapping = legendMappings[mode.getId()];
					const tokens = await mode.getSemanticTokens(document);
					applyTypesMapping(tokens, mapping.types);
					applyModifiersMapping(tokens, mapping.modifiers);
					for (let token of tokens) {
						allTokens.push(token);
					}
				}
			}
			return encodeTokens(allTokens, ranges, document);
		}
	};
}