/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { IFieldSchema, ITreeSchema } from "../modular-schema";
import { FieldKey, Named, TreeSchemaIdentifier, TreeTypeSet, ValueSchema } from "../../core";
import { MakeNominal, Assume, RestrictiveReadonlyRecord, _InlineTrick, FlattenKeys } from "../../util";
import { FieldKindTypes, FieldKinds } from "../default-field-kinds";
import { LazyItem } from "./flexList";
import { ObjectToMap, WithDefault } from "./typeUtils";
import { RecursiveTreeSchemaSpecification } from "./schemaBuilder";
/**
 * @alpha
 */
export interface Fields {
    readonly [key: string]: FieldSchema;
}
/**
 * @alpha
 */
export declare type NormalizeStructFieldsInner<T extends Fields> = {
    [Property in keyof T]: NormalizeField<T[Property]>;
};
/**
 * @alpha
 */
export declare type NormalizeStructFields<T extends Fields | undefined> = NormalizeStructFieldsInner<WithDefault<T, Record<string, never>>>;
/**
 * T must extend TreeSchemaSpecification.
 * This can not be enforced using TypeScript since doing so breaks recursive type support.
 * See note on SchemaBuilder.fieldRecursive.
 * @alpha
 */
export declare class TreeSchema<Name extends string = string, T extends RecursiveTreeSchemaSpecification = TreeSchemaSpecification> implements ITreeSchema {
    readonly builder: Named<string>;
    readonly structFields: ObjectToMap<NormalizeStructFields<Assume<T, TreeSchemaSpecification>["structFields"]>, FieldKey, FieldSchema>;
    readonly structFieldsObject: NormalizeStructFields<Assume<T, TreeSchemaSpecification>["structFields"]>;
    readonly mapFields?: FieldSchema;
    readonly leafValue: WithDefault<Assume<T, TreeSchemaSpecification>["leafValue"], undefined>;
    readonly name: Name & TreeSchemaIdentifier;
    readonly info: Assume<T, TreeSchemaSpecification>;
    constructor(builder: Named<string>, name: Name, info: T);
}
/**
 * Convert FieldSchemaSpecification | undefined into FieldSchema.
 * @alpha
 */
export declare type NormalizeField<T extends FieldSchema | undefined> = T extends FieldSchema ? T : FieldSchema<typeof FieldKinds.forbidden, []>;
/**
 * Allow any node (as long as it meets the schema for its own type).
 * @alpha
 */
export declare const Any: "Any";
/**
 * Allow any node (as long as it meets the schema for its own type).
 * @alpha
 */
export declare type Any = typeof Any;
/**
 * Tree type, but can be wrapped in a function to allow referring to types before they are declared.
 * This makes recursive and co-recursive types possible.
 * @alpha
 */
export declare type LazyTreeSchema = TreeSchema | (() => TreeSchema);
/**
 * Types for use in fields.
 *
 * "Any" is boxed in an array to allow use as variadic parameter.
 * @alpha
 */
export declare type AllowedTypes = [Any] | readonly LazyItem<TreeSchema>[];
/**
 * Checks if an {@link AllowedTypes} is {@link (Any:type)}.
 * @alpha
 */
export declare function allowedTypesIsAny(t: AllowedTypes): t is [Any];
/**
 * `TreeSchemaSpecification` for {@link SchemaBuilder.struct}.
 * @alpha
 */
export interface StructSchemaSpecification {
    readonly structFields: RestrictiveReadonlyRecord<string, FieldSchema>;
}
/**
 * `TreeSchemaSpecification` for {@link SchemaBuilder.map}.
 * @alpha
 */
export interface MapSchemaSpecification {
    readonly mapFields: FieldSchema;
}
/**
 * `TreeSchemaSpecification` for {@link SchemaBuilder.leaf}.
 * @alpha
 */
export interface LeafSchemaSpecification {
    readonly leafValue: ValueSchema;
}
/**
 * Object for capturing information about a TreeStoredSchema for use at both compile time and runtime.
 * @alpha
 */
export declare type TreeSchemaSpecification = [
    FlattenKeys<(StructSchemaSpecification | MapSchemaSpecification | LeafSchemaSpecification) & Partial<StructSchemaSpecification & MapSchemaSpecification & LeafSchemaSpecification>>
][_InlineTrick];
/**
 * All policy for a specific field,
 * including functionality that does not have to be kept consistent across versions or deterministic.
 *
 * This can include policy for how to use this schema for "view" purposes, and well as how to expose editing APIs.
 * @sealed @alpha
 */
export declare class FieldSchema<Kind extends FieldKindTypes = FieldKindTypes, Types = AllowedTypes> implements IFieldSchema {
    readonly kind: Kind;
    readonly allowedTypes: Types;
    /**
     * Schema for a field which must always be empty.
     */
    static readonly empty: FieldSchema<import("../default-field-kinds").Forbidden, never[]>;
    protected _typeCheck?: MakeNominal;
    constructor(kind: Kind, allowedTypes: Types);
    get types(): TreeTypeSet;
}
/**
 * Convert {@link AllowedTypes} to {@link TreeTypeSet}.
 * @alpha
 */
export declare function allowedTypesToTypeSet(t: AllowedTypes): TreeTypeSet;
//# sourceMappingURL=typedTreeSchema.d.ts.map