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';
88import { 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
7173async 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