/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { Listenable } from "@fluidframework/core-interfaces";
import { type AnchorEvents, type AnchorNode, type ExclusiveMapTree, type FieldKey, type FieldKindIdentifier, type FieldUpPath, type ITreeCursorSynchronous, type MapTree, type SchemaPolicy, type TreeNodeSchemaIdentifier, type TreeNodeStoredSchema, type TreeStoredSchema, type Value } from "../../core/index.js";
import { type FlexTreeContext, FlexTreeEntityKind, type FlexTreeField, type FlexTreeNode, type FlexTreeSequenceField, type FlexTreeTypedField, type FlexTreeUnknownUnboxed, flexTreeMarker, type FlexTreeHydratedContext, type FlexFieldKind, type SequenceFieldEditBuilder } from "../../feature-libraries/index.js";
import type { Context } from "./context.js";
interface UnhydratedTreeSequenceFieldEditBuilder extends SequenceFieldEditBuilder<ExclusiveMapTree[]> {
    /**
     * Issues a change which removes `count` elements starting at the given `index`.
     * @param index - The index of the first removed element.
     * @param count - The number of elements to remove.
     * @returns the MapTrees that were removed
     */
    remove(index: number, count: number): ExclusiveMapTree[];
}
type UnhydratedFlexTreeNodeEvents = Pick<AnchorEvents, "childrenChangedAfterBatch">;
/** A node's parent field and its index in that field */
interface LocationInField {
    readonly parent: FlexTreeField;
    readonly index: number;
}
/**
 * An unhydrated implementation of {@link FlexTreeNode} which wraps a {@link MapTree}.
 * @remarks
 * MapTreeNodes are unconditionally cached -
 * when retrieved via {@link getOrCreateNode}, the same {@link MapTree} object will always produce the same `UnhydratedFlexTreeNode` object.
 *
 * Create a `UnhydratedFlexTreeNode` by calling {@link getOrCreate}.
 */
export declare class UnhydratedFlexTreeNode implements UnhydratedFlexTreeNode {
    readonly simpleContext: Context;
    /** The underlying {@link MapTree} that this `UnhydratedFlexTreeNode` reads its data from */
    readonly mapTree: ExclusiveMapTree;
    private location;
    get schema(): TreeNodeSchemaIdentifier;
    get storedSchema(): TreeNodeStoredSchema;
    readonly [flexTreeMarker]: FlexTreeEntityKind.Node;
    private readonly _events;
    get events(): Listenable<UnhydratedFlexTreeNodeEvents>;
    /**
     * Create a {@link UnhydratedFlexTreeNode} that wraps the given {@link MapTree}, or get the node that already exists for that {@link MapTree} if there is one.
     * @param nodeSchema - the {@link FlexTreeNodeSchema | schema} that the node conforms to
     * @param mapTree - the {@link MapTree} containing the data for this node.
     * @remarks It must conform to the `nodeSchema`.
     */
    static getOrCreate(context: Context, mapTree: ExclusiveMapTree): UnhydratedFlexTreeNode;
    get context(): FlexTreeContext;
    /**
     * Create a new UnhydratedFlexTreeNode.
     * @param location - the parentage of this node, if it is being created underneath an existing node and field, or undefined if not
     * @remarks This class (and its subclasses) should not be directly constructed outside of this module.
     * Instead, use {@link getOrCreateNode} to create a UnhydratedFlexTreeNode from a {@link MapTree}.
     * A `UnhydratedFlexTreeNode` may never be constructed more than once for the same {@link MapTree} object.
     * Instead, it should always be acquired via {@link getOrCreateNode}.
     */
    constructor(simpleContext: Context, 
    /** The underlying {@link MapTree} that this `UnhydratedFlexTreeNode` reads its data from */
    mapTree: ExclusiveMapTree, location?: LocationInField);
    get type(): TreeNodeSchemaIdentifier;
    /**
     * Set this node's parentage (see {@link FlexTreeNode.parentField}).
     * @remarks The node may be given a parent if it has none, or may have its parent removed (by passing `undefined`).
     * However, a node with a parent may not be directly re-assigned a different parent.
     * That likely indicates either an attempted multi-parenting or an attempt to "move" the node, neither of which are supported.
     * Removing a node's parent twice in a row is also not supported, as it likely indicates a bug.
     */
    adoptBy(parent: undefined): void;
    adoptBy(parent: UnhydratedFlexTreeField, index: number): void;
    /**
     * The field this tree is in, and the index within that field.
     * @remarks If this node is unparented, this method will return the special {@link unparentedLocation} as the parent.
     */
    get parentField(): LocationInField;
    borrowCursor(): ITreeCursorSynchronous;
    tryGetField(key: FieldKey): UnhydratedFlexTreeField | undefined;
    getBoxed(key: string): FlexTreeField;
    boxedIterator(): IterableIterator<FlexTreeField>;
    keys(): IterableIterator<FieldKey>;
    get value(): Value;
    get anchorNode(): AnchorNode;
    private walkTree;
    private emitChangedEvent;
}
/**
 * Implementation of `FlexTreeContext`.
 *
 * @remarks An editor is required to edit the FlexTree.
 */
export declare class UnhydratedContext implements FlexTreeContext {
    readonly schemaPolicy: SchemaPolicy;
    readonly schema: TreeStoredSchema;
    /**
     * @param flexSchema - Schema to use when working with the tree.
     */
    constructor(schemaPolicy: SchemaPolicy, schema: TreeStoredSchema);
    isHydrated(): this is FlexTreeHydratedContext;
}
declare class UnhydratedFlexTreeField implements FlexTreeField {
    readonly simpleContext: Context;
    readonly schema: FieldKindIdentifier;
    readonly key: FieldKey;
    readonly parent: UnhydratedFlexTreeNode;
    readonly onEdit?: (() => void) | undefined;
    [flexTreeMarker]: FlexTreeEntityKind.Field;
    get context(): FlexTreeContext;
    constructor(simpleContext: Context, schema: FieldKindIdentifier, key: FieldKey, parent: UnhydratedFlexTreeNode, onEdit?: (() => void) | undefined);
    get mapTrees(): readonly ExclusiveMapTree[];
    get length(): number;
    is<TKind2 extends FlexFieldKind>(kind: TKind2): this is FlexTreeTypedField<TKind2>;
    boxedIterator(): IterableIterator<FlexTreeNode>;
    boxedAt(index: number): FlexTreeNode | undefined;
    /**
     * Mutate this field.
     * @param edit - A function which receives the current `MapTree`s that comprise the contents of the field so that it may be mutated.
     * The function may mutate the array in place or return a new array.
     * If a new array is returned then it will be used as the new contents of the field, otherwise the original array will be continue to be used.
     * @remarks All edits to the field (i.e. mutations of the field's MapTrees) should be directed through this function.
     * This function ensures that the parent MapTree has no empty fields (which is an invariant of `MapTree`) after the mutation.
     */
    protected edit(edit: (mapTrees: ExclusiveMapTree[]) => void | ExclusiveMapTree[]): void;
    getFieldPath(): FieldUpPath;
    /** Unboxes leaf nodes to their values */
    protected unboxed(index: number): FlexTreeUnknownUnboxed;
}
export declare class UnhydratedTreeSequenceField extends UnhydratedFlexTreeField implements FlexTreeSequenceField {
    readonly editor: UnhydratedTreeSequenceFieldEditBuilder;
    at(index: number): FlexTreeUnknownUnboxed | undefined;
    map<U>(callbackfn: (value: FlexTreeUnknownUnboxed, index: number) => U): U[];
    [Symbol.iterator](): IterableIterator<FlexTreeUnknownUnboxed>;
}
/**
 * If there exists a {@link UnhydratedFlexTreeNode} for the given {@link MapTree}, returns it, otherwise returns `undefined`.
 * @remarks {@link UnhydratedFlexTreeNode | UnhydratedFlexTreeNodes} are created via {@link getOrCreateNode}.
 */
export declare function tryUnhydratedFlexTreeNode(mapTree: MapTree): UnhydratedFlexTreeNode | undefined;
export declare function unsupportedUsageError(message?: string): Error;
export {};
//# sourceMappingURL=unhydratedFlexTree.d.ts.map