private void AddPropertyInfoFromPropertySchema()

in src/Json.Schema.ToDotNet/PropertyInfoDictionary.cs [214:385]


        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)));
        }