import { CodeEditor } from '@jupyterlab/codeeditor';
import { Signal } from '@lumino/signaling';
import { IDocumentInfo } from 'lsp-ws-connection';
import { IForeignCodeExtractor, IForeignCodeExtractorsRegistry } from '../extractors/types';
import { LanguageIdentifier } from '../lsp';
import { ICodeOverridesRegistry } from '../overrides/tokens';
import { IEditorPosition, ISourcePosition, IVirtualPosition } from '../positioning';
import { ILSPLogConsole } from '../tokens';
import { DefaultMap } from '../utils';
import IRange = CodeEditor.IRange;
declare type language = string;
interface IVirtualLine {
    /**
     * Inspections for which document should be skipped for this virtual line?
     */
    skip_inspect: Array<VirtualDocument.id_path>;
    /**
     * Where does the virtual line belongs to in the source document?
     */
    source_line: number | null;
    editor: CodeEditor.IEditor;
}
export interface ICodeBlockOptions {
    ce_editor: CodeEditor.IEditor;
    value: string;
}
export interface IVirtualDocumentBlock {
    /**
     * Line corresponding to the block in the entire foreign document
     */
    virtual_line: number;
    virtual_document: VirtualDocument;
    editor: CodeEditor.IEditor;
}
export declare type ForeignDocumentsMap = Map<IRange, IVirtualDocumentBlock>;
interface ISourceLine {
    virtual_line: number;
    editor: CodeEditor.IEditor;
    editor_line: number;
    editor_shift: CodeEditor.IPosition;
    /**
     * Everything which is not in the range of foreign documents belongs to the host.
     */
    foreign_documents_map: ForeignDocumentsMap;
}
export interface IForeignContext {
    foreign_document: VirtualDocument;
    parent_host: VirtualDocument;
}
/**
 * Check if given position is within range.
 * Both start and end are inclusive.
 * @param position
 * @param range
 */
export declare function is_within_range(position: CodeEditor.IPosition, range: CodeEditor.IRange): boolean;
/**
 * a virtual implementation of IDocumentInfo
 */
export declare class VirtualDocumentInfo implements IDocumentInfo {
    private _document;
    version: number;
    constructor(document: VirtualDocument);
    get text(): string;
    get uri(): string;
    get languageId(): string;
}
export declare namespace VirtualDocument {
    interface IOptions {
        language: LanguageIdentifier;
        foreign_code_extractors: IForeignCodeExtractorsRegistry;
        overrides_registry: ICodeOverridesRegistry;
        path: string;
        file_extension: string | undefined;
        console: ILSPLogConsole;
        /**
         * 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.
         */
        has_lsp_supported_file: 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?: 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 {
    language: string;
    last_virtual_line: number;
    foreign_document_closed: Signal<VirtualDocument, IForeignContext>;
    foreign_document_opened: Signal<VirtualDocument, IForeignContext>;
    readonly instance_id: number;
    protected console: ILSPLogConsole;
    standalone: boolean;
    isDisposed: boolean;
    /**
     * the remote document uri, version and other server-related info
     */
    document_info: IDocumentInfo;
    /**
     * Virtual lines keep all the lines present in the document AND extracted to the foreign document.
     */
    virtual_lines: Map<number, IVirtualLine>;
    protected source_lines: Map<number, ISourceLine>;
    foreign_extractors: IForeignCodeExtractor[];
    overrides_registry: ICodeOverridesRegistry;
    protected foreign_extractors_registry: IForeignCodeExtractorsRegistry;
    protected line_blocks: Array<string>;
    protected unused_documents: Set<VirtualDocument>;
    protected unused_standalone_documents: DefaultMap<language, Array<VirtualDocument>>;
    private _remaining_lifetime;
    private cell_magics_overrides;
    private line_magics_overrides;
    private static instances_count;
    foreign_documents: Map<VirtualDocument.virtual_id, VirtualDocument>;
    blank_lines_between_cells: number;
    last_source_line: number;
    private previous_value;
    changed: Signal<VirtualDocument, VirtualDocument>;
    path: string;
    file_extension: string | undefined;
    has_lsp_supported_file: boolean;
    parent?: VirtualDocument | null;
    private readonly options;
    update_manager: UpdateManager;
    constructor(options: VirtualDocument.IOptions);
    dispose(): 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 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 remaining_lifetime(): number;
    protected set remaining_lifetime(value: number);
    clear(): void;
    private forward_closed_signal;
    private forward_opened_signal;
    private open_foreign;
    document_at_source_position(position: ISourcePosition): VirtualDocument;
    is_within_foreign(source_position: ISourcePosition): boolean;
    virtual_position_at_document(source_position: ISourcePosition): IVirtualPosition;
    private choose_foreign_document;
    extract_foreign_code(block: ICodeBlockOptions, editor_shift: CodeEditor.IPosition): {
        cell_code_kept: string;
        foreign_document_map: Map<CodeEditor.IRange, IVirtualDocumentBlock>;
    };
    decode_code_block(raw_code: string): string;
    prepare_code_block(block: ICodeBlockOptions, editor_shift?: CodeEditor.IPosition): {
        lines: string[];
        foreign_document_map: Map<CodeEditor.IRange, IVirtualDocumentBlock>;
        skip_inspect: string[][];
    };
    get foreign_document_maps(): ForeignDocumentsMap[];
    append_code_block(block: ICodeBlockOptions, editor_shift?: CodeEditor.IPosition, virtual_shift?: CodeEditor.IPosition): void;
    get value(): string;
    get last_line(): string;
    close_expired_documents(): void;
    close_foreign(document: VirtualDocument): void;
    close_all_foreign_documents(): void;
    get virtual_id(): VirtualDocument.virtual_id;
    get ancestry(): Array<VirtualDocument>;
    get id_path(): VirtualDocument.id_path;
    get uri(): VirtualDocument.uri;
    transform_source_to_editor(pos: ISourcePosition): IEditorPosition;
    /**
    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.
    */
    transform_virtual_to_editor(virtual_position: IVirtualPosition): IEditorPosition | null;
    /**
    Can be null because some lines are added as padding/anchors
    to the virtual document and those do not exist in the source document.
    */
    transform_virtual_to_source(position: IVirtualPosition): ISourcePosition | null;
    get root(): VirtualDocument;
    get_editor_at_virtual_line(pos: IVirtualPosition): CodeEditor.IEditor;
    get_editor_at_source_line(pos: ISourcePosition): CodeEditor.IEditor;
    /**
     * Recursively emits changed signal from the document or any descendant foreign document.
     */
    maybe_emit_changed(): void;
}
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 id_path = string;
    /**
     * Instance identifier for standalone documents (snippets), or language identifier
     * for documents which should be interpreted as one when stretched across cells.
     */
    type virtual_id = string;
    /**
     * Identifier composed of the file path and id_path.
     */
    type uri = string;
}
export declare function collect_documents(virtual_document: VirtualDocument): Set<VirtualDocument>;
export interface IBlockAddedInfo {
    virtual_document: VirtualDocument;
    block: ICodeBlockOptions;
}
export declare class UpdateManager {
    private virtual_document;
    console: ILSPLogConsole;
    /**
     * Virtual documents update guard.
     */
    private is_update_in_progress;
    private update_lock;
    protected isDisposed: boolean;
    /**
     * Signal emitted by the editor that triggered the update, providing the root document of the updated documents.
     */
    private document_updated;
    block_added: Signal<UpdateManager, IBlockAddedInfo>;
    update_done: Promise<void>;
    update_began: Signal<UpdateManager, ICodeBlockOptions[]>;
    update_finished: Signal<UpdateManager, ICodeBlockOptions[]>;
    constructor(virtual_document: VirtualDocument, console: ILSPLogConsole);
    dispose(): void;
    /**
     * Once all the foreign documents were refreshed, the unused documents (and their connections)
     * should be terminated if their lifetime has expired.
     */
    private on_updated;
    private can_update;
    /**
     * 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
     */
    with_update_lock(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.
     */
    update_documents(blocks: ICodeBlockOptions[]): Promise<void>;
}
export {};
