public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLengthAccessor, DataType dataType) { LoquiType loqui = typeGen as LoquiType; var data = typeGen.GetFieldData(); 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(); } string DataAccessor(Accessor accessor, string positionStr, string lenStr) { if (objGen.GetObjectType() == ObjectType.Mod) { return($"{nameof(PluginBinaryOverlay)}.{nameof(PluginBinaryOverlay.LockExtractMemory)}({accessor}, {positionStr}, {lenStr})"); } else { return($"{accessor}.Slice({positionStr})"); } } string recConverter = $"default({nameof(TypedParseParams)})"; if (loqui.GetFieldData()?.RecordTypeConverter != null && loqui.GetFieldData().RecordTypeConverter.FromConversions.Count > 0) { recConverter = $"{objGen.RegistrationName}.{loqui.Name}Converter"; } var isRequiredRecord = !loqui.Nullable && data.HasTrigger; if (dataType == null) { if (loqui.GetFieldData()?.HasTrigger ?? false) { if (loqui is GroupType) { fg.AppendLine($"private List<{GetLocationObjectString(objGen)}>? _{typeGen.Name}Locations;"); using (new LineWrapper(fg)) { if (loqui.IsNullable) { fg.Append($"public "); } else { fg.Append($"private "); } fg.Append( $"{loqui.Interface(getter: true, internalInterface: true)}{(typeGen.CanBeNullable(getter: true) ? "?" : null)} "); if (!loqui.IsNullable || isRequiredRecord) { fg.Append("_"); } fg.Append($"{typeGen.Name}"); fg.Append($" => _{typeGen.Name}Locations != null ? "); fg.Append( $"{this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(_data, _{typeGen.Name}Locations, _package"); if (!recConverter.StartsWith("default(")) { fg.Append($", {recConverter}"); } fg.Append($") "); fg.Append($": default;"); } } else if (loqui.TargetObjectGeneration.IsTypelessStruct()) { if (loqui.Singleton || isRequiredRecord) { fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)}? _{typeGen.Name};"); } else if (loqui.Nullable) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)}? {typeGen.Name} {{ get; private set; }}"); } } else { var severalSubTypes = data.GenerationTypes .Select(i => i.Value) .WhereCastable <TypeGeneration, LoquiType>() .Where(loqui => !loqui?.TargetObjectGeneration?.Abstract ?? true) .CountGreaterThan(1); if (severalSubTypes) { fg.AppendLine($"private {nameof(RecordType)} _{typeGen.Name}Type;"); } if (data.OverflowRecordType.HasValue) { fg.AppendLine($"private int? _{typeGen.Name}LengthOverride;"); } fg.AppendLine($"private {GetLocationObjectString(objGen)}? _{typeGen.Name}Location;"); using (new LineWrapper(fg)) { if (loqui.IsNullable) { fg.Append($"public "); } else { fg.Append($"private "); } fg.Append($"{loqui.Interface(getter: true, internalInterface: true)}{(typeGen.CanBeNullable(getter: true) ? "?" : null)} "); if (!loqui.IsNullable || isRequiredRecord) { fg.Append("_"); } fg.Append($"{typeGen.Name}"); if (!severalSubTypes) { fg.Append($" => _{typeGen.Name}Location.HasValue ? "); fg.Append($"{this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{typeGen.Name}Location!.Value.Min", $"_{typeGen.Name}Location!.Value.Max")}, _package), _package{(data.OverflowRecordType.HasValue ? $", new {nameof(TypedParseParams)}(_{typeGen.Name}LengthOverride, null)" : null)}"); if (!recConverter.StartsWith("default(")) { fg.Append($", {recConverter}"); } fg.Append($") "); fg.Append($": default;"); } } if (severalSubTypes) { using (new BraceWrapper(fg)) { fg.AppendLine("get"); using (new BraceWrapper(fg)) { fg.AppendLine($"if (!_{typeGen.Name}Location.HasValue) return default;"); fg.AppendLine($"switch (_{typeGen.Name}Type.TypeInt)"); using (new BraceWrapper(fg)) { foreach (var gen in data.GenerationTypes) { if (!(gen.Value is LoquiType subLoq)) { continue; } if (subLoq?.TargetObjectGeneration?.Abstract ?? false) { continue; } foreach (var trigger in gen.Key) { fg.AppendLine($"case 0x{trigger.TypeInt.ToString("X")}: // {trigger.Type}"); } using (new DepthWrapper(fg)) using (new LineWrapper(fg)) { fg.Append($"return {this.Module.BinaryOverlayClassName(subLoq)}.{subLoq.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{subLoq.Name}Location!.Value.Min", $"_{subLoq.Name}Location!.Value.Max")}, _package), _package"); if (!loqui.Singleton) { fg.Append($", {recConverter}"); } fg.Append($");"); } } fg.AppendLine("default:"); using (new DepthWrapper(fg)) { fg.AppendLine("throw new ArgumentException();"); } } } } } } } else { if (!loqui.Singleton) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)} {typeGen.Name} => {this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({dataAccessor}.Slice({passedLengthAccessor ?? "0x0"}), _package), _package, {recConverter});"); } else { fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)} _{typeGen.Name} {{ get; private set; }}"); } } } else { isRequiredRecord = true; DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor); fg.AppendLine($"private {loqui.Interface(getter: true, internalInterface: true)}? _{typeGen.Name} => _{typeGen.Name}_IsSet ? {this.Module.BinaryOverlayClassName(loqui)}.{loqui.TargetObjectGeneration.Name}Factory(new {nameof(OverlayStream)}({DataAccessor(dataAccessor, $"_{typeGen.Name}Location", null)}, _package), _package) : default;"); } if (loqui.Singleton || isRequiredRecord) { fg.AppendLine($"public {loqui.Interface(getter: true, internalInterface: true)} {typeGen.Name} => _{typeGen.Name} ?? new {loqui.DirectTypeName}({(loqui.ThisConstruction ? "this" : null)});"); } }
public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLengthAccessor, DataType dataType = null) { passedLengthAccessor ??= "0x0"; var data = typeGen.GetFieldData(); 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 (data.HasTrigger) { fg.AppendLine($"private int? _{typeGen.Name}Location;"); } if (data.RecordType.HasValue) { if (dataType != null) { throw new ArgumentException(); } dataAccessor = $"{nameof(HeaderTranslation)}.{nameof(HeaderTranslation.ExtractSubrecordMemory)}({dataAccessor}, _{typeGen.Name}Location.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)})"; fg.AppendLine($"public {typeGen.TypeName(getter: true)}{(typeGen.Nullable ? "?" : null)} {typeGen.Name} => _{typeGen.Name}Location.HasValue ? {GenerateForTypicalWrapper(objGen, typeGen, dataAccessor, "_package")} : {typeGen.GetDefault(getter: true)};"); } else { var expectedLen = await this.ExpectedLength(objGen, typeGen); if (this.CustomWrapper != null) { if (CustomWrapper(fg, objGen, typeGen, dataAccessor, passedLengthAccessor)) { return; } } if (dataType == null) { if (typeGen.Nullable) { if (!typeGen.CanBeNullable(getter: true)) { throw new NotImplementedException(); //fg.AppendLine($"public bool {typeGen.Name}_IsSet => {dataAccessor}.Length >= {(currentPosition + this.ExpectedLength(objGen, typeGen).Value)};"); //fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Span.Slice({currentPosition}, {this.ExpectedLength(objGen, typeGen).Value})", "_package")};"); } else { string passed = int.TryParse(passedLengthAccessor.TrimStart("0x"), System.Globalization.NumberStyles.HexNumber, null, out var passedInt) ? (passedInt + expectedLen.Value).ToString() : $"({passedLengthAccessor} + {expectedLen.Value})"; fg.AppendLine($"public {typeGen.TypeName(getter: true)}? {typeGen.Name} => {dataAccessor}.Length >= {passed} ? {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Slice({passedLengthAccessor}{(expectedLen != null ? $", 0x{expectedLen.Value:X}" : null)})", "_package")} : {typeGen.GetDefault(getter: true)};"); } } else { fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Slice({passedLengthAccessor ?? "0x0"}{(expectedLen != null ? $", 0x{expectedLen.Value:X}" : null)})", "_package")};"); } } else { DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor); fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => _{typeGen.Name}_IsSet ? {GenerateForTypicalWrapper(objGen, typeGen, $"{dataAccessor}.Slice(_{typeGen.Name}Location{(expectedLen.HasValue ? $", {expectedLen.Value}" : null)})", "_package")} : {typeGen.GetDefault(getter: true)};"); } } }
public override async Task GenerateWrapperFields( FileGeneration fg, ObjectGeneration objGen, TypeGeneration typeGen, Accessor dataAccessor, int?currentPosition, string passedLengthAccessor, DataType dataType) { var data = typeGen.GetFieldData(); 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 (data.HasTrigger) { fg.AppendLine($"private int? _{typeGen.Name}Location;"); if (typeGen.CanBeNullable(getter: true)) { dataAccessor = $"{nameof(HeaderTranslation)}.{nameof(HeaderTranslation.ExtractSubrecordMemory)}({dataAccessor}, _{typeGen.Name}Location.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)})"; fg.AppendLine($"public {typeGen.TypeName(getter: true)}{(typeGen.Nullable ? "?" : null)} {typeGen.Name} => _{typeGen.Name}Location.HasValue ? {dataAccessor}[0] : default(Byte{(typeGen.Nullable ? "?" : null)});"); } else { fg.AppendLine($"public bool {typeGen.Name}_IsSet => _{typeGen.Name}Location.HasValue;"); if (dataType != null) { throw new ArgumentException(); } dataAccessor = $"{nameof(HeaderTranslation)}.{nameof(HeaderTranslation.ExtractSubrecordMemory)}({dataAccessor}, _{typeGen.Name}Location.Value, _package.{nameof(BinaryOverlayFactoryPackage.MetaData)}.{nameof(ParsingBundle.Constants)})"; fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => _{typeGen.Name}Location.HasValue ? {dataAccessor}[0] : default(Byte{(typeGen.Nullable ? "?" : null)});"); } } else { if (dataType == null) { fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => {dataAccessor}.Span[{passedLengthAccessor ?? "0x0"}];"); } else { DataBinaryTranslationGeneration.GenerateWrapperExtraMembers(fg, dataType, objGen, typeGen, passedLengthAccessor); fg.AppendLine($"public {typeGen.TypeName(getter: true)} {typeGen.Name} => _{typeGen.Name}_IsSet ? {dataAccessor}.Span[_{typeGen.Name}Location] : default;"); } } }