"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParsingWarehouse = void 0;
const antlr4ts_1 = require("antlr4ts");
const atn_1 = require("antlr4ts/atn");
const FlinkSQLLexer_1 = require("./lib/FlinkSQLLexer");
const FlinkSQLParser_1 = require("./lib/FlinkSQLParser");
const parse_error_listener_1 = require("./listeners/parse-error.listener");
class ParsingWarehouse {
    constructor() {
        this._warehouse = new Map();
    }
    setParsingValue(document) {
        const parseResult = this.parseDocument(document);
        this._warehouse.set(document.uri, {
            ...parseResult,
            tokenCollection: undefined
        });
    }
    parseDocument(document, range) {
        const text = range ? document.getText(range) : document.getText();
        const charStream = antlr4ts_1.CharStreams.fromString(text);
        const lexer = new FlinkSQLLexer_1.FlinkSQLLexer(charStream);
        const tokenStream = new antlr4ts_1.CommonTokenStream(lexer);
        const parser = new FlinkSQLParser_1.FlinkSQLParser(tokenStream);
        const errorListener = new parse_error_listener_1.ParseErrorListener(document);
        lexer.removeErrorListeners();
        parser.removeErrorListeners();
        let tree;
        parser.errorHandler = new antlr4ts_1.BailErrorStrategy();
        parser.interpreter.setPredictionMode(atn_1.PredictionMode.SLL);
        try {
            tree = parser.program();
        }
        catch (e) {
            parser.reset();
            parser.errorHandler = new antlr4ts_1.DefaultErrorStrategy();
            parser.addErrorListener(errorListener);
            parser.interpreter.setPredictionMode(atn_1.PredictionMode.LL);
            tree = parser.program();
        }
        return {
            origin: text,
            tokenStream,
            parser,
            tree,
            errors: errorListener.getErrors()
        };
    }
    hasParsingValue(document) {
        return this._warehouse.has(document.uri);
    }
    getParsingValue(document) {
        if (!this._warehouse.has(document.uri)) {
            this.setParsingValue(document);
        }
        return this._warehouse.get(document.uri);
    }
    setTokenCollection(document, tokens) {
        const parse = this._warehouse.get(document.uri);
        if (parse) {
            parse.tokenCollection = tokens;
        }
    }
    removeParsingValue(documentUri) {
        this._warehouse.delete(documentUri);
    }
}
exports.ParsingWarehouse = ParsingWarehouse;
//# sourceMappingURL=parsing-warehouse.js.map