"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * oracle语法解析的监听器，实现符号表
 */
const oracleListenerBase_1 = require("./oracleListenerBase");
const hashmaps_1 = require("@nebtex/hashmaps");
const symbolElement_1 = require("../../symbols/symbolElement");
const PlSqlParser_1 = require("../../grammar/oracle/PlSqlParser");
const PlSqlParser_2 = require("../../grammar/oracle/PlSqlParser");
const PlSqlParser_3 = require("../../grammar/oracle/PlSqlParser");
class OracleListener extends oracleListenerBase_1.OracleListenerBase {
    constructor(symbolTable) {
        super();
        /**
         * 当前作用域
         */
        this.currentLevel = "0";
        /**
         * 进入了普通sql的顶级规则中，创建一个顶级作用域
         */
        this.enterUnit_statement = (ctx) => {
            let table = new hashmaps_1.HashMap();
            let level = this.symbolTable.insertTable(this.currentLevel, table);
            this.currentLevel = level;
        };
        /**
         * 退出顶级作用域
         */
        this.exitUnit_statement = (ctx) => {
            this.currentLevel = this.symbolTable.exitTable(this.currentLevel);
        };
        /***************************************开始select语句***************************************************/
        /**
         * 进入到select语句中
         */
        this.enterSelect_statement = (ctx) => {
            let table = new hashmaps_1.HashMap();
            let level = this.symbolTable.insertTable(this.currentLevel, table);
            this.currentLevel = level;
        };
        /**
         * 退出select语句
         * @param ctx
         */
        this.exitSelect_statement = (ctx) => {
            this.currentLevel = this.symbolTable.exitTable(this.currentLevel);
        };
        /**
         * 进入到select语句中字段元素（可能一个，也肯定多个）
         * 思路：
         * 1.判断select_list_elements的子节点是不是expressions
         * 2.找到expressions子级节点为expression的节点
         * 3.expression节点此时表示了字段，写入到符号表中
         * @param ctx
         */
        this.enterSelect_list_elements = (ctx) => {
            for (let expressions of ctx.children) {
                //1.判断select_list_elements的子节点是不是expressions，如果不是就返回
                if (expressions instanceof PlSqlParser_1.ExpressionsContext) {
                    for (let expression of expressions.children) {
                        if (expression instanceof PlSqlParser_2.ExpressionContext) {
                            let element = new symbolElement_1.SymbolElement();
                            element.startIndex = expression.start.startIndex;
                            element.stopIndex = expression.stop.stopIndex;
                            element.text = expression.text;
                            element.type = symbolElement_1.ElementType.COLUMN;
                            element.level = this.currentLevel;
                            this.symbolTable.getTable(this.currentLevel).set(element.startIndex, element);
                        }
                    }
                }
            }
        };
        /**
         * 解决select语句中table的定位
         * 思路：
         * 1.进入到table_ref_aux
         * 2.找到table_ref_aux_internal的table_ref_aux_internal_one，此处为真实的表名
         * 3.找到table_alias，如果有，则表示当前表有别名，设置别名。
         * 注意：当前仅支持table_ref_aux_internal_one
         * @param ctx
         */
        this.enterTable_ref_aux = (ctx) => {
            let element;
            for (let children of ctx.children) {
                if (children instanceof PlSqlParser_3.Table_ref_aux_internal_oneContext) {
                    element = new symbolElement_1.SymbolElement();
                    element.startIndex = children.start.startIndex;
                    element.stopIndex = children.stop.stopIndex;
                    element.level = this.currentLevel;
                    element.type = symbolElement_1.ElementType.TABLE;
                    element.text = children.text;
                }
                if (children instanceof PlSqlParser_3.Table_aliasContext && element != undefined) {
                    element.alias = children.text;
                }
            }
            if (element != undefined) {
                this.symbolTable.getTable(this.currentLevel).set(element.startIndex, element);
            }
        };
        this.symbolTable = symbolTable;
    }
}
exports.OracleListener = OracleListener;
