"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Line = void 0;
const core_1 = require("@midwayjs/core");
class Span {
    constructor(source, start, end) {
        if (start == undefined) {
            start = 0;
        }
        if (end == undefined) {
            end = 0;
        }
        if (start > end) {
            throw new core_1.MidwayCommonError('Start must be <= end.');
        }
        if (start < 0) {
            throw new core_1.MidwayCommonError('Start must be >= 0.');
        }
        //        if (start > source.length - 1) {
        //            throw new MidwayCommonError("Start outside of string.");
        //        }
        if (end > source.length) {
            throw new core_1.MidwayCommonError('End outside of string.');
        }
        this.source = source;
        this.start = start;
        this.end = end;
        this.cachedText = source.substring(start, end);
    }
    getText() {
        return this.cachedText;
    }
    getLine() {
        if (this.line != null) {
            return this.line;
        }
        let lineStart = this.start;
        while (lineStart < this.end) {
            if (lineStart < 0) {
                break;
            }
            const c = this.source.charAt(lineStart);
            if (c == '\n') {
                lineStart = lineStart + 1;
                break;
            }
            lineStart--;
        }
        if (lineStart < 0) {
            lineStart = 0;
        }
        let lineEnd = this.end;
        while (true) {
            if (lineEnd > this.source.length - 1) {
                break;
            }
            const c = this.source.charAt(lineEnd);
            if (c == '\n') {
                break;
            }
            lineEnd++;
        }
        let lineNumber = 0;
        let idx = lineStart;
        while (idx > 0 && idx < this.end) {
            const c = this.source.charAt(idx);
            if (c == '\n') {
                lineNumber++;
            }
            idx--;
        }
        lineNumber++;
        idx = lineStart + 1;
        let endLineNumber = lineNumber;
        while (idx < lineEnd) {
            const c = this.source.charAt(idx);
            if (c == '\n') {
                endLineNumber++;
            }
            idx++;
        }
        const startCol = this.start - lineStart + 1;
        const endCol = startCol + this.end - this.start - 1;
        this.line = new Line(this.source, lineStart, lineEnd, lineNumber, endLineNumber, startCol, endCol);
        return this.line;
    }
    toString() {
        return ('Span [text=' +
            this.getText() +
            ', start=' +
            this.start +
            ', end=' +
            this.end +
            ']');
    }
}
exports.default = Span;
class Line {
    constructor(source, start, end, lineNumber, endLineNumber, startCol, endCol) {
        this.source = source;
        this.start = start;
        this.end = end;
        this.lineNumber = lineNumber;
        this.endLineNumber = endLineNumber;
        this.startCol = startCol;
        this.endCol = endCol;
    }
}
exports.Line = Line;
//# sourceMappingURL=Span.js.map