/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { ICodecFamily } from "../../codec/index.js";
import { type ChangeAtomId, type ChangeEncodingContext, type ChangeFamily, type ChangeFamilyEditor, type ChangeRebaser, type ChangesetLocalId, type DeltaDetachedNodeId, type DeltaRoot, type EditorOptions, type NormalizedFieldUpPath, type NormalizedUpPath, type RevisionTag, type TaggedChange, type TreeChunk } from "../../core/index.js";
import { type ModularChangeset } from "../modular-schema/index.js";
export type DefaultChangeset = ModularChangeset;
/**
 * Implementation of {@link ChangeFamily} based on the default set of supported field kinds.
 *
 * @sealed
 */
export declare class DefaultChangeFamily implements ChangeFamily<IdBasedChangeFamilyDataEditor, DefaultChangeset> {
    private readonly modularFamily;
    constructor(codecs: ICodecFamily<ModularChangeset, ChangeEncodingContext>);
    get rebaser(): ChangeRebaser<DefaultChangeset>;
    get codecs(): ICodecFamily<DefaultChangeset, ChangeEncodingContext>;
    buildEditor(mintRevisionTag: () => RevisionTag, changeReceiver: (change: TaggedChange<DefaultChangeset>) => void, options?: EditorOptions): IdBasedChangeFamilyDataEditor;
}
/**
 * @param change - The change to convert into a delta.
 */
export declare function intoDelta(taggedChange: TaggedChange<ModularChangeset>): DeltaRoot;
/**
 * 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.
 */
export declare function relevantRemovedRoots(change: ModularChangeset): Iterable<DeltaDetachedNodeId>;
export declare function getBuildsIds(change: ModularChangeset): Iterable<DeltaDetachedNodeId>;
export type DetachedRootIds = readonly DetachedRootIdRange[];
export interface DetachedRootIdRange {
    readonly first: ChangeAtomId;
    readonly count: number;
}
/**
 * Default editor for tree data changes.
 * @privateRemarks
 * When taking into account not just the content of the tree,
 * but also how the merge identities (and thus anchors, flex-tree and simple-tree nodes) of nodes before and after the edits correspond,
 * some edits are currently impossible to express.
 * Examples of these non-expressible edits include:
 *
 * - Changing the type of a node while keeping its merge identity.
 * - Changing the value of a leaf while keeping its merge identity.
 * - Swapping subtrees between two value fields.
 * - Replacing a node in the middle of a tree while reusing some of the old nodes decedents that were under value fields.
 *
 * At some point it will likely be worth supporting at least some of these, possibly using a mechanism that could support all of them if desired.
 * If/when such a mechanism becomes available, an evaluation should be done to determine if any existing editing operations should be changed to leverage it
 * (Possibly by adding opt ins at the view schema layer).
 */
export interface DataEditor<TContent, TDetachedRoot, TDetachedRoots> {
    /**
     * Moves a subsequence from one sequence field to another sequence field.
     *
     * Note that the `destinationIndex` is interpreted based on the state of the sequence *before* the move operation.
     * For example, `move(field, 0, 1, field, 2)` changes `[A, B, C]` to `[B, A, C]`.
     */
    move(sourceField: NormalizedFieldUpPath, sourceIndex: number, count: number, destinationField: NormalizedFieldUpPath, destinationIndex: number): void;
    /**
     * Add a constraint that the node at the given path must exist.
     * @param path - The path to the node that must exist.
     */
    addNodeExistsConstraint(path: NormalizedUpPath): void;
    /**
     * Add a constraint that the node at the given path must exist when reverting a change.
     * @param path - The path to the node that must exist when reverting a change.
     */
    addNodeExistsConstraintOnRevert(path: NormalizedUpPath): void;
    /**
     * Builds the detached roots for the given content.
     * @param content - The content to be built into detached nodes.
     *
     * Requires SharedTreeFormatVersion.vDetachedRoots or later.
     */
    buildRoots(content: TContent): TDetachedRoots;
    /**
     * @param field - the value field which is being edited under the parent node
     * @returns An object with methods to edit the given field of the given parent.
     * The returned object can be used (i.e., have its methods called) multiple times but its lifetime
     * is bounded by the lifetime of this edit builder.
     */
    valueField(field: NormalizedFieldUpPath): RequiredFieldEditor<TContent, TDetachedRoot>;
    /**
     * @param field - the optional field which is being edited under the parent node
     * @returns An object with methods to edit the given field of the given parent.
     * The returned object can be used (i.e., have its methods called) multiple times but its lifetime
     * is bounded by the lifetime of this edit builder.
     */
    optionalField(field: NormalizedFieldUpPath): OptionalFieldEditor<TContent, TDetachedRoot>;
    /**
     * @param field - the sequence field which is being edited under the parent node
     *
     * @returns An object with methods to edit the given field of the given parent.
     * The returned object can be used (i.e., have its methods called) multiple times but its lifetime
     * is bounded by the lifetime of this edit builder.
     */
    sequenceField(field: NormalizedFieldUpPath): SequenceFieldEditor<TContent, TDetachedRoots>;
}
export type IdBasedChangeFamilyDataEditor = ChangeFamilyEditor & DataEditor<TreeChunk, ChangeAtomId, DetachedRootIds>;
export declare function offsetChangesetLocalId(id: ChangesetLocalId, offset: number): ChangesetLocalId;
export declare function subtractChangesetLocalId(a: ChangesetLocalId, b: ChangesetLocalId): number;
/**
 * Implementation of {@link IdBasedChangeFamilyDataEditor} based on the default set of supported field kinds.
 * @sealed
 */
export declare class DefaultIdBasedDataEditor implements IdBasedChangeFamilyDataEditor {
    private readonly mintRevisionTag;
    private readonly options;
    private readonly modularBuilder;
    private readonly nodesWithoutCells;
    constructor(family: ChangeFamily<ChangeFamilyEditor, DefaultChangeset>, mintRevisionTag: () => RevisionTag, changeReceiver: (change: TaggedChange<DefaultChangeset>) => void, options?: EditorOptions);
    enterTransaction(): void;
    exitTransaction(): void;
    addNodeExistsConstraint(path: NormalizedUpPath): void;
    addNodeExistsConstraintOnRevert(path: NormalizedUpPath): void;
    buildRoots(content: TreeChunk): DetachedRootIds;
    valueField(field: NormalizedFieldUpPath): RequiredFieldEditor<TreeChunk, ChangeAtomId>;
    optionalField(field: NormalizedFieldUpPath): OptionalFieldEditor<TreeChunk, ChangeAtomId>;
    move(sourceField: NormalizedFieldUpPath, sourceIndex: number, count: number, destinationField: NormalizedFieldUpPath, destIndex: number): void;
    sequenceField(field: NormalizedFieldUpPath): SequenceFieldEditor<TreeChunk, DetachedRootIds>;
}
export interface RequiredFieldEditor<TContent, TDetachedRoot> {
    /**
     * Issues a change which replaces the content of the field with the given detached node.
     * @param content - The content to be attached in the field in the given order.
     * Must represent a single detached node.
     * Must have been created in the same JS turn.
     *
     * Requires SharedTreeFormatVersion.vDetachedRoots or later.
     */
    attach(content: TDetachedRoot): void;
    /**
     * Issues a change which replaces the content of the field with `newContent`.
     * @param newContent - the new content for the field.
     */
    set(newContent: TContent): void;
}
export interface OptionalFieldEditor<TContent, TDetachedRoots> {
    /**
     * Issues a change which replaces the content of the field with the given detached node.
     * @param content - The content to be attached in the field in the given order.
     * Must represent a single detached node.
     *
     * Requires SharedTreeFormatVersion.vDetachedRoots or later.
     */
    attach(content: TDetachedRoots | undefined, wasEmpty: boolean): void;
    /**
     * Issues a change which clears content of the field.
     * @param wasEmpty - whether the field is empty when creating this change
     */
    clear(wasEmpty: boolean): void;
    /**
     * Issues a change which replaces the content of the field with `newContent`
     * @param newContent - the new content for the field.
     * @param wasEmpty - whether the field is empty when creating this change
     */
    set(newContent: TContent | undefined, wasEmpty: boolean): void;
}
/**
 * Editor for the sequence field kind.
 */
export interface SequenceFieldEditor<TContent, TDetachedRoots, TRemoved = void> {
    /**
     * Issues a change which attaches a sequence of detached nodes at the given `index`.
     * @param index - The index at which to attach the detached nodes.
     * @param detachedContent - The content to be attached in the field in the given order. Each node must be detached.
     *
     * Requires SharedTreeFormatVersion.vDetachedRoots or later.
     */
    attach(index: number, detachedContent: TDetachedRoots): void;
    /**
     * Issues a change which inserts the `newContent` at the given `index`.
     * @param index - the index at which to insert the `newContent`.
     * @param newContent - the new content to be inserted in the field.
     */
    insert(index: number, newContent: TContent): void;
    /**
     * Issues a change which removes `count` elements starting at the given `index`.
     * @param index - The index of the first removed element.
     * @param count - The number of elements to remove.
     */
    remove(index: number, count: number): TRemoved;
}
//# sourceMappingURL=defaultEditBuilder.d.ts.map