pub const RUNTIME_SOURCE: &str = "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2026 The Hyperlight Authors.\n\n// Support types for C# bindings generated by hyperlight-component-csharp.\n// The encoding is specified in docs/component-wire-format.md.\n\n#nullable enable\n// Members named after WIT types and object overrides need no docs.\n#pragma warning disable CS1591\n\nusing System;\nusing System.Buffers.Binary;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace Hyperlight.Component\n{\n /// <summary>Calls guest functions by wire name.</summary>\n public interface IGuestCaller\n {\n /// <summary>\n /// Calls <paramref name=\"function\"/> with one encoded buffer per\n /// parameter and returns the encoded result.\n /// </summary>\n byte[] Call(string function, byte[][] args);\n }\n\n /// <summary>Registers host functions by wire name.</summary>\n public interface IHostFunctionRegistry\n {\n /// <summary>\n /// Registers <paramref name=\"implementation\"/>, which receives one\n /// encoded buffer per parameter and returns the encoded result.\n /// </summary>\n void Register(string function, int parameterCount, Func<byte[][], byte[]> implementation);\n }\n\n /// <summary>Thrown when encoded data does not match the expected type.</summary>\n public sealed class WireFormatException : Exception\n {\n public WireFormatException(string message) : base(message) { }\n }\n\n /// <summary>The payload of a <c>result</c> case without a type.</summary>\n public readonly struct Unit : IEquatable<Unit>\n {\n public bool Equals(Unit other) => true;\n public override bool Equals(object? obj) => obj is Unit;\n public override int GetHashCode() => 0;\n public override string ToString() => \"()\";\n\n public static bool operator ==(Unit left, Unit right) => true;\n\n public static bool operator !=(Unit left, Unit right) => false;\n }\n\n /// <summary>\n /// A WIT <c>option</c> whose payload is itself an <c>option</c>.\n /// Other options map to nullable types.\n /// </summary>\n public readonly struct Option<T> : IEquatable<Option<T>>\n {\n private readonly T _value;\n\n private Option(T value)\n {\n HasValue = true;\n _value = value;\n }\n\n public static Option<T> None => default;\n\n public static Option<T> Some(T value) => new(value);\n\n public bool HasValue { get; }\n\n public T Value => HasValue ? _value : throw new InvalidOperationException(\"option has no value\");\n\n public bool Equals(Option<T> other) =>\n HasValue == other.HasValue && (!HasValue || EqualityComparer<T>.Default.Equals(_value, other._value));\n\n public override bool Equals(object? obj) => obj is Option<T> other && Equals(other);\n\n public override int GetHashCode() => HasValue ? HashCode.Combine(true, _value) : 0;\n\n public override string ToString() => HasValue ? $\"Some({_value})\" : \"None\";\n\n public static bool operator ==(Option<T> left, Option<T> right) => left.Equals(right);\n\n public static bool operator !=(Option<T> left, Option<T> right) => !left.Equals(right);\n }\n\n /// <summary>A WIT <c>result</c>.</summary>\n public readonly struct Result<TOk, TErr> : IEquatable<Result<TOk, TErr>>\n {\n private readonly TOk _ok;\n private readonly TErr _err;\n\n private Result(bool isOk, TOk ok, TErr err)\n {\n IsOk = isOk;\n _ok = ok;\n _err = err;\n }\n\n public static Result<TOk, TErr> FromOk(TOk value) => new(true, value, default!);\n\n public static Result<TOk, TErr> FromErr(TErr value) => new(false, default!, value);\n\n public bool IsOk { get; }\n\n public TOk Ok => IsOk ? _ok : throw new InvalidOperationException(\"result is an error\");\n\n public TErr Err => IsOk ? throw new InvalidOperationException(\"result is not an error\") : _err;\n\n public bool Equals(Result<TOk, TErr> other) =>\n IsOk == other.IsOk && (IsOk\n ? EqualityComparer<TOk>.Default.Equals(_ok, other._ok)\n : EqualityComparer<TErr>.Default.Equals(_err, other._err));\n\n public override bool Equals(object? obj) => obj is Result<TOk, TErr> other && Equals(other);\n\n public override int GetHashCode() =>\n IsOk ? HashCode.Combine(true, _ok) : HashCode.Combine(false, _err);\n\n public override string ToString() => IsOk ? $\"Ok({_ok})\" : $\"Err({_err})\";\n\n public static bool operator ==(Result<TOk, TErr> left, Result<TOk, TErr> right) => left.Equals(right);\n\n public static bool operator !=(Result<TOk, TErr> left, Result<TOk, TErr> right) => !left.Equals(right);\n }\n\n /// <summary>Encodes values in the Hyperlight component wire format.</summary>\n public sealed class WireWriter\n {\n // Throws on lone surrogates, which a WIT string cannot hold.\n private static readonly UTF8Encoding StrictUtf8 = new(false, true);\n\n private byte[] _buffer;\n private int _length;\n\n public WireWriter(int capacity = 64)\n {\n _buffer = new byte[Math.Max(capacity, 1)];\n }\n\n /// <summary>The generated world\'s resource tables, for writing handles.</summary>\n public object? Resources { get; init; }\n\n /// <summary>The call that handles written here are given or lent in.</summary>\n public CallScope? Scope { get; init; }\n\n public byte[] ToArray() => _buffer.AsSpan(0, _length).ToArray();\n\n public void Bool(bool value) => U8(value ? (byte)1 : (byte)0);\n\n public void U8(byte value) => Grow(1)[0] = value;\n\n public void S8(sbyte value) => Grow(1)[0] = unchecked((byte)value);\n\n public void U16(ushort value) => BinaryPrimitives.WriteUInt16LittleEndian(Grow(2), value);\n\n public void S16(short value) => BinaryPrimitives.WriteInt16LittleEndian(Grow(2), value);\n\n public void U32(uint value) => BinaryPrimitives.WriteUInt32LittleEndian(Grow(4), value);\n\n public void S32(int value) => BinaryPrimitives.WriteInt32LittleEndian(Grow(4), value);\n\n public void U64(ulong value) => BinaryPrimitives.WriteUInt64LittleEndian(Grow(8), value);\n\n public void S64(long value) => BinaryPrimitives.WriteInt64LittleEndian(Grow(8), value);\n\n public void F32(float value) => BinaryPrimitives.WriteSingleLittleEndian(Grow(4), value);\n\n public void F64(double value) => BinaryPrimitives.WriteDoubleLittleEndian(Grow(8), value);\n\n public void Char(Rune value) => U32((uint)value.Value);\n\n public void String(string value)\n {\n ArgumentNullException.ThrowIfNull(value);\n var length = StrictUtf8.GetByteCount(value);\n Length(length);\n StrictUtf8.GetBytes(value, Grow(length));\n }\n\n /// <summary>Writes the element count of a <c>list</c>.</summary>\n public void Length(int count) => U32(checked((uint)count));\n\n /// <summary>Writes a <c>list<u8></c>.</summary>\n public void Bytes(byte[] value)\n {\n ArgumentNullException.ThrowIfNull(value);\n Length(value.Length);\n value.CopyTo(Grow(value.Length));\n }\n\n /// <summary>Writes a <c>list<u8, N></c>.</summary>\n public void FixedBytes(byte[] value, int count)\n {\n CheckFixedLength(value, count);\n value.CopyTo(Grow(count));\n }\n\n /// <summary>Writes the low <paramref name=\"byteCount\"/> bytes of a <c>flags</c> bitmask.</summary>\n public void Flags(uint bits, int byteCount)\n {\n var bytes = Grow(byteCount);\n for (var i = 0; i < byteCount; i++)\n {\n bytes[i] = (byte)(bits >> (8 * i));\n }\n }\n\n /// <summary>Throws unless a fixed-length list has <paramref name=\"count\"/> elements.</summary>\n public static void CheckFixedLength<T>(IReadOnlyCollection<T> value, int count)\n {\n ArgumentNullException.ThrowIfNull(value);\n if (value.Count != count)\n {\n throw new ArgumentException($\"fixed-length list needs {count} elements, got {value.Count}\");\n }\n }\n\n private Span<byte> Grow(int count)\n {\n if (_buffer.Length - _length < count)\n {\n Array.Resize(ref _buffer, Math.Max(checked(_length + count), _buffer.Length * 2));\n }\n var span = _buffer.AsSpan(_length, count);\n _length += count;\n return span;\n }\n }\n\n /// <summary>Decodes values in the Hyperlight component wire format.</summary>\n public ref struct WireReader\n {\n private static readonly UTF8Encoding StrictUtf8 = new(false, true);\n\n private readonly ReadOnlySpan<byte> _data;\n private int _position;\n\n public WireReader(ReadOnlySpan<byte> data)\n {\n _data = data;\n _position = 0;\n }\n\n /// <summary>The generated world\'s resource tables, for reading handles.</summary>\n public object? Resources { get; init; }\n\n public bool Bool() => U8() != 0;\n\n public byte U8() => Take(1)[0];\n\n public sbyte S8() => unchecked((sbyte)Take(1)[0]);\n\n public ushort U16() => BinaryPrimitives.ReadUInt16LittleEndian(Take(2));\n\n public short S16() => BinaryPrimitives.ReadInt16LittleEndian(Take(2));\n\n public uint U32() => BinaryPrimitives.ReadUInt32LittleEndian(Take(4));\n\n public int S32() => BinaryPrimitives.ReadInt32LittleEndian(Take(4));\n\n public ulong U64() => BinaryPrimitives.ReadUInt64LittleEndian(Take(8));\n\n public long S64() => BinaryPrimitives.ReadInt64LittleEndian(Take(8));\n\n public float F32() => BinaryPrimitives.ReadSingleLittleEndian(Take(4));\n\n public double F64() => BinaryPrimitives.ReadDoubleLittleEndian(Take(8));\n\n public Rune Char()\n {\n var value = U32();\n if (!Rune.IsValid(value))\n {\n throw new WireFormatException($\"invalid char {value:x}\");\n }\n return new Rune(value);\n }\n\n public string String()\n {\n var bytes = Take(Length());\n try\n {\n return StrictUtf8.GetString(bytes);\n }\n catch (DecoderFallbackException e)\n {\n throw new WireFormatException($\"invalid UTF-8: {e.Message}\");\n }\n }\n\n /// <summary>Reads the element count of a <c>list</c>.</summary>\n public int Length()\n {\n var count = U32();\n // Every element takes at least one byte.\n if (count > (uint)(_data.Length - _position))\n {\n throw new WireFormatException($\"list length {count} exceeds remaining input\");\n }\n return (int)count;\n }\n\n /// <summary>Reads a <c>list<u8></c>.</summary>\n public byte[] Bytes() => Take(Length()).ToArray();\n\n /// <summary>Reads a <c>list<u8, N></c>.</summary>\n public byte[] FixedBytes(int count) => Take(count).ToArray();\n\n /// <summary>Reads a four byte tag that must be below <paramref name=\"cases\"/>.</summary>\n public uint Tag32(uint cases)\n {\n var tag = U32();\n if (tag >= cases)\n {\n throw new WireFormatException($\"invalid tag {tag}\");\n }\n return tag;\n }\n\n /// <summary>\n /// Reads a <c>flags</c> bitmask of <paramref name=\"byteCount\"/> bytes\n /// and keeps the bits in <paramref name=\"mask\"/>.\n /// </summary>\n public uint Flags(int byteCount, uint mask)\n {\n var bytes = Take(byteCount);\n uint bits = 0;\n for (var i = 0; i < byteCount; i++)\n {\n bits |= (uint)bytes[i] << (8 * i);\n }\n return bits & mask;\n }\n\n private ReadOnlySpan<byte> Take(int count)\n {\n if ((uint)count > (uint)(_data.Length - _position))\n {\n throw new WireFormatException(\"unexpected end of input\");\n }\n var span = _data.Slice(_position, count);\n _position += count;\n return span;\n }\n }\n\n /// <summary>\n /// Host objects of one resource type that the guest refers to by\n /// handle. A handle is an index into the table.\n /// </summary>\n public sealed class ResourceTable<T> where T : class\n {\n private readonly List<Entry> _entries = new();\n\n private sealed class Entry\n {\n public T? Value;\n public bool Lent;\n }\n\n /// <summary>\n /// Gives <paramref name=\"value\"/> to the guest. With\n /// <paramref name=\"scope\"/>, the gift is undone unless the call\n /// starts.\n /// </summary>\n public uint Give(T value, CallScope? scope = null)\n {\n var handle = Add(value, lent: false);\n scope?.AddGift(() => Clear(handle));\n return handle;\n }\n\n /// <summary>Lends <paramref name=\"value\"/> to the guest until <paramref name=\"scope\"/> ends.</summary>\n public uint Lend(T value, CallScope scope)\n {\n ArgumentNullException.ThrowIfNull(scope);\n var handle = Add(value, lent: true);\n scope.AddLoan(() => Clear(handle));\n return handle;\n }\n\n private void Clear(uint handle)\n {\n lock (_entries)\n {\n _entries[(int)handle].Value = null;\n }\n }\n\n /// <summary>Takes back a value the guest owns.</summary>\n public T Take(uint handle)\n {\n lock (_entries)\n {\n var entry = Get(handle);\n if (entry.Lent || entry.Value is null)\n {\n throw new WireFormatException($\"resource handle {handle} is not owned\");\n }\n var value = entry.Value;\n entry.Value = null;\n return value;\n }\n }\n\n /// <summary>Returns the value for a handle the guest lends back to the host.</summary>\n public T Borrow(uint handle)\n {\n lock (_entries)\n {\n return Get(handle).Value ?? throw new WireFormatException($\"resource handle {handle} is not valid\");\n }\n }\n\n private uint Add(T value, bool lent)\n {\n ArgumentNullException.ThrowIfNull(value);\n lock (_entries)\n {\n _entries.Add(new Entry { Value = value, Lent = lent });\n return checked((uint)(_entries.Count - 1));\n }\n }\n\n private Entry Get(uint handle) =>\n handle < (uint)_entries.Count\n ? _entries[(int)handle]\n : throw new WireFormatException($\"invalid resource handle {handle}\");\n }\n\n /// <summary>\n /// Resources lent to the guest for one call, and resources given to it\n /// before the call starts.\n /// </summary>\n public sealed class CallScope\n {\n private List<Action>? _loans;\n private List<Action>? _gifts;\n\n internal void AddLoan(Action revoke) => (_loans ??= new()).Add(revoke);\n\n internal void AddGift(Action undo) => (_gifts ??= new()).Add(undo);\n\n /// <summary>Marks the call as started, which completes the gifts.</summary>\n public void Commit() => _gifts?.Clear();\n\n /// <summary>Revokes every loan, and undoes gifts made before <see cref=\"Commit\"/>.</summary>\n public void End()\n {\n Run(_gifts);\n Run(_loans);\n }\n\n private static void Run(List<Action>? actions)\n {\n if (actions is null)\n {\n return;\n }\n foreach (var action in actions)\n {\n action();\n }\n actions.Clear();\n }\n }\n}\n";Expand description
C# source for the Hyperlight.Component namespace that generated
bindings depend on.