private void AddPropertyInfoFromPropertySchema( IList <KeyValuePair <string, PropertyInfo> > entries, string schemaPropertyName, JsonSchema propertySchema, bool isRequired) { ComparisonKind comparisonKind; HashKind hashKind; InitializationKind initializationKind; TypeSyntax type; string namespaceName = null; string referencedEnumTypeName; bool isOfSchemaDefinedType = false; int arrayRank = 0; if (propertySchema.IsDateTime()) { comparisonKind = ComparisonKind.OperatorEquals; hashKind = HashKind.ScalarValueType; initializationKind = InitializationKind.SimpleAssign; type = MakeNamedType("System.DateTime", out namespaceName); } else if (propertySchema.IsUri()) { comparisonKind = ComparisonKind.OperatorEquals; hashKind = HashKind.ScalarReferenceType; initializationKind = InitializationKind.Uri; type = MakeNamedType("System.Uri", out namespaceName); } else if (propertySchema.ShouldBeDictionary(_typeName, schemaPropertyName, _hintDictionary, out DictionaryHint dictionaryHint)) { comparisonKind = ComparisonKind.Dictionary; hashKind = HashKind.Dictionary; initializationKind = InitializationKind.Dictionary; // If the schema for this property specifies additionalProperties, and if // the value of additionalProperties is a schema as opposed to a Boolean, // then we will represent this property as a dictionary from string to // whatever kind of object the schema represents. Otherwise, treat it as // a dictionary from string to string. JsonSchema dictionaryElementSchema = propertySchema.AdditionalProperties?.Schema != null ? propertySchema.AdditionalProperties.Schema : new JsonSchema { Type = new SchemaType[] { SchemaType.String } }; type = MakeDictionaryType(entries, schemaPropertyName, dictionaryHint, dictionaryElementSchema); namespaceName = "System.Collections.Generic"; // For IDictionary. } else if ((referencedEnumTypeName = GetReferencedEnumTypeName(propertySchema)) != null) { comparisonKind = ComparisonKind.OperatorEquals; hashKind = HashKind.ScalarValueType; initializationKind = InitializationKind.SimpleAssign; type = MakeNamedType(referencedEnumTypeName, out namespaceName); } else if (propertySchema.ShouldBeEnum(_typeName, schemaPropertyName, _hintDictionary, out EnumHint enumHint)) { comparisonKind = ComparisonKind.OperatorEquals; hashKind = HashKind.ScalarValueType; initializationKind = InitializationKind.SimpleAssign; type = MakeNamedType(enumHint.TypeName, out namespaceName); // The class whose property info we are generating contains a property // of an enumerated type. Notify the code generator that it must generate // the enumerated type in addition to the current type. OnAdditionalTypeRequired(enumHint, propertySchema); } else { SchemaType propertyType = propertySchema.SafeGetType(); switch (propertyType) { case SchemaType.Boolean: case SchemaType.Integer: case SchemaType.Number: comparisonKind = ComparisonKind.OperatorEquals; hashKind = HashKind.ScalarValueType; initializationKind = InitializationKind.SimpleAssign; type = MakePrimitiveType(propertyType); break; case SchemaType.String: comparisonKind = ComparisonKind.OperatorEquals; hashKind = HashKind.ScalarReferenceType; initializationKind = InitializationKind.SimpleAssign; type = MakePrimitiveType(propertyType); break; case SchemaType.Object: // If the schema for this property references a named type, // the generated Init method will initialize it by cloning an object // of that type. Otherwise, we treat this property as a System.Object // and just initialize it by assignment. if (propertySchema.Reference != null) { comparisonKind = ComparisonKind.EqualityComparerEquals; initializationKind = InitializationKind.Clone; hashKind = HashKind.ObjectModelType; isOfSchemaDefinedType = true; } else { comparisonKind = ComparisonKind.ObjectEquals; initializationKind = InitializationKind.SimpleAssign; hashKind = HashKind.ScalarReferenceType; } type = MakeObjectType(propertySchema, out namespaceName); break; case SchemaType.Array: comparisonKind = ComparisonKind.Collection; hashKind = HashKind.Collection; initializationKind = InitializationKind.Collection; namespaceName = "System.Collections.Generic"; // For IList. type = MakeArrayType(entries, schemaPropertyName, propertySchema); break; case SchemaType.None: SchemaType inferredType = InferSchemaTypeFromEnumValues(propertySchema.Enum); if (inferredType == SchemaType.None) { comparisonKind = ComparisonKind.ObjectEquals; hashKind = HashKind.ScalarReferenceType; initializationKind = InitializationKind.None; type = MakePrimitiveType(SchemaType.Object); break; } else if (inferredType == SchemaType.String) { comparisonKind = ComparisonKind.OperatorEquals; hashKind = HashKind.ScalarReferenceType; initializationKind = InitializationKind.SimpleAssign; type = MakePrimitiveType(SchemaType.String); break; } else { comparisonKind = ComparisonKind.OperatorEquals; hashKind = HashKind.ScalarValueType; initializationKind = InitializationKind.SimpleAssign; type = MakePrimitiveType(inferredType); break; } default: throw new ArgumentOutOfRangeException(nameof(propertySchema.Type)); } } var propertyNameHint = _hintDictionary?.GetHint <PropertyNameHint>(_typeName + "." + schemaPropertyName); string dotNetPropertyName = propertyNameHint != null ? propertyNameHint.DotNetPropertyName : schemaPropertyName.ToPascalCase(); entries.Add(new KeyValuePair <string, PropertyInfo>( dotNetPropertyName, new PropertyInfo( propertySchema.Description, schemaPropertyName, comparisonKind, hashKind, initializationKind, type, namespaceName, isRequired, propertySchema.Default, isOfSchemaDefinedType, arrayRank, entries.Count))); }