"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.keyAsDetachedField = exports.detachedFieldAsKey = exports.rootField = exports.rootFieldKeySymbol = exports.rootFieldKey = exports.EmptyKey = exports.isLocalKey = void 0;
const common_utils_1 = require("@fluidframework/common-utils");
const util_1 = require("../../util");
const globalFieldKeySymbol_1 = require("./globalFieldKeySymbol");
function isLocalKey(key) {
    return typeof key === "string";
}
exports.isLocalKey = isLocalKey;
/**
 * The empty key ("") is used for unnamed relationships, such as the indexer
 * of an explicit array node.
 *
 * This key is a hint that this field is the primary function of the node,
 * and in some abstractions the APIs for this field should be inlined onto the node.
 *
 * TODO:
 * This has to be a LocalFieldKey since different nodes will have different FieldStoredSchema for it.
 * This makes it prone to collisions and suggests
 * that this intention may be better conveyed by metadata on the ITreeSchema.
 * @alpha
 */
exports.EmptyKey = (0, util_1.brand)("");
/**
 * GlobalFieldKey to use for the root of documents.
 * TODO: if we do want to standardize on a single value for this,
 * it likely should be namespaced or a UUID to avoid risk of collisions.
 * @alpha
 */
exports.rootFieldKey = (0, util_1.brand)("rootFieldKey");
/**
 * @alpha
 */
exports.rootFieldKeySymbol = (0, globalFieldKeySymbol_1.symbolFromKey)(exports.rootFieldKey);
/**
 * @alpha
 */
exports.rootField = keyAsDetachedField(exports.rootFieldKeySymbol);
/**
 * Some code abstracts the root as a node with detached fields as its fields.
 * This maps detached field to field keys for thus use.
 *
 * @returns `field` as a {@link FieldKey} usable on a special root node serving as a parent of detached fields.
 * @alpha
 */
function detachedFieldAsKey(field) {
    if (field === exports.rootField) {
        return exports.rootFieldKeySymbol;
    }
    return (0, util_1.brand)((0, util_1.extractFromOpaque)(field));
}
exports.detachedFieldAsKey = detachedFieldAsKey;
/**
 * The inverse of {@link detachedFieldAsKey}.
 * Thus must only be used on {@link LocalFieldKey}s which were produced via {@link detachedFieldAsKey},
 * and with the same scope (ex: forest) as the detachedFieldAsKey was originally from.
 * @alpha
 */
function keyAsDetachedField(key) {
    if (isLocalKey(key)) {
        (0, common_utils_1.assert)(key !== exports.rootFieldKey, 0x3be /* Root is field key must be a global field key */);
        return (0, util_1.brand)(key);
    }
    (0, common_utils_1.assert)(key === exports.rootFieldKeySymbol, 0x3bf /* Root is only allowed global field key as detached field */);
    return (0, util_1.brand)(exports.rootFieldKey);
}
exports.keyAsDetachedField = keyAsDetachedField;
//# sourceMappingURL=types.js.map