/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { recordSchema, } from "../node-kinds/index.js";
import { SchemaFactory, scoped, structuralName, } from "./schemaFactory.js";
/* eslint-enable unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars, import/no-duplicates */
/**
 * {@link SchemaFactory} with additional beta APIs.
 * @beta
 * @privateRemarks
 */
export class SchemaFactoryBeta extends SchemaFactory {
    /**
     * 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 SchemaFactoryBeta(scoped(this, name));
    }
    /**
     * {@link SchemaFactoryBeta.record} implementation.
     *
     * @privateRemarks
     * This should return {@link TreeNodeSchemaBoth}: see note on {@link SchemaFactory.map} implementation for details.
     */
    record(nameOrAllowedTypes, maybeAllowedTypes) {
        if (maybeAllowedTypes === undefined) {
            const types = nameOrAllowedTypes;
            const fullName = structuralName("Record", types);
            return this.getStructuralType(fullName, types, () => this.namedRecord(fullName, nameOrAllowedTypes, 
            /* customizable */ false, 
            /* implicitlyConstructable */ true));
        }
        const out = this.namedRecord(nameOrAllowedTypes, maybeAllowedTypes, 
        /* customizable */ true, 
        /* implicitlyConstructable */ true);
        return out;
    }
    /**
     * Define a {@link TreeNodeSchema} for a {@link (TreeRecordNode:interface)}.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     *
     * @remarks
     * This is not intended to be used directly, use the overload of `record` which takes a name instead.
     */
    namedRecord(name, allowedTypes, customizable, implicitlyConstructable, options) {
        const record = recordSchema({
            identifier: scoped(this, name),
            info: allowedTypes,
            customizable,
            implicitlyConstructable,
            metadata: options?.metadata,
        });
        return record;
    }
    /**
     * {@link SchemaFactoryBeta.(record:2)} except tweaked to work better for recursive types.
     * Use with {@link ValidateRecursiveSchema} for improved type safety.
     * @remarks
     * This version of `SchemaFactory.record` uses the same workarounds as {@link SchemaFactory.objectRecursive}.
     * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.
     */
    // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
    recordRecursive(name, allowedTypes, options) {
        const RecordSchema = this.namedRecord(name, allowedTypes, 
        /* customizable */ true, 
        // Setting this to true seems to work ok currently, but not for other node kinds.
        // Supporting this could be fragile and might break other future changes, so it's being kept as false for now.
        /* implicitlyConstructable */ false, options);
        return RecordSchema;
    }
}
//# sourceMappingURL=schemaFactoryBeta.js.map