// Outputs a DEFINE_IL2CPP_ARG_TYPE call for all root or non-generic types defined by this file
        private void DefineIl2CppArgTypes(CppStreamWriter writer, CppTypeContext context)
        {
            var type = context.LocalType;

            // DEFINE_IL2CPP_ARG_TYPE
            var(ns, il2cppName) = type.This.GetIl2CppName();
            // For Name and Namespace here, we DO want all the `, /, etc
            if (!type.This.IsGeneric)
            {
                IncludeIl2CppTypeCheckIfNotAlready(writer);
                string fullName = context.GetCppName(context.LocalType.This, true, true, CppTypeContext.NeedAs.Definition, CppTypeContext.ForceAsType.Literal)
                                  ?? throw new UnresolvedTypeException(context.LocalType.This, context.LocalType.This);
                if (context.LocalType.Info.Refness == Refness.ReferenceType)
                {
                    fullName += "*";
                }
                writer.WriteLine($"DEFINE_IL2CPP_ARG_TYPE({fullName}, \"{ns}\", \"{il2cppName}\");");
            }
            else if (type.This.DeclaringType is null || !type.This.DeclaringType.IsGeneric)
            {
                IncludeIl2CppTypeCheckIfNotAlready(writer);
                string templateName = context.GetCppName(context.LocalType.This, true, false, CppTypeContext.NeedAs.Declaration, CppTypeContext.ForceAsType.Literal)
                                      ?? throw new UnresolvedTypeException(context.LocalType.This, context.LocalType.This);
                var structStr = context.LocalType.Info.Refness == Refness.ReferenceType ? "CLASS" : "STRUCT";
                writer.WriteLine($"DEFINE_IL2CPP_ARG_TYPE_GENERIC_{structStr}({templateName}, \"{ns}\", \"{il2cppName}\");");
            }

            foreach (var nested in context.NestedContexts.Where(n => n.InPlace))
            {
                DefineIl2CppArgTypes(writer, nested);
            }
        }
        // Resolve the field into context here
        public override void PreSerialize(CppTypeContext context, IField field)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (field is null)
            {
                throw new ArgumentNullException(nameof(field));
            }
            // In this situation, if the type is a pointer, we can simply forward declare.
            // Otherwise, we need to include the corresponding file. This must be resolved via context
            // If the resolved type name is null, we won't serialize this field
            // First, resolve the field type to see if it exists
            // If it does, because it is a field, we can FD it if it is a pointer
            // If it is not a pointer, then we need to include it
            // If it is a nested class, we need to deal with some stuff (maybe)
            var resolvedName = context.GetCppName(field.Type, true);

            if (!string.IsNullOrEmpty(resolvedName))
            {
                Resolved(field);
            }
            // In order to ensure we get an UnresolvedTypeException when we serialize
            ResolvedTypeNames.Add(field, resolvedName);

            string SafeFieldName()
            {
                var name = field.Name;

                if (name.EndsWith("k__BackingField"))
                {
                    name = name.Split(angleBrackets, StringSplitOptions.RemoveEmptyEntries)[0];
                }
                name = string.Join("$", name.Split(angleBrackets)).Trim('_');
                if (char.IsDigit(name[0]))
                {
                    name = "_" + name;
                }
                return(_config.SafeName(name));
            }

            SafeFieldNames.Add(field, SafeFieldName());
        }