"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.create = create;
const language_core_1 = require("@vue/language-core");
const utils_1 = require("../utils");
function create({ getComponentNames, getElementNames }) {
    return {
        name: 'vue-component-semantic-tokens',
        capabilities: {
            semanticTokensProvider: {
                legend: {
                    tokenTypes: ['component'],
                    tokenModifiers: [],
                },
            },
        },
        create(context) {
            return {
                async provideDocumentSemanticTokens(document, range, legend) {
                    const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
                    if (info?.code.id !== 'template') {
                        return;
                    }
                    const { template } = info.root.ir;
                    if (!template?.ast) {
                        return;
                    }
                    const componentSpans = [];
                    const start = document.offsetAt(range.start);
                    const end = document.offsetAt(range.end);
                    const validComponentNames = await getComponentNames(info.root.fileName) ?? [];
                    const elements = new Set(await getElementNames(info.root.fileName) ?? []);
                    const components = new Set([
                        ...validComponentNames,
                        ...validComponentNames.map(language_core_1.hyphenateTag),
                    ]);
                    for (const node of (0, language_core_1.forEachElementNode)(template.ast)) {
                        if (node.loc.end.offset <= start
                            || node.loc.start.offset >= end) {
                            continue;
                        }
                        if (components.has(node.tag) && !elements.has(node.tag)) {
                            let start = node.loc.start.offset;
                            if (template.lang === 'html') {
                                start += '<'.length;
                            }
                            componentSpans.push({
                                start,
                                length: node.tag.length,
                            });
                            if (template.lang === 'html' && !node.isSelfClosing) {
                                componentSpans.push({
                                    start: node.loc.start.offset + node.loc.source.lastIndexOf(node.tag),
                                    length: node.tag.length,
                                });
                            }
                        }
                    }
                    const result = [];
                    const tokenType = legend.tokenTypes.indexOf('component');
                    for (const span of componentSpans) {
                        const position = document.positionAt(span.start);
                        result.push([
                            position.line,
                            position.character,
                            span.length,
                            tokenType,
                            0,
                        ]);
                    }
                    return result;
                },
            };
        },
    };
}
//# sourceMappingURL=vue-component-semantic-tokens.js.map