Skip to content

Commit c923769

Browse files
authored
handle duplicated properties in parentes, fixes #688 (#690)
* handle duplicated properties in parentes, fixes #688 * Remove no-needed comments
1 parent aa99bef commit c923769

File tree

1 file changed

+46
-42
lines changed

1 file changed

+46
-42
lines changed

powershell/plugins/plugin-tweak-model.ts

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
5-
import { Property, SealedChoiceSchema, codeModelSchema, CodeModel, StringSchema, ObjectSchema, GroupSchema, isObjectSchema, SchemaType, GroupProperty, ParameterLocation, Operation, Parameter, VirtualParameter, getAllProperties, ImplementationLocation, OperationGroup, Request, SchemaContext, ChoiceSchema, Scheme, Schema, ConstantSchema } from '@azure-tools/codemodel';
5+
import { Property, SealedChoiceSchema, codeModelSchema, CodeModel, StringSchema, ObjectSchema, GroupSchema, isObjectSchema, SchemaType, GroupProperty, ParameterLocation, Operation, Parameter, VirtualParameter, getAllProperties, ImplementationLocation, OperationGroup, Request, SchemaContext, ChoiceSchema, Scheme, Schema, ConstantSchema, ConditionalValue } from '@azure-tools/codemodel';
66
//import { ModelState } from '@azure-tools/codemodel-v3';
77
//import { KnownMediaType, knownMediaType, ParameterLocation, getPolymorphicBases, isSchemaObject, JsonType, Property, Schema, processCodeModel, StringFormat, codemodel, ModelState } from '@azure-tools/codemodel-v3';
88
import { pascalCase, deconstruct, fixLeadingNumber, serialize, KnownMediaType } from '@azure-tools/codegen';
@@ -35,38 +35,40 @@ export function titleToAzureServiceName(title: string): string {
3535
}
3636

3737

38-
// function dropDuplicatePropertiesInChildSchemas(schema: Schema, state: State, map: Map<string, Property> = new Map()) {
39-
// let success = true;
40-
// for (const parent of values(schema.allOf)) {
41-
// handle parents first
42-
// if (!dropDuplicatePropertiesInChildSchemas(parent, state, map)) {
43-
// return false;
44-
// }
45-
// }
46-
// for (const { key: id, value: property } of items(schema.properties)) {
47-
// see if it's in the parent.
48-
// const pProp = map.get(property.serializedName);
49-
// if (pProp) {
50-
// if the parent prop is the same type as the child prop
51-
// we're going to drop the child property.
52-
// if (pProp.schema.type === property.schema.type) {
53-
// if it's an object type, it has to be the exact same schema type too
54-
// if (pProp.schema.type != JsonType.Object || pProp.schema === property.schema) {
55-
// state.verbose(`Property '${property.serializedName}' in '${schema.details.default.name}' has a property the same as the parent, and is dropping the duplicate.`, {});
56-
// delete schema.properties[id];
57-
// } else {
58-
// const conflict = `Property '${property.serializedName}' in '${schema.details.default.name}' has a conflict with a parent schema (allOf ${schema.allOf.joinWith(each => each.details.default.name)}.`;
59-
// state.error(conflict, [], {});
60-
// success = false;
61-
// }
62-
// }
63-
// }
64-
// else {
65-
// map.set(property.serializedName, property);
66-
// }
67-
// }
68-
// return success;
69-
// }
38+
function dropDuplicatePropertiesInChildSchemas(schema: ObjectSchema, state: State, map: Map<string, Property> = new Map()) {
39+
let success = true;
40+
for (const parent of values(schema.parents?.immediate)) {
41+
//handle parents first
42+
if (!dropDuplicatePropertiesInChildSchemas(<ObjectSchema>parent, state, map)) {
43+
return false;
44+
}
45+
}
46+
for (const { key: id, value: property } of items(schema.properties)) {
47+
//see if it's in the parent.
48+
const pProp = map.get(property.serializedName);
49+
if (pProp) {
50+
//if the parent prop is the same type as the child prop
51+
//we're going to drop the child property.
52+
if (pProp.schema.type === property.schema.type) {
53+
//if it's an object type, it has to be the exact same schema type too
54+
if (pProp.schema.type != SchemaType.Object || pProp.schema === property.schema) {
55+
state.verbose(`Property '${property.serializedName}' in '${schema.language.default.name}' has a property the same as the parent, and is dropping the duplicate.`, {});
56+
if (schema.properties) {
57+
delete schema.properties[id];
58+
}
59+
} else {
60+
const conflict = `Property '${property.serializedName}' in '${schema.language.default.name}' has a conflict with a parent schema (allOf ${schema.parents?.immediate.joinWith(each => each.language.default.name)}.`;
61+
state.error(conflict, [], {});
62+
success = false;
63+
}
64+
}
65+
}
66+
else {
67+
map.set(property.serializedName, property);
68+
}
69+
}
70+
return success;
71+
}
7072

7173
async function tweakModelV2(state: State): Promise<PwshModel> {
7274
const title = pascalCase(fixLeadingNumber(deconstruct(await state.getValue('title', state.model.info.title))));
@@ -142,16 +144,15 @@ async function tweakModelV2(state: State): Promise<PwshModel> {
142144
// }
143145
// }
144146

145-
// xichen: should be no duplicate properties in m4. Skip
146147
// schemas that have parents and implement properties that are in the parent schemas
147148
// will have the property dropped in the child schema
148-
// for (const schema of values(model.schemas)) {
149-
// if (length(schema.allOf) > 0) {
150-
// if (!dropDuplicatePropertiesInChildSchemas(schema, state)) {
151-
// throw new Error('Schemas are in conflict.');
152-
// }
153-
// }
154-
// }
149+
for (const schema of values(model.schemas.objects)) {
150+
if (length(schema.parents?.immediate) > 0) {
151+
if (!dropDuplicatePropertiesInChildSchemas(schema, state)) {
152+
throw new Error('Schemas are in conflict.');
153+
}
154+
}
155+
}
155156

156157

157158
if (await state.getValue('use-storage-pipeline', false)) {
@@ -310,6 +311,9 @@ async function tweakModelV2(state: State): Promise<PwshModel> {
310311
// identify properties that are constants
311312
for (const schema of values(schemas.objects)) {
312313
for (const property of values(schema.properties)) {
314+
if (property === undefined) {
315+
continue;
316+
}
313317
if (property.required) {
314318
if (property.schema.type === SchemaType.Choice) {
315319
const choiceSchema = property.schema as ChoiceSchema;
@@ -637,4 +641,4 @@ export async function tweakModelPlugin(service: Host) {
637641
//const result = tweakModelV2(session);
638642
await service.WriteFile('code-model-v4-tweakcodemodel-v2.yaml', serialize(await tweakModelV2(state)), undefined, 'code-model-v4');
639643
//return processCodeModel(tweakModelV2, service, 'tweakcodemodel-v2');
640-
}
644+
}

0 commit comments

Comments
 (0)