@itwin/ecschema-editing 4.5.0-dev.30 → 4.5.0-dev.32

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 (83) hide show
  1. package/lib/cjs/Differencing/SchemaConflicts.d.ts +76 -0
  2. package/lib/cjs/Differencing/SchemaConflicts.d.ts.map +1 -0
  3. package/lib/cjs/Differencing/SchemaConflicts.js +56 -0
  4. package/lib/cjs/Differencing/SchemaConflicts.js.map +1 -0
  5. package/lib/cjs/Differencing/SchemaDiagnosticVisitor.d.ts +43 -0
  6. package/lib/cjs/Differencing/SchemaDiagnosticVisitor.d.ts.map +1 -0
  7. package/lib/cjs/Differencing/SchemaDiagnosticVisitor.js +501 -0
  8. package/lib/cjs/Differencing/SchemaDiagnosticVisitor.js.map +1 -0
  9. package/lib/cjs/Differencing/SchemaDifference.d.ts +150 -0
  10. package/lib/cjs/Differencing/SchemaDifference.d.ts.map +1 -0
  11. package/lib/cjs/Differencing/SchemaDifference.js +54 -0
  12. package/lib/cjs/Differencing/SchemaDifference.js.map +1 -0
  13. package/lib/cjs/Editing/Constants.js.map +1 -1
  14. package/lib/cjs/Editing/CustomAttributes.js.map +1 -1
  15. package/lib/cjs/Editing/ECClasses.js.map +1 -1
  16. package/lib/cjs/Editing/Editor.js.map +1 -1
  17. package/lib/cjs/Editing/Entities.js.map +1 -1
  18. package/lib/cjs/Editing/Enumerations.js.map +1 -1
  19. package/lib/cjs/Editing/Formats.js.map +1 -1
  20. package/lib/cjs/Editing/InvertedUnits.js.map +1 -1
  21. package/lib/cjs/Editing/KindOfQuantities.js.map +1 -1
  22. package/lib/cjs/Editing/Mixins.js.map +1 -1
  23. package/lib/cjs/Editing/Mutable/MutableArrayProperty.js.map +1 -1
  24. package/lib/cjs/Editing/Mutable/MutableCAClass.js.map +1 -1
  25. package/lib/cjs/Editing/Mutable/MutableClass.js.map +1 -1
  26. package/lib/cjs/Editing/Mutable/MutableConstant.js.map +1 -1
  27. package/lib/cjs/Editing/Mutable/MutableEntityClass.js.map +1 -1
  28. package/lib/cjs/Editing/Mutable/MutableEnumeration.js.map +1 -1
  29. package/lib/cjs/Editing/Mutable/MutableFormat.js.map +1 -1
  30. package/lib/cjs/Editing/Mutable/MutableInvertedUnit.js.map +1 -1
  31. package/lib/cjs/Editing/Mutable/MutableKindOfQuantity.js.map +1 -1
  32. package/lib/cjs/Editing/Mutable/MutableMixin.js.map +1 -1
  33. package/lib/cjs/Editing/Mutable/MutablePhenomenon.js.map +1 -1
  34. package/lib/cjs/Editing/Mutable/MutablePrimitiveOrEnumProperty.js.map +1 -1
  35. package/lib/cjs/Editing/Mutable/MutableProperty.js.map +1 -1
  36. package/lib/cjs/Editing/Mutable/MutablePropertyCategory.js.map +1 -1
  37. package/lib/cjs/Editing/Mutable/MutableRelationshipClass.js.map +1 -1
  38. package/lib/cjs/Editing/Mutable/MutableSchema.js.map +1 -1
  39. package/lib/cjs/Editing/Mutable/MutableUnit.js.map +1 -1
  40. package/lib/cjs/Editing/Mutable/MutableUnitSystem.js.map +1 -1
  41. package/lib/cjs/Editing/Phenomena.js.map +1 -1
  42. package/lib/cjs/Editing/PropertyCategories.js.map +1 -1
  43. package/lib/cjs/Editing/RelationshipClasses.js.map +1 -1
  44. package/lib/cjs/Editing/SchemaItems.js.map +1 -1
  45. package/lib/cjs/Editing/Structs.js.map +1 -1
  46. package/lib/cjs/Editing/UnitSystems.js.map +1 -1
  47. package/lib/cjs/Editing/Units.js.map +1 -1
  48. package/lib/cjs/Merging/CAClassMerger.js.map +1 -1
  49. package/lib/cjs/Merging/ClassMerger.js.map +1 -1
  50. package/lib/cjs/Merging/ConstantMerger.js.map +1 -1
  51. package/lib/cjs/Merging/CustomAttributeMerger.js.map +1 -1
  52. package/lib/cjs/Merging/EntityClassMerger.js.map +1 -1
  53. package/lib/cjs/Merging/EnumerationMerger.js.map +1 -1
  54. package/lib/cjs/Merging/KindOfQuantityMerger.js.map +1 -1
  55. package/lib/cjs/Merging/MixinMerger.js.map +1 -1
  56. package/lib/cjs/Merging/PropertyMerger.js.map +1 -1
  57. package/lib/cjs/Merging/RelationshipClassMerger.js.map +1 -1
  58. package/lib/cjs/Merging/SchemaItemFactory.js.map +1 -1
  59. package/lib/cjs/Merging/SchemaItemMerger.js.map +1 -1
  60. package/lib/cjs/Merging/SchemaMerger.js.map +1 -1
  61. package/lib/cjs/Merging/SchemaReferenceMerger.js.map +1 -1
  62. package/lib/cjs/Merging/StructClassMerger.js.map +1 -1
  63. package/lib/cjs/Validation/Diagnostic.js.map +1 -1
  64. package/lib/cjs/Validation/DiagnosticReporter.js.map +1 -1
  65. package/lib/cjs/Validation/ECRules.js.map +1 -1
  66. package/lib/cjs/Validation/LoggingDiagnosticReporter.js.map +1 -1
  67. package/lib/cjs/Validation/RuleSuppressionSet.js.map +1 -1
  68. package/lib/cjs/Validation/Rules.js.map +1 -1
  69. package/lib/cjs/Validation/SchemaChanges.js.map +1 -1
  70. package/lib/cjs/Validation/SchemaCompareDiagnostics.js.map +1 -1
  71. package/lib/cjs/Validation/SchemaCompareReporter.js.map +1 -1
  72. package/lib/cjs/Validation/SchemaCompareResultDelegate.js.map +1 -1
  73. package/lib/cjs/Validation/SchemaCompareVisitor.js.map +1 -1
  74. package/lib/cjs/Validation/SchemaComparer.js.map +1 -1
  75. package/lib/cjs/Validation/SchemaValidater.js.map +1 -1
  76. package/lib/cjs/Validation/SchemaValidationVisitor.js.map +1 -1
  77. package/lib/cjs/Validation/SchemaWalker.js.map +1 -1
  78. package/lib/cjs/ecschema-editing.d.ts +4 -0
  79. package/lib/cjs/ecschema-editing.d.ts.map +1 -1
  80. package/lib/cjs/ecschema-editing.js +4 -0
  81. package/lib/cjs/ecschema-editing.js.map +1 -1
  82. package/package.json +9 -9
  83. package/public/locales/en/ECSchemaEditing.json +26 -26
@@ -0,0 +1,501 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Differencing
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.SchemaDiagnosticVisitor = void 0;
11
+ const SchemaCompareDiagnostics_1 = require("../Validation/SchemaCompareDiagnostics");
12
+ const ecschema_metadata_1 = require("@itwin/ecschema-metadata");
13
+ const SchemaConflicts_1 = require("./SchemaConflicts");
14
+ /**
15
+ * Recursive syncronous function to figure whether a given class derived from
16
+ * a class with the given baseClassName.
17
+ */
18
+ function derivedFrom(ecClass, baseClassName) {
19
+ if (ecClass === undefined) {
20
+ return false;
21
+ }
22
+ if (ecClass && ecClass.name === baseClassName) {
23
+ return true;
24
+ }
25
+ return derivedFrom(ecClass.getBaseClassSync(), baseClassName);
26
+ }
27
+ /**
28
+ * The SchemaDiagnosticVisitor is a visitor implementation for diagnostic entries
29
+ * from the schema comparer api. Depending on the diagnostic code, the difference
30
+ * result is build together.
31
+ * @internal
32
+ */
33
+ class SchemaDiagnosticVisitor {
34
+ constructor(differenceReport) {
35
+ this._differenceReport = differenceReport;
36
+ }
37
+ addEntry(entry) {
38
+ this._differenceReport.changes.push(entry);
39
+ return entry;
40
+ }
41
+ lookupEntry(changeType, args) {
42
+ return this._differenceReport.changes && this._differenceReport.changes.find((change) => {
43
+ return (change.changeType === changeType)
44
+ && (!args.schemaType || change.schemaType === args.schemaType)
45
+ && (!args.itemName || change.itemName === args.itemName)
46
+ && change.path === args.path;
47
+ });
48
+ }
49
+ addConflict(conflict) {
50
+ this._differenceReport.conflicts.push(conflict);
51
+ }
52
+ /**
53
+ * Visitor function to process the schema change diagnostic object.
54
+ * @internal
55
+ */
56
+ visit(diagnostic) {
57
+ switch (diagnostic.code) {
58
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.SchemaDelta:
59
+ return this.visitChangedSchemaProperties(diagnostic);
60
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.SchemaReferenceMissing:
61
+ return this.visitSchemaReference(diagnostic, "add");
62
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.SchemaReferenceDelta:
63
+ return this.visitSchemaReference(diagnostic, "modify");
64
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.SchemaItemMissing:
65
+ return this.visitMissingSchemaItem(diagnostic);
66
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.SchemaItemDelta:
67
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.ClassDelta:
68
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.ConstantDelta:
69
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.CustomAttributeClassDelta:
70
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.FormatDelta:
71
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.InvertedUnitDelta:
72
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.KoqDelta:
73
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.MixinDelta:
74
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.PhenomenonDelta:
75
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.PropertyCategoryDelta:
76
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.RelationshipDelta:
77
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.UnitDelta:
78
+ return this.visitChangedSchemaItem(diagnostic);
79
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.EnumerationDelta:
80
+ return this.visitChangedEnumeration(diagnostic);
81
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.EnumeratorDelta:
82
+ return this.visitChangedEnumerator(diagnostic);
83
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.EnumeratorMissing:
84
+ return this.visitMissingEnumerator(diagnostic);
85
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.BaseClassDelta:
86
+ return this.visitMissingBaseClass(diagnostic);
87
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.EntityMixinMissing:
88
+ return this.visitMissingMixinOnClass(diagnostic);
89
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.PropertyDelta:
90
+ return this.visitChangedProperty(diagnostic);
91
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.PropertyMissing:
92
+ return this.visitMissingProperty(diagnostic);
93
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.RelationshipConstraintClassMissing:
94
+ return this.visitMissingRelationshipConstraintClass(diagnostic);
95
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.RelationshipConstraintDelta:
96
+ return this.visitChangedRelationshipConstraint(diagnostic);
97
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.CustomAttributeInstanceClassMissing:
98
+ return this.visitMissingCustomAttributeInstance(diagnostic);
99
+ // Currently not handled...
100
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.FormatUnitMissing:
101
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.PresentationUnitMissing:
102
+ case SchemaCompareDiagnostics_1.SchemaCompareCodes.UnitLabelOverrideDelta:
103
+ break;
104
+ }
105
+ return;
106
+ }
107
+ visitChangedSchemaProperties(diagnostic) {
108
+ let modifyEntry = this.lookupEntry("modify", { schemaType: "Schema" });
109
+ let hasChanges = false;
110
+ const existsAlready = modifyEntry !== undefined;
111
+ if (!existsAlready) {
112
+ modifyEntry = {
113
+ changeType: "modify",
114
+ schemaType: "Schema",
115
+ json: {},
116
+ };
117
+ }
118
+ // Only label and description are taken from the source schema. If the schema name or alias
119
+ // differs, those are ignored for now.
120
+ const [propertyName, propertyValue] = diagnostic.messageArgs;
121
+ switch (propertyName) {
122
+ case "label":
123
+ modifyEntry.json.label = propertyValue;
124
+ hasChanges = true;
125
+ break;
126
+ case "description":
127
+ modifyEntry.json.description = propertyValue;
128
+ hasChanges = true;
129
+ break;
130
+ }
131
+ if (!existsAlready && hasChanges) {
132
+ this.addEntry(modifyEntry);
133
+ }
134
+ }
135
+ visitMissingSchemaItem(diagnostic) {
136
+ const schemaItem = diagnostic.ecDefinition;
137
+ this.addEntry({
138
+ changeType: "add",
139
+ schemaType: getSchemaItemName(schemaItem.schemaItemType),
140
+ itemName: schemaItem.name,
141
+ json: schemaItem.toJSON(),
142
+ });
143
+ }
144
+ visitChangedSchemaItem(diagnostic) {
145
+ const schemaItem = diagnostic.ecDefinition;
146
+ if (this.lookupEntry("add", { itemName: schemaItem.name })) {
147
+ return;
148
+ }
149
+ const [propertyName, sourceValue, targetValue] = diagnostic.messageArgs;
150
+ if (propertyName === "schemaItemType") {
151
+ return this.addConflict({
152
+ code: SchemaConflicts_1.ConflictCode.ConflictingItemName,
153
+ schemaType: getSchemaItemName(schemaItem.schemaItemType),
154
+ itemName: schemaItem.name,
155
+ source: sourceValue,
156
+ target: targetValue,
157
+ description: "Target schema already contains a schema item with the name but different type.",
158
+ });
159
+ }
160
+ if (sourceValue === undefined) {
161
+ return;
162
+ }
163
+ let modifyEntry = this.lookupEntry("modify", { itemName: schemaItem.name });
164
+ if (!modifyEntry) {
165
+ modifyEntry = this.addEntry({
166
+ changeType: "modify",
167
+ schemaType: getSchemaItemName(schemaItem.schemaItemType),
168
+ itemName: schemaItem.name,
169
+ json: {},
170
+ });
171
+ }
172
+ modifyEntry.json[propertyName] = sourceValue;
173
+ }
174
+ visitChangedEnumeration(diagnostic) {
175
+ const enumeration = diagnostic.ecDefinition;
176
+ if (this.lookupEntry("add", { itemName: enumeration.name })) {
177
+ return;
178
+ }
179
+ const [propertyName, sourceValue, targetValue] = diagnostic.messageArgs;
180
+ if (propertyName === "type") {
181
+ return this.addConflict({
182
+ code: SchemaConflicts_1.ConflictCode.ConflictingEnumerationType,
183
+ schemaType: getSchemaItemName(ecschema_metadata_1.SchemaItemType.Enumeration),
184
+ itemName: enumeration.name,
185
+ source: sourceValue,
186
+ target: targetValue,
187
+ description: "Enumeration has a different primitive type.",
188
+ });
189
+ }
190
+ return this.visitChangedSchemaItem(diagnostic);
191
+ }
192
+ visitMissingEnumerator(diagnostic) {
193
+ const enumeration = diagnostic.ecDefinition;
194
+ if (this.lookupEntry("add", { itemName: enumeration.name })) {
195
+ return;
196
+ }
197
+ const [enumerator] = diagnostic.messageArgs;
198
+ this.addEntry({
199
+ changeType: "add",
200
+ schemaType: "Enumeration",
201
+ itemName: enumeration.name,
202
+ path: "$enumerators",
203
+ json: enumerator,
204
+ });
205
+ }
206
+ lookupEnumeratorEntry(changeType, item, enumeratorName) {
207
+ return this._differenceReport.changes && this._differenceReport.changes.find((change) => {
208
+ return change.changeType === changeType
209
+ && change.schemaType === "Enumeration"
210
+ && change.itemName === item
211
+ && change.path === "$enumerators"
212
+ && change.json.name === enumeratorName;
213
+ });
214
+ }
215
+ visitChangedEnumerator(diagnostic) {
216
+ const enumeration = diagnostic.ecDefinition;
217
+ if (this.lookupEntry("add", { itemName: enumeration.name })) {
218
+ return;
219
+ }
220
+ const [enumerator, propertyName, sourceValue, targetValue] = diagnostic.messageArgs;
221
+ if (this.lookupEnumeratorEntry("add", enumeration.name, enumerator.name)) {
222
+ return;
223
+ }
224
+ if (!this.validateEnumerator(enumeration, enumerator, propertyName, sourceValue, targetValue)) {
225
+ return;
226
+ }
227
+ const enumeratorPath = `$enumerators.${enumerator.name}`;
228
+ let modifyEntry = this.lookupEntry("modify", { itemName: enumeration.name, path: enumeratorPath });
229
+ if (!modifyEntry) {
230
+ modifyEntry = this.addEntry({
231
+ changeType: "modify",
232
+ schemaType: "Enumeration",
233
+ itemName: enumeration.name,
234
+ path: enumeratorPath,
235
+ json: {},
236
+ });
237
+ }
238
+ if (sourceValue !== undefined) {
239
+ modifyEntry.json[propertyName] = sourceValue;
240
+ }
241
+ }
242
+ validateEnumerator(enumeration, enumerator, propertyName, sourceValue, targetValue) {
243
+ if (propertyName === "value") {
244
+ this.addConflict({
245
+ code: SchemaConflicts_1.ConflictCode.ConflictingEnumeratorValue,
246
+ schemaType: getSchemaItemName(ecschema_metadata_1.SchemaItemType.Enumeration),
247
+ itemName: enumeration.name,
248
+ path: enumerator.name,
249
+ source: sourceValue,
250
+ target: targetValue,
251
+ description: "Enumerator values must not differ.",
252
+ });
253
+ return false;
254
+ }
255
+ return true;
256
+ }
257
+ visitMissingProperty(diagnostic) {
258
+ const property = diagnostic.ecDefinition;
259
+ if (this.lookupEntry("add", { itemName: property.class.name })) {
260
+ return;
261
+ }
262
+ this.addEntry({
263
+ changeType: "add",
264
+ schemaType: "Property",
265
+ itemName: property.class.name,
266
+ path: property.name,
267
+ json: property.toJSON(),
268
+ });
269
+ }
270
+ visitChangedProperty(diagnostic) {
271
+ const property = diagnostic.ecDefinition;
272
+ if (this.lookupEntry("add", { itemName: property.class.name })
273
+ || this.lookupEntry("add", { itemName: property.class.name, path: property.name })) {
274
+ return;
275
+ }
276
+ const [propertyName, sourceValue, targetValue] = diagnostic.messageArgs;
277
+ if (!this.validatePropertyChange(property, propertyName, sourceValue, targetValue)) {
278
+ return;
279
+ }
280
+ let modifyEntry = this.lookupEntry("modify", { itemName: property.class.name, path: property.name });
281
+ if (!modifyEntry) {
282
+ modifyEntry = this.addEntry({
283
+ changeType: "modify",
284
+ schemaType: "Property",
285
+ itemName: property.class.name,
286
+ path: property.name,
287
+ json: {},
288
+ });
289
+ }
290
+ if (propertyName !== "name" && sourceValue !== undefined) {
291
+ modifyEntry.json[propertyName] = sourceValue;
292
+ }
293
+ }
294
+ validatePropertyChange(ecProperty, propertyName, sourceValue, targetValue) {
295
+ if (propertyName === "primitiveType") {
296
+ this.addConflict({
297
+ code: SchemaConflicts_1.ConflictCode.ConflictingPropertyName,
298
+ schemaType: getSchemaItemName(ecProperty.class.schemaItemType),
299
+ itemName: ecProperty.class.name,
300
+ path: ecProperty.name,
301
+ source: sourceValue,
302
+ target: targetValue,
303
+ description: "Target class already contains a property with a different type.",
304
+ });
305
+ return false;
306
+ }
307
+ return true;
308
+ }
309
+ visitMissingBaseClass(diagnostic) {
310
+ const ecClass = diagnostic.ecDefinition;
311
+ if (this.lookupEntry("add", { itemName: ecClass.name })) {
312
+ return;
313
+ }
314
+ const [sourceBaseClass, targetBaseClass] = diagnostic.messageArgs;
315
+ if (!this.validateBaseClassChange(ecClass, sourceBaseClass, targetBaseClass)) {
316
+ return;
317
+ }
318
+ let modifyEntry = this.lookupEntry("modify", { itemName: ecClass.name });
319
+ if (!modifyEntry) {
320
+ modifyEntry = this.addEntry({
321
+ changeType: "modify",
322
+ schemaType: getSchemaItemName(ecClass.schemaItemType),
323
+ itemName: ecClass.name,
324
+ json: {},
325
+ });
326
+ }
327
+ modifyEntry.json.baseClass = sourceBaseClass.fullName;
328
+ }
329
+ validateBaseClassChange(targetClass, sourceBaseClass, targetBaseClass) {
330
+ if (sourceBaseClass === undefined) {
331
+ this.addConflict({
332
+ code: SchemaConflicts_1.ConflictCode.RemovingBaseClass,
333
+ schemaType: getSchemaItemName(targetClass.schemaItemType),
334
+ itemName: targetClass.name,
335
+ path: "$baseClass",
336
+ source: undefined,
337
+ target: targetBaseClass?.fullName,
338
+ description: "BaseClass cannot be set unset if there has been a baseClass before.",
339
+ });
340
+ return false;
341
+ }
342
+ if (sourceBaseClass.modifier === ecschema_metadata_1.ECClassModifier.Sealed) {
343
+ this.addConflict({
344
+ code: SchemaConflicts_1.ConflictCode.SealedBaseClass,
345
+ schemaType: getSchemaItemName(targetClass.schemaItemType),
346
+ itemName: targetClass.name,
347
+ path: "$baseClass",
348
+ source: sourceBaseClass.fullName,
349
+ target: targetBaseClass?.fullName,
350
+ description: "BaseClass is sealed.",
351
+ });
352
+ return false;
353
+ }
354
+ if (targetBaseClass && !derivedFrom(sourceBaseClass, targetBaseClass.name)) {
355
+ this.addConflict({
356
+ code: SchemaConflicts_1.ConflictCode.ConflictingBaseClass,
357
+ schemaType: getSchemaItemName(targetClass.schemaItemType),
358
+ itemName: targetClass.name,
359
+ path: "$baseClass",
360
+ source: sourceBaseClass.fullName,
361
+ target: targetBaseClass.fullName,
362
+ description: "BaseClass is not valid, source class must derive from target.",
363
+ });
364
+ return false;
365
+ }
366
+ return true;
367
+ }
368
+ visitMissingMixinOnClass(diagnostic) {
369
+ const ecClass = diagnostic.ecDefinition;
370
+ if (this.lookupEntry("add", { itemName: ecClass.name })) {
371
+ return;
372
+ }
373
+ const [mixin] = diagnostic.messageArgs;
374
+ if (!this.validateMixin(ecClass, mixin)) {
375
+ return;
376
+ }
377
+ let modifyEntry = this.lookupEntry("modify", { itemName: ecClass.name, path: "$mixins" });
378
+ if (!modifyEntry) {
379
+ modifyEntry = this.addEntry({
380
+ changeType: "modify",
381
+ schemaType: "EntityClass",
382
+ itemName: ecClass.name,
383
+ path: "$mixins",
384
+ json: [],
385
+ });
386
+ }
387
+ modifyEntry.json.push(mixin.fullName);
388
+ }
389
+ validateMixin(targetClass, mixin) {
390
+ if (mixin.appliesTo && !derivedFrom(targetClass, mixin.appliesTo.name)) {
391
+ this.addConflict({
392
+ code: SchemaConflicts_1.ConflictCode.MixinAppliedMustDeriveFromConstraint,
393
+ schemaType: getSchemaItemName(targetClass.schemaItemType),
394
+ itemName: targetClass.name,
395
+ path: "$mixins",
396
+ source: mixin.fullName,
397
+ target: undefined,
398
+ description: "Mixin cannot applied to this class.",
399
+ });
400
+ return false;
401
+ }
402
+ return true;
403
+ }
404
+ visitMissingRelationshipConstraintClass(diagnostic) {
405
+ const constraint = diagnostic.ecDefinition;
406
+ const className = constraint.relationshipClass.name;
407
+ const constraintPath = `$${constraint.isSource ? "source" : "target"}.constraintClasses`;
408
+ if (this.lookupEntry("add", { itemName: className })) {
409
+ return;
410
+ }
411
+ let modifyEntry = this.lookupEntry("modify", { itemName: className, path: constraintPath });
412
+ if (!modifyEntry) {
413
+ modifyEntry = this.addEntry({
414
+ changeType: "modify",
415
+ schemaType: "RelationshipClass",
416
+ itemName: className,
417
+ path: constraintPath,
418
+ json: [],
419
+ });
420
+ }
421
+ const [constraintClass] = diagnostic.messageArgs;
422
+ modifyEntry.json.push(constraintClass.fullName);
423
+ }
424
+ visitChangedRelationshipConstraint(diagnostic) {
425
+ const constraint = diagnostic.ecDefinition;
426
+ const className = constraint.relationshipClass.name;
427
+ const constraintPath = `$${constraint.isSource ? "source" : "target"}`;
428
+ if (this.lookupEntry("add", { itemName: className })) {
429
+ return;
430
+ }
431
+ let modifyEntry = this.lookupEntry("modify", { itemName: className, path: constraintPath });
432
+ if (!modifyEntry) {
433
+ modifyEntry = this.addEntry({
434
+ changeType: "modify",
435
+ schemaType: "RelationshipConstraint",
436
+ itemName: className,
437
+ path: constraintPath,
438
+ json: {},
439
+ });
440
+ }
441
+ const [propertyName, propertyValue] = diagnostic.messageArgs;
442
+ if (propertyValue !== undefined) {
443
+ modifyEntry.json[propertyName] = propertyValue;
444
+ }
445
+ }
446
+ visitSchemaReference(diagnostic, changeType) {
447
+ const [referencedSchema] = diagnostic.messageArgs;
448
+ this.addEntry({
449
+ changeType,
450
+ schemaType: "Schema",
451
+ path: "$references",
452
+ json: {
453
+ name: referencedSchema.name,
454
+ version: referencedSchema.schemaKey.version.toString(),
455
+ },
456
+ });
457
+ }
458
+ visitMissingCustomAttributeInstance(diagnostic) {
459
+ const { schemaType, itemName, path } = getItemNameAndPath(diagnostic.ecDefinition);
460
+ if (itemName && (this.lookupEntry("add", { itemName }) || this.lookupEntry("add", { itemName, path }))) {
461
+ return;
462
+ }
463
+ const [customAttribute] = diagnostic.messageArgs;
464
+ this.addEntry({
465
+ changeType: "add",
466
+ schemaType,
467
+ itemName: itemName,
468
+ path: `${path ? `${path}.` : ""}$customAttributes`,
469
+ json: customAttribute,
470
+ });
471
+ }
472
+ }
473
+ exports.SchemaDiagnosticVisitor = SchemaDiagnosticVisitor;
474
+ function getItemNameAndPath(type) {
475
+ if (ecschema_metadata_1.Schema.isSchema(type))
476
+ return {
477
+ schemaType: "Schema",
478
+ };
479
+ if (ecschema_metadata_1.SchemaItem.isSchemaItem(type))
480
+ return {
481
+ schemaType: getSchemaItemName(type.schemaItemType),
482
+ itemName: type.name,
483
+ };
484
+ if (type instanceof ecschema_metadata_1.Property)
485
+ return {
486
+ schemaType: "Property",
487
+ itemName: type.class.name,
488
+ path: type.name,
489
+ };
490
+ if (type instanceof ecschema_metadata_1.RelationshipConstraint)
491
+ return {
492
+ schemaType: "RelationshipClass",
493
+ itemName: type.relationshipClass.name,
494
+ path: type.isSource ? "$source" : "$target",
495
+ };
496
+ throw Error("Unhandled Type");
497
+ }
498
+ function getSchemaItemName(schemaItemType) {
499
+ return (0, ecschema_metadata_1.schemaItemTypeToString)(schemaItemType);
500
+ }
501
+ //# sourceMappingURL=SchemaDiagnosticVisitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaDiagnosticVisitor.js","sourceRoot":"","sources":["../../../src/Differencing/SchemaDiagnosticVisitor.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Differencing\r\n */\r\n\r\nimport type { AnyDiagnostic } from \"../Validation/Diagnostic\";\r\nimport { SchemaCompareCodes } from \"../Validation/SchemaCompareDiagnostics\";\r\nimport {\r\n AnyECType, AnyEnumerator, AnySchemaItemProps, CustomAttribute, ECClass, ECClassModifier, Enumeration, Mixin, Property, PropertyProps,\r\n RelationshipConstraint, RelationshipConstraintProps, Schema, SchemaItem, SchemaItemType, schemaItemTypeToString,\r\n} from \"@itwin/ecschema-metadata\";\r\nimport {\r\n AnySchemaDifference,\r\n DifferenceType,\r\n SchemaClassMixinDifference,\r\n SchemaDifference,\r\n SchemaDifferences,\r\n SchemaEnumeratorDifference,\r\n SchemaItemDifference,\r\n SchemaItemTypeName,\r\n SchemaPropertyDifference,\r\n SchemaRelationshipConstraintClassDifference,\r\n SchemaRelationshipConstraintDifference,\r\n SchemaType,\r\n} from \"./SchemaDifference\";\r\nimport { ConflictCode, SchemaDifferenceConflict } from \"./SchemaConflicts\";\r\n\r\n/**\r\n * Recursive syncronous function to figure whether a given class derived from\r\n * a class with the given baseClassName.\r\n */\r\nfunction derivedFrom(ecClass: ECClass|undefined, baseClassName: string): boolean {\r\n if(ecClass === undefined) {\r\n return false;\r\n }\r\n if(ecClass && ecClass.name === baseClassName) {\r\n return true;\r\n }\r\n return derivedFrom(ecClass.getBaseClassSync(), baseClassName);\r\n}\r\n\r\n/**\r\n * Definition of lookup args to locate certain elements in the existing differences.\r\n */\r\ninterface LookupArgs {\r\n schemaType?: string;\r\n itemName?: string;\r\n path?: string;\r\n}\r\n\r\n/**\r\n * The SchemaDiagnosticVisitor is a visitor implementation for diagnostic entries\r\n * from the schema comparer api. Depending on the diagnostic code, the difference\r\n * result is build together.\r\n * @internal\r\n */\r\nexport class SchemaDiagnosticVisitor {\r\n\r\n private readonly _differenceReport: SchemaDifferences;\r\n\r\n constructor(differenceReport: SchemaDifferences) {\r\n this._differenceReport = differenceReport;\r\n }\r\n\r\n private addEntry<T extends AnySchemaDifference>(entry: T): T {\r\n this._differenceReport.changes.push(entry);\r\n return entry;\r\n }\r\n\r\n private lookupEntry(changeType: DifferenceType, args: LookupArgs) {\r\n return this._differenceReport.changes && this._differenceReport.changes.find((change) => {\r\n return (change.changeType === changeType)\r\n && (!args.schemaType || change.schemaType === args.schemaType)\r\n && (!args.itemName || change.itemName === args.itemName)\r\n && change.path === args.path;\r\n });\r\n }\r\n\r\n private addConflict(conflict: SchemaDifferenceConflict) {\r\n this._differenceReport.conflicts.push(conflict);\r\n }\r\n\r\n /**\r\n * Visitor function to process the schema change diagnostic object.\r\n * @internal\r\n */\r\n public visit(diagnostic: AnyDiagnostic) {\r\n switch(diagnostic.code) {\r\n case SchemaCompareCodes.SchemaDelta:\r\n return this.visitChangedSchemaProperties(diagnostic);\r\n\r\n case SchemaCompareCodes.SchemaReferenceMissing:\r\n return this.visitSchemaReference(diagnostic, \"add\");\r\n case SchemaCompareCodes.SchemaReferenceDelta:\r\n return this.visitSchemaReference(diagnostic, \"modify\");\r\n\r\n case SchemaCompareCodes.SchemaItemMissing:\r\n return this.visitMissingSchemaItem(diagnostic);\r\n\r\n case SchemaCompareCodes.SchemaItemDelta:\r\n case SchemaCompareCodes.ClassDelta:\r\n case SchemaCompareCodes.ConstantDelta:\r\n case SchemaCompareCodes.CustomAttributeClassDelta:\r\n case SchemaCompareCodes.FormatDelta:\r\n case SchemaCompareCodes.InvertedUnitDelta:\r\n case SchemaCompareCodes.KoqDelta:\r\n case SchemaCompareCodes.MixinDelta:\r\n case SchemaCompareCodes.PhenomenonDelta:\r\n case SchemaCompareCodes.PropertyCategoryDelta:\r\n case SchemaCompareCodes.RelationshipDelta:\r\n case SchemaCompareCodes.UnitDelta:\r\n return this.visitChangedSchemaItem(diagnostic);\r\n\r\n case SchemaCompareCodes.EnumerationDelta:\r\n return this.visitChangedEnumeration(diagnostic);\r\n\r\n case SchemaCompareCodes.EnumeratorDelta:\r\n return this.visitChangedEnumerator(diagnostic);\r\n case SchemaCompareCodes.EnumeratorMissing:\r\n return this.visitMissingEnumerator(diagnostic);\r\n\r\n case SchemaCompareCodes.BaseClassDelta:\r\n return this.visitMissingBaseClass(diagnostic);\r\n case SchemaCompareCodes.EntityMixinMissing:\r\n return this.visitMissingMixinOnClass(diagnostic);\r\n case SchemaCompareCodes.PropertyDelta:\r\n return this.visitChangedProperty(diagnostic);\r\n case SchemaCompareCodes.PropertyMissing:\r\n return this.visitMissingProperty(diagnostic);\r\n\r\n case SchemaCompareCodes.RelationshipConstraintClassMissing:\r\n return this.visitMissingRelationshipConstraintClass(diagnostic);\r\n case SchemaCompareCodes.RelationshipConstraintDelta:\r\n return this.visitChangedRelationshipConstraint(diagnostic);\r\n\r\n case SchemaCompareCodes.CustomAttributeInstanceClassMissing:\r\n return this.visitMissingCustomAttributeInstance(diagnostic);\r\n\r\n // Currently not handled...\r\n case SchemaCompareCodes.FormatUnitMissing:\r\n case SchemaCompareCodes.PresentationUnitMissing:\r\n case SchemaCompareCodes.UnitLabelOverrideDelta:\r\n break;\r\n }\r\n return;\r\n }\r\n\r\n private visitChangedSchemaProperties(diagnostic: AnyDiagnostic) {\r\n let modifyEntry = this.lookupEntry(\"modify\", { schemaType: \"Schema\" }) as SchemaDifference;\r\n let hasChanges = false;\r\n const existsAlready = modifyEntry !== undefined;\r\n if(!existsAlready) {\r\n modifyEntry = {\r\n changeType: \"modify\",\r\n schemaType: \"Schema\",\r\n json: {},\r\n };\r\n }\r\n\r\n // Only label and description are taken from the source schema. If the schema name or alias\r\n // differs, those are ignored for now.\r\n const [propertyName, propertyValue] = diagnostic.messageArgs as [string, any];\r\n switch(propertyName) {\r\n case \"label\":\r\n modifyEntry.json.label = propertyValue;\r\n hasChanges = true;\r\n break;\r\n case \"description\":\r\n modifyEntry.json.description = propertyValue;\r\n hasChanges = true;\r\n break;\r\n }\r\n\r\n if(!existsAlready && hasChanges) {\r\n this.addEntry(modifyEntry);\r\n }\r\n }\r\n\r\n private visitMissingSchemaItem(diagnostic: AnyDiagnostic) {\r\n const schemaItem = diagnostic.ecDefinition as SchemaItem;\r\n this.addEntry({\r\n changeType: \"add\",\r\n schemaType: getSchemaItemName(schemaItem.schemaItemType),\r\n itemName: schemaItem.name,\r\n json: schemaItem.toJSON(),\r\n });\r\n }\r\n\r\n private visitChangedSchemaItem(diagnostic: AnyDiagnostic) {\r\n const schemaItem = diagnostic.ecDefinition as SchemaItem;\r\n if(this.lookupEntry(\"add\", { itemName: schemaItem.name })) {\r\n return;\r\n }\r\n\r\n const [propertyName, sourceValue, targetValue] = diagnostic.messageArgs as [keyof AnySchemaItemProps, any, any];\r\n if(propertyName === \"schemaItemType\") {\r\n return this.addConflict({\r\n code: ConflictCode.ConflictingItemName,\r\n schemaType: getSchemaItemName(schemaItem.schemaItemType),\r\n itemName: schemaItem.name,\r\n source: sourceValue,\r\n target: targetValue,\r\n description: \"Target schema already contains a schema item with the name but different type.\",\r\n });\r\n }\r\n\r\n if(sourceValue === undefined) {\r\n return;\r\n }\r\n\r\n let modifyEntry = this.lookupEntry(\"modify\", { itemName: schemaItem.name }) as SchemaItemDifference;\r\n if(!modifyEntry) {\r\n modifyEntry = this.addEntry({\r\n changeType: \"modify\",\r\n schemaType: getSchemaItemName(schemaItem.schemaItemType),\r\n itemName: schemaItem.name,\r\n json: {},\r\n });\r\n }\r\n\r\n modifyEntry.json[propertyName] = sourceValue;\r\n }\r\n\r\n private visitChangedEnumeration(diagnostic: AnyDiagnostic) {\r\n const enumeration = diagnostic.ecDefinition as Enumeration;\r\n if(this.lookupEntry(\"add\", { itemName: enumeration.name })) {\r\n return;\r\n }\r\n\r\n const [propertyName, sourceValue, targetValue] = diagnostic.messageArgs as [string, string, string];\r\n if(propertyName === \"type\") {\r\n return this.addConflict({\r\n code: ConflictCode.ConflictingEnumerationType,\r\n schemaType: getSchemaItemName(SchemaItemType.Enumeration),\r\n itemName: enumeration.name,\r\n source: sourceValue,\r\n target: targetValue,\r\n description: \"Enumeration has a different primitive type.\",\r\n });\r\n }\r\n\r\n return this.visitChangedSchemaItem(diagnostic);\r\n }\r\n\r\n private visitMissingEnumerator(diagnostic: AnyDiagnostic) {\r\n const enumeration = diagnostic.ecDefinition as SchemaItem;\r\n if(this.lookupEntry(\"add\", { itemName: enumeration.name })) {\r\n return;\r\n }\r\n\r\n const [enumerator] = diagnostic.messageArgs as [AnyEnumerator];\r\n this.addEntry({\r\n changeType: \"add\",\r\n schemaType: \"Enumeration\",\r\n itemName: enumeration.name,\r\n path: \"$enumerators\",\r\n json: enumerator,\r\n });\r\n }\r\n\r\n private lookupEnumeratorEntry(changeType: DifferenceType, item: string, enumeratorName: string) {\r\n return this._differenceReport.changes && this._differenceReport.changes.find((change) => {\r\n return change.changeType === changeType\r\n && change.schemaType === \"Enumeration\"\r\n && change.itemName === item\r\n && change.path === \"$enumerators\"\r\n && (change.json as AnyEnumerator).name === enumeratorName;\r\n });\r\n }\r\n\r\n private visitChangedEnumerator(diagnostic: AnyDiagnostic) {\r\n const enumeration = diagnostic.ecDefinition as Enumeration;\r\n if(this.lookupEntry(\"add\", { itemName: enumeration.name })) {\r\n return;\r\n }\r\n\r\n const [enumerator, propertyName, sourceValue, targetValue] = diagnostic.messageArgs as [AnyEnumerator, keyof AnyEnumerator, any, any];\r\n if(this.lookupEnumeratorEntry(\"add\", enumeration.name, enumerator.name)) {\r\n return;\r\n }\r\n\r\n if(!this.validateEnumerator(enumeration, enumerator, propertyName, sourceValue, targetValue)) {\r\n return;\r\n }\r\n\r\n const enumeratorPath = `$enumerators.${enumerator.name}`;\r\n let modifyEntry = this.lookupEntry(\"modify\", { itemName: enumeration.name, path: enumeratorPath}) as SchemaEnumeratorDifference;\r\n if(!modifyEntry) {\r\n modifyEntry = this.addEntry({\r\n changeType: \"modify\",\r\n schemaType: \"Enumeration\",\r\n itemName: enumeration.name,\r\n path: enumeratorPath,\r\n json: {},\r\n });\r\n }\r\n\r\n if(sourceValue !== undefined) {\r\n modifyEntry.json[propertyName] = sourceValue;\r\n }\r\n }\r\n\r\n private validateEnumerator(enumeration: Enumeration, enumerator: AnyEnumerator, propertyName: string, sourceValue: unknown, targetValue: unknown) {\r\n if(propertyName === \"value\") {\r\n this.addConflict({\r\n code: ConflictCode.ConflictingEnumeratorValue,\r\n schemaType: getSchemaItemName(SchemaItemType.Enumeration),\r\n itemName: enumeration.name,\r\n path: enumerator.name,\r\n source: sourceValue,\r\n target: targetValue,\r\n description: \"Enumerator values must not differ.\",\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private visitMissingProperty(diagnostic: AnyDiagnostic) {\r\n const property = diagnostic.ecDefinition as Property;\r\n if(this.lookupEntry(\"add\", { itemName: property.class.name })) {\r\n return;\r\n }\r\n\r\n this.addEntry({\r\n changeType: \"add\",\r\n schemaType: \"Property\",\r\n itemName: property.class.name,\r\n path: property.name,\r\n json: property.toJSON(),\r\n });\r\n }\r\n\r\n private visitChangedProperty(diagnostic: AnyDiagnostic) {\r\n const property = diagnostic.ecDefinition as Property;\r\n if(this.lookupEntry(\"add\", { itemName: property.class.name})\r\n || this.lookupEntry(\"add\", { itemName: property.class.name, path: property.name })) {\r\n return;\r\n }\r\n const [propertyName, sourceValue, targetValue] = diagnostic.messageArgs as [keyof PropertyProps, any, any];\r\n if(!this.validatePropertyChange(property, propertyName, sourceValue, targetValue)) {\r\n return;\r\n }\r\n\r\n let modifyEntry = this.lookupEntry(\"modify\", { itemName: property.class.name, path: property.name}) as SchemaPropertyDifference;\r\n if(!modifyEntry) {\r\n modifyEntry = this.addEntry({\r\n changeType: \"modify\",\r\n schemaType: \"Property\",\r\n itemName: property.class.name,\r\n path: property.name,\r\n json: {},\r\n });\r\n }\r\n\r\n if(propertyName !== \"name\" && sourceValue !== undefined) {\r\n modifyEntry.json[propertyName] = sourceValue;\r\n }\r\n }\r\n\r\n private validatePropertyChange(ecProperty: Property, propertyName: string, sourceValue: unknown, targetValue: unknown): boolean {\r\n if(propertyName === \"primitiveType\") {\r\n this.addConflict({\r\n code: ConflictCode.ConflictingPropertyName,\r\n schemaType: getSchemaItemName(ecProperty.class.schemaItemType),\r\n itemName: ecProperty.class.name,\r\n path: ecProperty.name,\r\n source: sourceValue,\r\n target: targetValue,\r\n description: \"Target class already contains a property with a different type.\",\r\n });\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private visitMissingBaseClass(diagnostic: AnyDiagnostic) {\r\n const ecClass = diagnostic.ecDefinition as ECClass;\r\n if(this.lookupEntry(\"add\", { itemName: ecClass.name })) {\r\n return;\r\n }\r\n\r\n const [sourceBaseClass, targetBaseClass] = diagnostic.messageArgs as [ECClass, ECClass];\r\n if(!this.validateBaseClassChange(ecClass, sourceBaseClass, targetBaseClass)) {\r\n return;\r\n }\r\n\r\n let modifyEntry = this.lookupEntry(\"modify\",{ itemName: ecClass.name }) as SchemaItemDifference<{ baseClass: string }>;\r\n if(!modifyEntry) {\r\n modifyEntry = this.addEntry({\r\n changeType: \"modify\",\r\n schemaType: getSchemaItemName(ecClass.schemaItemType),\r\n itemName: ecClass.name,\r\n json: {},\r\n });\r\n }\r\n\r\n modifyEntry.json.baseClass = sourceBaseClass.fullName;\r\n }\r\n\r\n private validateBaseClassChange(targetClass: ECClass, sourceBaseClass?: ECClass, targetBaseClass?: ECClass): boolean {\r\n if(sourceBaseClass === undefined) {\r\n this.addConflict({\r\n code: ConflictCode.RemovingBaseClass,\r\n schemaType: getSchemaItemName(targetClass.schemaItemType),\r\n itemName: targetClass.name,\r\n path: \"$baseClass\",\r\n source: undefined,\r\n target: targetBaseClass?.fullName,\r\n description: \"BaseClass cannot be set unset if there has been a baseClass before.\",\r\n });\r\n return false;\r\n }\r\n\r\n if(sourceBaseClass.modifier === ECClassModifier.Sealed) {\r\n this.addConflict({\r\n code: ConflictCode.SealedBaseClass,\r\n schemaType: getSchemaItemName(targetClass.schemaItemType),\r\n itemName: targetClass.name,\r\n path: \"$baseClass\",\r\n source: sourceBaseClass.fullName,\r\n target: targetBaseClass?.fullName,\r\n description: \"BaseClass is sealed.\",\r\n });\r\n return false;\r\n }\r\n\r\n if(targetBaseClass && !derivedFrom(sourceBaseClass, targetBaseClass.name)) {\r\n this.addConflict({\r\n code: ConflictCode.ConflictingBaseClass,\r\n schemaType: getSchemaItemName(targetClass.schemaItemType),\r\n itemName: targetClass.name,\r\n path: \"$baseClass\",\r\n source: sourceBaseClass.fullName,\r\n target: targetBaseClass.fullName,\r\n description: \"BaseClass is not valid, source class must derive from target.\",\r\n });\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private visitMissingMixinOnClass(diagnostic: AnyDiagnostic) {\r\n const ecClass = diagnostic.ecDefinition as ECClass;\r\n if(this.lookupEntry(\"add\", { itemName: ecClass.name })) {\r\n return;\r\n }\r\n\r\n const [mixin] = diagnostic.messageArgs as [Mixin];\r\n if(!this.validateMixin(ecClass, mixin)) {\r\n return;\r\n }\r\n\r\n let modifyEntry = this.lookupEntry(\"modify\", { itemName: ecClass.name, path: \"$mixins\" }) as SchemaClassMixinDifference;\r\n if(!modifyEntry) {\r\n modifyEntry = this.addEntry({\r\n changeType: \"modify\",\r\n schemaType: \"EntityClass\",\r\n itemName: ecClass.name,\r\n path: \"$mixins\",\r\n json: [],\r\n });\r\n }\r\n\r\n modifyEntry.json.push(mixin.fullName);\r\n }\r\n\r\n private validateMixin(targetClass: ECClass, mixin: Mixin): boolean {\r\n if(mixin.appliesTo && !derivedFrom(targetClass, mixin.appliesTo.name)) {\r\n this.addConflict({\r\n code: ConflictCode.MixinAppliedMustDeriveFromConstraint,\r\n schemaType: getSchemaItemName(targetClass.schemaItemType),\r\n itemName: targetClass.name,\r\n path: \"$mixins\",\r\n source: mixin.fullName,\r\n target: undefined,\r\n description: \"Mixin cannot applied to this class.\",\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private visitMissingRelationshipConstraintClass(diagnostic: AnyDiagnostic) {\r\n const constraint = diagnostic.ecDefinition as RelationshipConstraint;\r\n const className = constraint.relationshipClass.name;\r\n const constraintPath = `$${constraint.isSource ? \"source\" : \"target\"}.constraintClasses`;\r\n if(this.lookupEntry(\"add\", { itemName: className })) {\r\n return;\r\n }\r\n\r\n let modifyEntry = this.lookupEntry(\"modify\", { itemName: className, path: constraintPath}) as SchemaRelationshipConstraintClassDifference;\r\n if(!modifyEntry) {\r\n modifyEntry = this.addEntry({\r\n changeType: \"modify\",\r\n schemaType: \"RelationshipClass\",\r\n itemName: className,\r\n path: constraintPath,\r\n json: [],\r\n });\r\n }\r\n\r\n const [constraintClass] = diagnostic.messageArgs as [ECClass];\r\n modifyEntry.json.push(constraintClass.fullName);\r\n }\r\n\r\n private visitChangedRelationshipConstraint(diagnostic: AnyDiagnostic) {\r\n const constraint = diagnostic.ecDefinition as RelationshipConstraint;\r\n const className = constraint.relationshipClass.name;\r\n const constraintPath = `$${constraint.isSource ? \"source\" : \"target\"}`;\r\n if(this.lookupEntry(\"add\", { itemName: className })) {\r\n return;\r\n }\r\n\r\n let modifyEntry = this.lookupEntry(\"modify\", { itemName: className, path: constraintPath }) as SchemaRelationshipConstraintDifference;\r\n if(!modifyEntry) {\r\n modifyEntry = this.addEntry({\r\n changeType: \"modify\",\r\n schemaType: \"RelationshipConstraint\",\r\n itemName: className,\r\n path: constraintPath,\r\n json: {},\r\n });\r\n }\r\n\r\n const [propertyName, propertyValue] = diagnostic.messageArgs as [keyof RelationshipConstraintProps, any];\r\n if(propertyValue !== undefined) {\r\n modifyEntry.json[propertyName] = propertyValue;\r\n }\r\n }\r\n\r\n private visitSchemaReference(diagnostic: AnyDiagnostic, changeType: DifferenceType) {\r\n const [referencedSchema] = diagnostic.messageArgs as [Schema];\r\n this.addEntry({\r\n changeType,\r\n schemaType: \"Schema\",\r\n path: \"$references\",\r\n json: {\r\n name: referencedSchema.name,\r\n version: referencedSchema.schemaKey.version.toString(),\r\n },\r\n });\r\n }\r\n\r\n private visitMissingCustomAttributeInstance(diagnostic: AnyDiagnostic) {\r\n const { schemaType, itemName, path } = getItemNameAndPath(diagnostic.ecDefinition);\r\n if(itemName && (this.lookupEntry(\"add\", { itemName }) || this.lookupEntry(\"add\", { itemName, path }))) {\r\n return;\r\n }\r\n\r\n const [customAttribute] = diagnostic.messageArgs as [CustomAttribute];\r\n this.addEntry({\r\n changeType: \"add\",\r\n schemaType,\r\n itemName: itemName!,\r\n path: `${path ? `${path}.` : \"\"}$customAttributes`,\r\n json: customAttribute as any,\r\n });\r\n }\r\n}\r\n\r\nfunction getItemNameAndPath(type: AnyECType): { schemaType: SchemaType, itemName?: string, path?: string } {\r\n if(Schema.isSchema(type))\r\n return {\r\n schemaType: \"Schema\",\r\n };\r\n if(SchemaItem.isSchemaItem(type))\r\n return {\r\n schemaType: getSchemaItemName(type.schemaItemType),\r\n itemName: type.name,\r\n };\r\n if(type instanceof Property)\r\n return {\r\n schemaType: \"Property\",\r\n itemName: type.class.name,\r\n path: type.name,\r\n };\r\n if(type instanceof RelationshipConstraint)\r\n return {\r\n schemaType: \"RelationshipClass\",\r\n itemName: type.relationshipClass.name,\r\n path: type.isSource ? \"$source\" : \"$target\",\r\n };\r\n throw Error(\"Unhandled Type\");\r\n}\r\n\r\nfunction getSchemaItemName(schemaItemType: SchemaItemType) {\r\n return schemaItemTypeToString(schemaItemType) as SchemaItemTypeName;\r\n}\r\n"]}