"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mySqlListenerBase_1 = require("./mySqlListenerBase");
const MySqlParser_1 = require("../../grammar/mysql/MySqlParser");
const hashmaps_1 = require("@nebtex/hashmaps");
const symbolElement_1 = require("../../symbols/symbolElement");
class MysqlListener extends mySqlListenerBase_1.MySqlListenerBase {
    constructor(symbolTable) {
        super();
        /**
         * 当前作用域
         */
        this.currentLevel = "0";
        /**
         * 进入到sqlStatement语句，创建一个顶级的作用域
         * @param ctx
         */
        this.enterSqlStatement = (ctx) => {
            let table = new hashmaps_1.HashMap();
            let level = this.symbolTable.insertTable(this.currentLevel, table);
            this.currentLevel = level;
        };
        /**
         * 退出sqlStatement语句的作用域
         * @param ctx
         */
        this.exitSqlStatement = (ctx) => {
            this.currentLevel = this.symbolTable.exitTable(this.currentLevel);
        };
        /***************************************开始select语句***************************************************/
        /**
         * 新建一个select语句的作用域
         */
        this.enterQuerySpecification = (ctx) => {
            let table = new hashmaps_1.HashMap();
            let level = this.symbolTable.insertTable(this.currentLevel, table);
            this.currentLevel = level;
        };
        /**
         * 退出一个select语句的作用域
         * @param ctx
         */
        this.exitQuerySpecification = (ctx) => {
            this.currentLevel = this.symbolTable.exitTable(this.currentLevel);
        };
        /**
         * 新建一个select语句的作用域
         * @param ctx
         */
        this.enterQuerySpecificationNointo = (ctx) => {
            let table = new hashmaps_1.HashMap();
            let level = this.symbolTable.insertTable(this.currentLevel, table);
            this.currentLevel = level;
        };
        /**
         * 退出一个select语句的作用域
         */
        this.exitQuerySpecificationNointo = () => {
            this.currentLevel = this.symbolTable.exitTable(this.currentLevel);
        };
        /**
         * 进入字段处理
         * @param ctx
         */
        this.enterFullColumnName = (ctx) => {
            if (ctx.childCount == 1) {
                let startIndex = ctx.start.startIndex;
                let element = new symbolElement_1.SymbolElement();
                element.type = symbolElement_1.ElementType.COLUMN;
                element.text = ctx.text;
                element.startIndex = startIndex;
                element.stopIndex = ctx.start.stopIndex;
                element.level = this.currentLevel;
                this.symbolTable.getTable(this.currentLevel).set(startIndex, element);
            }
            else if (ctx.childCount == 2) {
                let uidContext = ctx.getChild(0);
                let dottedIdContext = ctx.getChild(1);
                let startIndex1 = dottedIdContext.start.startIndex;
                let stopIndex = dottedIdContext.start.stopIndex;
                let element = new symbolElement_1.SymbolElement();
                element.type = symbolElement_1.ElementType.COLUMN;
                element.level = this.currentLevel;
                element.text = dottedIdContext.text;
                element.startIndex = startIndex1;
                element.stopIndex = stopIndex;
                element.alias = uidContext.text;
                this.symbolTable.getTable(this.currentLevel).set(startIndex1, element);
            }
        };
        /**
         * 进入到表名处理
         * @param ctx
         */
        this.enterAtomTableItem = (ctx) => {
            if (ctx.childCount == 1) {
                let element = new symbolElement_1.SymbolElement();
                element.level = this.currentLevel;
                element.type = symbolElement_1.ElementType.TABLE;
                element.startIndex = ctx.start.startIndex;
                element.stopIndex = ctx.start.stopIndex;
                element.text = ctx.text;
                this.symbolTable.getTable(this.currentLevel).set(ctx.start.startIndex, element);
            }
            else {
                let tableNameContext = ctx.getChild(0);
                let uidContext = ctx.getChild(ctx.childCount - 1);
                let element1 = new symbolElement_1.SymbolElement();
                element1.level = this.currentLevel;
                element1.type = symbolElement_1.ElementType.TABLE;
                element1.startIndex = tableNameContext.start.startIndex;
                element1.stopIndex = tableNameContext.start.stopIndex;
                element1.text = tableNameContext.text;
                element1.alias = uidContext.text;
                this.symbolTable.getTable(this.currentLevel).set(element1.startIndex, element1);
            }
        };
        /**
         * 进入到有子select时，table的别名处理
         * @param ctx
         */
        this.enterSubqueryTableItem = (ctx) => {
            let uidContext = ctx.getChild(ctx.childCount - 1);
            let element = new symbolElement_1.SymbolElement();
            element.level = this.currentLevel;
            element.type = symbolElement_1.ElementType.TABLE;
            element.startIndex = ctx.start.startIndex;
            element.stopIndex = ctx.start.stopIndex;
            element.alias = uidContext.text;
            this.symbolTable.getTable(this.currentLevel).set(ctx.start.startIndex, element);
        };
        /***************************************结束select语句***************************************************/
        /***************************************开始delete语句***************************************************/
        /**
         * 进入到了delete处理语句的作用域
         * @param ctx
         */
        this.enterDeleteStatement = (ctx) => {
            let table = new hashmaps_1.HashMap();
            let level = this.symbolTable.insertTable(this.currentLevel, table);
            this.currentLevel = level;
        };
        /**
         * 退出delete处理语句的作用域
         * @param ctx
         */
        this.exitDeleteStatement = (ctx) => {
            this.currentLevel = this.symbolTable.exitTable(this.currentLevel);
        };
        /**
         * 进入到表名处理
         */
        this.enterTableName = (ctx) => {
            let fullIdContext = ctx.getChild(0);
            let element = new symbolElement_1.SymbolElement();
            element.type = symbolElement_1.ElementType.TABLE;
            element.level = this.currentLevel;
            if (fullIdContext.childCount == 1) {
                element.startIndex = fullIdContext.start.startIndex;
                element.stopIndex = fullIdContext.start.stopIndex;
                element.text = fullIdContext.text;
                if (!this.symbolTable.getTable(this.currentLevel).has(element.startIndex)) {
                    this.symbolTable.getTable(this.currentLevel).set(element.startIndex, element);
                }
            }
            else if (fullIdContext.childCount == 2) {
                let terminalNode = fullIdContext.getChild(1);
                element.startIndex = fullIdContext.stop.startIndex;
                element.stopIndex = fullIdContext.stop.stopIndex;
                element.text = terminalNode.text;
                if (!this.symbolTable.getTable(this.currentLevel).has(fullIdContext.start.startIndex)) {
                    this.symbolTable.getTable(this.currentLevel).set(element.startIndex, element);
                }
            }
        };
        /***************************************结束select语句***************************************************/
        /***************************************开始update语句***************************************************/
        /**
         * 进入update的域
         * @param ctx
         */
        this.enterUpdateStatement = (ctx) => {
            let table = new hashmaps_1.HashMap();
            let level = this.symbolTable.insertTable(this.currentLevel, table);
            this.currentLevel = level;
        };
        /**
         * 退出update的域
         * @param ctx
         */
        this.exitUpdateStatement = (ctx) => {
            this.currentLevel = this.symbolTable.exitTable(this.currentLevel);
        };
        /***************************************结束update语句***************************************************/
        /***************************************开始insert语句***************************************************/
        /**
         * 进入到insert域
         * @param ctx
         */
        this.enterInsertStatement = () => {
            let table = new hashmaps_1.HashMap();
            let level = this.symbolTable.insertTable(this.currentLevel, table);
            this.currentLevel = level;
        };
        /**
         * 退出insert域
         * @param ctx
         */
        this.exitInsertStatement = () => {
            this.currentLevel = this.symbolTable.exitTable(this.currentLevel);
        };
        this.enterUidList = (ctx) => {
            for (let parseTree of ctx.children) {
                if (parseTree instanceof MySqlParser_1.UidContext) {
                    let uidContext = parseTree;
                    let element = new symbolElement_1.SymbolElement();
                    element.text = uidContext.text;
                    element.startIndex = uidContext.stop.startIndex;
                    element.stopIndex = uidContext.stop.stopIndex;
                    element.level = this.currentLevel;
                    element.type = symbolElement_1.ElementType.COLUMN;
                    this.symbolTable.getTable(this.currentLevel).set(element.startIndex, element);
                }
            }
        };
        this.symbolTable = symbolTable;
    }
}
exports.MysqlListener = MysqlListener;
