private static CodegenType MakeDictionaryType(string name, Schema schema) { var returnType = new CodegenType(); if (schema.AdditionalProperties.Type.Count > 1) { returnType.CodeType = new CodeTypeReference(typeof(Dictionary <string, object>)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } if (schema.Default != null) { throw new NotImplementedException("Defaults for dictionaries are not yet supported"); } if (schema.AdditionalProperties.Type[0].Name == "object") { if (schema.AdditionalProperties.Title != null) { returnType.CodeType = new CodeTypeReference($"System.Collections.Generic.Dictionary<string, {Helpers.ToPascalCase(schema.AdditionalProperties.Title)}>"); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } returnType.CodeType = new CodeTypeReference(typeof(Dictionary <string, object>)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } if (schema.AdditionalProperties.Type[0].Name == "string") { returnType.CodeType = new CodeTypeReference(typeof(Dictionary <string, string>)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } if (schema.AdditionalProperties.Type[0].Name == "integer") { returnType.CodeType = new CodeTypeReference(typeof(Dictionary <string, int>)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } throw new NotImplementedException($"Dictionary<string,{schema.AdditionalProperties.Type[0].Name}> not yet implemented."); }
private static void EnforceRestrictionsOnSetValues(CodegenType returnType, string name, Schema schema) { if (schema.Minimum != null) { returnType.SetStatements.Add(new CodeConditionStatement { Condition = new CodeBinaryOperatorExpression { Left = new CodePropertySetValueReferenceExpression(), Operator = schema.ExclusiveMinimum ? CodeBinaryOperatorType.LessThanOrEqual : CodeBinaryOperatorType.LessThan, Right = new CodePrimitiveExpression(schema.Minimum) }, TrueStatements = { new CodeThrowExceptionStatement { ToThrow = new CodeObjectCreateExpression { CreateType = new CodeTypeReference(typeof(ArgumentOutOfRangeException)), Parameters = { new CodePrimitiveExpression(name), new CodePropertySetValueReferenceExpression(), new CodePrimitiveExpression( schema.ExclusiveMinimum ? $"Expected value to be greater than {schema.Minimum}" : $"Expected value to be greater than or equal to {schema.Minimum}") } } } } }); } if (schema.Maximum != null) { returnType.SetStatements.Add(new CodeConditionStatement { Condition = new CodeBinaryOperatorExpression { Left = new CodePropertySetValueReferenceExpression(), Operator = schema.ExclusiveMaximum ? CodeBinaryOperatorType.GreaterThanOrEqual : CodeBinaryOperatorType.GreaterThan, Right = new CodePrimitiveExpression(schema.Maximum) }, TrueStatements = { new CodeThrowExceptionStatement { ToThrow = new CodeObjectCreateExpression { CreateType = new CodeTypeReference(typeof(ArgumentOutOfRangeException)), Parameters = { new CodePrimitiveExpression(name), new CodePropertySetValueReferenceExpression(), new CodePrimitiveExpression( schema.ExclusiveMaximum ? $"Expected value to be less than {schema.Maximum}" : $"Expected value to be less than or equal to {schema.Maximum}") } } } } }); } if (schema.MinItems != null) { throw new NotImplementedException(); } if (schema.MinLength != null) { throw new NotImplementedException(); } if (schema.MaxItems != null) { throw new NotImplementedException(); } if (schema.MaxLength != null) { throw new NotImplementedException(); } }
public static CodegenType MakeCodegenType(string name, Schema schema) { CodegenType returnType = new CodegenType(); EnforceRestrictionsOnSetValues(returnType, name, schema); if (schema.Format == "uriref") { switch (schema.UriType) { case UriType.Application: case UriType.Image: case UriType.Text: returnType.CodeType = new CodeTypeReference(typeof(string)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); break; case UriType.None: throw new InvalidDataException("UriType must be specified in the schema"); } return(returnType); } if (schema.Type.Count > 1) { returnType.CodeType = new CodeTypeReference(typeof(object)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } var typeRef = schema.Type[0]; if (typeRef.IsReference) { throw new NotImplementedException(); } if (typeRef.Name == "object") { if (schema.Enum != null || schema.Default != null) { throw new NotImplementedException(); } if (schema.Title != null) { returnType.CodeType = new CodeTypeReference(Helpers.ToPascalCase(schema.Title)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } throw new NotImplementedException(); } if (typeRef.Name == "number") { if (schema.Enum != null) { throw new NotImplementedException(); } if (schema.Default != null) { returnType.DefaultValue = new CodePrimitiveExpression(((JsonElement)schema.Default).GetSingle()); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else if (!schema.IsRequired) { returnType.CodeType = new CodeTypeReference(typeof(float?)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } returnType.CodeType = new CodeTypeReference(typeof(float)); return(returnType); } if (typeRef.Name == "string") { if (schema.Enum != null && !((string)schema.Enum[0]).Contains('/')) { returnType.Attributes.Add( new CodeAttributeDeclaration("System.Text.Json.Serialization.JsonConverterAttribute", new[] { new CodeAttributeArgument(new CodeTypeOfExpression(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))) })); var enumType = GenStringEnumType(name, schema); returnType.AdditionalMembers.Add(enumType); if (schema.Default != null) { returnType.CodeType = new CodeTypeReference(enumType.Name); for (var i = 0; i < enumType.Members.Count; i++) { if (enumType.Members[i].Name.Equals(((JsonElement)schema.Default).GetString(), StringComparison.OrdinalIgnoreCase)) { returnType.DefaultValue = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(enumType.Name), enumType.Members[i].Name); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); return(returnType); } } throw new InvalidDataException("The default value is not in the enum list"); } // TODO: System.Text.Json.Serialization.JsonStringEnumConverter cannot handle nullable enums. else if (!schema.IsRequired) { returnType.CodeType = new CodeTypeReference(typeof(Nullable <>)); returnType.CodeType.TypeArguments.Add(new CodeTypeReference(enumType.Name)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } returnType.CodeType = new CodeTypeReference(enumType.Name); return(returnType); } if (schema.Default != null) { returnType.DefaultValue = new CodePrimitiveExpression(((JsonElement)schema.Default).GetString()); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else { returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); } returnType.CodeType = new CodeTypeReference(typeof(string)); return(returnType); } if (typeRef.Name == "integer") { if (schema.Enum != null) { var enumType = GenIntEnumType(name, schema); returnType.AdditionalMembers.Add(enumType); if (schema.Default != null) { returnType.DefaultValue = GetEnumField(enumType, ((JsonElement)schema.Default).GetInt32()); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else if (!schema.IsRequired) { returnType.CodeType = new CodeTypeReference(typeof(Nullable <>)); returnType.CodeType.TypeArguments.Add(new CodeTypeReference(enumType.Name)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } returnType.CodeType = new CodeTypeReference(enumType.Name); return(returnType); } if (schema.Default != null) { returnType.DefaultValue = new CodePrimitiveExpression(((JsonElement)schema.Default).GetInt32()); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else if (!schema.IsRequired) { returnType.CodeType = new CodeTypeReference(typeof(int?)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } returnType.CodeType = new CodeTypeReference(typeof(int)); return(returnType); } if (typeRef.Name == "boolean") { if (schema.Enum != null) { throw new NotImplementedException(); } if (schema.Default != null) { returnType.DefaultValue = new CodePrimitiveExpression(((JsonElement)schema.Default).GetBoolean()); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else if (!schema.IsRequired) { returnType.CodeType = new CodeTypeReference(typeof(bool?)); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } returnType.CodeType = new CodeTypeReference(typeof(bool)); return(returnType); } // other types: array, null throw new NotImplementedException(typeRef.Name); }
private static void EnforceRestrictionsOnSetValues(CodegenType returnType, string name, Schema schema) { // TODO: System.Text.Json cannot handle sets arrays to null before assigning a value to them. //if (schema.Default is null) { var fieldName = Helpers.GetFieldName(name); returnType.SetStatements.Add(new CodeConditionStatement { Condition = new CodeBinaryOperatorExpression { Left = new CodePropertySetValueReferenceExpression(), Operator = CodeBinaryOperatorType.ValueEquality, Right = new CodePrimitiveExpression(null) }, TrueStatements = { new CodeAssignStatement() { Left = new CodeFieldReferenceExpression { FieldName = fieldName, TargetObject = new CodeThisReferenceExpression() }, Right = new CodePropertySetValueReferenceExpression() }, new CodeMethodReturnStatement() } }); } if (schema.MinItems != null) { returnType.SetStatements.Add(new CodeConditionStatement { Condition = new CodeBinaryOperatorExpression { Left = new CodePropertyReferenceExpression(new CodePropertySetValueReferenceExpression(), "Length"), Operator = CodeBinaryOperatorType.LessThan, Right = new CodePrimitiveExpression(schema.MinItems) }, TrueStatements = { new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ArgumentException), new CodeExpression[] { new CodePrimitiveExpression("Array not long enough") })) } }); } if (schema.MaxItems != null) { returnType.SetStatements.Add(new CodeConditionStatement { Condition = new CodeBinaryOperatorExpression { Left = new CodePropertyReferenceExpression(new CodePropertySetValueReferenceExpression(), "Length"), Operator = CodeBinaryOperatorType.GreaterThan, Right = new CodePrimitiveExpression(schema.MaxItems) }, TrueStatements = { new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ArgumentException), new CodeExpression[] { new CodePrimitiveExpression("Array too long") })) } }); } if (schema.Items.Minimum != null || schema.Items.Maximum != null || schema.Items.MinLength != null || schema.Items.MaxLength != null) { returnType.SetStatements.Add(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0))); } if (schema.Items.Minimum != null) { returnType.SetStatements.Add(LoopThroughArray(new CodePropertySetValueReferenceExpression(), new CodeStatementCollection { new CodeConditionStatement { Condition = new CodeBinaryOperatorExpression { Left = new CodeArrayIndexerExpression { TargetObject = new CodePropertySetValueReferenceExpression(), Indices = { new CodeVariableReferenceExpression("index") }, }, Operator = schema.Items.ExclusiveMinimum ? CodeBinaryOperatorType.LessThanOrEqual : CodeBinaryOperatorType.LessThan, Right = new CodePrimitiveExpression(schema.Items.Minimum) }, TrueStatements = { new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ArgumentOutOfRangeException))) } } })); } if (schema.Items.Maximum != null) { returnType.SetStatements.Add(LoopThroughArray(new CodePropertySetValueReferenceExpression(), new CodeStatementCollection { new CodeConditionStatement { Condition = new CodeBinaryOperatorExpression { Left = new CodeArrayIndexerExpression { TargetObject = new CodePropertySetValueReferenceExpression(), Indices = { new CodeVariableReferenceExpression("index") }, }, Operator = schema.Items.ExclusiveMaximum ? CodeBinaryOperatorType.GreaterThanOrEqual : CodeBinaryOperatorType.GreaterThan, Right = new CodePrimitiveExpression(schema.Items.Maximum) }, TrueStatements = { new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ArgumentOutOfRangeException))) } } })); } if (schema.Items.MinLength != null) { throw new NotImplementedException(); } if (schema.Items.MaxLength != null) { throw new NotImplementedException(); } }
public static CodegenType MakeCodegenType(string name, Schema schema) { if (!(schema.Items?.Type?.Count > 0)) { throw new InvalidOperationException("Array type must contain an item type"); } if (schema.Enum != null) { throw new InvalidOperationException(); } var returnType = new CodegenType(); if (schema.Items.Type.Count > 1) { returnType.CodeType = new CodeTypeReference(typeof(object[])); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } EnforceRestrictionsOnSetValues(returnType, name, schema); if (schema.Items.Type[0].Name == "integer") { if (schema.Items.Enum != null) { throw new NotImplementedException(); } if (schema.Default != null) { var defaultValueArray = ((JsonElement)schema.Default).EnumerateArray().Select(x => new CodePrimitiveExpression(x.GetInt32())).ToArray(); returnType.DefaultValue = new CodeArrayCreateExpression(typeof(int), defaultValueArray); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheArrayOfValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else { returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); } returnType.CodeType = new CodeTypeReference(typeof(int[])); return(returnType); } if (schema.Items.Enum != null) { throw new NotImplementedException(); } if (schema.Items.Type[0].Name == "number") { if (schema.Default != null) { var defaultValueArray = ((JsonElement)schema.Default).EnumerateArray().Select(x => new CodePrimitiveExpression(x.GetSingle())).ToArray(); returnType.DefaultValue = new CodeArrayCreateExpression(typeof(float), defaultValueArray); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheArrayOfValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else { returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); } returnType.CodeType = new CodeTypeReference(typeof(float[])); return(returnType); } if (schema.Items.Minimum != null || schema.Items.Maximum != null) { throw new NotImplementedException(); } if (schema.Items.Type[0].Name == "boolean") { if (schema.Default != null) { var defaultValueArray = ((JsonElement)schema.Default).EnumerateArray().Select(x => new CodePrimitiveExpression(x.GetBoolean())).ToArray(); returnType.DefaultValue = new CodeArrayCreateExpression(typeof(bool), defaultValueArray); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheArrayOfValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else { returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); } returnType.CodeType = new CodeTypeReference(typeof(bool[])); return(returnType); } if (schema.Items.Type[0].Name == "string") { if (schema.Default != null) { var defaultValueArray = ((JsonElement)schema.Default).EnumerateArray().Select(x => new CodePrimitiveExpression(x.GetString())).ToArray(); returnType.DefaultValue = new CodeArrayCreateExpression(typeof(string), defaultValueArray); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheArrayOfValueOfAMemberIsNotEqualToAnotherExpression(name, returnType.DefaultValue)); } else { returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); } returnType.CodeType = new CodeTypeReference(typeof(string[])); return(returnType); } if (schema.Items.Type[0].Name == "object") { if (schema.Default != null) { throw new NotImplementedException("Array of Objects has default value"); } if (schema.Items.Title != null) { returnType.CodeType = new CodeTypeReference(Helpers.ToPascalCase(schema.Items.Title) + "[]"); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); returnType.Attributes.Clear(); if (schema.Items.MinLength != null || schema.Items.MaxLength != null) { throw new NotImplementedException(); } return(returnType); } if (schema.Items.AdditionalProperties != null) { if (schema.Items.AdditionalProperties.Type[0].Name == "integer") { returnType.CodeType = new CodeTypeReference(typeof(Dictionary <string, int>[])); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); returnType.Attributes.Clear(); return(returnType); } throw new NotImplementedException($"Dictionary<string,{schema.Items.AdditionalProperties.Type[0].Name}> not yet implemented."); } returnType.CodeType = new CodeTypeReference(typeof(object[])); returnType.AdditionalMembers.Add(Helpers.CreateMethodThatChecksIfTheValueOfAMemberIsNotEqualToAnotherExpression(name, new CodePrimitiveExpression(null))); return(returnType); } throw new NotImplementedException("Array of " + schema.Items.Type[0].Name); }