"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.fieldSchemaFromStoredSchema = exports.treeSchemaFromStoredSchema = void 0;
const core_utils_1 = require("@fluidframework/core-utils");
const index_js_1 = require("../core/index.js");
const index_js_2 = require("../util/index.js");
const index_js_3 = require("./default-schema/index.js");
const index_js_4 = require("./typed-schema/index.js");
/**
 * Creates a new view schema using the stored schema.
 * @remarks
 * This is really only suitable for use with code that happens to need access to things which require a view schema, but isn't actually schema aware.
 * If the input schema came from a view schema, it will not return the same view schema, and will not be compatible:
 * the returned TreeSchema is simply one which schematize will not object to.
 * Assumes the schema uses the default field kinds.
 * @internal
 */
function treeSchemaFromStoredSchema(schema) {
    const map = new Map();
    for (const [identifier, innerSchema] of schema.nodeSchema) {
        if (innerSchema instanceof index_js_1.LeafNodeStoredSchema) {
            map.set(identifier, index_js_4.LeafNodeSchema.create({ name: "intoTypedSchema" }, identifier, innerSchema.leafValue));
        }
        else if (innerSchema instanceof index_js_1.MapNodeStoredSchema) {
            map.set(identifier, index_js_4.FlexMapNodeSchema.create({ name: "intoTypedSchema" }, identifier, fieldSchemaFromStoredSchema(innerSchema.mapFields, map)));
        }
        else {
            (0, core_utils_1.assert)(innerSchema instanceof index_js_1.ObjectNodeStoredSchema, 0x882 /* unsupported node kind */);
            const fields = new Map();
            for (const [key, field] of innerSchema.objectNodeFields) {
                fields.set(key, fieldSchemaFromStoredSchema(field, map));
            }
            const fieldsObject = mapToObject(fields);
            map.set(identifier, index_js_4.FlexObjectNodeSchema.create({ name: "intoTypedSchema" }, identifier, fieldsObject));
        }
    }
    return {
        adapters: {},
        policy: index_js_3.defaultSchemaPolicy,
        rootFieldSchema: fieldSchemaFromStoredSchema(schema.rootFieldSchema, map),
        nodeSchema: map,
    };
}
exports.treeSchemaFromStoredSchema = treeSchemaFromStoredSchema;
function mapToObject(map) {
    const objectMap = Object.create(null);
    for (const [key, value] of map.entries()) {
        // This code has to be careful to avoid assigned to __proto__ or similar built in fields.
        Object.defineProperty(objectMap, key, {
            enumerable: true,
            configurable: false,
            writable: false,
            value,
        });
    }
    return objectMap;
}
function fieldSchemaFromStoredSchema(schema, map) {
    const kind = index_js_3.defaultSchemaPolicy.fieldKinds.get(schema.kind.identifier) ?? (0, index_js_2.fail)("missing field kind");
    const types = schema.types === undefined
        ? [index_js_4.Any]
        : Array.from(schema.types, (v) => () => map.get(v) ?? (0, index_js_2.fail)("missing schema"));
    return index_js_4.FlexFieldSchema.create(kind, types);
}
exports.fieldSchemaFromStoredSchema = fieldSchemaFromStoredSchema;
//# sourceMappingURL=storedToViewSchema.js.map