/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { IFieldSchema, ITreeSchema } from "../view";
import { GlobalFieldKey, GlobalFieldKeySymbol, LocalFieldKey, Named, TreeSchemaIdentifier, TreeTypeSet, ValueSchema } from "../../../core";
import { MakeNominal, Assume } from "../../../util";
import { FieldKindTypes, FieldKinds } from "../../defaultFieldKinds";
import { FlexList, LazyItem } from "./flexList";
import { ObjectToMap, WithDefault } from "./typeUtils";
import { RecursiveTreeSchemaSpecification } from "./schemaBuilder";
/**
 * @alpha
 */
export interface LocalFields {
    readonly [key: string]: FieldSchema;
}
/**
 * @alpha
 */
export declare type NormalizeLocalFieldsInner<T extends LocalFields> = {
    [Property in keyof T]: NormalizeField<T[Property]>;
};
/**
 * @alpha
 */
export declare type NormalizeLocalFields<T extends LocalFields | undefined> = NormalizeLocalFieldsInner<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 localFields: ObjectToMap<NormalizeLocalFields<Assume<T, TreeSchemaSpecification>["local"]>, LocalFieldKey, FieldSchema>;
    readonly localFieldsObject: NormalizeLocalFields<Assume<T, TreeSchemaSpecification>["local"]>;
    readonly extraLocalFields: FieldSchema;
    readonly extraGlobalFields: boolean;
    readonly value: WithDefault<Assume<T, TreeSchemaSpecification>["value"], ValueSchema.Nothing>;
    readonly name: Name & TreeSchemaIdentifier;
    readonly info: Assume<T, TreeSchemaSpecification>;
    constructor(builder: Named<string>, name: Name, info: T);
    get globalFields(): ReadonlySet<GlobalFieldKey>;
}
/**
 * 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.
 */
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>[];
export declare function allowedTypesIsAny(t: AllowedTypes): t is [Any];
/**
 * Object for capturing information about a TreeStoredSchema for use at both compile time and runtime.
 * @alpha
 */
export interface TreeSchemaSpecification {
    readonly local?: {
        readonly [key: string]: FieldSchema;
    };
    readonly global?: FlexList<GlobalFieldSchema>;
    readonly extraLocalFields?: FieldSchema;
    readonly extraGlobalFields?: boolean;
    readonly value?: ValueSchema;
}
/**
 * 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("../../defaultFieldKinds").Forbidden, never[]>;
    protected _typeCheck?: MakeNominal;
    constructor(kind: Kind, allowedTypes: Types);
    get types(): TreeTypeSet;
}
export declare function allowedTypesToTypeSet(t: AllowedTypes): TreeTypeSet;
/**
 * 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 GlobalFieldSchema<Kind extends FieldKindTypes = FieldKindTypes, Types extends AllowedTypes = AllowedTypes> implements IFieldSchema {
    readonly builder: Named<string>;
    readonly key: GlobalFieldKey;
    readonly schema: FieldSchema<Kind, Types>;
    readonly symbol: GlobalFieldKeySymbol;
    protected _typeCheck?: MakeNominal;
    constructor(builder: Named<string>, key: GlobalFieldKey, schema: FieldSchema<Kind, Types>);
    get kind(): Kind;
    get types(): TreeTypeSet;
}
//# sourceMappingURL=typedTreeSchema.d.ts.map