/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { type AnchorNode, type FieldKey, type MapTree, type TreeNodeSchemaIdentifier, type TreeValue, type Value } from "../../core/index.js";
import { type FlexTreeContext, FlexTreeEntityKind, type FlexTreeField, type FlexTreeFieldNode, type FlexTreeLeafNode, type FlexTreeMapNode, type FlexTreeNode, type FlexTreeNodeEvents, type FlexTreeTypedField, type FlexTreeTypedNode, type FlexTreeTypedNodeUnion, type FlexTreeUnboxField, type FlexibleFieldContent, TreeStatus, flexTreeMarker } from "../flex-tree/index.js";
import { type FlexAllowedTypes, type FlexFieldNodeSchema, FlexFieldSchema, type FlexMapNodeSchema, type FlexTreeNodeSchema, type LeafNodeSchema } from "../typed-schema/index.js";
import type { FlexFieldKind } from "../modular-schema/index.js";
import { type Listenable } from "../../events/index.js";
/**
 * A readonly {@link FlexTreeNode} which wraps a {@link MapTree}.
 * @remarks Reading data from the MapTreeNode will read the corresponding data from the {@link MapTree}.
 * Create a `MapTreeNode` by calling {@link getOrCreateMapTreeNode}.
 */
export interface MapTreeNode extends FlexTreeNode {
    readonly mapTree: MapTree;
    forwardEvents(to: Listenable<FlexTreeNodeEvents>): void;
}
/**
 * Checks if the given {@link FlexTreeNode} is a {@link MapTreeNode}.
 */
export declare function isMapTreeNode(flexNode: FlexTreeNode): flexNode is MapTreeNode;
/** A node's parent field and its index in that field */
interface LocationInField {
    readonly parent: MapTreeField<FlexAllowedTypes>;
    readonly index: number;
}
/**
 * A readonly implementation of {@link FlexTreeNode} which wraps a {@link MapTree}.
 * @remarks Any methods that would mutate the node will fail,
 * as will the querying of data specific to the {@link LazyTreeNode} implementation (e.g. {@link FlexTreeNode.context}).
 * MapTreeNodes are unconditionally cached -
 * when retrieved via {@link getOrCreateNode}, the same {@link MapTree} object will always produce the same `MapTreeNode` object.
 */
export declare class EagerMapTreeNode<TSchema extends FlexTreeNodeSchema> implements MapTreeNode {
    readonly schema: TSchema;
    /** The underlying {@link MapTree} that this `MapTreeNode` reads its data from */
    readonly mapTree: MapTree;
    private location;
    readonly [flexTreeMarker]: FlexTreeEntityKind.Node;
    private readonly events;
    forwardEvents(to: Listenable<FlexTreeNodeEvents>): void;
    /**
     * Create a new MapTreeNode.
     * @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 MapTreeNode from a {@link MapTree}.
     * A `MapTreeNode` may never be constructed more than once for the same {@link MapTree} object.
     * Instead, it should always be acquired via {@link getOrCreateNode}.
     */
    constructor(schema: TSchema, 
    /** The underlying {@link MapTree} that this `MapTreeNode` reads its data from */
    mapTree: MapTree, location: LocationInField | undefined);
    get type(): TreeNodeSchemaIdentifier;
    /**
     * Set this node's parentage (see {@link FlexTreeNode.parentField}).
     * @remarks A node may only be adopted to a new parent one time, and only if it was not constructed with a parent.
     */
    adopt(parent: MapTreeField<FlexAllowedTypes>, 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 rootMapTreeField} as the parent.
     */
    get parentField(): LocationInField;
    is<TSchemaInner extends FlexTreeNodeSchema>(schema: TSchemaInner): this is FlexTreeTypedNode<TSchemaInner>;
    tryGetField(key: FieldKey): MapTreeField<FlexAllowedTypes> | undefined;
    getBoxed(key: string): FlexTreeField;
    boxedIterator(): IterableIterator<FlexTreeField>;
    treeStatus(): TreeStatus;
    get value(): Value;
    on<K extends keyof FlexTreeNodeEvents>(eventName: K, listener: FlexTreeNodeEvents[K]): () => void;
    get context(): FlexTreeContext;
    get anchorNode(): AnchorNode;
    private walkTree;
}
/**
 * The implementation of a field node created by {@link getOrCreateNode}.
 */
export declare class EagerMapTreeFieldNode<TSchema extends FlexFieldNodeSchema> extends EagerMapTreeNode<TSchema> implements FlexTreeFieldNode<TSchema> {
    get content(): FlexTreeUnboxField<TSchema["info"]>;
    get boxedContent(): FlexTreeTypedField<TSchema["info"]>;
    getBoxed(key: string): FlexTreeTypedField<TSchema["info"]>;
}
/**
 * The implementation of a map node created by {@link getOrCreateNode}.
 */
export declare class EagerMapTreeMapNode<TSchema extends FlexMapNodeSchema> extends EagerMapTreeNode<TSchema> implements FlexTreeMapNode<TSchema> {
    get size(): number;
    has(key: string): boolean;
    get(key: string): FlexTreeUnboxField<TSchema["info"]>;
    keys(): IterableIterator<FieldKey>;
    values(): IterableIterator<FlexTreeUnboxField<TSchema["info"], "notEmpty">>;
    entries(): IterableIterator<[
        FieldKey,
        FlexTreeUnboxField<TSchema["info"], "notEmpty">
    ]>;
    forEach(callbackFn: (value: FlexTreeUnboxField<TSchema["info"], "notEmpty">, key: FieldKey, map: FlexTreeMapNode<TSchema>) => void, thisArg?: unknown): void;
    getBoxed(key: string): FlexTreeTypedField<TSchema["info"]>;
    set(key: string, value: FlexibleFieldContent<TSchema["info"]> | undefined): void;
    delete(key: string): void;
    [Symbol.iterator](): IterableIterator<[
        FieldKey,
        FlexTreeUnboxField<TSchema["info"], "notEmpty">
    ]>;
    boxedIterator(): IterableIterator<FlexTreeTypedField<TSchema["info"]>>;
}
declare class EagerMapTreeLeafNode<TSchema extends LeafNodeSchema> extends EagerMapTreeNode<TSchema> implements FlexTreeLeafNode<TSchema> {
    get value(): TreeValue<TSchema["info"]>;
}
/**
 * A special singleton that is the implicit parent field of all un-parented {@link EagerMapTreeNode}s.
 * @remarks This exists because {@link EagerMapTreeNode.parentField} must return a field.
 * If a {@link EagerMapTreeNode} is created without a parent, its {@link EagerMapTreeNode.parentField} property will point to this object.
 * However, this field cannot be used in any practical way because it is empty, i.e. it does not actually contain the children that claim to be parented under it.
 * It has the "empty" schema and it will always contain zero children if queried.
 */
export declare const rootMapTreeField: MapTreeField<FlexAllowedTypes>;
declare class MapTreeField<T extends FlexAllowedTypes> implements FlexTreeField {
    readonly schema: FlexFieldSchema<FlexFieldKind, T>;
    readonly key: FieldKey;
    readonly parent: FlexTreeNode | undefined;
    readonly mapTrees: readonly MapTree[];
    [flexTreeMarker]: FlexTreeEntityKind.Field;
    constructor(schema: FlexFieldSchema<FlexFieldKind, T>, key: FieldKey, parent: FlexTreeNode | undefined, mapTrees: readonly MapTree[]);
    get length(): number;
    is<TSchemaInner extends FlexFieldSchema>(schema: TSchemaInner): this is FlexTreeTypedField<TSchemaInner>;
    isSameAs(other: FlexTreeField): boolean;
    boxedIterator(): IterableIterator<FlexTreeTypedNodeUnion<T>>;
    boxedAt(index: number): FlexTreeTypedNodeUnion<T> | undefined;
    get context(): FlexTreeContext;
    treeStatus(): TreeStatus;
}
/**
 * If there exists a {@link EagerMapTreeNode} for the given {@link MapTree}, returns it, otherwise returns `undefined`.
 * @remarks {@link EagerMapTreeNode | MapTreeNodes} are created via {@link getOrCreateNode}.
 */
export declare function tryGetMapTreeNode(mapTree: MapTree): MapTreeNode | undefined;
/**
 * Create a {@link MapTreeNode} 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`.
 */
export declare function getOrCreateMapTreeNode(nodeSchema: FlexTreeNodeSchema, mapTree: MapTree): MapTreeNode;
/**
 * Create a {@link EagerMapTreeNode} 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`.
 * This function is exported for the purposes of unit testing.
 */
export declare function getOrCreateNode<TSchema extends LeafNodeSchema>(nodeSchema: TSchema, mapTree: MapTree): EagerMapTreeLeafNode<TSchema>;
export declare function getOrCreateNode<TSchema extends FlexMapNodeSchema>(nodeSchema: TSchema, mapTree: MapTree): EagerMapTreeMapNode<TSchema>;
export declare function getOrCreateNode<TSchema extends FlexFieldNodeSchema>(nodeSchema: TSchema, mapTree: MapTree): EagerMapTreeFieldNode<TSchema>;
export declare function getOrCreateNode<TSchema extends FlexTreeNodeSchema>(nodeSchema: TSchema, mapTree: MapTree): EagerMapTreeNode<TSchema>;
export declare function unsupportedUsageError(message?: string): Error;
export {};
//# sourceMappingURL=mapTreeNode.d.ts.map