"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decorateLanguageService = exports.isPatched = void 0;
const utils_1 = require("../utils");
const call_hierarchy_1 = require("./call-hierarchy");
const completions_1 = require("./completions");
const definition_1 = require("./definition");
const diagnostics_1 = require("./diagnostics");
const find_references_1 = require("./find-references");
const hover_1 = require("./hover");
const implementation_1 = require("./implementation");
const inlay_hints_1 = require("./inlay-hints");
const rename_1 = require("./rename");
const update_imports_1 = require("./update-imports");
const host_1 = require("./host");
const sveltePluginPatchSymbol = Symbol('sveltePluginPatchSymbol');
function isPatched(ls) {
    return ls[sveltePluginPatchSymbol] === true;
}
exports.isPatched = isPatched;
function decorateLanguageService(ls, snapshotManager, logger, configManager, info, typescript) {
    // Decorate using a proxy so we can dynamically enable/disable method
    // patches depending on the enabled state of our config
    const proxy = new Proxy(ls, createProxyHandler(configManager));
    (0, host_1.decorateLanguageServiceHost)(info.languageServiceHost);
    decorateLanguageServiceInner(proxy, snapshotManager, logger, info, typescript);
    return proxy;
}
exports.decorateLanguageService = decorateLanguageService;
function decorateLanguageServiceInner(ls, snapshotManager, logger, info, typescript) {
    patchLineColumnOffset(ls, snapshotManager);
    (0, rename_1.decorateRename)(ls, snapshotManager, logger);
    (0, diagnostics_1.decorateDiagnostics)(ls, info, typescript, logger);
    (0, find_references_1.decorateFindReferences)(ls, snapshotManager, logger);
    (0, completions_1.decorateCompletions)(ls, info, typescript, logger);
    (0, definition_1.decorateGetDefinition)(ls, info, typescript, snapshotManager, logger);
    (0, implementation_1.decorateGetImplementation)(ls, snapshotManager, logger);
    (0, update_imports_1.decorateUpdateImports)(ls, snapshotManager, logger);
    (0, call_hierarchy_1.decorateCallHierarchy)(ls, snapshotManager, typescript);
    (0, hover_1.decorateHover)(ls, info, typescript, logger);
    (0, inlay_hints_1.decorateInlayHints)(ls, info, typescript, logger);
    return ls;
}
function createProxyHandler(configManager) {
    const decorated = {};
    return {
        get(target, p) {
            var _a;
            // always return patch symbol whether the plugin is enabled or not
            if (p === sveltePluginPatchSymbol) {
                return true;
            }
            if (!configManager.getConfig().enable || p === 'dispose') {
                return target[p];
            }
            return ((_a = decorated[p]) !== null && _a !== void 0 ? _a : target[p]);
        },
        set(_, p, value) {
            decorated[p] = value;
            return true;
        }
    };
}
function patchLineColumnOffset(ls, snapshotManager) {
    if (!ls.toLineColumnOffset) {
        return;
    }
    // We need to patch this because (according to source, only) getDefinition uses this
    const toLineColumnOffset = ls.toLineColumnOffset;
    ls.toLineColumnOffset = (fileName, position) => {
        if ((0, utils_1.isSvelteFilePath)(fileName)) {
            const snapshot = snapshotManager.get(fileName);
            if (snapshot) {
                return snapshot.positionAt(position);
            }
        }
        return toLineColumnOffset(fileName, position);
    };
}
//# sourceMappingURL=index.js.map