@itwin/ecschema-metadata 5.1.0-dev.9 → 5.2.0-dev.2

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 (210) hide show
  1. package/CHANGELOG.md +74 -1
  2. package/lib/cjs/Context.d.ts +1 -1
  3. package/lib/cjs/Context.js +1 -1
  4. package/lib/cjs/Context.js.map +1 -1
  5. package/lib/cjs/Deserialization/Helper.d.ts +30 -11
  6. package/lib/cjs/Deserialization/Helper.d.ts.map +1 -1
  7. package/lib/cjs/Deserialization/Helper.js +124 -96
  8. package/lib/cjs/Deserialization/Helper.js.map +1 -1
  9. package/lib/cjs/Deserialization/SchemaGraphUtil.d.ts +12 -3
  10. package/lib/cjs/Deserialization/SchemaGraphUtil.d.ts.map +1 -1
  11. package/lib/cjs/Deserialization/SchemaGraphUtil.js +36 -23
  12. package/lib/cjs/Deserialization/SchemaGraphUtil.js.map +1 -1
  13. package/lib/cjs/Deserialization/XmlParser.d.ts.map +1 -1
  14. package/lib/cjs/Deserialization/XmlParser.js +14 -5
  15. package/lib/cjs/Deserialization/XmlParser.js.map +1 -1
  16. package/lib/cjs/Deserialization/XmlSerializationUtils.js +1 -1
  17. package/lib/cjs/Deserialization/XmlSerializationUtils.js.map +1 -1
  18. package/lib/cjs/ECName.js +1 -1
  19. package/lib/cjs/ECName.js.map +1 -1
  20. package/lib/cjs/ECObjects.d.ts +1 -1
  21. package/lib/cjs/ECObjects.js +2 -2
  22. package/lib/cjs/ECObjects.js.map +1 -1
  23. package/lib/cjs/IncrementalLoading/ClassParsers.d.ts +60 -0
  24. package/lib/cjs/IncrementalLoading/ClassParsers.d.ts.map +1 -0
  25. package/lib/cjs/IncrementalLoading/ClassParsers.js +111 -0
  26. package/lib/cjs/IncrementalLoading/ClassParsers.js.map +1 -0
  27. package/lib/cjs/IncrementalLoading/ECSqlSchemaLocater.d.ts +211 -0
  28. package/lib/cjs/IncrementalLoading/ECSqlSchemaLocater.d.ts.map +1 -0
  29. package/lib/cjs/IncrementalLoading/ECSqlSchemaLocater.js +387 -0
  30. package/lib/cjs/IncrementalLoading/ECSqlSchemaLocater.js.map +1 -0
  31. package/lib/cjs/IncrementalLoading/FullSchemaQueries.d.ts +14 -0
  32. package/lib/cjs/IncrementalLoading/FullSchemaQueries.d.ts.map +1 -0
  33. package/lib/cjs/IncrementalLoading/FullSchemaQueries.js +609 -0
  34. package/lib/cjs/IncrementalLoading/FullSchemaQueries.js.map +1 -0
  35. package/lib/cjs/IncrementalLoading/IncrementalSchemaLocater.d.ts +109 -0
  36. package/lib/cjs/IncrementalLoading/IncrementalSchemaLocater.d.ts.map +1 -0
  37. package/lib/cjs/IncrementalLoading/IncrementalSchemaLocater.js +219 -0
  38. package/lib/cjs/IncrementalLoading/IncrementalSchemaLocater.js.map +1 -0
  39. package/lib/cjs/IncrementalLoading/IncrementalSchemaReader.d.ts +36 -0
  40. package/lib/cjs/IncrementalLoading/IncrementalSchemaReader.d.ts.map +1 -0
  41. package/lib/cjs/IncrementalLoading/IncrementalSchemaReader.js +77 -0
  42. package/lib/cjs/IncrementalLoading/IncrementalSchemaReader.js.map +1 -0
  43. package/lib/cjs/IncrementalLoading/PerformanceLogger.d.ts +60 -0
  44. package/lib/cjs/IncrementalLoading/PerformanceLogger.d.ts.map +1 -0
  45. package/lib/cjs/IncrementalLoading/PerformanceLogger.js +82 -0
  46. package/lib/cjs/IncrementalLoading/PerformanceLogger.js.map +1 -0
  47. package/lib/cjs/IncrementalLoading/SchemaItemParsers.d.ts +51 -0
  48. package/lib/cjs/IncrementalLoading/SchemaItemParsers.d.ts.map +1 -0
  49. package/lib/cjs/IncrementalLoading/SchemaItemParsers.js +122 -0
  50. package/lib/cjs/IncrementalLoading/SchemaItemParsers.js.map +1 -0
  51. package/lib/cjs/IncrementalLoading/SchemaItemQueries.d.ts +16 -0
  52. package/lib/cjs/IncrementalLoading/SchemaItemQueries.d.ts.map +1 -0
  53. package/lib/cjs/IncrementalLoading/SchemaItemQueries.js +308 -0
  54. package/lib/cjs/IncrementalLoading/SchemaItemQueries.js.map +1 -0
  55. package/lib/cjs/IncrementalLoading/SchemaParser.d.ts +42 -0
  56. package/lib/cjs/IncrementalLoading/SchemaParser.d.ts.map +1 -0
  57. package/lib/cjs/IncrementalLoading/SchemaParser.js +109 -0
  58. package/lib/cjs/IncrementalLoading/SchemaParser.js.map +1 -0
  59. package/lib/cjs/IncrementalLoading/SchemaStubQueries.d.ts +12 -0
  60. package/lib/cjs/IncrementalLoading/SchemaStubQueries.d.ts.map +1 -0
  61. package/lib/cjs/IncrementalLoading/SchemaStubQueries.js +365 -0
  62. package/lib/cjs/IncrementalLoading/SchemaStubQueries.js.map +1 -0
  63. package/lib/cjs/Metadata/Class.d.ts +5 -16
  64. package/lib/cjs/Metadata/Class.d.ts.map +1 -1
  65. package/lib/cjs/Metadata/Class.js +68 -68
  66. package/lib/cjs/Metadata/Class.js.map +1 -1
  67. package/lib/cjs/Metadata/CustomAttribute.d.ts +7 -1
  68. package/lib/cjs/Metadata/CustomAttribute.d.ts.map +1 -1
  69. package/lib/cjs/Metadata/CustomAttribute.js.map +1 -1
  70. package/lib/cjs/Metadata/CustomAttributeClass.d.ts +1 -1
  71. package/lib/cjs/Metadata/CustomAttributeClass.js +1 -1
  72. package/lib/cjs/Metadata/CustomAttributeClass.js.map +1 -1
  73. package/lib/cjs/Metadata/EntityClass.d.ts +6 -6
  74. package/lib/cjs/Metadata/EntityClass.d.ts.map +1 -1
  75. package/lib/cjs/Metadata/EntityClass.js +48 -26
  76. package/lib/cjs/Metadata/EntityClass.js.map +1 -1
  77. package/lib/cjs/Metadata/Format.d.ts +5 -0
  78. package/lib/cjs/Metadata/Format.d.ts.map +1 -1
  79. package/lib/cjs/Metadata/Format.js +7 -0
  80. package/lib/cjs/Metadata/Format.js.map +1 -1
  81. package/lib/cjs/Metadata/KindOfQuantity.js.map +1 -1
  82. package/lib/cjs/Metadata/Schema.d.ts +10 -0
  83. package/lib/cjs/Metadata/Schema.d.ts.map +1 -1
  84. package/lib/cjs/Metadata/Schema.js +13 -0
  85. package/lib/cjs/Metadata/Schema.js.map +1 -1
  86. package/lib/cjs/Metadata/SchemaItem.d.ts +10 -0
  87. package/lib/cjs/Metadata/SchemaItem.d.ts.map +1 -1
  88. package/lib/cjs/Metadata/SchemaItem.js +13 -0
  89. package/lib/cjs/Metadata/SchemaItem.js.map +1 -1
  90. package/lib/cjs/SchemaFormatsProvider.d.ts +4 -3
  91. package/lib/cjs/SchemaFormatsProvider.d.ts.map +1 -1
  92. package/lib/cjs/SchemaFormatsProvider.js +60 -17
  93. package/lib/cjs/SchemaFormatsProvider.js.map +1 -1
  94. package/lib/cjs/SchemaLoader.d.ts +4 -1
  95. package/lib/cjs/SchemaLoader.d.ts.map +1 -1
  96. package/lib/cjs/SchemaLoader.js +4 -1
  97. package/lib/cjs/SchemaLoader.js.map +1 -1
  98. package/lib/cjs/ecschema-metadata.d.ts +2 -0
  99. package/lib/cjs/ecschema-metadata.d.ts.map +1 -1
  100. package/lib/cjs/ecschema-metadata.js +2 -0
  101. package/lib/cjs/ecschema-metadata.js.map +1 -1
  102. package/lib/cjs/utils/SchemaLoadingController.d.ts +37 -0
  103. package/lib/cjs/utils/SchemaLoadingController.d.ts.map +1 -0
  104. package/lib/cjs/utils/SchemaLoadingController.js +65 -0
  105. package/lib/cjs/utils/SchemaLoadingController.js.map +1 -0
  106. package/lib/esm/Context.d.ts +1 -1
  107. package/lib/esm/Context.js +1 -1
  108. package/lib/esm/Context.js.map +1 -1
  109. package/lib/esm/Deserialization/Helper.d.ts +30 -11
  110. package/lib/esm/Deserialization/Helper.d.ts.map +1 -1
  111. package/lib/esm/Deserialization/Helper.js +124 -96
  112. package/lib/esm/Deserialization/Helper.js.map +1 -1
  113. package/lib/esm/Deserialization/SchemaGraphUtil.d.ts +12 -3
  114. package/lib/esm/Deserialization/SchemaGraphUtil.d.ts.map +1 -1
  115. package/lib/esm/Deserialization/SchemaGraphUtil.js +36 -23
  116. package/lib/esm/Deserialization/SchemaGraphUtil.js.map +1 -1
  117. package/lib/esm/Deserialization/XmlParser.d.ts.map +1 -1
  118. package/lib/esm/Deserialization/XmlParser.js +14 -5
  119. package/lib/esm/Deserialization/XmlParser.js.map +1 -1
  120. package/lib/esm/Deserialization/XmlSerializationUtils.js +1 -1
  121. package/lib/esm/Deserialization/XmlSerializationUtils.js.map +1 -1
  122. package/lib/esm/ECName.js +1 -1
  123. package/lib/esm/ECName.js.map +1 -1
  124. package/lib/esm/ECObjects.d.ts +1 -1
  125. package/lib/esm/ECObjects.js +2 -2
  126. package/lib/esm/ECObjects.js.map +1 -1
  127. package/lib/esm/IncrementalLoading/ClassParsers.d.ts +60 -0
  128. package/lib/esm/IncrementalLoading/ClassParsers.d.ts.map +1 -0
  129. package/lib/esm/IncrementalLoading/ClassParsers.js +104 -0
  130. package/lib/esm/IncrementalLoading/ClassParsers.js.map +1 -0
  131. package/lib/esm/IncrementalLoading/ECSqlSchemaLocater.d.ts +211 -0
  132. package/lib/esm/IncrementalLoading/ECSqlSchemaLocater.d.ts.map +1 -0
  133. package/lib/esm/IncrementalLoading/ECSqlSchemaLocater.js +383 -0
  134. package/lib/esm/IncrementalLoading/ECSqlSchemaLocater.js.map +1 -0
  135. package/lib/esm/IncrementalLoading/FullSchemaQueries.d.ts +14 -0
  136. package/lib/esm/IncrementalLoading/FullSchemaQueries.d.ts.map +1 -0
  137. package/lib/esm/IncrementalLoading/FullSchemaQueries.js +606 -0
  138. package/lib/esm/IncrementalLoading/FullSchemaQueries.js.map +1 -0
  139. package/lib/esm/IncrementalLoading/IncrementalSchemaLocater.d.ts +109 -0
  140. package/lib/esm/IncrementalLoading/IncrementalSchemaLocater.d.ts.map +1 -0
  141. package/lib/esm/IncrementalLoading/IncrementalSchemaLocater.js +215 -0
  142. package/lib/esm/IncrementalLoading/IncrementalSchemaLocater.js.map +1 -0
  143. package/lib/esm/IncrementalLoading/IncrementalSchemaReader.d.ts +36 -0
  144. package/lib/esm/IncrementalLoading/IncrementalSchemaReader.d.ts.map +1 -0
  145. package/lib/esm/IncrementalLoading/IncrementalSchemaReader.js +73 -0
  146. package/lib/esm/IncrementalLoading/IncrementalSchemaReader.js.map +1 -0
  147. package/lib/esm/IncrementalLoading/PerformanceLogger.d.ts +60 -0
  148. package/lib/esm/IncrementalLoading/PerformanceLogger.d.ts.map +1 -0
  149. package/lib/esm/IncrementalLoading/PerformanceLogger.js +78 -0
  150. package/lib/esm/IncrementalLoading/PerformanceLogger.js.map +1 -0
  151. package/lib/esm/IncrementalLoading/SchemaItemParsers.d.ts +51 -0
  152. package/lib/esm/IncrementalLoading/SchemaItemParsers.d.ts.map +1 -0
  153. package/lib/esm/IncrementalLoading/SchemaItemParsers.js +117 -0
  154. package/lib/esm/IncrementalLoading/SchemaItemParsers.js.map +1 -0
  155. package/lib/esm/IncrementalLoading/SchemaItemQueries.d.ts +16 -0
  156. package/lib/esm/IncrementalLoading/SchemaItemQueries.d.ts.map +1 -0
  157. package/lib/esm/IncrementalLoading/SchemaItemQueries.js +305 -0
  158. package/lib/esm/IncrementalLoading/SchemaItemQueries.js.map +1 -0
  159. package/lib/esm/IncrementalLoading/SchemaParser.d.ts +42 -0
  160. package/lib/esm/IncrementalLoading/SchemaParser.d.ts.map +1 -0
  161. package/lib/esm/IncrementalLoading/SchemaParser.js +104 -0
  162. package/lib/esm/IncrementalLoading/SchemaParser.js.map +1 -0
  163. package/lib/esm/IncrementalLoading/SchemaStubQueries.d.ts +12 -0
  164. package/lib/esm/IncrementalLoading/SchemaStubQueries.d.ts.map +1 -0
  165. package/lib/esm/IncrementalLoading/SchemaStubQueries.js +359 -0
  166. package/lib/esm/IncrementalLoading/SchemaStubQueries.js.map +1 -0
  167. package/lib/esm/Metadata/Class.d.ts +5 -16
  168. package/lib/esm/Metadata/Class.d.ts.map +1 -1
  169. package/lib/esm/Metadata/Class.js +68 -68
  170. package/lib/esm/Metadata/Class.js.map +1 -1
  171. package/lib/esm/Metadata/CustomAttribute.d.ts +7 -1
  172. package/lib/esm/Metadata/CustomAttribute.d.ts.map +1 -1
  173. package/lib/esm/Metadata/CustomAttribute.js.map +1 -1
  174. package/lib/esm/Metadata/CustomAttributeClass.d.ts +1 -1
  175. package/lib/esm/Metadata/CustomAttributeClass.js +1 -1
  176. package/lib/esm/Metadata/CustomAttributeClass.js.map +1 -1
  177. package/lib/esm/Metadata/EntityClass.d.ts +6 -6
  178. package/lib/esm/Metadata/EntityClass.d.ts.map +1 -1
  179. package/lib/esm/Metadata/EntityClass.js +48 -26
  180. package/lib/esm/Metadata/EntityClass.js.map +1 -1
  181. package/lib/esm/Metadata/Format.d.ts +5 -0
  182. package/lib/esm/Metadata/Format.d.ts.map +1 -1
  183. package/lib/esm/Metadata/Format.js +7 -0
  184. package/lib/esm/Metadata/Format.js.map +1 -1
  185. package/lib/esm/Metadata/KindOfQuantity.js.map +1 -1
  186. package/lib/esm/Metadata/Schema.d.ts +10 -0
  187. package/lib/esm/Metadata/Schema.d.ts.map +1 -1
  188. package/lib/esm/Metadata/Schema.js +13 -0
  189. package/lib/esm/Metadata/Schema.js.map +1 -1
  190. package/lib/esm/Metadata/SchemaItem.d.ts +10 -0
  191. package/lib/esm/Metadata/SchemaItem.d.ts.map +1 -1
  192. package/lib/esm/Metadata/SchemaItem.js +13 -0
  193. package/lib/esm/Metadata/SchemaItem.js.map +1 -1
  194. package/lib/esm/SchemaFormatsProvider.d.ts +4 -3
  195. package/lib/esm/SchemaFormatsProvider.d.ts.map +1 -1
  196. package/lib/esm/SchemaFormatsProvider.js +61 -18
  197. package/lib/esm/SchemaFormatsProvider.js.map +1 -1
  198. package/lib/esm/SchemaLoader.d.ts +4 -1
  199. package/lib/esm/SchemaLoader.d.ts.map +1 -1
  200. package/lib/esm/SchemaLoader.js +4 -1
  201. package/lib/esm/SchemaLoader.js.map +1 -1
  202. package/lib/esm/ecschema-metadata.d.ts +2 -0
  203. package/lib/esm/ecschema-metadata.d.ts.map +1 -1
  204. package/lib/esm/ecschema-metadata.js +2 -0
  205. package/lib/esm/ecschema-metadata.js.map +1 -1
  206. package/lib/esm/utils/SchemaLoadingController.d.ts +37 -0
  207. package/lib/esm/utils/SchemaLoadingController.d.ts.map +1 -0
  208. package/lib/esm/utils/SchemaLoadingController.js +61 -0
  209. package/lib/esm/utils/SchemaLoadingController.js.map +1 -0
  210. package/package.json +15 -10
@@ -36,8 +36,11 @@ export class SchemaReadHelper {
36
36
  * calling getCachedSchema on the context.
37
37
  * @param schema The Schema to populate
38
38
  * @param rawSchema The serialized data to use to populate the Schema.
39
+ * @param addSchemaToCache Optional parameter that indicates if the schema should be added to the SchemaContext.
40
+ * The default is true. If false, the schema loading will not begin asynchronously in the background because the
41
+ * schema promise must be added to the context. In this case, only the SchemaInfo is returned.
39
42
  */
40
- async readSchemaInfo(schema, rawSchema) {
43
+ async readSchemaInfo(schema, rawSchema, addSchemaToCache = true) {
41
44
  // Ensure context matches schema context
42
45
  if (schema.context) {
43
46
  if (this._context !== schema.context)
@@ -50,15 +53,15 @@ export class SchemaReadHelper {
50
53
  // Loads all of the properties on the Schema object
51
54
  await schema.fromJSON(this._parser.parseSchema());
52
55
  this._schema = schema;
53
- const schemaInfoReferences = [];
54
- const schemaInfo = { schemaKey: schema.schemaKey, alias: schema.alias, references: schemaInfoReferences };
56
+ const schemaReferences = [];
57
+ const schemaInfo = { schemaKey: schema.schemaKey, alias: schema.alias, references: schemaReferences };
55
58
  for (const reference of this._parser.getReferences()) {
56
59
  const refKey = new SchemaKey(reference.name, ECVersion.fromString(reference.version));
57
- schemaInfoReferences.push({ schemaKey: refKey });
60
+ schemaReferences.push({ schemaKey: refKey });
58
61
  }
59
62
  this._schemaInfo = schemaInfo;
60
63
  // Need to add this schema to the context to be able to locate schemaItems within the context.
61
- if (!this._context.schemaExists(schema.schemaKey)) {
64
+ if (addSchemaToCache && !this._context.schemaExists(schema.schemaKey)) {
62
65
  await this._context.addSchemaPromise(schemaInfo, schema, this.loadSchema(schemaInfo, schema));
63
66
  }
64
67
  return schemaInfo;
@@ -67,33 +70,53 @@ export class SchemaReadHelper {
67
70
  * Populates the given Schema from a serialized representation.
68
71
  * @param schema The Schema to populate
69
72
  * @param rawSchema The serialized data to use to populate the Schema.
73
+ * @param addSchemaToCache Optional parameter that indicates if the schema should be added to the SchemaContext.
74
+ * The default is true. If false, the schema will be loaded directly by this method and not from the context's schema cache.
70
75
  */
71
- async readSchema(schema, rawSchema) {
76
+ async readSchema(schema, rawSchema, addSchemaToCache = true) {
72
77
  if (!this._schemaInfo) {
73
- await this.readSchemaInfo(schema, rawSchema);
78
+ await this.readSchemaInfo(schema, rawSchema, addSchemaToCache);
79
+ }
80
+ // If not adding schema to cache (occurs in readSchemaInfo), we must load the schema here
81
+ if (!addSchemaToCache) {
82
+ const loadedSchema = await this.loadSchema(this._schemaInfo, schema);
83
+ if (undefined === loadedSchema)
84
+ throw new ECSchemaError(ECSchemaStatus.UnableToLoadSchema, `Could not load schema ${schema.schemaKey.toString()}`);
85
+ return loadedSchema;
74
86
  }
75
87
  const cachedSchema = await this._context.getCachedSchema(this._schemaInfo.schemaKey, SchemaMatchType.Latest);
76
88
  if (undefined === cachedSchema)
77
89
  throw new ECSchemaError(ECSchemaStatus.UnableToLoadSchema, `Could not load schema ${schema.schemaKey.toString()}`);
78
90
  return cachedSchema;
79
91
  }
92
+ /**
93
+ * Called when a SchemaItem has been successfully loaded by the Helper. The default implementation simply
94
+ * checks if the schema item is undefined. An implementation of the helper may choose to partially load
95
+ * a schema item in which case this method would indicate if the item has been fully loaded.
96
+ * @param schemaItem The SchemaItem to check.
97
+ * @returns True if the SchemaItem has been fully loaded, false otherwise.
98
+ */
99
+ isSchemaItemLoaded(schemaItem) {
100
+ return schemaItem !== undefined;
101
+ }
80
102
  /* Finish loading the rest of the schema */
81
103
  async loadSchema(schemaInfo, schema) {
82
104
  // Verify that there are no schema reference cycles, this will start schema loading by loading their headers
83
105
  (await SchemaGraph.generateGraph(schemaInfo, this._context)).throwIfCycles();
84
106
  for (const reference of schemaInfo.references) {
85
- await this.loadSchemaReference(schemaInfo, reference.schemaKey);
107
+ await this.loadSchemaReference(schema, reference.schemaKey);
86
108
  }
87
109
  if (this._visitorHelper)
88
110
  await this._visitorHelper.visitSchema(schema, false);
89
111
  // Load all schema items
90
112
  for (const [itemName, itemType, rawItem] of this._parser.getItems()) {
91
- // Make sure the item has not already been read. No need to check the SchemaContext because all SchemaItems are added to a Schema,
113
+ // Make sure the item has not already been loaded. No need to check the SchemaContext because all SchemaItems are added to a Schema,
92
114
  // which would be found when adding to the context.
93
- if (await schema.getItem(itemName) !== undefined)
115
+ const schemaItem = await schema.getItem(itemName);
116
+ if (this.isSchemaItemLoaded(schemaItem))
94
117
  continue;
95
118
  const loadedItem = await this.loadSchemaItem(schema, itemName, itemType, rawItem);
96
- if (loadedItem && this._visitorHelper) {
119
+ if (this.isSchemaItemLoaded(loadedItem) && this._visitorHelper) {
97
120
  await this._visitorHelper.visitSchemaPart(loadedItem);
98
121
  }
99
122
  }
@@ -124,12 +147,8 @@ export class SchemaReadHelper {
124
147
  this._visitorHelper.visitSchemaSync(schema, false);
125
148
  // Load all schema items
126
149
  for (const [itemName, itemType, rawItem] of this._parser.getItems()) {
127
- // Make sure the item has not already been read. No need to check the SchemaContext because all SchemaItems are added to a Schema,
128
- // which would be found when adding to the context.
129
- if (schema.getItemSync(itemName) !== undefined)
130
- continue;
131
150
  const loadedItem = this.loadSchemaItemSync(schema, itemName, itemType, rawItem);
132
- if (loadedItem && this._visitorHelper) {
151
+ if (this.isSchemaItemLoaded(loadedItem) && this._visitorHelper) {
133
152
  this._visitorHelper.visitSchemaPartSync(loadedItem);
134
153
  }
135
154
  }
@@ -142,12 +161,14 @@ export class SchemaReadHelper {
142
161
  * Ensures that the schema references can be located and adds them to the schema.
143
162
  * @param ref The object to read the SchemaReference's props from.
144
163
  */
145
- async loadSchemaReference(schemaInfo, refKey) {
164
+ async loadSchemaReference(schema, refKey) {
146
165
  const refSchema = await this._context.getSchema(refKey, SchemaMatchType.LatestWriteCompatible);
147
166
  if (undefined === refSchema)
148
- throw new ECSchemaError(ECSchemaStatus.UnableToLocateSchema, `Could not locate the referenced schema, ${refKey.name}.${refKey.version.toString()}, of ${schemaInfo.schemaKey.name}`);
149
- await this._schema.addReference(refSchema);
150
- const results = this.validateSchemaReferences(this._schema);
167
+ throw new ECSchemaError(ECSchemaStatus.UnableToLocateSchema, `Could not locate the referenced schema, ${refKey.name}.${refKey.version.toString()}, of ${schema.schemaKey.name}`);
168
+ if (schema.references.find((ref) => ref.schemaKey.matches(refSchema.schemaKey)))
169
+ return refSchema;
170
+ await schema.addReference(refSchema);
171
+ const results = this.validateSchemaReferences(schema);
151
172
  let errorMessage = "";
152
173
  for (const result of results) {
153
174
  errorMessage += `${result}\r\n`;
@@ -155,6 +176,7 @@ export class SchemaReadHelper {
155
176
  if (errorMessage) {
156
177
  throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `${errorMessage}`);
157
178
  }
179
+ return refSchema;
158
180
  }
159
181
  /**
160
182
  * Ensures that the schema references can be located and adds them to the schema.
@@ -204,73 +226,97 @@ export class SchemaReadHelper {
204
226
  * @param schemaItemObject The Object to populate the SchemaItem with.
205
227
  */
206
228
  async loadSchemaItem(schema, name, itemType, schemaItemObject) {
207
- let schemaItem;
229
+ let schemaItem = await schema.getItem(name);
230
+ if (this.isSchemaItemLoaded(schemaItem)) {
231
+ return schemaItem;
232
+ }
208
233
  switch (parseSchemaItemType(itemType)) {
209
234
  case SchemaItemType.EntityClass:
210
- schemaItem = await schema.createEntityClass(name);
211
- await this.loadEntityClass(schemaItem, schemaItemObject);
235
+ schemaItem = schemaItem || await schema.createEntityClass(name);
236
+ schemaItemObject && await this.loadEntityClass(schemaItem, schemaItemObject);
212
237
  break;
213
238
  case SchemaItemType.StructClass:
214
- schemaItem = await schema.createStructClass(name);
215
- const structProps = this._parser.parseStructClass(schemaItemObject);
216
- await this.loadClass(schemaItem, structProps, schemaItemObject);
239
+ schemaItem = schemaItem || await schema.createStructClass(name);
240
+ const structProps = schemaItemObject && this._parser.parseStructClass(schemaItemObject);
241
+ structProps && await this.loadClass(schemaItem, structProps, schemaItemObject);
217
242
  break;
218
243
  case SchemaItemType.Mixin:
219
- schemaItem = await schema.createMixinClass(name);
220
- await this.loadMixin(schemaItem, schemaItemObject);
244
+ schemaItem = schemaItem || await schema.createMixinClass(name);
245
+ schemaItemObject && await this.loadMixin(schemaItem, schemaItemObject);
221
246
  break;
222
247
  case SchemaItemType.CustomAttributeClass:
223
- schemaItem = await schema.createCustomAttributeClass(name);
224
- const caClassProps = this._parser.parseCustomAttributeClass(schemaItemObject);
225
- await this.loadClass(schemaItem, caClassProps, schemaItemObject);
248
+ schemaItem = schemaItem || await schema.createCustomAttributeClass(name);
249
+ const caClassProps = schemaItemObject && this._parser.parseCustomAttributeClass(schemaItemObject);
250
+ caClassProps && await this.loadClass(schemaItem, caClassProps, schemaItemObject);
226
251
  break;
227
252
  case SchemaItemType.RelationshipClass:
228
- schemaItem = await schema.createRelationshipClass(name);
229
- await this.loadRelationshipClass(schemaItem, schemaItemObject);
253
+ schemaItem = schemaItem || await schema.createRelationshipClass(name);
254
+ schemaItemObject && await this.loadRelationshipClass(schemaItem, schemaItemObject);
230
255
  break;
231
256
  case SchemaItemType.KindOfQuantity:
232
- schemaItem = await schema.createKindOfQuantity(name);
233
- await this.loadKindOfQuantity(schemaItem, schemaItemObject);
257
+ schemaItem = schemaItem || await schema.createKindOfQuantity(name);
258
+ schemaItemObject && await this.loadKindOfQuantity(schemaItem, schemaItemObject);
234
259
  break;
235
260
  case SchemaItemType.Unit:
236
- schemaItem = await schema.createUnit(name);
237
- await this.loadUnit(schemaItem, schemaItemObject);
261
+ schemaItem = schemaItem || await schema.createUnit(name);
262
+ schemaItemObject && await this.loadUnit(schemaItem, schemaItemObject);
238
263
  break;
239
264
  case SchemaItemType.Constant:
240
- schemaItem = await schema.createConstant(name);
241
- await this.loadConstant(schemaItem, schemaItemObject);
265
+ schemaItem = schemaItem || await schema.createConstant(name);
266
+ schemaItemObject && await this.loadConstant(schemaItem, schemaItemObject);
242
267
  break;
243
268
  case SchemaItemType.InvertedUnit:
244
- schemaItem = await schema.createInvertedUnit(name);
245
- await this.loadInvertedUnit(schemaItem, schemaItemObject);
269
+ schemaItem = schemaItem || await schema.createInvertedUnit(name);
270
+ schemaItemObject && await this.loadInvertedUnit(schemaItem, schemaItemObject);
246
271
  break;
247
272
  case SchemaItemType.Format:
248
- schemaItem = await schema.createFormat(name);
249
- await this.loadFormat(schemaItem, schemaItemObject);
273
+ schemaItem = schemaItem || await schema.createFormat(name);
274
+ schemaItemObject && await this.loadFormat(schemaItem, schemaItemObject);
250
275
  break;
251
276
  case SchemaItemType.Phenomenon:
252
- schemaItem = await schema.createPhenomenon(name);
253
- const phenomenonProps = this._parser.parsePhenomenon(schemaItemObject);
254
- await schemaItem.fromJSON(phenomenonProps);
277
+ schemaItem = schemaItem || await schema.createPhenomenon(name);
278
+ const phenomenonProps = schemaItemObject && this._parser.parsePhenomenon(schemaItemObject);
279
+ phenomenonProps && await schemaItem.fromJSON(phenomenonProps);
255
280
  break;
256
281
  case SchemaItemType.UnitSystem:
257
- schemaItem = await schema.createUnitSystem(name);
258
- await schemaItem.fromJSON(this._parser.parseUnitSystem(schemaItemObject));
282
+ schemaItem = schemaItem || await schema.createUnitSystem(name);
283
+ schemaItemObject && await schemaItem.fromJSON(this._parser.parseUnitSystem(schemaItemObject));
259
284
  break;
260
285
  case SchemaItemType.PropertyCategory:
261
- schemaItem = await schema.createPropertyCategory(name);
262
- const propertyCategoryProps = this._parser.parsePropertyCategory(schemaItemObject);
263
- await schemaItem.fromJSON(propertyCategoryProps);
286
+ schemaItem = schemaItem || await schema.createPropertyCategory(name);
287
+ const propertyCategoryProps = schemaItemObject && this._parser.parsePropertyCategory(schemaItemObject);
288
+ propertyCategoryProps && schemaItemObject && await schemaItem.fromJSON(propertyCategoryProps);
264
289
  break;
265
290
  case SchemaItemType.Enumeration:
266
- schemaItem = await schema.createEnumeration(name);
267
- const enumerationProps = this._parser.parseEnumeration(schemaItemObject);
268
- await schemaItem.fromJSON(enumerationProps);
291
+ schemaItem = schemaItem || await schema.createEnumeration(name);
292
+ const enumerationProps = schemaItemObject && this._parser.parseEnumeration(schemaItemObject);
293
+ enumerationProps && await schemaItem.fromJSON(enumerationProps);
269
294
  break;
270
295
  // 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
271
296
  }
272
297
  return schemaItem;
273
298
  }
299
+ /**
300
+ * Load the customAttribute class dependencies for a set of CustomAttribute objects and add
301
+ * them to a given custom attribute container.
302
+ * @param container The CustomAttributeContainer that each CustomAttribute will be added to.
303
+ * @param customAttributes An iterable set of parsed CustomAttribute objects.
304
+ */
305
+ async loadCustomAttributes(container, caProviders) {
306
+ for (const providerTuple of caProviders) {
307
+ // First tuple entry is the CA class name.
308
+ const caClass = await this.findSchemaItem(providerTuple[0]);
309
+ // If custom attribute exist within the context and is referenced, validate the reference is defined in the container's schema
310
+ if (caClass && caClass.key.schemaName !== container.schema.name &&
311
+ !container.schema.getReferenceSync(caClass.key.schemaName)) {
312
+ throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `Unable to load custom attribute ${caClass.fullName} from container ${container.fullName}, ${caClass.key.schemaName} reference not defined`);
313
+ }
314
+ // Second tuple entry ia a function that provides the CA instance.
315
+ const provider = providerTuple[1];
316
+ const customAttribute = provider(caClass);
317
+ container.addCustomAttribute(customAttribute);
318
+ }
319
+ }
274
320
  /**
275
321
  * Given the schema item object, the anticipated type and the name a schema item is created and loaded into the schema provided.
276
322
  * @param schema The Schema the SchemaItem to.
@@ -279,66 +325,69 @@ export class SchemaReadHelper {
279
325
  * @param schemaItemObject The Object to populate the SchemaItem with.
280
326
  */
281
327
  loadSchemaItemSync(schema, name, itemType, schemaItemObject) {
282
- let schemaItem;
328
+ let schemaItem = schema.getItemSync(name);
329
+ if (this.isSchemaItemLoaded(schemaItem)) {
330
+ return schemaItem;
331
+ }
283
332
  switch (parseSchemaItemType(itemType)) {
284
333
  case SchemaItemType.EntityClass:
285
- schemaItem = schema.createEntityClassSync(name);
334
+ schemaItem = schemaItem || schema.createEntityClassSync(name);
286
335
  this.loadEntityClassSync(schemaItem, schemaItemObject);
287
336
  break;
288
337
  case SchemaItemType.StructClass:
289
- schemaItem = schema.createStructClassSync(name);
338
+ schemaItem = schemaItem || schema.createStructClassSync(name);
290
339
  const structProps = this._parser.parseStructClass(schemaItemObject);
291
340
  this.loadClassSync(schemaItem, structProps, schemaItemObject);
292
341
  break;
293
342
  case SchemaItemType.Mixin:
294
- schemaItem = schema.createMixinClassSync(name);
343
+ schemaItem = schemaItem || schema.createMixinClassSync(name);
295
344
  this.loadMixinSync(schemaItem, schemaItemObject);
296
345
  break;
297
346
  case SchemaItemType.CustomAttributeClass:
298
- schemaItem = schema.createCustomAttributeClassSync(name);
347
+ schemaItem = schemaItem || schema.createCustomAttributeClassSync(name);
299
348
  const caClassProps = this._parser.parseCustomAttributeClass(schemaItemObject);
300
349
  this.loadClassSync(schemaItem, caClassProps, schemaItemObject);
301
350
  break;
302
351
  case SchemaItemType.RelationshipClass:
303
- schemaItem = schema.createRelationshipClassSync(name);
352
+ schemaItem = schemaItem || schema.createRelationshipClassSync(name);
304
353
  this.loadRelationshipClassSync(schemaItem, schemaItemObject);
305
354
  break;
306
355
  case SchemaItemType.KindOfQuantity:
307
- schemaItem = schema.createKindOfQuantitySync(name);
356
+ schemaItem = schemaItem || schema.createKindOfQuantitySync(name);
308
357
  this.loadKindOfQuantitySync(schemaItem, schemaItemObject);
309
358
  break;
310
359
  case SchemaItemType.Unit:
311
- schemaItem = schema.createUnitSync(name);
360
+ schemaItem = schemaItem || schema.createUnitSync(name);
312
361
  this.loadUnitSync(schemaItem, schemaItemObject);
313
362
  break;
314
363
  case SchemaItemType.Constant:
315
- schemaItem = schema.createConstantSync(name);
364
+ schemaItem = schemaItem || schema.createConstantSync(name);
316
365
  this.loadConstantSync(schemaItem, schemaItemObject);
317
366
  break;
318
367
  case SchemaItemType.InvertedUnit:
319
- schemaItem = schema.createInvertedUnitSync(name);
368
+ schemaItem = schemaItem || schema.createInvertedUnitSync(name);
320
369
  this.loadInvertedUnitSync(schemaItem, schemaItemObject);
321
370
  break;
322
371
  case SchemaItemType.Format:
323
- schemaItem = schema.createFormatSync(name);
372
+ schemaItem = schemaItem || schema.createFormatSync(name);
324
373
  this.loadFormatSync(schemaItem, schemaItemObject);
325
374
  break;
326
375
  case SchemaItemType.Phenomenon:
327
- schemaItem = schema.createPhenomenonSync(name);
376
+ schemaItem = schemaItem || schema.createPhenomenonSync(name);
328
377
  const phenomenonProps = this._parser.parsePhenomenon(schemaItemObject);
329
378
  schemaItem.fromJSONSync(phenomenonProps);
330
379
  break;
331
380
  case SchemaItemType.UnitSystem:
332
- schemaItem = schema.createUnitSystemSync(name);
381
+ schemaItem = schemaItem || schema.createUnitSystemSync(name);
333
382
  schemaItem.fromJSONSync(this._parser.parseUnitSystem(schemaItemObject));
334
383
  break;
335
384
  case SchemaItemType.PropertyCategory:
336
- schemaItem = schema.createPropertyCategorySync(name);
385
+ schemaItem = schemaItem || schema.createPropertyCategorySync(name);
337
386
  const propertyCategoryProps = this._parser.parsePropertyCategory(schemaItemObject);
338
387
  schemaItem.fromJSONSync(propertyCategoryProps);
339
388
  break;
340
389
  case SchemaItemType.Enumeration:
341
- schemaItem = schema.createEnumerationSync(name);
390
+ schemaItem = schemaItem || schema.createEnumerationSync(name);
342
391
  const enumerationProps = this._parser.parseEnumeration(schemaItemObject);
343
392
  schemaItem.fromJSONSync(enumerationProps);
344
393
  break;
@@ -386,7 +435,7 @@ export class SchemaReadHelper {
386
435
  const foundItem = this._parser.findItem(itemName);
387
436
  if (foundItem) {
388
437
  schemaItem = await this.loadSchemaItem(this._schema, ...foundItem);
389
- if (!skipVisitor && schemaItem && this._visitorHelper) {
438
+ if (!skipVisitor && this.isSchemaItemLoaded(schemaItem) && this._visitorHelper) {
390
439
  await this._visitorHelper.visitSchemaPart(schemaItem);
391
440
  }
392
441
  if (loadCallBack && schemaItem)
@@ -419,7 +468,7 @@ export class SchemaReadHelper {
419
468
  const foundItem = this._parser.findItem(itemName);
420
469
  if (foundItem) {
421
470
  schemaItem = this.loadSchemaItemSync(this._schema, ...foundItem);
422
- if (!skipVisitor && schemaItem && this._visitorHelper) {
471
+ if (!skipVisitor && this.isSchemaItemLoaded(schemaItem) && this._visitorHelper) {
423
472
  this._visitorHelper.visitSchemaPartSync(schemaItem);
424
473
  }
425
474
  if (loadCallBack && schemaItem)
@@ -569,7 +618,7 @@ export class SchemaReadHelper {
569
618
  */
570
619
  async loadClass(classObj, classProps, rawClass) {
571
620
  const baseClassLoaded = async (baseClass) => {
572
- if (this._visitorHelper)
621
+ if (this._visitorHelper && this.isSchemaItemLoaded(baseClass))
573
622
  await this._visitorHelper.visitSchemaPart(baseClass);
574
623
  };
575
624
  // Load base class first
@@ -592,7 +641,7 @@ export class SchemaReadHelper {
592
641
  */
593
642
  loadClassSync(classObj, classProps, rawClass) {
594
643
  const baseClassLoaded = async (baseClass) => {
595
- if (this._visitorHelper)
644
+ if (this._visitorHelper && this.isSchemaItemLoaded(baseClass))
596
645
  this._visitorHelper.visitSchemaPartSync(baseClass);
597
646
  };
598
647
  // Load base class first
@@ -643,7 +692,7 @@ export class SchemaReadHelper {
643
692
  async loadMixin(mixin, rawMixin) {
644
693
  const mixinProps = this._parser.parseMixin(rawMixin);
645
694
  const appliesToLoaded = async (appliesToClass) => {
646
- if (this._visitorHelper)
695
+ if (this._visitorHelper && this.isSchemaItemLoaded(appliesToClass))
647
696
  await this._visitorHelper.visitSchemaPart(appliesToClass);
648
697
  };
649
698
  await this.findSchemaItem(mixinProps.appliesTo, true, appliesToLoaded);
@@ -657,7 +706,7 @@ export class SchemaReadHelper {
657
706
  loadMixinSync(mixin, rawMixin) {
658
707
  const mixinProps = this._parser.parseMixin(rawMixin);
659
708
  const appliesToLoaded = async (appliesToClass) => {
660
- if (this._visitorHelper)
709
+ if (this._visitorHelper && this.isSchemaItemLoaded(appliesToClass))
661
710
  await this._visitorHelper.visitSchemaPart(appliesToClass);
662
711
  };
663
712
  this.findSchemaItemSync(mixinProps.appliesTo, true, appliesToLoaded);
@@ -853,27 +902,6 @@ export class SchemaReadHelper {
853
902
  propertyObj.fromJSONSync(props);
854
903
  this.loadCustomAttributesSync(propertyObj, this._parser.getPropertyCustomAttributeProviders(rawProperty));
855
904
  }
856
- /**
857
- * Load the customAttribute class dependencies for a set of CustomAttribute objects and add
858
- * them to a given custom attribute container.
859
- * @param container The CustomAttributeContainer that each CustomAttribute will be added to.
860
- * @param customAttributes An iterable set of parsed CustomAttribute objects.
861
- */
862
- async loadCustomAttributes(container, caProviders) {
863
- for (const providerTuple of caProviders) {
864
- // First tuple entry is the CA class name.
865
- const caClass = await this.findSchemaItem(providerTuple[0]);
866
- // If custom attribute exist within the context and is referenced, validate the reference is defined in the container's schema
867
- if (caClass && caClass.key.schemaName !== container.schema.name &&
868
- !container.schema.getReferenceSync(caClass.key.schemaName)) {
869
- throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `Unable to load custom attribute ${caClass.fullName} from container ${container.fullName}, ${caClass.key.schemaName} reference not defined`);
870
- }
871
- // Second tuple entry ia a function that provides the CA instance.
872
- const provider = providerTuple[1];
873
- const customAttribute = provider(caClass);
874
- container.addCustomAttribute(customAttribute);
875
- }
876
- }
877
905
  /**
878
906
  * Load the customAttribute class dependencies for a set of CustomAttribute objects and add them to a given custom attribute container.
879
907
  * @param container The CustomAttributeContainer that each CustomAttribute will be added to.