/*!
 * 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 FieldKey, type FieldKindIdentifier, type ITreeCursorSynchronous, type NodeData, type NormalizedFieldUpPath, type SchemaPolicy, type TreeNodeSchemaIdentifier, type TreeNodeStoredSchema, type TreeStoredSchema, type TreeValue, type Value } from "../../core/index.js";
import { type FlexTreeContext, FlexTreeEntityKind, type FlexTreeField, type FlexTreeNode, type FlexTreeOptionalField, type FlexTreeSequenceField, type FlexTreeTypedField, type FlexTreeUnknownUnboxed, flexTreeMarker, type FlexTreeHydratedContext, type FlexFieldKind, type FlexibleNodeContent, type FlexTreeHydratedContextMinimal, type FlexibleFieldContent, type MapTreeFieldViewGeneric, type MapTreeNodeViewGeneric, type HydratedFlexTreeNode, type MinimalFieldMap } from "../../feature-libraries/index.js";
import type { Context } from "./context.js";
import type { ContextualFieldProvider } from "../fieldSchema.js";
import type { TreeNode } from "./treeNode.js";
type UnhydratedFlexTreeNodeEvents = Pick<AnchorEvents, "childrenChangedAfterBatch">;
/** A node's parent field and its index in that field */
type LocationInField = FlexTreeNode["parentField"];
/**
 * The {@link Unhydrated} implementation of {@link FlexTreeNode}.
 */
export declare class UnhydratedFlexTreeNode implements FlexTreeNode, MapTreeNodeViewGeneric<UnhydratedFlexTreeNode> {
    /**
     * The {@link NodeData} for this node.
     */
    readonly data: NodeData;
    /**
     * All {@link UnhydratedFlexTreeField} for this node that have been created so far.
     * @remarks
     * This includes all non-empty fields, but also any empty fields which have been previously requested.
     */
    private readonly fieldsAll;
    /**
     * The {@link Context} for this node.
     * @remarks
     * Provides access to all schema reachable from this node.
     * See {@link getUnhydratedContext}.
     */
    readonly simpleContext: Context;
    isHydrated(): this is HydratedFlexTreeNode;
    private location;
    get storedSchema(): TreeNodeStoredSchema;
    /**
     * Cache storing the {@link TreeNode} for this inner node.
     * @remarks
     * When creating a `TreeNode` for this `UnhydratedFlexTreeNode`, cache the `TreeNode` in this property.
     * Currently this is done by {@link TreeNodeKernel}.
     *
     * See {@link getOrCreateNodeFromInnerNode} how to get the `TreeNode`, even if not already created, regardless of hydration status.
     */
    treeNode: TreeNode | undefined;
    readonly [flexTreeMarker]: FlexTreeEntityKind.Node;
    private readonly _events;
    get events(): Listenable<UnhydratedFlexTreeNodeEvents>;
    get context(): FlexTreeContext;
    /**
     * Create a new UnhydratedFlexTreeNode.
     */
    constructor(
    /**
     * The {@link NodeData} for this node.
     */
    data: NodeData, 
    /**
     * All {@link UnhydratedFlexTreeField} for this node that have been created so far.
     * @remarks
     * This includes all non-empty fields, but also any empty fields which have been previously requested.
     */
    fieldsAll: Map<FieldKey, UnhydratedFlexTreeField>, 
    /**
     * The {@link Context} for this node.
     * @remarks
     * Provides access to all schema reachable from this node.
     * See {@link getUnhydratedContext}.
     */
    simpleContext: Context);
    /**
     * The non-empty fields on this node.
     * @remarks
     * This is needed to implement {@link MapTreeNodeViewGeneric.fields}, which must omit empty fields.
     * Due to having to detect if a field is empty, this forces the evaluation of any pending defaults in the fields.
     * Use {@link allFieldsLazy} to avoid evaluating pending defaults.
     */
    readonly fields: MinimalFieldMap<UnhydratedFlexTreeField>;
    [Symbol.iterator](): IterableIterator<UnhydratedFlexTreeField>;
    /**
     * Gets all fields, without filtering out empty ones.
     * @remarks
     * This avoids forcing the evaluating of pending defaults in the fields, and also saves a copy on access.
     */
    get allFieldsLazy(): ReadonlyMap<FieldKey, UnhydratedFlexTreeField>;
    get type(): TreeNodeSchemaIdentifier;
    private getOrCreateField;
    /**
     * 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): UnhydratedFlexTreeField;
    keys(): IterableIterator<FieldKey>;
    get value(): Value;
    emitChangedEvent(key: FieldKey): void;
}
/**
 * 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);
    isDisposed(): boolean;
    isHydrated(): this is FlexTreeHydratedContext;
}
/**
 * The {@link Unhydrated} implementation of {@link FlexTreeField}.
 */
export declare class UnhydratedFlexTreeField implements FlexTreeField, MapTreeFieldViewGeneric<UnhydratedFlexTreeNode> {
    readonly context: FlexTreeContext;
    readonly schema: FieldKindIdentifier;
    readonly key: FieldKey;
    /**
     * The children of this field.
     * @remarks
     * This is either an array of {@link UnhydratedFlexTreeNode}s or a {@link ContextualFieldProvider} that will be used to populate the children lazily (after which it will become an array).
     * See {@link fillPendingDefaults}.
     * Note that any fields using a {@link ConstantFieldProvider} should be evaluated before constructing the UnhydratedFlexTreeField.
     */
    private lazyChildren;
    [flexTreeMarker]: FlexTreeEntityKind.Field;
    parent: UnhydratedFlexTreeNode | undefined;
    constructor(context: FlexTreeContext, schema: FieldKindIdentifier, key: FieldKey, 
    /**
     * The children of this field.
     * @remarks
     * This is either an array of {@link UnhydratedFlexTreeNode}s or a {@link ContextualFieldProvider} that will be used to populate the children lazily (after which it will become an array).
     * See {@link fillPendingDefaults}.
     * Note that any fields using a {@link ConstantFieldProvider} should be evaluated before constructing the UnhydratedFlexTreeField.
     */
    lazyChildren: UnhydratedFlexTreeNode[] | ContextualFieldProvider);
    borrowCursor(): ITreeCursorSynchronous;
    private getPendingDefault;
    /**
     * Populate pending default (if present) using the provided context.
     * @remarks
     * This apply to just this field: caller will likely want to recursively walk the tree.
     * @see {@link pendingDefault}.
     */
    fillPendingDefaults(context: FlexTreeHydratedContextMinimal): void;
    /**
     * Returns true if this field has a pending default due to defined defined using a {@link ContextualFieldProvider}.
     */
    get pendingDefault(): boolean;
    get children(): UnhydratedFlexTreeNode[];
    get length(): number;
    is<TKind2 extends FlexFieldKind>(kind: TKind2): this is FlexTreeTypedField<TKind2>;
    boxedAt(index: number): FlexTreeNode | undefined;
    [Symbol.iterator](): IterableIterator<UnhydratedFlexTreeNode>;
    /**
     * 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: UnhydratedFlexTreeNode[]) => void | UnhydratedFlexTreeNode[]): void;
    getFieldPath(): NormalizedFieldUpPath;
    /** Unboxes leaf nodes to their values */
    protected unboxed(index: number): TreeValue | UnhydratedFlexTreeNode;
}
/**
 * The {@link Unhydrated} implementation of {@link FlexTreeOptionalField}.
 */
export declare class UnhydratedOptionalField extends UnhydratedFlexTreeField implements FlexTreeOptionalField {
    readonly editor: {
        set: (newContent: FlexibleNodeContent | undefined) => void;
    };
    get content(): FlexTreeUnknownUnboxed | undefined;
}
/**
 * The {@link Unhydrated} implementation of {@link FlexTreeSequenceField}.
 */
export declare class UnhydratedSequenceField extends UnhydratedFlexTreeField implements FlexTreeSequenceField {
    readonly editor: {
        insert: (index: number, newContent: FlexibleFieldContent) => void;
        remove: (index: number, count: number) => UnhydratedFlexTreeNode[];
    };
    at(index: number): FlexTreeUnknownUnboxed | undefined;
    map<U>(callbackfn: (value: FlexTreeUnknownUnboxed, index: number) => U): U[];
}
/** Creates a field with the given attributes */
export declare function createField(...args: ConstructorParameters<typeof UnhydratedFlexTreeField>): UnhydratedFlexTreeField;
export declare function unsupportedUsageError(message?: string): Error;
export {};
//# sourceMappingURL=unhydratedFlexTree.d.ts.map