"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WritableDocument = exports.ReadableDocument = void 0;
const utils_1 = require("./utils");
/**
 * Represents a textual document.
 */
class ReadableDocument {
    constructor() {
        /**
         * Current version of the document.
         */
        this.version = 0;
    }
    /**
     * Get the length of the document's content
     */
    getTextLength() {
        return this.getText().length;
    }
    /**
     * Get the line and character based on the offset
     * @param offset The index of the position
     */
    positionAt(offset) {
        return (0, utils_1.positionAt)(offset, this.getText(), this.getLineOffsets());
    }
    /**
     * Get the index of the line and character position
     * @param position Line and character position
     */
    offsetAt(position) {
        return (0, utils_1.offsetAt)(position, this.getText(), this.getLineOffsets());
    }
    getLineOffsets() {
        if (!this.lineOffsets) {
            this.lineOffsets = (0, utils_1.getLineOffsets)(this.getText());
        }
        return this.lineOffsets;
    }
    /**
     * Implements TextDocument
     */
    get uri() {
        return this.getURL();
    }
    get lineCount() {
        return this.getLineOffsets().length;
    }
}
exports.ReadableDocument = ReadableDocument;
/**
 * Represents a textual document that can be manipulated.
 */
class WritableDocument extends ReadableDocument {
    /**
     * Batch update the document with the LSP change events.
     */
    update(changes) {
        let newText = this.getText();
        for (const change of changes) {
            if ('range' in change) {
                const lineOffsets = (0, utils_1.getLineOffsets)(newText);
                const start = (0, utils_1.offsetAt)(change.range.start, newText, lineOffsets);
                const end = (0, utils_1.offsetAt)(change.range.end, newText, lineOffsets);
                newText = newText.slice(0, start) + change.text + newText.slice(end);
            }
            else {
                newText = change.text;
            }
        }
        this.setText(newText);
    }
}
exports.WritableDocument = WritableDocument;
//# sourceMappingURL=DocumentBase.js.map