/// <summary> /// The visitor method for building service types. This is called when an instance of this class is /// visiting a _swaggerModeler to build a service type. /// </summary> /// <param name="serviceTypeName">name for the service type</param> /// <returns>built service type</returns> public virtual IModelType BuildServiceType(string serviceTypeName) { PrimaryType type = SwaggerObject.ToType(); Debug.Assert(type != null); if (type.KnownPrimaryType == KnownPrimaryType.Object && SwaggerObject.KnownFormat == KnownFormat.file) { type = New <PrimaryType>(KnownPrimaryType.Stream); } type.XmlProperties = (SwaggerObject as Schema)?.Xml; type.Format = SwaggerObject.Format; if (SwaggerObject.Enum != null && type.KnownPrimaryType == KnownPrimaryType.String && !(IsSwaggerObjectConstant(SwaggerObject))) { var enumType = New <EnumType>(); SwaggerObject.Enum.ForEach(v => enumType.Values.Add(new EnumValue { Name = v, SerializedName = v })); if (SwaggerObject.Extensions.ContainsKey(Core.Model.XmsExtensions.Enum.Name)) { var enumObject = SwaggerObject.Extensions[Core.Model.XmsExtensions.Enum.Name] as Newtonsoft.Json.Linq.JContainer; if (enumObject != null) { enumType.SetName(enumObject["name"].ToString()); if (enumObject["modelAsString"] != null) { enumType.ModelAsString = bool.Parse(enumObject["modelAsString"].ToString()); } } enumType.SerializedName = enumType.Name; if (string.IsNullOrEmpty(enumType.Name)) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "{0} extension needs to specify an enum name.", Core.Model.XmsExtensions.Enum.Name)); } var existingEnum = Modeler.CodeModel.EnumTypes.FirstOrDefault( e => e.Name.RawValue.EqualsIgnoreCase(enumType.Name.RawValue)); if (existingEnum != null) { if (!existingEnum.StructurallyEquals(enumType)) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Swagger document contains two or more {0} extensions with the same name '{1}' and different values.", Core.Model.XmsExtensions.Enum.Name, enumType.Name)); } // Use the existing one! enumType = existingEnum; } else { Modeler.CodeModel.Add(enumType); } } else { enumType.ModelAsString = true; enumType.SetName(string.Empty); enumType.SerializedName = string.Empty; } enumType.XmlProperties = (SwaggerObject as Schema)?.Xml; return(enumType); } if (SwaggerObject.Type == DataType.Array) { string itemServiceTypeName; if (SwaggerObject.Items.Reference != null) { itemServiceTypeName = SwaggerObject.Items.Reference.StripDefinitionPath(); } else { itemServiceTypeName = serviceTypeName + "Item"; } var elementType = SwaggerObject.Items.GetBuilder(Modeler).BuildServiceType(itemServiceTypeName); return(New <SequenceType>(new { ElementType = elementType, Extensions = SwaggerObject.Items.Extensions, XmlProperties = (SwaggerObject as Schema)?.Xml, ElementXmlProperties = SwaggerObject.Items?.Xml })); } if (SwaggerObject.AdditionalProperties != null) { string dictionaryValueServiceTypeName; if (SwaggerObject.AdditionalProperties.Reference != null) { dictionaryValueServiceTypeName = SwaggerObject.AdditionalProperties.Reference.StripDefinitionPath(); } else { dictionaryValueServiceTypeName = serviceTypeName + "Value"; } return(New <DictionaryType>(new { ValueType = SwaggerObject.AdditionalProperties.GetBuilder(Modeler) .BuildServiceType((dictionaryValueServiceTypeName)), Extensions = SwaggerObject.AdditionalProperties.Extensions, XmlProperties = (SwaggerObject as Schema)?.Xml })); } return(type); }
/// <summary> /// The visitor method for building service types. This is called when an instance of this class is /// visiting a _swaggerModeler to build a service type. /// </summary> /// <param name="serviceTypeName">name for the service type</param> /// <returns>built service type</returns> public virtual IType BuildServiceType(string serviceTypeName) { PrimaryType type = SwaggerObject.ToType(); if (type == PrimaryType.Object && "file".Equals(SwaggerObject.Format, StringComparison.OrdinalIgnoreCase)) { type = PrimaryType.Stream; } if (SwaggerObject.Enum != null && type == PrimaryType.String && (SwaggerObject.Enum.Count > 1 || IsExpandableEnum(SwaggerObject))) { var enumType = new EnumType(); SwaggerObject.Enum.ForEach(v => enumType.Values.Add(new EnumValue { Name = v, SerializedName = v })); if (SwaggerObject.Extensions.ContainsKey(CodeGenerator.EnumObject)) { var enumObject = SwaggerObject.Extensions[CodeGenerator.EnumObject] as Newtonsoft.Json.Linq.JContainer; if (enumObject != null) { enumType.Name = enumObject["name"].ToString(); if (enumObject["modelAsString"] != null) { enumType.ModelAsString = bool.Parse(enumObject["modelAsString"].ToString()); } } enumType.SerializedName = enumType.Name; if (string.IsNullOrEmpty(enumType.Name)) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "{0} extension needs to specify an enum name.", CodeGenerator.EnumObject)); } var existingEnum = Modeler.ServiceClient.EnumTypes.FirstOrDefault( e => e.Name.Equals(enumType.Name, StringComparison.OrdinalIgnoreCase)); if (existingEnum != null) { if (!existingEnum.Equals(enumType)) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Swagger document contains two or more {0} extensions with the same name '{1}' and different values.", CodeGenerator.EnumObject, enumType.Name)); } } else { Modeler.ServiceClient.EnumTypes.Add(enumType); } } else { enumType.ModelAsString = true; enumType.Name = string.Empty; enumType.SerializedName = string.Empty; } return(enumType); } if (SwaggerObject.Type == DataType.Array) { string itemServiceTypeName; if (SwaggerObject.Items.Reference != null) { itemServiceTypeName = SwaggerObject.Items.Reference.StripDefinitionPath(); } else { itemServiceTypeName = serviceTypeName + "Item"; } var elementType = SwaggerObject.Items.GetBuilder(Modeler).BuildServiceType(itemServiceTypeName); return(new SequenceType { ElementType = elementType }); } if (SwaggerObject.AdditionalProperties != null) { string dictionaryValueServiceTypeName; if (SwaggerObject.AdditionalProperties.Reference != null) { dictionaryValueServiceTypeName = SwaggerObject.AdditionalProperties.Reference.StripDefinitionPath(); } else { dictionaryValueServiceTypeName = serviceTypeName + "Value"; } return(new DictionaryType { ValueType = SwaggerObject.AdditionalProperties.GetBuilder(Modeler) .BuildServiceType((dictionaryValueServiceTypeName)) }); } return(type); }
/// <summary> /// The visitor method for building service types. This is called when an instance of this class is /// visiting a _swaggerModeler to build a service type. /// </summary> /// <param name="serviceTypeName">name for the service type</param> /// <returns>built service type</returns> public virtual IModelType BuildServiceType(string serviceTypeName, bool required) { PrimaryType type = SwaggerObject.ToType(); Debug.Assert(type != null); if (type.KnownPrimaryType == KnownPrimaryType.Object && SwaggerObject.KnownFormat == KnownFormat.file) { type = New <PrimaryType>(KnownPrimaryType.Stream); } type.XmlProperties = (SwaggerObject as Schema)?.Xml; type.Format = SwaggerObject.Format; var xMsEnum = SwaggerObject.Extensions.GetValue <JToken>(Core.Model.XmsExtensions.Enum.Name); if (xMsEnum != null && SwaggerObject.Enum == null) { throw new InvalidOperationException($"Found 'x-ms-enum' without 'enum' on the same level. Please either add an 'enum' restriction or remove 'x-ms-enum'."); } if (SwaggerObject.Enum != null && type.KnownPrimaryType == KnownPrimaryType.String && !(IsSwaggerObjectConstant(SwaggerObject, required))) { if (SwaggerObject.Enum.Count == 0) { throw new InvalidOperationException($"Found an 'enum' with no values. Please remove this (unsatisfiable) restriction or add values."); } var enumType = New <EnumType>(); // Set the underlying type. This helps to determine whether the values in EnumValue are of type string, number, etc. enumType.UnderlyingType = type; SwaggerObject.Enum.OfType <JValue>().Select(x => (string)x).ForEach(v => enumType.Values.Add(new EnumValue { Name = v, SerializedName = v })); if (xMsEnum is JContainer enumObject) { var enumName = "" + enumObject["name"]; if (string.IsNullOrEmpty(enumName)) { throw new InvalidOperationException($"{Core.Model.XmsExtensions.Enum.Name} extension needs to specify an enum name."); } enumType.SetName(enumName); if (enumObject["modelAsString"] != null) { enumType.ModelAsString = bool.Parse(enumObject["modelAsString"].ToString()); } enumType.OldModelAsString = (enumObject["oldModelAsString"] != null)? bool.Parse(enumObject["oldModelAsString"].ToString()) : false; if (enumType.OldModelAsString) { enumType.ModelAsString = true; } var valueOverrides = enumObject["values"] as JArray; if (valueOverrides != null) { var valuesBefore = new HashSet <string>(enumType.Values.Select(x => x.SerializedName)); enumType.Values.Clear(); foreach (var valueOverride in valueOverrides) { var value = valueOverride["value"]; var description = valueOverride["description"]; var name = valueOverride["name"] ?? value; var enumVal = new EnumValue { Name = (string)name, SerializedName = (string)value, Description = (string)description }; if (valueOverride["allowedValues"] is JArray allowedValues) { // set the allowedValues if any foreach (var allowedValue in allowedValues) { enumVal.AllowedValues.Add(allowedValue.ToString()); } } enumType.Values.Add(enumVal); } var valuesAfter = new HashSet <string>(enumType.Values.Select(x => x.SerializedName)); // compare values if (!valuesBefore.SetEquals(valuesAfter)) { throw new InvalidOperationException($"Values specified by 'enum' mismatch those specified by 'x-ms-enum' (name: '{enumName}'): " + string.Join(", ", valuesBefore.Select(x => $"'{x}'")) + " vs " + string.Join(", ", valuesAfter.Select(x => $"'{x}'"))); } } var existingEnum = Modeler.CodeModel.EnumTypes.FirstOrDefault( e => e.Name.RawValue.EqualsIgnoreCase(enumType.Name.RawValue)); if (existingEnum != null) { if (!existingEnum.StructurallyEquals(enumType)) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Swagger document contains two or more {0} extensions with the same name '{1}' and different values: {2} vs. {3}", Core.Model.XmsExtensions.Enum.Name, enumType.Name, string.Join(",", existingEnum.Values.Select(x => x.SerializedName)), string.Join(",", enumType.Values.Select(x => x.SerializedName)))); } // Use the existing one! enumType = existingEnum; } else { Modeler.CodeModel.Add(enumType); } } else { enumType.ModelAsString = true; enumType.SetName(string.Empty); } enumType.XmlProperties = (SwaggerObject as Schema)?.Xml; return(enumType); } if (SwaggerObject.Type == DataType.Array) { if (SwaggerObject.Items == null) { throw new Exception($"Invalid Swagger: Missing 'items' definition of an 'array' type."); } string itemServiceTypeName; if (SwaggerObject.Items.Reference != null) { itemServiceTypeName = SwaggerObject.Items.Reference.StripComponentsSchemaPath(); } else { itemServiceTypeName = serviceTypeName + "Item"; } var elementType = SwaggerObject.Items.GetBuilder(Modeler).BuildServiceType(itemServiceTypeName, false); return(New <SequenceType>(new { ElementType = elementType, Extensions = SwaggerObject.Items.Extensions, XmlProperties = (SwaggerObject as Schema)?.Xml, ElementXmlProperties = SwaggerObject.Items?.Xml })); } if (SwaggerObject.AdditionalProperties != null) { string dictionaryValueServiceTypeName; if (SwaggerObject.AdditionalProperties.Reference != null) { dictionaryValueServiceTypeName = SwaggerObject.AdditionalProperties.Reference.StripComponentsSchemaPath(); } else { dictionaryValueServiceTypeName = serviceTypeName + "Value"; } return(New <DictionaryType>(new { ValueType = SwaggerObject.AdditionalProperties.GetBuilder(Modeler) .BuildServiceType(dictionaryValueServiceTypeName, false), Extensions = SwaggerObject.AdditionalProperties.Extensions, XmlProperties = (SwaggerObject as Schema)?.Xml })); } return(type); }
/// <summary> /// The visitor method for building service types. This is called when an instance of this class is /// visiting a _swaggerModeler to build a service type. /// </summary> /// <param name="serviceTypeName">name for the service type</param> /// <returns>built service type</returns> public virtual IModelType BuildServiceType(string serviceTypeName) { PrimaryType type = SwaggerObject.ToType(); Debug.Assert(type != null); if (type.KnownPrimaryType == KnownPrimaryType.Object && SwaggerObject.KnownFormat == KnownFormat.file) { type = New <PrimaryType>(KnownPrimaryType.Stream); } type.XmlProperties = (SwaggerObject as Schema)?.Xml; type.Format = SwaggerObject.Format; var xMsEnum = SwaggerObject.Extensions.GetValue <JToken>(Core.Model.XmsExtensions.Enum.Name); if ((SwaggerObject.Enum != null || xMsEnum != null) && type.KnownPrimaryType == KnownPrimaryType.String && !(IsSwaggerObjectConstant(SwaggerObject))) { var enumType = New <EnumType>(); if (SwaggerObject.Enum != null) { SwaggerObject.Enum.ForEach(v => enumType.Values.Add(new EnumValue { Name = v, SerializedName = v })); } if (xMsEnum != null) { var enumObject = xMsEnum as JContainer; if (enumObject != null) { enumType.SetName(enumObject["name"].ToString()); if (enumObject["modelAsString"] != null) { enumType.ModelAsString = bool.Parse(enumObject["modelAsString"].ToString()); } var valueOverrides = enumObject["values"] as JArray; if (valueOverrides != null) { enumType.Values.Clear(); foreach (var valueOverride in valueOverrides) { var value = valueOverride["value"]; var description = valueOverride["description"]; var name = valueOverride["name"] ?? value; enumType.Values.Add(new EnumValue { Name = (string)name, SerializedName = (string)value, Description = (string)description }); } } } if (string.IsNullOrEmpty(enumType.Name)) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "{0} extension needs to specify an enum name.", Core.Model.XmsExtensions.Enum.Name)); } var existingEnum = Modeler.CodeModel.EnumTypes.FirstOrDefault( e => e.Name.RawValue.EqualsIgnoreCase(enumType.Name.RawValue)); if (existingEnum != null) { if (!existingEnum.StructurallyEquals(enumType)) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Swagger document contains two or more {0} extensions with the same name '{1}' and different values: {2} vs. {3}", Core.Model.XmsExtensions.Enum.Name, enumType.Name, string.Join(",", existingEnum.Values.Select(x => x.SerializedName)), string.Join(",", enumType.Values.Select(x => x.SerializedName)))); } // Use the existing one! enumType = existingEnum; } else { Modeler.CodeModel.Add(enumType); } } else { enumType.ModelAsString = true; enumType.SetName(string.Empty); } enumType.XmlProperties = (SwaggerObject as Schema)?.Xml; return(enumType); } if (SwaggerObject.Type == DataType.Array) { if (SwaggerObject.Items == null) { throw new Exception($"Invalid Swagger: Missing 'items' definition of an 'array' type."); } string itemServiceTypeName; if (SwaggerObject.Items.Reference != null) { itemServiceTypeName = SwaggerObject.Items.Reference.StripDefinitionPath(); } else { itemServiceTypeName = serviceTypeName + "Item"; } var elementType = SwaggerObject.Items.GetBuilder(Modeler).BuildServiceType(itemServiceTypeName); return(New <SequenceType>(new { ElementType = elementType, Extensions = SwaggerObject.Items.Extensions, XmlProperties = (SwaggerObject as Schema)?.Xml, ElementXmlProperties = SwaggerObject.Items?.Xml })); } if (SwaggerObject.AdditionalProperties != null) { string dictionaryValueServiceTypeName; if (SwaggerObject.AdditionalProperties.Reference != null) { dictionaryValueServiceTypeName = SwaggerObject.AdditionalProperties.Reference.StripDefinitionPath(); } else { dictionaryValueServiceTypeName = serviceTypeName + "Value"; } return(New <DictionaryType>(new { ValueType = SwaggerObject.AdditionalProperties.GetBuilder(Modeler) .BuildServiceType((dictionaryValueServiceTypeName)), Extensions = SwaggerObject.AdditionalProperties.Extensions, XmlProperties = (SwaggerObject as Schema)?.Xml })); } return(type); }
/// <summary> /// The visitor method for building service types. This is called when an instance of this class is /// visiting a _swaggerModeler to build a service type. /// </summary> /// <param name="serviceTypeName">name for the service type</param> /// <returns>built service type</returns> public virtual IType BuildServiceType(string serviceTypeName) { PrimaryType type = SwaggerObject.ToType(); if (SwaggerObject.Enum != null && SwaggerObject.Enum.Any() && type == PrimaryType.String) { var enumType = new EnumType(); SwaggerObject.Enum.ForEach(v => enumType.Values.Add(new EnumValue { Name = v, SerializedName = v })); if (SwaggerObject.Extensions.ContainsKey("x-ms-enum")) { enumType.IsExpandable = false; enumType.Name = SwaggerObject.Extensions["x-ms-enum"] as string; enumType.SerializedName = enumType.Name; if (string.IsNullOrEmpty(enumType.Name)) { throw new InvalidOperationException("x-ms-enum extension needs to specify an enum name."); } var existingEnum = Modeler.ServiceClient.EnumTypes.FirstOrDefault( e => e.Name.Equals(enumType.Name, StringComparison.OrdinalIgnoreCase)); if (existingEnum != null) { if (!existingEnum.Equals(enumType)) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, "Swagger document contains two or more x-ms-enum extensions with the same name '{0}' and different values.", enumType.Name)); } } else { Modeler.ServiceClient.EnumTypes.Add(enumType); } } else { enumType.IsExpandable = true; enumType.Name = string.Empty; enumType.SerializedName = string.Empty; } return(enumType); } if (SwaggerObject.Type == DataType.Array) { string itemServiceTypeName; if (SwaggerObject.Items.Reference != null) { itemServiceTypeName = SwaggerObject.Items.Reference.StripDefinitionPath(); } else { itemServiceTypeName = serviceTypeName + "Item"; } var elementType = SwaggerObject.Items.GetBuilder(Modeler).BuildServiceType(itemServiceTypeName); return(new SequenceType { ElementType = elementType }); } if (SwaggerObject.AdditionalProperties != null) { string dictionaryValueServiceTypeName; if (SwaggerObject.AdditionalProperties.Reference != null) { dictionaryValueServiceTypeName = SwaggerObject.AdditionalProperties.Reference.StripDefinitionPath(); } else { dictionaryValueServiceTypeName = serviceTypeName + "Value"; } return(new DictionaryType { ValueType = SwaggerObject.AdditionalProperties.GetBuilder(Modeler) .BuildServiceType((dictionaryValueServiceTypeName)) }); } return(type); }