@itwin/ecschema-metadata 4.8.0-dev.9 → 4.9.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/lib/cjs/Constants.js.map +1 -1
  3. package/lib/cjs/DelayedPromise.js.map +1 -1
  4. package/lib/cjs/Deserialization/AbstractParser.js.map +1 -1
  5. package/lib/cjs/Deserialization/Helper.js.map +1 -1
  6. package/lib/cjs/Deserialization/JsonParser.js.map +1 -1
  7. package/lib/cjs/Deserialization/JsonProps.d.ts +4 -0
  8. package/lib/cjs/Deserialization/JsonProps.d.ts.map +1 -1
  9. package/lib/cjs/Deserialization/JsonProps.js.map +1 -1
  10. package/lib/cjs/Deserialization/SchemaGraphUtil.js.map +1 -1
  11. package/lib/cjs/Deserialization/XmlParser.js.map +1 -1
  12. package/lib/cjs/Deserialization/XmlSerializationUtils.js.map +1 -1
  13. package/lib/cjs/ECName.js.map +1 -1
  14. package/lib/cjs/ECObjects.js.map +1 -1
  15. package/lib/cjs/Exception.js.map +1 -1
  16. package/lib/cjs/Interfaces.js.map +1 -1
  17. package/lib/cjs/Metadata/Class.d.ts +0 -6
  18. package/lib/cjs/Metadata/Class.d.ts.map +1 -1
  19. package/lib/cjs/Metadata/Class.js +0 -8
  20. package/lib/cjs/Metadata/Class.js.map +1 -1
  21. package/lib/cjs/Metadata/Constant.js.map +1 -1
  22. package/lib/cjs/Metadata/CustomAttribute.js.map +1 -1
  23. package/lib/cjs/Metadata/CustomAttributeClass.d.ts +7 -3
  24. package/lib/cjs/Metadata/CustomAttributeClass.d.ts.map +1 -1
  25. package/lib/cjs/Metadata/CustomAttributeClass.js +16 -10
  26. package/lib/cjs/Metadata/CustomAttributeClass.js.map +1 -1
  27. package/lib/cjs/Metadata/EntityClass.js.map +1 -1
  28. package/lib/cjs/Metadata/Enumeration.js.map +1 -1
  29. package/lib/cjs/Metadata/Format.js.map +1 -1
  30. package/lib/cjs/Metadata/InvertedUnit.js.map +1 -1
  31. package/lib/cjs/Metadata/KindOfQuantity.js.map +1 -1
  32. package/lib/cjs/Metadata/Mixin.js.map +1 -1
  33. package/lib/cjs/Metadata/OverrideFormat.d.ts.map +1 -1
  34. package/lib/cjs/Metadata/OverrideFormat.js +3 -1
  35. package/lib/cjs/Metadata/OverrideFormat.js.map +1 -1
  36. package/lib/cjs/Metadata/Phenomenon.js.map +1 -1
  37. package/lib/cjs/Metadata/Property.js.map +1 -1
  38. package/lib/cjs/Metadata/PropertyCategory.js.map +1 -1
  39. package/lib/cjs/Metadata/RelationshipClass.js.map +1 -1
  40. package/lib/cjs/Metadata/Schema.d.ts +14 -0
  41. package/lib/cjs/Metadata/Schema.d.ts.map +1 -1
  42. package/lib/cjs/Metadata/Schema.js +21 -0
  43. package/lib/cjs/Metadata/Schema.js.map +1 -1
  44. package/lib/cjs/Metadata/SchemaItem.d.ts +5 -0
  45. package/lib/cjs/Metadata/SchemaItem.d.ts.map +1 -1
  46. package/lib/cjs/Metadata/SchemaItem.js +7 -0
  47. package/lib/cjs/Metadata/SchemaItem.js.map +1 -1
  48. package/lib/cjs/Metadata/UnitSystem.js.map +1 -1
  49. package/lib/cjs/PropertyTypes.js.map +1 -1
  50. package/lib/cjs/SchemaJsonLocater.js.map +1 -1
  51. package/lib/cjs/SchemaKey.js.map +1 -1
  52. package/lib/cjs/SchemaLoader.js.map +1 -1
  53. package/lib/cjs/SchemaPartVisitorDelegate.js.map +1 -1
  54. package/lib/cjs/UnitConversion/Graph.js.map +1 -1
  55. package/lib/cjs/UnitConversion/Parser.js.map +1 -1
  56. package/lib/cjs/UnitConversion/UnitConversion.js.map +1 -1
  57. package/lib/cjs/UnitConversion/UnitConverter.js.map +1 -1
  58. package/lib/cjs/UnitConversion/UnitTree.js.map +1 -1
  59. package/lib/cjs/UnitProvider/SchemaUnitProvider.js.map +1 -1
  60. package/lib/cjs/Validation/SchemaWalker.js.map +1 -1
  61. package/lib/cjs/ecschema-metadata.js.map +1 -1
  62. package/lib/cjs/utils/SchemaGraph.js.map +1 -1
  63. package/lib/esm/Constants.d.ts +24 -0
  64. package/lib/esm/Constants.d.ts.map +1 -0
  65. package/lib/esm/Constants.js +30 -0
  66. package/lib/esm/Constants.js.map +1 -0
  67. package/lib/esm/Context.d.ts +219 -0
  68. package/lib/esm/Context.d.ts.map +1 -0
  69. package/lib/esm/Context.js +321 -0
  70. package/lib/esm/Context.js.map +1 -0
  71. package/lib/esm/DelayedPromise.d.ts +89 -0
  72. package/lib/esm/DelayedPromise.d.ts.map +1 -0
  73. package/lib/esm/DelayedPromise.js +88 -0
  74. package/lib/esm/DelayedPromise.js.map +1 -0
  75. package/lib/esm/Deserialization/AbstractParser.d.ts +46 -0
  76. package/lib/esm/Deserialization/AbstractParser.d.ts.map +1 -0
  77. package/lib/esm/Deserialization/AbstractParser.js +8 -0
  78. package/lib/esm/Deserialization/AbstractParser.js.map +1 -0
  79. package/lib/esm/Deserialization/Helper.d.ts +263 -0
  80. package/lib/esm/Deserialization/Helper.d.ts.map +1 -0
  81. package/lib/esm/Deserialization/Helper.js +871 -0
  82. package/lib/esm/Deserialization/Helper.js.map +1 -0
  83. package/lib/esm/Deserialization/JsonParser.d.ts +166 -0
  84. package/lib/esm/Deserialization/JsonParser.d.ts.map +1 -0
  85. package/lib/esm/Deserialization/JsonParser.js +677 -0
  86. package/lib/esm/Deserialization/JsonParser.js.map +1 -0
  87. package/lib/esm/Deserialization/JsonProps.d.ts +273 -0
  88. package/lib/esm/Deserialization/JsonProps.d.ts.map +1 -0
  89. package/lib/esm/Deserialization/JsonProps.js +9 -0
  90. package/lib/esm/Deserialization/JsonProps.js.map +1 -0
  91. package/lib/esm/Deserialization/SchemaGraphUtil.d.ts +35 -0
  92. package/lib/esm/Deserialization/SchemaGraphUtil.d.ts.map +1 -0
  93. package/lib/esm/Deserialization/SchemaGraphUtil.js +74 -0
  94. package/lib/esm/Deserialization/SchemaGraphUtil.js.map +1 -0
  95. package/lib/esm/Deserialization/XmlParser.d.ts +86 -0
  96. package/lib/esm/Deserialization/XmlParser.d.ts.map +1 -0
  97. package/lib/esm/Deserialization/XmlParser.js +970 -0
  98. package/lib/esm/Deserialization/XmlParser.js.map +1 -0
  99. package/lib/esm/Deserialization/XmlSerializationUtils.d.ts +55 -0
  100. package/lib/esm/Deserialization/XmlSerializationUtils.d.ts.map +1 -0
  101. package/lib/esm/Deserialization/XmlSerializationUtils.js +172 -0
  102. package/lib/esm/Deserialization/XmlSerializationUtils.js.map +1 -0
  103. package/lib/esm/ECName.d.ts +31 -0
  104. package/lib/esm/ECName.d.ts.map +1 -0
  105. package/lib/esm/ECName.js +82 -0
  106. package/lib/esm/ECName.js.map +1 -0
  107. package/lib/esm/ECObjects.d.ts +166 -0
  108. package/lib/esm/ECObjects.d.ts.map +1 -0
  109. package/lib/esm/ECObjects.js +422 -0
  110. package/lib/esm/ECObjects.js.map +1 -0
  111. package/lib/esm/Exception.d.ts +45 -0
  112. package/lib/esm/Exception.d.ts.map +1 -0
  113. package/lib/esm/Exception.js +82 -0
  114. package/lib/esm/Exception.js.map +1 -0
  115. package/lib/esm/Interfaces.d.ts +79 -0
  116. package/lib/esm/Interfaces.d.ts.map +1 -0
  117. package/lib/esm/Interfaces.js +9 -0
  118. package/lib/esm/Interfaces.js.map +1 -0
  119. package/lib/esm/Metadata/Class.d.ts +245 -0
  120. package/lib/esm/Metadata/Class.d.ts.map +1 -0
  121. package/lib/esm/Metadata/Class.js +552 -0
  122. package/lib/esm/Metadata/Class.js.map +1 -0
  123. package/lib/esm/Metadata/Constant.d.ts +65 -0
  124. package/lib/esm/Metadata/Constant.d.ts.map +1 -0
  125. package/lib/esm/Metadata/Constant.js +119 -0
  126. package/lib/esm/Metadata/Constant.js.map +1 -0
  127. package/lib/esm/Metadata/CustomAttribute.d.ts +24 -0
  128. package/lib/esm/Metadata/CustomAttribute.d.ts.map +1 -0
  129. package/lib/esm/Metadata/CustomAttribute.js +24 -0
  130. package/lib/esm/Metadata/CustomAttribute.js.map +1 -0
  131. package/lib/esm/Metadata/CustomAttributeClass.d.ts +44 -0
  132. package/lib/esm/Metadata/CustomAttributeClass.d.ts.map +1 -0
  133. package/lib/esm/Metadata/CustomAttributeClass.js +70 -0
  134. package/lib/esm/Metadata/CustomAttributeClass.js.map +1 -0
  135. package/lib/esm/Metadata/EntityClass.d.ts +78 -0
  136. package/lib/esm/Metadata/EntityClass.d.ts.map +1 -0
  137. package/lib/esm/Metadata/EntityClass.js +224 -0
  138. package/lib/esm/Metadata/EntityClass.js.map +1 -0
  139. package/lib/esm/Metadata/Enumeration.d.ts +87 -0
  140. package/lib/esm/Metadata/Enumeration.d.ts.map +1 -0
  141. package/lib/esm/Metadata/Enumeration.js +155 -0
  142. package/lib/esm/Metadata/Enumeration.js.map +1 -0
  143. package/lib/esm/Metadata/Format.d.ts +99 -0
  144. package/lib/esm/Metadata/Format.d.ts.map +1 -0
  145. package/lib/esm/Metadata/Format.js +238 -0
  146. package/lib/esm/Metadata/Format.js.map +1 -0
  147. package/lib/esm/Metadata/InvertedUnit.d.ts +50 -0
  148. package/lib/esm/Metadata/InvertedUnit.d.ts.map +1 -0
  149. package/lib/esm/Metadata/InvertedUnit.js +93 -0
  150. package/lib/esm/Metadata/InvertedUnit.js.map +1 -0
  151. package/lib/esm/Metadata/KindOfQuantity.d.ts +72 -0
  152. package/lib/esm/Metadata/KindOfQuantity.d.ts.map +1 -0
  153. package/lib/esm/Metadata/KindOfQuantity.js +229 -0
  154. package/lib/esm/Metadata/KindOfQuantity.js.map +1 -0
  155. package/lib/esm/Metadata/Mixin.d.ts +55 -0
  156. package/lib/esm/Metadata/Mixin.d.ts.map +1 -0
  157. package/lib/esm/Metadata/Mixin.js +109 -0
  158. package/lib/esm/Metadata/Mixin.js.map +1 -0
  159. package/lib/esm/Metadata/OverrideFormat.d.ts +68 -0
  160. package/lib/esm/Metadata/OverrideFormat.d.ts.map +1 -0
  161. package/lib/esm/Metadata/OverrideFormat.js +124 -0
  162. package/lib/esm/Metadata/OverrideFormat.js.map +1 -0
  163. package/lib/esm/Metadata/Phenomenon.d.ts +34 -0
  164. package/lib/esm/Metadata/Phenomenon.d.ts.map +1 -0
  165. package/lib/esm/Metadata/Phenomenon.js +55 -0
  166. package/lib/esm/Metadata/Phenomenon.js.map +1 -0
  167. package/lib/esm/Metadata/Property.d.ts +247 -0
  168. package/lib/esm/Metadata/Property.d.ts.map +1 -0
  169. package/lib/esm/Metadata/Property.js +565 -0
  170. package/lib/esm/Metadata/Property.js.map +1 -0
  171. package/lib/esm/Metadata/PropertyCategory.d.ts +40 -0
  172. package/lib/esm/Metadata/PropertyCategory.d.ts.map +1 -0
  173. package/lib/esm/Metadata/PropertyCategory.js +57 -0
  174. package/lib/esm/Metadata/PropertyCategory.js.map +1 -0
  175. package/lib/esm/Metadata/RelationshipClass.d.ts +170 -0
  176. package/lib/esm/Metadata/RelationshipClass.d.ts.map +1 -0
  177. package/lib/esm/Metadata/RelationshipClass.js +380 -0
  178. package/lib/esm/Metadata/RelationshipClass.js.map +1 -0
  179. package/lib/esm/Metadata/Schema.d.ts +330 -0
  180. package/lib/esm/Metadata/Schema.d.ts.map +1 -0
  181. package/lib/esm/Metadata/Schema.js +570 -0
  182. package/lib/esm/Metadata/Schema.js.map +1 -0
  183. package/lib/esm/Metadata/SchemaItem.d.ts +67 -0
  184. package/lib/esm/Metadata/SchemaItem.d.ts.map +1 -0
  185. package/lib/esm/Metadata/SchemaItem.js +140 -0
  186. package/lib/esm/Metadata/SchemaItem.js.map +1 -0
  187. package/lib/esm/Metadata/Unit.d.ts +77 -0
  188. package/lib/esm/Metadata/Unit.d.ts.map +1 -0
  189. package/lib/esm/Metadata/Unit.js +158 -0
  190. package/lib/esm/Metadata/Unit.js.map +1 -0
  191. package/lib/esm/Metadata/UnitSystem.d.ts +21 -0
  192. package/lib/esm/Metadata/UnitSystem.d.ts.map +1 -0
  193. package/lib/esm/Metadata/UnitSystem.js +25 -0
  194. package/lib/esm/Metadata/UnitSystem.js.map +1 -0
  195. package/lib/esm/PropertyTypes.d.ts +50 -0
  196. package/lib/esm/PropertyTypes.d.ts.map +1 -0
  197. package/lib/esm/PropertyTypes.js +88 -0
  198. package/lib/esm/PropertyTypes.js.map +1 -0
  199. package/lib/esm/SchemaJsonLocater.d.ts +42 -0
  200. package/lib/esm/SchemaJsonLocater.d.ts.map +1 -0
  201. package/lib/esm/SchemaJsonLocater.js +54 -0
  202. package/lib/esm/SchemaJsonLocater.js.map +1 -0
  203. package/lib/esm/SchemaKey.d.ts +111 -0
  204. package/lib/esm/SchemaKey.d.ts.map +1 -0
  205. package/lib/esm/SchemaKey.js +214 -0
  206. package/lib/esm/SchemaKey.js.map +1 -0
  207. package/lib/esm/SchemaLoader.d.ts +32 -0
  208. package/lib/esm/SchemaLoader.d.ts.map +1 -0
  209. package/lib/esm/SchemaLoader.js +53 -0
  210. package/lib/esm/SchemaLoader.js.map +1 -0
  211. package/lib/esm/SchemaPartVisitorDelegate.d.ts +275 -0
  212. package/lib/esm/SchemaPartVisitorDelegate.d.ts.map +1 -0
  213. package/lib/esm/SchemaPartVisitorDelegate.js +209 -0
  214. package/lib/esm/SchemaPartVisitorDelegate.js.map +1 -0
  215. package/lib/esm/UnitConversion/Graph.d.ts +35 -0
  216. package/lib/esm/UnitConversion/Graph.d.ts.map +1 -0
  217. package/lib/esm/UnitConversion/Graph.js +80 -0
  218. package/lib/esm/UnitConversion/Graph.js.map +1 -0
  219. package/lib/esm/UnitConversion/Parser.d.ts +9 -0
  220. package/lib/esm/UnitConversion/Parser.d.ts.map +1 -0
  221. package/lib/esm/UnitConversion/Parser.js +39 -0
  222. package/lib/esm/UnitConversion/Parser.js.map +1 -0
  223. package/lib/esm/UnitConversion/UnitConversion.d.ts +46 -0
  224. package/lib/esm/UnitConversion/UnitConversion.d.ts.map +1 -0
  225. package/lib/esm/UnitConversion/UnitConversion.js +74 -0
  226. package/lib/esm/UnitConversion/UnitConversion.js.map +1 -0
  227. package/lib/esm/UnitConversion/UnitConverter.d.ts +40 -0
  228. package/lib/esm/UnitConversion/UnitConverter.d.ts.map +1 -0
  229. package/lib/esm/UnitConversion/UnitConverter.js +113 -0
  230. package/lib/esm/UnitConversion/UnitConverter.js.map +1 -0
  231. package/lib/esm/UnitConversion/UnitTree.d.ts +44 -0
  232. package/lib/esm/UnitConversion/UnitTree.d.ts.map +1 -0
  233. package/lib/esm/UnitConversion/UnitTree.js +165 -0
  234. package/lib/esm/UnitConversion/UnitTree.js.map +1 -0
  235. package/lib/esm/UnitProvider/SchemaUnitProvider.d.ts +78 -0
  236. package/lib/esm/UnitProvider/SchemaUnitProvider.d.ts.map +1 -0
  237. package/lib/esm/UnitProvider/SchemaUnitProvider.js +231 -0
  238. package/lib/esm/UnitProvider/SchemaUnitProvider.js.map +1 -0
  239. package/lib/esm/Validation/SchemaWalker.d.ts +24 -0
  240. package/lib/esm/Validation/SchemaWalker.d.ts.map +1 -0
  241. package/lib/esm/Validation/SchemaWalker.js +50 -0
  242. package/lib/esm/Validation/SchemaWalker.js.map +1 -0
  243. package/lib/esm/ecschema-metadata.d.ts +52 -0
  244. package/lib/esm/ecschema-metadata.d.ts.map +1 -0
  245. package/lib/esm/ecschema-metadata.js +55 -0
  246. package/lib/esm/ecschema-metadata.js.map +1 -0
  247. package/lib/esm/utils/SchemaGraph.d.ts +44 -0
  248. package/lib/esm/utils/SchemaGraph.d.ts.map +1 -0
  249. package/lib/esm/utils/SchemaGraph.js +111 -0
  250. package/lib/esm/utils/SchemaGraph.js.map +1 -0
  251. package/package.json +9 -7
@@ -0,0 +1,871 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { SchemaContext } from "../Context";
6
+ import { parsePrimitiveType, parseSchemaItemType, SchemaItemType, SchemaMatchType } from "../ECObjects";
7
+ import { ECObjectsError, ECObjectsStatus } from "../Exception";
8
+ import { SchemaItem } from "../Metadata/SchemaItem";
9
+ import { ECVersion, SchemaItemKey, SchemaKey } from "../SchemaKey";
10
+ import { SchemaPartVisitorDelegate } from "../SchemaPartVisitorDelegate";
11
+ import { getItemNamesFromFormatString } from "@itwin/core-quantity";
12
+ import { SchemaGraph } from "../utils/SchemaGraph";
13
+ /**
14
+ * This class properly handles the order the deserialization of ECSchemas and SchemaItems from serialized formats.
15
+ * For example, when deserializing an ECClass most times all base class should be de-serialized before the given class.
16
+ * @internal
17
+ */
18
+ export class SchemaReadHelper {
19
+ constructor(parserType, context, visitor) {
20
+ this._context = (undefined !== context) ? context : new SchemaContext();
21
+ this._visitorHelper = visitor ? new SchemaPartVisitorDelegate(visitor) : undefined;
22
+ this._parserType = parserType;
23
+ }
24
+ /**
25
+ * Creates a complete SchemaInfo and starts parsing the schema from a serialized representation.
26
+ * The info and schema promise will be registered with the SchemaContext. The complete schema can be retrieved by
27
+ * calling getCachedSchema on the context.
28
+ * @param schema The Schema to populate
29
+ * @param rawSchema The serialized data to use to populate the Schema.
30
+ */
31
+ async readSchemaInfo(schema, rawSchema) {
32
+ // Ensure context matches schema context
33
+ if (schema.context) {
34
+ if (this._context !== schema.context)
35
+ throw new ECObjectsError(ECObjectsStatus.DifferentSchemaContexts, "The SchemaContext of the schema must be the same SchemaContext held by the SchemaReadHelper.");
36
+ }
37
+ else {
38
+ schema.setContext(this._context);
39
+ }
40
+ this._parser = new this._parserType(rawSchema);
41
+ // Loads all of the properties on the Schema object
42
+ await schema.fromJSON(this._parser.parseSchema());
43
+ this._schema = schema;
44
+ const schemaInfo = { schemaKey: schema.schemaKey, references: [] };
45
+ for (const reference of this._parser.getReferences()) {
46
+ const refKey = new SchemaKey(reference.name, ECVersion.fromString(reference.version));
47
+ schemaInfo.references.push({ schemaKey: refKey });
48
+ }
49
+ this._schemaInfo = schemaInfo;
50
+ // Need to add this schema to the context to be able to locate schemaItems within the context.
51
+ if (!this._context.schemaExists(schema.schemaKey)) {
52
+ await this._context.addSchemaPromise(schemaInfo, schema, this.loadSchema(schemaInfo, schema));
53
+ }
54
+ return schemaInfo;
55
+ }
56
+ /**
57
+ * Populates the given Schema from a serialized representation.
58
+ * @param schema The Schema to populate
59
+ * @param rawSchema The serialized data to use to populate the Schema.
60
+ */
61
+ async readSchema(schema, rawSchema) {
62
+ if (!this._schemaInfo) {
63
+ await this.readSchemaInfo(schema, rawSchema);
64
+ }
65
+ const cachedSchema = await this._context.getCachedSchema(this._schemaInfo.schemaKey, SchemaMatchType.Latest);
66
+ if (undefined === cachedSchema)
67
+ throw new ECObjectsError(ECObjectsStatus.UnableToLoadSchema, `Could not load schema ${schema.schemaKey.toString()}`);
68
+ return cachedSchema;
69
+ }
70
+ /* Finish loading the rest of the schema */
71
+ async loadSchema(schemaInfo, schema) {
72
+ // Verify that there are no schema reference cycles, this will start schema loading by loading their headers
73
+ (await SchemaGraph.generateGraph(schemaInfo, this._context)).throwIfCycles();
74
+ for (const reference of schemaInfo.references) {
75
+ await this.loadSchemaReference(schemaInfo, reference.schemaKey);
76
+ }
77
+ if (this._visitorHelper)
78
+ await this._visitorHelper.visitSchema(schema, false);
79
+ // Load all schema items
80
+ for (const [itemName, itemType, rawItem] of this._parser.getItems()) {
81
+ // Make sure the item has not already been read. No need to check the SchemaContext because all SchemaItems are added to a Schema,
82
+ // which would be found when adding to the context.
83
+ if (await schema.getItem(itemName) !== undefined)
84
+ continue;
85
+ const loadedItem = await this.loadSchemaItem(schema, itemName, itemType, rawItem);
86
+ if (loadedItem && this._visitorHelper) {
87
+ await this._visitorHelper.visitSchemaPart(loadedItem);
88
+ }
89
+ }
90
+ await this.loadCustomAttributes(schema, this._parser.getSchemaCustomAttributeProviders());
91
+ if (this._visitorHelper)
92
+ await this._visitorHelper.visitSchema(schema);
93
+ return schema;
94
+ }
95
+ /**
96
+ * Populates the given Schema from a serialized representation.
97
+ * @param schema The Schema to populate
98
+ * @param rawSchema The serialized data to use to populate the Schema.
99
+ */
100
+ readSchemaSync(schema, rawSchema) {
101
+ this._parser = new this._parserType(rawSchema);
102
+ // Loads all of the properties on the Schema object
103
+ schema.fromJSONSync(this._parser.parseSchema());
104
+ this._schema = schema;
105
+ // Need to add this schema to the context to be able to locate schemaItems within the context.
106
+ if (!this._context.schemaExists(schema.schemaKey))
107
+ this._context.addSchemaSync(schema);
108
+ // Load schema references first
109
+ // Need to figure out if other schemas are present.
110
+ for (const reference of this._parser.getReferences()) {
111
+ this.loadSchemaReferenceSync(reference);
112
+ }
113
+ if (this._visitorHelper)
114
+ this._visitorHelper.visitSchemaSync(schema, false);
115
+ // Load all schema items
116
+ for (const [itemName, itemType, rawItem] of this._parser.getItems()) {
117
+ // Make sure the item has not already been read. No need to check the SchemaContext because all SchemaItems are added to a Schema,
118
+ // which would be found when adding to the context.
119
+ if (schema.getItemSync(itemName) !== undefined)
120
+ continue;
121
+ const loadedItem = this.loadSchemaItemSync(schema, itemName, itemType, rawItem);
122
+ if (loadedItem && this._visitorHelper) {
123
+ this._visitorHelper.visitSchemaPartSync(loadedItem);
124
+ }
125
+ }
126
+ this.loadCustomAttributesSync(schema, this._parser.getSchemaCustomAttributeProviders());
127
+ if (this._visitorHelper)
128
+ this._visitorHelper.visitSchemaSync(schema);
129
+ return schema;
130
+ }
131
+ /**
132
+ * Ensures that the schema references can be located and adds them to the schema.
133
+ * @param ref The object to read the SchemaReference's props from.
134
+ */
135
+ async loadSchemaReference(schemaInfo, refKey) {
136
+ const refSchema = await this._context.getSchema(refKey, SchemaMatchType.LatestWriteCompatible);
137
+ if (undefined === refSchema)
138
+ throw new ECObjectsError(ECObjectsStatus.UnableToLocateSchema, `Could not locate the referenced schema, ${refKey.name}.${refKey.version.toString()}, of ${schemaInfo.schemaKey.name}`);
139
+ await this._schema.addReference(refSchema);
140
+ const results = this.validateSchemaReferences(this._schema);
141
+ let errorMessage = "";
142
+ for (const result of results) {
143
+ errorMessage += `${result}\r\n`;
144
+ }
145
+ if (errorMessage) {
146
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `${errorMessage}`);
147
+ }
148
+ }
149
+ /**
150
+ * Ensures that the schema references can be located and adds them to the schema.
151
+ * @param ref The object to read the SchemaReference's props from.
152
+ */
153
+ loadSchemaReferenceSync(ref) {
154
+ const schemaKey = new SchemaKey(ref.name, ECVersion.fromString(ref.version));
155
+ const refSchema = this._context.getSchemaSync(schemaKey, SchemaMatchType.LatestWriteCompatible);
156
+ if (!refSchema)
157
+ throw new ECObjectsError(ECObjectsStatus.UnableToLocateSchema, `Could not locate the referenced schema, ${ref.name}.${ref.version}, of ${this._schema.schemaKey.name}`);
158
+ this._schema.addReferenceSync(refSchema);
159
+ SchemaGraph.generateGraphSync(this._schema).throwIfCycles();
160
+ const results = this.validateSchemaReferences(this._schema);
161
+ let errorMessage = "";
162
+ for (const result of results) {
163
+ errorMessage += `${result}\r\n`;
164
+ }
165
+ if (errorMessage) {
166
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `${errorMessage}`);
167
+ }
168
+ }
169
+ /**
170
+ * Validates schema references against multiple EC rules.
171
+ * @param schema The schema to validate.
172
+ */
173
+ *validateSchemaReferences(schema) {
174
+ const aliases = new Map();
175
+ for (const schemaRef of schema.references) {
176
+ if (schemaRef.customAttributes && schemaRef.customAttributes.has("CoreCustomAttributes.SupplementalSchema"))
177
+ yield `Referenced schema '${schemaRef.name}' of schema '${schema.name}' is a supplemental schema. Supplemental schemas are not allowed to be referenced.`;
178
+ if (schema.schemaKey.matches(schemaRef.schemaKey))
179
+ yield `Schema '${schema.name}' has reference cycles: '${schema.name} --> ${schemaRef.name}'`;
180
+ if (aliases.has(schemaRef.alias)) {
181
+ const currentRef = aliases.get(schemaRef.alias);
182
+ yield `Schema '${schema.name}' has multiple schema references (${currentRef.name}, $schemaRef.name}) with the same alias '${schemaRef.alias}', which is not allowed.`;
183
+ }
184
+ else {
185
+ aliases.set(schemaRef.alias, schemaRef);
186
+ }
187
+ }
188
+ }
189
+ /**
190
+ * Given the schema item object, the anticipated type and the name a schema item is created and loaded into the schema provided.
191
+ * @param schema The Schema the SchemaItem to.
192
+ * @param name The name of the schema item to be loaded.
193
+ * @param itemType The SchemaItemType of the item to load.
194
+ * @param schemaItemObject The Object to populate the SchemaItem with.
195
+ */
196
+ async loadSchemaItem(schema, name, itemType, schemaItemObject) {
197
+ let schemaItem;
198
+ switch (parseSchemaItemType(itemType)) {
199
+ case SchemaItemType.EntityClass:
200
+ schemaItem = await schema.createEntityClass(name);
201
+ await this.loadEntityClass(schemaItem, schemaItemObject);
202
+ break;
203
+ case SchemaItemType.StructClass:
204
+ schemaItem = await schema.createStructClass(name);
205
+ const structProps = this._parser.parseStructClass(schemaItemObject);
206
+ await this.loadClass(schemaItem, structProps, schemaItemObject);
207
+ break;
208
+ case SchemaItemType.Mixin:
209
+ schemaItem = await schema.createMixinClass(name);
210
+ await this.loadMixin(schemaItem, schemaItemObject);
211
+ break;
212
+ case SchemaItemType.CustomAttributeClass:
213
+ schemaItem = await schema.createCustomAttributeClass(name);
214
+ const caClassProps = this._parser.parseCustomAttributeClass(schemaItemObject);
215
+ await this.loadClass(schemaItem, caClassProps, schemaItemObject);
216
+ break;
217
+ case SchemaItemType.RelationshipClass:
218
+ schemaItem = await schema.createRelationshipClass(name);
219
+ await this.loadRelationshipClass(schemaItem, schemaItemObject);
220
+ break;
221
+ case SchemaItemType.KindOfQuantity:
222
+ schemaItem = await schema.createKindOfQuantity(name);
223
+ await this.loadKindOfQuantity(schemaItem, schemaItemObject);
224
+ break;
225
+ case SchemaItemType.Unit:
226
+ schemaItem = await schema.createUnit(name);
227
+ await this.loadUnit(schemaItem, schemaItemObject);
228
+ break;
229
+ case SchemaItemType.Constant:
230
+ schemaItem = await schema.createConstant(name);
231
+ await this.loadConstant(schemaItem, schemaItemObject);
232
+ break;
233
+ case SchemaItemType.InvertedUnit:
234
+ schemaItem = await schema.createInvertedUnit(name);
235
+ await this.loadInvertedUnit(schemaItem, schemaItemObject);
236
+ break;
237
+ case SchemaItemType.Format:
238
+ schemaItem = await schema.createFormat(name);
239
+ await this.loadFormat(schemaItem, schemaItemObject);
240
+ break;
241
+ case SchemaItemType.Phenomenon:
242
+ schemaItem = await schema.createPhenomenon(name);
243
+ const phenomenonProps = this._parser.parsePhenomenon(schemaItemObject);
244
+ await schemaItem.fromJSON(phenomenonProps);
245
+ break;
246
+ case SchemaItemType.UnitSystem:
247
+ schemaItem = await schema.createUnitSystem(name);
248
+ await schemaItem.fromJSON(this._parser.parseUnitSystem(schemaItemObject));
249
+ break;
250
+ case SchemaItemType.PropertyCategory:
251
+ schemaItem = await schema.createPropertyCategory(name);
252
+ const propertyCategoryProps = this._parser.parsePropertyCategory(schemaItemObject);
253
+ await schemaItem.fromJSON(propertyCategoryProps);
254
+ break;
255
+ case SchemaItemType.Enumeration:
256
+ schemaItem = await schema.createEnumeration(name);
257
+ const enumerationProps = this._parser.parseEnumeration(schemaItemObject);
258
+ await schemaItem.fromJSON(enumerationProps);
259
+ break;
260
+ // NOTE: we are being permissive here and allowing unknown types to silently fail. Not sure if we want to hard fail or just do a basic deserialization
261
+ }
262
+ return schemaItem;
263
+ }
264
+ /**
265
+ * Given the schema item object, the anticipated type and the name a schema item is created and loaded into the schema provided.
266
+ * @param schema The Schema the SchemaItem to.
267
+ * @param name The name of the schema item to be loaded.
268
+ * @param itemType The SchemaItemType of the item to load.
269
+ * @param schemaItemObject The Object to populate the SchemaItem with.
270
+ */
271
+ loadSchemaItemSync(schema, name, itemType, schemaItemObject) {
272
+ let schemaItem;
273
+ switch (parseSchemaItemType(itemType)) {
274
+ case SchemaItemType.EntityClass:
275
+ schemaItem = schema.createEntityClassSync(name);
276
+ this.loadEntityClassSync(schemaItem, schemaItemObject);
277
+ break;
278
+ case SchemaItemType.StructClass:
279
+ schemaItem = schema.createStructClassSync(name);
280
+ const structProps = this._parser.parseStructClass(schemaItemObject);
281
+ this.loadClassSync(schemaItem, structProps, schemaItemObject);
282
+ break;
283
+ case SchemaItemType.Mixin:
284
+ schemaItem = schema.createMixinClassSync(name);
285
+ this.loadMixinSync(schemaItem, schemaItemObject);
286
+ break;
287
+ case SchemaItemType.CustomAttributeClass:
288
+ schemaItem = schema.createCustomAttributeClassSync(name);
289
+ const caClassProps = this._parser.parseCustomAttributeClass(schemaItemObject);
290
+ this.loadClassSync(schemaItem, caClassProps, schemaItemObject);
291
+ break;
292
+ case SchemaItemType.RelationshipClass:
293
+ schemaItem = schema.createRelationshipClassSync(name);
294
+ this.loadRelationshipClassSync(schemaItem, schemaItemObject);
295
+ break;
296
+ case SchemaItemType.KindOfQuantity:
297
+ schemaItem = schema.createKindOfQuantitySync(name);
298
+ this.loadKindOfQuantitySync(schemaItem, schemaItemObject);
299
+ break;
300
+ case SchemaItemType.Unit:
301
+ schemaItem = schema.createUnitSync(name);
302
+ this.loadUnitSync(schemaItem, schemaItemObject);
303
+ break;
304
+ case SchemaItemType.Constant:
305
+ schemaItem = schema.createConstantSync(name);
306
+ this.loadConstantSync(schemaItem, schemaItemObject);
307
+ break;
308
+ case SchemaItemType.InvertedUnit:
309
+ schemaItem = schema.createInvertedUnitSync(name);
310
+ this.loadInvertedUnitSync(schemaItem, schemaItemObject);
311
+ break;
312
+ case SchemaItemType.Format:
313
+ schemaItem = schema.createFormatSync(name);
314
+ this.loadFormatSync(schemaItem, schemaItemObject);
315
+ break;
316
+ case SchemaItemType.Phenomenon:
317
+ schemaItem = schema.createPhenomenonSync(name);
318
+ const phenomenonProps = this._parser.parsePhenomenon(schemaItemObject);
319
+ schemaItem.fromJSONSync(phenomenonProps);
320
+ break;
321
+ case SchemaItemType.UnitSystem:
322
+ schemaItem = schema.createUnitSystemSync(name);
323
+ schemaItem.fromJSONSync(this._parser.parseUnitSystem(schemaItemObject));
324
+ break;
325
+ case SchemaItemType.PropertyCategory:
326
+ schemaItem = schema.createPropertyCategorySync(name);
327
+ const propertyCategoryProps = this._parser.parsePropertyCategory(schemaItemObject);
328
+ schemaItem.fromJSONSync(propertyCategoryProps);
329
+ break;
330
+ case SchemaItemType.Enumeration:
331
+ schemaItem = schema.createEnumerationSync(name);
332
+ const enumerationProps = this._parser.parseEnumeration(schemaItemObject);
333
+ schemaItem.fromJSONSync(enumerationProps);
334
+ break;
335
+ // NOTE: we are being permissive here and allowing unknown types to silently fail. Not sure if we want to hard fail or just do a basic deserialization
336
+ }
337
+ return schemaItem;
338
+ }
339
+ /**
340
+ * Given the full (Schema.ItemName) or qualified (alias:ItemName) item name, returns
341
+ * a tuple of strings in the format ["SchemaName", "ItemName"]. The schema name may be
342
+ * empty if the item comes from the schema being parsed.
343
+ * @param fullOrQualifiedName The full or qualified name of the schema item.
344
+ * @param schema The schema that will be used to lookup the schema name by alias, if necessary.
345
+ */
346
+ static resolveSchemaAndItemName(fullOrQualifiedName, schema) {
347
+ const [schemaName, itemName] = SchemaItem.parseFullName(fullOrQualifiedName);
348
+ // If a schema is provided we attempt to resolve the alias by looking at the reference schemas.
349
+ if (undefined !== schema && -1 !== fullOrQualifiedName.indexOf(":")) {
350
+ const refName = schema.getReferenceNameByAlias(schemaName);
351
+ if (undefined === refName)
352
+ throw new ECObjectsError(ECObjectsStatus.UnableToLocateSchema, `Could not resolve schema alias '${schemaName}' for schema item '${itemName}.`);
353
+ return [refName, itemName];
354
+ }
355
+ return [schemaName, itemName];
356
+ }
357
+ /**
358
+ * Finds the a SchemaItem matching the name first by checking the schema that is being deserialized. If it does
359
+ * not exist within the schema, the SchemaContext will be searched.
360
+ * @param name The full (Schema.ItemName) or qualified (alias:ItemName) name of the SchemaItem to search for.
361
+ * @param skipVisitor Used to break Mixin -appliesTo-> Entity -extends-> Mixin cycle.
362
+ * @param loadCallBack Only called if the SchemaItem had to be loaded.
363
+ * @return The SchemaItem if it had to be loaded, otherwise undefined.
364
+ */
365
+ async findSchemaItem(name, skipVisitor = false, loadCallBack) {
366
+ let schemaItem;
367
+ // TODO: A better solution should be investigated for handling both an alias and the schema name.
368
+ const [schemaName, itemName] = SchemaReadHelper.resolveSchemaAndItemName(name, this._schema);
369
+ const isInThisSchema = (this._schema && this._schema.name.toLowerCase() === schemaName.toLowerCase());
370
+ if (undefined === schemaName || 0 === schemaName.length)
371
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `The SchemaItem ${name} is invalid without a schema name`);
372
+ if (isInThisSchema) {
373
+ schemaItem = await this._schema.getItem(itemName);
374
+ if (schemaItem)
375
+ return schemaItem;
376
+ const foundItem = this._parser.findItem(itemName);
377
+ if (foundItem) {
378
+ schemaItem = await this.loadSchemaItem(this._schema, ...foundItem);
379
+ if (!skipVisitor && schemaItem && this._visitorHelper) {
380
+ await this._visitorHelper.visitSchemaPart(schemaItem);
381
+ }
382
+ if (loadCallBack && schemaItem)
383
+ loadCallBack(schemaItem);
384
+ return schemaItem;
385
+ }
386
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `Unable to locate SchemaItem ${name}.`);
387
+ }
388
+ schemaItem = await this._context.getSchemaItem(new SchemaItemKey(itemName, new SchemaKey(schemaName)));
389
+ if (undefined === schemaItem)
390
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `Unable to locate SchemaItem ${name}.`);
391
+ return schemaItem;
392
+ }
393
+ /**
394
+ * Finds the a SchemaItem matching the name first by checking the schema that is being deserialized. If it does
395
+ * not exist within the schema, the SchemaContext will be searched.
396
+ * @param name The full (Schema.ItemName) or qualified (alias:ItemName) name of the SchemaItem to search for.
397
+ * @param skipVisitor Used to break Mixin -appliesTo-> Entity -extends-> Mixin cycle.
398
+ * @param loadCallBack Only called if the SchemaItem had to be loaded.
399
+ * @return The SchemaItem if it had to be loaded, otherwise undefined.
400
+ */
401
+ findSchemaItemSync(name, skipVisitor = false, loadCallBack) {
402
+ let schemaItem;
403
+ // TODO: A better solution should be investigated for handling both an alias and the schema name.
404
+ const [schemaName, itemName] = SchemaReadHelper.resolveSchemaAndItemName(name, this._schema);
405
+ const isInThisSchema = (this._schema && this._schema.name.toLowerCase() === schemaName.toLowerCase());
406
+ if (undefined === schemaName || schemaName.length === 0)
407
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `The SchemaItem ${name} is invalid without a schema name`);
408
+ if (isInThisSchema && undefined === this._schema.getItemSync(itemName)) {
409
+ const foundItem = this._parser.findItem(itemName);
410
+ if (foundItem) {
411
+ schemaItem = this.loadSchemaItemSync(this._schema, ...foundItem);
412
+ if (!skipVisitor && schemaItem && this._visitorHelper) {
413
+ this._visitorHelper.visitSchemaPartSync(schemaItem);
414
+ }
415
+ if (loadCallBack && schemaItem)
416
+ loadCallBack(schemaItem);
417
+ return schemaItem;
418
+ }
419
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `Unable to locate SchemaItem ${name}.`);
420
+ }
421
+ schemaItem = this._context.getSchemaItemSync(new SchemaItemKey(itemName, new SchemaKey(schemaName)));
422
+ if (undefined === schemaItem)
423
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `Unable to locate SchemaItem ${name}.`);
424
+ return schemaItem;
425
+ }
426
+ /**
427
+ * Load dependencies on phenomenon and unitSystem for a Unit object and load the Unit from its serialized format.
428
+ * @param unit The Unit object that we are loading dependencies for and "deserializing into".
429
+ * @param rawUnit The serialized unit data
430
+ */
431
+ async loadUnit(unit, rawUnit) {
432
+ const unitProps = this._parser.parseUnit(rawUnit);
433
+ await this.findSchemaItem(unitProps.phenomenon, true);
434
+ await this.findSchemaItem(unitProps.unitSystem, true);
435
+ await unit.fromJSON(unitProps);
436
+ }
437
+ /**
438
+ * Load dependencies on phenomenon and unitSystem for a Unit object and load the Unit from its serialized format.
439
+ * @param unit The Unit object that we are loading dependencies for and "deserializing into".
440
+ * @param rawUnit The serialized unit data
441
+ */
442
+ loadUnitSync(unit, rawUnit) {
443
+ const unitProps = this._parser.parseUnit(rawUnit);
444
+ this.findSchemaItemSync(unitProps.phenomenon, true);
445
+ this.findSchemaItemSync(unitProps.unitSystem, true);
446
+ unit.fromJSONSync(unitProps);
447
+ }
448
+ /**
449
+ * Load the persistence unit and presentation unit dependencies for a KindOfQuantity object and load the KoQ from its serialized format.
450
+ * @param koq The KindOfQuantity object that we are loading dependencies for and "deserializing into".
451
+ * @param rawKoQ The serialized kind of quantity data
452
+ */
453
+ async loadKindOfQuantity(koq, rawKoQ) {
454
+ const koqProps = this._parser.parseKindOfQuantity(rawKoQ);
455
+ await this.findSchemaItem(koqProps.persistenceUnit);
456
+ if (undefined !== koqProps.presentationUnits) {
457
+ for (const formatString of koqProps.presentationUnits) {
458
+ for (const name of getItemNamesFromFormatString(formatString)) {
459
+ await this.findSchemaItem(name);
460
+ }
461
+ }
462
+ }
463
+ await koq.fromJSON(koqProps);
464
+ }
465
+ /**
466
+ * Load the persistence unit and presentation unit dependencies for a KindOfQuantity object and load the KoQ from its serialized format.
467
+ * @param koq The KindOfQuantity object that we are loading dependencies for and "deserializing into".
468
+ * @param rawKoQ The serialized kind of quantity data
469
+ */
470
+ loadKindOfQuantitySync(koq, rawKoQ) {
471
+ const koqProps = this._parser.parseKindOfQuantity(rawKoQ);
472
+ this.findSchemaItemSync(koqProps.persistenceUnit);
473
+ if (undefined !== koqProps.presentationUnits) {
474
+ for (const formatString of koqProps.presentationUnits) {
475
+ for (const name of getItemNamesFromFormatString(formatString)) {
476
+ this.findSchemaItemSync(name);
477
+ }
478
+ }
479
+ }
480
+ koq.fromJSONSync(koqProps);
481
+ }
482
+ /**
483
+ * Load the phenomenon dependency for a Constant object and load the Constant from its serialized format.
484
+ * @param constant The Constant object that we are loading the phenomenon dependency for
485
+ * @param rawConstant The serialized constant data
486
+ */
487
+ async loadConstant(constant, rawConstant) {
488
+ const constantProps = this._parser.parseConstant(rawConstant);
489
+ await this.findSchemaItem(constantProps.phenomenon, true);
490
+ await constant.fromJSON(constantProps);
491
+ }
492
+ /**
493
+ * Load the phenomenon dependency for a Constant object and load the Constant from its serialized format.
494
+ * @param constant The Constant object that we are loading dependencies for and "deserializing into".
495
+ * @param rawConstant The serialized constant data
496
+ */
497
+ loadConstantSync(constant, rawConstant) {
498
+ const constantProps = this._parser.parseConstant(rawConstant);
499
+ this.findSchemaItemSync(constantProps.phenomenon, true);
500
+ constant.fromJSONSync(constantProps);
501
+ }
502
+ /**
503
+ * Load the unit system and invertsUnit dependencies for an Inverted Unit object and load the Inverted Unit from its serialized format.
504
+ * @param invertedUnit The InvertedUnit object that we are loading dependencies for and "deserializing into".
505
+ * @param rawInvertedUnit The serialized inverted unit data.
506
+ */
507
+ async loadInvertedUnit(invertedUnit, rawInvertedUnit) {
508
+ const invertedUnitProps = this._parser.parseInvertedUnit(rawInvertedUnit);
509
+ await this.findSchemaItem(invertedUnitProps.invertsUnit, true);
510
+ await this.findSchemaItem(invertedUnitProps.unitSystem, true);
511
+ await invertedUnit.fromJSON(invertedUnitProps);
512
+ }
513
+ /**
514
+ * Load the unit system and invertsUnit dependencies for an Inverted Unit object and load the Inverted Unit from its serialized format.
515
+ * @param invertedUnit The InvertedUnit object that we are loading dependencies for and "deserializing into".
516
+ * @param rawInvertedUnit The serialized inverted unit data.
517
+ */
518
+ loadInvertedUnitSync(invertedUnit, rawInvertedUnit) {
519
+ const invertedUnitProps = this._parser.parseInvertedUnit(rawInvertedUnit);
520
+ this.findSchemaItemSync(invertedUnitProps.invertsUnit, true);
521
+ this.findSchemaItemSync(invertedUnitProps.unitSystem, true);
522
+ invertedUnit.fromJSONSync(invertedUnitProps);
523
+ }
524
+ /**
525
+ * Load the unit dependencies for a Format object and load the Format from its serialized format.
526
+ * @param format The Format object that we are loading dependencies for and "deserializing into".
527
+ * @param rawFormat The serialized format data.
528
+ */
529
+ async loadFormat(format, rawFormat) {
530
+ const formatProps = this._parser.parseFormat(rawFormat);
531
+ if (undefined !== formatProps.composite) {
532
+ const formatUnits = formatProps.composite.units;
533
+ for (const unit of formatUnits) {
534
+ await this.findSchemaItem(unit.name, true);
535
+ }
536
+ }
537
+ await format.fromJSON(formatProps);
538
+ }
539
+ /**
540
+ * Load the unit dependencies for a Format object and load the Format from its serialized format.
541
+ * @param format The Format object that we are loading dependencies for and "deserializing into".
542
+ * @param rawFormat The serialized format data.
543
+ */
544
+ loadFormatSync(format, rawFormat) {
545
+ const formatProps = this._parser.parseFormat(rawFormat);
546
+ if (undefined !== formatProps.composite) {
547
+ const formatUnits = formatProps.composite.units;
548
+ for (const unit of formatUnits) {
549
+ this.findSchemaItemSync(unit.name, true);
550
+ }
551
+ }
552
+ format.fromJSONSync(formatProps);
553
+ }
554
+ /**
555
+ * Load the base class and property type dependencies for an ECClass object and load the ECClass (and its properties) from its serialized format.
556
+ * @param classObj The ECClass object that we are loading dependencies for and "deserializing into".
557
+ * @param classProps The parsed class props object.
558
+ * @param rawClass The serialized class data.
559
+ */
560
+ async loadClass(classObj, classProps, rawClass) {
561
+ const baseClassLoaded = async (baseClass) => {
562
+ if (this._visitorHelper)
563
+ await this._visitorHelper.visitSchemaPart(baseClass);
564
+ };
565
+ // Load base class first
566
+ if (undefined !== classProps.baseClass) {
567
+ await this.findSchemaItem(classProps.baseClass, true, baseClassLoaded);
568
+ }
569
+ // Now deserialize the class itself, *before* any properties
570
+ // (We need to do this to break Entity -navProp-> Relationship -constraint-> Entity cycle.)
571
+ await classObj.fromJSON(classProps);
572
+ for (const [propName, propType, rawProp] of this._parser.getProperties(rawClass, classObj.fullName)) {
573
+ await this.loadPropertyTypes(classObj, propName, propType, rawProp);
574
+ }
575
+ await this.loadCustomAttributes(classObj, this._parser.getClassCustomAttributeProviders(rawClass));
576
+ }
577
+ /**
578
+ * Load the base class and property type dependencies for an ECClass object and load the ECClass (and its properties) from its serialized format.
579
+ * @param classObj The ECClass object that we are loading dependencies for and "deserializing into".
580
+ * @param classProps The parsed class props object.
581
+ * @param rawClass The serialized class data.
582
+ */
583
+ loadClassSync(classObj, classProps, rawClass) {
584
+ const baseClassLoaded = async (baseClass) => {
585
+ if (this._visitorHelper)
586
+ this._visitorHelper.visitSchemaPartSync(baseClass);
587
+ };
588
+ // Load base class first
589
+ if (undefined !== classProps.baseClass) {
590
+ this.findSchemaItemSync(classProps.baseClass, true, baseClassLoaded);
591
+ }
592
+ // Now deserialize the class itself, *before* any properties
593
+ // (We need to do this to break Entity -navProp-> Relationship -constraint-> Entity cycle.)
594
+ classObj.fromJSONSync(classProps);
595
+ for (const [propName, propType, rawProp] of this._parser.getProperties(rawClass, classObj.fullName)) {
596
+ this.loadPropertyTypesSync(classObj, propName, propType, rawProp);
597
+ }
598
+ this.loadCustomAttributesSync(classObj, this._parser.getClassCustomAttributeProviders(rawClass));
599
+ }
600
+ /**
601
+ * Load the mixin, base class, and property type dependencies for an EntityClass object and load the EntityClass (and properties) from its serialized format.
602
+ * @param entity The EntityClass that we are loading dependencies for and "deserializing into".
603
+ * @param rawEntity The serialized entity class data.
604
+ */
605
+ async loadEntityClass(entity, rawEntity) {
606
+ const entityClassProps = this._parser.parseEntityClass(rawEntity);
607
+ // Load Mixin classes first
608
+ if (undefined !== entityClassProps.mixins) {
609
+ for (const mixinName of entityClassProps.mixins)
610
+ await this.findSchemaItem(mixinName);
611
+ }
612
+ await this.loadClass(entity, entityClassProps, rawEntity);
613
+ }
614
+ /**
615
+ * Load the mixin, base class, and property type dependencies for an EntityClass object and load the EntityClass (and properties) from its serialized format.
616
+ * @param entity The EntityClass that we are loading dependencies for and "deserializing into".
617
+ * @param rawEntity The serialized entity class data.
618
+ */
619
+ loadEntityClassSync(entity, rawEntity) {
620
+ const entityClassProps = this._parser.parseEntityClass(rawEntity);
621
+ // Load Mixin classes first
622
+ if (undefined !== entityClassProps.mixins) {
623
+ for (const mixinName of entityClassProps.mixins)
624
+ this.findSchemaItemSync(mixinName);
625
+ }
626
+ this.loadClassSync(entity, entityClassProps, rawEntity);
627
+ }
628
+ /**
629
+ * Load the appliesTo class, base class, and property type dependencies for a Mixin object and load the Mixin (and properties) from its serialized format.
630
+ * @param mixin The Mixin that we are loading dependencies for and "deserializing into".
631
+ * @param rawMixin The serialized mixin data.
632
+ */
633
+ async loadMixin(mixin, rawMixin) {
634
+ const mixinProps = this._parser.parseMixin(rawMixin);
635
+ const appliesToLoaded = async (appliesToClass) => {
636
+ if (this._visitorHelper)
637
+ await this._visitorHelper.visitSchemaPart(appliesToClass);
638
+ };
639
+ await this.findSchemaItem(mixinProps.appliesTo, true, appliesToLoaded);
640
+ await this.loadClass(mixin, mixinProps, rawMixin);
641
+ }
642
+ /**
643
+ * Load the appliesTo class, base class, and property type dependencies for a Mixin object and load the Mixin (and properties) from its serialized format.
644
+ * @param mixin The Mixin that we are loading dependencies for and "deserializing into".
645
+ * @param rawMixin The serialized mixin data.
646
+ */
647
+ loadMixinSync(mixin, rawMixin) {
648
+ const mixinProps = this._parser.parseMixin(rawMixin);
649
+ const appliesToLoaded = async (appliesToClass) => {
650
+ if (this._visitorHelper)
651
+ await this._visitorHelper.visitSchemaPart(appliesToClass);
652
+ };
653
+ this.findSchemaItemSync(mixinProps.appliesTo, true, appliesToLoaded);
654
+ this.loadClassSync(mixin, mixinProps, rawMixin);
655
+ }
656
+ /**
657
+ * Load the relationship constraint, base class, and property type dependencies for a RelationshipClass object and load the RelationshipClass (and properties) from its serialized format.
658
+ * @param rel The RelationshipClass that we are loading dependencies for and "deserializing into".
659
+ * @param rawRel The serialized relationship class data.
660
+ */
661
+ async loadRelationshipClass(rel, rawRel) {
662
+ const relationshipClassProps = this._parser.parseRelationshipClass(rawRel);
663
+ await this.loadClass(rel, relationshipClassProps, rawRel);
664
+ await this.loadRelationshipConstraint(rel.source, relationshipClassProps.source);
665
+ await this.loadRelationshipConstraint(rel.target, relationshipClassProps.target);
666
+ const [sourceCustomAttributes, targetCustomAttributes] = this._parser.getRelationshipConstraintCustomAttributeProviders(rawRel);
667
+ await this.loadCustomAttributes(rel.source, sourceCustomAttributes);
668
+ await this.loadCustomAttributes(rel.target, targetCustomAttributes);
669
+ }
670
+ /**
671
+ * Load the relationship constraint, base class, and property type dependencies for a RelationshipClass object and load the RelationshipClass (and properties) from its serialized format.
672
+ * @param rel The RelationshipClass that we are loading dependencies for and "deserializing into".
673
+ * @param rawRel The serialized relationship class data.
674
+ */
675
+ loadRelationshipClassSync(rel, rawRel) {
676
+ const relationshipClassProps = this._parser.parseRelationshipClass(rawRel);
677
+ this.loadClassSync(rel, relationshipClassProps, rawRel);
678
+ this.loadRelationshipConstraintSync(rel.source, relationshipClassProps.source);
679
+ this.loadRelationshipConstraintSync(rel.target, relationshipClassProps.target);
680
+ const [sourceCustomAttributes, targetCustomAttributes] = this._parser.getRelationshipConstraintCustomAttributeProviders(rawRel);
681
+ this.loadCustomAttributesSync(rel.source, sourceCustomAttributes);
682
+ this.loadCustomAttributesSync(rel.target, targetCustomAttributes);
683
+ }
684
+ /**
685
+ * Load the abstract constraint and constraint class dependencies for a RelationshipConstraint object and load the RelationshipConstraint from its parsed props.
686
+ * @param relConstraint The RelationshipConstraint that we are loading dependencies for and "deserializing into".
687
+ * @param props The parsed relationship constraint props.
688
+ */
689
+ async loadRelationshipConstraint(relConstraint, props) {
690
+ if (undefined !== props.abstractConstraint) {
691
+ await this.findSchemaItem(props.abstractConstraint);
692
+ }
693
+ if (undefined !== props.constraintClasses) { // TODO: this should be required
694
+ for (const constraintClass of props.constraintClasses) {
695
+ await this.findSchemaItem(constraintClass);
696
+ }
697
+ }
698
+ await relConstraint.fromJSON(props);
699
+ }
700
+ /**
701
+ * Load the abstract constraint and constraint class dependencies for a RelationshipConstraint object and load the RelationshipConstraint from its parsed props.
702
+ * @param relConstraint The RelationshipConstraint that we are loading dependencies for and "deserializing into".
703
+ * @param props The parsed relationship constraint props.
704
+ */
705
+ loadRelationshipConstraintSync(relConstraint, props) {
706
+ if (undefined !== props.abstractConstraint) {
707
+ this.findSchemaItemSync(props.abstractConstraint);
708
+ }
709
+ if (undefined !== props.constraintClasses) {
710
+ for (const constraintClass of props.constraintClasses) {
711
+ this.findSchemaItemSync(constraintClass);
712
+ }
713
+ }
714
+ relConstraint.fromJSONSync(props);
715
+ }
716
+ /**
717
+ * Load the type dependencies for a serialized property, then creates and deserialized the Property object in the given ECClass.
718
+ * @param classObj The ECClass that the Property should be created in.
719
+ * @param propName The name of the Property.
720
+ * @param propType The (serialized string) kind of property to create.
721
+ * @param rawProperty The serialized property data.
722
+ */
723
+ async loadPropertyTypes(classObj, propName, propType, rawProperty) {
724
+ const loadTypeName = async (typeName) => {
725
+ if (undefined === parsePrimitiveType(typeName))
726
+ await this.findSchemaItem(typeName);
727
+ };
728
+ const lowerCasePropType = propType.toLowerCase();
729
+ switch (lowerCasePropType) {
730
+ case "primitiveproperty":
731
+ const primPropertyProps = this._parser.parsePrimitiveProperty(rawProperty);
732
+ await loadTypeName(primPropertyProps.typeName);
733
+ const primProp = await classObj.createPrimitiveProperty(propName, primPropertyProps.typeName);
734
+ return this.loadProperty(primProp, primPropertyProps, rawProperty);
735
+ case "structproperty":
736
+ const structPropertyProps = this._parser.parseStructProperty(rawProperty);
737
+ await loadTypeName(structPropertyProps.typeName);
738
+ const structProp = await classObj.createStructProperty(propName, structPropertyProps.typeName);
739
+ return this.loadProperty(structProp, structPropertyProps, rawProperty);
740
+ case "primitivearrayproperty":
741
+ const primArrPropertyProps = this._parser.parsePrimitiveArrayProperty(rawProperty);
742
+ await loadTypeName(primArrPropertyProps.typeName);
743
+ const primArrProp = await classObj.createPrimitiveArrayProperty(propName, primArrPropertyProps.typeName);
744
+ return this.loadProperty(primArrProp, primArrPropertyProps, rawProperty);
745
+ case "structarrayproperty":
746
+ const structArrPropertyProps = this._parser.parseStructArrayProperty(rawProperty);
747
+ await loadTypeName(structArrPropertyProps.typeName);
748
+ const structArrProp = await classObj.createStructArrayProperty(propName, structArrPropertyProps.typeName);
749
+ return this.loadProperty(structArrProp, structArrPropertyProps, rawProperty);
750
+ case "navigationproperty":
751
+ if (classObj.schemaItemType !== SchemaItemType.EntityClass && classObj.schemaItemType !== SchemaItemType.RelationshipClass && classObj.schemaItemType !== SchemaItemType.Mixin)
752
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `The Navigation Property ${classObj.name}.${propName} is invalid, because only EntityClasses, Mixins, and RelationshipClasses can have NavigationProperties.`);
753
+ const navPropertyProps = this._parser.parseNavigationProperty(rawProperty);
754
+ await this.findSchemaItem(navPropertyProps.relationshipName);
755
+ const navProp = await classObj.createNavigationProperty(propName, navPropertyProps.relationshipName, navPropertyProps.direction);
756
+ return this.loadProperty(navProp, navPropertyProps, rawProperty);
757
+ }
758
+ }
759
+ /**
760
+ * Load the type dependencies for a serialized property, then creates and deserialized the Property object in the given ECClass.
761
+ * @param classObj The ECClass that the Property should be created in.
762
+ * @param propName The name of the Property.
763
+ * @param propType The (serialized string) kind of property to create.
764
+ * @param rawProperty The serialized property data.
765
+ */
766
+ loadPropertyTypesSync(classObj, propName, propType, rawProperty) {
767
+ const loadTypeName = (typeName) => {
768
+ if (undefined === parsePrimitiveType(typeName))
769
+ this.findSchemaItemSync(typeName);
770
+ };
771
+ const lowerCasePropType = propType.toLowerCase();
772
+ switch (lowerCasePropType) {
773
+ case "primitiveproperty":
774
+ const primPropertyProps = this._parser.parsePrimitiveProperty(rawProperty);
775
+ loadTypeName(primPropertyProps.typeName);
776
+ const primProp = classObj.createPrimitivePropertySync(propName, primPropertyProps.typeName);
777
+ return this.loadPropertySync(primProp, primPropertyProps, rawProperty);
778
+ case "structproperty":
779
+ const structPropertyProps = this._parser.parseStructProperty(rawProperty);
780
+ loadTypeName(structPropertyProps.typeName);
781
+ const structProp = classObj.createStructPropertySync(propName, structPropertyProps.typeName);
782
+ return this.loadPropertySync(structProp, structPropertyProps, rawProperty);
783
+ case "primitivearrayproperty":
784
+ const primArrPropertyProps = this._parser.parsePrimitiveArrayProperty(rawProperty);
785
+ loadTypeName(primArrPropertyProps.typeName);
786
+ const primArrProp = classObj.createPrimitiveArrayPropertySync(propName, primArrPropertyProps.typeName);
787
+ return this.loadPropertySync(primArrProp, primArrPropertyProps, rawProperty);
788
+ case "structarrayproperty":
789
+ const structArrPropertyProps = this._parser.parseStructArrayProperty(rawProperty);
790
+ loadTypeName(structArrPropertyProps.typeName);
791
+ const structArrProp = classObj.createStructArrayPropertySync(propName, structArrPropertyProps.typeName);
792
+ return this.loadPropertySync(structArrProp, structArrPropertyProps, rawProperty);
793
+ case "navigationproperty":
794
+ if (classObj.schemaItemType !== SchemaItemType.EntityClass && classObj.schemaItemType !== SchemaItemType.RelationshipClass && classObj.schemaItemType !== SchemaItemType.Mixin)
795
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `The Navigation Property ${classObj.name}.${propName} is invalid, because only EntityClasses, Mixins, and RelationshipClasses can have NavigationProperties.`);
796
+ const navPropertyProps = this._parser.parseNavigationProperty(rawProperty);
797
+ this.findSchemaItemSync(navPropertyProps.relationshipName);
798
+ const navProp = classObj.createNavigationPropertySync(propName, navPropertyProps.relationshipName, navPropertyProps.direction);
799
+ return this.loadPropertySync(navProp, navPropertyProps, rawProperty);
800
+ }
801
+ }
802
+ /**
803
+ * Load the propertyCategory, kindOfQuantity, and customAttribute dependencies for a Property object and load the Property from its parsed props.
804
+ * @param propertyObj The Property that we are loading dependencies for and "deserializing into".
805
+ * @param props The parsed property props.
806
+ * @param rawProperty The serialized property data.
807
+ */
808
+ async loadProperty(propertyObj, props, rawProperty) {
809
+ if (undefined !== props.category) {
810
+ await this.findSchemaItem(props.category);
811
+ }
812
+ if (undefined !== props.kindOfQuantity) {
813
+ await this.findSchemaItem(props.kindOfQuantity);
814
+ }
815
+ await propertyObj.fromJSON(props);
816
+ await this.loadCustomAttributes(propertyObj, this._parser.getPropertyCustomAttributeProviders(rawProperty));
817
+ }
818
+ /**
819
+ * Load the propertyCategory, kindOfQuantity, and customAttribute dependencies for a Property object and load the Property from its parsed props.
820
+ * @param propertyObj The Property that we are loading dependencies for and "deserializing into".
821
+ * @param props The parsed property props.
822
+ * @param rawProperty The serialized property data.
823
+ */
824
+ loadPropertySync(propertyObj, props, rawProperty) {
825
+ if (undefined !== props.category) {
826
+ this.findSchemaItemSync(props.category);
827
+ }
828
+ if (undefined !== props.kindOfQuantity) {
829
+ this.findSchemaItemSync(props.kindOfQuantity);
830
+ }
831
+ propertyObj.fromJSONSync(props);
832
+ this.loadCustomAttributesSync(propertyObj, this._parser.getPropertyCustomAttributeProviders(rawProperty));
833
+ }
834
+ /**
835
+ * Load the customAttribute class dependencies for a set of CustomAttribute objects and add
836
+ * them to a given custom attribute container.
837
+ * @param container The CustomAttributeContainer that each CustomAttribute will be added to.
838
+ * @param customAttributes An iterable set of parsed CustomAttribute objects.
839
+ */
840
+ async loadCustomAttributes(container, caProviders) {
841
+ for (const providerTuple of caProviders) {
842
+ // First tuple entry is the CA class name.
843
+ const caClass = await this.findSchemaItem(providerTuple[0]);
844
+ // If custom attribute exist within the context and is referenced, validate the reference is defined in the container's schema
845
+ if (caClass && caClass.key.schemaName !== container.schema.name &&
846
+ !container.schema.getReferenceSync(caClass.key.schemaName)) {
847
+ throw new ECObjectsError(ECObjectsStatus.InvalidECJson, `Unable to load custom attribute ${caClass.fullName} from container ${container.fullName}, ${caClass.key.schemaName} reference not defined`);
848
+ }
849
+ // Second tuple entry ia a function that provides the CA instance.
850
+ const provider = providerTuple[1];
851
+ const customAttribute = provider(caClass);
852
+ container.addCustomAttribute(customAttribute);
853
+ }
854
+ }
855
+ /**
856
+ * Load the customAttribute class dependencies for a set of CustomAttribute objects and add them to a given custom attribute container.
857
+ * @param container The CustomAttributeContainer that each CustomAttribute will be added to.
858
+ * @param customAttributes An iterable set of parsed CustomAttribute objects.
859
+ */
860
+ loadCustomAttributesSync(container, caProviders) {
861
+ for (const providerTuple of caProviders) {
862
+ // First tuple entry is the CA class name.
863
+ const caClass = this.findSchemaItemSync(providerTuple[0]);
864
+ // Second tuple entry ia a function that provides the CA instance.
865
+ const provider = providerTuple[1];
866
+ const customAttribute = provider(caClass);
867
+ container.addCustomAttribute(customAttribute);
868
+ }
869
+ }
870
+ }
871
+ //# sourceMappingURL=Helper.js.map