public static void GenerateWrapperExtraMembers(FileGeneration fg, DataType dataType, ObjectGeneration objGen, TypeGeneration typeGen, string posAccessor)
        {
            var           fieldData   = typeGen.GetFieldData();
            var           dataMeta    = dataType.IterateFieldsWithMeta().First(item => item.Field == typeGen);
            List <string> extraChecks = new List <string>();

            if (dataMeta.EncounteredBreaks.Any())
            {
                var breakIndex = dataMeta.EncounteredBreaks.Last();
                extraChecks.Add($"!{dataType.StateName}.HasFlag({objGen.Name}.{dataType.EnumName}.Break{breakIndex})");
            }
            if (dataMeta.RangeIndex != -1)
            {
                extraChecks.Add($"{dataType.StateName}.HasFlag({objGen.Name}.{dataType.EnumName}.Range{dataMeta.RangeIndex})");
            }
            if (fieldData.HasVersioning)
            {
                extraChecks.Add(VersioningModule.GetVersionIfCheck(fieldData, "_package.FormVersion!.FormVersion!.Value"));
            }
            fg.AppendLine($"private int _{typeGen.Name}Location => {posAccessor};");
            switch (typeGen.GetFieldData().BinaryOverlayFallback)
            {
            case BinaryGenerationType.Normal:
                fg.AppendLine($"private bool _{typeGen.Name}_IsSet => _{dataType.GetFieldData().RecordType}Location.HasValue{(extraChecks.Count > 0 ? $" && {string.Join(" && ", extraChecks)}" : null)};");
                break;

            case BinaryGenerationType.Custom:
                break;

            default:
                throw new NotImplementedException();
            }
        }
        public override async Task GenerateWrapperFields(
            FileGeneration fg,
            ObjectGeneration objGen,
            TypeGeneration typeGen,
            Accessor dataAccessor,
            int? currentPosition,
            string passedLengthAccessor,
            DataType dataType)
        {
            var eType = typeGen as EnumType;
            var data = typeGen.GetFieldData();
            var nullable = typeGen.Nullable && eType.NullableFallbackInt == null;
            switch (data.BinaryOverlayFallback)
            {
                case BinaryGenerationType.Normal:
                    break;
                case BinaryGenerationType.NoGeneration:
                    return;
                case BinaryGenerationType.Custom:
                    await this.Module.CustomLogic.GenerateForCustomFlagWrapperFields(
                        fg,
                        objGen,
                        typeGen,
                        dataAccessor,
                        currentPosition,
                        passedLengthAccessor,
                        dataType);
                    return;
                default:
                    throw new NotImplementedException();
            }

            if (dataType == null && data.HasVersioning && !typeGen.Nullable)
            {
                fg.AppendLine($"private bool _{typeGen.Name}_IsSet => {VersioningModule.GetVersionIfCheck(data, "_package.FormVersion!.FormVersion!.Value")};");
            }
            if (data.HasTrigger)
            {
                fg.AppendLine($"private int? _{typeGen.Name}Location;");
            }
            var posStr = dataType == null ? passedLengthAccessor : $"_{typeGen.Name}Location";
            string slice;
            if (data.RecordType.HasValue)
            {
                slice = $"{nameof(HeaderTranslation)}.{nameof(HeaderTranslation.ExtractSubrecordMemory)}({dataAccessor}, _{typeGen.Name}Location!.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)})";
            }
            else
            {
                slice = $"{dataAccessor}.Span.Slice({posStr ?? "0x0"}, 0x{eType.ByteLength:X})";
            }
            var getType = GenerateForTypicalWrapper(objGen, typeGen, slice, "_package");

            if (dataType != null)
            {
                DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor);
            }

            bool isSetCheck = dataType != null || data.HasVersioning;

            if (eType.NullableFallbackInt != null)
            {
                fg.AppendLine($"public {eType.TypeName(getter: true)}? {eType.Name}");
                using (new BraceWrapper(fg))
                {
                    fg.AppendLine("get");
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"var val = {getType};");
                        fg.AppendLine($"if (((int)val) == {eType.NullableFallbackInt}) return null;");
                        fg.AppendLine("return val;");
                    }
                }
            }
            else if (data.HasTrigger)
            {
                if (typeGen.CanBeNullable(getter: true))
                {
                    fg.AppendLine($"public {eType.TypeName(getter: true)}{(nullable ? "?" : null)} {eType.Name} => _{typeGen.Name}Location.HasValue ? {getType} : default({eType.TypeName(getter: true)}{(nullable ? "?" : null)});");
                }
                else
                {
                    fg.AppendLine($"public {eType.TypeName(getter: true)} {eType.Name} => {getType};");
                }
            }
            else
            {
                if (!isSetCheck)
                {
                    fg.AppendLine($"public {eType.TypeName(getter: true)} {eType.Name} => {getType};");
                }
                else
                {
                    fg.AppendLine($"public {eType.TypeName(getter: true)} {eType.Name} => _{typeGen.Name}_IsSet ? {getType} : default;");
                }
            }

        }
        public override async Task GenerateWrapperFields(
            FileGeneration fg,
            ObjectGeneration objGen,
            TypeGeneration typeGen,
            Accessor dataAccessor,
            int?passedLength,
            string passedLengthAccesor,
            DataType _)
        {
            DataType dataType = typeGen as DataType;

            fg.AppendLine($"private int? _{dataType.GetFieldData().RecordType}Location;");
            fg.AppendLine($"public {objGen.ObjectName}.{dataType.EnumName} {dataType.StateName} {{ get; private set; }}");
            switch (typeGen.GetFieldData().BinaryOverlayFallback)
            {
            case BinaryGenerationType.Custom:
                await this.Module.CustomLogic.GenerateWrapperFields(
                    fg,
                    objGen,
                    typeGen,
                    dataAccessor,
                    passedLength,
                    passedLengthAccesor);

                break;

            default:
                break;
            }

            var lengths = await this.Module.IteratePassedLengths(
                objGen,
                dataType.SubFields,
                forOverlay : true)
                          .ToListAsync();

            TypeGeneration lastVersionedField = null;

            foreach (var field in dataType.IterateFieldsWithMeta())
            {
                if (!field.Field.Enabled)
                {
                    continue;
                }
                if (!this.Module.TryGetTypeGeneration(field.Field.GetType(), out var subTypeGen))
                {
                    continue;
                }
                using (new RegionWrapper(fg, field.Field.Name)
                {
                    AppendExtraLine = false,
                    SkipIfOnlyOneLine = true
                })
                {
                    var fieldData = field.Field.GetFieldData();
                    var length    = lengths.FirstOrDefault(l => l.Field == field.Field);
                    if (length.Field == null)
                    {
                        throw new ArgumentException();
                    }

                    var passIn = length.PassedAccessor;
                    if (passIn == null)
                    {
                        passIn = $"_{dataType.GetFieldData().RecordType}Location!.Value";
                    }
                    else if (passIn == null ||
                             length.PassedType == BinaryTranslationModule.PassedType.Direct)
                    {
                        passIn = $"_{dataType.GetFieldData().RecordType}Location!.Value + {passIn}";
                    }

                    await subTypeGen.GenerateWrapperFields(
                        fg,
                        objGen,
                        field.Field,
                        dataAccessor,
                        length.PassedLength,
                        passIn,
                        data : dataType);

                    if (fieldData.HasVersioning)
                    {
                        VersioningModule.AddVersionOffset(fg, field.Field, length.FieldLength.Value, lastVersionedField, $"_package.FormVersion!.FormVersion!.Value");
                        lastVersionedField = field.Field;
                    }
                    if (length.CurLength == null)
                    {
                        fg.AppendLine($"protected int {length.Field.Name}EndingPos;");
                        if (fieldData.BinaryOverlayFallback == BinaryGenerationType.Custom)
                        {
                            fg.AppendLine($"partial void Custom{length.Field.Name}EndPos();");
                        }
                    }
                }
            }
        }