"use strict";
/*
 * Copyright OpenSearch Contributors
 * SPDX-License-Identifier: Apache-2.0
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.DOTTED_PATH_RULES = void 0;
exports.isRuleNode = isRuleNode;
exports.isTerminalNode = isTerminalNode;
exports.isParserRuleContext = isParserRuleContext;
exports.createCompiledRuleNameToIndex = createCompiledRuleNameToIndex;
exports.createRuntimeRuleNameToIndex = createRuntimeRuleNameToIndex;
exports.findChildByRule = findChildByRule;
exports.findAllChildrenByRule = findAllChildrenByRule;
exports.findAllDescendantsByRule = findAllDescendantsByRule;
exports.collectDottedPathNodes = collectDottedPathNodes;
exports.getTokenText = getTokenText;
const antlr_grammar_1 = require("@osd/antlr-grammar");
// Duck-type guards (instanceof breaks across duplicate bundles in workers).
function isRuleNode(node) {
    return (node != null &&
        typeof node.ruleIndex === 'number' &&
        node.ruleIndex >= 0 &&
        'children' in node);
}
function isTerminalNode(node) {
    return (node != null &&
        typeof node.symbol === 'object' &&
        node.symbol != null &&
        !('ruleIndex' in node && node.ruleIndex >= 0));
}
// Typed narrowing alias over isRuleNode for parse-tree callers (same duck-type).
function isParserRuleContext(node) {
    return isRuleNode(node);
}
let compiledRuleNameToIndexMap;
function getCompiledRuleNameToIndexMap() {
    if (!compiledRuleNameToIndexMap) {
        compiledRuleNameToIndexMap = new Map();
        const ruleNames = antlr_grammar_1.SimplifiedOpenSearchPPLParser.ruleNames;
        for (let i = 0; i < ruleNames.length; i++) {
            compiledRuleNameToIndexMap.set(ruleNames[i], i);
        }
    }
    return compiledRuleNameToIndexMap;
}
function createCompiledRuleNameToIndex() {
    const map = getCompiledRuleNameToIndexMap();
    return (name) => map.get(name) ?? -1;
}
function createRuntimeRuleNameToIndex(runtimeRuleNameToIndex) {
    return (name) => runtimeRuleNameToIndex.get(name) ?? -1;
}
function findChildByRule(ctx, ruleNameToIndex, ruleName) {
    const idx = ruleNameToIndex(ruleName);
    if (idx === -1) {
        return undefined;
    }
    const children = ctx.children ?? [];
    for (const child of children) {
        if (isRuleNode(child) && child.ruleIndex === idx) {
            return child;
        }
    }
    return undefined;
}
function findAllChildrenByRule(ctx, ruleNameToIndex, ruleName) {
    const idx = ruleNameToIndex(ruleName);
    if (idx === -1) {
        return [];
    }
    const children = ctx.children ?? [];
    return children.filter((c) => isRuleNode(c) && c.ruleIndex === idx);
}
function findAllDescendantsByRule(ctx, ruleNameToIndex, ruleName) {
    const idx = ruleNameToIndex(ruleName);
    if (idx === -1) {
        return [];
    }
    const matches = [];
    const stack = [...(ctx.children ?? [])];
    while (stack.length > 0) {
        const node = stack.pop();
        if (isRuleNode(node)) {
            if (node.ruleIndex === idx) {
                matches.push(node);
            }
            if (node.children) {
                stack.push(...node.children);
            }
        }
    }
    return matches;
}
exports.DOTTED_PATH_RULES = ['qualifiedName', 'wcQualifiedName'];
function collectDottedPathNodes(ctx, ruleNameToIndex) {
    const seen = new Set();
    let fallbackId = 0;
    const result = [];
    for (const ruleName of exports.DOTTED_PATH_RULES) {
        for (const node of findAllDescendantsByRule(ctx, ruleNameToIndex, ruleName)) {
            if (node.getText().indexOf('.') === -1) {
                continue;
            }
            const startIndex = node.start?.start ?? `__null_${fallbackId++}`;
            if (!seen.has(startIndex)) {
                seen.add(startIndex);
                result.push(node);
            }
        }
    }
    return result;
}
function getTokenText(ctx) {
    const children = ctx.children ?? [];
    return children
        .filter((c) => isTerminalNode(c))
        .map((c) => c.getText())
        .join('');
}
//# sourceMappingURL=rule_index.js.map