/** @packageDocumentation
 * @module Schema
 */
import { Id64String } from "@itwin/core-bentley";
import { ElementLoadOptions, EntityProps, EntityReferenceSet, PropertyCallback } from "@itwin/core-common";
import type { IModelDb } from "./IModelDb";
import { Schema } from "./Schema";
import { EntityClass, Property, RelationshipClass, SchemaItemKey } from "@itwin/ecschema-metadata";
/** Represents a row returned by an ECSql query. The row is returned as a map of property names to values.
 * ECSqlRow has same schema as declared in ECSchema for the class and similar to if ECSQL SELECT * FROM <schema>:<class> were executed.
 * @beta */
export interface ECSqlRow {
    [key: string]: any;
}
/** Set of properties that are used to deserialize an [[EntityProps]] from an ECSqlRow.
 * @beta */
export interface DeserializeEntityArgs {
    /** Row to deserialize */
    row: ECSqlRow;
    /** The IModel that contains this Entity */
    iModel: IModelDb;
    /** The options used when loading */
    options?: {
        /** Options used when loading an element */
        element?: ElementLoadOptions;
    };
}
/** A property of an [[Entity]] that needs to be custom handled during deserialization and serialization.
 * @beta */
export interface CustomHandledProperty {
    /** The name of the property as it appears in the ECSqlRow */
    readonly propertyName: string;
    /** Where the property is defined */
    readonly source: "Class" | "Computed";
}
/** Represents one of the fundamental building block in an [[IModelDb]]: as an [[Element]], [[Model]], or [[Relationship]].
 * Every subclass of Entity represents one BIS [ECClass]($ecschema-metadata).
 * An Entity is typically instantiated from an [EntityProps]($common) and can be converted back to this representation via [[Entity.toJSON]].
 * @public @preview
 */
export declare class Entity {
    /** An immutable property used to discriminate between [[Entity]] and [EntityProps]($common), used to inform the TypeScript compiler that these two types
     * are never substitutable for one another. To obtain an EntityProps from an Entity, use [[Entity.toJSON]].
     */
    readonly isInstanceOfEntity: true;
    /** The Schema that defines this class. */
    static schema: typeof Schema;
    private get _ctor();
    /** The name of the BIS class associated with this class.
     * @note Every subclass of Entity **MUST** override this method to identify its BIS class.
     * Failure to do so will ordinarily result in an error when the class is registered, since there may only
     * be one JavaScript class for a given BIS class (usually the errant class will collide with its superclass.)
     */
    static get className(): string;
    /** Serves as a unique identifier for this class. Typed variant of [[classFullName]].
     * @public @preview
     */
    static get schemaItemKey(): SchemaItemKey;
    /** Cached Metadata for the ECClass */
    protected _metadata?: EntityClass | RelationshipClass;
    /** When working with an Entity it can be useful to set property values directly, bypassing the compiler's type checking.
     * This property makes such code slightly less tedious to read and write.
     * @internal
     */
    get asAny(): any;
    /** The name of the BIS Schema that defines this class */
    get schemaName(): string;
    /** The name of the BIS class associated with this class. */
    get className(): string;
    /** The [[IModelDb]] that contains this Entity */
    iModel: IModelDb;
    /** The Id of this Entity. May be invalid if the Entity has not yet been saved in the database. */
    id: Id64String;
    protected constructor(props: EntityProps, iModel: IModelDb);
    /** Invoke the constructor of the specified `Entity` subclass.
     * @internal
     */
    static instantiate(subclass: typeof Entity, props: EntityProps, iModel: IModelDb): Entity;
    /** List of properties that are need to be custom handled during deserialization and serialization.
     * These properties differ between the ECSql instance of an Entity and the Entity itself.
     * @beta */
    protected static readonly _customHandledProps: CustomHandledProperty[];
    /** Get the list of properties that are custom handled by this class and its superclasses.
     * @internal */
    private static getCustomHandledProperties;
    /** Converts an ECSqlRow of an Entity to an EntityProps. This is used to deserialize an Entity from the database.
     * @beta */
    static deserialize(props: DeserializeEntityArgs): EntityProps;
    /** Converts an EntityProps to an ECSqlRow. This is used to serialize an Entity to prepare to write it to the database.
     * @beta */
    static serialize(props: EntityProps, _iModel: IModelDb): ECSqlRow;
    /** Obtain the JSON representation of this Entity. Subclasses of [[Entity]] typically override this method to return their corresponding sub-type of [EntityProps]($common) -
     * for example, [[GeometricElement.toJSON]] returns a [GeometricElementProps]($common).
     */
    toJSON(): EntityProps;
    /** Call a function for each property of this Entity.
     * @param func The callback to be invoked on each property
     * @param includeCustom If true (default), include custom-handled properties in the iteration. Otherwise, skip custom-handled properties.
     * @note Custom-handled properties are core properties that have behavior enforced by C++ handlers.
     * @deprecated in 5.0 - will not be removed until after 2026-06-13. Please use `forEach` to get the metadata and iterate over the properties instead.
     *
     * @example
     * ```typescript
     * // Deprecated method
     * entity.forEachProperty((name, propMetaData) => {
     *   console.log(`Property name: ${name}, Property type: ${propMetaData.primitiveType}`);
     * });
     *
     * // New method
     * entity.forEach((name, property) => {
     *   console.log(`Property name: ${name}, Property type: ${property.propertyType}`);
     * });
     * ```
     */
    forEachProperty(func: PropertyCallback, includeCustom?: boolean): void;
    /**
     * Call a function for each property of this Entity.
     * @param func The callback to be invoked on each property.
     * @param includeCustom If true (default), include custom-handled properties in the iteration. Otherwise, skip custom-handled properties.
     * @note Custom-handled properties are core properties that have behavior enforced by C++ handlers.
     * @throws Error if metadata for the class cannot be retrieved.
     *
     * @example
     * ```typescript
     * entity.forEach((name, property) => {
     *   console.log(`Property name: ${name}, Property type: ${property.propertyType}`);
     * });
     * ```
     */
    forEach(func: PropertyHandler, includeCustom?: boolean): void;
    /** Get the full BIS class name of this Entity in the form "schema:class" */
    static get classFullName(): string;
    /** Get the full BIS class name of this Entity in the form "schema:class". */
    get classFullName(): string;
    /**
     * Get the item key used by the ecschema-metadata package to identify this entity class
     * @public @preview
     */
    get schemaItemKey(): SchemaItemKey;
    /** Query metadata for this entity class from the iModel's schema. Returns cached metadata if available.
     * @throws [[IModelError]] if there is a problem querying the schema
     * @returns The metadata for the current entity
     * @public @preview
     */
    getMetaData(): Promise<EntityClass | RelationshipClass>;
    /** @internal */
    getMetaDataSync(): EntityClass | RelationshipClass;
    /** @internal */
    static get protectedOperations(): string[];
    /** return whether this Entity class is a subclass of another Entity class
     * @note the subclass-ness is checked according to JavaScript inheritance, to check the underlying raw EC class's
     * inheritance, you can use [ECClass.is]($ecschema-metadata)
     * @note this should have a type of `is<T extends typeof Entity>(otherClass: T): this is T` but can't because of
     * typescript's restriction on the `this` type in static methods
     */
    static is(otherClass: typeof Entity): boolean;
    /** whether this JavaScript class was generated for this ECClass because there was no registered custom implementation
     * ClassRegistry overrides this when generating a class
     * @internal
     */
    static get isGeneratedClass(): boolean;
    /** Get the set of this entity's *entity references*, [EntityReferenceSet]($backend). An *entity reference* is any id
     * stored on the entity, in its EC properties or json fields.
     * This is important for cloning operations but can be useful in other situations as well.
     * @see this.collectReferenceIds
     * @beta
     */
    getReferenceIds(): EntityReferenceSet;
    /** Collect the Ids of this entity's *references* at this level of the class hierarchy.
     * A *reference* is any entity referenced by this entity's EC Data, including json fields.
     * This is important for cloning operations but can be useful in other situations as well.
     * @param _referenceIds The Id64Set to populate with reference Ids.
     * @note This should be overridden (with `super` called) at each level the class hierarchy that introduces references.
     * @see getReferenceIds
     * @beta
     */
    protected collectReferenceIds(_referenceIds: EntityReferenceSet): void;
}
/** A callback function to process properties of an Entity
 * @public @preview
 */
export type PropertyHandler = (name: string, property: Property) => void;
/** Parameter type that can accept both abstract constructor types and non-abstract constructor types for `instanceof` to test.
 * @public @preview
 */
export type EntityClassType<T> = Function & {
    prototype: T;
};
//# sourceMappingURL=Entity.d.ts.map