"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 util_1 = require("../util");
const default_schema_1 = require("./default-schema");
const typed_schema_1 = require("./typed-schema");
/**
 * 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.
 * @alpha
 */
function treeSchemaFromStoredSchema(schema) {
    const map = new Map();
    for (const [identifier, innerSchema] of schema.nodeSchema) {
        if (innerSchema.leafValue !== undefined) {
            map.set(identifier, typed_schema_1.LeafNodeSchema.create({ name: "intoTypedSchema" }, identifier, innerSchema.leafValue));
        }
        else if (innerSchema.mapFields !== undefined) {
            map.set(identifier, typed_schema_1.MapNodeSchema.create({ name: "intoTypedSchema" }, identifier, fieldSchemaFromStoredSchema(innerSchema.mapFields, map)));
        }
        else {
            const fields = new Map();
            for (const [key, field] of innerSchema.objectNodeFields) {
                fields.set(key, fieldSchemaFromStoredSchema(field, map));
            }
            const fieldsObject = mapToObject(fields);
            map.set(identifier, typed_schema_1.ObjectNodeSchema.create({ name: "intoTypedSchema" }, identifier, fieldsObject));
        }
    }
    return {
        adapters: {},
        policy: default_schema_1.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 = default_schema_1.defaultSchemaPolicy.fieldKinds.get(schema.kind.identifier) ?? (0, util_1.fail)("missing field kind");
    const types = schema.types === undefined
        ? [typed_schema_1.Any]
        : Array.from(schema.types, (v) => () => map.get(v) ?? (0, util_1.fail)("missing schema"));
    return typed_schema_1.TreeFieldSchema.create(kind, types);
}
exports.fieldSchemaFromStoredSchema = fieldSchemaFromStoredSchema;
//# sourceMappingURL=storedToViewSchema.js.map