/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { IIdCompressor } from "@fluidframework/id-compressor";
import { type FieldKey, type FieldKindIdentifier, type ITreeCursorSynchronous, type TreeFieldStoredSchema, type TreeNodeSchemaIdentifier, type Value } from "../../../core/index.js";
import type { FlexFieldKind } from "../../modular-schema/index.js";
import type { Counter, DeduplicationTable } from "./chunkCodecUtilities.js";
import { type BufferFormat as BufferFormatGeneric, Shape as ShapeGeneric } from "./chunkEncodingGeneric.js";
import type { FieldBatch } from "./fieldBatch.js";
import { type EncodedChunkShape, type EncodedFieldBatch, type EncodedValueShape } from "./format.js";
/**
 * Encode data from `FieldBatch` into an `EncodedChunk`.
 *
 * Optimized for encoded size and encoding performance.
 *
 * Most of the compression strategy comes from the policy provided via `context`.
 */
export declare function compressedEncode(fieldBatch: FieldBatch, context: EncoderContext): EncodedFieldBatch;
export type BufferFormat = BufferFormatGeneric<EncodedChunkShape>;
export type Shape = ShapeGeneric<EncodedChunkShape>;
/**
 * Like {@link FieldEncoder}, except data will be prefixed with the key.
 */
export interface KeyedFieldEncoder {
    readonly key: FieldKey;
    readonly encoder: FieldEncoder;
}
/**
 * An encoder with an associated shape.
 */
export interface Encoder {
    /**
     * The shape which describes how the encoded data is laid out.
     * Used by decoders to interpret the output of `encodeNode`.
     */
    readonly shape: Shape;
}
/**
 * An encoder for a specific shape of node.
 *
 * Can only be used with compatible nodes.
 */
export interface NodeEncoder extends Encoder {
    /**
     * @param cursor - in Nodes mode. Does not move cursor.
     */
    encodeNode(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat): void;
}
/**
 * Like {@link NodeEncoder}, except encodes a run of nodes.
 */
export interface NodesEncoder extends Encoder {
    /**
     * @param cursor - in Nodes mode. Moves cursor however many nodes it encodes.
     */
    encodeNodes(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat): void;
}
/**
 * Like {@link NodeEncoder}, except encodes a field.
 */
export interface FieldEncoder extends Encoder {
    /**
     * @param cursor - in Fields mode. Encodes entire field.
     */
    encodeField(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat): void;
}
/**
 * Makes a {@link FieldEncoder} which runs `encoder` on every node in the field.
 * This does not encode the number nodes: the user of this may need to encode that elsewhere.
 */
export declare function asFieldEncoder(encoder: NodeEncoder): FieldEncoder;
/**
 * Adapt a {@link NodeEncoder} to a {@link NodesEncoder} which invokes `encoder` once.
 */
export declare function asNodesEncoder(encoder: NodeEncoder): NodesEncoder;
/**
 * Encodes a chunk with {@link EncodedAnyShape} by prefixing the data with its shape.
 */
export declare class AnyShape extends ShapeGeneric<EncodedChunkShape> {
    private constructor();
    static readonly instance: AnyShape;
    encodeShape(identifiers: DeduplicationTable<string>, shapes: DeduplicationTable<Shape>): EncodedChunkShape;
    countReferencedShapesAndIdentifiers(identifiers: Counter<string>, shapeDiscovered: (shape: Shape) => void): void;
    static encodeField(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat, encoder: FieldEncoder): void;
    static encodeNode(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat, encoder: NodeEncoder): void;
    static encodeNodes(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat, encoder: NodesEncoder): void;
}
/**
 * Encodes a single node polymorphically.
 */
export declare const anyNodeEncoder: NodeEncoder;
/**
 * Encodes a field polymorphically.
 */
export declare const anyFieldEncoder: FieldEncoder;
/**
 * Encodes a chunk using {@link EncodedInlineArrayShape}.
 * @remarks
 * The fact this is also a Shape is an implementation detail of the encoder: that allows the shape it uses to be itself,
 * which is an easy way to keep all the related code together without extra objects.
 */
export declare class InlineArrayEncoder extends ShapeGeneric<EncodedChunkShape> implements NodesEncoder, FieldEncoder {
    readonly length: number;
    readonly inner: NodesEncoder;
    static readonly empty: InlineArrayEncoder;
    /**
     * @param length - number of invocations of `inner`.
     */
    constructor(length: number, inner: NodesEncoder);
    encodeNodes(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat): void;
    encodeField(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat): void;
    encodeShape(identifiers: DeduplicationTable<string>, shapes: DeduplicationTable<Shape>): EncodedChunkShape;
    countReferencedShapesAndIdentifiers(identifiers: Counter<string>, shapeDiscovered: (shape: Shape) => void): void;
    get shape(): this;
}
/**
 * Encodes a field as a nested array with the {@link EncodedNestedArrayShape} shape.
 * @remarks
 * The fact this is also a Shape is an implementation detail of the encoder: that allows the shape it uses to be itself,
 * which is an easy way to keep all the related code together without extra objects.
 */
export declare class NestedArrayEncoder extends ShapeGeneric<EncodedChunkShape> implements FieldEncoder {
    readonly inner: NodeEncoder;
    readonly shape: Shape;
    constructor(inner: NodeEncoder);
    encodeField(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat): void;
    encodeShape(identifiers: DeduplicationTable<string>, shapes: DeduplicationTable<Shape>): EncodedChunkShape;
    countReferencedShapesAndIdentifiers(identifiers: Counter<string>, shapeDiscovered: (shape: Shape) => void): void;
}
/**
 * Encode `value` with `shape` into `outputBuffer`.
 *
 * Requires that `value` is compatible with `shape`.
 */
export declare function encodeValue(value: Value, shape: EncodedValueShape, outputBuffer: BufferFormat): void;
/**
 * Provides common contextual information during encoding, like schema and policy settings.
 * Also, provides a cache to avoid duplicating equivalent shapes during a batch of encode operations.
 * To avoid Shape duplication, any Shapes used in the encoding should either be:
 * - Singletons defined in a static scope.
 * - Cached in this object for future reuse such that all equivalent Shapes are deduplicated.
 */
export declare class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {
    private readonly nodeEncoderFromPolicy;
    private readonly fieldEncoderFromPolicy;
    readonly fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>;
    readonly idCompressor: IIdCompressor;
    private readonly nodeEncodersFromSchema;
    private readonly nestedArrayEncoders;
    constructor(nodeEncoderFromPolicy: NodeEncoderPolicy, fieldEncoderFromPolicy: FieldEncoderPolicy, fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>, idCompressor: IIdCompressor);
    nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder;
    fieldEncoderFromSchema(fieldSchema: TreeFieldStoredSchema): FieldEncoder;
    nestedArrayEncoder(inner: NodeEncoder): NestedArrayEncoder;
}
export interface NodeEncodeBuilder {
    nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder;
}
export interface FieldEncodeBuilder {
    fieldEncoderFromSchema(schema: TreeFieldStoredSchema): FieldEncoder;
}
/**
 * The policy for building a {@link FieldEncoder} for a field.
 */
export type FieldEncoderPolicy = (nodeBuilder: NodeEncodeBuilder, schema: TreeFieldStoredSchema) => FieldEncoder;
/**
 * The policy for building a {@link NodeEncoder} for a node.
 */
export type NodeEncoderPolicy = (fieldBuilder: FieldEncodeBuilder, schemaName: TreeNodeSchemaIdentifier) => NodeEncoder;
//# sourceMappingURL=compressedEncode.d.ts.map