/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { IFluidHandle } from "@fluidframework/core-interfaces";
import type { ImplicitAllowedTypes, ImplicitAnnotatedAllowedTypes, UnannotateImplicitAllowedTypes } from "../core/index.js";
import { FieldKind } from "../fieldSchema.js";
import type { FieldProps, FieldSchema, FieldPropsAlpha, FieldSchemaAlpha } from "../fieldSchema.js";
import type { LeafSchema } from "../leafNodeSchema.js";
import { stringSchema } from "../leafNodeSchema.js";
import type { System_Unsafe, FieldSchemaAlphaUnsafe } from "./typesUnsafe.js";
/**
 * Stateless APIs exposed via {@link SchemaFactory} as both instance properties and as statics.
 * @privateRemarks
 * We have no way to make linkable members which exist both as statics and instance properties since API-Extractor does not support this.
 * As a workaround, we have this type as a third place which can be linked.
 * @system @sealed @public
 */
export interface SchemaStatics {
    /**
     * {@link TreeNodeSchema} for holding a JavaScript `string`.
     *
     * @remarks
     * Strings containing unpaired UTF-16 surrogate pair code units may not be handled correctly.
     *
     * These limitations come from the use of UTF-8 encoding of the strings, which requires them to be valid unicode.
     * JavaScript does not make this requirement for its strings so not all possible JavaScript strings are supported.
     * @privateRemarks
     * TODO:
     * We should be much more clear about what happens if you use problematic values.
     * We should validate and/or normalize them when inserting content.
     */
    readonly string: LeafSchema<"string", string>;
    /**
     * {@link TreeNodeSchema} for holding a JavaScript `number`.
     *
     * @remarks
     * The number is a {@link https://en.wikipedia.org/wiki/Double-precision_floating-point_format | double-precision 64-bit binary format IEEE 754} value, however there are some exceptions:
     *
     * - `NaN`, and the infinities are converted to `null` (and may therefore only be used where `null` is allowed by the schema).
     *
     * - `-0` may be converted to `0` in some cases.
     *
     * These limitations match the limitations of JSON.
     * @privateRemarks
     * TODO:
     * We should be much more clear about what happens if you use problematic values.
     * We should validate and/or normalize them when inserting content.
     */
    readonly number: LeafSchema<"number", number>;
    /**
     * {@link TreeNodeSchema} for holding a boolean.
     */
    readonly boolean: LeafSchema<"boolean", boolean>;
    /**
     * {@link TreeNodeSchema} for JavaScript `null`.
     *
     * @remarks
     * There are good {@link https://www.npmjs.com/package/%40rushstack/eslint-plugin#rushstackno-new-null | reasons to avoid using null} in JavaScript, however sometimes it is desired.
     * This {@link TreeNodeSchema} node provides the option to include nulls in trees when desired.
     * Unless directly inter-operating with existing data using null, consider other approaches, like wrapping the value in an optional field, or using a more specifically named empty object node.
     */
    readonly null: LeafSchema<"null", null>;
    /**
     * {@link TreeNodeSchema} for holding an {@link @fluidframework/core-interfaces#(IFluidHandle:interface)}.
     */
    readonly handle: LeafSchema<"handle", IFluidHandle>;
    /**
     * {@link AllowedTypes} for holding any of the leaf types.
     */
    readonly leaves: readonly [
        SchemaStatics["string"],
        SchemaStatics["number"],
        SchemaStatics["boolean"],
        SchemaStatics["null"],
        SchemaStatics["handle"]
    ];
    /**
     * Make a field optional instead of the default, which is required.
     *
     * @param t - The types allowed under the field.
     * @param props - Optional properties to associate with the field.
     *
     * @typeParam TCustomMetadata - Custom metadata properties to associate with the field.
     * See {@link FieldSchemaMetadata.custom}.
     */
    readonly optional: <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">) => FieldSchema<FieldKind.Optional, T, TCustomMetadata>;
    /**
     * Make a field explicitly required.
     *
     * @param t - The types allowed under the field.
     * @param props - Optional properties to associate with the field.
     *
     * @remarks
     * Fields are required by default, but this API can be used to make the required nature explicit in the schema,
     * and allows associating custom {@link FieldProps | properties} with the field.
     *
     * @typeParam TCustomMetadata - Custom metadata properties to associate with the field.
     * See {@link FieldSchemaMetadata.custom}.
     */
    readonly required: <const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">) => FieldSchema<FieldKind.Required, T, TCustomMetadata>;
    /**
     * {@link SchemaStatics.optional} except tweaked to work better for recursive types.
     * Use with {@link ValidateRecursiveSchema} for improved type safety.
     * @remarks
     * This version of {@link SchemaStatics.optional} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.
     * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.
     */
    readonly optionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">) => System_Unsafe.FieldSchemaUnsafe<FieldKind.Optional, T, TCustomMetadata>;
    /**
     * {@link SchemaStatics.required} except tweaked to work better for recursive types.
     * Use with {@link ValidateRecursiveSchema} for improved type safety.
     * @remarks
     * This version of {@link SchemaStatics.required} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.
     * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.
     */
    readonly requiredRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">) => System_Unsafe.FieldSchemaUnsafe<FieldKind.Required, T, TCustomMetadata>;
}
declare function optional<const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider">): FieldSchemaAlpha<FieldKind.Optional, T, TCustomMetadata>;
declare function optional<const T extends ImplicitAnnotatedAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider">): FieldSchemaAlpha<FieldKind.Optional, UnannotateImplicitAllowedTypes<T>, TCustomMetadata>;
declare function required<const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider">): FieldSchemaAlpha<FieldKind.Required, T, TCustomMetadata>;
declare function required<const T extends ImplicitAnnotatedAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider">): FieldSchemaAlpha<FieldKind.Required, UnannotateImplicitAllowedTypes<T>, TCustomMetadata>;
/**
 * Implementation of {@link SchemaStatics}.
 * @remarks
 * Entries can use more specific types than {@link SchemaStatics} requires to be more useful for non-public consumers.
 * Additional non-public members are in {@link schemaStatics}.
 */
export declare const schemaStaticsStable: {
    readonly string: LeafSchema<"string", string> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly number: LeafSchema<"number", number> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly boolean: LeafSchema<"boolean", boolean> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly null: LeafSchema<"null", null> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly handle: LeafSchema<"handle", IFluidHandle<unknown>> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly leaves: readonly [LeafSchema<"string", string> & import("../simpleSchema.js").SimpleLeafNodeSchema, LeafSchema<"number", number> & import("../simpleSchema.js").SimpleLeafNodeSchema, LeafSchema<"boolean", boolean> & import("../simpleSchema.js").SimpleLeafNodeSchema, LeafSchema<"null", null> & import("../simpleSchema.js").SimpleLeafNodeSchema, LeafSchema<"handle", IFluidHandle<unknown>> & import("../simpleSchema.js").SimpleLeafNodeSchema];
    readonly optional: typeof optional;
    readonly required: typeof required;
    readonly optionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata>, "defaultProvider">) => FieldSchemaAlphaUnsafe<FieldKind.Optional, T, TCustomMetadata>;
    readonly requiredRecursive: <const T_1 extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata_1 = unknown>(t: T_1, props?: Omit<FieldPropsAlpha<TCustomMetadata_1>, "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Required, T_1, TCustomMetadata_1>;
};
/**
 * Unstable extensions to {@link schemaStaticsStable}.
 */
export declare const schemaStatics: {
    readonly identifier: <const TCustomMetadata = unknown>(props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">) => FieldSchemaAlpha<FieldKind.Identifier, typeof stringSchema, TCustomMetadata>;
    readonly string: LeafSchema<"string", string> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly number: LeafSchema<"number", number> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly boolean: LeafSchema<"boolean", boolean> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly null: LeafSchema<"null", null> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly handle: LeafSchema<"handle", IFluidHandle<unknown>> & import("../simpleSchema.js").SimpleLeafNodeSchema;
    readonly leaves: readonly [LeafSchema<"string", string> & import("../simpleSchema.js").SimpleLeafNodeSchema, LeafSchema<"number", number> & import("../simpleSchema.js").SimpleLeafNodeSchema, LeafSchema<"boolean", boolean> & import("../simpleSchema.js").SimpleLeafNodeSchema, LeafSchema<"null", null> & import("../simpleSchema.js").SimpleLeafNodeSchema, LeafSchema<"handle", IFluidHandle<unknown>> & import("../simpleSchema.js").SimpleLeafNodeSchema];
    readonly optional: typeof optional;
    readonly required: typeof required;
    readonly optionalRecursive: <const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata_1 = unknown>(t: T, props?: Omit<FieldPropsAlpha<TCustomMetadata_1>, "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Optional, T, TCustomMetadata_1>;
    readonly requiredRecursive: <const T_1 extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata_2 = unknown>(t: T_1, props?: Omit<FieldPropsAlpha<TCustomMetadata_2>, "defaultProvider"> | undefined) => FieldSchemaAlphaUnsafe<FieldKind.Required, T_1, TCustomMetadata_2>;
};
export {};
//# sourceMappingURL=schemaStatics.d.ts.map