/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { idAllocatorFromMaxId } from "../../util";
import { DetachedFieldIndex } from "./detachedFieldIndex";
import { visitDelta } from "./visitDelta";
export function makeDetachedFieldIndex(prefix = "Temp") {
    return new DetachedFieldIndex(prefix, idAllocatorFromMaxId());
}
export function applyDelta(delta, deltaProcessor, detachedFieldIndex) {
    const visitor = deltaProcessor.acquireVisitor();
    visitDelta(delta, visitor, detachedFieldIndex);
    visitor.free();
}
export function announceDelta(delta, deltaProcessor, detachedFieldIndex) {
    const visitor = deltaProcessor.acquireVisitor();
    visitDelta(delta, combineVisitors([visitor], [visitor]), detachedFieldIndex);
    visitor.free();
}
export function combineVisitors(visitors, announceVisitors = []) {
    return {
        free: () => visitors.forEach((v) => v.free()),
        create: (...args) => {
            visitors.forEach((v) => v.create(...args));
            announceVisitors.forEach((v) => v.afterCreate(...args));
        },
        destroy: (...args) => {
            announceVisitors.forEach((v) => v.beforeDestroy(...args));
            visitors.forEach((v) => v.destroy(...args));
        },
        attach: (source, count, destination) => {
            announceVisitors.forEach((v) => v.beforeAttach(source, count, destination));
            visitors.forEach((v) => v.attach(source, count, destination));
            announceVisitors.forEach((v) => v.afterAttach(source, { start: destination, end: destination + count }));
        },
        detach: (source, destination) => {
            announceVisitors.forEach((v) => v.beforeDetach(source, destination));
            visitors.forEach((v) => v.detach(source, destination));
            announceVisitors.forEach((v) => v.afterDetach(source.start, source.end - source.start, destination));
        },
        replace: (newContent, oldContent, oldContentDestination) => {
            announceVisitors.forEach((v) => v.beforeReplace(newContent, oldContent, oldContentDestination));
            visitors.forEach((v) => v.replace(newContent, oldContent, oldContentDestination));
            announceVisitors.forEach((v) => v.afterReplace(newContent, oldContent, oldContentDestination));
        },
        enterNode: (...args) => visitors.forEach((v) => v.enterNode(...args)),
        exitNode: (...args) => visitors.forEach((v) => v.exitNode(...args)),
        enterField: (...args) => visitors.forEach((v) => v.enterField(...args)),
        exitField: (...args) => visitors.forEach((v) => v.exitField(...args)),
    };
}
//# sourceMappingURL=visitorUtils.js.map