src/vs/workbench/api/common/extHostLanguageFeatures.ts/LinkProviderAdapter/provideLinks
class LinkProviderAdapter:	async provideLinks(resource: URI, token: CancellationToken): Promise<extHostProtocol.ILinksListDto | undefined> {
		const doc = this._documents.getDocument(resource);

		const links = await asPromise(() => this._provider.provideDocumentLinks(doc, token));
		if (!Array.isArray(links) || links.length === 0) {
			// bad result
			return undefined;
		}
		if (token.isCancellationRequested) {
			// cancelled -> return without further ado, esp no caching
			// of results as they will leak
			return undefined;
		}
		if (typeof this._provider.resolveDocumentLink !== 'function') {
			// no resolve -> no caching
			return { links: links.filter(LinkProviderAdapter._validateLink).map(typeConvert.DocumentLink.from) };

		} else {
			// cache links for future resolving
			const pid = this._cache.add(links);
			const result: extHostProtocol.ILinksListDto = { links: [], id: pid };
			for (let i = 0; i < links.length; i++) {

				if (!LinkProviderAdapter._validateLink(links[i])) {
					continue;
				}

				const dto: extHostProtocol.ILinkDto = typeConvert.DocumentLink.from(links[i]);
				dto.cacheId = [pid, i];
				result.links.push(dto);
			}
			return result;
		}
	}