"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.isTreeNodeSchemaClass = exports.NodeKind = exports.getTreeNodeSchemaPrivateData = exports.CompatibilityLevel = exports.privateDataSymbol = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
/**
 * Symbol for use by {@link TreeNodeSchemaCorePrivate}.
 */
exports.privateDataSymbol = Symbol("PrivateData");
/**
 * Indicates a compatibility level for inferring a schema to apply to insertable data.
 * @remarks
 * Each schema allowed at a location in the tree has its compatibility level checked against the data being inserted.
 * The compatibility is considered unambiguous if there is a single schema with a higher compatibility than all others.
 *
 * This approach allows adding new compatible formats as a non breaking change.
 * If the new format was already compatible with some other schema, it can still be added as non-breaking as long as a lower compatibility level is used.
 * For example, support for constructing maps from record like objects was added in Fluid Framework 2.2.
 * This format (an object with fields) was already compatible with Object nodes at compatibility level Normal so the new format support for maps was added at compatibility level Low.
 * This ensures that existing code that was using object literals as insertable content where both objects and maps were allowed will continue to work,
 * assuming the objects are intended as ObjectNodes.
 * However new code can now be written using record like objects to construct maps, as long as the schema does not also allow Object nodes which are compatible with the data in that location.
 *
 * @see {@link ITreeConfigurationOptions.preventAmbiguity} for a related setting which interacts with this in a somewhat complex way.
 */
var CompatibilityLevel;
(function (CompatibilityLevel) {
    /**
     * Not compatible. Constructor typing indicates incompatibility.
     */
    CompatibilityLevel[CompatibilityLevel["None"] = 0] = "None";
    /**
     * Additional compatibility cases added in Fluid Framework 2.2.
     */
    CompatibilityLevel[CompatibilityLevel["Low"] = 1] = "Low";
    /**
     * Compatible in Fluid Framework 2.0.
     */
    CompatibilityLevel[CompatibilityLevel["Normal"] = 2] = "Normal";
})(CompatibilityLevel || (exports.CompatibilityLevel = CompatibilityLevel = {}));
/**
 * Downcasts a {@link TreeNodeSchemaCore} to {@link TreeNodeSchemaCorePrivate} and get its {@link TreeNodeSchemaPrivateData}.
 */
function getTreeNodeSchemaPrivateData(schema) {
    (0, internal_1.assert)(exports.privateDataSymbol in schema, 0xbc9 /* All implementations of TreeNodeSchemaCore must also implement TreeNodeSchemaCorePrivate */);
    const schemaValid = schema;
    return schemaValid[exports.privateDataSymbol];
}
exports.getTreeNodeSchemaPrivateData = getTreeNodeSchemaPrivateData;
/**
 * Kind of tree node.
 * @remarks
 * More kinds may be added over time, so do not assume this is an exhaustive set.
 * @public
 */
var NodeKind;
(function (NodeKind) {
    /**
     * A node which serves as a map, storing children under string keys.
     */
    NodeKind[NodeKind["Map"] = 0] = "Map";
    /**
     * A node which serves as an array, storing children in an ordered sequence.
     */
    NodeKind[NodeKind["Array"] = 1] = "Array";
    /**
     * A node which stores a heterogenous collection of children in named fields.
     * @remarks
     * Each field gets its own schema.
     */
    NodeKind[NodeKind["Object"] = 2] = "Object";
    /**
     * A node which stores a single leaf value.
     */
    NodeKind[NodeKind["Leaf"] = 3] = "Leaf";
    /**
     * A node which serves as a record, storing children under string keys.
     */
    NodeKind[NodeKind["Record"] = 4] = "Record";
})(NodeKind || (exports.NodeKind = NodeKind = {}));
/**
 * Returns true if the given schema is a {@link TreeNodeSchemaClass}, or otherwise false if it is a {@link TreeNodeSchemaNonClass}.
 * @internal
 */
function isTreeNodeSchemaClass(schema) {
    return schema.constructor !== undefined;
}
exports.isTreeNodeSchemaClass = isTreeNodeSchemaClass;
//# sourceMappingURL=treeNodeSchema.js.map