private bool TryReadProperty(string streamName, string dataName, Property property, List <Property> properties, CodeBuilder builder, SyntaxProvider syntaxProvider, Method readMethod = null)
        {
            if (readMethod is null)
            {
                syntaxProvider.Methods.TryGetReadMethod(property, out readMethod);
            }

            var context = new MethodBuildingContext(streamName, dataName, property, properties, builder, readMethod, syntaxProvider.Methods, syntaxProvider.Context);

            if (property.Reading.Execute(context))
            {
                return(true);
            }

            // Attributes behavior
            for (int i = 0; i < property.Attributes.Length; i++)
            {
                if (property.Attributes[i].ModifyDeserialization(context))
                {
                    property.Read.Execute(context);
                    return(true);
                }
            }

            // Default behavior
            if (readMethod is null)
            {
                ReportMissingMethod(syntaxProvider, property, "deserialization");
                return(false);
            }
            builder.Line($"{dataName} = {streamName}.{readMethod}();");

            property.Read.Execute(context);
            return(true);
        }
        private bool TrySerializeProperty(string streamName, Property property, List <Property> properties, CodeBuilder builder, SyntaxProvider syntaxProvider, Method writeMethod = null)
        {
            if (writeMethod is null)
            {
                syntaxProvider.Methods.TryGetWriteMethod(property, out writeMethod);
            }

            var context = new MethodBuildingContext(streamName, property.Name, property, properties, builder, writeMethod, syntaxProvider.Methods, syntaxProvider.Context);

            if (property.Writing.Execute(context))
            {
                return(true);
            }

            // Attributes behavior
            for (int i = 0; i < property.Attributes.Length; i++)
            {
                if (property.Attributes[i].ModifySerialization(context))
                {
                    property.Written.Execute(context);
                    return(true);
                }
            }

            // Default behavior
            if (writeMethod is null)
            {
                ReportMissingMethod(syntaxProvider, property, "serialization");
                return(false);
            }
            builder.Line($"{streamName}.{writeMethod}({property});");

            property.Written.Execute(context);
            return(true);
        }
        private bool TryReadPropertyCollection(string streamName, string dataName, Property property, List <Property> properties, CodeBuilder builder, SyntaxProvider syntaxProvider)
        {
            // If there is a method for writing the whole collection, use it instead
            if (syntaxProvider.Methods.TryGetReadMethod(property, collection: true, out Method collectionReadMethod))
            {
                return(TryReadProperty(streamName, dataName, property, properties, builder, syntaxProvider, collectionReadMethod));
            }

            syntaxProvider.Methods.TryGetReadMethod(varInt, out Method readMethod);
            var context = new MethodBuildingContext(streamName, dataName, property, properties, builder, readMethod, syntaxProvider.Methods, syntaxProvider.Context);

            if (property.Reading.Execute(context))
            {
                return(true);
            }

            // Attributes behavior
            for (int i = 0; i < property.Attributes.Length; i++)
            {
                if (property.Attributes[i].ModifyCollectionPrefixDeserialization(context))
                {
                    goto LOOP;
                }
            }

            // Default behavior
            if (readMethod is null)
            {
                ReportMissingMethod(syntaxProvider, property, "deserialization");
                return(false);
            }
            string getLength = $"{streamName}.{readMethod}()";

            builder.Line($"{dataName} = {property.NewCollection(getLength)};");

LOOP:
            builder.Statement($"for (int i = 0; i < {dataName}.{property.Length}; i++)");

            context = new MethodBuildingContext(streamName, dataName + "[i]", property, properties, builder, readMethod, syntaxProvider.Methods, syntaxProvider.Context);

            // Attributes behavior
            for (int i = 0; i < property.Attributes.Length; i++)
            {
                if (property.Attributes[i].ModifyDeserialization(context))
                {
                    goto END_LOOP;
                }
            }

            // Default behavior
            if (readMethod is null)
            {
                ReportMissingMethod(syntaxProvider, property, "deserialization");
                return(false);
            }
            builder.Line($"{dataName}[i] = {streamName}.{readMethod}();");

END_LOOP:
            builder.EndScope();

            property.Read.Execute(context);
            return(true);
        }
        private bool TrySerializePropertyCollection(string streamName, Property property, List <Property> properties, CodeBuilder builder, SyntaxProvider syntaxProvider)
        {
            // If there is a method for writing the whole collection, use it instead
            if (syntaxProvider.Methods.TryGetWriteMethod(property, collection: true, out Method collectionWriteMethod))
            {
                return(TrySerializeProperty(streamName, property, properties, builder, syntaxProvider, collectionWriteMethod));
            }

            syntaxProvider.Methods.TryGetWriteMethod(varInt, out Method writeMethod);

            var context = new MethodBuildingContext(streamName, property.Name, property, properties, builder, writeMethod, syntaxProvider.Methods, syntaxProvider.Context);

            if (property.Writing.Execute(context))
            {
                return(true);
            }

            // Attributes behavior
            for (int i = 0; i < property.Attributes.Length; i++)
            {
                if (property.Attributes[i].ModifyCollectionPrefixSerialization(context))
                {
                    goto LOOP;
                }
            }

            // Default behavior
            if (writeMethod is null)
            {
                ReportMissingMethod(syntaxProvider, property, "serialization");
                return(false);
            }
            builder.Line($"{streamName}.{writeMethod}({property}.{property.Length});");

LOOP:
            property.Written.Execute(context);

            // Begin the for loop
            builder.Statement($"for (int i = 0; i < {property}.{property.Length}; i++)");
            syntaxProvider.Methods.TryGetWriteMethod(property, out writeMethod);
            context = new MethodBuildingContext(streamName, property.Name + "[i]", property, properties, builder, writeMethod, syntaxProvider.Methods, syntaxProvider.Context);

            // Attributes behavior
            for (int i = 0; i < property.Attributes.Length; i++)
            {
                if (property.Attributes[i].ModifySerialization(context))
                {
                    goto END_LOOP;
                }
            }

            // Default behavior
            if (writeMethod is null)
            {
                ReportMissingMethod(syntaxProvider, property, "serialization");
                return(false);
            }
            builder.Line($"{streamName}.{writeMethod}({property}[i]);");

END_LOOP:
            builder.EndScope();

            property.Written.Execute(context);
            return(true);
        }