/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { ICodecFamily } from "../../codec/index.js";
import { ChangeAtomIdMap, ChangeEncodingContext, ChangeFamily, ChangeFamilyEditor, ChangeRebaser, ChangesetLocalId, DeltaDetachedNodeId, DeltaRoot, EditBuilder, FieldKindIdentifier, FieldUpPath, ITreeCursorSynchronous, RevisionInfo, RevisionMetadataSource, RevisionTag, TaggedChange, UpPath } from "../../core/index.js";
import { TreeChunk } from "../chunked-forest/index.js";
import { FieldChangeHandler, RebaseRevisionMetadata } from "./fieldChangeHandler.js";
import { FieldKindWithEditor } from "./fieldKindWithEditor.js";
import { FieldChangeset, ModularChangeset } from "./modularChangeTypes.js";
/**
 * Implementation of ChangeFamily which delegates work in a given field to the appropriate FieldKind
 * as determined by the schema.
 */
export declare class ModularChangeFamily implements ChangeFamily<ModularEditBuilder, ModularChangeset>, ChangeRebaser<ModularChangeset> {
    readonly codecs: ICodecFamily<ModularChangeset, ChangeEncodingContext>;
    static readonly emptyChange: ModularChangeset;
    readonly fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>;
    constructor(fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>, codecs: ICodecFamily<ModularChangeset, ChangeEncodingContext>);
    get rebaser(): ChangeRebaser<ModularChangeset>;
    /**
     * Produces an equivalent list of `FieldChangeset`s that all target the same {@link FlexFieldKind}.
     * @param changes - The list of `FieldChange`s whose `FieldChangeset`s needs to be normalized.
     * @returns An object that contains both the equivalent list of `FieldChangeset`s that all
     * target the same {@link FlexFieldKind}, and the `FieldKind` that they target.
     * The returned `FieldChangeset`s may be a shallow copy of the input `FieldChange`s.
     */
    private normalizeFieldChanges;
    private normalizeFieldChange;
    compose(changes: TaggedChange<ModularChangeset>[]): ModularChangeset;
    private composePair;
    private composeFieldMaps;
    private composeNodesById;
    private composeNodeChanges;
    /**
     * @param change - The change to invert.
     * @param isRollback - Whether the inverted change is meant to rollback a change on a branch as is the case when
     * performing a sandwich rebase.
     * @param repairStore - The store to query for repair data.
     */
    invert(change: TaggedChange<ModularChangeset>, isRollback: boolean): ModularChangeset;
    private invertFieldMap;
    private invertNodeChange;
    rebase(change: ModularChangeset, over: TaggedChange<ModularChangeset>, revisionMetadata: RevisionMetadataSource): ModularChangeset;
    private rebaseFieldMap;
    private rebaseNodeChange;
    private pruneFieldMap;
    private pruneNodeChange;
    buildEditor(changeReceiver: (change: ModularChangeset) => void): ModularEditBuilder;
}
/**
 * Returns the set of removed roots that should be in memory for the given change to be applied.
 * A removed root is relevant if any of the following is true:
 * - It is being inserted
 * - It is being restored
 * - It is being edited
 * - The ID it is associated with is being changed
 *
 * May be conservative by returning more removed roots than strictly necessary.
 *
 * Will never return IDs for non-root trees, even if they are removed.
 *
 * @param change - The change to be applied.
 * @param fieldKinds - The field kinds to delegate to.
 */
export declare function relevantRemovedRoots({ change, revision }: TaggedChange<ModularChangeset>, fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>): Iterable<DeltaDetachedNodeId>;
/**
 * Adds any refreshers missing from the provided change that are relevant to the change and
 * removes any refreshers from the provided change that are not relevant to the change.
 * This function enforces that all relevant removed roots have a corresponding build or refresher.
 *
 * @param change - The change that possibly has missing or superfluous refreshers. Not mutated by this function.
 * @param getDetachedNode - The function to retrieve a tree chunk from the corresponding detached node id.
 * @param removedRoots - The set of removed roots that should be in memory for the given change to be applied.
 * Can be retrieved by calling {@link relevantRemovedRoots}.
 */
export declare function updateRefreshers({ change, revision }: TaggedChange<ModularChangeset>, getDetachedNode: (id: DeltaDetachedNodeId) => TreeChunk | undefined, removedRoots: Iterable<DeltaDetachedNodeId>): ModularChangeset;
/**
 * @param change - The change to convert into a delta.
 * @param fieldKinds - The field kinds to delegate to.
 */
export declare function intoDelta(taggedChange: TaggedChange<ModularChangeset>, fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>): DeltaRoot;
/**
 * @internal
 * @param revInfos - This should describe all revisions in the rebase path, even if not part of the current base changeset.
 * For example, when rebasing change B from a local branch [A, B, C] over a branch [X, Y], the `revInfos` must include
 * the changes [A⁻¹ X, Y, A'] for each rebase step of B.
 * @param baseRevisions - The set of revisions in the changeset being rebased over.
 * For example, when rebasing change B from a local branch [A, B, C] over a branch [X, Y], the `baseRevisions` must include
 * revisions [A⁻¹ X, Y, A'] if rebasing over the composition of all those changes, or
 * revision [A⁻¹] for the first rebase, then [X], etc. if rebasing over edits individually.
 * @returns - RebaseRevisionMetadata to be passed to `FieldChangeRebaser.rebase`*
 */
export declare function rebaseRevisionMetadataFromInfo(revInfos: readonly RevisionInfo[], baseRevisions: (RevisionTag | undefined)[]): RebaseRevisionMetadata;
export declare function getFieldKind(fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>, kind: FieldKindIdentifier): FieldKindWithEditor;
export declare function getChangeHandler(fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>, kind: FieldKindIdentifier): FieldChangeHandler<unknown>;
export declare class ModularEditBuilder extends EditBuilder<ModularChangeset> {
    private transactionDepth;
    private idAllocator;
    constructor(family: ChangeFamily<ChangeFamilyEditor, ModularChangeset>, changeReceiver: (change: ModularChangeset) => void);
    enterTransaction(): void;
    exitTransaction(): void;
    /**
     * @param firstId - The ID to associate with the first node
     * @param content - The node(s) to build. Can be in either Field or Node mode.
     * @returns A description of the edit that can be passed to `submitChanges`.
     */
    buildTrees(firstId: ChangesetLocalId, content: ITreeCursorSynchronous): GlobalEditDescription;
    /**
     * Adds a change to the edit builder
     * @param field - the field which is being edited
     * @param fieldKind - the kind of the field
     * @param change - the change to the field
     * @param maxId - the highest `ChangesetLocalId` used in this change
     */
    submitChange(field: FieldUpPath, fieldKind: FieldKindIdentifier, change: FieldChangeset): void;
    submitChanges(changes: EditDescription[]): void;
    buildChanges(changes: EditDescription[]): ModularChangeset;
    generateId(count?: number): ChangesetLocalId;
    addNodeExistsConstraint(path: UpPath): void;
}
/**
 * @internal
 */
export interface FieldEditDescription {
    type: "field";
    field: FieldUpPath;
    fieldKind: FieldKindIdentifier;
    change: FieldChangeset;
}
/**
 * @internal
 */
export interface GlobalEditDescription {
    type: "global";
    builds?: ChangeAtomIdMap<TreeChunk>;
}
/**
 * @internal
 */
export type EditDescription = FieldEditDescription | GlobalEditDescription;
//# sourceMappingURL=modularChangeFamily.d.ts.map