"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImplementationProviderImpl = void 0;
const documents_1 = require("../../../lib/documents");
const utils_1 = require("../../../utils");
const utils_2 = require("../utils");
const utils_3 = require("./utils");
class ImplementationProviderImpl {
    constructor(lsAndTsDocResolver) {
        this.lsAndTsDocResolver = lsAndTsDocResolver;
    }
    async getImplementation(document, position, cancellationToken) {
        const { tsDoc, lang, lsContainer } = await this.lsAndTsDocResolver.getLSAndTSDoc(document);
        if (cancellationToken?.isCancellationRequested) {
            return null;
        }
        const offset = tsDoc.offsetAt(tsDoc.getGeneratedPosition(position));
        const implementations = lang.getImplementationAtPosition(tsDoc.filePath, offset);
        const snapshots = new utils_3.SnapshotMap(this.lsAndTsDocResolver, lsContainer);
        snapshots.set(tsDoc.filePath, tsDoc);
        if (!implementations) {
            return null;
        }
        const result = await Promise.all(implementations.map(async (implementation) => {
            let snapshot = await snapshots.retrieve(implementation.fileName);
            // Go from generated $store to store if user wants to find implementation for $store
            if ((0, utils_3.isTextSpanInGeneratedCode)(snapshot.getFullText(), implementation.textSpan)) {
                if (!(0, utils_3.is$storeVariableIn$storeDeclaration)(snapshot.getFullText(), implementation.textSpan.start)) {
                    return;
                }
                // there will be exactly one definition, the store
                implementation = lang.getImplementationAtPosition(tsDoc.filePath, tsDoc.getFullText().indexOf(');', implementation.textSpan.start) - 1)[0];
                snapshot = await snapshots.retrieve(implementation.fileName);
            }
            if (cancellationToken?.isCancellationRequested) {
                return null;
            }
            const location = (0, documents_1.mapLocationToOriginal)(snapshot, (0, utils_2.convertRange)(snapshot, implementation.textSpan));
            if (location.range.start.line >= 0 && location.range.end.line >= 0) {
                return location;
            }
        }));
        return result.filter(utils_1.isNotNullOrUndefined);
    }
}
exports.ImplementationProviderImpl = ImplementationProviderImpl;
//# sourceMappingURL=ImplementationProvider.js.map