"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.emptyField = exports.typedTreeSchemaFromInfo = exports.nameSet = exports.nameSetSimple = exports.unrestrictedFieldSchema = exports.typedFieldSchema = exports.typedTreeSchema = void 0;
const core_1 = require("../../../core");
const util_1 = require("../../../util");
const defaultFieldKinds_1 = require("../../defaultFieldKinds");
const viewSchemaUtil_1 = require("../../viewSchemaUtil");
/**
 * Builds a TreeSchema with the type information also captured in the
 * typescript type to allow for deriving schema aware APIs.
 *
 * @remarks
 * The name is passed is separate instead of part of the builder to the caller does not have to
 * do "as const" after the name for its type to be captured properly.
 *
 * @alpha
 */
function typedTreeSchema(name, t) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const data = {
        localFields: t.local,
        globalFields: (_b = (_a = t.global) === null || _a === void 0 ? void 0 : _a.map((key) => (0, core_1.keyFromSymbol)(typeof key === "symbol" ? key : key.name))) !== null && _b !== void 0 ? _b : [],
        extraLocalFields: (_c = t.extraLocalFields) !== null && _c !== void 0 ? _c : exports.emptyField,
        extraGlobalFields: t.extraGlobalFields,
        value: t.value,
    };
    // TreeInfoFromBuilder<T, TName>
    const typeInfo = {
        name,
        local: (_d = t.local) !== null && _d !== void 0 ? _d : {},
        global: extractNames((_e = t.global) !== null && _e !== void 0 ? _e : []),
        extraLocalFields: (_f = t.extraLocalFields) !== null && _f !== void 0 ? _f : exports.emptyField,
        extraGlobalFields: (_g = t.extraGlobalFields) !== null && _g !== void 0 ? _g : false,
        value: (_h = t.value) !== null && _h !== void 0 ? _h : core_1.ValueSchema.Nothing,
    };
    return Object.assign(Object.assign({ name: (0, util_1.brand)(name) }, (0, core_1.treeSchema)(data)), { typeInfo });
}
exports.typedTreeSchema = typedTreeSchema;
/**
 * Builds a FieldSchema with the type information also captured in the
 * typescript type to allow for deriving schema aware APIs.
 *
 * @remarks
 * The typing here explicitly forbids passing no types: no types would make a field that didn't allow anything.
 * While the underlying system does support such fields (which can be useful if planning to modify their schema later),
 * usually what is instead desired is a field which allows any child type.
 * For that see {@link TypedSchema#fieldUnrestricted}.
 *
 * @alpha
 */
function typedFieldSchema(kind, ...typeArray) {
    const types = nameSet(...typeArray);
    return { kind, types };
}
exports.typedFieldSchema = typedFieldSchema;
/**
 * Builds a FieldSchema with the type information also captured in the
 * typescript type to allow for deriving schema aware APIs.
 *
 * For fields with unrestricted polymorphism (meaning all child types are allowed).
 * @alpha
 */
function unrestrictedFieldSchema(kind) {
    return { kind };
}
exports.unrestrictedFieldSchema = unrestrictedFieldSchema;
function extractNames(items) {
    return items.map((item) => typeof item === "object" ? item.name : item);
}
function nameSetSimple(...names) {
    return new Set(names);
}
exports.nameSetSimple = nameSetSimple;
/**
 * Gets a set of names from a list of named objects or names.
 * @alpha
 */
function nameSet(...names) {
    return new Set(extractNames(names));
}
exports.nameSet = nameSet;
/**
 * Builds a TreeSchema with the type information also captured in the
 * typescript type to allow for deriving schema aware APIs.
 */
function typedTreeSchemaFromInfo(t) {
    return (0, viewSchemaUtil_1.namedTreeSchema)(Object.assign(Object.assign({}, t), { name: (0, util_1.brand)(t.name) }));
}
exports.typedTreeSchemaFromInfo = typedTreeSchemaFromInfo;
/**
 * Schema for a field which must always be empty.
 * @alpha
 */
exports.emptyField = unrestrictedFieldSchema(defaultFieldKinds_1.forbidden);
//# sourceMappingURL=typedSchema.js.map