/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { arraySchema, mapSchema, objectSchema, } from "../node-kinds/index.js";
import { defaultSchemaFactoryObjectOptions, SchemaFactory, schemaStatics, } from "./schemaFactory.js";
/**
 * {@link SchemaFactory} with additional alpha APIs.
 *
 * @alpha
 * @privateRemarks
 *
 * Some private methods on `SchemaFactory` are intentionally duplicated here to avoid increasing their exposure to `protected`.
 * If we were to do so, they would be exposed on the public API surface of `SchemaFactory`.
 */
export class SchemaFactoryAlpha extends SchemaFactory {
    constructor() {
        super(...arguments);
        /**
         * {@inheritDoc SchemaStatics.leaves}
         */
        this.leaves = schemaStatics.leaves;
        /**
         * {@inheritDoc SchemaStatics.optional}
         */
        this.optional = schemaStatics.optional;
        /**
         * {@inheritDoc SchemaStatics.required}
         */
        this.required = schemaStatics.required;
        /**
         * {@inheritDoc SchemaStatics.optionalRecursive}
         */
        this.optionalRecursive = schemaStatics.optionalRecursive;
        /**
         * {@inheritDoc SchemaStatics.requiredRecursive}
         */
        this.requiredRecursive = schemaStatics.requiredRecursive;
    }
    scoped2(name) {
        return (this.scope === undefined ? `${name}` : `${this.scope}.${name}`);
    }
    /**
     * Define a {@link TreeNodeSchemaClass} for a {@link TreeObjectNode}.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     * @param fields - Schema for fields of the object node's schema. Defines what children can be placed under each key.
     * @param options - Additional options for the schema.
     */
    objectAlpha(name, fields, options) {
        return objectSchema(this.scoped2(name), fields, true, options?.allowUnknownOptionalFields ??
            defaultSchemaFactoryObjectOptions.allowUnknownOptionalFields, options?.metadata, options?.persistedMetadata);
    }
    /**
     * {@inheritdoc SchemaFactory.objectRecursive}
     */
    objectRecursive(name, t, options) {
        return this.objectAlpha(name, t, options);
    }
    /**
     * Define a {@link TreeNodeSchema} for a {@link TreeMapNode}.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     * @param allowedTypes - The types that may appear as values in the map.
     * @param options - Additional options for the schema.
     *
     * @example
     * ```typescript
     * class NamedMap extends factory.map("name", factory.number, {
     * 	metadata: { description: "A map of numbers" }
     * }) {}
     * ```
     */
    mapAlpha(name, allowedTypes, options) {
        return mapSchema(this.scoped2(name), allowedTypes, true, true, options?.metadata, options?.persistedMetadata);
    }
    /**
     * {@inheritDoc SchemaFactory.objectRecursive}
     */
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
    mapRecursive(name, allowedTypes, options) {
        return this.mapAlpha(name, allowedTypes, options);
    }
    /**
     * Define (and add to this library) a {@link TreeNodeSchemaClass} for a {@link (TreeArrayNode:interface)}.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     * @param allowedTypes - The types that may appear in the array.
     * @param options - Additional options for the schema.
     *
     * @example
     * ```typescript
     * class NamedArray extends factory.arrayAlpha("name", factory.number) {}
     * ```
     */
    arrayAlpha(name, allowedTypes, options) {
        return arraySchema(this.scoped2(name), allowedTypes, true, true, options?.metadata, options?.persistedMetadata);
    }
    /**
     * {@inheritDoc SchemaFactory.objectRecursive}
     */
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
    arrayRecursive(name, allowedTypes, options) {
        return this.arrayAlpha(name, allowedTypes, options);
    }
    /**
     * Create a {@link SchemaFactory} with a {@link SchemaFactory.scope|scope} which is a combination of this factory's scope and the provided name.
     * @remarks
     * The main use-case for this is when creating a collection of related schema (for example using a function that creates multiple schema).
     * Creating such related schema using a sub-scope helps ensure they won't collide with other schema in the parent scope.
     */
    scopedFactory(name) {
        return new SchemaFactoryAlpha(this.scoped2(name));
    }
}
/**
 * {@inheritDoc SchemaStatics.leaves}
 */
SchemaFactoryAlpha.leaves = schemaStatics.leaves;
/**
 * {@inheritDoc SchemaStatics.optional}
 */
SchemaFactoryAlpha.optional = schemaStatics.optional;
/**
 * {@inheritDoc SchemaStatics.required}
 */
SchemaFactoryAlpha.required = schemaStatics.required;
/**
 * {@inheritDoc SchemaStatics.optionalRecursive}
 */
SchemaFactoryAlpha.optionalRecursive = schemaStatics.optionalRecursive;
/**
 * {@inheritDoc SchemaStatics.requiredRecursive}
 */
SchemaFactoryAlpha.requiredRecursive = schemaStatics.requiredRecursive;
/**
 * Like {@link SchemaFactory.identifier} but static and a factory function that can be provided {@link FieldProps}.
 */
SchemaFactoryAlpha.identifier = schemaStatics.identifier;
//# sourceMappingURL=schemaFactoryAlpha.js.map