/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { type FieldKindIdentifier, type TreeStoredSchema, type ValueSchema } from "../../core/index.js";
/**
 * @remarks
 *
 * 1. FieldIncompatibility
 *
 * `FieldIncompatibility` represents the differences between two `TreeFieldStoredSchema` objects. It consists of
 * three types of incompatibilities:
 *
 * - FieldKindIncompatibility: Indicates the differences in `FieldKindIdentifier` between two `TreeFieldStoredSchema`
 * objects (e.g., optional, required, sequence, etc.).
 * - AllowedTypesIncompatibility: Indicates the differences in the allowed child types between the two schemas.
 * - ValueSchemaIncompatibility: Specifically indicates the differences in the `ValueSchema` of two
 * `LeafNodeStoredSchema` objects.
 *
 * 2. NodeIncompatibility
 *
 * `NodeIncompatibility` represents the differences between two `TreeNodeStoredSchema` objects and includes:
 *
 * - NodeKindIncompatibility: Indicates the differences in the types of `TreeNodeStoredSchema` (currently supports
 * `ObjectNodeStoredSchema`, `MapNodeStoredSchema`, and `LeafNodeStoredSchema`).
 * - NodeFieldsIncompatibility: Indicates the `FieldIncompatibility` of `TreeFieldStoredSchema` within two
 * `TreeNodeStoredSchema`. It includes an array of `FieldIncompatibility` instances in the `differences` field.
 *
 * When comparing two nodes for compatibility, it only makes sense to compare their fields if the nodes are of
 * the same kind (map, object, leaf).
 *
 * 3. Incompatibility
 *
 * Incompatibility consists of both `NodeIncompatibility` and `FieldIncompatibility`, representing any kind of
 * schema differences. See {@link getAllowedContentIncompatibilities} for more details about how we process it
 * and the ordering.
 */
export type Incompatibility = FieldIncompatibility | NodeIncompatibility;
export type NodeIncompatibility = NodeKindIncompatibility | NodeFieldsIncompatibility;
export type FieldIncompatibility = AllowedTypeIncompatibility | FieldKindIncompatibility | ValueSchemaIncompatibility;
export interface AllowedTypeIncompatibility {
    identifier: string | undefined;
    mismatch: "allowedTypes";
    /**
     * List of allowed type identifiers in viewed schema
     */
    view: string[];
    /**
     * List of allowed type identifiers in stored schema
     */
    stored: string[];
}
export interface FieldKindIncompatibility {
    identifier: string | undefined;
    mismatch: "fieldKind";
    view: FieldKindIdentifier | undefined;
    stored: FieldKindIdentifier | undefined;
}
export interface ValueSchemaIncompatibility {
    identifier: string;
    mismatch: "valueSchema";
    view: ValueSchema | undefined;
    stored: ValueSchema | undefined;
}
export interface NodeKindIncompatibility {
    identifier: string;
    mismatch: "nodeKind";
    view: SchemaFactoryNodeKind | undefined;
    stored: SchemaFactoryNodeKind | undefined;
}
export interface NodeFieldsIncompatibility {
    identifier: string;
    mismatch: "fields";
    differences: FieldIncompatibility[];
}
type SchemaFactoryNodeKind = "object" | "leaf" | "map";
/**
 * @remarks
 *
 * The workflow for finding schema incompatibilities:
 * 1. Compare the two root schemas to identify any `FieldIncompatibility`.
 *
 * 2. For each node schema in the `view`:
 * - Verify if the node schema exists in the stored. If it does, ensure that the `SchemaFactoryNodeKind` are
 * consistent. Otherwise this difference is treated as `NodeKindIncompatibility`
 * - If a node schema with the same identifier exists in both view and stored, and their `SchemaFactoryNodeKind`
 * are consistent, perform a exhaustive validation to identify all `FieldIncompatibility`.
 *
 * 3. For each node schema in the stored, verify if it exists in the view. The overlapping parts were already
 * addressed in the previous step.
 *
 * @returns the discrepancies between two TreeStoredSchema objects
 */
export declare function getAllowedContentIncompatibilities(view: TreeStoredSchema, stored: TreeStoredSchema): Incompatibility[];
/**
 * @remarks
 *
 * This function uses incompatibilities to determine if changes to a document schema are backward-compatible, i.e., it determines
 * whether the `view` schema allows a superset of the documents that the `stored` schema allows.
 * According to the policy of schema evolution, `isRepoSuperset` supports three types of changes:
 * 1. Adding an optional field to an object node.
 * 2. Expanding the set of allowed types for a field.
 * 3. Relaxing a field kind to a more general field kind.
 *
 * Notes: We expect isRepoSuperset to return consistent results with allowsRepoSuperset. However, currently there are some scenarios
 * where the inconsistency will occur:
 *
 * - Different Node Kinds: If a and b have different node kinds (e.g., a is an objectNodeSchema and b is a mapNodeSchema),
 * `isRepoSuperset` will determine that a can never be the superset of b. In contrast, `allowsRepoSuperset` will continue
 * validating internal fields.
 */
export declare function isRepoSuperset(view: TreeStoredSchema, stored: TreeStoredSchema): boolean;
export {};
//# sourceMappingURL=discrepancies.d.ts.map