in src/typespec-aaz/src/convertor.ts [984:1090]
function convertModel2CMDObjectDiscriminator(
context: AAZSchemaEmitterContext,
model: Model,
discriminatorInfo: DiscriminatorInfo,
): CMDObjectSchemaDiscriminator | undefined {
const object: CMDObjectSchemaDiscriminator = {
property: discriminatorInfo.propertyName,
value: discriminatorInfo.value,
};
const payloadModel = context.metadateInfo.getEffectivePayloadType(model, context.visibility) as Model;
const properties: Record<string, CMDSchema> = {};
const discriminator = getDiscriminator(context.program, payloadModel);
for (const prop of payloadModel.properties.values()) {
if (isNeverType(prop.type)) {
// If the property has a type of 'never', don't include it in the schema
continue;
}
if (!context.metadateInfo.isPayloadProperty(prop, context.visibility)) {
continue;
}
const jsonName = getJsonName(context, prop);
if (jsonName === discriminatorInfo.propertyName) {
// if this property is a discriminator property, remove it as autorest
continue;
}
let schema = convert2CMDSchema(
{
...context,
supportClsSchema: true,
},
prop,
jsonName,
);
if (schema) {
if (isReadonlyProperty(context.program, prop)) {
schema.readOnly = true;
}
if (!context.metadateInfo.isOptional(prop, context.visibility) || prop.name === discriminator?.propertyName) {
schema.required = true;
}
if (shouldClientFlatten(context, prop)) {
if (schema.type === "object") {
schema = {
...schema,
clientFlatten: true,
} as CMDObjectSchema;
} else if (schema.type instanceof ClsType) {
schema = {
...schema,
clientFlatten: true,
} as CMDClsSchema;
}
}
properties[schema.name] = schema;
}
}
// TODO: handle discriminator.propertyName === discriminatorInfo.propertyName
if (discriminator && discriminator.propertyName !== discriminatorInfo.propertyName) {
const { propertyName } = discriminator;
console.assert(object.discriminators === undefined, "Discriminator should be undefined.");
// Push discriminator into base type, but only if it is not already there
if (!payloadModel.properties.get(propertyName)) {
const discriminatorProperty: CMDStringSchema = {
name: propertyName,
type: "string",
required: true,
description: `Discriminator property for ${payloadModel.name}.`,
};
properties[propertyName] = discriminatorProperty;
}
const discProperty = properties[propertyName] as CMDStringSchema;
const derivedModels = payloadModel.derivedModels.filter(includeDerivedModel);
for (const child of derivedModels) {
const childDiscriminatorValue = getDiscriminatorInfo(context, child);
if (childDiscriminatorValue) {
const disc = convertModel2CMDObjectDiscriminator(context, child, childDiscriminatorValue);
if (disc) {
object.discriminators ??= [];
object.discriminators.push(disc);
discProperty.enum ??= {
items: [],
};
discProperty.enum.items.push({
value: childDiscriminatorValue.value,
});
}
}
}
}
if (Object.keys(properties).length > 0) {
object.props = Object.values(properties).filter((prop) => !isEmptiedSchema(prop));
if (object.props.length === 0) {
object.props = undefined;
}
}
return object;
}