"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.SharedTreeMutableChangeEnricher = exports.SharedTreeReadonlyChangeEnricher = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
const index_js_1 = require("../core/index.js");
const index_js_2 = require("../feature-libraries/index.js");
const index_js_3 = require("../util/index.js");
const sharedTreeChangeFamily_js_1 = require("./sharedTreeChangeFamily.js");
class SharedTreeReadonlyChangeEnricher {
    /**
     * @param borrowedForest - The state based on which to enrich changes.
     * Not owned by the constructed instance.
     * @param schema - The schema that corresponds to the forest.
     * @param borrowedRemovedRoots - The set of removed roots based on which to enrich changes.
     * Not owned by the constructed instance.
     * @param idCompressor - The id compressor to use when chunking trees.
     */
    constructor(borrowedForest, schema, borrowedRemovedRoots, idCompressor) {
        this.borrowedForest = borrowedForest;
        this.schema = schema;
        this.borrowedRemovedRoots = borrowedRemovedRoots;
        this.idCompressor = idCompressor;
        this.getDetachedRoot = (id) => {
            const root = this.borrowedRemovedRoots.tryGetEntry(id);
            if (root !== undefined) {
                const cursor = this.borrowedForest.getCursorAboveDetachedFields();
                const parentField = this.borrowedRemovedRoots.toFieldKey(root);
                cursor.enterField(parentField);
                cursor.enterNode(0);
                return (0, index_js_2.chunkTree)(cursor, {
                    policy: index_js_2.defaultChunkPolicy,
                    idCompressor: this.idCompressor,
                });
            }
            return undefined;
        };
    }
    fork() {
        return new SharedTreeMutableChangeEnricher(this.borrowedForest.clone(this.schema, new index_js_1.AnchorSet()), this.schema, this.borrowedRemovedRoots.clone());
    }
    updateChangeEnrichments(change) {
        return (0, sharedTreeChangeFamily_js_1.updateRefreshers)(change, index_js_2.getBuildsIds, this.getDetachedRoot, index_js_2.relevantRemovedRoots, index_js_2.updateRefreshers);
    }
}
exports.SharedTreeReadonlyChangeEnricher = SharedTreeReadonlyChangeEnricher;
class SharedTreeMutableChangeEnricher extends SharedTreeReadonlyChangeEnricher {
    /**
     * @param forest - The state based on which to enrich changes.
     * Owned by the constructed instance.
     * @param schema - The schema that corresponds to the forest.
     * @param removedRoots - The set of removed roots based on which to enrich changes.
     * Owned by the constructed instance.
     * @param idCompressor - The id compressor to use when chunking trees.
     */
    constructor(forest, schema, removedRoots, idCompressor) {
        super(forest, schema, removedRoots, idCompressor);
        this.forest = forest;
        this.removedRoots = removedRoots;
    }
    applyTipChange(change, revision) {
        for (const dataOrSchemaChange of change.changes) {
            const type = dataOrSchemaChange.type;
            switch (type) {
                case "data": {
                    const delta = (0, index_js_2.intoDelta)((0, index_js_1.tagChange)(dataOrSchemaChange.innerChange, revision));
                    const visitor = this.forest.acquireVisitor();
                    (0, index_js_1.visitDelta)(delta, visitor, this.removedRoots, revision);
                    visitor.free();
                    break;
                }
                case "schema":
                    // This enricher doesn't need to maintain schema information.
                    // Note that the refreshers being generated through `updateChangeEnrichments` will be encoded using
                    // the schema that was used in the input context of the data changeset these refreshers are on.
                    // See the encoding logic in SharedTreeCore for details.
                    break;
                default:
                    (0, internal_1.unreachableCase)(type);
            }
        }
    }
    [index_js_3.disposeSymbol]() {
        // TODO: in the future, forest and/or its AnchorSet may require disposal.
    }
}
exports.SharedTreeMutableChangeEnricher = SharedTreeMutableChangeEnricher;
//# sourceMappingURL=sharedTreeChangeEnricher.js.map