// Write the field here
        public override void Serialize(CppStreamWriter writer, IField field, bool asHeader)
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            if (field is null)
            {
                throw new ArgumentNullException(nameof(field));
            }
            // If we could not resolve the type name, don't serialize the field (this should cause a critical failure in the type)
            if (ResolvedTypeNames[field] == null)
            {
                throw new UnresolvedTypeException(field.DeclaringType, field.Type);
            }

            var fieldString = "";

            foreach (var spec in field.Specifiers)
            {
                fieldString += $"{spec} ";
            }
            writer.WriteComment(fieldString + field.Type + " " + field.Name);

            writer.WriteComment($"Offset: 0x{field.Offset:X}");
            if (!field.Specifiers.IsStatic() && !field.Specifiers.IsConst())
            {
                writer.WriteFieldDeclaration(ResolvedTypeNames[field] !, SafeFieldNames[field]);
            }
            writer.Flush();
            Serialized(field);
        }
        internal void Serialize(CppTypeContext context)
        {
            var data           = context.LocalType;
            var headerLocation = Path.Combine(_config.OutputDirectory, _config.OutputHeaderDirectory, context.HeaderFileName);

            Directory.CreateDirectory(Path.GetDirectoryName(headerLocation));
            using var ms        = new MemoryStream();
            using var rawWriter = new StreamWriter(ms);
            using var writer    = new CppStreamWriter(rawWriter, "  ");
            // Write header
            writer.WriteComment($"Autogenerated from {nameof(CppHeaderCreator)}");
            writer.WriteComment("Created by Sc2ad");
            writer.WriteComment("=========================================================================");
            writer.WriteLine("#pragma once");
            // TODO: determine when/if we need this
            // For sizes that are valid, we ALSO want to write with pack of 1
            // Invalid sizes are ignored.

            // Write SerializerContext and actual type
            try
            {
                _serializer.Serialize(writer, context, true);
            }
            catch (UnresolvedTypeException e)
            {
                if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.DisplayInFile)
                {
                    writer.WriteComment("Unresolved type exception!");
                    writer.WriteLine("/*");
                    writer.WriteLine(e);
                    writer.WriteLine("*/");
                }
                else if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.SkipIssue)
                {
                    return;
                }
                else if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.Elevate)
                {
                    throw new InvalidOperationException($"Cannot elevate {e} to a parent type- there is no parent type!");
                }
            }
            // End the namespace
            writer.CloseDefinition();
            hasIl2CppTypeCheckInclude = context.NeedIl2CppUtilsFunctionsInHeader;

            if (data.This.Namespace == "System" && data.This.Name == "ValueType")
            {
                IncludeIl2CppTypeCheckIfNotAlready(writer);
                writer.WriteLine("template<class T>");
                writer.WriteLine("struct is_value_type<T, typename std::enable_if_t<std::is_base_of_v<System::ValueType, T>>> : std::true_type{};");
            }

            DefineIl2CppArgTypes(writer, context);
            writer.WriteLine("#include \"extern/beatsaber-hook/shared/utils/il2cpp-utils-methods.hpp\"");
            _serializer.WritePostSerializeMethods(writer, context, true);
            writer.Flush();

            writer.WriteIfDifferent(headerLocation, context);
        }
        internal void Serialize(CppTypeContext context)
        {
            var sourceLocation = Path.Combine(_config.OutputDirectory, _config.OutputSourceDirectory, context.CppFileName);

            Directory.CreateDirectory(Path.GetDirectoryName(sourceLocation));
            using var ms        = new MemoryStream();
            using var rawWriter = new StreamWriter(ms);
            using var writer    = new CppStreamWriter(rawWriter, "  ");
            // Write header
            writer.WriteComment($"Autogenerated from {nameof(CppSourceCreator)}");
            writer.WriteComment($"Created by Sc2ad");
            writer.WriteComment("=========================================================================");
            try
            {
                // Write SerializerContext and actual type
                _serializer.Serialize(writer, context, false);
            }
            catch (UnresolvedTypeException e)
            {
                if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.DisplayInFile)
                {
                    writer.WriteLine("// Unresolved type exception!");
                    writer.WriteLine("/*");
                    writer.WriteLine(e);
                    writer.WriteLine("*/");
                }
                else if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.SkipIssue)
                {
                    return;
                }
                else if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.Elevate)
                {
                    throw new InvalidOperationException($"Cannot elevate {e} to a parent type- there is no parent type!");
                }
            }
            writer.Flush();
            rawWriter.Flush();

            writer.WriteIfDifferent(sourceLocation, context);
        }