<commit_before>﻿using System;
using SharpYaml.Events;
using SharpYaml.Serialization.Descriptors;

namespace SharpYaml.Serialization.Serializers
{
    /// <summary>
	/// Base class for serializing an object that can be a Yaml !!map or !!seq.
	/// </summary>
	public class ObjectSerializer : IYamlSerializable, IYamlSerializableFactory
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="ObjectSerializer"/> class.
		/// </summary>
		public ObjectSerializer()
		{
		}

		public virtual IYamlSerializable TryCreate(SerializerContext context, ITypeDescriptor typeDescriptor)
		{
			// always accept
			return this;
		}
		
		/// <summary>
		/// Checks if a type is a sequence.
		/// </summary>
		/// <param name="typeDescriptor">The type descriptor.</param>
		/// <returns><c>true</c> if a type is a sequence, <c>false</c> otherwise.</returns>
		protected virtual bool CheckIsSequence(ITypeDescriptor typeDescriptor)
		{
			// By default an object serializer is a mapping
			return false;
		}

		protected virtual YamlStyle GetStyle(SerializerContext context, object thisObject, ITypeDescriptor typeDescriptor)
		{
			return typeDescriptor.Style;
		}

		public virtual ValueOutput ReadYaml(SerializerContext context, object value, ITypeDescriptor typeDescriptor)
		{
			var type = typeDescriptor.Type;

			// When the node is not scalar, we need to instantiate the type directly
			if (value == null && !(typeDescriptor is PrimitiveDescriptor))
			{
				value = context.ObjectFactory.Create(type);
				//if (value == null)
				//{
				//	throw new YamlException(node.Start, node.End, "Unexpected null value");
				//}
			}

			// Get the object accessor for the corresponding class
			var isSequence = CheckIsSequence(typeDescriptor);

			// Process members
			return new ValueOutput(isSequence
						? ReadItems<SequenceStart, SequenceEnd>(context, value, typeDescriptor)
						: ReadItems<MappingStart, MappingEnd>(context, value, typeDescriptor));
		}

		protected virtual object ReadItems<TStart, TEnd>(SerializerContext context, object thisObject, ITypeDescriptor typeDescriptor) 
			where TStart : NodeEvent
			where TEnd : ParsingEvent
		{
			var reader = context.Reader;
			reader.Expect<TStart>();
			while (!reader.Accept<TEnd>())
			{
				ReadItem(context, thisObject, typeDescriptor);
			}
			reader.Expect<TEnd>();
			return thisObject;
		}

		public virtual void ReadItem(SerializerContext context, object thisObject, ITypeDescriptor typeDescriptor)
		{
			var reader = context.Reader;

			// For a regular object, the key is expected to be a simple scalar
		    string propertyName;<commit_msg>Allow object creation when deserializing to be overrided on a per ObjectSerializer basis (for custom serialization)<commit_after>﻿using System;
using SharpYaml.Events;
using SharpYaml.Serialization.Descriptors;

namespace SharpYaml.Serialization.Serializers
{
    /// <summary>
	/// Base class for serializing an object that can be a Yaml !!map or !!seq.
	/// </summary>
	public class ObjectSerializer : IYamlSerializable, IYamlSerializableFactory
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="ObjectSerializer"/> class.
		/// </summary>
		public ObjectSerializer()
		{
		}

		public virtual IYamlSerializable TryCreate(SerializerContext context, ITypeDescriptor typeDescriptor)
		{
			// always accept
			return this;
		}
		
		/// <summary>
		/// Checks if a type is a sequence.
		/// </summary>
		/// <param name="typeDescriptor">The type descriptor.</param>
		/// <returns><c>true</c> if a type is a sequence, <c>false</c> otherwise.</returns>
		protected virtual bool CheckIsSequence(ITypeDescriptor typeDescriptor)
		{
			// By default an object serializer is a mapping
			return false;
		}

		protected virtual YamlStyle GetStyle(SerializerContext context, object thisObject, ITypeDescriptor typeDescriptor)
		{
			return typeDescriptor.Style;
		}

		public virtual ValueOutput ReadYaml(SerializerContext context, object value, ITypeDescriptor typeDescriptor)
		{
			// When the node is not scalar, we need to instantiate the type directly
			if (value == null && !(typeDescriptor is PrimitiveDescriptor))
			{
			    value = CreateObject(context, typeDescriptor);
			}

			// Get the object accessor for the corresponding class
			var isSequence = CheckIsSequence(typeDescriptor);

			// Process members
			return new ValueOutput(isSequence
						? ReadItems<SequenceStart, SequenceEnd>(context, value, typeDescriptor)
						: ReadItems<MappingStart, MappingEnd>(context, value, typeDescriptor));
		}

        /// <summary>
        /// Overrides this method when deserializing an object that needs special instantiation. By default, this is calling
        /// <see cref="IObjectFactory.Create"/>.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeDescriptor">The type descriptor of the object to create.</param>
        /// <returns>A new instance of the object</returns>
	    protected virtual object CreateObject(SerializerContext context, ITypeDescriptor typeDescriptor)
	    {
            return context.ObjectFactory.Create(typeDescriptor.Type);
	    }

		protected virtual object ReadItems<TStart, TEnd>(SerializerContext context, object thisObject, ITypeDescriptor typeDescriptor) 
			where TStart : NodeEvent
			where TEnd : ParsingEvent
		{
			var reader = context.Reader;
			reader.Expect<TStart>();
			while (!reader.Accept<TEnd>())
			{
				ReadItem(context, thisObject, typeDescriptor);
			}
			reader.Expect<TEnd>();
			return thisObject;
		}

		public virtual void ReadItem(SerializerContext context, object thisObject, ITypeDescriptor typeDescriptor)
		{
			var reader = context.Reader;

			// For a regular object, the key is expected to be a simple scalar
		    string propertyName;
{'fraction_non_alphanumeric': 0.09826191705386336, 'fraction_numerical': 0.0, 'mean_word_length': 3.668273092369478, 'pattern_counts': {'":': 0, '<': 54, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6033216', 'n_tokens_mistral': 1772, 'n_tokens_neox': 1538, 'n_words': 495}