import { IDisposable } from '@lumino/disposable';
import { IDocumentInfo } from '../ws-connection/types';
import { IPosition } from '../positioning';
import { CodeEditor } from '@jupyterlab/codeeditor';
import { ISignal } from '@lumino/signaling';
import { Document, ILSPCodeExtractorsManager } from '../tokens';
import { LanguageIdentifier } from '../lsp';
import { IEditorPosition, IRootPosition, ISourcePosition, IVirtualPosition } from '../positioning';
import { DefaultMap } from '../utils';
type IRange = CodeEditor.IRange;
type language = string;
interface IVirtualLine {
    /**
     * Inspections for which document should be skipped for this virtual line?
     */
    skipInspect: Array<VirtualDocument.idPath>;
    /**
     * Where does the virtual line belongs to in the source document?
     */
    sourceLine: number | null;
    /**
     * The editor holding this virtual line
     */
    editor: Document.IEditor;
}
export type ForeignDocumentsMap = Map<IRange, Document.IVirtualDocumentBlock>;
interface ISourceLine {
    /**
     * Line corresponding to the block in the entire foreign document
     */
    virtualLine: number;
    /**
     * The CM editor associated with this virtual line.
     */
    editor: Document.IEditor;
    /**
     * Line in the CM editor corresponding to the virtual line.
     */
    editorLine: number;
    /**
     * Shift of the virtual line
     */
    editorShift: CodeEditor.IPosition;
    /**
     * Everything which is not in the range of foreign documents belongs to the host.
     */
    foreignDocumentsMap: ForeignDocumentsMap;
}
/**
 * Check if given position is within range.
 * Both start and end are inclusive.
 * @param position
 * @param range
 */
export declare function isWithinRange(position: CodeEditor.IPosition, range: CodeEditor.IRange): boolean;
/**
 * A virtual implementation of IDocumentInfo
 */
export declare class VirtualDocumentInfo implements IDocumentInfo {
    /**
     * Creates an instance of VirtualDocumentInfo.
     * @param document - the virtual document need to
     * be wrapped.
     */
    constructor(document: VirtualDocument);
    /**
     * Current version of the virtual document.
     */
    version: number;
    /**
     * Get the text content of the virtual document.
     */
    get text(): string;
    /**
     * Get the uri of the virtual document, if the document is not available,
     * it returns an empty string, users need to check for the length of returned
     * value before using it.
     */
    get uri(): string;
    /**
     * Get the language identifier of the document.
     */
    get languageId(): string;
    /**
     * The wrapped virtual document.
     */
    private _document;
}
export declare namespace VirtualDocument {
    interface IOptions {
        /**
         * The language identifier of the document.
         */
        language: LanguageIdentifier;
        /**
         * The foreign code extractor manager token.
         */
        foreignCodeExtractors: ILSPCodeExtractorsManager;
        /**
         * Path to the document.
         */
        path: string;
        /**
         * File extension of the document.
         */
        fileExtension: string | undefined;
        /**
         * Notebooks or any other aggregates of documents are not supported
         * by the LSP specification, and we need to make appropriate
         * adjustments for them, pretending they are simple files
         * so that the LSP servers do not refuse to cooperate.
         */
        hasLspSupportedFile: boolean;
        /**
         * Being standalone is relevant to foreign documents
         * and defines whether following chunks of code in the same
         * language should be appended to this document (false, not standalone)
         * or should be considered separate documents (true, standalone)
         *
         */
        standalone?: boolean;
        /**
         * Parent of the current virtual document.
         */
        parent?: VirtualDocument;
    }
}
/**
 *
 * A notebook can hold one or more virtual documents; there is always one,
 * "root" document, corresponding to the language of the kernel. All other
 * virtual documents are extracted out of the notebook, based on magics,
 * or other syntax constructs, depending on the kernel language.
 *
 * Virtual documents represent the underlying code in a single language,
 * which has been parsed excluding interactive kernel commands (magics)
 * which could be misunderstood by the specific LSP server.
 *
 * VirtualDocument has no awareness of the notebook or editor it lives in,
 * however it is able to transform its content back to the notebook space,
 * as it keeps editor coordinates for each virtual line.
 *
 * The notebook/editor aware transformations are preferred to be placed in
 * VirtualEditor descendants rather than here.
 *
 * No dependency on editor implementation (such as CodeMirrorEditor)
 * is allowed for VirtualEditor.
 */
export declare class VirtualDocument implements IDisposable {
    constructor(options: VirtualDocument.IOptions);
    /**
     * Convert from code editor position into code mirror position.
     */
    static ceToCm(position: CodeEditor.IPosition): IPosition;
    /**
     * Number of blank lines appended to the virtual document between
     * each cell.
     */
    blankLinesBetweenCells: number;
    /**
     * Line number of the last line in the real document.
     */
    lastSourceLine: number;
    /**
     * Line number of the last line in the virtual document.
     */
    lastVirtualLine: number;
    /**
     * the remote document uri, version and other server-related info
     */
    documentInfo: IDocumentInfo;
    /**
     * Parent of the current virtual document.
     */
    parent?: VirtualDocument | null;
    /**
     * The language identifier of the document.
     */
    readonly language: string;
    /**
     * Being standalone is relevant to foreign documents
     * and defines whether following chunks of code in the same
     * language should be appended to this document (false, not standalone)
     * or should be considered separate documents (true, standalone)
     */
    readonly standalone: boolean;
    /**
     * Path to the document.
     */
    readonly path: string;
    /**
     * File extension of the document.
     */
    readonly fileExtension: string | undefined;
    /**
     * Notebooks or any other aggregates of documents are not supported
     * by the LSP specification, and we need to make appropriate
     * adjustments for them, pretending they are simple files
     * so that the LSP servers do not refuse to cooperate.
     */
    readonly hasLspSupportedFile: boolean;
    /**
     * Map holding the children `VirtualDocument` .
     */
    readonly foreignDocuments: Map<VirtualDocument.virtualId, VirtualDocument>;
    /**
     * The update manager object.
     */
    readonly updateManager: UpdateManager;
    /**
     * Unique id of the virtual document.
     */
    readonly instanceId: number;
    /**
     * Test whether the document is disposed.
     */
    get isDisposed(): boolean;
    /**
     * Signal emitted when the foreign document is closed
     */
    get foreignDocumentClosed(): ISignal<VirtualDocument, Document.IForeignContext>;
    /**
     * Signal emitted when the foreign document is opened
     */
    get foreignDocumentOpened(): ISignal<VirtualDocument, Document.IForeignContext>;
    /**
     * Signal emitted when the foreign document is changed
     */
    get changed(): ISignal<VirtualDocument, VirtualDocument>;
    /**
     * Id of the virtual document.
     */
    get virtualId(): VirtualDocument.virtualId;
    /**
     * Return the ancestry to this document.
     */
    get ancestry(): Array<VirtualDocument>;
    /**
     * Return the id path to the virtual document.
     */
    get idPath(): VirtualDocument.idPath;
    /**
     * Get the uri of the virtual document.
     */
    get uri(): VirtualDocument.uri;
    /**
     * Get the text value of the document
     */
    get value(): string;
    /**
     * Get the last line in the virtual document
     */
    get lastLine(): string;
    /**
     * Get the root document of current virtual document.
     */
    get root(): VirtualDocument;
    /**
     * Dispose the virtual document.
     */
    dispose(): void;
    /**
     * Clear the virtual document and all related stuffs
     */
    clear(): void;
    /**
     * Get the virtual document from the cursor position of the source
     * document
     * @param position - position in source document
     */
    documentAtSourcePosition(position: ISourcePosition): VirtualDocument;
    /**
     * Detect if the input source position is belong to the current
     * virtual document.
     *
     * @param sourcePosition - position in the source document
     */
    isWithinForeign(sourcePosition: ISourcePosition): boolean;
    /**
     * Compute the position in root document from the position of
     * a child editor.
     *
     * @param editor - the active editor.
     * @param position - position in the active editor.
     */
    transformFromEditorToRoot(editor: Document.IEditor, position: IEditorPosition): IRootPosition | null;
    /**
     * Compute the position in the virtual document from the position
     * if the source document.
     *
     * @param sourcePosition - position in source document
     */
    virtualPositionAtDocument(sourcePosition: ISourcePosition): IVirtualPosition;
    /**
     * Append a code block to the end of the virtual document.
     *
     * @param  block - block to be appended
     * @param  editorShift - position shift in source
     * document
     * @param  [virtualShift] - position shift in
     * virtual document.
     */
    appendCodeBlock(block: Document.ICodeBlockOptions, editorShift?: CodeEditor.IPosition, virtualShift?: CodeEditor.IPosition): void;
    /**
     * Extract a code block into list of string in supported language and
     * a map of foreign document if any.
     * @param  block - block to be appended
     * @param  editorShift - position shift in source document
     */
    prepareCodeBlock(block: Document.ICodeBlockOptions, editorShift?: CodeEditor.IPosition): {
        lines: string[];
        foreignDocumentsMap: Map<CodeEditor.IRange, Document.IVirtualDocumentBlock>;
    };
    /**
     * Extract the foreign code from input block by using the registered
     * extractors.
     * @param  block - block to be appended
     * @param  editorShift - position shift in source document
     */
    extractForeignCode(block: Document.ICodeBlockOptions, editorShift: CodeEditor.IPosition): {
        cellCodeKept: string;
        foreignDocumentsMap: Map<CodeEditor.IRange, Document.IVirtualDocumentBlock>;
    };
    /**
     * Close a foreign document and disconnect all associated signals
     */
    closeForeign(document: VirtualDocument): void;
    /**
     * Close all foreign documents.
     */
    closeAllForeignDocuments(): void;
    /**
     * Close all expired documents.
     */
    closeExpiredDocuments(): void;
    /**
     * Transform the position of the source to the editor
     * position.
     *
     * @param  pos - position in the source document
     * @return position in the editor.
     */
    transformSourceToEditor(pos: ISourcePosition): IEditorPosition;
    /**
     * Transform the position in the virtual document to the
     * editor position.
     * Can be null because some lines are added as padding/anchors
     * to the virtual document and those do not exist in the source document
     * and thus they are absent in the editor.
     */
    transformVirtualToEditor(virtualPosition: IVirtualPosition): IEditorPosition | null;
    /**
     * Transform the position in the virtual document to the source.
     * Can be null because some lines are added as padding/anchors
     * to the virtual document and those do not exist in the source document.
     */
    transformVirtualToSource(position: IVirtualPosition): ISourcePosition | null;
    /**
     * Compute the position in root document from the position of
     * a virtual document.
     */
    transformVirtualToRoot(position: IVirtualPosition): IRootPosition | null;
    /**
     * Get the corresponding editor of the virtual line.
     */
    getEditorAtVirtualLine(pos: IVirtualPosition): Document.IEditor;
    /**
     * Get the corresponding editor of the source line
     */
    getEditorAtSourceLine(pos: ISourcePosition): Document.IEditor;
    /**
     * Recursively emits changed signal from the document or any descendant foreign document.
     */
    maybeEmitChanged(): void;
    /**
     * When this counter goes down to 0, the document will be destroyed and the associated connection will be closed;
     * This is meant to reduce the number of open connections when a foreign code snippet was removed from the document.
     *
     * Note: top level virtual documents are currently immortal (unless killed by other means); it might be worth
     * implementing culling of unused documents, but if and only if JupyterLab will also implement culling of
     * idle kernels - otherwise the user experience could be a bit inconsistent, and we would need to invent our own rules.
     */
    protected get remainingLifetime(): number;
    protected set remainingLifetime(value: number);
    /**
     * Virtual lines keep all the lines present in the document AND extracted to the foreign document.
     */
    protected virtualLines: Map<number, IVirtualLine>;
    protected sourceLines: Map<number, ISourceLine>;
    protected lineBlocks: Array<string>;
    protected unusedStandaloneDocuments: DefaultMap<language, Array<VirtualDocument>>;
    private _isDisposed;
    private _remainingLifetime;
    private _editorToSourceLine;
    private _editorToSourceLineNew;
    private _foreignCodeExtractors;
    private previousValue;
    private static instancesCount;
    private readonly options;
    /**
     * Get the foreign document that can be opened with the input extractor.
     */
    private _chooseForeignDocument;
    /**
     * Create a foreign document from input language and file extension.
     *
     * @param  language - the required language
     * @param  standalone - the document type is supported natively by LSP?
     * @param  fileExtension - File extension.
     */
    private openForeign;
    /**
     * Forward the closed signal from the foreign document to the host document's
     * signal
     */
    private forwardClosedSignal;
    /**
     * Forward the opened signal from the foreign document to the host document's
     * signal
     */
    private forwardOpenedSignal;
    /**
     * Slot of the `updateBegan` signal.
     */
    private _updateBeganSlot;
    /**
     * Slot of the `blockAdded` signal.
     */
    private _blockAddedSlot;
    /**
     * Slot of the `updateFinished` signal.
     */
    private _updateFinishedSlot;
    private _foreignDocumentClosed;
    private _foreignDocumentOpened;
    private _changed;
}
export declare namespace VirtualDocument {
    /**
     * Identifier composed of `virtual_id`s of a nested structure of documents,
     * used to aide assignment of the connection to the virtual document
     * handling specific, nested language usage; it will be appended to the file name
     * when creating a connection.
     */
    type idPath = string;
    /**
     * Instance identifier for standalone documents (snippets), or language identifier
     * for documents which should be interpreted as one when stretched across cells.
     */
    type virtualId = string;
    /**
     * Identifier composed of the file path and id_path.
     */
    type uri = string;
}
/**
 * Create foreign documents if available from input virtual documents.
 * @param virtualDocument - the virtual document to be collected
 * @return - Set of generated foreign documents
 */
export declare function collectDocuments(virtualDocument: VirtualDocument): Set<VirtualDocument>;
export interface IBlockAddedInfo {
    /**
     * The virtual document.
     */
    virtualDocument: VirtualDocument;
    /**
     * Option of the code block.
     */
    block: Document.ICodeBlockOptions;
}
export declare class UpdateManager implements IDisposable {
    private virtualDocument;
    constructor(virtualDocument: VirtualDocument);
    /**
     * Promise resolved when the updating process finishes.
     */
    get updateDone(): Promise<void>;
    /**
     * Test whether the document is disposed.
     */
    get isDisposed(): boolean;
    /**
     * Signal emitted when a code block is added to the document.
     */
    get blockAdded(): ISignal<UpdateManager, IBlockAddedInfo>;
    /**
     * Signal emitted by the editor that triggered the update,
     * providing the root document of the updated documents.
     */
    get documentUpdated(): ISignal<UpdateManager, VirtualDocument>;
    /**
     * Signal emitted when the update is started
     */
    get updateBegan(): ISignal<UpdateManager, Document.ICodeBlockOptions[]>;
    /**
     * Signal emitted when the update is finished
     */
    get updateFinished(): ISignal<UpdateManager, Document.ICodeBlockOptions[]>;
    /**
     * Dispose the class
     */
    dispose(): void;
    /**
     * Execute provided callback within an update-locked context, which guarantees that:
     *  - the previous updates must have finished before the callback call, and
     *  - no update will happen when executing the callback
     * @param fn - the callback to execute in update lock
     */
    withUpdateLock(fn: () => void): Promise<void>;
    /**
     * Update all the virtual documents, emit documents updated with root document if succeeded,
     * and resolve a void promise. The promise does not contain the text value of the root document,
     * as to avoid an easy trap of ignoring the changes in the virtual documents.
     */
    updateDocuments(blocks: Document.ICodeBlockOptions[]): Promise<void>;
    private _isDisposed;
    /**
     * Promise resolved when the updating process finishes.
     */
    private _updateDone;
    /**
     * Virtual documents update guard.
     */
    private _isUpdateInProgress;
    /**
     * Update lock to prevent multiple updates are applied at the same time.
     */
    private _updateLock;
    private _blockAdded;
    private _documentUpdated;
    private _updateBegan;
    private _updateFinished;
    /**
     * Once all the foreign documents were refreshed, the unused documents (and their connections)
     * should be terminated if their lifetime has expired.
     */
    private _onUpdated;
    /**
     * Check if the document can be updated.
     */
    private _canUpdate;
}
export {};
