/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { type SchemaAndPolicy, type ExclusiveMapTree } from "../core/index.js";
import { type NodeKeyManager } from "../feature-libraries/index.js";
import { type ImplicitAllowedTypes, type ImplicitFieldSchema } from "./schemaTypes.js";
import { type TreeNode, type TreeNodeSchema, type Unhydrated } from "./core/index.js";
import { SchemaValidationErrors } from "../feature-libraries/index.js";
import type { IFluidHandle } from "@fluidframework/core-interfaces";
/**
 * Module notes:
 *
 * The flow of the below code is in terms of the structure of the input data. We then verify that the associated
 * schema is appropriate for that kind of data. This is fine while we have a 1:1 mapping of kind of input data to
 * the kind of schema we expect for it (e.g. an input that is an array always need to be associated with a sequence in
 * the schema). If/when we begin accepting kinds of input data that are ambiguous (e.g. accepting an input that is an
 * array of key/value tuples to instantiate a map) we may need to rethink the structure here to be based more on the
 * schema than on the input data.
 */
/**
 * Transforms an input {@link TypedNode} tree to a {@link MapTree}.
 * @param data - The input tree to be converted.
 * If the data is an unsupported value (e.g. NaN), a fallback value will be used when supported,
 * otherwise an error will be thrown.
 *
 * Fallbacks:
 *
 * * `NaN` =\> `null`
 *
 * * `+/-∞` =\> `null`
 *
 * * `-0` =\> `+0`
 *
 * For fields with a default value, the field may be omitted.
 * If `context` is not provided, defaults which require a context will be left empty which can be out of schema.
 *
 * @param allowedTypes - The set of types allowed by the parent context. Used to validate the input tree.
 * @param context - An optional context which, if present, will allow defaults to be created by {@link ContextualFieldProvider}s.
 * If absent, only defaults from {@link ConstantFieldProvider}s will be created.
 * @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema
 * validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will
 * be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.
 *
 * TODO:BUG: AB#9131
 * This schema validation is done before defaults are provided.
 * This can not easily be fixed by reordering things within this implementation since even at the end of this function defaults requiring a context may not have been filled.
 * This means schema validation reject required fields getting their value from a default like identifier fields.
 *
 * @remarks The resulting tree will be populated with any defaults from {@link FieldProvider}s in the schema.
 *
 * @privateRemarks
 * TODO: AB#9126 AB#9131
 * When an app wants schema validation, we should ensure data is validated. Doing the validation here is not robust (since many callers to this don't have a context and thus can't opt into validation).
 * Additionally the validation here does not correctly handle default values, and introduces a second schema representation which is a bit odd API wise as its typically derivable from the view schema.
 * It may make more sense to validate when hydrating the MapTreeNode when the context is known and the defaults are available.
 * Applying the "parse don't validate" idiom here could help ensuring we capture when the validation optionally happens in the type system to avoid missing or redundant validation,
 * as well as ensuring validation happens after defaulting (or can handle validating data missing defaults)
 */
export declare function mapTreeFromNodeData(data: InsertableContent, allowedTypes: ImplicitAllowedTypes, context?: NodeKeyManager, schemaValidationPolicy?: SchemaAndPolicy): ExclusiveMapTree;
export declare function mapTreeFromNodeData(data: InsertableContent | undefined, allowedTypes: ImplicitFieldSchema, context?: NodeKeyManager, schemaValidationPolicy?: SchemaAndPolicy): ExclusiveMapTree | undefined;
/**
 * Throws a UsageError if maybeError indicates a tree is out of schema.
 */
export declare function inSchemaOrThrow(maybeError: SchemaValidationErrors): void;
/**
 * @returns all types for which the data is schema-compatible.
 */
export declare function getPossibleTypes(allowedTypes: ReadonlySet<TreeNodeSchema>, data: FactoryContent): TreeNodeSchema[];
/**
 * Walk the given {@link ExclusiveMapTree} and deeply provide any field defaults for fields that are missing in the tree but present in the schema.
 * @param mapTree - The tree to populate with defaults. This is borrowed: no references to it are kept by this function.
 * @param allowedTypes - Some {@link TreeNodeSchema}, at least one of which the input tree must conform to
 * @param context - An optional context for generating defaults.
 * If present, all applicable defaults will be provided.
 * If absent, only defaults produced by a {@link ConstantFieldProvider} will be provided, and defaults produced by a {@link ContextualFieldProvider} will be ignored.
 * @remarks This function mutates the input tree by deeply adding new fields to the field maps where applicable.
 */
export declare function addDefaultsToMapTree(mapTree: ExclusiveMapTree, allowedTypes: ImplicitAllowedTypes, context: NodeKeyManager | undefined): void;
/**
 * Content which can be used to build a node.
 * @remarks
 * Can contain unhydrated nodes, but can not be an unhydrated node at the root.
 * @system @alpha
 */
export type FactoryContent = IFluidHandle | string | number | boolean | null | Iterable<readonly [string, InsertableContent]> | readonly InsertableContent[] | FactoryContentObject;
/**
 * Record-like object which can be used to build some kinds of nodes.
 * @remarks
 * Can contain unhydrated nodes, but can not be an unhydrated node at the root.
 *
 * Supports object and map nodes.
 * @system @alpha
 */
export type FactoryContentObject = {
    readonly [P in string]?: InsertableContent;
};
/**
 * Content which can be inserted into a tree.
 * @system @alpha
 */
export type InsertableContent = Unhydrated<TreeNode> | FactoryContent;
//# sourceMappingURL=toMapTree.d.ts.map