extensions/html-language-features/server/src/modes/htmlFolding.ts/getFoldingRanges
export async function getFoldingRanges(languageModes: LanguageModes, document: TextDocument, maxRanges: number | undefined, _cancellationToken: CancellationToken | null): Promise<FoldingRange[]> {
	const htmlMode = languageModes.getMode('html');
	const range = Range.create(Position.create(0, 0), Position.create(document.lineCount, 0));
	let result: FoldingRange[] = [];
	if (htmlMode && htmlMode.getFoldingRanges) {
		result.push(... await htmlMode.getFoldingRanges(document));
	}

	// cache folding ranges per mode
	const rangesPerMode: { [mode: string]: FoldingRange[] } = Object.create(null);
	const getRangesForMode = async (mode: LanguageMode) => {
		if (mode.getFoldingRanges) {
			let ranges = rangesPerMode[mode.getId()];
			if (!Array.isArray(ranges)) {
				ranges = await mode.getFoldingRanges(document) || [];
				rangesPerMode[mode.getId()] = ranges;
			}
			return ranges;
		}
		return [];
	};

	const modeRanges = languageModes.getModesInRange(document, range);
	for (const modeRange of modeRanges) {
		const mode = modeRange.mode;
		if (mode && mode !== htmlMode && !modeRange.attributeValue) {
			const ranges = await getRangesForMode(mode);
			result.push(...ranges.filter(r => r.startLine >= modeRange.start.line && r.endLine < modeRange.end.line));
		}
	}
	if (maxRanges && result.length > maxRanges) {
		result = limitRanges(result, maxRanges);
	}
	return result;
}