/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { FieldKey, Value, TreeNodeStoredSchema, TreeFieldStoredSchema, TreeNodeSchemaIdentifier, TreeTypeSet, MapTree, ITreeCursorSynchronous, TreeStoredSchema, TreeValue } from "../core";
import { FieldKind } from "./modular-schema";
import { AllowedTypes, TreeFieldSchema, TreeNodeSchema } from "./typed-schema";
import { AllowedTypesToFlexInsertableTree, InsertableFlexField, InsertableFlexNode } from "./schema-aware";
import { TreeDataContext } from "./fieldGenerator";
/**
 * This library defines a tree data format that can infer its types from context.
 * It can only be used when the schema is known.
 * The format is optimized for ergonomics when the developer knows the schema,
 * and needs to declare or navigate trees.
 *
 * The format defined here is very tolerant to optimize for flexibility of expressing trees:
 * APIs exposing data in this format should likely further constrain what is allowed.
 * For example guarantee which fields and nodes should be inlined, and that types will be required everywhere.
 *
 * This is from Editable tree one which has been deleted and should no longer be used!
 */
/**
 * Check if NewFieldContent is made of {@link ITreeCursor}s.
 *
 * Useful when APIs want to take in tree data in multiple formats, including cursors.
 */
export declare function areCursors(data: NewFieldContent): data is ITreeCursorSynchronous | readonly ITreeCursorSynchronous[];
/**
 * @returns true iff `schema` trees should default to being viewed as just their value when possible.
 * @deprecated This definition of Primitive is from editable-tree-1 and should not be used.
 * @remarks
 * TODO:
 * This (like most things in this file) works with stored schema doing things that should be done with view schema.
 * This just replicates the old editable-tree policy: this entire file should get replaced with the new factory based approach which has access to view schema to align this with how LeafSchema work.
 * @alpha
 */
export declare function isPrimitive(schema: TreeNodeStoredSchema): boolean;
/**
 * A symbol for the name of the type of a tree in contexts where string keys are already in use for fields.
 * See {@link TreeNodeSchemaIdentifier}.
 * @alpha
 */
export declare const typeNameSymbol: unique symbol;
/**
 * A symbol for the value of a tree node in contexts where string keys are already in use for fields.
 * @alpha
 */
export declare const valueSymbol: unique symbol;
/**
 * Checks if a value is a {@link TreeValue}.
 */
export declare function isTreeValue(nodeValue: unknown): nodeValue is TreeValue;
/**
 * @returns the key and the schema of the primary field out of the given tree schema.
 *
 * See note on {@link EmptyKey} for what is a primary field.
 * @alpha
 */
export declare function getPrimaryField(schema: TreeNodeStoredSchema): {
    key: FieldKey;
    schema: TreeFieldStoredSchema;
} | undefined;
export declare function getFieldSchema(field: FieldKey, schema: TreeNodeStoredSchema): TreeFieldStoredSchema;
export declare function getFieldKind(fieldSchema: TreeFieldStoredSchema): FieldKind;
/**
 * @returns all allowed child types for `typeSet`.
 */
export declare function getAllowedTypes(schemaData: TreeStoredSchema, typeSet: TreeTypeSet): ReadonlySet<TreeNodeSchemaIdentifier>;
/**
 * @returns all types, for which the data is schema-compatible.
 */
export declare function getPossibleTypes(context: TreeDataContext, typeSet: TreeTypeSet, data: ContextuallyTypedNodeData): TreeNodeSchemaIdentifier[];
/**
 * A symbol used to define a {@link MarkedArrayLike} interface.
 * @alpha
 */
export declare const arrayLikeMarkerSymbol: unique symbol;
/**
 * Can be used to mark a type which works like an array, but is not compatible with `Array.isArray`.
 * @alpha
 */
export interface MarkedArrayLike<TGet, TSet extends TGet = TGet> extends ArrayLikeMut<TGet, TSet> {
    readonly [arrayLikeMarkerSymbol]: true;
    [Symbol.iterator](): IterableIterator<TGet>;
}
/**
 * Can be used to mark a type which works like an array, but is not compatible with `Array.isArray`.
 * @alpha
 */
export interface ReadonlyMarkedArrayLike<T> extends ArrayLike<T> {
    readonly [arrayLikeMarkerSymbol]: true;
    [Symbol.iterator](): IterableIterator<T>;
}
/**
 * `ArrayLike` numeric indexed access, but writable.
 *
 * @remarks
 * Note that due to language limitations, this also allows reading as TSet.
 * This is why `TSet extends TGet` is required.
 *
 * See https://github.com/microsoft/TypeScript/issues/43826.
 * @alpha
 */
export interface ArrayLikeMut<TGet, TSet extends TGet = TGet> extends ArrayLike<TGet> {
    [n: number]: TSet;
}
/**
 * Content of a tree which needs external schema information to interpret.
 *
 * This format is intended for concise authoring of tree literals when the schema is statically known.
 *
 * Once schema aware APIs are implemented, they can be used to provide schema specific subsets of this type.
 * @alpha
 */
export type ContextuallyTypedNodeData = ContextuallyTypedNodeDataObject | number | string | boolean | null | readonly ContextuallyTypedNodeData[] | MarkedArrayLike<ContextuallyTypedNodeData>;
/**
 * Content of a field which needs external schema information to interpret.
 *
 * This format is intended for concise authoring of tree literals when the schema is statically known.
 *
 * Once schema aware APIs are implemented, they can be used to provide schema specific subsets of this type.
 * @alpha
 */
export type ContextuallyTypedFieldData = ContextuallyTypedNodeData | undefined;
/**
 * Checks the type of a `ContextuallyTypedNodeData`.
 */
export declare function isArrayLike(data: ContextuallyTypedFieldData): data is readonly ContextuallyTypedNodeData[] | ReadonlyMarkedArrayLike<ContextuallyTypedNodeData>;
/**
 * Checks the type of a `ContextuallyTypedNodeData`.
 * @alpha
 */
export declare function isContextuallyTypedNodeDataObject(data: ContextuallyTypedNodeData | undefined): data is ContextuallyTypedNodeDataObject;
/**
 * Object case of {@link ContextuallyTypedNodeData}.
 * @alpha
 */
export interface ContextuallyTypedNodeDataObject {
    /**
     * Value stored on this node.
     */
    readonly [valueSymbol]?: Value;
    /**
     * The type of the node.
     * If this node is well-formed, it must follow this schema.
     */
    readonly [typeNameSymbol]?: string;
    /**
     * Fields of this node, indexed by their field keys.
     *
     * Allow explicit undefined for compatibility with EditableTree, and type-safety on read.
     */
    [key: FieldKey]: ContextuallyTypedFieldData;
    /**
     * Fields of this node, indexed by their field keys as strings.
     *
     * Allow unbranded field keys as a convenience for literals.
     */
    [key: string]: ContextuallyTypedFieldData;
}
/**
 * Construct a tree from ContextuallyTypedNodeData.
 *
 * TODO: this should probably be refactored into a `try` function which either returns a Cursor or a SchemaError with a path to the error.
 * @returns a cursor in Nodes mode for a single node containing the provided data.
 * @alpha
 */
export declare function cursorFromContextualData(context: TreeDataContext, typeSet: TreeTypeSet, data: ContextuallyTypedNodeData): ITreeCursorSynchronous;
/**
 * Strongly typed {@link cursorFromContextualData} for a TreeNodeSchema.
 * @returns a cursor in Nodes mode for a single node containing the provided data.
 * @alpha
 */
export declare function cursorForTypedTreeData<T extends TreeNodeSchema>(context: TreeDataContext, schema: T, data: InsertableFlexNode<T>): ITreeCursorSynchronous;
/**
 * Strongly typed {@link cursorFromContextualData} for AllowedTypes.
 * @returns a cursor in Nodes mode for a single node containing the provided data.
 * @alpha
 */
export declare function cursorForTypedData<T extends AllowedTypes>(context: TreeDataContext, schema: T, data: AllowedTypesToFlexInsertableTree<T>): ITreeCursorSynchronous;
/**
 * Construct a tree from ContextuallyTypedNodeData.
 *
 * TODO: this should probably be refactored into a `try` function which either returns a Cursor or a SchemaError with a path to the error.
 * TODO: migrate APIs which take arrays of cursors to take cursors in fields mode.
 */
export declare function cursorsFromContextualData(context: TreeDataContext, field: TreeFieldStoredSchema, data: ContextuallyTypedNodeData | undefined): ITreeCursorSynchronous[];
/**
 * Strongly typed {@link cursorsFromContextualData} for a TreeFieldSchema
 * @alpha
 */
export declare function cursorsForTypedFieldData<T extends TreeFieldSchema>(context: TreeDataContext, schema: T, data: InsertableFlexField<T>): ITreeCursorSynchronous[];
/**
 * Construct a MapTree from ContextuallyTypedNodeData.
 *
 * TODO: this should probably be refactored into a `try` function which either returns a MapTree or a SchemaError with a path to the error.
 * TODO: test suite.
 *
 * @remarks
 * This version is only exported as a more testable entry point than `cursorFromContextualData` which keeps the use of `MapTree` as an implementation detail.
 * This should not be reexported from the parent module.
 */
export declare function applyTypesFromContext(context: TreeDataContext, typeSet: TreeTypeSet, data: ContextuallyTypedNodeData): MapTree;
/**
 * Construct a MapTree from ContextuallyTypedNodeData.
 *
 * TODO: this should probably be refactored into a `try` function which either returns a MapTree or a SchemaError with a path to the error.
 * TODO: test suite.
 *
 * @remarks
 * This version is only exported as a more testable entry point than `cursorsFromContextualData` which keeps the use of `MapTree` as an implementation detail.
 * This should not be reexported from the parent module.
 */
export declare function applyFieldTypesFromContext(context: TreeDataContext, field: TreeFieldStoredSchema, data: ContextuallyTypedFieldData): MapTree[];
/**
 * Content to use for a field.
 *
 * When used, this content will be deeply copied into the tree, and must comply with the schema.
 *
 * The content must follow the {@link Multiplicity} of the {@link FieldKind}:
 * - use a single cursor for an `optional` or `value` field;
 * - use array of cursors for a `sequence` field;
 *
 * TODO: this should allow a field cursor instead of an array of cursors.
 * TODO: Make this generic so a variant of this type that allows placeholders for detached sequences to consume.
 * @alpha
 */
export type NewFieldContent = ITreeCursorSynchronous | readonly ITreeCursorSynchronous[] | ContextuallyTypedFieldData;
/**
 * Convert NewFieldContent into ITreeCursor array.
 */
export declare function normalizeNewFieldContent(context: TreeDataContext, schema: TreeFieldStoredSchema, content: NewFieldContent): readonly ITreeCursorSynchronous[];
//# sourceMappingURL=contextuallyTyped.d.ts.map