| File: _generated\0\LayoutSet.g.cs | Web Access |
| Project: src\runtime\src\native\managed\cdac\Microsoft.Diagnostics.DataContractReader.Contracts\Microsoft.Diagnostics.DataContractReader.Contracts.csproj (Microsoft.Diagnostics.DataContractReader.Contracts) |
// <auto-generated/> #nullable enable using System; using System.Collections.Generic; using Microsoft.Diagnostics.DataContractReader.Contracts; namespace Microsoft.Diagnostics.DataContractReader.Generated; /// <summary> /// An ordered set of type layouts resolved from multiple type info sources. /// Field lookups iterate sources in priority order (native cdac descriptor /// first, then managed type metadata), trying each candidate field name /// per source. Sources are resolved lazily. /// </summary> internal readonly struct LayoutSet { private readonly LazyLayout[] _layouts; public LayoutSet(LazyLayout[] layouts) { _layouts = layouts; } public ulong InstanceSize { get { foreach (LazyLayout layout in _layouts) { if (layout.Get()?.Size is uint s) return s; } throw new InvalidOperationException("No layout source has a known instance size."); } } public bool TrySelect(TargetPointer address, out Target.TypeInfo type, out TargetPointer baseAddr, out string name, params ReadOnlySpan<string> names) { foreach (LazyLayout layout in _layouts) { if (layout.Get() is not Target.TypeInfo ti) continue; foreach (string candidate in names) { if (ti.Fields.ContainsKey(candidate)) { type = ti; baseAddr = address; name = candidate; return true; } } } type = default!; baseAddr = default; name = default!; return false; } public void Select(TargetPointer address, out Target.TypeInfo type, out TargetPointer baseAddr, out string name, params ReadOnlySpan<string> names) { if (!TrySelect(address, out type, out baseAddr, out name, names)) { throw new InvalidOperationException(FormatMissing(names)); } } private static string FormatMissing(ReadOnlySpan<string> names) => $"Field not found in any layout (names=[{string.Join(",", names.ToArray())}])."; public static LayoutSet Resolve(Target target, string[] names) { List<LazyLayout> layouts = new(2); foreach (string name in names) { if (target.TryGetTypeInfo(name, out Target.TypeInfo n)) { layouts.Add(new LazyLayout(n)); break; } } if (target.Contracts.TryGetContract(out IManagedTypeSource mts)) { layouts.Add(new LazyLayout(() => { foreach (string name in names) { if (mts.TryGetTypeInfo(name, out Target.TypeInfo m)) return m; } return null; })); } return new LayoutSet(layouts.ToArray()); } } /// <summary> /// Memoized lazy holder for a single <see cref="Target.TypeInfo"/> source. /// Constructed either with a pre-resolved value (for cheap sources) or with /// a factory invoked on first access (for expensive sources). /// </summary> internal sealed class LazyLayout { private Func<Target.TypeInfo?>? _factory; private Target.TypeInfo? _value; public LazyLayout(Target.TypeInfo value) { _value = value; } public LazyLayout(Func<Target.TypeInfo?> factory) { _factory = factory; } public Target.TypeInfo? Get() { if (_factory is not null) { _value = _factory(); _factory = null; } return _value; } }