private static JsonSchema ParseCompositeType(Property property, CompositeType compositeType, bool includeBaseModelTypeProperties, IDictionary <string, JsonSchema> definitions, IEnumerable <CompositeType> modelTypes) { string definitionName = compositeType.SerializedName; if (!definitions.ContainsKey(definitionName)) { JsonSchema definition = new JsonSchema() { JsonType = "object", Description = compositeType.Documentation, }; // This definition must be added to the definition map before we start parsing // its properties because its properties may recursively reference back to this // definition. definitions.Add(definitionName, definition); JsonSchema baseTypeDefinition; string discriminatorPropertyName = compositeType.PolymorphicDiscriminator; if (string.IsNullOrWhiteSpace(discriminatorPropertyName)) { baseTypeDefinition = definition; } else { baseTypeDefinition = new JsonSchema(); definition.AddAllOf(baseTypeDefinition); JsonSchema derivedTypeDefinitionRefs = new JsonSchema(); CompositeType[] subTypes = modelTypes.Where(modelType => modelType.BaseModelType == compositeType).ToArray(); if (subTypes != null && subTypes.Length > 0) { JsonSchema discriminatorDefinition = new JsonSchema() { JsonType = "string" }; foreach (CompositeType subType in subTypes) { if (subType != null) { // Sub-types are never referenced directly in the Swagger // discriminator scenario, so they wouldn't be added to the // produced resource schema. By calling ParseCompositeType() on the // sub-type we add the sub-type to the resource schema. ParseCompositeType(null, subType, false, definitions, modelTypes); derivedTypeDefinitionRefs.AddAnyOf(new JsonSchema() { Ref = "#/definitions/" + subType.SerializedName, }); const string discriminatorValueExtensionName = "x-ms-discriminator-value"; if (subType.ComposedExtensions.ContainsKey(discriminatorValueExtensionName)) { string discriminatorValue = subType.ComposedExtensions[discriminatorValueExtensionName] as string; if (!string.IsNullOrWhiteSpace(discriminatorValue)) { discriminatorDefinition.AddEnum(discriminatorValue); } } } } baseTypeDefinition.AddProperty(discriminatorPropertyName, discriminatorDefinition); definition.AddAllOf(derivedTypeDefinitionRefs); } } IEnumerable <Property> compositeTypeProperties = includeBaseModelTypeProperties ? compositeType.ComposedProperties : compositeType.Properties; foreach (Property subProperty in compositeTypeProperties) { JsonSchema subPropertyDefinition = ParseType(subProperty, subProperty.ModelType, definitions, modelTypes); if (subPropertyDefinition != null) { baseTypeDefinition.AddProperty(subProperty.SerializedName.Else(subProperty.Name.RawValue), subPropertyDefinition, subProperty.IsRequired); } } } JsonSchema result = new JsonSchema() { Ref = "#/definitions/" + definitionName }; if (property != null) { result.Description = RemovePossibleValuesFromDescription(property.Documentation); } return(result); }