@itwin/ecschema-metadata
Version:
ECObjects core concepts in typescript
768 lines • 33.2 kB
JavaScript
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Metadata
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MutableClass = exports.MutableStructClass = exports.StructClass = exports.ECClass = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const DelayedPromise_1 = require("../DelayedPromise");
const XmlSerializationUtils_1 = require("../Deserialization/XmlSerializationUtils");
const ECObjects_1 = require("../ECObjects");
const Exception_1 = require("../Exception");
const SchemaKey_1 = require("../SchemaKey");
const CustomAttribute_1 = require("./CustomAttribute");
const Enumeration_1 = require("./Enumeration");
const Property_1 = require("./Property");
const SchemaItem_1 = require("./SchemaItem");
const Helper_1 = require("../Deserialization/Helper");
/**
* A common abstract class for all of the ECClass types.
* @public @preview
*/
class ECClass extends SchemaItem_1.SchemaItem {
/** @internal */
static get schemaItemType() { return ECObjects_1.AbstractSchemaItemType.Class; } // need this so getItem("name", ECClass) in schema works
_modifier;
_baseClass;
_derivedClasses;
_properties;
_customAttributes;
_mergedPropertyCache;
get modifier() { return this._modifier; }
get customAttributes() { return this._customAttributes; }
/** @internal */
constructor(schema, name, modifier) {
super(schema, name);
if (modifier)
this._modifier = modifier;
else
this._modifier = ECObjects_1.ECClassModifier.None;
}
/**
* Gets the base class if it exists, otherwise returns undefined.
*/
get baseClass() {
return this._baseClass;
}
getBaseClassSync() {
if (!this.baseClass) {
return undefined;
}
return this.schema.lookupItemSync(this.baseClass, ECClass);
}
/**
* Sets the base class of the ECClass. Pass undefined to 'remove' the base class.
*
* @internal
*/
async setBaseClass(baseClass) {
const oldBaseClass = this._baseClass;
this._baseClass = baseClass;
if (baseClass)
this.addDerivedClass(await baseClass, this);
else if (oldBaseClass)
this.removeDerivedClass(await oldBaseClass, this);
}
/**
* Gets the derived classes belonging to this class.
* @returns An array of ECClasses or undefined if no derived classes exist.
*/
async getDerivedClasses() {
if (!this._derivedClasses || this._derivedClasses.size === 0)
return undefined;
return Array.from(await Promise.all(this._derivedClasses.values()));
}
/**
* Convenience method for adding an already loaded ECProperty used by create*Property methods.
* @param prop The property to add.
* @return The property that was added.
*
* @internal
*/
addProperty(prop) {
if (!this._properties)
this._properties = new Map();
this._properties.set(prop.name.toUpperCase(), prop);
this.cleanCache();
return prop;
}
/**
* Deletes a property from within this class.
* @param name The property name to delete, lookup is case-insensitive
* @internal
*/
async deleteProperty(name) {
if (this._properties) {
const property = await this.getProperty(name);
if (property) {
this._properties.delete(name.toUpperCase());
this.cleanCache();
}
}
}
/**
* Deletes a property from within this class.
* @param name The property name to delete, lookup is case-insensitive
* @internal
*/
deletePropertySync(name) {
if (this._properties) {
const property = this.getPropertySync(name);
if (property) {
this._properties.delete(name.toUpperCase());
this.cleanCache();
}
}
}
/**
* Searches, case-insensitive, for an ECProperty with given the name on this class and, by default, on
* all base classes. Set excludeInherited to 'true' to only search the local class.
* @param name The name of the property to retrieve.
* @param excludeInherited If true, excludes inherited properties from the results. Defaults to false.
*/
async getProperty(name, excludeInherited) {
const upperKey = name.toUpperCase();
let property;
if (this._properties) {
property = this._properties.get(upperKey);
if (property) {
return property;
}
}
if (excludeInherited) {
return undefined;
}
if (!this._mergedPropertyCache) {
this._mergedPropertyCache = await this.buildPropertyCache();
}
return this._mergedPropertyCache.get(upperKey);
}
/**
* Searches, case-insensitive, for a local ECProperty with the name provided.
* @param name The name of the property to retrieve.
* @param excludeInherited If true, excludes inherited properties from the results. Defaults to false.
*/
getPropertySync(name, excludeInherited) {
const upperKey = name.toUpperCase();
let property;
if (this._properties) {
property = this._properties.get(upperKey);
if (property) {
return property;
}
}
if (excludeInherited) {
return undefined;
}
if (!this._mergedPropertyCache) {
this._mergedPropertyCache = this.buildPropertyCacheSync();
}
return this._mergedPropertyCache.get(upperKey);
}
/**
* Searches the base class, if one exists, for the property with the name provided.
* @param name The name of the inherited property to find.
*/
async getInheritedProperty(name) {
if (this.baseClass) {
const baseClassObj = await this.baseClass;
return baseClassObj.getProperty(name);
}
return undefined;
}
/**
* Searches the base class, if one exists, for the property with the name provided.
* @param name The name of the inherited property to find.
*/
getInheritedPropertySync(name) {
const baseClassObj = this.getBaseClassSync();
if (baseClassObj)
return baseClassObj.getPropertySync(name);
return undefined;
}
async createPrimitiveProperty(name, primitiveType) {
if (await this.getProperty(name, true))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.DuplicateProperty, `An ECProperty with the name ${name} already exists in the class ${this.name}.`);
const propType = await this.loadPrimitiveType(primitiveType, this.schema);
if (typeof (propType) === "number")
return this.addProperty(new Property_1.PrimitiveProperty(this, name, propType));
return this.addProperty(new Property_1.EnumerationProperty(this, name, new DelayedPromise_1.DelayedPromiseWithProps(propType.key, async () => propType)));
}
createPrimitivePropertySync(name, primitiveType) {
if (this.getPropertySync(name, true))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.DuplicateProperty, `An ECProperty with the name ${name} already exists in the class ${this.name}.`);
const propType = this.loadPrimitiveTypeSync(primitiveType, this.schema);
if (typeof (propType) === "number")
return this.addProperty(new Property_1.PrimitiveProperty(this, name, propType));
return this.addProperty(new Property_1.EnumerationProperty(this, name, new DelayedPromise_1.DelayedPromiseWithProps(propType.key, async () => propType)));
}
async createPrimitiveArrayProperty(name, primitiveType) {
if (await this.getProperty(name, true))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.DuplicateProperty, `An ECProperty with the name ${name} already exists in the class ${this.name}.`);
const propType = await this.loadPrimitiveType(primitiveType, this.schema);
if (typeof (propType) === "number")
return this.addProperty(new Property_1.PrimitiveArrayProperty(this, name, propType));
return this.addProperty(new Property_1.EnumerationArrayProperty(this, name, new DelayedPromise_1.DelayedPromiseWithProps(propType.key, async () => propType)));
}
createPrimitiveArrayPropertySync(name, primitiveType) {
if (this.getPropertySync(name, true))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.DuplicateProperty, `An ECProperty with the name ${name} already exists in the class ${this.name}.`);
const propType = this.loadPrimitiveTypeSync(primitiveType, this.schema);
if (typeof (propType) === "number")
return this.addProperty(new Property_1.PrimitiveArrayProperty(this, name, propType));
return this.addProperty(new Property_1.EnumerationArrayProperty(this, name, new DelayedPromise_1.DelayedPromiseWithProps(propType.key, async () => propType)));
}
/**
*
* @param name The name of property to create.
* @param structType The struct type of property to create.
*
* @internal
*/
async createStructProperty(name, structType) {
if (await this.getProperty(name, true))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.DuplicateProperty, `An ECProperty with the name ${name} already exists in the class ${this.name}.`);
return this.addProperty(new Property_1.StructProperty(this, name, await this.loadStructType(structType, this.schema)));
}
/**
*
* @param name The name of property to create.
* @param structType The struct type of property to create.
*
* @internal
*/
createStructPropertySync(name, structType) {
if (this.getPropertySync(name, true))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.DuplicateProperty, `An ECProperty with the name ${name} already exists in the class ${this.name}.`);
return this.addProperty(new Property_1.StructProperty(this, name, this.loadStructTypeSync(structType, this.schema)));
}
/**
*
* @param name
* @param type
*
* @internal
*/
async createStructArrayProperty(name, structType) {
if (await this.getProperty(name, true))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.DuplicateProperty, `An ECProperty with the name ${name} already exists in the class ${this.name}.`);
return this.addProperty(new Property_1.StructArrayProperty(this, name, await this.loadStructType(structType, this.schema)));
}
/**
*
* @param name
* @param type
*
* @internal
*/
createStructArrayPropertySync(name, structType) {
if (this.getPropertySync(name, true))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.DuplicateProperty, `An ECProperty with the name ${name} already exists in the class ${this.name}.`);
return this.addProperty(new Property_1.StructArrayProperty(this, name, this.loadStructTypeSync(structType, this.schema)));
}
/**
*
* @param structType
* @param schema
* @returns
*
* @internal
*/
async loadStructType(structType, schema) {
let correctType;
if (typeof (structType) === "string") {
correctType = await schema.lookupItem(structType, StructClass);
}
else
correctType = structType;
if (!correctType)
// eslint-disable-next-line @typescript-eslint/no-base-to-string
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidType, `The provided Struct type, ${structType}, is not a valid StructClass.`);
return correctType;
}
/**
*
* @param structType
* @param schema
* @returns
*
* @internal
*/
loadStructTypeSync(structType, schema) {
let correctType;
if (typeof (structType) === "string") {
correctType = schema.lookupItemSync(structType, StructClass);
}
else
correctType = structType;
if (!correctType)
// eslint-disable-next-line @typescript-eslint/no-base-to-string
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidType, `The provided Struct type, ${structType}, is not a valid StructClass.`);
return correctType;
}
/**
*
* @param primitiveType
* @param schema
* @returns
*
* @internal
*/
async loadPrimitiveType(primitiveType, schema) {
if (primitiveType === undefined)
return ECObjects_1.PrimitiveType.Integer;
if (typeof (primitiveType) === "string") {
let resolvedType = (0, ECObjects_1.parsePrimitiveType)(primitiveType);
if (!resolvedType) {
resolvedType = await schema.lookupItem(primitiveType, Enumeration_1.Enumeration);
}
if (resolvedType === undefined)
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidType, `The provided primitive type, ${primitiveType}, is not a valid PrimitiveType or Enumeration.`);
// If resolvedType is a SchemaItem, make sure it is an Enumeration- if not, throw an error
if (typeof (resolvedType) !== "number" && resolvedType.schemaItemType !== ECObjects_1.SchemaItemType.Enumeration)
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidType, `The provided primitive type, ${primitiveType}, is not a valid PrimitiveType or Enumeration.`);
return resolvedType;
}
return primitiveType;
}
/**
*
* @param primitiveType
* @param schema
* @returns
*
* @internal
*/
loadPrimitiveTypeSync(primitiveType, schema) {
if (primitiveType === undefined)
return ECObjects_1.PrimitiveType.Integer;
if (typeof (primitiveType) === "string") {
let resolvedType = (0, ECObjects_1.parsePrimitiveType)(primitiveType);
if (!resolvedType) {
resolvedType = schema.lookupItemSync(primitiveType, Enumeration_1.Enumeration);
}
if (resolvedType === undefined)
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidType, `The provided primitive type, ${primitiveType}, is not a valid PrimitiveType or Enumeration.`);
return resolvedType;
}
return primitiveType;
}
/**
* Save this Classes properties to an object for serializing to JSON.
* @param standalone Serialization includes only this object (as opposed to the full schema).
* @param includeSchemaVersion Include the Schema's version information in the serialized object.
*/
toJSON(standalone = false, includeSchemaVersion = false) {
const schemaJson = super.toJSON(standalone, includeSchemaVersion);
const isMixin = ECObjects_1.SchemaItemType.Mixin === this.schemaItemType;
const isRelationship = ECObjects_1.SchemaItemType.RelationshipClass === this.schemaItemType;
if (!isMixin && (ECObjects_1.ECClassModifier.None !== this.modifier || isRelationship))
schemaJson.modifier = (0, ECObjects_1.classModifierToString)(this.modifier);
if (this.baseClass !== undefined)
schemaJson.baseClass = this.baseClass.fullName;
if (this._properties !== undefined && this._properties.size > 0)
schemaJson.properties = [...this._properties.values()].map((prop) => prop.toJSON());
const customAttributes = (0, CustomAttribute_1.serializeCustomAttributes)(this.customAttributes);
if (customAttributes !== undefined)
schemaJson.customAttributes = customAttributes;
return schemaJson;
}
/** @internal */
async toXml(schemaXml) {
const itemElement = await super.toXml(schemaXml);
if (undefined !== this.modifier)
itemElement.setAttribute("modifier", (0, ECObjects_1.classModifierToString)(this.modifier));
if (undefined !== this.baseClass) {
const baseClass = await this.baseClass;
const baseClassElement = schemaXml.createElement("BaseClass");
const baseClassName = XmlSerializationUtils_1.XmlSerializationUtils.createXmlTypedName(this.schema, baseClass.schema, baseClass.name);
baseClassElement.textContent = baseClassName;
itemElement.appendChild(baseClassElement);
}
if (this._properties) {
for (const prop of this._properties.values()) {
const propXml = await prop.toXml(schemaXml);
itemElement.appendChild(propXml);
}
}
if (this._customAttributes) {
const caContainerElement = schemaXml.createElement("ECCustomAttributes");
for (const [name, attribute] of this._customAttributes) {
const caElement = await XmlSerializationUtils_1.XmlSerializationUtils.writeCustomAttribute(name, attribute, schemaXml, this.schema);
caContainerElement.appendChild(caElement);
}
itemElement.appendChild(caContainerElement);
}
return itemElement;
}
fromJSONSync(classProps) {
super.fromJSONSync(classProps);
if (undefined !== classProps.modifier) {
const modifier = (0, ECObjects_1.parseClassModifier)(classProps.modifier);
if (undefined === modifier) {
if (Helper_1.SchemaReadHelper.isECSpecVersionNewer({ readVersion: classProps.originalECSpecMajorVersion, writeVersion: classProps.originalECSpecMinorVersion }))
this._modifier = ECObjects_1.ECClassModifier.None;
else
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidModifier, `The string '${classProps.modifier}' is not a valid ECClassModifier.`);
}
else {
this._modifier = modifier;
}
}
if (undefined !== classProps.baseClass) {
const ecClassSchemaItemKey = this.schema.getSchemaItemKey(classProps.baseClass);
if (!ecClassSchemaItemKey)
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `Unable to locate the baseClass ${classProps.baseClass}.`);
const baseClass = this.schema.lookupItemSync(ecClassSchemaItemKey);
let lazyBase;
if (!baseClass) {
lazyBase = new DelayedPromise_1.DelayedPromiseWithProps(ecClassSchemaItemKey, async () => {
const baseItem = await this.schema.lookupItem(ecClassSchemaItemKey);
if (undefined === baseItem || !ECClass.isECClass(baseItem))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `Unable to locate the baseClass ${classProps.baseClass}.`);
return baseItem;
});
}
else {
lazyBase = new DelayedPromise_1.DelayedPromiseWithProps(ecClassSchemaItemKey, async () => {
return baseClass;
});
}
this._baseClass = lazyBase;
if (!baseClass)
return;
this.addDerivedClass(baseClass, this);
}
}
async fromJSON(classProps) {
this.fromJSONSync(classProps);
}
/**
*
* @param customAttribute
*
* @internal
*/
addCustomAttribute(customAttribute) {
if (!this._customAttributes)
this._customAttributes = new Map();
this._customAttributes.set(customAttribute.className, customAttribute);
}
/**
* Iterates (recursively) over all base classes and mixins, in "property override" order.
* This is essentially a depth-first traversal through the inheritance tree.
*/
async *getAllBaseClasses() {
const baseClasses = [this];
const addBaseClasses = async (ecClass) => {
if (ECObjects_1.SchemaItemType.EntityClass === ecClass.schemaItemType) {
for (let i = ecClass.mixins.length - 1; i >= 0; i--) {
baseClasses.push(await ecClass.mixins[i]);
}
}
if (ecClass.baseClass)
baseClasses.push(await ecClass.baseClass);
};
while (baseClasses.length > 0) {
const baseClass = baseClasses.pop();
await addBaseClasses(baseClass);
if (baseClass !== this)
yield baseClass;
}
}
*getAllBaseClassesSync() {
const baseClasses = [this];
const addBaseClasses = (ecClass) => {
if (ecClass.schemaItemType === ECObjects_1.SchemaItemType.EntityClass) { // cannot use EntityClass typeguard because of circular reference
for (const m of Array.from(ecClass.getMixinsSync()).reverse()) {
baseClasses.push(m);
}
}
const baseClass = ecClass.getBaseClassSync();
if (baseClass)
baseClasses.push(baseClass);
};
while (baseClasses.length > 0) {
const baseClass = baseClasses.pop();
addBaseClasses(baseClass);
if (baseClass !== this)
yield baseClass;
}
}
/**
*
* @param cache
* @returns
*
* @internal
*/
async buildPropertyCache() {
const cache = new Map();
const baseClass = await this.baseClass;
if (baseClass) {
for (const property of await baseClass.getProperties()) {
if (!cache.has(property.name.toUpperCase())) {
cache.set(property.name.toUpperCase(), property);
}
}
}
if (this._properties) {
this._properties.forEach(property => {
cache.set(property.name.toUpperCase(), property);
});
}
return cache;
}
/**
*
* @param cache
* @returns
*
* @internal
*/
buildPropertyCacheSync() {
const cache = new Map();
const baseClass = this.getBaseClassSync();
if (baseClass) {
for (const property of baseClass.getPropertiesSync()) {
if (!cache.has(property.name.toUpperCase())) {
cache.set(property.name.toUpperCase(), property);
}
}
}
if (this._properties) {
this._properties.forEach(property => {
cache.set(property.name.toUpperCase(), property);
});
}
return cache;
}
/**
* Clears all caches on this object. This is called implicitly for this class,
* but needs to be called if derived classes have changed.
* @internal
*/
cleanCache() {
this._mergedPropertyCache = undefined;
}
/**
* Returns the properties on this class and its base classes.
* Since this is an expensive operation, results will be cached after first call.
* @param excludeInherited If true, only properties defined directly on this class will be returned. Defaults to false.
* @returns An array of properties, empty array if none exist.
*/
getPropertiesSync(excludeInherited) {
if (excludeInherited) {
return this._properties && this._properties.size > 0 ? this._properties.values() : [];
}
if (!this._mergedPropertyCache) {
this._mergedPropertyCache = this.buildPropertyCacheSync();
}
return this._mergedPropertyCache.values();
}
/**
* Quick way to check whether this class has any local properties without having to use the iterable
*/
get hasLocalProperties() {
return this._properties !== undefined && this._properties.size > 0;
}
/**
* Returns the properties on this class and its base classes.
* Since this is an expensive operation, results will be cached after first call.
* @param excludeInherited If true, only properties defined directly on this class will be returned.
* @returns An array of properties, empty array if none exist.
*/
async getProperties(excludeInherited) {
// At the moment we do not lazy load properties, so this is the same as getPropertiesSync
return this.getPropertiesSync(excludeInherited);
}
/**
* Retrieve all custom attributes in the current class and its bases
* This is the async version of getCustomAttributesSync()
*/
async getCustomAttributes() {
return this.getCustomAttributesSync();
}
/**
* Retrieve all custom attributes in the current class and its bases.
*/
getCustomAttributesSync() {
let customAttributes = this._customAttributes;
if (undefined === customAttributes) {
customAttributes = new Map();
}
this.traverseBaseClassesSync((ecClass) => {
if (undefined === ecClass.customAttributes)
return false;
for (const [className, customAttribute] of ecClass.customAttributes) {
if (customAttributes.has(className))
continue;
customAttributes.set(className, customAttribute);
}
return false;
});
return customAttributes;
}
/**
* Asynchronously traverses through the inheritance tree, using depth-first traversal, calling the given callback
* function for each base class encountered.
* @param callback The function to call for each base class in the hierarchy.
* @param arg An argument that will be passed as the second parameter to the callback function.
*/
async traverseBaseClasses(callback, arg) {
for await (const baseClass of this.getAllBaseClasses()) {
if (callback(baseClass, arg))
return true;
}
return false;
}
/**
* Synchronously traverses through the inheritance tree, using depth-first traversal, calling the given callback
* function for each base class encountered.
* @param callback The function to call for each base class in the hierarchy.
* @param arg An argument that will be passed as the second parameter to the callback function.
*/
traverseBaseClassesSync(callback, arg) {
const baseClasses = this.getAllBaseClassesSync();
if (!baseClasses)
return false;
for (const baseClass of baseClasses) {
if (callback(baseClass, arg))
return true;
}
return false;
}
async is(targetClass, schemaName) {
if (schemaName !== undefined) {
(0, core_bentley_1.assert)(typeof (targetClass) === "string", "Expected targetClass of type string because schemaName was specified");
const key = new SchemaKey_1.SchemaItemKey(targetClass, new SchemaKey_1.SchemaKey(schemaName));
if (SchemaItem_1.SchemaItem.equalByKey(this, key))
return true;
return this.traverseBaseClasses((thisSchemaItem, thatSchemaItemOrKey) => SchemaItem_1.SchemaItem.equalByKey(thisSchemaItem, thatSchemaItemOrKey), key);
}
else {
(0, core_bentley_1.assert)(ECClass.isECClass(targetClass), "Expected targetClass to be of type ECClass");
if (SchemaItem_1.SchemaItem.equalByKey(this, targetClass))
return true;
return this.traverseBaseClasses((thisSchemaItem, thatSchemaItemOrKey) => SchemaItem_1.SchemaItem.equalByKey(thisSchemaItem, thatSchemaItemOrKey), targetClass);
}
}
/** @internal */
isSync(targetClass, schemaName) {
if (schemaName !== undefined) {
(0, core_bentley_1.assert)(typeof (targetClass) === "string", "Expected targetClass of type string because schemaName was specified");
const key = new SchemaKey_1.SchemaItemKey(targetClass, new SchemaKey_1.SchemaKey(schemaName));
if (SchemaItem_1.SchemaItem.equalByKey(this, key))
return true;
return this.traverseBaseClassesSync((thisSchemaItem, thatSchemaItemOrKey) => SchemaItem_1.SchemaItem.equalByKey(thisSchemaItem, thatSchemaItemOrKey), key);
}
else {
(0, core_bentley_1.assert)(ECClass.isECClass(targetClass), "Expected targetClass to be of type ECClass");
if (SchemaItem_1.SchemaItem.equalByKey(this, targetClass))
return true;
return this.traverseBaseClassesSync((thisSchemaItem, thatSchemaItemOrKey) => SchemaItem_1.SchemaItem.equalByKey(thisSchemaItem, thatSchemaItemOrKey), targetClass);
}
}
/**
* @internal
*/
static isECClass(object) {
if (!SchemaItem_1.SchemaItem.isSchemaItem(object))
return false;
return object.schemaItemType === ECObjects_1.SchemaItemType.EntityClass || object.schemaItemType === ECObjects_1.SchemaItemType.Mixin || object.schemaItemType === ECObjects_1.SchemaItemType.RelationshipClass ||
object.schemaItemType === ECObjects_1.SchemaItemType.StructClass || object.schemaItemType === ECObjects_1.SchemaItemType.CustomAttributeClass;
}
/**
* A setter method for the ECClass modifier, used specifically for schema editing.
* @param modifier
* @internal
*/
setModifier(modifier) {
this._modifier = modifier;
}
/**
* Adds an ECClass to the derived class collection. This method is only intended to update the local
* cache of derived classes. For adding a class to the hierarchy, use the baseClass setter method.
* @param prop The property to add.
* @return The property that was added.
*/
addDerivedClass(baseClass, derivedClass) {
if (!baseClass._derivedClasses)
baseClass._derivedClasses = new Map();
if (baseClass._derivedClasses.has(derivedClass.fullName))
return;
if (derivedClass.isSync(baseClass)) {
const promise = new DelayedPromise_1.DelayedPromiseWithProps(derivedClass.key, async () => derivedClass);
baseClass._derivedClasses.set(derivedClass.fullName, promise);
}
}
/**
* Removes an ECClass from the derived class collection. This method is only intended to update the local
* cache of derived classes. For updating the class hierarchy, use the baseClass setter method.
* @param prop The property to add.
* @return The property that was added.
*/
removeDerivedClass(baseClass, derivedClass) {
if (!baseClass._derivedClasses)
return;
if (!baseClass._derivedClasses.has(derivedClass.fullName))
return;
baseClass._derivedClasses.delete(derivedClass.fullName);
}
}
exports.ECClass = ECClass;
/**
* A Typescript class representation of an ECStructClass.
* @public @preview
*/
class StructClass extends ECClass {
/**
* Get the type of item represented by this instance
*/
schemaItemType = StructClass.schemaItemType;
/**
* Get the type of item represented by this class
* @internal
*/
static get schemaItemType() { return ECObjects_1.SchemaItemType.StructClass; }
/**
* Type guard to check if the SchemaItem is of type StructClass.
* @param item The SchemaItem to check.
* @returns True if the item is a StructClass, false otherwise.
*/
static isStructClass(item) {
if (item && item.schemaItemType === ECObjects_1.SchemaItemType.StructClass)
return true;
return false;
}
/**
* Type assertion to check if the SchemaItem is of type StructClass.
* @param item The SchemaItem to check.
* @returns The item cast to StructClass if it is a StructClass, undefined otherwise.
* @internal
*/
static assertIsStructClass(item) {
if (!this.isStructClass(item))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidSchemaItemType, `Expected '${ECObjects_1.SchemaItemType.StructClass}' (StructClass)`);
}
}
exports.StructClass = StructClass;
/**
* @internal
* An abstract class used for schema editing.
*/
class MutableStructClass extends StructClass {
}
exports.MutableStructClass = MutableStructClass;
/**
* Hackish approach that works like a "friend class" so we can access protected members without making them public.
* @internal
*/
class MutableClass extends ECClass {
}
exports.MutableClass = MutableClass;
//# sourceMappingURL=Class.js.map