Exemplo n.º 1
0
        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);
        }