/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { IFluidHandle } from "@fluidframework/core-interfaces";
import { AllowedTypes, TreeFieldSchema, ObjectNodeSchema, TreeNodeSchema, MapNodeSchema, FieldNodeSchema, FlexTreeSequenceField, FlexTreeNode, FlexTreeTypedField } from "../feature-libraries";
import { type TreeNodeSchema as TreeNodeSchemaClass } from "../class-tree";
import { TreeListNodeOld } from "./treeListNode";
import { TreeField, TypedNode, TreeMapNode, TreeObjectNode, TreeNode, Unhydrated } from "./types";
import { InsertableTypedNode } from "./insertable";
/** Retrieve the associated proxy for the given field. */
export declare function getProxyForField<TSchema extends TreeFieldSchema>(field: FlexTreeTypedField<TSchema>): TreeField<TSchema>;
/**
 * A symbol for storing TreeNodeSchemaClass on FlexTreeNode's schema.
 */
export declare const simpleSchemaSymbol: unique symbol;
export declare function getClassSchema(schema: TreeNodeSchema): TreeNodeSchemaClass | undefined;
export declare function getOrCreateNodeProxy<TSchema extends TreeNodeSchema>(flexNode: FlexTreeNode): TypedNode<TSchema>;
/**
 * @param flexNode - underlying tree node which this proxy should wrap.
 * @param allowAdditionalProperties - If true, setting of unexpected properties will be forwarded to the target object.
 * Otherwise setting of unexpected properties will error.
 * @param customTargetObject - Target object of the proxy.
 * If not provided an empty collection of the relevant type is used for the target and a separate object created to dispatch methods.
 * If provided, the customTargetObject will be used as both the dispatch object and the proxy target, and therefor must provide needed functionality depending on the schema kind.
 */
export declare function createNodeProxy<TSchema extends TreeNodeSchema>(flexNode: FlexTreeNode, allowAdditionalProperties: boolean, targetObject?: object): TypedNode<TSchema>;
/**
 * @param allowAdditionalProperties - If true, setting of unexpected properties will be forwarded to the target object.
 * Otherwise setting of unexpected properties will error.
 * @param customTargetObject - Target object of the proxy.
 * If not provided `{}` is used for the target.
 */
export declare function createObjectProxy<TSchema extends ObjectNodeSchema>(schema: TSchema, allowAdditionalProperties: boolean, targetObject?: object): TreeObjectNode<TSchema>;
/**
 * Given a list proxy, returns its underlying LazySequence field.
 */
export declare const getSequenceField: <TTypes extends AllowedTypes>(list: TreeListNodeOld) => FlexTreeSequenceField<TTypes>;
/**
 * PropertyDescriptorMap used to build the prototype for our SharedListNode dispatch object.
 */
export declare const listPrototypeProperties: PropertyDescriptorMap;
export declare const mapStaticDispatchMap: PropertyDescriptorMap;
/**
 * Create a proxy to a {@link TreeObjectNode} that is backed by a raw object node (see {@link createRawNode}).
 * @param schema - the schema of the object node
 * @param content - the content to be stored in the raw node.
 * A copy of content is stored, the input `content` is not modified and can be safely reused in another call to {@link createRawObjectProxy}.
 * @param allowAdditionalProperties - If true, setting of unexpected properties will be forwarded to the target object.
 * Otherwise setting of unexpected properties will error.
 * @param customTargetObject - Target object of the proxy.
 * If not provided `{}` is used for the target.
 * @remarks
 * Because this proxy is backed by a raw node, it has the same limitations as the node created by {@link createRawNode}.
 * Most of its properties and methods will error if read/called.
 */
export declare function createRawNodeProxy<TSchema extends ObjectNodeSchema>(schema: TSchema, content: InsertableTypedNode<TSchema>, allowAdditionalProperties: boolean, target?: object): Unhydrated<TreeObjectNode<TSchema>>;
export declare function createRawNodeProxy<TSchema extends FieldNodeSchema>(schema: TSchema, content: InsertableTypedNode<TSchema>, allowAdditionalProperties: boolean, target?: object): Unhydrated<TreeListNodeOld<TSchema["info"]["allowedTypes"]>>;
export declare function createRawNodeProxy<TSchema extends MapNodeSchema>(schema: TSchema, content: InsertableTypedNode<TSchema>, allowAdditionalProperties: boolean, target?: object): Unhydrated<TreeMapNode<TSchema>>;
type ProxyHydrator = (flexNode: FlexTreeNode | undefined) => void;
/** The result returned by {@link extractFactoryContent} and its related helpers. */
interface ExtractedFactoryContent<out T = FactoryContent> {
    /** The content with the factory subtrees replaced. */
    readonly content: T;
    /**
     * A function which walks all factory-created object that underwent replacement/extraction.
     * Before hydration, those objects are unusable (see {@link createRawObjectProxy}).
     * However, after the content is fully inserted into the tree the `hydrateProxies` function may be invoked in order to update the contents of these objects such that they become a mirror of the content in the tree.
     * This must be done before any calls to {@link getOrCreateNodeProxy} so that the "edit node to proxy" mapping is correctly updated (see {@link setFlexNode}).
     */
    readonly hydrateProxies: ProxyHydrator;
}
/**
 * Given a content tree that is to be inserted into the shared tree, replace all subtrees that were created by factories
 * (via {@link SharedTreeObjectFactory.create}) with the content that was passed to those factories.
 * @param content - the content being inserted which may be, and/or may contain, factory-created content
 * @param insertedAtIndex - if the content being inserted is list content, this must be the index in the list at which the content is being inserted
 * @returns the result of the content replacement and a {@link ExtractedFactoryContent.hydrateProxies} function which must be invoked if present.
 * @remarks
 * This functions works recursively.
 * Factory-created objects that are nested inside of the content passed to other factory-created objects, and so on, will be in-lined.
 * This function also adds the hidden {@link typeNameSymbol} of each object schema to the output.
 * @example
 * ```ts
 * const x = foo.create({
 *   a: 3, b: bar.create({
 *     c: [baz.create({ d: 5 })]
 *   })
 * });
 * const y = extractFactoryContent(x);
 * y === {
 *   [typeNameSymbol]: "foo", a: 3, b: {
 *     [typeNameSymbol]: "bar", c: [{ [typeNameSymbol]: "baz", d: 5 }]
 *  }
 * }
 * ```
 */
export declare function extractFactoryContent(input: InsertableContent, insertedAtIndex?: number): ExtractedFactoryContent;
/**
 * Content which can be used to build a node.
 * @remarks
 * Can contain unhydrated nodes, but can not be an unhydrated node at the root.
 */
export type FactoryContent = IFluidHandle | string | number | boolean | null | ReadonlyMap<string, InsertableContent> | readonly InsertableContent[] | {
    readonly [P in string]?: InsertableContent;
};
/**
 * Content which can be inserted into a tree.
 */
export type InsertableContent = Unhydrated<TreeNode> | FactoryContent;
export {};
//# sourceMappingURL=proxies.d.ts.map