diff --git a/.gitignore b/.gitignore index 64fa334..752be25 100644 --- a/.gitignore +++ b/.gitignore @@ -336,3 +336,6 @@ ASALocalRun/ # Capnp code behind *.capnp.cs /globalPackages + +# Coverage results folder +coverage/ diff --git a/Benchmarking/Benchmark/Benchmark.csproj b/Benchmarking/Benchmark/Benchmark.csproj index 051d009..5193d73 100644 --- a/Benchmarking/Benchmark/Benchmark.csproj +++ b/Benchmarking/Benchmark/Benchmark.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/Benchmarking/Benchmark/Program.cs b/Benchmarking/Benchmark/Program.cs index 16a0924..fe51c0a 100644 --- a/Benchmarking/Benchmark/Program.cs +++ b/Benchmarking/Benchmark/Program.cs @@ -11,8 +11,11 @@ namespace Benchmark { static void Main(string[] args) { - BenchmarkRunner.Run(); - BenchmarkRunner.Run(); + if (args.Length == 0 || args[0] == "grpc") + BenchmarkRunner.Run(); + + if (args.Length == 0 || args[0] == "capnp") + BenchmarkRunner.Run(); } } } diff --git a/Benchmarking/CapnpBench.sln b/Benchmarking/CapnpBench.sln index 061559d..700be3a 100644 --- a/Benchmarking/CapnpBench.sln +++ b/Benchmarking/CapnpBench.sln @@ -3,11 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29728.190 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EchoServiceGrpc", "EchoServiceGrpc\EchoServiceGrpc.csproj", "{D59C7B71-3887-426B-A636-2DBDA0549817}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmark", "Benchmark\Benchmark.csproj", "{7F7580CA-CCF0-4650-87BF-502D51A8F435}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "Benchmark\Benchmark.csproj", "{7F7580CA-CCF0-4650-87BF-502D51A8F435}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EchoServiceCapnp", "EchoServiceCapnp\EchoServiceCapnp.csproj", "{309A4A26-F29E-4F49-AB49-76BAE0FD7D62}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EchoServiceCapnp", "EchoServiceCapnp\EchoServiceCapnp.csproj", "{309A4A26-F29E-4F49-AB49-76BAE0FD7D62}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EchoServiceGrpc", "EchoServiceGrpc\EchoServiceGrpc.csproj", "{C9CEE2AD-AC6F-4CBD-A83D-2784832C1E37}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,10 +15,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D59C7B71-3887-426B-A636-2DBDA0549817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D59C7B71-3887-426B-A636-2DBDA0549817}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D59C7B71-3887-426B-A636-2DBDA0549817}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D59C7B71-3887-426B-A636-2DBDA0549817}.Release|Any CPU.Build.0 = Release|Any CPU {7F7580CA-CCF0-4650-87BF-502D51A8F435}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7F7580CA-CCF0-4650-87BF-502D51A8F435}.Debug|Any CPU.Build.0 = Debug|Any CPU {7F7580CA-CCF0-4650-87BF-502D51A8F435}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -27,6 +23,10 @@ Global {309A4A26-F29E-4F49-AB49-76BAE0FD7D62}.Debug|Any CPU.Build.0 = Debug|Any CPU {309A4A26-F29E-4F49-AB49-76BAE0FD7D62}.Release|Any CPU.ActiveCfg = Release|Any CPU {309A4A26-F29E-4F49-AB49-76BAE0FD7D62}.Release|Any CPU.Build.0 = Release|Any CPU + {C9CEE2AD-AC6F-4CBD-A83D-2784832C1E37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C9CEE2AD-AC6F-4CBD-A83D-2784832C1E37}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C9CEE2AD-AC6F-4CBD-A83D-2784832C1E37}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C9CEE2AD-AC6F-4CBD-A83D-2784832C1E37}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Benchmarking/CapnpProfile/CapnpProfile.csproj b/Benchmarking/CapnpProfile/CapnpProfile.csproj index 953f368..9ffe4d3 100644 --- a/Benchmarking/CapnpProfile/CapnpProfile.csproj +++ b/Benchmarking/CapnpProfile/CapnpProfile.csproj @@ -9,11 +9,12 @@ full true x64 + - - + + diff --git a/Benchmarking/CapnpProfile/EnginePair.cs b/Benchmarking/CapnpProfile/EnginePair.cs new file mode 100644 index 0000000..815e12a --- /dev/null +++ b/Benchmarking/CapnpProfile/EnginePair.cs @@ -0,0 +1,63 @@ +using Capnp; +using Capnp.Rpc; +using System.Collections.Generic; + +namespace CapnpProfile +{ + class EnginePair + { + class EngineChannel : IEndpoint + { + readonly Queue _frameBuffer = new Queue(); + bool _dismissed; + + public EngineChannel() + { + } + + public RpcEngine.RpcEndpoint OtherEndpoint { get; set; } + public bool HasBufferedFrames => _frameBuffer.Count > 0; + public int FrameCounter { get; private set; } + + + public void Dismiss() + { + if (!_dismissed) + { + _dismissed = true; + OtherEndpoint.Dismiss(); + } + } + + public void Forward(WireFrame frame) + { + if (_dismissed) + return; + + OtherEndpoint.Forward(frame); + } + } + + readonly EngineChannel _channel1, _channel2; + + public RpcEngine Engine1 { get; } + public RpcEngine Engine2 { get; } + public RpcEngine.RpcEndpoint Endpoint1 { get; } + public RpcEngine.RpcEndpoint Endpoint2 { get; } + + public EnginePair() + { + Engine1 = new RpcEngine(); + Engine2 = new RpcEngine(); + _channel1 = new EngineChannel(); + Endpoint1 = Engine1.AddEndpoint(_channel1); + _channel2 = new EngineChannel(); + Endpoint2 = Engine2.AddEndpoint(_channel2); + _channel1.OtherEndpoint = Endpoint2; + _channel2.OtherEndpoint = Endpoint1; + } + + public int Channel1SendCount => _channel1.FrameCounter; + public int Channel2SendCount => _channel2.FrameCounter; + } +} diff --git a/Benchmarking/CapnpProfile/Program.cs b/Benchmarking/CapnpProfile/Program.cs index 274bb97..97a28ce 100644 --- a/Benchmarking/CapnpProfile/Program.cs +++ b/Benchmarking/CapnpProfile/Program.cs @@ -7,25 +7,62 @@ using System.Threading.Tasks; namespace CapnpProfile { + class Program { - static async Task Main(string[] args) + static async Task Run(IEchoer echoer) { - using var server = new TcpRpcServer(); - server.Main = new CapnpEchoService(); - server.AddBuffering(); - server.StartAccepting(IPAddress.Any, 5002); - using var client = new TcpRpcClient("localhost", 5002); - await client.WhenConnected; - using var echoer = client.GetMain(); var payload = new byte[20]; new Random().NextBytes(payload); +#if SOTASK_PERF + int counter = 0; +#endif + while (true) { var result = await echoer.Echo(payload); if (result.Count != payload.Length) throw new InvalidOperationException("Echo server malfunction"); + +#if SOTASK_PERF + if (++counter == 10000) + { + counter = 0; + + Console.WriteLine($"StrictlyOrderedTask performance statistics:"); + Console.WriteLine($"AwaitInternal: max. {Capnp.Util.StrictlyOrderedTaskExtensions.Stats.AwaitInternalMaxOuterIterations} outer iterations"); + Console.WriteLine($"AwaitInternal: max. {Capnp.Util.StrictlyOrderedTaskExtensions.Stats.AwaitInternalMaxInnerIterations} inner iterations"); + Console.WriteLine($"OnCompleted: max. {Capnp.Util.StrictlyOrderedTaskExtensions.Stats.OnCompletedMaxSpins} iterations"); + } +#endif + } + } + + static async Task Main(string[] args) + { + + if (args.Length > 0) + { + var pair = new EnginePair(); + pair.Engine1.Main = new CapnpEchoService(); + var echoer = (CapabilityReflection.CreateProxy(pair.Endpoint2.QueryMain()) as IEchoer); + + await Run(echoer); + } + else + { + using var server = new TcpRpcServer(); + server.Main = new CapnpEchoService(); + server.AddBuffering(); + server.StartAccepting(IPAddress.Any, 5002); + using var client = new TcpRpcClient(); + client.AddBuffering(); + client.Connect("localhost", 5002); + await client.WhenConnected; + using var echoer = client.GetMain(); + + await Run(echoer); } } } diff --git a/Benchmarking/EchoServiceCapnp/EchoServiceCapnp.csproj b/Benchmarking/EchoServiceCapnp/EchoServiceCapnp.csproj index 2ef80ba..cbc0e54 100644 --- a/Benchmarking/EchoServiceCapnp/EchoServiceCapnp.csproj +++ b/Benchmarking/EchoServiceCapnp/EchoServiceCapnp.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/Benchmarking/EchoServiceGrpc/EchoServiceGrpc.csproj b/Benchmarking/EchoServiceGrpc/EchoServiceGrpc.csproj index 861d83c..da2e193 100644 --- a/Benchmarking/EchoServiceGrpc/EchoServiceGrpc.csproj +++ b/Benchmarking/EchoServiceGrpc/EchoServiceGrpc.csproj @@ -5,7 +5,9 @@ - + + Protos\Echo.proto + diff --git a/Benchmarking/EchoServiceGrpc/Program.cs b/Benchmarking/EchoServiceGrpc/Program.cs index f24aee5..a3d05d6 100644 --- a/Benchmarking/EchoServiceGrpc/Program.cs +++ b/Benchmarking/EchoServiceGrpc/Program.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; -namespace EchoService +namespace EchoServiceGrpc2 { public class Program { diff --git a/Benchmarking/EchoServiceGrpc/Protos/Echo.proto b/Benchmarking/EchoServiceGrpc/Protos/Echo.proto deleted file mode 100644 index b1b0c0d..0000000 --- a/Benchmarking/EchoServiceGrpc/Protos/Echo.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -service Echoer { - rpc Echo (EchoRequest) returns (EchoReply); -} - -message EchoRequest { - bytes payload = 1; -} - -message EchoReply { - bytes payload = 1; -} \ No newline at end of file diff --git a/Benchmarking/EchoServiceGrpc/Startup.cs b/Benchmarking/EchoServiceGrpc/Startup.cs index b93a112..3679177 100644 --- a/Benchmarking/EchoServiceGrpc/Startup.cs +++ b/Benchmarking/EchoServiceGrpc/Startup.cs @@ -2,13 +2,14 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using EchoService; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -namespace EchoService +namespace EchoServiceGrpc2 { public class Startup { diff --git a/Benchmarking/EchoServiceGrpc/appsettings.Development.json b/Benchmarking/EchoServiceGrpc/appsettings.Development.json index 1ca5366..fe20c40 100644 --- a/Benchmarking/EchoServiceGrpc/appsettings.Development.json +++ b/Benchmarking/EchoServiceGrpc/appsettings.Development.json @@ -1,10 +1,10 @@ { "Logging": { "LogLevel": { - "Default": "Warning", - "System": "Warning", - "Grpc": "Warning", - "Microsoft": "Warning" + "Default": "Debug", + "System": "Information", + "Grpc": "Information", + "Microsoft": "Information" } } } diff --git a/Benchmarking/NuGet.Config b/Benchmarking/NuGet.Config index 3f0e003..3bb8cd5 100644 --- a/Benchmarking/NuGet.Config +++ b/Benchmarking/NuGet.Config @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/Benchmarking/nuget.config b/Benchmarking/nuget.config index 3f0e003..3bb8cd5 100644 --- a/Benchmarking/nuget.config +++ b/Benchmarking/nuget.config @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/Capnp.Net.Runtime.Core21/Capnp.Net.Runtime.Core21.csproj b/Capnp.Net.Runtime.Core21/Capnp.Net.Runtime.Core21.csproj deleted file mode 100644 index 60c4831..0000000 --- a/Capnp.Net.Runtime.Core21/Capnp.Net.Runtime.Core21.csproj +++ /dev/null @@ -1,113 +0,0 @@ - - - - netcoreapp2.1 - true - Capnp.Net.Runtime - Christian Köllner and contributors - - capnproto-dotnetcore - A Cap'n Proto implementation for .NET Core, runtime assembly for .NET Core 2.1 - Christian Köllner and contributors - MIT - - https://github.com/c80k/capnproto-dotnetcore - https://github.com/c80k/capnproto-dotnetcore - Capnp.Net.Runtime - Capnp - Git - capnp "Cap'n Proto" RPC serialization cerealization - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj b/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj deleted file mode 100644 index 30d40e2..0000000 --- a/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj +++ /dev/null @@ -1,52 +0,0 @@ - - - - netcoreapp2.1 - - false - - Debug;Release - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Capnp.Net.Runtime.Tests/CapabilityReflectionTests.cs b/Capnp.Net.Runtime.Tests/CapabilityReflectionTests.cs new file mode 100644 index 0000000..ccc529d --- /dev/null +++ b/Capnp.Net.Runtime.Tests/CapabilityReflectionTests.cs @@ -0,0 +1,30 @@ +using Capnp.Rpc; +using Capnproto_test.Capnp.Test; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Capnp.Net.Runtime.Tests +{ + [TestClass] + [TestCategory("Coverage")] + public class CapabilityReflectionTests + { + [TestMethod] + public void ValidateCapabilityInterface() + { + Assert.ThrowsException(() => CapabilityReflection.ValidateCapabilityInterface(null)); + CapabilityReflection.ValidateCapabilityInterface(typeof(ITestInterface)); + Assert.ThrowsException(() => CapabilityReflection.ValidateCapabilityInterface(typeof(CapabilityReflectionTests))); + } + + [TestMethod] + public void IsValidCapabilityInterface() + { + Assert.ThrowsException(() => CapabilityReflection.IsValidCapabilityInterface(null)); + Assert.IsTrue(CapabilityReflection.IsValidCapabilityInterface(typeof(ITestInterface))); + Assert.IsFalse(CapabilityReflection.IsValidCapabilityInterface(typeof(CapabilityReflectionTests))); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj b/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.csproj similarity index 73% rename from Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj rename to Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.csproj index 2f47c80..8cfe88d 100644 --- a/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj +++ b/Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.csproj @@ -1,7 +1,7 @@  - net471 + netcoreapp2.1;net471 false @@ -10,18 +10,25 @@ Library Debug;Release + + Capnp.Net.Runtime.Tests DEBUG;TRACE + + TRACE + + + diff --git a/Capnp.Net.Runtime.Tests/DeserializationTests.cs b/Capnp.Net.Runtime.Tests/DeserializationTests.cs index 882d4d7..e42637d 100644 --- a/Capnp.Net.Runtime.Tests/DeserializationTests.cs +++ b/Capnp.Net.Runtime.Tests/DeserializationTests.cs @@ -1,8 +1,15 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Capnp.Net.Runtime.Tests.GenImpls; +using Capnproto_test.Capnp.Test; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using static Capnproto_test.Capnp.Test.TestStructUnion; namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class DeserializationTests { [TestMethod] @@ -144,6 +151,9 @@ namespace Capnp.Net.Runtime.Tests Assert.AreEqual(2, asListOfStructs.Count); Assert.AreEqual(0ul, asListOfStructs[0].ReadDataULong(0)); Assert.AreEqual(ulong.MaxValue, asListOfStructs[1].ReadDataULong(0)); + Assert.ThrowsException(() => asListOfStructs[-1].ReadDataUShort(0)); + Assert.ThrowsException(() => asListOfStructs[3].ReadDataUShort(0)); + CollectionAssert.AreEqual(new ulong[] { 0, ulong.MaxValue }, asListOfStructs.Select(_ => _.ReadDataULong(0)).ToArray()); } [TestMethod] @@ -207,6 +217,22 @@ namespace Capnp.Net.Runtime.Tests Assert.AreEqual(double.PositiveInfinity, asListOfStructs[5].ReadDataDouble(0)); } + [TestMethod] + public void ListOfStructsAsListOfBools() + { + var ds = new DynamicSerializerState(MessageBuilder.Create(128)); + ds.SetListOfStructs(3, 1, 0); + ds.ListBuildStruct(1).WriteData(0, false); + ds.ListBuildStruct(2).WriteData(0, true); + + DeserializerState d = ds; + var asListOfBools = d.RequireList().CastBool(); + Assert.AreEqual(3, asListOfBools.Count); + Assert.AreEqual(false, asListOfBools[0]); + Assert.AreEqual(false, asListOfBools[1]); + Assert.AreEqual(true, asListOfBools[2]); + } + [TestMethod] public void ListOfStructsAsListOfBytes() { @@ -353,5 +379,599 @@ namespace Capnp.Net.Runtime.Tests Assert.AreEqual(double.NegativeInfinity, asListOfDoubles[0]); Assert.AreEqual(double.MaxValue, asListOfDoubles[1]); } + + [TestMethod] + public void NestedLists() + { + var expected = new int[][] { + new int[] { 1, 2, 3 }, + new int[] { 4, 5 }, + new int[] { 6 } }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + Assert.ThrowsException(() => ld.CastText()); + var result = ld.Cast2D(); + Assert.AreEqual(3, result.Count); + for (int i = 0; i < result.Count; i++) + { + CollectionAssert.AreEqual(expected[i], result[i].ToArray()); + } + + Assert.ThrowsException(() => ld.Cast2D()); + } + + [TestMethod] + public void LinearListWrongUse() + { + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(new int[] { 1, 2, 3 }); + DeserializerState d = dss; + var ld = d.RequireList(); + Assert.ThrowsException(() => ld.CastList()); + Assert.ThrowsException(() => ld.CastCapList()); + } + + [TestMethod] + public void NestedLists3D() + { + var expected = new int[][][] { + new int[][] + { + new int[] { 1, 2, 3 }, + new int[] { 4, 5 }, + new int[] { 6 } + }, + new int[][] + { + new int[] { 1, 2, 3 }, + new int[0] + }, + new int[0][] + }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = ld.Cast3D(); + Assert.AreEqual(3, result.Count); + for (int i = 0; i < result.Count; i++) + { + var inner = result[i]; + Assert.AreEqual(expected[i].Length, inner.Count); + + for (int j = 0; j < expected[i].Length; j++) + { + var inner2 = inner[j]; + CollectionAssert.AreEqual(expected[i][j], inner2.ToArray()); + } + } + } + + [TestMethod] + public void NestedListsND() + { + var expected = new int[][][] { + new int[][] + { + new int[] { 1, 2, 3 }, + new int[] { 4, 5 }, + new int[] { 6 } + }, + new int[][] + { + new int[] { 1, 2, 3 }, + new int[0] + }, + new int[0][] + }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = (IReadOnlyList)ld.CastND(3); + Assert.AreEqual(3, result.Count); + for (int i = 0; i < result.Count; i++) + { + var inner = (IReadOnlyList)result[i]; + Assert.AreEqual(expected[i].Length, inner.Count); + + for (int j = 0; j < expected[i].Length; j++) + { + var inner2 = (IReadOnlyList)inner[j]; + CollectionAssert.AreEqual(expected[i][j], inner2.ToArray()); + } + } + } + + [TestMethod] + public void NestedLists3DStruct() + { + var expected = new List>>(); + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + for (int i = 0; i < 3; i++) + { + expected.Add(new List>()); + + for (int j = 0; j <= i; j++) + { + expected[i].Add(new List()); + + for (int k = 0; k <= j; k++) + { + var x = b.CreateObject(); + x.SomeText = $"{i}, {j}, {k}"; + expected[i][j].Add(x); + } + } + } + + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = ld.Cast3D(_ => new SomeStruct.READER(_)); + Assert.AreEqual(3, result.Count); + for (int i = 0; i < result.Count; i++) + { + var inner = result[i]; + Assert.AreEqual(i + 1, inner.Count); + + for (int j = 0; j < inner.Count; j++) + { + var inner2 = inner[j]; + Assert.AreEqual(j + 1, inner2.Count); + + for (int k = 0; k < inner2.Count; k++) + { + Assert.AreEqual($"{i}, {j}, {k}", inner2[k].SomeText); + } + } + } + } + + [TestMethod] + public void NestedListsNDStruct() + { + var expected = new List>>(); + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + for (int i = 0; i < 3; i++) + { + expected.Add(new List>()); + + for (int j = 0; j <= i; j++) + { + expected[i].Add(new List()); + + for (int k = 0; k <= j; k++) + { + var x = b.CreateObject(); + x.SomeText = $"{i}, {j}, {k}"; + expected[i][j].Add(x); + } + } + } + + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = (IReadOnlyList)ld.CastND(3, _ => new SomeStruct.READER(_)); + Assert.AreEqual(3, result.Count); + for (int i = 0; i < result.Count; i++) + { + var inner = (IReadOnlyList)result[i]; + Assert.AreEqual(i + 1, inner.Count); + + for (int j = 0; j < inner.Count; j++) + { + var inner2 = (IReadOnlyList)inner[j]; + Assert.AreEqual(j + 1, inner2.Count); + + for (int k = 0; k < inner2.Count; k++) + { + Assert.AreEqual($"{i}, {j}, {k}", inner2[k].SomeText); + } + } + } + } + + [TestMethod] + public void NestedLists2DStruct() + { + var expected = new List>(); + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + for (int i = 0; i < 3; i++) + { + expected.Add(new List()); + + for (int j = 0; j <= i; j++) + { + var x = b.CreateObject(); + x.SomeText = $"{i}, {j}"; + expected[i].Add(x); + } + } + + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = ld.Cast2D(_ => new SomeStruct.READER(_)); + Assert.AreEqual(3, result.Count); + for (int i = 0; i < result.Count; i++) + { + var inner = result[i]; + Assert.AreEqual(i + 1, inner.Count); + + for (int j = 0; j < inner.Count; j++) + { + Assert.AreEqual($"{i}, {j}", inner[j].SomeText); + } + } + } + + [TestMethod] + public void ListOfEnums() + { + var expected = new TestEnum[] { TestEnum.bar, TestEnum.baz, TestEnum.corge }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = ld.CastEnums(_ => (TestEnum)_); + CollectionAssert.AreEqual(expected, result.ToArray()); + } + + [TestMethod] + public void NestedLists2DEnum() + { + var expected = new TestEnum[][] + { + new TestEnum[] { TestEnum.bar, TestEnum.baz, TestEnum.corge }, + new TestEnum[] { TestEnum.corge, TestEnum.foo, TestEnum.garply } + }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = ld.CastEnums2D(_ => (TestEnum)_); + Assert.AreEqual(expected.Length, result.Count); + for (int i = 0; i < result.Count; i++) + { + CollectionAssert.AreEqual(expected[i], result[i].ToArray()); + } + } + + [TestMethod] + public void NestedLists3DEnum() + { + var expected = new TestEnum[][][] { + new TestEnum[][] + { + new TestEnum[] { TestEnum.qux, TestEnum.quux, TestEnum.grault }, + new TestEnum[] { TestEnum.garply, TestEnum.foo }, + new TestEnum[] { TestEnum.corge } + }, + new TestEnum[][] + { + new TestEnum[] { TestEnum.baz, TestEnum.bar }, + new TestEnum[0] + }, + new TestEnum[0][] + }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = ld.CastEnums3D(_ => (TestEnum)_); + Assert.AreEqual(3, result.Count); + for (int i = 0; i < result.Count; i++) + { + var inner = result[i]; + Assert.AreEqual(expected[i].Length, inner.Count); + + for (int j = 0; j < expected[i].Length; j++) + { + var inner2 = inner[j]; + CollectionAssert.AreEqual(expected[i][j], inner2.ToArray()); + } + } + } + + [TestMethod] + public void NestedListsNDEnum() + { + var expected = new TestEnum[][][] { + new TestEnum[][] + { + new TestEnum[] { TestEnum.qux, TestEnum.quux, TestEnum.grault }, + new TestEnum[] { TestEnum.garply, TestEnum.foo }, + new TestEnum[] { TestEnum.corge } + }, + new TestEnum[][] + { + new TestEnum[] { TestEnum.baz, TestEnum.bar }, + new TestEnum[0] + }, + new TestEnum[0][] + }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + var ld = d.RequireList(); + var result = (IReadOnlyList)ld.CastEnumsND(3, _ => (TestEnum)_); + Assert.AreEqual(3, result.Count); + for (int i = 0; i < result.Count; i++) + { + var inner = (IReadOnlyList)result[i]; + Assert.AreEqual(expected[i].Length, inner.Count); + + for (int j = 0; j < expected[i].Length; j++) + { + var inner2 = (IReadOnlyList)inner[j]; + CollectionAssert.AreEqual(expected[i][j], inner2.ToArray()); + } + } + } + + [TestMethod] + public void NestedLists2DVoid() + { + var b = MessageBuilder.Create(); + var s = b.CreateObject>(); + s.Init(3); + s[0].Init(4); + s[1].Init(5); + s[2].Init(6); + DeserializerState d = s; + var voids = d.RequireList().CastVoid2D(); + CollectionAssert.AreEqual(new int[] { 4, 5, 6 }, voids.ToArray()); + } + + [TestMethod] + public void NestedLists3DVoid() + { + var expected = new int[][] { + new int[] { 1, 2, 3 }, + new int[] { 4, 5 }, + new int[] { 6 } }; + + var b = MessageBuilder.Create(); + var s = b.CreateObject>>(); + s.Init(expected.Length); + for (int i = 0; i < expected.Length; i++) + { + s[i].Init(expected[i], (l, j) => l.Init(j)); + } + DeserializerState d = s; + var voids = d.RequireList().CastVoid3D(); + Assert.AreEqual(expected.Length, voids.Count); + for (int i = 0; i < expected.Length; i++) + { + CollectionAssert.AreEqual(expected[i], voids[i].ToArray()); + } + } + + [TestMethod] + public void ListOfEmpty() + { + var expected = new TestEnum[] { TestEnum.bar, TestEnum.baz, TestEnum.corge }; + + var b = MessageBuilder.Create(); + var loes = b.CreateObject(); + loes.Init(12345678); + DeserializerState d = loes; + var ld = d.RequireList(); + Assert.AreEqual(ListKind.ListOfEmpty, ld.Kind); + if (!(ld is ListOfEmptyDeserializer loed)) + { + Assert.Fail("List did not deserialize back to ListOfEmptyDeserializer"); + return; + } + Assert.AreEqual(12345678, loed.Count); + Assert.ThrowsException(() => { var _ = loed[-1]; }); + Assert.ThrowsException(() => { var _ = loed[12345678]; }); + _ = loed[12345677]; + var kind = loed.Cast(_ => _.Kind).Take(1).Single(); + Assert.AreEqual(ObjectKind.Nil, kind); + } + + [TestMethod] + public void DeserializerStateBadConv() + { + SerializerState s = null; + Assert.ThrowsException(() => (DeserializerState)s); + s = new DynamicSerializerState(); + Assert.ThrowsException(() => (DeserializerState)s); + } + + [TestMethod] + public void BadPointers() + { + var data = new ulong[1]; + var wf = new WireFrame(new Memory[] { new Memory(data) }); + var d0 = DeserializerState.CreateRoot(wf); + Assert.AreEqual(ObjectKind.Nil, d0.Kind); + WirePointer p = default; + p.BeginStruct(1, 0); + p.Offset = 0; + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.BeginList(ListKind.ListOfBits, 64); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.BeginList(ListKind.ListOfBytes, 8); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.BeginList(ListKind.ListOfEmpty, 6400); + data[0] = p; + var d1 = DeserializerState.CreateRoot(wf); + p.BeginList(ListKind.ListOfInts, 2); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.BeginList(ListKind.ListOfLongs, 1); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.BeginList(ListKind.ListOfPointers, 1); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.BeginList(ListKind.ListOfShorts, 4); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.BeginList(ListKind.ListOfStructs, 1); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.SetFarPointer(0, 0, false); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.SetFarPointer(1, 0, false); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.SetFarPointer(0, 1, false); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + p.SetFarPointer(0, 0, true); + data[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf)); + + var data2 = new ulong[3]; + var wf2 = new WireFrame(new Memory[] { new Memory(data2) }); + p.BeginList(ListKind.ListOfStructs, 1); + data2[0] = p; + data2[1] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf2)); + + p.SetFarPointer(0, 1, true); + data2[0] = p; + data2[1] = 0; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf2)); + + p.SetFarPointer(0, 1, false); + data2[1] = p; + data2[2] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf2)); + + p.SetFarPointer(0, 2, true); + data2[0] = p; + Assert.ThrowsException(() => DeserializerState.CreateRoot(wf2)); + } + + [TestMethod] + public void ReadCap1() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + dss.SetStruct(0, 1); + DeserializerState ds = dss; + Assert.ThrowsException(() => ds.ReadCap(-1)); + Assert.ThrowsException(() => ds.ReadCap(0)); + } + + [TestMethod] + public void ReadCap2() + { + var mb = MessageBuilder.Create(); + mb.InitCapTable(); + var dss1 = mb.CreateObject(); + var dss2 = mb.CreateObject(); + dss2.SetStruct(1, 1); + dss1.SetStruct(0, 2); + dss1.Link(0, dss2); + dss1.LinkToCapability(1, 7); + var d = (DeserializerState)dss1; + Assert.ThrowsException(() => d.ReadCap(0)); + Assert.ThrowsException(() => d.ReadCap(1)); + } + + [TestMethod] + public void Read1() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + dss.SetStruct(1, 0); + dss.WriteData(0, ulong.MaxValue); + var d = (DeserializerState)dss; + Assert.AreEqual(ushort.MaxValue, d.ReadDataUShort(48)); + Assert.ThrowsException(() => d.ReadDataUShort(49)); + Assert.AreEqual((ushort)0, d.ReadDataUShort(64)); + Assert.IsNotNull(d.StructReadPointer(7)); + Assert.ThrowsException(() => d.RequireCapList()); + } + + [TestMethod] + public void Read2() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + dss.Init(50); + var d = (DeserializerState)dss; + Assert.ThrowsException(() => d.ReadDataUInt(0)); + Assert.ThrowsException(() => d.StructReadPointer(0)); + } + + [TestMethod] + public void ReadCapList() + { + var mb = MessageBuilder.Create(); + mb.InitCapTable(); + var dss = mb.CreateObject(); + dss.SetStruct(0, 1); + var loc = mb.CreateObject>(); + loc.Init(1); + loc[0] = new TestInterfaceImpl2(); + dss.LinkObject(0, loc); + var d = (DeserializerState)dss; + var cl = d.ReadCapList(0); + Assert.AreEqual(1, cl.Count); + Assert.IsNotNull(cl[0]); + } + + [TestMethod] + public void ReadCap() + { + var dss = DynamicSerializerState.CreateForRpc(); + dss.SetStruct(0, 1); + dss.LinkObject(0, new TestInterfaceImpl2()); + var d = (DeserializerState)dss; + Assert.IsNotNull(d.ReadCap(0)); + Assert.IsNotNull(d.ReadCap(0)); + } + + [TestMethod] + public void RequireCap1() + { + var dss = DynamicSerializerState.CreateForRpc(); + dss.SetStruct(1, 1); + var d = (DeserializerState)dss; + Assert.ThrowsException(() => d.RequireCap()); + } + + [TestMethod] + public void RequireCap2() + { + DeserializerState d = default; + d.Kind = ObjectKind.Capability; + Assert.ThrowsException(() => d.RequireCap()); + } } } diff --git a/Capnp.Net.Runtime.Tests/Dtbdct.cs b/Capnp.Net.Runtime.Tests/Dtbdct.cs new file mode 100644 index 0000000..4a4c9c6 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/Dtbdct.cs @@ -0,0 +1,198 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Capnp.Net.Runtime.Tests +{ + [TestClass] + [TestCategory("Coverage")] + public class Dtbdct: TestBase + { + [TestMethod] + public void EmbargoOnPromisedAnswer() + { + NewDtbdctTestbed().RunTest(Testsuite.EmbargoOnPromisedAnswer); + } + + [TestMethod] + public void EmbargoOnImportedCap() + { + NewDtbdctTestbed().RunTest(Testsuite.EmbargoOnImportedCap); + } + + [TestMethod] + public void EmbargoError() + { + NewDtbdctTestbed().RunTest(Testsuite.EmbargoError); + } + + [TestMethod] + public void EmbargoNull() + { + NewDtbdctTestbed().RunTest(Testsuite.EmbargoNull); + } + + [TestMethod] + public void CallBrokenPromise() + { + NewDtbdctTestbed().RunTest(Testsuite.CallBrokenPromise); + } + + [TestMethod] + public void TailCall() + { + NewDtbdctTestbed().RunTest(Testsuite.TailCall); + } + + [TestMethod] + public void SendTwice() + { + NewDtbdctTestbed().RunTest(Testsuite.SendTwice); + } + + [TestMethod] + public void Cancel() + { + NewDtbdctTestbed().RunTest(Testsuite.Cancel); + } + + [TestMethod] + public void RetainAndRelease() + { + NewDtbdctTestbed().RunTest(Testsuite.RetainAndRelease); + } + + [TestMethod] + public void PromiseResolve() + { + NewDtbdctTestbed().RunTest(Testsuite.PromiseResolve); + } + + [TestMethod] + public void PromiseResolveLate() + { + NewDtbdctTestbed().RunTest(Testsuite.PromiseResolveLate); + } + + [TestMethod] + public void PromiseResolveError() + { + NewDtbdctTestbed().RunTest(Testsuite.PromiseResolveError); + } + + [TestMethod] + public void Cancelation() + { + NewDtbdctTestbed().RunTest(Testsuite.Cancelation); + } + + [TestMethod] + public void ReleaseOnCancel() + { + NewDtbdctTestbed().RunTest(Testsuite.ReleaseOnCancel); + } + + [TestMethod] + public void Release() + { + NewDtbdctTestbed().RunTest(Testsuite.Release); + } + + [TestMethod] + public void Pipeline() + { + NewDtbdctTestbed().RunTest(Testsuite.Pipeline); + } + + [TestMethod] + public void Basic() + { + NewDtbdctTestbed().RunTest(Testsuite.Basic); + } + + [TestMethod] + public void BootstrapReuse() + { + NewDtbdctTestbed().RunTest(Testsuite.BootstrapReuse); + } + + [TestMethod] + public void Ownership1() + { + NewDtbdctTestbed().RunTest(Testsuite.Ownership1); + } + + [TestMethod] + public void Ownership2() + { + NewDtbdctTestbed().RunTest(Testsuite.Ownership2); + } + + [TestMethod] + public void Ownership3() + { + NewDtbdctTestbed().RunTest(Testsuite.Ownership3); + } + + [TestMethod] + public void SillySkeleton() + { + NewDtbdctTestbed().RunTest(Testsuite.SillySkeleton); + } + + [TestMethod] + public void ImportReceiverAnswer() + { + NewDtbdctTestbed().RunTest(Testsuite.ImportReceiverAnswer); + } + + [TestMethod] + public void ImportReceiverAnswerError() + { + NewDtbdctTestbed().RunTest(Testsuite.ImportReceiverAnswerError); + } + + [TestMethod] + public void ImportReceiverAnswerCanceled() + { + NewDtbdctTestbed().RunTest(Testsuite.ImportReceiverCanceled); + } + + [TestMethod] + public void ButNoTailCall() + { + NewDtbdctTestbed().RunTest(Testsuite.ButNoTailCall); + } + + [TestMethod] + public void SecondIsTailCall() + { + NewDtbdctTestbed().RunTest(Testsuite.SecondIsTailCall); + } + + [TestMethod] + public void ReexportSenderPromise() + { + NewDtbdctTestbed().RunTest(Testsuite.ReexportSenderPromise); + } + + [TestMethod] + public void CallAfterFinish1() + { + NewDtbdctTestbed().RunTest(Testsuite.CallAfterFinish1); + } + + [TestMethod] + public void CallAfterFinish2() + { + NewDtbdctTestbed().RunTest(Testsuite.CallAfterFinish2); + } + + [TestMethod] + public void LegacyAccess() + { + NewDtbdctTestbed().RunTest(Testsuite.LegacyAccess); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/DynamicSerializerStateTests.cs b/Capnp.Net.Runtime.Tests/DynamicSerializerStateTests.cs index 0797860..a65c71f 100644 --- a/Capnp.Net.Runtime.Tests/DynamicSerializerStateTests.cs +++ b/Capnp.Net.Runtime.Tests/DynamicSerializerStateTests.cs @@ -7,6 +7,7 @@ using System.IO; namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class DynamicSerializerStateTests { [TestMethod] diff --git a/Capnp.Net.Runtime.Tests/EdgeCaseHandling.cs b/Capnp.Net.Runtime.Tests/EdgeCaseHandling.cs new file mode 100644 index 0000000..225b5b8 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/EdgeCaseHandling.cs @@ -0,0 +1,1356 @@ +using Capnp; +using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Rpc; +using Capnproto_test.Capnp.Test; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Pipelines; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Capnp.Net.Runtime.Tests +{ + [TestClass] + [TestCategory("Coverage")] + public class EdgeCaseHandling: TestBase + { + class MemStreamEndpoint : IEndpoint + { + readonly FramePump _fromEnginePump; + readonly BinaryReader _reader; + readonly FrameTracing.RpcFrameTracer _tracer; + + public bool Dismissed { get; private set; } + + public MemStreamEndpoint() + { + var pipe = new Pipe(); + _tracer = new FrameTracing.RpcFrameTracer(Console.Out, false); + _fromEnginePump = new FramePump(pipe.Writer.AsStream()); + _fromEnginePump.AttachTracer(_tracer); + _reader = new BinaryReader(pipe.Reader.AsStream()); + } + + public void Dismiss() + { + Dismissed = true; + } + + public void Forward(WireFrame frame) + { + _fromEnginePump.Send(frame); + } + + public void Flush() + { + _fromEnginePump.Flush(); + } + + public WireFrame ReadNextFrame() + { + var frame = _reader.ReadWireFrame(); + _tracer.TraceFrame(FrameTracing.FrameDirection.Rx, frame); + return frame; + } + } + + class RpcEngineTester + { + readonly MemStreamEndpoint _fromEngine; + + public RpcEngineTester() + { + Engine = new RpcEngine(); + _fromEngine = new MemStreamEndpoint(); + RealEnd = Engine.AddEndpoint(_fromEngine); + } + + public RpcEngine Engine { get; } + public RpcEngine.RpcEndpoint RealEnd { get; } + public bool IsDismissed => _fromEngine.Dismissed; + + public void Send(Action build) + { + var mb = MessageBuilder.Create(); + mb.InitCapTable(); + build(mb.BuildRoot()); + RealEnd.Forward(mb.Frame); + } + + public void Recv(Action verify) + { + var task = Task.Run(() => DeserializerState.CreateRoot(_fromEngine.ReadNextFrame())); + Assert.IsTrue(task.Wait(MediumNonDbgTimeout), "reception timeout"); + verify(new Message.READER(task.Result)); + } + + public void ExpectAbort() + { + Recv(_ => { Assert.AreEqual(Message.WHICH.Abort, _.which); }); + Assert.IsTrue(IsDismissed); + Assert.ThrowsException( + () => Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 33; })); + } + } + + [TestMethod] + public void DuplicateQuestion1() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; }); + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void DuplicateQuestion2() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 99; + _.Call.Target.which = MessageTarget.WHICH.ImportedCap; + _.Call.Target.ImportedCap = bootCapId; + _.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id; + _.Call.MethodId = 0; + _.Call.Params.Content.Rewrap(); + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void DuplicateQuestion3() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 42; + _.Call.Target.which = MessageTarget.WHICH.ImportedCap; + _.Call.Target.ImportedCap = bootCapId; + _.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id; + _.Call.MethodId = 0; + var wr = _.Call.Params.Content.Rewrap(); + wr.I = 123u; + wr.J = true; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 42; + _.Call.Target.which = MessageTarget.WHICH.ImportedCap; + _.Call.Target.ImportedCap = bootCapId; + _.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id; + _.Call.MethodId = 0; + _.Call.Params.Content.Rewrap(); + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void NoBootstrap() + { + var tester = new RpcEngineTester(); + + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Exception, _.Return.which); + }); + Assert.IsFalse(tester.IsDismissed); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 1; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + }); + } + + [TestMethod] + public void DuplicateFinish() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { + _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Finish; + _.Finish.QuestionId = 99; + }); + tester.Send(_ => { + _.which = Message.WHICH.Finish; + _.Finish.QuestionId = 99; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void DuplicateAnswer() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted; + _.Return.Results.CapTable[0].SenderHosted = 1; + }); + Assert.IsTrue(proxy.WhenResolved.IsCompleted); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted; + _.Return.Results.CapTable[0].SenderHosted = 1; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void UnimplementedReturnAcceptFromThirdParty() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.AcceptFromThirdParty; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + } + + [TestMethod] + public void UnimplementedReturnUnknown() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = (Return.WHICH)33; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + } + + [TestMethod] + public void InvalidReturnTakeFromOtherQuestion() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.TakeFromOtherQuestion; + _.Return.TakeFromOtherQuestion = 1u; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void InvalidReceiverHosted() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.ReceiverHosted; + _.Return.Results.CapTable[0].ReceiverHosted = 0; + }); + Assert.IsTrue(proxy.WhenResolved.IsCompleted); + tester.ExpectAbort(); + } + + [TestMethod] + public void InvalidReceiverAnswer() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.ReceiverAnswer; + _.Return.Results.CapTable[0].ReceiverAnswer.QuestionId = 0; + _.Return.Results.CapTable[0].ReceiverAnswer.Transform.Init(1); + _.Return.Results.CapTable[0].ReceiverAnswer.Transform[0].which = PromisedAnswer.Op.WHICH.GetPointerField; + _.Return.Results.CapTable[0].ReceiverAnswer.Transform[0].GetPointerField = 0; + }); + Assert.IsTrue(proxy.WhenResolved.IsCompleted); + tester.ExpectAbort(); + } + + [TestMethod] + public void InvalidCallTargetImportedCap() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 1; + _.Call.Target.which = MessageTarget.WHICH.ImportedCap; + _.Call.Target.ImportedCap = bootCapId + 1; + _.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id; + _.Call.MethodId = 0; + _.Call.Params.Content.Rewrap(); + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void InvalidCallTargetPromisedAnswer() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 1; + _.Call.Target.which = MessageTarget.WHICH.PromisedAnswer; + _.Call.Target.PromisedAnswer.QuestionId = 1; + _.Call.Target.PromisedAnswer.Transform.Init(1); + _.Call.Target.PromisedAnswer.Transform[0].which = PromisedAnswer.Op.WHICH.GetPointerField; + _.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id; + _.Call.MethodId = 0; + _.Call.Params.Content.Rewrap(); + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void UnimplementedCallTargetUnknown() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 1; + _.Call.Target.which = (MessageTarget.WHICH)77; + _.Call.InterfaceId = ((TypeIdAttribute)typeof(ITestInterface).GetCustomAttributes(typeof(TypeIdAttribute), false)[0]).Id; + _.Call.MethodId = 0; + _.Call.Params.Content.Rewrap(); + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void DuplicateResolve1() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderPromise; + _.Return.Results.CapTable[0].SenderPromise = 0; + }); + tester.Send(_ => { + _.which = Message.WHICH.Resolve; + _.Resolve.which = Resolve.WHICH.Cap; + _.Resolve.Cap.which = CapDescriptor.WHICH.SenderHosted; + _.Resolve.Cap.SenderHosted = 1; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + tester.Send(_ => { + _.which = Message.WHICH.Resolve; + _.Resolve.which = Resolve.WHICH.Exception; + _.Resolve.Exception.Reason = "problem"; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Release, _.which); + }); + + // tester.ExpectAbort(); + + // Duplicate resolve is only a protocol error if the Rpc engine can prove misbehavior. + // In this case that proof is not possible because the preliminary cap is release (thus, removed from import table) + // immediately after the first resolution. Now we get the situation that the 2nd resolution refers to a non-existing + // cap. This is not considered a protocol error because it might be due to an expected race condition + // between receiver-side Release and sender-side Resolve. + } + + [TestMethod] + public void DuplicateResolve2() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderPromise; + _.Return.Results.CapTable[0].SenderPromise = 0; + _.Return.Results.Content.SetCapability(0); + }); + proxy.Call(0, 0, DynamicSerializerState.CreateForRpc()); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Call, _.which); + }); + tester.Send(_ => { + _.which = Message.WHICH.Resolve; + _.Resolve.which = Resolve.WHICH.Cap; + _.Resolve.Cap.which = CapDescriptor.WHICH.SenderHosted; + _.Resolve.Cap.SenderHosted = 1; + }); + tester.Send(_ => { + _.which = Message.WHICH.Resolve; + _.Resolve.which = Resolve.WHICH.Exception; + _.Resolve.Exception.Reason = "problem"; + }); + + tester.ExpectAbort(); + } + + [TestMethod] + public void UnimplementedResolveCategory() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderPromise; + _.Return.Results.CapTable[0].SenderPromise = 0; + }); + tester.Send(_ => { + _.which = Message.WHICH.Resolve; + _.Resolve.which = (Resolve.WHICH)7; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + } + + [TestMethod] + public void InvalidResolve() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted; + _.Return.Results.CapTable[0].SenderHosted = 7; + }); + tester.Send(_ => { + _.which = Message.WHICH.Resolve; + _.Resolve.which = Resolve.WHICH.Cap; + _.Resolve.PromiseId = 7; + _.Resolve.Cap.which = CapDescriptor.WHICH.SenderHosted; + _.Resolve.Cap.SenderHosted = 1; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + + tester.ExpectAbort(); + } + + [TestMethod] + public void DuplicateRelease1() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { + _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Release; + _.Release.Id = bootCapId; + _.Release.ReferenceCount = 1; + }); + tester.Send(_ => { + _.which = Message.WHICH.Release; + _.Release.Id = bootCapId; + _.Release.ReferenceCount = 1; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void DuplicateRelease2() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { + _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Release; + _.Release.Id = bootCapId; + _.Release.ReferenceCount = 2; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void UnimplementedAccept() + { + var tester = new RpcEngineTester(); + + tester.Send(_ => { + _.which = Message.WHICH.Accept; + _.Accept.Embargo = true; + _.Accept.QuestionId = 47; + _.Accept.Provision.SetStruct(1, 0); + _.Accept.Provision.Allocate(); + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + Assert.AreEqual(Message.WHICH.Accept, _.Unimplemented.which); + Assert.IsTrue(_.Unimplemented.Accept.Embargo); + Assert.AreEqual(47u, _.Unimplemented.Accept.QuestionId); + Assert.AreEqual(1, _.Unimplemented.Accept.Provision.StructDataCount); + Assert.AreEqual(0, _.Unimplemented.Accept.Provision.StructPtrCount); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void UnimplementedJoin() + { + var tester = new RpcEngineTester(); + + tester.Send(_ => { + _.which = Message.WHICH.Join; + _.Join.QuestionId = 74; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + Assert.AreEqual(Message.WHICH.Join, _.Unimplemented.which); + Assert.AreEqual(74u, _.Unimplemented.Join.QuestionId); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void UnimplementedProvide() + { + var tester = new RpcEngineTester(); + + tester.Send(_ => { + _.which = Message.WHICH.Provide; + _.Provide.QuestionId = 666; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + Assert.AreEqual(Message.WHICH.Provide, _.Unimplemented.which); + Assert.AreEqual(666u, _.Unimplemented.Provide.QuestionId); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void UnimplementedObsoleteDelete() + { + var tester = new RpcEngineTester(); + + tester.Send(_ => { + _.which = Message.WHICH.ObsoleteDelete; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + Assert.AreEqual(Message.WHICH.ObsoleteDelete, _.Unimplemented.which); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void UnimplementedObsoleteSave() + { + var tester = new RpcEngineTester(); + + tester.Send(_ => { + _.which = Message.WHICH.ObsoleteSave; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + Assert.AreEqual(Message.WHICH.ObsoleteSave, _.Unimplemented.which); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void UnimplementedUnknown() + { + var tester = new RpcEngineTester(); + + tester.Send(_ => { + _.which = (Message.WHICH)123; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + Assert.AreEqual((Message.WHICH)123, _.Unimplemented.which); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void UnimplementedSendResultsToThirdParty() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { + _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 42; + _.Call.Target.which = MessageTarget.WHICH.ImportedCap; + _.Call.Target.ImportedCap = bootCapId; + _.Call.InterfaceId = new TestInterface_Skeleton().InterfaceId; + _.Call.MethodId = 0; + var wr = _.Call.Params.Content.Rewrap(); + _.Call.Params.CapTable.Init(0); + _.Call.SendResultsTo.which = Call.sendResultsTo.WHICH.ThirdParty; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void UnimplementedSendResultsToUnknown() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + uint bootCapId = 0; + + tester.Send(_ => { + _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 0; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 42; + _.Call.Target.which = MessageTarget.WHICH.ImportedCap; + _.Call.Target.ImportedCap = bootCapId; + _.Call.InterfaceId = new TestInterface_Skeleton().InterfaceId; + _.Call.MethodId = 0; + var wr = _.Call.Params.Content.Rewrap(); + _.Call.Params.CapTable.Init(0); + _.Call.SendResultsTo.which = (Call.sendResultsTo.WHICH)13; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + Assert.IsFalse(tester.IsDismissed); + } + + class TestPipelineImpl3 : ITestPipeline + { + readonly TestPipelineImpl2 _impl; + readonly ITestPipeline _proxy; + + public TestPipelineImpl3(Task complete) + { + _impl = new TestPipelineImpl2(complete); + var bproxy = BareProxy.FromImpl(_impl); + _proxy = bproxy.Cast(true); + } + + public void Dispose() + { + } + + public bool IsGrandsonCapDisposed => _impl.IsChildCapDisposed; + + public Task<(string, TestPipeline.AnyBox)> GetAnyCap(uint n, BareProxy inCap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task<(string, TestPipeline.Box)> GetCap(uint n, ITestInterface inCap, CancellationToken cancellationToken_ = default) + { + return Task.FromResult(("foo", new TestPipeline.Box() { Cap = _proxy.GetCap(0, null).OutBox_Cap() })); + } + + public Task TestPointers(ITestInterface cap, object obj, IReadOnlyList list, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + } + + [TestMethod] + public void UnimplementedResolve() + { + var tcs = new TaskCompletionSource(); + var tester = new RpcEngineTester(); + var impl = new TestPipelineImpl3(tcs.Task); + tester.Engine.Main = impl; + + uint bootCapId = 0; + + tester.Send(_ => { + _.which = Message.WHICH.Bootstrap; _.Bootstrap.QuestionId = 99; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + bootCapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => { + _.which = Message.WHICH.Call; + _.Call.QuestionId = 42; + _.Call.Target.which = MessageTarget.WHICH.ImportedCap; + _.Call.Target.ImportedCap = bootCapId; + _.Call.InterfaceId = new TestPipeline_Skeleton().InterfaceId; + _.Call.MethodId = 0; + var wr = _.Call.Params.Content.Rewrap(); + wr.InCap = null; + _.Call.Params.CapTable.Init(1); + _.Call.Params.CapTable[0].which = CapDescriptor.WHICH.ReceiverHosted; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(1, _.Return.Results.CapTable.Count); + Assert.AreEqual(CapDescriptor.WHICH.SenderPromise, _.Return.Results.CapTable[0].which); + }); + tcs.SetResult(0); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Resolve, _.which); + Assert.AreEqual(Resolve.WHICH.Cap, _.Resolve.which); + Assert.AreEqual(CapDescriptor.WHICH.SenderHosted, _.Resolve.Cap.which); + + Assert.IsFalse(impl.IsGrandsonCapDisposed); + + tester.Send(_1 => + { + _1.which = Message.WHICH.Unimplemented; + _1.Unimplemented.which = Message.WHICH.Resolve; + Reserializing.DeepCopy(_.Resolve, _1.Unimplemented.Resolve); + }); + + Assert.IsFalse(impl.IsGrandsonCapDisposed); + + tester.Send(_1 => + { + _1.which = Message.WHICH.Finish; + _1.Finish.QuestionId = 42; + _1.Finish.ReleaseResultCaps = true; + }); + + Assert.IsTrue(impl.IsGrandsonCapDisposed); + }); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void SenderLoopbackOnInvalidCap() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + tester.Send(_ => { + _.which = Message.WHICH.Disembargo; + _.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap; + _.Disembargo.Target.ImportedCap = 0; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void SenderLoopbackOnInvalidPromisedAnswer() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + tester.Send(_ => { + _.which = Message.WHICH.Disembargo; + _.Disembargo.Context.which = Disembargo.context.WHICH.SenderLoopback; + _.Disembargo.Context.SenderLoopback = 0; + _.Disembargo.Target.which = MessageTarget.WHICH.PromisedAnswer; + _.Disembargo.Target.PromisedAnswer.QuestionId = 9; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void SenderLoopbackOnUnknownTarget() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + tester.Send(_ => { + _.which = Message.WHICH.Disembargo; + _.Disembargo.Context.which = Disembargo.context.WHICH.SenderLoopback; + _.Disembargo.Context.SenderLoopback = 0; + _.Disembargo.Target.which = (MessageTarget.WHICH)12; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + } + + [TestMethod] + public void ReceiverLoopbackOnInvalidCap() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + tester.Send(_ => { + _.which = Message.WHICH.Disembargo; + _.Disembargo.Context.which = Disembargo.context.WHICH.ReceiverLoopback; + _.Disembargo.Context.ReceiverLoopback = 0; + _.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap; + _.Disembargo.Target.ImportedCap = 0; + }); + tester.ExpectAbort(); + } + + [TestMethod] + public void UnimplementedDisembargoAccept() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + tester.Send(_ => { + _.which = Message.WHICH.Disembargo; + _.Disembargo.Context.which = Disembargo.context.WHICH.Accept; + _.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap; + _.Disembargo.Target.ImportedCap = 0; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + } + + [TestMethod] + public void UnimplementedDisembargoProvide() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + tester.Send(_ => { + _.which = Message.WHICH.Disembargo; + _.Disembargo.Context.which = Disembargo.context.WHICH.Provide; + _.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap; + _.Disembargo.Target.ImportedCap = 0; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + } + + [TestMethod] + public void UnimplementedDisembargoUnknown() + { + var tester = new RpcEngineTester(); + tester.Engine.Main = new TestInterfaceImpl(new Counters()); + + tester.Send(_ => { + _.which = Message.WHICH.Disembargo; + _.Disembargo.Context.which = (Disembargo.context.WHICH)50; + _.Disembargo.Target.which = MessageTarget.WHICH.ImportedCap; + _.Disembargo.Target.ImportedCap = 0; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + } + + [TestMethod] + public void UnimplementedCall() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted; + _.Return.Results.CapTable[0].SenderHosted = 1; + _.Return.Results.Content.SetCapability(0); + }); + Assert.IsTrue(proxy.WhenResolved.IsCompleted); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + var args = DynamicSerializerState.CreateForRpc(); + var ti = new TestInterfaceImpl(new Counters()); + args.ProvideCapability(ti); + proxy.Call(1, 2, args); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Call, _.which); + Assert.AreEqual(1ul, _.Call.InterfaceId); + Assert.AreEqual((ushort)2, _.Call.MethodId); + + Assert.IsFalse(ti.IsDisposed); + + tester.Send(_1 => + { + _1.which = Message.WHICH.Unimplemented; + _1.Unimplemented.which = Message.WHICH.Call; + Reserializing.DeepCopy(_.Call, _1.Unimplemented.Call); + }); + + Assert.IsTrue(ti.IsDisposed); + }); + } + + [TestMethod] + public void UnimplementedBootstrap() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + + tester.Send(_1 => + { + _1.which = Message.WHICH.Unimplemented; + _1.Unimplemented.which = Message.WHICH.Bootstrap; + Reserializing.DeepCopy(_.Bootstrap, _1.Unimplemented.Bootstrap); + }); + }); + + tester.ExpectAbort(); + } + + [TestMethod] + public void Abort() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + }); + + tester.Send(_ => { + _.which = Message.WHICH.Abort; + }); + } + + [TestMethod] + public void ThirdPartyHostedBootstrap() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + + tester.Send(_1 => + { + _1.which = Message.WHICH.Return; + _1.Return.AnswerId = _.Bootstrap.QuestionId; + _1.Return.which = Return.WHICH.Results; + _1.Return.Results.CapTable.Init(1); + _1.Return.Results.CapTable[0].which = CapDescriptor.WHICH.ThirdPartyHosted; + _1.Return.Results.CapTable[0].ThirdPartyHosted.VineId = 27; + _1.Return.Results.Content.SetCapability(0); + }); + }); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + + proxy.Call(1, 2, DynamicSerializerState.CreateForRpc()); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Call, _.which); + Assert.AreEqual(MessageTarget.WHICH.ImportedCap, _.Call.Target.which); + Assert.AreEqual(27u, _.Call.Target.ImportedCap); + + tester.Send(_1 => + { + _1.which = Message.WHICH.Return; + _1.Return.AnswerId = _.Call.QuestionId; + _1.Return.which = Return.WHICH.Results; + _1.Return.Results.CapTable.Init(1); + _1.Return.Results.CapTable[0].which = CapDescriptor.WHICH.ThirdPartyHosted; + _1.Return.Results.CapTable[0].ThirdPartyHosted.VineId = 27; + _1.Return.Results.Content.SetCapability(0); + }); + }); + } + + [TestMethod] + public void NoneImportBootstrap() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + + tester.Send(_1 => + { + _1.which = Message.WHICH.Return; + _1.Return.AnswerId = _.Bootstrap.QuestionId; + _1.Return.which = Return.WHICH.Results; + _1.Return.Results.CapTable.Init(1); + _1.Return.Results.CapTable[0].which = CapDescriptor.WHICH.None; + }); + }); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + + var answer = proxy.Call(1, 2, DynamicSerializerState.CreateForRpc()); + var task = Impatient.MakePipelineAware(answer, _ => _); + Assert.IsTrue(task.IsFaulted); + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void UnknownImportBootstrap() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + + tester.Send(_1 => + { + _1.which = Message.WHICH.Return; + _1.Return.AnswerId = _.Bootstrap.QuestionId; + _1.Return.which = Return.WHICH.Results; + _1.Return.Results.CapTable.Init(1); + _1.Return.Results.CapTable[0].which = (CapDescriptor.WHICH)27; + }); + }); + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Unimplemented, _.which); + }); + + Assert.IsFalse(tester.IsDismissed); + } + + [TestMethod] + public void ReturnToWrongSide1() + { + var tester = new RpcEngineTester(); + + var cap = tester.RealEnd.QueryMain(); + var proxy = new BareProxy(cap); + Assert.IsFalse(proxy.WhenResolved.IsCompleted); + uint id = 0; + + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Bootstrap, _.which); + id = _.Bootstrap.QuestionId; + }); + tester.Send(_ => { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.ResultsSentElsewhere; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + Assert.IsTrue(proxy.WhenResolved.IsCompleted); + Assert.IsTrue(proxy.WhenResolved.WrappedTask.IsFaulted); + tester.ExpectAbort(); + } + + [TestMethod] + public void ReturnToWrongSide2() + { + var tester = new RpcEngineTester(); + + tester.Engine.Main = new TestTailCallerImpl(new Counters()); + + tester.Send(_ => { + _.which = Message.WHICH.Bootstrap; + _.Bootstrap.QuestionId = 0; + }); + uint bootstrapId = 0; + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.Results, _.Return.which); + Assert.AreEqual(CapDescriptor.WHICH.SenderHosted, _.Return.Results.CapTable[0].which); + bootstrapId = _.Return.Results.CapTable[0].SenderHosted; + }); + tester.Send(_ => + { + _.which = Message.WHICH.Call; + _.Call.Target.which = MessageTarget.WHICH.ImportedCap; + _.Call.Target.ImportedCap = 0; + _.Call.SendResultsTo.which = Call.sendResultsTo.WHICH.Caller; + _.Call.InterfaceId = new TestTailCaller_Skeleton().InterfaceId; + _.Call.MethodId = 0; + _.Call.QuestionId = 1; + var a = _.Call.Params.Content.Rewrap(); + a.Callee = new TestTailCalleeImpl(new Counters()); + _.Call.Params.CapTable.Init(1); + _.Call.Params.CapTable[0].which = CapDescriptor.WHICH.SenderHosted; + _.Call.Params.CapTable[0].SenderHosted = 0; + }); + uint q = 0; + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Call, _.which); + Assert.AreEqual(Call.sendResultsTo.WHICH.Yourself, _.Call.SendResultsTo.which); + q = _.Call.QuestionId; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Release, _.which); + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Return, _.which); + Assert.AreEqual(Return.WHICH.TakeFromOtherQuestion, _.Return.which); + }); + tester.Send(_ => + { + _.which = Message.WHICH.Return; + _.Return.which = Return.WHICH.Results; + _.Return.AnswerId = q; + var wr = _.Return.Results.Content.Rewrap(); + wr.C = new TestCallOrderImpl(); + wr.I = 0; + wr.T = "test"; + _.Return.Results.CapTable.Init(1); + _.Return.Results.CapTable[0].which = CapDescriptor.WHICH.SenderHosted; + _.Return.Results.CapTable[0].SenderHosted = 1; + }); + tester.Recv(_ => { + Assert.AreEqual(Message.WHICH.Finish, _.which); + }); + tester.ExpectAbort(); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/FramePumpTests.cs b/Capnp.Net.Runtime.Tests/FramePumpTests.cs index 2ebef32..8c964a6 100644 --- a/Capnp.Net.Runtime.Tests/FramePumpTests.cs +++ b/Capnp.Net.Runtime.Tests/FramePumpTests.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class FramePumpTests { class MyStruct : SerializerState diff --git a/Capnp.Net.Runtime.Tests/General.cs b/Capnp.Net.Runtime.Tests/General.cs index 662b039..856771b 100644 --- a/Capnp.Net.Runtime.Tests/General.cs +++ b/Capnp.Net.Runtime.Tests/General.cs @@ -1,15 +1,18 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Capnp.Rpc; +using Capnp.Util; +using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Threading.Tasks.Dataflow; namespace Capnp.Net.Runtime.Tests { [TestClass] - public class General + public class General: TestBase { [TestMethod] public void AwaitOrderTest() @@ -41,31 +44,174 @@ namespace Capnp.Net.Runtime.Tests Task.WhenAll(tasks).Wait(); } - [TestMethod] - public void AwaitOrderTest2() + class PromisedAnswerMock : IPromisedAnswer { - int returnCounter = 0; + readonly TaskCompletionSource _tcs = new TaskCompletionSource(); - async Task ExpectCount(Task task, int count) + public PromisedAnswerMock() { - await task; - Assert.AreEqual(count, returnCounter++); + WhenReturned = _tcs.Task.EnforceAwaitOrder(); } - var tcs = new TaskCompletionSource(); - var cts = new CancellationTokenSource(); + public StrictlyOrderedAwaitTask WhenReturned { get; } - var tasks = - from i in Enumerable.Range(0, 100) - select ExpectCount(tcs.Task.ContinueWith( - t => t, - cts.Token, - TaskContinuationOptions.ExecuteSynchronously, - TaskScheduler.Current), i); + public void Return() + { + _tcs.SetResult(default); + } - tcs.SetResult(0); + public void Cancel() + { + _tcs.SetCanceled(); + } - Task.WhenAll(tasks).Wait(); + public void Fault() + { + _tcs.SetException(new InvalidOperationException("test fault")); + } + + public ConsumedCapability Access(MemberAccessPath access) + { + throw new NotImplementedException(); + } + + public ConsumedCapability Access(MemberAccessPath access, Task proxyTask) + { + throw new NotImplementedException(); + } + + public bool IsTailCall => false; + + public void Dispose() + { + } + } + + [TestMethod] + public void MakePipelineAwareOnFastPath() + { + var mock = new PromisedAnswerMock(); + mock.Return(); + for (int i = 0; i < 100; i++) + { + var t = Impatient.MakePipelineAware(mock, _ => (object)null); + Assert.IsTrue(t.IsCompleted); + }; + } + + [TestMethod] + [TestCategory("Coverage")] + public void SafeJoinCompletedThread() + { + var thread = new Thread(() => + { + }); + thread.Start(); + thread.SafeJoin(null, 200); + } + + [TestMethod] + [TestCategory("Coverage")] + public void SafeJoinBusyThread() + { + var thread = new Thread(() => + { + try + { + while (true) ; + } + catch (ThreadInterruptedException) + { + Console.WriteLine("Interrupted"); + } + catch (ThreadAbortException) + { + Console.WriteLine("Aborted"); + } + }); + thread.Start(); + thread.SafeJoin(null, 5); + } + + [TestMethod] + [TestCategory("Coverage")] + public void SafeJoinSleepingThread() + { + var thread = new Thread(() => + { + try + { + Thread.Sleep(Timeout.Infinite); + } + catch (ThreadInterruptedException) + { + Console.WriteLine("Interrupted"); + } + catch (ThreadAbortException) + { + Console.WriteLine("Aborted"); + } + }); + + thread.Start(); + thread.SafeJoin(null, 5); + } + + [TestMethod] + [TestCategory("Coverage")] + public void SafeJoinDeadlockedThread() + { + var lk = new object(); + + lock (lk) + { + var thread = new Thread(() => + { + try + { + lock (lk) + { + } + } + catch (ThreadInterruptedException) + { + Console.WriteLine("Interrupted"); + } + catch (ThreadAbortException) + { + Console.WriteLine("Aborted"); + } + }); + + thread.Start(); + thread.SafeJoin(null, 5); + } + } + + [TestMethod] + [TestCategory("Coverage")] + public void SafeJoinDefensiveThread() + { + var thread = new Thread(() => + { + for (; ; ) + { + try + { + Thread.Sleep(Timeout.Infinite); + } + catch (ThreadInterruptedException) + { + Console.WriteLine("Interrupted"); + } + catch (ThreadAbortException) + { + Console.WriteLine("Aborted"); + } + } + }); + thread.Start(); + thread.SafeJoin(null, 5); } } } diff --git a/Capnp.Net.Runtime.Tests/ImpatientTests.cs b/Capnp.Net.Runtime.Tests/ImpatientTests.cs new file mode 100644 index 0000000..f57dad7 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/ImpatientTests.cs @@ -0,0 +1,208 @@ +using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Rpc; +using Capnp.Util; +using Capnproto_test.Capnp.Test; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Capnp.Net.Runtime.Tests +{ + [TestClass] + [TestCategory("Coverage")] + public class ImpatientTests + { + [TestMethod] + public async Task Unwrap() + { + var impl = new TestInterfaceImpl2(); + Assert.AreEqual(impl, await impl.Unwrap()); + using (var proxy = Proxy.Share(impl)) + using (var reso = ((Proxy)proxy).GetResolvedCapability()) + { + + Assert.AreEqual(((Proxy)proxy).ConsumedCap, ((Proxy)reso).ConsumedCap); + } + Assert.IsNull(await default(ITestInterface).Unwrap()); + var tcs = new TaskCompletionSource(); + tcs.SetResult(null); + Assert.IsNull(await tcs.Task.Eager(true).Unwrap()); + var excepted = Task.FromException(new InvalidTimeZoneException("So annoying")); + await Assert.ThrowsExceptionAsync(async () => await excepted.Eager(true).Unwrap()); + } + + [TestMethod] + public async Task MaybeTailCall3() + { + bool flag = false; + + SerializerState Fn(int a, int b, int c) + { + Assert.AreEqual(0, a); + Assert.AreEqual(1, b); + Assert.AreEqual(2, c); + flag = true; + return null; + } + + var t = Task.FromResult((0, 1, 2)); + await Impatient.MaybeTailCall(t, Fn); + Assert.IsTrue(flag); + } + + [TestMethod] + public async Task MaybeTailCall4() + { + bool flag = false; + + SerializerState Fn(int a, int b, int c, int d) + { + Assert.AreEqual(0, a); + Assert.AreEqual(1, b); + Assert.AreEqual(2, c); + Assert.AreEqual(3, d); + flag = true; + return null; + } + + var t = Task.FromResult((0, 1, 2, 3)); + await Impatient.MaybeTailCall(t, Fn); + Assert.IsTrue(flag); + } + + [TestMethod] + public async Task MaybeTailCall5() + { + bool flag = false; + + SerializerState Fn(int a, int b, int c, int d, int e) + { + Assert.AreEqual(0, a); + Assert.AreEqual(1, b); + Assert.AreEqual(2, c); + Assert.AreEqual(3, d); + Assert.AreEqual(4, e); + flag = true; + return null; + } + + var t = Task.FromResult((0, 1, 2, 3, 4)); + await Impatient.MaybeTailCall(t, Fn); + Assert.IsTrue(flag); + } + + [TestMethod] + public async Task MaybeTailCall6() + { + bool flag = false; + + SerializerState Fn(int a, int b, int c, int d, int e, int f) + { + Assert.AreEqual(0, a); + Assert.AreEqual(1, b); + Assert.AreEqual(2, c); + Assert.AreEqual(3, d); + Assert.AreEqual(4, e); + Assert.AreEqual(5, f); + flag = true; + return null; + } + + var t = Task.FromResult((0, 1, 2, 3, 4, 5)); + await Impatient.MaybeTailCall(t, Fn); + Assert.IsTrue(flag); + } + + [TestMethod] + public async Task MaybeTailCall7() + { + bool flag = false; + + SerializerState Fn(int a, int b, int c, int d, int e, int f, int g) + { + Assert.AreEqual(0, a); + Assert.AreEqual(1, b); + Assert.AreEqual(2, c); + Assert.AreEqual(3, d); + Assert.AreEqual(4, e); + Assert.AreEqual(5, f); + Assert.AreEqual(6, g); + flag = true; + return null; + } + + var t = Task.FromResult((0, 1, 2, 3, 4, 5, 6)); + await Impatient.MaybeTailCall(t, Fn); + Assert.IsTrue(flag); + } + + class PromisedAnswerMock : IPromisedAnswer + { + readonly TaskCompletionSource _tcs = new TaskCompletionSource(); + public StrictlyOrderedAwaitTask WhenReturned { get; } + + public PromisedAnswerMock() + { + WhenReturned = _tcs.Task.EnforceAwaitOrder(); + } + + public bool IsTailCall => false; + + public ConsumedCapability Access(MemberAccessPath access) + { + throw new NotImplementedException(); + } + + public ConsumedCapability Access(MemberAccessPath access, Task proxyTask) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + } + } + + [TestMethod] + public void ObsoleteGetAnswer() + { +#pragma warning disable CS0618 + var answer = new PromisedAnswerMock(); + Assert.ThrowsException(() => Impatient.GetAnswer(Task.FromResult(new object()))); + var t = Impatient.MakePipelineAware(answer, _ => _); + Assert.AreEqual(answer, Impatient.GetAnswer(t)); +#pragma warning restore CS0618 + } + + [TestMethod] + public async Task Access() + { + var answer = new PromisedAnswerMock(); + async Task AwaitReturn() => await answer.WhenReturned; + var cap = Impatient.Access(AwaitReturn(), new MemberAccessPath(), Task.FromResult(new TestInterfaceImpl2())); + using (var proxy = new BareProxy(cap)) + { + await proxy.WhenResolved; + } + } + + [TestMethod] + public void ObsoletePseudoEager() + { +#pragma warning disable CS0618 + var task = Task.FromResult(new TestInterfaceImpl2()); + Assert.IsTrue(task.PseudoEager() is Proxy proxy && proxy.WhenResolved.IsCompleted); +#pragma warning restore CS0618 + } + + [TestMethod] + public void Eager() + { + var task = Task.FromResult(new TestInterfaceImpl2()); + Assert.ThrowsException(() => task.Eager(false)); + Assert.ThrowsException(() => task.Eager()); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/Interception.cs b/Capnp.Net.Runtime.Tests/Interception.cs index ea7c1f5..8eaaa4b 100644 --- a/Capnp.Net.Runtime.Tests/Interception.cs +++ b/Capnp.Net.Runtime.Tests/Interception.cs @@ -14,6 +14,7 @@ using System.Threading.Tasks.Dataflow; namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class Interception: TestBase { class MyPolicy : IInterceptionPolicy @@ -66,9 +67,8 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - var counters = new Counters(); + server.Main = policy.Attach(new TestInterfaceImpl(counters)); using (var main = client.GetMain()) { @@ -77,13 +77,13 @@ namespace Capnp.Net.Runtime.Tests Assert.IsTrue(fcc.Wait(MediumNonDbgTimeout)); var cc = fcc.Result; - var pr = new Capnproto_test.Capnp.Test.TestInterface.Params_foo.READER(cc.InArgs); + var pr = new Capnproto_test.Capnp.Test.TestInterface.Params_Foo.READER(cc.InArgs); Assert.AreEqual(123u, pr.I); cc.ForwardToBob(); Assert.IsTrue(policy.Returns.ReceiveAsync().Wait(MediumNonDbgTimeout)); - var rr = new Capnproto_test.Capnp.Test.TestInterface.Result_foo.READER(cc.OutArgs); + var rr = new Capnproto_test.Capnp.Test.TestInterface.Result_Foo.READER(cc.OutArgs); Assert.AreEqual("foo", rr.X); cc.ReturnToAlice(); @@ -95,6 +95,46 @@ namespace Capnp.Net.Runtime.Tests } } + [TestMethod] + public void InterceptServerSideRedirectCall() + { + var policy = new MyPolicy("a"); + + (var server, var client) = SetupClientServerPair(); + + using (server) + using (client) + { + //client.WhenConnected.Wait(); + + var counters = new Counters(); + server.Main = policy.Attach(new TestInterfaceImpl(counters)); + var redirTarget = new TestInterfaceImpl2(); + using (var main = client.GetMain()) + using (redirTarget) + { + var request1 = main.Foo(123, true, default); + var fcc = policy.Calls.ReceiveAsync(); + Assert.IsTrue(fcc.Wait(MediumNonDbgTimeout)); + var cc = fcc.Result; + + Assert.ThrowsException(() => cc.Bob = null); + cc.Bob = redirTarget; + cc.ForwardToBob(); + + Assert.IsTrue(policy.Returns.ReceiveAsync().Wait(MediumNonDbgTimeout)); + + cc.ReturnToAlice(); + + Assert.IsTrue(request1.Wait(MediumNonDbgTimeout)); + + Assert.AreEqual("bar", request1.Result); + } + Assert.IsTrue(redirTarget.IsDisposed); + Assert.AreEqual(0, counters.CallCount); + } + } + [TestMethod] public void InterceptClientSideModifyCall() { @@ -105,7 +145,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); @@ -116,11 +156,11 @@ namespace Capnp.Net.Runtime.Tests Assert.AreEqual(InterceptionState.RequestedFromAlice, cc.State); - var pr = new Capnproto_test.Capnp.Test.TestInterface.Params_foo.READER(cc.InArgs); + var pr = new Capnproto_test.Capnp.Test.TestInterface.Params_Foo.READER(cc.InArgs); Assert.AreEqual(321u, pr.I); Assert.AreEqual(false, pr.J); - var pw = cc.InArgs.Rewrap(); + var pw = cc.InArgs.Rewrap(); pw.I = 123u; pw.J = true; @@ -129,15 +169,15 @@ namespace Capnp.Net.Runtime.Tests var rx = policy.Returns.ReceiveAsync(); // Racing against Bob's answer - Assert.IsTrue(cc.State == InterceptionState.ForwardedToBob || rx.IsCompleted); + Assert.IsTrue(cc.State == InterceptionState.ForwardedToBob || cc.State == InterceptionState.ReturnedFromBob); Assert.IsTrue(rx.Wait(MediumNonDbgTimeout)); - var rr = new Capnproto_test.Capnp.Test.TestInterface.Result_foo.READER(cc.OutArgs); + var rr = new Capnproto_test.Capnp.Test.TestInterface.Result_Foo.READER(cc.OutArgs); Assert.AreEqual("foo", rr.X); Assert.IsFalse(request1.IsCompleted); - var rw = ((DynamicSerializerState)cc.OutArgs).Rewrap(); + var rw = ((DynamicSerializerState)cc.OutArgs).Rewrap(); rw.X = "bar"; cc.OutArgs = rw; @@ -163,7 +203,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); @@ -173,7 +213,7 @@ namespace Capnp.Net.Runtime.Tests Assert.IsTrue(policy.Calls.TryReceive(out var cc)); Assert.IsFalse(request1.IsCompleted); - var rw = SerializerState.CreateForRpc(); + var rw = SerializerState.CreateForRpc(); rw.X = "bar"; cc.OutArgs = rw; @@ -196,7 +236,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); @@ -227,7 +267,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); @@ -261,17 +301,17 @@ namespace Capnp.Net.Runtime.Tests client.WhenConnected.Wait(); var counters = new Counters(); - server.Main = new TestInterfaceImpl(counters); - using (var main = policy.Attach(client.GetMain())) + server.Main = new TestMoreStuffImpl(counters); + using (var main = policy.Attach(client.GetMain())) { - var request1 = main.Foo(321, false, new CancellationToken(true)); + var request1 = main.NeverReturn(new TestInterfaceImpl(new Counters()), new CancellationToken(true)); Assert.IsTrue(policy.Calls.TryReceive(out var cc)); Assert.IsFalse(request1.IsCompleted); Assert.IsTrue(cc.CancelFromAlice.IsCancellationRequested); cc.ForwardToBob(); - Assert.IsTrue(policy.Returns.ReceiveAsync().Wait(MediumNonDbgTimeout)); - Assert.IsTrue(cc.ReturnCanceled); + Assert.IsTrue(policy.Returns.ReceiveAsync().Wait(MediumNonDbgTimeout), "must return"); + Assert.IsTrue(cc.ReturnCanceled, "must be canceled"); cc.ReturnCanceled = false; cc.Exception = "Cancelled"; @@ -283,6 +323,41 @@ namespace Capnp.Net.Runtime.Tests } } + [TestMethod] + public void InterceptClientSideOverrideFaultedCall() + { + var policy = new MyPolicy("a"); + + (var server, var client) = SetupClientServerPair(); + + using (server) + using (client) + { + //client.WhenConnected.Wait(); + + var counters = new Counters(); + server.Main = new TestInterfaceImpl(counters); + using (var main = policy.Attach(client.GetMain())) + { + var request1 = main.Bar(); + Assert.IsTrue(policy.Calls.TryReceive(out var cc)); + Assert.IsFalse(request1.IsCompleted); + + cc.ForwardToBob(); + Assert.IsTrue(policy.Returns.ReceiveAsync().Wait(MediumNonDbgTimeout)); + Assert.IsNotNull(cc.Exception); + cc.ReturnCanceled = false; + cc.Exception = null; + + cc.ReturnToAlice(); + Assert.ThrowsException(() => cc.ReturnToAlice()); + + Assert.IsTrue(request1.IsCompleted); + Assert.IsFalse(request1.IsFaulted); + } + } + } + [TestMethod] public void InterceptClientSideRedirectCall() { @@ -293,7 +368,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); @@ -320,6 +395,44 @@ namespace Capnp.Net.Runtime.Tests } } + [TestMethod] + public void InterceptClientSideModifyPipelinedCall() + { + var policy = new MyPolicy("a"); + + (var server, var client) = SetupClientServerPair(TcpRpcTestOptions.ClientTracer); + + using (server) + using (client) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + server.Main = impl; + using (var main = policy.Attach(client.GetMain())) + { + var req = main.GetNull().Eager().GetCallSequence(0); + Assert.IsTrue(policy.Calls.TryReceive(out var ccGetNull)); + Assert.IsTrue(policy.Calls.TryReceive(out var ccGetCallSequence)); + + ccGetNull.ForwardToBob(); + + Assert.IsTrue(policy.Returns.ReceiveAsync().Wait(MediumNonDbgTimeout)); + + ccGetNull.ReturnToAlice(); + + ccGetCallSequence.Bob = Proxy.Share(impl); + ccGetCallSequence.ForwardToBob(); + + Assert.IsTrue(policy.Returns.ReceiveAsync().Wait(MediumNonDbgTimeout)); + + ccGetCallSequence.ReturnToAlice(); + + Assert.IsTrue(req.IsCompleted && !req.IsFaulted && !req.IsCanceled); + Assert.AreEqual(0u, req.Result); + } + } + } + [TestMethod] public void InterfaceAndMethodId() { @@ -330,7 +443,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); @@ -355,7 +468,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestTailCallerImpl(counters); @@ -387,7 +500,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); @@ -427,7 +540,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = policy.Attach(new TestMoreStuffImpl(counters)); @@ -484,7 +597,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); @@ -552,7 +665,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); @@ -592,7 +705,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); server.Main = implAc; using (var main = client.GetMain()) @@ -620,5 +733,35 @@ namespace Capnp.Net.Runtime.Tests } } + [TestMethod] + public void AttachWrongUse() + { + var impl = new TestInterfaceImpl2(); + Assert.ThrowsException(() => default(IInterceptionPolicy).Attach(impl)); + Assert.ThrowsException(() => new MyPolicy("x").Attach(default(ITestInterface))); + } + + [TestMethod] + public void DetachWrongUse() + { + var impl = new TestInterfaceImpl2(); + Assert.ThrowsException(() => default(IInterceptionPolicy).Detach(impl)); + Assert.ThrowsException(() => new MyPolicy("x").Detach(default(ITestInterface))); + } + + [TestMethod] + public void AttachDetach() + { + ConsumedCapability GetCap(object obj) => ((Proxy)obj).ConsumedCap; + + var a = new MyPolicy("a"); + var b = new MyPolicy("b"); + var c = new MyPolicy("c"); + var proxy = Proxy.Share(new TestInterfaceImpl2()); + var attached = a.Attach(b.Attach(c.Attach(proxy))); + Assert.AreEqual(GetCap(attached), GetCap(b.Attach(attached))); + var detached = c.Detach(a.Detach(b.Detach(attached))); + Assert.AreEqual(GetCap(proxy), GetCap(detached)); + } } } diff --git a/Capnp.Net.Runtime.Tests/LocalRpc.cs b/Capnp.Net.Runtime.Tests/LocalRpc.cs new file mode 100644 index 0000000..36ab7e5 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/LocalRpc.cs @@ -0,0 +1,253 @@ +using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Rpc; +using Capnproto_test.Capnp.Test; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Threading.Tasks.Dataflow; + +namespace Capnp.Net.Runtime.Tests +{ + [TestClass] + [TestCategory("Coverage")] + public class LocalRpc: TestBase + { + [TestMethod] + public void DeferredLocalAnswer() + { + var tcs = new TaskCompletionSource(); + var impl = new TestPipelineImpl2(tcs.Task); + var bproxy = BareProxy.FromImpl(impl); + using (var proxy = bproxy.Cast(true)) + using (var cap = proxy.GetCap(0, null).OutBox_Cap()) + { + var foo = cap.Foo(123, true); + tcs.SetResult(0); + Assert.IsTrue(foo.Wait(TestBase.MediumNonDbgTimeout)); + Assert.AreEqual("bar", foo.Result); + } + } + + [TestMethod] + public void Embargo() + { + NewLocalTestbed().RunTest(Testsuite.EmbargoOnPromisedAnswer); + } + + [TestMethod] + public void EmbargoError() + { + NewLocalTestbed().RunTest(Testsuite.EmbargoError); + } + + [TestMethod] + public void EmbargoNull() + { + NewLocalTestbed().RunTest(Testsuite.EmbargoNull); + } + + [TestMethod] + public void CallBrokenPromise() + { + NewLocalTestbed().RunTest(Testsuite.CallBrokenPromise); + } + + [TestMethod] + public void TailCall() + { + NewLocalTestbed().RunTest(Testsuite.TailCall); + } + + [TestMethod] + public void SendTwice() + { + NewLocalTestbed().RunTest(Testsuite.SendTwice); + } + + [TestMethod] + public void Cancel() + { + NewLocalTestbed().RunTest(Testsuite.Cancel); + } + + [TestMethod] + public void RetainAndRelease() + { + NewLocalTestbed().RunTest(Testsuite.RetainAndRelease); + } + + [TestMethod] + public void PromiseResolve() + { + NewLocalTestbed().RunTest(Testsuite.PromiseResolve); + } + + [TestMethod] + public void Cancelation() + { + NewLocalTestbed().RunTest(Testsuite.Cancelation); + } + + [TestMethod] + public void ReleaseOnCancel() + { + NewLocalTestbed().RunTest(Testsuite.ReleaseOnCancel); + } + + [TestMethod] + public void Release() + { + NewLocalTestbed().RunTest(Testsuite.Release); + } + + [TestMethod] + public void Pipeline() + { + NewLocalTestbed().RunTest(Testsuite.Pipeline); + } + + [TestMethod] + public void Basic() + { + NewLocalTestbed().RunTest(Testsuite.Basic); + } + + [TestMethod] + public void Ownership1() + { + NewLocalTestbed().RunTest(Testsuite.Ownership1); + } + + [TestMethod] + public void Ownership2() + { + NewLocalTestbed().RunTest(Testsuite.Ownership2); + } + + [TestMethod] + public void Ownership3() + { + NewLocalTestbed().RunTest(Testsuite.Ownership3); + } + + [TestMethod] + public void ImportReceiverAnswer() + { + NewLocalTestbed().RunTest(Testsuite.Ownership3); + } + + [TestMethod] + public void LegacyAccess() + { + NewLocalTestbed().RunTest(Testsuite.LegacyAccess); + } + + [TestMethod] + public void EagerRace() + { + var impl = new TestMoreStuffImpl(new Counters()); + var tcs = new TaskCompletionSource(); + using (var promise = tcs.Task.Eager(true)) + using (var cts = new CancellationTokenSource()) + { + var bb = new BufferBlock>(); + int counter = 0; + + void Generator() + { + while (!cts.IsCancellationRequested) + { + bb.Post(promise.GetCallSequence((uint)Volatile.Read(ref counter))); + Interlocked.Increment(ref counter); + } + + bb.Complete(); + } + + async Task Verifier() + { + uint i = 0; + while (true) + { + Task t; + + try + { + t = await bb.ReceiveAsync(); + } + catch (InvalidOperationException) + { + break; + } + + uint j = await t; + Assert.AreEqual(i, j); + i++; + } + } + + var genTask = Task.Run(() => Generator()); + var verTask = Verifier(); + SpinWait.SpinUntil(() => Volatile.Read(ref counter) >= 100); + Task.Run(() => tcs.SetResult(impl)); + cts.Cancel(); + Assert.IsTrue(genTask.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(verTask.Wait(MediumNonDbgTimeout)); + } + } + + [TestMethod] + public void AwaitNoDeadlock() + { + for (int i = 0; i < 100; i++) + { + var tcs1 = new TaskCompletionSource(); + var tcs2 = new TaskCompletionSource(); + + var t1 = Capnp.Util.StrictlyOrderedTaskExtensions.EnforceAwaitOrder(tcs1.Task); + var t2 = Capnp.Util.StrictlyOrderedTaskExtensions.EnforceAwaitOrder(tcs2.Task); + + async Task Wait1() + { + await t1; + await t2; + } + + async Task Wait2() + { + await t2; + await t1; + } + + var w1 = Wait1(); + var w2 = Wait2(); + + Task.Run(() => tcs1.SetResult(0)); + Task.Run(() => tcs2.SetResult(0)); + + Assert.IsTrue(Task.WaitAll(new Task[] { w1, w2 }, MediumNonDbgTimeout)); + } + } + + [TestMethod] + public void DisposedProxy() + { + var b = new BareProxy(); + Assert.ThrowsException(() => b.Bind(null)); + var impl = new TestInterfaceImpl2(); + var proxy = Proxy.Share(impl); + var p = (Proxy)proxy; + Assert.ThrowsException(() => p.Bind(p.ConsumedCap)); + Assert.IsFalse(p.IsDisposed); + proxy.Dispose(); + Assert.IsTrue(p.IsDisposed); + Assert.ThrowsException(() => p.ConsumedCap); + var t = proxy.Foo(123, true); + Assert.IsTrue(Assert.ThrowsExceptionAsync(() => t).Wait(MediumNonDbgTimeout)); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/MessageBuilderTests.cs b/Capnp.Net.Runtime.Tests/MessageBuilderTests.cs index 32196a6..5b3d6b1 100644 --- a/Capnp.Net.Runtime.Tests/MessageBuilderTests.cs +++ b/Capnp.Net.Runtime.Tests/MessageBuilderTests.cs @@ -3,6 +3,7 @@ namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class MessageBuilderTests { class Struct2D0P : SerializerState diff --git a/Capnp.Net.Runtime.Tests/TestCapImplementations.cs b/Capnp.Net.Runtime.Tests/Mock/TestCapImplementations.cs similarity index 61% rename from Capnp.Net.Runtime.Tests/TestCapImplementations.cs rename to Capnp.Net.Runtime.Tests/Mock/TestCapImplementations.cs index 029ac0f..630d527 100644 --- a/Capnp.Net.Runtime.Tests/TestCapImplementations.cs +++ b/Capnp.Net.Runtime.Tests/Mock/TestCapImplementations.cs @@ -420,18 +420,53 @@ namespace Capnp.Net.Runtime.Tests.GenImpls public void Dispose() { - _tcs?.SetResult(0); + _tcs?.TrySetResult(0); + Assert.IsFalse(IsDisposed); + IsDisposed = true; + DisposeCallStack = Environment.StackTrace; } + public string DisposeCallStack { get; private set; } + public bool IsDisposed { get; private set; } + public virtual Task Foo(uint i, bool j, CancellationToken cancellationToken) { Interlocked.Increment(ref _counters.CallCount); + cancellationToken.ThrowIfCancellationRequested(); Assert.AreEqual(123u, i); Assert.IsTrue(j); return Task.FromResult("foo"); } } + class TestInterfaceImpl2 : ITestInterface + { + public Task Bar(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task Baz(TestAllTypes s, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + Assert.IsFalse(IsDisposed); + IsDisposed = true; + } + + public bool IsDisposed { get; private set; } + + public Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default) + { + Assert.AreEqual(123u, i); + Assert.IsTrue(j); + return Task.FromResult("bar"); + } + } + #endregion TestInterface #region TestExtends @@ -485,20 +520,26 @@ namespace Capnp.Net.Runtime.Tests.GenImpls public async Task<(string, TestPipeline.AnyBox)> GetAnyCap(uint n, BareProxy inCap, CancellationToken cancellationToken_) { - Interlocked.Increment(ref _counters.CallCount); - Assert.AreEqual(234u, n); - var s = await inCap.Cast(true).Foo(123, true, cancellationToken_); - Assert.AreEqual("foo", s); - return ("bar", new TestPipeline.AnyBox() { Cap = BareProxy.FromImpl(new TestExtendsImpl(_counters)) }); + using (inCap) + { + Interlocked.Increment(ref _counters.CallCount); + Assert.AreEqual(234u, n); + var s = await inCap.Cast(true).Foo(123, true, cancellationToken_); + Assert.AreEqual("foo", s); + return ("bar", new TestPipeline.AnyBox() { Cap = BareProxy.FromImpl(new TestExtendsImpl(_counters)) }); + } } public async Task<(string, TestPipeline.Box)> GetCap(uint n, ITestInterface inCap, CancellationToken cancellationToken_) { - Interlocked.Increment(ref _counters.CallCount); - Assert.AreEqual(234u, n); - var s = await inCap.Foo(123, true, cancellationToken_); - Assert.AreEqual("foo", s); - return ("bar", new TestPipeline.Box() { Cap = new TestExtendsImpl(_counters) }); + using (inCap) + { + Interlocked.Increment(ref _counters.CallCount); + Assert.AreEqual(234u, n); + var s = await inCap.Foo(123, true, cancellationToken_); + Assert.AreEqual("foo", s); + return ("bar", new TestPipeline.Box() { Cap = new TestExtendsImpl(_counters) }); + } } public Task TestPointers(ITestInterface cap, object obj, IReadOnlyList list, CancellationToken cancellationToken_) @@ -506,24 +547,61 @@ namespace Capnp.Net.Runtime.Tests.GenImpls throw new NotImplementedException(); } } + + class TestPipelineImpl2 : ITestPipeline + { + readonly Task _deblock; + readonly TestInterfaceImpl2 _timpl2; + + public TestPipelineImpl2(Task deblock) + { + _deblock = deblock; + _timpl2 = new TestInterfaceImpl2(); + } + + public void Dispose() + { + } + + public bool IsChildCapDisposed => _timpl2.IsDisposed; + + public Task<(string, TestPipeline.AnyBox)> GetAnyCap(uint n, BareProxy inCap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public async Task<(string, TestPipeline.Box)> GetCap(uint n, ITestInterface inCap, CancellationToken cancellationToken_ = default) + { + using (inCap) + { + await _deblock; + return ("hello", new TestPipeline.Box() { Cap = _timpl2 }); + } + } + + public Task TestPointers(ITestInterface cap, object obj, IReadOnlyList list, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + } + #endregion TestPipeline #region TestCallOrder class TestCallOrderImpl : ITestCallOrder { readonly object _lock = new object(); + uint _counter; ILogger Logger { get; } = Logging.CreateLogger(); - public uint Count { get; set; } - public uint? CountToDispose { get; set; } public void Dispose() { lock (_lock) - { - Assert.IsTrue(!CountToDispose.HasValue || Count == CountToDispose, "Must not dispose at this point"); + { + Assert.IsTrue(!CountToDispose.HasValue || _counter == CountToDispose, $"Must not dispose at this point: {_counter} {Thread.CurrentThread.Name}"); } } @@ -531,26 +609,24 @@ namespace Capnp.Net.Runtime.Tests.GenImpls { lock (_lock) { - return Task.FromResult(Count++); + Assert.AreEqual(expected, _counter); + return Task.FromResult(_counter++); + } + } + + public uint Count + { + get + { + lock (_lock) + { + return _counter; + } } } } #endregion TestCallOrder - #region TestTailCaller - class TestTailCaller : ITestTailCaller - { - public void Dispose() - { - } - - public Task Foo(int i, ITestTailCallee callee, CancellationToken cancellationToken_) - { - return callee.Foo(i, "from TestTailCaller", cancellationToken_); - } - } - #endregion TestTailCaller - #region TestTailCaller class TestTailCallerImpl : ITestTailCaller { @@ -575,6 +651,107 @@ namespace Capnp.Net.Runtime.Tests.GenImpls } } } + + class TestTailCallerImpl2 : ITestTailCaller + { + ITestCallOrder _keeper; + + public TestTailCallerImpl2() + { + } + + public void Dispose() + { + _keeper?.Dispose(); + } + + public Task Foo(int i, ITestTailCallee callee, CancellationToken cancellationToken_) + { + using (callee) + { + if (_keeper == null) + { + var task = callee.Foo(i, "from TestTailCaller", cancellationToken_); + _keeper = task.C(); + return task; + } + else + { + return Task.FromResult( + new TestTailCallee.TailResult() + { + C = _keeper + }); + } + } + } + } + + class TestTailCallerImpl3 : ITestTailCaller + { + public TestTailCallerImpl3() + { + } + + public void Dispose() + { + } + + public Task Foo(int i, ITestTailCallee callee, CancellationToken cancellationToken_) + { + using (callee) + { + var task1 = callee.Foo(i, "from TestTailCaller 1", cancellationToken_); + + async void FinishTask() + { + var r = await task1; + r.C.Dispose(); + } + + FinishTask(); + + var task2 = callee.Foo(i, "from TestTailCaller 2", cancellationToken_); + + async void AssertIsTailCall() + { + try + { + await task2; + Assert.Fail("Not a tail call"); + } + catch (NoResultsException) + { + } + } + + AssertIsTailCall(); + + return task2; + } + } + } + + class TestTailCallerImpl4 : ITestTailCaller + { + public TestTailCallerImpl4() + { + } + + public void Dispose() + { + } + + public async Task Foo(int i, ITestTailCallee callee, CancellationToken cancellationToken_) + { + await Task.Yield(); + + using (callee) + { + return await callee.Foo(i, "from TestTailCaller", cancellationToken_); + } + } + } #endregion TestTailCaller #region TestTailCallee @@ -589,10 +766,15 @@ namespace Capnp.Net.Runtime.Tests.GenImpls public void Dispose() { + IsDisposed = true; } + public bool IsDisposed { get; private set; } + public Task Foo(int i, string t, CancellationToken cancellationToken_) { + Assert.IsFalse(IsDisposed); + Interlocked.Increment(ref _counters.CallCount); var result = new TestTailCallee.TailResult() @@ -638,9 +820,12 @@ namespace Capnp.Net.Runtime.Tests.GenImpls public async Task CallFooWhenResolved(ITestInterface cap, CancellationToken cancellationToken_) { Interlocked.Increment(ref _counters.CallCount); - await ((Proxy)cap).WhenResolved; - string s = await cap.Foo(123, true, cancellationToken_); - Assert.AreEqual("foo", s); + using (cap) + { + await ((Proxy)cap).WhenResolved; + string s = await cap.Foo(123, true, cancellationToken_); + Assert.AreEqual("foo", s); + } return "bar"; } @@ -656,6 +841,7 @@ namespace Capnp.Net.Runtime.Tests.GenImpls public void Dispose() { ClientToHold?.Dispose(); + ClientToHold = null; } public Task Echo(ITestCallOrder cap, CancellationToken cancellationToken_) @@ -687,7 +873,7 @@ namespace Capnp.Net.Runtime.Tests.GenImpls public Task GetHeld(CancellationToken cancellationToken_) { Interlocked.Increment(ref _counters.CallCount); - return Task.FromResult(ClientToHold); + return Task.FromResult(Proxy.Share(ClientToHold)); } public Task GetNull(CancellationToken cancellationToken_) @@ -735,6 +921,399 @@ namespace Capnp.Net.Runtime.Tests.GenImpls } } + class TestMoreStuffImpl2 : ITestMoreStuff + { + readonly TaskCompletionSource _echo = new TaskCompletionSource(); + readonly TaskCompletionSource _held = new TaskCompletionSource(); + ITestCallOrder _cap; + int _callCount; + + public TestMoreStuffImpl2() + { + } + + public async Task CallFoo(ITestInterface cap, CancellationToken cancellationToken_) + { + using (cap) + { + string s = await cap.Foo(123, true, cancellationToken_); + Assert.AreEqual("foo", s); + } + return "bar"; + } + + public Task CallFooWhenResolved(ITestInterface cap, CancellationToken cancellationToken_) + { + throw new NotImplementedException(); + } + + public Task CallHeld(CancellationToken cancellationToken_) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + } + + public Task Echo(ITestCallOrder cap, CancellationToken cancellationToken_) + { + _cap = cap; + return Task.FromResult(_echo.Task.Eager(true)); + } + + public void EnableEcho() + { + _echo.SetResult(_cap); + } + + public Task ExpectCancel(ITestInterface cap, CancellationToken cancellationToken_) + { + throw new NotImplementedException(); + } + + public Task GetCallSequence(uint expected, CancellationToken cancellationToken_) + { + return Task.FromResult((uint)(Interlocked.Increment(ref _callCount) - 1)); + } + + public Task GetEnormousString(CancellationToken cancellationToken_) + { + return Task.FromResult(new string(new char[100000000])); + } + + public Task GetHandle(CancellationToken cancellationToken_) + { + throw new NotImplementedException(); + } + + public Task GetHeld(CancellationToken cancellationToken_) + { + return _held.Task; + } + + public Task GetNull(CancellationToken cancellationToken_) + { + return Task.FromResult(default(ITestMoreStuff)); + } + + public async Task Hold(ITestInterface cap, CancellationToken cancellationToken_) + { + try + { + var unwrapped = await cap.Unwrap(); + _held.SetResult(unwrapped); + } + catch (System.Exception exception) when (exception.Message == new TaskCanceledException().Message) + { + _held.SetCanceled(); + } + catch (System.Exception exception) + { + _held.SetException(exception); + } + } + + public Task<(string, string)> MethodWithDefaults(string a, uint b, string c, CancellationToken cancellationToken_) + { + throw new NotImplementedException(); + } + + public Task MethodWithNullDefault(string a, ITestInterface b, CancellationToken cancellationToken_) + { + throw new NotImplementedException(); + } + + public Task NeverReturn(ITestInterface cap, CancellationToken cancellationToken_) + { + throw new NotImplementedException(); + } + } + + class TestMoreStuffImpl3 : ITestMoreStuff, ITestCallOrder + { + readonly TaskCompletionSource _heldCap = new TaskCompletionSource(); + + public Task CallFoo(ITestInterface cap, CancellationToken cancellationToken_ = default) + { + using (cap) + { + return cap.Foo(123, true); + } + } + + public Task CallFooWhenResolved(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task CallHeld(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public async void Dispose() + { + using (var cap = await _heldCap.Task) + { + } + } + + int _echoCounter; + + public Task Echo(ITestCallOrder cap, CancellationToken cancellationToken_ = default) + { + if (_echoCounter++ < 20) + { + return Task.FromResult(((Proxy)cap).Cast(false).Echo(cap).Eager()); + } + else + { + return Task.FromResult(cap); + } + } + + public Task ExpectCancel(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + uint _counter; + + public Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default) + { + Assert.AreEqual(_counter, expected); + return Task.FromResult(_counter++); + } + + public Task GetEnormousString(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task GetHandle(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public async Task GetHeld(CancellationToken cancellationToken_ = default) + { + return await _heldCap.Task; + } + + public Task GetNull(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task Hold(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + _heldCap.SetResult(Cap); + return Task.CompletedTask; + } + + public Task<(string, string)> MethodWithDefaults(string A, uint B, string C, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task MethodWithNullDefault(string A, ITestInterface B, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task NeverReturn(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + } + + class TestMoreStuffImpl4 : ITestMoreStuff, ITestCallOrder + { + readonly TaskCompletionSource _heldCap = new TaskCompletionSource(); + + public Task CallFoo(ITestInterface cap, CancellationToken cancellationToken_ = default) + { + using (cap) + { + return cap.Foo(123, true); + } + } + + public Task CallFooWhenResolved(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task CallHeld(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public async void Dispose() + { + using (var cap = await _heldCap.Task) + { + } + } + + public Task Echo(ITestCallOrder cap, CancellationToken cancellationToken_ = default) + { + using (var target = ((Proxy)cap).Cast(false)) + { + return Task.FromResult(target.Echo(cap).Eager()); + } + } + + public Task ExpectCancel(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + uint _counter; + + public Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default) + { + Assert.AreEqual(_counter, expected); + return Task.FromResult(_counter++); + } + + public Task GetEnormousString(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task GetHandle(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task GetHeld(CancellationToken cancellationToken_ = default) + { + return Task.FromResult(_heldCap.Task.Eager(true)); + } + + public Task GetNull(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task Hold(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + _heldCap.SetResult(Cap); + return Task.CompletedTask; + } + + public Task<(string, string)> MethodWithDefaults(string A, uint B, string C, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task MethodWithNullDefault(string A, ITestInterface B, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task NeverReturn(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + } + + class TestMoreStuffImpl5 : ITestMoreStuff, ITestCallOrder + { + readonly TaskCompletionSource _heldCap = new TaskCompletionSource(); + + public Task CallFoo(ITestInterface cap, CancellationToken cancellationToken_ = default) + { + using (cap) + { + return cap.Foo(123, true); + } + } + + public Task CallFooWhenResolved(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task CallHeld(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public async void Dispose() + { + using (var cap = await _heldCap.Task) + { + } + } + + TaskCompletionSource _echoEnabled = new TaskCompletionSource(); + + public void EnableEcho() => _echoEnabled.SetResult(0); + + public async Task Echo(ITestCallOrder cap, CancellationToken cancellationToken_ = default) + { + await _echoEnabled.Task; + return cap; + } + + public Task ExpectCancel(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + uint _counter; + + public Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default) + { + Assert.AreEqual(_counter, expected); + return Task.FromResult(_counter++); + } + + public Task GetEnormousString(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task GetHandle(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task GetHeld(CancellationToken cancellationToken_ = default) + { + return Task.FromResult(_heldCap.Task.Eager(true)); + } + + public Task GetNull(CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task Hold(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + _heldCap.SetResult(Cap); + return Task.CompletedTask; + } + + public Task<(string, string)> MethodWithDefaults(string A, uint B, string C, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task MethodWithNullDefault(string A, ITestInterface B, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + + public Task NeverReturn(ITestInterface Cap, CancellationToken cancellationToken_ = default) + { + throw new NotImplementedException(); + } + } + #endregion TestMoreStuff #region TestHandle diff --git a/Capnp.Net.Runtime.Tests/test.cs b/Capnp.Net.Runtime.Tests/Mock/test.cs similarity index 86% rename from Capnp.Net.Runtime.Tests/test.cs rename to Capnp.Net.Runtime.Tests/Mock/test.cs index e56b8ff..1e6dacb 100644 --- a/Capnp.Net.Runtime.Tests/test.cs +++ b/Capnp.Net.Runtime.Tests/Mock/test.cs @@ -1,13 +1,14 @@ using Capnp; using Capnp.Rpc; using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace Capnproto_test.Capnp.Test { - [TypeId(0x9c8e9318b29d9cd3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9c8e9318b29d9cd3UL)] public enum TestEnum : ushort { foo, @@ -20,7 +21,7 @@ namespace Capnproto_test.Capnp.Test garply } - [TypeId(0xa0a8f314b80b63fdUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa0a8f314b80b63fdUL)] public class TestAllTypes : ICapnpSerializable { public const UInt64 typeId = 0xa0a8f314b80b63fdUL; @@ -56,7 +57,7 @@ namespace Capnproto_test.Capnp.Test Float64List = reader.Float64List; TextList = reader.TextList; DataList = reader.DataList; - StructList = reader.StructList.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + StructList = reader.StructList?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); EnumList = reader.EnumList; InterfaceList = reader.InterfaceList; applyDefaults(); @@ -321,7 +322,7 @@ namespace Capnproto_test.Capnp.Test public ulong UInt64Field => ctx.ReadDataULong(192UL, 0UL); public float Float32Field => ctx.ReadDataFloat(256UL, 0F); public double Float64Field => ctx.ReadDataDouble(320UL, 0); - public string TextField => ctx.ReadText(0, ""); + public string TextField => ctx.ReadText(0, null); public IReadOnlyList DataField => ctx.ReadList(1).CastByte(); public Capnproto_test.Capnp.Test.TestAllTypes.READER StructField => ctx.ReadStruct(2, Capnproto_test.Capnp.Test.TestAllTypes.READER.create); public Capnproto_test.Capnp.Test.TestEnum EnumField => (Capnproto_test.Capnp.Test.TestEnum)ctx.ReadDataUShort(288UL, (ushort)0); @@ -419,8 +420,8 @@ namespace Capnproto_test.Capnp.Test public string TextField { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ListOfPrimitivesSerializer DataField @@ -545,7 +546,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xeb3f9ebe98c73cb6UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xeb3f9ebe98c73cb6UL)] public class TestDefaults : ICapnpSerializable { public const UInt64 typeId = 0xeb3f9ebe98c73cb6UL; @@ -581,7 +582,7 @@ namespace Capnproto_test.Capnp.Test Float64List = reader.Float64List; TextList = reader.TextList; DataList = reader.DataList; - StructList = reader.StructList.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + StructList = reader.StructList?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); EnumList = reader.EnumList; InterfaceList = reader.InterfaceList; applyDefaults(); @@ -1216,7 +1217,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe3da5a2ccd28c0d8UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe3da5a2ccd28c0d8UL)] public class TestAnyPointer : ICapnpSerializable { public const UInt64 typeId = 0xe3da5a2ccd28c0d8UL; @@ -1276,7 +1277,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf49850f63c2bfa59UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf49850f63c2bfa59UL)] public class TestAnyOthers : ICapnpSerializable { public const UInt64 typeId = 0xf49850f63c2bfa59UL; @@ -1284,7 +1285,7 @@ namespace Capnproto_test.Capnp.Test { var reader = READER.create(arg_); AnyStructField = CapnpSerializable.Create(reader.AnyStructField); - AnyListField = reader.AnyListField.ToReadOnlyList(_ => (object)_); + AnyListField = reader.AnyListField?.ToReadOnlyList(_ => (object)_); CapabilityField = reader.CapabilityField; applyDefaults(); } @@ -1366,7 +1367,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa9d5f8efe770022bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9d5f8efe770022bUL)] public class TestOutOfOrder : ICapnpSerializable { public const UInt64 typeId = 0xa9d5f8efe770022bUL; @@ -1472,15 +1473,15 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Qux => ctx.ReadText(0, ""); - public string Grault => ctx.ReadText(1, ""); - public string Bar => ctx.ReadText(2, ""); - public string Foo => ctx.ReadText(3, ""); - public string Corge => ctx.ReadText(4, ""); - public string Waldo => ctx.ReadText(5, ""); - public string Quux => ctx.ReadText(6, ""); - public string Garply => ctx.ReadText(7, ""); - public string Baz => ctx.ReadText(8, ""); + public string Qux => ctx.ReadText(0, null); + public string Grault => ctx.ReadText(1, null); + public string Bar => ctx.ReadText(2, null); + public string Foo => ctx.ReadText(3, null); + public string Corge => ctx.ReadText(4, null); + public string Waldo => ctx.ReadText(5, null); + public string Quux => ctx.ReadText(6, null); + public string Garply => ctx.ReadText(7, null); + public string Baz => ctx.ReadText(8, null); } public class WRITER : SerializerState @@ -1492,71 +1493,71 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Grault { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } public string Bar { - get => this.ReadText(2, ""); - set => this.WriteText(2, value, ""); + get => this.ReadText(2, null); + set => this.WriteText(2, value, null); } public string Foo { - get => this.ReadText(3, ""); - set => this.WriteText(3, value, ""); + get => this.ReadText(3, null); + set => this.WriteText(3, value, null); } public string Corge { - get => this.ReadText(4, ""); - set => this.WriteText(4, value, ""); + get => this.ReadText(4, null); + set => this.WriteText(4, value, null); } public string Waldo { - get => this.ReadText(5, ""); - set => this.WriteText(5, value, ""); + get => this.ReadText(5, null); + set => this.WriteText(5, value, null); } public string Quux { - get => this.ReadText(6, ""); - set => this.WriteText(6, value, ""); + get => this.ReadText(6, null); + set => this.WriteText(6, value, null); } public string Garply { - get => this.ReadText(7, ""); - set => this.WriteText(7, value, ""); + get => this.ReadText(7, null); + set => this.WriteText(7, value, null); } public string Baz { - get => this.ReadText(8, ""); - set => this.WriteText(8, value, ""); + get => this.ReadText(8, null); + set => this.WriteText(8, value, null); } } } - [TypeId(0xf47697362233ce52UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf47697362233ce52UL)] public class TestUnion : ICapnpSerializable { public const UInt64 typeId = 0xf47697362233ce52UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - Union0 = CapnpSerializable.Create(reader.Union0); - Union1 = CapnpSerializable.Create(reader.Union1); - Union2 = CapnpSerializable.Create(reader.Union2); - Union3 = CapnpSerializable.Create(reader.Union3); + Union0 = CapnpSerializable.Create(reader.Union0); + Union1 = CapnpSerializable.Create(reader.Union1); + Union2 = CapnpSerializable.Create(reader.Union2); + Union3 = CapnpSerializable.Create(reader.Union3); Bit0 = reader.Bit0; Bit2 = reader.Bit2; Bit3 = reader.Bit3; @@ -1593,25 +1594,25 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestUnion.@union0 Union0 + public Capnproto_test.Capnp.Test.TestUnion.union0 Union0 { get; set; } - public Capnproto_test.Capnp.Test.TestUnion.@union1 Union1 + public Capnproto_test.Capnp.Test.TestUnion.union1 Union1 { get; set; } - public Capnproto_test.Capnp.Test.TestUnion.@union2 Union2 + public Capnproto_test.Capnp.Test.TestUnion.union2 Union2 { get; set; } - public Capnproto_test.Capnp.Test.TestUnion.@union3 Union3 + public Capnproto_test.Capnp.Test.TestUnion.union3 Union3 { get; set; @@ -1676,10 +1677,10 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public @union0.READER Union0 => new @union0.READER(ctx); - public @union1.READER Union1 => new @union1.READER(ctx); - public @union2.READER Union2 => new @union2.READER(ctx); - public @union3.READER Union3 => new @union3.READER(ctx); + public union0.READER Union0 => new union0.READER(ctx); + public union1.READER Union1 => new union1.READER(ctx); + public union2.READER Union2 => new union2.READER(ctx); + public union3.READER Union3 => new union3.READER(ctx); public bool Bit0 => ctx.ReadDataBool(128UL, false); public bool Bit2 => ctx.ReadDataBool(130UL, false); public bool Bit3 => ctx.ReadDataBool(131UL, false); @@ -1697,24 +1698,24 @@ namespace Capnproto_test.Capnp.Test this.SetStruct(8, 2); } - public @union0.WRITER Union0 + public union0.WRITER Union0 { - get => Rewrap<@union0.WRITER>(); + get => Rewrap(); } - public @union1.WRITER Union1 + public union1.WRITER Union1 { - get => Rewrap<@union1.WRITER>(); + get => Rewrap(); } - public @union2.WRITER Union2 + public union2.WRITER Union2 { - get => Rewrap<@union2.WRITER>(); + get => Rewrap(); } - public @union3.WRITER Union3 + public union3.WRITER Union3 { - get => Rewrap<@union3.WRITER>(); + get => Rewrap(); } public bool Bit0 @@ -1766,8 +1767,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xfc76a82eecb7a718UL)] - public class @union0 : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfc76a82eecb7a718UL)] + public class union0 : ICapnpSerializable { public const UInt64 typeId = 0xfc76a82eecb7a718UL; public enum WHICH : ushort @@ -2091,13 +2092,13 @@ namespace Capnproto_test.Capnp.Test public short U0f0s16 => which == WHICH.U0f0s16 ? ctx.ReadDataShort(64UL, (short)0) : default; public int U0f0s32 => which == WHICH.U0f0s32 ? ctx.ReadDataInt(64UL, 0) : default; public long U0f0s64 => which == WHICH.U0f0s64 ? ctx.ReadDataLong(64UL, 0L) : default; - public string U0f0sp => which == WHICH.U0f0sp ? ctx.ReadText(0, "") : default; + public string U0f0sp => which == WHICH.U0f0sp ? ctx.ReadText(0, null) : default; public bool U0f1s1 => which == WHICH.U0f1s1 ? ctx.ReadDataBool(64UL, false) : default; public sbyte U0f1s8 => which == WHICH.U0f1s8 ? ctx.ReadDataSByte(64UL, (sbyte)0) : default; public short U0f1s16 => which == WHICH.U0f1s16 ? ctx.ReadDataShort(64UL, (short)0) : default; public int U0f1s32 => which == WHICH.U0f1s32 ? ctx.ReadDataInt(64UL, 0) : default; public long U0f1s64 => which == WHICH.U0f1s64 ? ctx.ReadDataLong(64UL, 0L) : default; - public string U0f1sp => which == WHICH.U0f1sp ? ctx.ReadText(0, "") : default; + public string U0f1sp => which == WHICH.U0f1sp ? ctx.ReadText(0, null) : default; } public class WRITER : SerializerState @@ -2144,8 +2145,8 @@ namespace Capnproto_test.Capnp.Test public string U0f0sp { - get => which == WHICH.U0f0sp ? this.ReadText(0, "") : default; - set => this.WriteText(0, value, ""); + get => which == WHICH.U0f0sp ? this.ReadText(0, null) : default; + set => this.WriteText(0, value, null); } public bool U0f1s1 @@ -2180,14 +2181,14 @@ namespace Capnproto_test.Capnp.Test public string U0f1sp { - get => which == WHICH.U0f1sp ? this.ReadText(0, "") : default; - set => this.WriteText(0, value, ""); + get => which == WHICH.U0f1sp ? this.ReadText(0, null) : default; + set => this.WriteText(0, value, null); } } } - [TypeId(0xee0a6b99b7dc7ab2UL)] - public class @union1 : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xee0a6b99b7dc7ab2UL)] + public class union1 : ICapnpSerializable { public const UInt64 typeId = 0xee0a6b99b7dc7ab2UL; public enum WHICH : ushort @@ -2636,14 +2637,14 @@ namespace Capnproto_test.Capnp.Test public int U1f1s32 => which == WHICH.U1f1s32 ? ctx.ReadDataInt(160UL, 0) : default; public long U1f0s64 => which == WHICH.U1f0s64 ? ctx.ReadDataLong(192UL, 0L) : default; public long U1f1s64 => which == WHICH.U1f1s64 ? ctx.ReadDataLong(192UL, 0L) : default; - public string U1f0sp => which == WHICH.U1f0sp ? ctx.ReadText(1, "") : default; - public string U1f1sp => which == WHICH.U1f1sp ? ctx.ReadText(1, "") : default; + public string U1f0sp => which == WHICH.U1f0sp ? ctx.ReadText(1, null) : default; + public string U1f1sp => which == WHICH.U1f1sp ? ctx.ReadText(1, null) : default; public bool U1f2s1 => which == WHICH.U1f2s1 ? ctx.ReadDataBool(129UL, false) : default; public sbyte U1f2s8 => which == WHICH.U1f2s8 ? ctx.ReadDataSByte(136UL, (sbyte)0) : default; public short U1f2s16 => which == WHICH.U1f2s16 ? ctx.ReadDataShort(144UL, (short)0) : default; public int U1f2s32 => which == WHICH.U1f2s32 ? ctx.ReadDataInt(160UL, 0) : default; public long U1f2s64 => which == WHICH.U1f2s64 ? ctx.ReadDataLong(192UL, 0L) : default; - public string U1f2sp => which == WHICH.U1f2sp ? ctx.ReadText(1, "") : default; + public string U1f2sp => which == WHICH.U1f2sp ? ctx.ReadText(1, null) : default; } public class WRITER : SerializerState @@ -2720,14 +2721,14 @@ namespace Capnproto_test.Capnp.Test public string U1f0sp { - get => which == WHICH.U1f0sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f0sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public string U1f1sp { - get => which == WHICH.U1f1sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f1sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public bool U1f2s1 @@ -2762,14 +2763,14 @@ namespace Capnproto_test.Capnp.Test public string U1f2sp { - get => which == WHICH.U1f2sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f2sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } } } - [TypeId(0xafc5fd419f0d66d4UL)] - public class @union2 : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xafc5fd419f0d66d4UL)] + public class union2 : ICapnpSerializable { public const UInt64 typeId = 0xafc5fd419f0d66d4UL; public enum WHICH : ushort @@ -2983,8 +2984,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa2fb022ec7f30053UL)] - public class @union3 : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa2fb022ec7f30053UL)] + public class union3 : ICapnpSerializable { public const UInt64 typeId = 0xa2fb022ec7f30053UL; public enum WHICH : ushort @@ -3199,7 +3200,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9e2e784c915329b6UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9e2e784c915329b6UL)] public class TestUnnamedUnion : ICapnpSerializable { public const UInt64 typeId = 0x9e2e784c915329b6UL; @@ -3328,11 +3329,11 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(32U, (ushort)0); - public string Before => ctx.ReadText(0, ""); + public string Before => ctx.ReadText(0, null); public ushort Foo => which == WHICH.Foo ? ctx.ReadDataUShort(0UL, (ushort)0) : default; public ushort Middle => ctx.ReadDataUShort(16UL, (ushort)0); public uint Bar => which == WHICH.Bar ? ctx.ReadDataUInt(64UL, 0U) : default; - public string After => ctx.ReadText(1, ""); + public string After => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -3350,8 +3351,8 @@ namespace Capnproto_test.Capnp.Test public string Before { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ushort Foo @@ -3374,20 +3375,20 @@ namespace Capnproto_test.Capnp.Test public string After { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } - [TypeId(0x89a9494f1b900f22UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x89a9494f1b900f22UL)] public class TestUnionInUnion : ICapnpSerializable { public const UInt64 typeId = 0x89a9494f1b900f22UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - Outer = CapnpSerializable.Create(reader.Outer); + Outer = CapnpSerializable.Create(reader.Outer); applyDefaults(); } @@ -3405,7 +3406,7 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestUnionInUnion.@outer Outer + public Capnproto_test.Capnp.Test.TestUnionInUnion.outer Outer { get; set; @@ -3422,7 +3423,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public @outer.READER Outer => new @outer.READER(ctx); + public outer.READER Outer => new outer.READER(ctx); } public class WRITER : SerializerState @@ -3432,14 +3433,14 @@ namespace Capnproto_test.Capnp.Test this.SetStruct(2, 0); } - public @outer.WRITER Outer + public outer.WRITER Outer { - get => Rewrap<@outer.WRITER>(); + get => Rewrap(); } } - [TypeId(0xd005f6c63707670cUL)] - public class @outer : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd005f6c63707670cUL)] + public class outer : ICapnpSerializable { public const UInt64 typeId = 0xd005f6c63707670cUL; public enum WHICH : ushort @@ -3455,7 +3456,7 @@ namespace Capnproto_test.Capnp.Test switch (reader.which) { case WHICH.Inner: - Inner = CapnpSerializable.Create(reader.Inner); + Inner = CapnpSerializable.Create(reader.Inner); break; case WHICH.Baz: Baz = reader.Baz; @@ -3510,9 +3511,9 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestUnionInUnion.@outer.@inner Inner + public Capnproto_test.Capnp.Test.TestUnionInUnion.outer.inner Inner { - get => _which == WHICH.Inner ? (Capnproto_test.Capnp.Test.TestUnionInUnion.@outer.@inner)_content : null; + get => _which == WHICH.Inner ? (Capnproto_test.Capnp.Test.TestUnionInUnion.outer.inner)_content : null; set { _which = WHICH.Inner; @@ -3542,7 +3543,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(64U, (ushort)0); - public @inner.READER Inner => which == WHICH.Inner ? new @inner.READER(ctx) : default; + public inner.READER Inner => which == WHICH.Inner ? new inner.READER(ctx) : default; public int Baz => which == WHICH.Baz ? ctx.ReadDataInt(0UL, 0) : default; } @@ -3558,9 +3559,9 @@ namespace Capnproto_test.Capnp.Test set => this.WriteData(64U, (ushort)value, (ushort)0); } - public @inner.WRITER Inner + public inner.WRITER Inner { - get => which == WHICH.Inner ? Rewrap<@inner.WRITER>() : default; + get => which == WHICH.Inner ? Rewrap() : default; } public int Baz @@ -3570,8 +3571,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xff9ce111c6f8e5dbUL)] - public class @inner : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xff9ce111c6f8e5dbUL)] + public class inner : ICapnpSerializable { public const UInt64 typeId = 0xff9ce111c6f8e5dbUL; public enum WHICH : ushort @@ -3706,14 +3707,14 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdc841556134c3103UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdc841556134c3103UL)] public class TestGroups : ICapnpSerializable { public const UInt64 typeId = 0xdc841556134c3103UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - Groups = CapnpSerializable.Create(reader.Groups); + Groups = CapnpSerializable.Create(reader.Groups); applyDefaults(); } @@ -3731,7 +3732,7 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestGroups.@groups Groups + public Capnproto_test.Capnp.Test.TestGroups.groups Groups { get; set; @@ -3748,7 +3749,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public @groups.READER Groups => new @groups.READER(ctx); + public groups.READER Groups => new groups.READER(ctx); } public class WRITER : SerializerState @@ -3758,14 +3759,14 @@ namespace Capnproto_test.Capnp.Test this.SetStruct(2, 2); } - public @groups.WRITER Groups + public groups.WRITER Groups { - get => Rewrap<@groups.WRITER>(); + get => Rewrap(); } } - [TypeId(0xe22ae74ff9113268UL)] - public class @groups : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe22ae74ff9113268UL)] + public class groups : ICapnpSerializable { public const UInt64 typeId = 0xe22ae74ff9113268UL; public enum WHICH : ushort @@ -3782,13 +3783,13 @@ namespace Capnproto_test.Capnp.Test switch (reader.which) { case WHICH.Foo: - Foo = CapnpSerializable.Create(reader.Foo); + Foo = CapnpSerializable.Create(reader.Foo); break; case WHICH.Baz: - Baz = CapnpSerializable.Create(reader.Baz); + Baz = CapnpSerializable.Create(reader.Baz); break; case WHICH.Bar: - Bar = CapnpSerializable.Create(reader.Bar); + Bar = CapnpSerializable.Create(reader.Bar); break; } @@ -3846,9 +3847,9 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestGroups.@groups.@foo Foo + public Capnproto_test.Capnp.Test.TestGroups.groups.foo Foo { - get => _which == WHICH.Foo ? (Capnproto_test.Capnp.Test.TestGroups.@groups.@foo)_content : null; + get => _which == WHICH.Foo ? (Capnproto_test.Capnp.Test.TestGroups.groups.foo)_content : null; set { _which = WHICH.Foo; @@ -3856,9 +3857,9 @@ namespace Capnproto_test.Capnp.Test } } - public Capnproto_test.Capnp.Test.TestGroups.@groups.@baz Baz + public Capnproto_test.Capnp.Test.TestGroups.groups.baz Baz { - get => _which == WHICH.Baz ? (Capnproto_test.Capnp.Test.TestGroups.@groups.@baz)_content : null; + get => _which == WHICH.Baz ? (Capnproto_test.Capnp.Test.TestGroups.groups.baz)_content : null; set { _which = WHICH.Baz; @@ -3866,9 +3867,9 @@ namespace Capnproto_test.Capnp.Test } } - public Capnproto_test.Capnp.Test.TestGroups.@groups.@bar Bar + public Capnproto_test.Capnp.Test.TestGroups.groups.bar Bar { - get => _which == WHICH.Bar ? (Capnproto_test.Capnp.Test.TestGroups.@groups.@bar)_content : null; + get => _which == WHICH.Bar ? (Capnproto_test.Capnp.Test.TestGroups.groups.bar)_content : null; set { _which = WHICH.Bar; @@ -3888,9 +3889,9 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(32U, (ushort)0); - public @foo.READER Foo => which == WHICH.Foo ? new @foo.READER(ctx) : default; - public @baz.READER Baz => which == WHICH.Baz ? new @baz.READER(ctx) : default; - public @bar.READER Bar => which == WHICH.Bar ? new @bar.READER(ctx) : default; + public foo.READER Foo => which == WHICH.Foo ? new foo.READER(ctx) : default; + public baz.READER Baz => which == WHICH.Baz ? new baz.READER(ctx) : default; + public bar.READER Bar => which == WHICH.Bar ? new bar.READER(ctx) : default; } public class WRITER : SerializerState @@ -3905,24 +3906,24 @@ namespace Capnproto_test.Capnp.Test set => this.WriteData(32U, (ushort)value, (ushort)0); } - public @foo.WRITER Foo + public foo.WRITER Foo { - get => which == WHICH.Foo ? Rewrap<@foo.WRITER>() : default; + get => which == WHICH.Foo ? Rewrap() : default; } - public @baz.WRITER Baz + public baz.WRITER Baz { - get => which == WHICH.Baz ? Rewrap<@baz.WRITER>() : default; + get => which == WHICH.Baz ? Rewrap() : default; } - public @bar.WRITER Bar + public bar.WRITER Bar { - get => which == WHICH.Bar ? Rewrap<@bar.WRITER>() : default; + get => which == WHICH.Bar ? Rewrap() : default; } } - [TypeId(0xf5fcba89c0c1196fUL)] - public class @foo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf5fcba89c0c1196fUL)] + public class foo : ICapnpSerializable { public const UInt64 typeId = 0xf5fcba89c0c1196fUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -3981,7 +3982,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); public long Grault => ctx.ReadDataLong(64UL, 0L); - public string Garply => ctx.ReadText(0, ""); + public string Garply => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -4004,14 +4005,14 @@ namespace Capnproto_test.Capnp.Test public string Garply { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xf0fa30304066a4b3UL)] - public class @baz : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf0fa30304066a4b3UL)] + public class baz : ICapnpSerializable { public const UInt64 typeId = 0xf0fa30304066a4b3UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -4069,8 +4070,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); - public string Grault => ctx.ReadText(0, ""); - public string Garply => ctx.ReadText(1, ""); + public string Grault => ctx.ReadText(0, null); + public string Garply => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -4087,20 +4088,20 @@ namespace Capnproto_test.Capnp.Test public string Grault { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Garply { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } - [TypeId(0xb727c0d0091a001dUL)] - public class @bar : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb727c0d0091a001dUL)] + public class bar : ICapnpSerializable { public const UInt64 typeId = 0xb727c0d0091a001dUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -4158,7 +4159,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); - public string Grault => ctx.ReadText(0, ""); + public string Grault => ctx.ReadText(0, null); public long Garply => ctx.ReadDataLong(64UL, 0L); } @@ -4176,8 +4177,8 @@ namespace Capnproto_test.Capnp.Test public string Grault { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public long Garply @@ -4190,15 +4191,15 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf77ed6f7454eec40UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf77ed6f7454eec40UL)] public class TestInterleavedGroups : ICapnpSerializable { public const UInt64 typeId = 0xf77ed6f7454eec40UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - Group1 = CapnpSerializable.Create(reader.Group1); - Group2 = CapnpSerializable.Create(reader.Group2); + Group1 = CapnpSerializable.Create(reader.Group1); + Group2 = CapnpSerializable.Create(reader.Group2); applyDefaults(); } @@ -4217,13 +4218,13 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestInterleavedGroups.@group1 Group1 + public Capnproto_test.Capnp.Test.TestInterleavedGroups.group1 Group1 { get; set; } - public Capnproto_test.Capnp.Test.TestInterleavedGroups.@group2 Group2 + public Capnproto_test.Capnp.Test.TestInterleavedGroups.group2 Group2 { get; set; @@ -4240,8 +4241,8 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public @group1.READER Group1 => new @group1.READER(ctx); - public @group2.READER Group2 => new @group2.READER(ctx); + public group1.READER Group1 => new group1.READER(ctx); + public group2.READER Group2 => new group2.READER(ctx); } public class WRITER : SerializerState @@ -4251,19 +4252,19 @@ namespace Capnproto_test.Capnp.Test this.SetStruct(6, 6); } - public @group1.WRITER Group1 + public group1.WRITER Group1 { - get => Rewrap<@group1.WRITER>(); + get => Rewrap(); } - public @group2.WRITER Group2 + public group2.WRITER Group2 { - get => Rewrap<@group2.WRITER>(); + get => Rewrap(); } } - [TypeId(0xc7485a3516c7d3c8UL)] - public class @group1 : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc7485a3516c7d3c8UL)] + public class group1 : ICapnpSerializable { public const UInt64 typeId = 0xc7485a3516c7d3c8UL; public enum WHICH : ushort @@ -4283,7 +4284,7 @@ namespace Capnproto_test.Capnp.Test Qux = reader.Qux; break; case WHICH.Corge: - Corge = CapnpSerializable.Create(reader.Corge); + Corge = CapnpSerializable.Create(reader.Corge); break; case WHICH.Fred: Fred = reader.Fred; @@ -4373,9 +4374,9 @@ namespace Capnproto_test.Capnp.Test } } - public Capnproto_test.Capnp.Test.TestInterleavedGroups.@group1.@corge Corge + public Capnproto_test.Capnp.Test.TestInterleavedGroups.group1.corge Corge { - get => _which == WHICH.Corge ? (Capnproto_test.Capnp.Test.TestInterleavedGroups.@group1.@corge)_content : null; + get => _which == WHICH.Corge ? (Capnproto_test.Capnp.Test.TestInterleavedGroups.group1.corge)_content : null; set { _which = WHICH.Corge; @@ -4414,9 +4415,9 @@ namespace Capnproto_test.Capnp.Test public uint Foo => ctx.ReadDataUInt(0UL, 0U); public ulong Bar => ctx.ReadDataULong(64UL, 0UL); public ushort Qux => which == WHICH.Qux ? ctx.ReadDataUShort(192UL, (ushort)0) : default; - public @corge.READER Corge => which == WHICH.Corge ? new @corge.READER(ctx) : default; - public string Waldo => ctx.ReadText(0, ""); - public string Fred => which == WHICH.Fred ? ctx.ReadText(2, "") : default; + public corge.READER Corge => which == WHICH.Corge ? new corge.READER(ctx) : default; + public string Waldo => ctx.ReadText(0, null); + public string Fred => which == WHICH.Fred ? ctx.ReadText(2, null) : default; } public class WRITER : SerializerState @@ -4449,26 +4450,26 @@ namespace Capnproto_test.Capnp.Test set => this.WriteData(192UL, value, (ushort)0); } - public @corge.WRITER Corge + public corge.WRITER Corge { - get => which == WHICH.Corge ? Rewrap<@corge.WRITER>() : default; + get => which == WHICH.Corge ? Rewrap() : default; } public string Waldo { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Fred { - get => which == WHICH.Fred ? this.ReadText(2, "") : default; - set => this.WriteText(2, value, ""); + get => which == WHICH.Fred ? this.ReadText(2, null) : default; + set => this.WriteText(2, value, null); } } - [TypeId(0xdb0afd413f4a313aUL)] - public class @corge : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdb0afd413f4a313aUL)] + public class corge : ICapnpSerializable { public const UInt64 typeId = 0xdb0afd413f4a313aUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -4535,8 +4536,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong Grault => ctx.ReadDataULong(256UL, 0UL); public ushort Garply => ctx.ReadDataUShort(192UL, (ushort)0); - public string Plugh => ctx.ReadText(2, ""); - public string Xyzzy => ctx.ReadText(4, ""); + public string Plugh => ctx.ReadText(2, null); + public string Xyzzy => ctx.ReadText(4, null); } public class WRITER : SerializerState @@ -4559,21 +4560,21 @@ namespace Capnproto_test.Capnp.Test public string Plugh { - get => this.ReadText(2, ""); - set => this.WriteText(2, value, ""); + get => this.ReadText(2, null); + set => this.WriteText(2, value, null); } public string Xyzzy { - get => this.ReadText(4, ""); - set => this.WriteText(4, value, ""); + get => this.ReadText(4, null); + set => this.WriteText(4, value, null); } } } } - [TypeId(0xcc85a335569990e9UL)] - public class @group2 : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xcc85a335569990e9UL)] + public class group2 : ICapnpSerializable { public const UInt64 typeId = 0xcc85a335569990e9UL; public enum WHICH : ushort @@ -4593,7 +4594,7 @@ namespace Capnproto_test.Capnp.Test Qux = reader.Qux; break; case WHICH.Corge: - Corge = CapnpSerializable.Create(reader.Corge); + Corge = CapnpSerializable.Create(reader.Corge); break; case WHICH.Fred: Fred = reader.Fred; @@ -4683,9 +4684,9 @@ namespace Capnproto_test.Capnp.Test } } - public Capnproto_test.Capnp.Test.TestInterleavedGroups.@group2.@corge Corge + public Capnproto_test.Capnp.Test.TestInterleavedGroups.group2.corge Corge { - get => _which == WHICH.Corge ? (Capnproto_test.Capnp.Test.TestInterleavedGroups.@group2.@corge)_content : null; + get => _which == WHICH.Corge ? (Capnproto_test.Capnp.Test.TestInterleavedGroups.group2.corge)_content : null; set { _which = WHICH.Corge; @@ -4724,9 +4725,9 @@ namespace Capnproto_test.Capnp.Test public uint Foo => ctx.ReadDataUInt(32UL, 0U); public ulong Bar => ctx.ReadDataULong(128UL, 0UL); public ushort Qux => which == WHICH.Qux ? ctx.ReadDataUShort(208UL, (ushort)0) : default; - public @corge.READER Corge => which == WHICH.Corge ? new @corge.READER(ctx) : default; - public string Waldo => ctx.ReadText(1, ""); - public string Fred => which == WHICH.Fred ? ctx.ReadText(3, "") : default; + public corge.READER Corge => which == WHICH.Corge ? new corge.READER(ctx) : default; + public string Waldo => ctx.ReadText(1, null); + public string Fred => which == WHICH.Fred ? ctx.ReadText(3, null) : default; } public class WRITER : SerializerState @@ -4759,26 +4760,26 @@ namespace Capnproto_test.Capnp.Test set => this.WriteData(208UL, value, (ushort)0); } - public @corge.WRITER Corge + public corge.WRITER Corge { - get => which == WHICH.Corge ? Rewrap<@corge.WRITER>() : default; + get => which == WHICH.Corge ? Rewrap() : default; } public string Waldo { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } public string Fred { - get => which == WHICH.Fred ? this.ReadText(3, "") : default; - set => this.WriteText(3, value, ""); + get => which == WHICH.Fred ? this.ReadText(3, null) : default; + set => this.WriteText(3, value, null); } } - [TypeId(0xa017f0366827ee37UL)] - public class @corge : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa017f0366827ee37UL)] + public class corge : ICapnpSerializable { public const UInt64 typeId = 0xa017f0366827ee37UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -4845,8 +4846,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong Grault => ctx.ReadDataULong(320UL, 0UL); public ushort Garply => ctx.ReadDataUShort(208UL, (ushort)0); - public string Plugh => ctx.ReadText(3, ""); - public string Xyzzy => ctx.ReadText(5, ""); + public string Plugh => ctx.ReadText(3, null); + public string Xyzzy => ctx.ReadText(5, null); } public class WRITER : SerializerState @@ -4869,21 +4870,21 @@ namespace Capnproto_test.Capnp.Test public string Plugh { - get => this.ReadText(3, ""); - set => this.WriteText(3, value, ""); + get => this.ReadText(3, null); + set => this.WriteText(3, value, null); } public string Xyzzy { - get => this.ReadText(5, ""); - set => this.WriteText(5, value, ""); + get => this.ReadText(5, null); + set => this.WriteText(5, value, null); } } } } } - [TypeId(0x94f7e0b103b4b718UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x94f7e0b103b4b718UL)] public class TestUnionDefaults : ICapnpSerializable { public const UInt64 typeId = 0x94f7e0b103b4b718UL; @@ -4914,13 +4915,13 @@ namespace Capnproto_test.Capnp.Test { S16s8s64s8Set = S16s8s64s8Set ?? new Capnproto_test.Capnp.Test.TestUnion() { - Union0 = new Capnproto_test.Capnp.Test.TestUnion.@union0() + Union0 = new Capnproto_test.Capnp.Test.TestUnion.union0() { }, - Union1 = new Capnproto_test.Capnp.Test.TestUnion.@union1() + Union1 = new Capnproto_test.Capnp.Test.TestUnion.union1() { }, - Union2 = new Capnproto_test.Capnp.Test.TestUnion.@union2() + Union2 = new Capnproto_test.Capnp.Test.TestUnion.union2() { }, - Union3 = new Capnproto_test.Capnp.Test.TestUnion.@union3() + Union3 = new Capnproto_test.Capnp.Test.TestUnion.union3() { }, Bit0 = false, Bit2 = false, @@ -4933,13 +4934,13 @@ namespace Capnproto_test.Capnp.Test }; S0sps1s32Set = S0sps1s32Set ?? new Capnproto_test.Capnp.Test.TestUnion() { - Union0 = new Capnproto_test.Capnp.Test.TestUnion.@union0() + Union0 = new Capnproto_test.Capnp.Test.TestUnion.union0() { }, - Union1 = new Capnproto_test.Capnp.Test.TestUnion.@union1() + Union1 = new Capnproto_test.Capnp.Test.TestUnion.union1() { }, - Union2 = new Capnproto_test.Capnp.Test.TestUnion.@union2() + Union2 = new Capnproto_test.Capnp.Test.TestUnion.union2() { }, - Union3 = new Capnproto_test.Capnp.Test.TestUnion.@union3() + Union3 = new Capnproto_test.Capnp.Test.TestUnion.union3() { }, Bit0 = false, Bit2 = false, @@ -5030,7 +5031,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd9f2b5941a343bcdUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd9f2b5941a343bcdUL)] public class TestNestedTypes : ICapnpSerializable { public const UInt64 typeId = 0xd9f2b5941a343bcdUL; @@ -5121,14 +5122,14 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb651d2fba42056d4UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb651d2fba42056d4UL)] public enum NestedEnum : ushort { foo, bar } - [TypeId(0x82cd03a53b29d76bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x82cd03a53b29d76bUL)] public class NestedStruct : ICapnpSerializable { public const UInt64 typeId = 0x82cd03a53b29d76bUL; @@ -5204,7 +5205,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xcfa0d546993a3df3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xcfa0d546993a3df3UL)] public enum NestedEnum : ushort { baz, @@ -5214,7 +5215,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe78aac389e77b065UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe78aac389e77b065UL)] public class TestUsing : ICapnpSerializable { public const UInt64 typeId = 0xe78aac389e77b065UL; @@ -5291,23 +5292,23 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe41885c94393277eUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe41885c94393277eUL)] public class TestLists : ICapnpSerializable { public const UInt64 typeId = 0xe41885c94393277eUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - List0 = reader.List0.ToReadOnlyList(_ => CapnpSerializable.Create(_)); - List1 = reader.List1.ToReadOnlyList(_ => CapnpSerializable.Create(_)); - List8 = reader.List8.ToReadOnlyList(_ => CapnpSerializable.Create(_)); - List16 = reader.List16.ToReadOnlyList(_ => CapnpSerializable.Create(_)); - List32 = reader.List32.ToReadOnlyList(_ => CapnpSerializable.Create(_)); - List64 = reader.List64.ToReadOnlyList(_ => CapnpSerializable.Create(_)); - ListP = reader.ListP.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + List0 = reader.List0?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + List1 = reader.List1?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + List8 = reader.List8?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + List16 = reader.List16?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + List32 = reader.List32?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + List64 = reader.List64?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + ListP = reader.ListP?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); Int32ListList = reader.Int32ListList; TextListList = reader.TextListList; - StructListList = reader.StructListList.ToReadOnlyList(_2 => _2.ToReadOnlyList(_ => CapnpSerializable.Create(_))); + StructListList = reader.StructListList?.ToReadOnlyList(_2 => _2?.ToReadOnlyList(_ => CapnpSerializable.Create(_))); applyDefaults(); } @@ -5485,7 +5486,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8412c03b75b2cfeeUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8412c03b75b2cfeeUL)] public class Struct0 : ICapnpSerializable { public const UInt64 typeId = 0x8412c03b75b2cfeeUL; @@ -5530,7 +5531,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe0fe5870b141ad69UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe0fe5870b141ad69UL)] public class Struct1 : ICapnpSerializable { public const UInt64 typeId = 0xe0fe5870b141ad69UL; @@ -5590,7 +5591,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa6411a353090145bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa6411a353090145bUL)] public class Struct8 : ICapnpSerializable { public const UInt64 typeId = 0xa6411a353090145bUL; @@ -5650,7 +5651,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa8abf7a82928986cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa8abf7a82928986cUL)] public class Struct16 : ICapnpSerializable { public const UInt64 typeId = 0xa8abf7a82928986cUL; @@ -5710,7 +5711,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xad7beedc4ed30742UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xad7beedc4ed30742UL)] public class Struct32 : ICapnpSerializable { public const UInt64 typeId = 0xad7beedc4ed30742UL; @@ -5770,7 +5771,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xef9a34f2ff7cc646UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xef9a34f2ff7cc646UL)] public class Struct64 : ICapnpSerializable { public const UInt64 typeId = 0xef9a34f2ff7cc646UL; @@ -5830,7 +5831,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc6abf1b0329e6227UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc6abf1b0329e6227UL)] public class StructP : ICapnpSerializable { public const UInt64 typeId = 0xc6abf1b0329e6227UL; @@ -5872,7 +5873,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string F => ctx.ReadText(0, ""); + public string F => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5884,13 +5885,13 @@ namespace Capnproto_test.Capnp.Test public string F { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0x943a234ca336b16aUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x943a234ca336b16aUL)] public class Struct0c : ICapnpSerializable { public const UInt64 typeId = 0x943a234ca336b16aUL; @@ -5932,7 +5933,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5944,13 +5945,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0x8991bc0e74a594cdUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8991bc0e74a594cdUL)] public class Struct1c : ICapnpSerializable { public const UInt64 typeId = 0x8991bc0e74a594cdUL; @@ -6001,7 +6002,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public bool F => ctx.ReadDataBool(0UL, false); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6019,13 +6020,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xed267416528c7a24UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xed267416528c7a24UL)] public class Struct8c : ICapnpSerializable { public const UInt64 typeId = 0xed267416528c7a24UL; @@ -6076,7 +6077,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public byte F => ctx.ReadDataByte(0UL, (byte)0); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6094,13 +6095,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0x9978837b037d58e6UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9978837b037d58e6UL)] public class Struct16c : ICapnpSerializable { public const UInt64 typeId = 0x9978837b037d58e6UL; @@ -6151,7 +6152,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ushort F => ctx.ReadDataUShort(0UL, (ushort)0); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6169,13 +6170,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xed5fa940f54a7904UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xed5fa940f54a7904UL)] public class Struct32c : ICapnpSerializable { public const UInt64 typeId = 0xed5fa940f54a7904UL; @@ -6226,7 +6227,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public uint F => ctx.ReadDataUInt(0UL, 0U); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6244,13 +6245,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xbc743778f2597c7dUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbc743778f2597c7dUL)] public class Struct64c : ICapnpSerializable { public const UInt64 typeId = 0xbc743778f2597c7dUL; @@ -6301,7 +6302,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong F => ctx.ReadDataULong(0UL, 0UL); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6319,13 +6320,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xc2e364a40182013dUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc2e364a40182013dUL)] public class StructPc : ICapnpSerializable { public const UInt64 typeId = 0xc2e364a40182013dUL; @@ -6375,7 +6376,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string F => ctx.ReadText(0, ""); + public string F => ctx.ReadText(0, null); public ulong Pad => ctx.ReadDataULong(0UL, 0UL); } @@ -6388,8 +6389,8 @@ namespace Capnproto_test.Capnp.Test public string F { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ulong Pad @@ -6401,7 +6402,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x92fc29a80f3ddd5cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x92fc29a80f3ddd5cUL)] public class TestFieldZeroIsBit : ICapnpSerializable { public const UInt64 typeId = 0x92fc29a80f3ddd5cUL; @@ -6493,7 +6494,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa851ad32cbc2ffeaUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa851ad32cbc2ffeaUL)] public class TestListDefaults : ICapnpSerializable { public const UInt64 typeId = 0xa851ad32cbc2ffeaUL; @@ -6588,7 +6589,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa76e3c9bb7fd56d3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa76e3c9bb7fd56d3UL)] public class TestLateUnion : ICapnpSerializable { public const UInt64 typeId = 0xa76e3c9bb7fd56d3UL; @@ -6598,8 +6599,8 @@ namespace Capnproto_test.Capnp.Test Foo = reader.Foo; Bar = reader.Bar; Baz = reader.Baz; - TheUnion = CapnpSerializable.Create(reader.TheUnion); - AnotherUnion = CapnpSerializable.Create(reader.AnotherUnion); + TheUnion = CapnpSerializable.Create(reader.TheUnion); + AnotherUnion = CapnpSerializable.Create(reader.AnotherUnion); applyDefaults(); } @@ -6639,13 +6640,13 @@ namespace Capnproto_test.Capnp.Test set; } - public Capnproto_test.Capnp.Test.TestLateUnion.@theUnion TheUnion + public Capnproto_test.Capnp.Test.TestLateUnion.theUnion TheUnion { get; set; } - public Capnproto_test.Capnp.Test.TestLateUnion.@anotherUnion AnotherUnion + public Capnproto_test.Capnp.Test.TestLateUnion.anotherUnion AnotherUnion { get; set; @@ -6663,10 +6664,10 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Foo => ctx.ReadDataInt(0UL, 0); - public string Bar => ctx.ReadText(0, ""); + public string Bar => ctx.ReadText(0, null); public short Baz => ctx.ReadDataShort(32UL, (short)0); - public @theUnion.READER TheUnion => new @theUnion.READER(ctx); - public @anotherUnion.READER AnotherUnion => new @anotherUnion.READER(ctx); + public theUnion.READER TheUnion => new theUnion.READER(ctx); + public anotherUnion.READER AnotherUnion => new anotherUnion.READER(ctx); } public class WRITER : SerializerState @@ -6684,8 +6685,8 @@ namespace Capnproto_test.Capnp.Test public string Bar { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public short Baz @@ -6694,19 +6695,19 @@ namespace Capnproto_test.Capnp.Test set => this.WriteData(32UL, value, (short)0); } - public @theUnion.WRITER TheUnion + public theUnion.WRITER TheUnion { - get => Rewrap<@theUnion.WRITER>(); + get => Rewrap(); } - public @anotherUnion.WRITER AnotherUnion + public anotherUnion.WRITER AnotherUnion { - get => Rewrap<@anotherUnion.WRITER>(); + get => Rewrap(); } } - [TypeId(0x807280a2901aa079UL)] - public class @theUnion : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x807280a2901aa079UL)] + public class theUnion : ICapnpSerializable { public const UInt64 typeId = 0x807280a2901aa079UL; public enum WHICH : ushort @@ -6829,7 +6830,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(48U, (ushort)0); - public string Qux => which == WHICH.Qux ? ctx.ReadText(1, "") : default; + public string Qux => which == WHICH.Qux ? ctx.ReadText(1, null) : default; public IReadOnlyList Corge => which == WHICH.Corge ? ctx.ReadList(1).CastInt() : default; public float Grault => which == WHICH.Grault ? ctx.ReadDataFloat(64UL, 0F) : default; } @@ -6848,8 +6849,8 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => which == WHICH.Qux ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.Qux ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public ListOfPrimitivesSerializer Corge @@ -6866,8 +6867,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc1973984dee98e3aUL)] - public class @anotherUnion : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc1973984dee98e3aUL)] + public class anotherUnion : ICapnpSerializable { public const UInt64 typeId = 0xc1973984dee98e3aUL; public enum WHICH : ushort @@ -6990,7 +6991,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(96U, (ushort)0); - public string Qux => which == WHICH.Qux ? ctx.ReadText(2, "") : default; + public string Qux => which == WHICH.Qux ? ctx.ReadText(2, null) : default; public IReadOnlyList Corge => which == WHICH.Corge ? ctx.ReadList(2).CastInt() : default; public float Grault => which == WHICH.Grault ? ctx.ReadDataFloat(128UL, 0F) : default; } @@ -7009,8 +7010,8 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => which == WHICH.Qux ? this.ReadText(2, "") : default; - set => this.WriteText(2, value, ""); + get => which == WHICH.Qux ? this.ReadText(2, null) : default; + set => this.WriteText(2, value, null); } public ListOfPrimitivesSerializer Corge @@ -7028,7 +7029,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x95b30dd14e01dda8UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x95b30dd14e01dda8UL)] public class TestOldVersion : ICapnpSerializable { public const UInt64 typeId = 0x95b30dd14e01dda8UL; @@ -7087,7 +7088,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public long Old1 => ctx.ReadDataLong(0UL, 0L); - public string Old2 => ctx.ReadText(0, ""); + public string Old2 => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestOldVersion.READER Old3 => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestOldVersion.READER.create); } @@ -7106,8 +7107,8 @@ namespace Capnproto_test.Capnp.Test public string Old2 { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestOldVersion.WRITER Old3 @@ -7118,7 +7119,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8ed75a7469f04ce3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8ed75a7469f04ce3UL)] public class TestNewVersion : ICapnpSerializable { public const UInt64 typeId = 0x8ed75a7469f04ce3UL; @@ -7195,7 +7196,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public long Old1 => ctx.ReadDataLong(0UL, 0L); - public string Old2 => ctx.ReadText(0, ""); + public string Old2 => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestNewVersion.READER Old3 => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestNewVersion.READER.create); public long New1 => ctx.ReadDataLong(64UL, 987L); public string New2 => ctx.ReadText(2, "baz"); @@ -7216,8 +7217,8 @@ namespace Capnproto_test.Capnp.Test public string Old2 { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestNewVersion.WRITER Old3 @@ -7240,7 +7241,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xbd5fe16e5170c492UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbd5fe16e5170c492UL)] public class TestOldUnionVersion : ICapnpSerializable { public const UInt64 typeId = 0xbd5fe16e5170c492UL; @@ -7356,7 +7357,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc7e4c513a975492bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc7e4c513a975492bUL)] public class TestNewUnionVersion : ICapnpSerializable { public const UInt64 typeId = 0xc7e4c513a975492bUL; @@ -7373,7 +7374,7 @@ namespace Capnproto_test.Capnp.Test switch (reader.which) { case WHICH.A: - A = CapnpSerializable.Create(reader.A); + A = CapnpSerializable.Create(reader.A); break; case WHICH.B: B = reader.B; @@ -7428,9 +7429,9 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestNewUnionVersion.@a A + public Capnproto_test.Capnp.Test.TestNewUnionVersion.a A { - get => _which == WHICH.A ? (Capnproto_test.Capnp.Test.TestNewUnionVersion.@a)_content : null; + get => _which == WHICH.A ? (Capnproto_test.Capnp.Test.TestNewUnionVersion.a)_content : null; set { _which = WHICH.A; @@ -7460,7 +7461,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(0U, (ushort)0); - public @a.READER A => which == WHICH.A ? new @a.READER(ctx) : default; + public a.READER A => which == WHICH.A ? new a.READER(ctx) : default; public ulong B => which == WHICH.B ? ctx.ReadDataULong(64UL, 0UL) : default; } @@ -7477,9 +7478,9 @@ namespace Capnproto_test.Capnp.Test set => this.WriteData(0U, (ushort)value, (ushort)0); } - public @a.WRITER A + public a.WRITER A { - get => which == WHICH.A ? Rewrap<@a.WRITER>() : default; + get => which == WHICH.A ? Rewrap() : default; } public ulong B @@ -7489,8 +7490,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x86232c1de4513e84UL)] - public class @a : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x86232c1de4513e84UL)] + public class a : ICapnpSerializable { public const UInt64 typeId = 0x86232c1de4513e84UL; public enum WHICH : ushort @@ -7605,14 +7606,14 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xfaf781ef89a00e39UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfaf781ef89a00e39UL)] public class TestStructUnion : ICapnpSerializable { public const UInt64 typeId = 0xfaf781ef89a00e39UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - Un = CapnpSerializable.Create(reader.Un); + Un = CapnpSerializable.Create(reader.Un); applyDefaults(); } @@ -7630,7 +7631,7 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestStructUnion.@un Un + public Capnproto_test.Capnp.Test.TestStructUnion.un Un { get; set; @@ -7647,7 +7648,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public @un.READER Un => new @un.READER(ctx); + public un.READER Un => new un.READER(ctx); } public class WRITER : SerializerState @@ -7657,14 +7658,14 @@ namespace Capnproto_test.Capnp.Test this.SetStruct(1, 1); } - public @un.WRITER Un + public un.WRITER Un { - get => Rewrap<@un.WRITER>(); + get => Rewrap(); } } - [TypeId(0x992edc677bef5a3cUL)] - public class @un : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x992edc677bef5a3cUL)] + public class un : ICapnpSerializable { public const UInt64 typeId = 0x992edc677bef5a3cUL; public enum WHICH : ushort @@ -7797,7 +7798,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9daec9823f171085UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9daec9823f171085UL)] public class SomeStruct : ICapnpSerializable { public const UInt64 typeId = 0x9daec9823f171085UL; @@ -7847,8 +7848,8 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string SomeText => ctx.ReadText(0, ""); - public string MoreText => ctx.ReadText(1, ""); + public string SomeText => ctx.ReadText(0, null); + public string MoreText => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -7860,20 +7861,20 @@ namespace Capnproto_test.Capnp.Test public string SomeText { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string MoreText { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } } - [TypeId(0xdec497819d097c3cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdec497819d097c3cUL)] public class TestPrintInlineStructs : ICapnpSerializable { public const UInt64 typeId = 0xdec497819d097c3cUL; @@ -7881,7 +7882,7 @@ namespace Capnproto_test.Capnp.Test { var reader = READER.create(arg_); SomeText = reader.SomeText; - StructList = reader.StructList.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + StructList = reader.StructList?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); applyDefaults(); } @@ -7923,7 +7924,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string SomeText => ctx.ReadText(0, ""); + public string SomeText => ctx.ReadText(0, null); public IReadOnlyList StructList => ctx.ReadList(1).Cast(Capnproto_test.Capnp.Test.TestPrintInlineStructs.InlineStruct.READER.create); } @@ -7936,8 +7937,8 @@ namespace Capnproto_test.Capnp.Test public string SomeText { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ListOfStructsSerializer StructList @@ -7947,7 +7948,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8e4936003708dac2UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8e4936003708dac2UL)] public class InlineStruct : ICapnpSerializable { public const UInt64 typeId = 0x8e4936003708dac2UL; @@ -7998,7 +7999,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Int32Field => ctx.ReadDataInt(0UL, 0); - public string TextField => ctx.ReadText(0, ""); + public string TextField => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -8016,14 +8017,14 @@ namespace Capnproto_test.Capnp.Test public string TextField { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } } - [TypeId(0x91afd4a864dbb030UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x91afd4a864dbb030UL)] public class TestWholeFloatDefault : ICapnpSerializable { public const UInt64 typeId = 0x91afd4a864dbb030UL; @@ -8100,7 +8101,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9d5b8cd8de9922ebUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9d5b8cd8de9922ebUL)] public class TestGenerics : ICapnpSerializable where TFoo : class where TBar : class { public const UInt64 typeId = 0x9d5b8cd8de9922ebUL; @@ -8120,13 +8121,13 @@ namespace Capnproto_test.Capnp.Test which = reader.which; break; case WHICH.Ug: - Ug = CapnpSerializable.Create.@ug>(reader.Ug); + Ug = CapnpSerializable.Create.ug>(reader.Ug); break; } Foo = CapnpSerializable.Create(reader.Foo); Rev = CapnpSerializable.Create>(reader.Rev); - List = reader.List.ToReadOnlyList(_ => CapnpSerializable.Create.Inner>(_)); + List = reader.List?.ToReadOnlyList(_ => CapnpSerializable.Create.Inner>(_)); applyDefaults(); } @@ -8189,9 +8190,9 @@ namespace Capnproto_test.Capnp.Test set; } - public Capnproto_test.Capnp.Test.TestGenerics.@ug Ug + public Capnproto_test.Capnp.Test.TestGenerics.ug Ug { - get => _which == WHICH.Ug ? (Capnproto_test.Capnp.Test.TestGenerics.@ug)_content : null; + get => _which == WHICH.Ug ? (Capnproto_test.Capnp.Test.TestGenerics.ug)_content : null; set { _which = WHICH.Ug; @@ -8219,7 +8220,7 @@ namespace Capnproto_test.Capnp.Test public WHICH which => (WHICH)ctx.ReadDataUShort(0U, (ushort)0); public DeserializerState Foo => ctx.StructReadPointer(0); public Capnproto_test.Capnp.Test.TestGenerics.READER Rev => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestGenerics.READER.create); - public @ug.READER Ug => which == WHICH.Ug ? new @ug.READER(ctx) : default; + public ug.READER Ug => which == WHICH.Ug ? new ug.READER(ctx) : default; public IReadOnlyList.Inner.READER> List => ctx.ReadList(2).Cast(Capnproto_test.Capnp.Test.TestGenerics.Inner.READER.create); } @@ -8248,9 +8249,9 @@ namespace Capnproto_test.Capnp.Test set => Link(1, value); } - public @ug.WRITER Ug + public ug.WRITER Ug { - get => which == WHICH.Ug ? Rewrap<@ug.WRITER>() : default; + get => which == WHICH.Ug ? Rewrap() : default; } public ListOfStructsSerializer.Inner.WRITER> List @@ -8260,8 +8261,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb46a779beaf3384eUL)] - public class @ug : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb46a779beaf3384eUL)] + public class ug : ICapnpSerializable { public const UInt64 typeId = 0xb46a779beaf3384eUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -8319,7 +8320,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf6a841117e19ac73UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf6a841117e19ac73UL)] public class Inner : ICapnpSerializable { public const UInt64 typeId = 0xf6a841117e19ac73UL; @@ -8394,7 +8395,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa9ab42b118d6d435UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9ab42b118d6d435UL)] public class Inner2 : ICapnpSerializable where TBaz : class { public const UInt64 typeId = 0xa9ab42b118d6d435UL; @@ -8498,7 +8499,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb6a0829c762b06f3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb6a0829c762b06f3UL)] public class DeepNest : ICapnpSerializable where TQux : class { public const UInt64 typeId = 0xb6a0829c762b06f3UL; @@ -8602,26 +8603,30 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8839ed86c9794287UL), Proxy(typeof(DeepNestInterface_Proxy<>)), Skeleton(typeof(DeepNestInterface_Skeleton<>))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8839ed86c9794287UL), Proxy(typeof(DeepNestInterface_Proxy<>)), Skeleton(typeof(DeepNestInterface_Skeleton<>))] public interface IDeepNestInterface : IDisposable where TQuux : class { Task Call(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8839ed86c9794287UL)] public class DeepNestInterface_Proxy : Proxy, IDeepNestInterface where TQuux : class { public async Task Call(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc.Inner2.DeepNest.DeepNestInterface.Params_call.WRITER>(); - var arg_ = new Capnproto_test.Capnp.Test.TestGenerics.Inner2.DeepNest.DeepNestInterface.Params_call() + var in_ = SerializerState.CreateForRpc.Inner2.DeepNest.DeepNestInterface.Params_Call.WRITER>(); + var arg_ = new Capnproto_test.Capnp.Test.TestGenerics.Inner2.DeepNest.DeepNestInterface.Params_Call() { }; - arg_.serialize(in_); - var d_ = await Call(9816138025992274567UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create.Inner2.DeepNest.DeepNestInterface.Result_call>(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(9816138025992274567UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create.Inner2.DeepNest.DeepNestInterface.Result_Call>(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8839ed86c9794287UL)] public class DeepNestInterface_Skeleton : Skeleton> where TQuux : class { public DeepNestInterface_Skeleton() @@ -8632,17 +8637,20 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 9816138025992274567UL; async Task Call(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Call(cancellationToken_); - var s_ = SerializerState.CreateForRpc.Inner2.DeepNest.DeepNestInterface.Result_call.WRITER>(); - return s_; + using (d_) + { + await Impl.Call(cancellationToken_); + var s_ = SerializerState.CreateForRpc.Inner2.DeepNest.DeepNestInterface.Result_Call.WRITER>(); + return s_; + } } } public static class DeepNestInterface where TQuux : class { - [TypeId(0xb84eecc799437049UL)] - public class Params_call : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb84eecc799437049UL)] + public class Params_Call : ICapnpSerializable { public const UInt64 typeId = 0xb84eecc799437049UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -8686,8 +8694,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe080f0fc54614f6fUL)] - public class Result_call : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe080f0fc54614f6fUL)] + public class Result_Call : ICapnpSerializable { public const UInt64 typeId = 0xe080f0fc54614f6fUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -8734,28 +8742,33 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc9e749e8dd54da5cUL), Proxy(typeof(Interface_Proxy<>)), Skeleton(typeof(Interface_Skeleton<>))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc9e749e8dd54da5cUL), Proxy(typeof(Interface_Proxy<>)), Skeleton(typeof(Interface_Skeleton<>))] public interface IInterface : IDisposable where TQux : class { Task<(TQux, Capnproto_test.Capnp.Test.TestGenerics)> Call(Capnproto_test.Capnp.Test.TestGenerics.Inner2 arg_, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc9e749e8dd54da5cUL)] public class Interface_Proxy : Proxy, IInterface where TQux : class { public Task<(TQux, Capnproto_test.Capnp.Test.TestGenerics)> Call(Capnproto_test.Capnp.Test.TestGenerics.Inner2 arg_, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc.Inner2.WRITER>(); - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(14548678385738242652UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create.Interface.Result_call>(d_); - return (r_.Qux, r_.Gen); + using (d_) + { + var r_ = CapnpSerializable.Create.Interface.Result_Call>(d_); + return (r_.Qux, r_.Gen); + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc9e749e8dd54da5cUL)] public class Interface_Skeleton : Skeleton> where TQux : class { public Interface_Skeleton() @@ -8766,23 +8779,26 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 14548678385738242652UL; Task Call(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.Call(CapnpSerializable.Create.Inner2>(d_), cancellationToken_), (qux, gen) => + using (d_) { - var s_ = SerializerState.CreateForRpc.Interface.Result_call.WRITER>(); - var r_ = new Capnproto_test.Capnp.Test.TestGenerics.Interface.Result_call { Qux = qux, Gen = gen }; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.Call(CapnpSerializable.Create.Inner2>(d_), cancellationToken_), (qux, gen) => + { + var s_ = SerializerState.CreateForRpc.Interface.Result_Call.WRITER>(); + var r_ = new Capnproto_test.Capnp.Test.TestGenerics.Interface.Result_Call { Qux = qux, Gen = gen }; + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class Interface where TQux : class { - [TypeId(0xa5b46224e33581adUL)] - public class Result_call : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa5b46224e33581adUL)] + public class Result_Call : ICapnpSerializable { public const UInt64 typeId = 0xa5b46224e33581adUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -8857,7 +8873,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8e656edfb45ba6cfUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8e656edfb45ba6cfUL)] public class UseAliases : ICapnpSerializable { public const UInt64 typeId = 0x8e656edfb45ba6cfUL; @@ -8993,7 +9009,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa9b2b1f52dde845dUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9b2b1f52dde845dUL)] public class TestGenericsWrapper : ICapnpSerializable where TFoo : class where TBar : class { public const UInt64 typeId = 0xa9b2b1f52dde845dUL; @@ -9053,7 +9069,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf28f83667a557a04UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf28f83667a557a04UL)] public class TestGenericsWrapper2 : ICapnpSerializable { public const UInt64 typeId = 0xf28f83667a557a04UL; @@ -9113,32 +9129,37 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8b9717a3f8d85a9aUL), Proxy(typeof(TestImplicitMethodParams_Proxy)), Skeleton(typeof(TestImplicitMethodParams_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8b9717a3f8d85a9aUL), Proxy(typeof(TestImplicitMethodParams_Proxy)), Skeleton(typeof(TestImplicitMethodParams_Skeleton))] public interface ITestImplicitMethodParams : IDisposable { Task> Call(TT foo, TU bar, CancellationToken cancellationToken_ = default) where TT : class where TU : class; } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8b9717a3f8d85a9aUL)] public class TestImplicitMethodParams_Proxy : Proxy, ITestImplicitMethodParams { public Task> Call(TT foo, TU bar, CancellationToken cancellationToken_ = default) where TT : class where TU : class { - var in_ = SerializerState.CreateForRpc.WRITER>(); - var arg_ = new Capnproto_test.Capnp.Test.TestImplicitMethodParams.Params_call() + var in_ = SerializerState.CreateForRpc.WRITER>(); + var arg_ = new Capnproto_test.Capnp.Test.TestImplicitMethodParams.Params_Call() { Foo = foo, Bar = bar }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(10058534285777328794UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create>(d_); - return r_; + using (d_) + { + var r_ = CapnpSerializable.Create>(d_); + return r_; + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8b9717a3f8d85a9aUL)] public class TestImplicitMethodParams_Skeleton : Skeleton { public TestImplicitMethodParams_Skeleton() @@ -9150,22 +9171,25 @@ namespace Capnproto_test.Capnp.Test Task Call(DeserializerState d_, CancellationToken cancellationToken_) where TT : class where TU : class { - var in_ = CapnpSerializable.Create>(d_); - return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc.WRITER>(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create>(d_); + return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc.WRITER>(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestImplicitMethodParams { - [TypeId(0xf83f8caf54bdc486UL)] - public class Params_call : ICapnpSerializable where TT : class where TU : class + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf83f8caf54bdc486UL)] + public class Params_Call : ICapnpSerializable where TT : class where TU : class { public const UInt64 typeId = 0xf83f8caf54bdc486UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -9240,32 +9264,37 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdf9ccdeb81a704c9UL), Proxy(typeof(TestImplicitMethodParamsInGeneric_Proxy<>)), Skeleton(typeof(TestImplicitMethodParamsInGeneric_Skeleton<>))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdf9ccdeb81a704c9UL), Proxy(typeof(TestImplicitMethodParamsInGeneric_Proxy<>)), Skeleton(typeof(TestImplicitMethodParamsInGeneric_Skeleton<>))] public interface ITestImplicitMethodParamsInGeneric : IDisposable where TV : class { Task> Call(TT foo, TU bar, CancellationToken cancellationToken_ = default) where TT : class where TU : class; } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdf9ccdeb81a704c9UL)] public class TestImplicitMethodParamsInGeneric_Proxy : Proxy, ITestImplicitMethodParamsInGeneric where TV : class { public Task> Call(TT foo, TU bar, CancellationToken cancellationToken_ = default) where TT : class where TU : class { - var in_ = SerializerState.CreateForRpc.Params_call.WRITER>(); - var arg_ = new Capnproto_test.Capnp.Test.TestImplicitMethodParamsInGeneric.Params_call() + var in_ = SerializerState.CreateForRpc.Params_Call.WRITER>(); + var arg_ = new Capnproto_test.Capnp.Test.TestImplicitMethodParamsInGeneric.Params_Call() { Foo = foo, Bar = bar }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(16112979978201007305UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create>(d_); - return r_; + using (d_) + { + var r_ = CapnpSerializable.Create>(d_); + return r_; + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdf9ccdeb81a704c9UL)] public class TestImplicitMethodParamsInGeneric_Skeleton : Skeleton> where TV : class { public TestImplicitMethodParamsInGeneric_Skeleton() @@ -9277,23 +9306,26 @@ namespace Capnproto_test.Capnp.Test Task Call(DeserializerState d_, CancellationToken cancellationToken_) where TT : class where TU : class { - var in_ = CapnpSerializable.Create.Params_call>(d_); - return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc.WRITER>(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create.Params_Call>(d_); + return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc.WRITER>(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestImplicitMethodParamsInGeneric where TV : class { - [TypeId(0x9aab8e25c808d71eUL)] - public class Params_call : ICapnpSerializable where TT : class where TU : class + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9aab8e25c808d71eUL)] + public class Params_Call : ICapnpSerializable where TT : class where TU : class { public const UInt64 typeId = 0x9aab8e25c808d71eUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -9368,7 +9400,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa54870440e919063UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa54870440e919063UL)] public class TestGenericsUnion : ICapnpSerializable where TFoo : class where TBar : class { public const UInt64 typeId = 0xa54870440e919063UL; @@ -9503,7 +9535,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9427b2a71030338fUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9427b2a71030338fUL)] public class TestUseGenerics : ICapnpSerializable { public const UInt64 typeId = 0x9427b2a71030338fUL; @@ -10602,7 +10634,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc5598844441096dcUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc5598844441096dcUL)] public class TestEmptyStruct : ICapnpSerializable { public const UInt64 typeId = 0xc5598844441096dcUL; @@ -10647,7 +10679,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xabed745cd8c92095UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xabed745cd8c92095UL)] public class TestConstants : ICapnpSerializable { public const UInt64 typeId = 0xabed745cd8c92095UL; @@ -10692,7 +10724,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xddc280dbee9c99b3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddc280dbee9c99b3UL)] public class TestAnyPointerConstants : ICapnpSerializable { public const UInt64 typeId = 0xddc280dbee9c99b3UL; @@ -10702,7 +10734,7 @@ namespace Capnproto_test.Capnp.Test AnyKindAsStruct = CapnpSerializable.Create(reader.AnyKindAsStruct); AnyStructAsStruct = CapnpSerializable.Create(reader.AnyStructAsStruct); AnyKindAsList = CapnpSerializable.Create(reader.AnyKindAsList); - AnyListAsList = reader.AnyListAsList.ToReadOnlyList(_ => (object)_); + AnyListAsList = reader.AnyListAsList?.ToReadOnlyList(_ => (object)_); applyDefaults(); } @@ -10797,7 +10829,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x88eb12a0e0af92b2UL), Proxy(typeof(TestInterface_Proxy)), Skeleton(typeof(TestInterface_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x88eb12a0e0af92b2UL), Proxy(typeof(TestInterface_Proxy)), Skeleton(typeof(TestInterface_Skeleton))] public interface ITestInterface : IDisposable { Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default); @@ -10805,42 +10837,50 @@ namespace Capnproto_test.Capnp.Test Task Baz(Capnproto_test.Capnp.Test.TestAllTypes s, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x88eb12a0e0af92b2UL)] public class TestInterface_Proxy : Proxy, ITestInterface { public async Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_foo() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Foo() { I = i, J = j }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.X); + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.X); + } } public async Task Bar(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_bar() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Bar() { }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes s, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_baz() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Baz() { S = s }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x88eb12a0e0af92b2UL)] public class TestInterface_Skeleton : Skeleton { public TestInterface_Skeleton() @@ -10851,38 +10891,47 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 9865999890858873522UL; Task Foo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.J, cancellationToken_), x => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestInterface.Result_foo { X = x }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.J, cancellationToken_), x => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestInterface.Result_Foo { X = x }; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task Bar(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Bar(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Bar(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Baz(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.Baz(in_.S, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.Baz(in_.S, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestInterface { - [TypeId(0xb874edc0d559b391UL)] - public class Params_foo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb874edc0d559b391UL)] + public class Params_Foo : ICapnpSerializable { public const UInt64 typeId = 0xb874edc0d559b391UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -10956,8 +11005,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb04fcaddab714ba4UL)] - public class Result_foo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb04fcaddab714ba4UL)] + public class Result_Foo : ICapnpSerializable { public const UInt64 typeId = 0xb04fcaddab714ba4UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -10998,7 +11047,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string X => ctx.ReadText(0, ""); + public string X => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -11010,14 +11059,14 @@ namespace Capnproto_test.Capnp.Test public string X { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xd044893357b42568UL)] - public class Params_bar : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd044893357b42568UL)] + public class Params_Bar : ICapnpSerializable { public const UInt64 typeId = 0xd044893357b42568UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11061,8 +11110,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9bf141df4247d52fUL)] - public class Result_bar : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9bf141df4247d52fUL)] + public class Result_Bar : ICapnpSerializable { public const UInt64 typeId = 0x9bf141df4247d52fUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11106,8 +11155,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd9ac8abb2a91cfbcUL)] - public class Params_baz : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd9ac8abb2a91cfbcUL)] + public class Params_Baz : ICapnpSerializable { public const UInt64 typeId = 0xd9ac8abb2a91cfbcUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11166,8 +11215,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9b99d14f2f375b2dUL)] - public class Result_baz : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9b99d14f2f375b2dUL)] + public class Result_Baz : ICapnpSerializable { public const UInt64 typeId = 0x9b99d14f2f375b2dUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11212,7 +11261,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe4e9bac98670b748UL), Proxy(typeof(TestExtends_Proxy)), Skeleton(typeof(TestExtends_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe4e9bac98670b748UL), Proxy(typeof(TestExtends_Proxy)), Skeleton(typeof(TestExtends_Skeleton))] public interface ITestExtends : Capnproto_test.Capnp.Test.ITestInterface { Task Qux(CancellationToken cancellationToken_ = default); @@ -11220,73 +11269,87 @@ namespace Capnproto_test.Capnp.Test Task Grault(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe4e9bac98670b748UL)] public class TestExtends_Proxy : Proxy, ITestExtends { public async Task Qux(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_qux() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_Qux() { }; - arg_.serialize(in_); - var d_ = await Call(16494920484927878984UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(16494920484927878984UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Corge(Capnproto_test.Capnp.Test.TestAllTypes arg_, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); - arg_.serialize(in_); - var d_ = await Call(16494920484927878984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(16494920484927878984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Grault(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_grault() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_Grault() { }; - arg_.serialize(in_); - var d_ = await Call(16494920484927878984UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + arg_?.serialize(in_); + using (var d_ = await Call(16494920484927878984UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } public async Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_foo() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Foo() { I = i, J = j }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.X); + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.X); + } } public async Task Bar(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_bar() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Bar() { }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes s, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_baz() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Baz() { S = s }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe4e9bac98670b748UL)] public class TestExtends_Skeleton : Skeleton { public TestExtends_Skeleton() @@ -11297,35 +11360,44 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 16494920484927878984UL; async Task Qux(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Qux(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Qux(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Corge(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Corge(CapnpSerializable.Create(d_), cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Corge(CapnpSerializable.Create(d_), cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } Task Grault(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.Grault(cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.Grault(cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestExtends { - [TypeId(0x83a4bc5471363f17UL)] - public class Params_qux : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x83a4bc5471363f17UL)] + public class Params_Qux : ICapnpSerializable { public const UInt64 typeId = 0x83a4bc5471363f17UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11369,8 +11441,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8e4b3d1a3e2753ddUL)] - public class Result_qux : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8e4b3d1a3e2753ddUL)] + public class Result_Qux : ICapnpSerializable { public const UInt64 typeId = 0x8e4b3d1a3e2753ddUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11414,8 +11486,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xacf67532a7e7bad9UL)] - public class Result_corge : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xacf67532a7e7bad9UL)] + public class Result_Corge : ICapnpSerializable { public const UInt64 typeId = 0xacf67532a7e7bad9UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11459,8 +11531,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf3b834e851ea8af6UL)] - public class Params_grault : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf3b834e851ea8af6UL)] + public class Params_Grault : ICapnpSerializable { public const UInt64 typeId = 0xf3b834e851ea8af6UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11505,78 +11577,92 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x98d7e0ef61488783UL), Proxy(typeof(TestExtends2_Proxy)), Skeleton(typeof(TestExtends2_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x98d7e0ef61488783UL), Proxy(typeof(TestExtends2_Proxy)), Skeleton(typeof(TestExtends2_Skeleton))] public interface ITestExtends2 : Capnproto_test.Capnp.Test.ITestExtends { } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x98d7e0ef61488783UL)] public class TestExtends2_Proxy : Proxy, ITestExtends2 { public async Task Qux(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_qux() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_Qux() { }; - arg_.serialize(in_); - var d_ = await Call(16494920484927878984UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(16494920484927878984UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Corge(Capnproto_test.Capnp.Test.TestAllTypes arg_, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); - arg_.serialize(in_); - var d_ = await Call(16494920484927878984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(16494920484927878984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Grault(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_grault() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_Grault() { }; - arg_.serialize(in_); - var d_ = await Call(16494920484927878984UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + arg_?.serialize(in_); + using (var d_ = await Call(16494920484927878984UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } public async Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_foo() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Foo() { I = i, J = j }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.X); + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.X); + } } public async Task Bar(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_bar() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Bar() { }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes s, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_baz() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Baz() { S = s }; - arg_.serialize(in_); - var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x98d7e0ef61488783UL)] public class TestExtends2_Skeleton : Skeleton { public TestExtends2_Skeleton() @@ -11587,7 +11673,7 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11013518732491786115UL; } - [TypeId(0xa5a404caa61d4cd0UL), Proxy(typeof(TestPipeline_Proxy)), Skeleton(typeof(TestPipeline_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa5a404caa61d4cd0UL), Proxy(typeof(TestPipeline_Proxy)), Skeleton(typeof(TestPipeline_Skeleton))] public interface ITestPipeline : IDisposable { Task<(string, Capnproto_test.Capnp.Test.TestPipeline.Box)> GetCap(uint n, Capnproto_test.Capnp.Test.ITestInterface inCap, CancellationToken cancellationToken_ = default); @@ -11595,18 +11681,22 @@ namespace Capnproto_test.Capnp.Test Task<(string, Capnproto_test.Capnp.Test.TestPipeline.AnyBox)> GetAnyCap(uint n, BareProxy inCap, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa5a404caa61d4cd0UL)] public class TestPipeline_Proxy : Proxy, ITestPipeline { public Task<(string, Capnproto_test.Capnp.Test.TestPipeline.Box)> GetCap(uint n, Capnproto_test.Capnp.Test.ITestInterface inCap, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_getCap() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_GetCap() { N = n, InCap = inCap }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(11935670180855499984UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.S, r_.OutBox); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S, r_.OutBox); + } } ); @@ -11614,31 +11704,37 @@ namespace Capnproto_test.Capnp.Test public async Task TestPointers(Capnproto_test.Capnp.Test.ITestInterface cap, object obj, IReadOnlyList list, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_testPointers() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_TestPointers() { Cap = cap, Obj = obj, List = list }; - arg_.serialize(in_); - var d_ = await Call(11935670180855499984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(11935670180855499984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public Task<(string, Capnproto_test.Capnp.Test.TestPipeline.AnyBox)> GetAnyCap(uint n, BareProxy inCap, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_getAnyCap() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_GetAnyCap() { N = n, InCap = inCap }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(11935670180855499984UL, 2, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.S, r_.OutBox); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S, r_.OutBox); + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa5a404caa61d4cd0UL)] public class TestPipeline_Skeleton : Skeleton { public TestPipeline_Skeleton() @@ -11649,44 +11745,53 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11935670180855499984UL; Task GetCap(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.GetCap(in_.N, in_.InCap, cancellationToken_), (s, outBox) => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestPipeline.Result_getCap { S = s, OutBox = outBox }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.GetCap(in_.N, in_.InCap, cancellationToken_), (s, outBox) => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestPipeline.Result_GetCap { S = s, OutBox = outBox }; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task TestPointers(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.TestPointers(in_.Cap, in_.Obj, in_.List, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.TestPointers(in_.Cap, in_.Obj, in_.List, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } Task GetAnyCap(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.GetAnyCap(in_.N, in_.InCap, cancellationToken_), (s, outBox) => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestPipeline.Result_getAnyCap { S = s, OutBox = outBox }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.GetAnyCap(in_.N, in_.InCap, cancellationToken_), (s, outBox) => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestPipeline.Result_GetAnyCap { S = s, OutBox = outBox }; + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestPipeline { - [TypeId(0xb0b29e51db0e26b1UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb0b29e51db0e26b1UL)] public class Box : ICapnpSerializable { public const UInt64 typeId = 0xb0b29e51db0e26b1UL; @@ -11746,7 +11851,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9442ad5a1d2c8acbUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9442ad5a1d2c8acbUL)] public class AnyBox : ICapnpSerializable { public const UInt64 typeId = 0x9442ad5a1d2c8acbUL; @@ -11806,8 +11911,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc7e8df5096257034UL)] - public class Params_getCap : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc7e8df5096257034UL)] + public class Params_GetCap : ICapnpSerializable { public const UInt64 typeId = 0xc7e8df5096257034UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11881,8 +11986,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb2442a9e0ba28fdfUL)] - public class Result_getCap : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb2442a9e0ba28fdfUL)] + public class Result_GetCap : ICapnpSerializable { public const UInt64 typeId = 0xb2442a9e0ba28fdfUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -11931,7 +12036,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestPipeline.Box.READER OutBox => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestPipeline.Box.READER.create); } @@ -11944,8 +12049,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestPipeline.Box.WRITER OutBox @@ -11956,8 +12061,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa604ee63cf37819fUL)] - public class Params_testPointers : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa604ee63cf37819fUL)] + public class Params_TestPointers : ICapnpSerializable { public const UInt64 typeId = 0xa604ee63cf37819fUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -12046,8 +12151,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8eda54756c6070d6UL)] - public class Result_testPointers : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8eda54756c6070d6UL)] + public class Result_TestPointers : ICapnpSerializable { public const UInt64 typeId = 0x8eda54756c6070d6UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -12091,8 +12196,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf8e36b53ab093d4eUL)] - public class Params_getAnyCap : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf8e36b53ab093d4eUL)] + public class Params_GetAnyCap : ICapnpSerializable { public const UInt64 typeId = 0xf8e36b53ab093d4eUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -12166,8 +12271,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xbf44b4c94c26ef79UL)] - public class Result_getAnyCap : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbf44b4c94c26ef79UL)] + public class Result_GetAnyCap : ICapnpSerializable { public const UInt64 typeId = 0xbf44b4c94c26ef79UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -12216,7 +12321,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestPipeline.AnyBox.READER OutBox => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestPipeline.AnyBox.READER.create); } @@ -12229,8 +12334,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestPipeline.AnyBox.WRITER OutBox @@ -12242,26 +12347,30 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa0e77035bdff0051UL), Proxy(typeof(TestCallOrder_Proxy)), Skeleton(typeof(TestCallOrder_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa0e77035bdff0051UL), Proxy(typeof(TestCallOrder_Proxy)), Skeleton(typeof(TestCallOrder_Skeleton))] public interface ITestCallOrder : IDisposable { Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa0e77035bdff0051UL)] public class TestCallOrder_Proxy : Proxy, ITestCallOrder { public async Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestCallOrder.Params_getCallSequence() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestCallOrder.Params_GetCallSequence() { Expected = expected }; - arg_.serialize(in_); - var d_ = await Call(11594359141811814481UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.N); + arg_?.serialize(in_); + using (var d_ = await Call(11594359141811814481UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.N); + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa0e77035bdff0051UL)] public class TestCallOrder_Skeleton : Skeleton { public TestCallOrder_Skeleton() @@ -12272,23 +12381,26 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11594359141811814481UL; Task GetCallSequence(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.GetCallSequence(in_.Expected, cancellationToken_), n => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestCallOrder.Result_getCallSequence { N = n }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.GetCallSequence(in_.Expected, cancellationToken_), n => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestCallOrder.Result_GetCallSequence { N = n }; + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestCallOrder { - [TypeId(0x8f1e8cd56ceb74dcUL)] - public class Params_getCallSequence : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8f1e8cd56ceb74dcUL)] + public class Params_GetCallSequence : ICapnpSerializable { public const UInt64 typeId = 0x8f1e8cd56ceb74dcUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -12347,8 +12459,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdedbb6bf3810eab7UL)] - public class Result_getCallSequence : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdedbb6bf3810eab7UL)] + public class Result_GetCallSequence : ICapnpSerializable { public const UInt64 typeId = 0xdedbb6bf3810eab7UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -12408,30 +12520,35 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xddd699207eb8e23bUL), Proxy(typeof(TestTailCallee_Proxy)), Skeleton(typeof(TestTailCallee_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddd699207eb8e23bUL), Proxy(typeof(TestTailCallee_Proxy)), Skeleton(typeof(TestTailCallee_Skeleton))] public interface ITestTailCallee : IDisposable { Task Foo(int i, string t, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddd699207eb8e23bUL)] public class TestTailCallee_Proxy : Proxy, ITestTailCallee { public Task Foo(int i, string t, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestTailCallee.Params_foo() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestTailCallee.Params_Foo() { I = i, T = t }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15985132292242203195UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return r_; + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddd699207eb8e23bUL)] public class TestTailCallee_Skeleton : Skeleton { public TestTailCallee_Skeleton() @@ -12442,21 +12559,24 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 15985132292242203195UL; Task Foo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.T, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.T, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestTailCallee { - [TypeId(0xa9ed2e5a9fd53d19UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9ed2e5a9fd53d19UL)] public class TailResult : ICapnpSerializable { public const UInt64 typeId = 0xa9ed2e5a9fd53d19UL; @@ -12515,7 +12635,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public uint I => ctx.ReadDataUInt(0UL, 0U); - public string T => ctx.ReadText(0, ""); + public string T => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestCallOrder C => ctx.ReadCap(1); } @@ -12534,8 +12654,8 @@ namespace Capnproto_test.Capnp.Test public string T { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestCallOrder C @@ -12546,8 +12666,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc5e1efc325614957UL)] - public class Params_foo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc5e1efc325614957UL)] + public class Params_Foo : ICapnpSerializable { public const UInt64 typeId = 0xc5e1efc325614957UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -12597,7 +12717,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int I => ctx.ReadDataInt(0UL, 0); - public string T => ctx.ReadText(0, ""); + public string T => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -12615,37 +12735,42 @@ namespace Capnproto_test.Capnp.Test public string T { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } } - [TypeId(0x870bf40110ce3035UL), Proxy(typeof(TestTailCaller_Proxy)), Skeleton(typeof(TestTailCaller_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x870bf40110ce3035UL), Proxy(typeof(TestTailCaller_Proxy)), Skeleton(typeof(TestTailCaller_Skeleton))] public interface ITestTailCaller : IDisposable { Task Foo(int i, Capnproto_test.Capnp.Test.ITestTailCallee callee, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x870bf40110ce3035UL)] public class TestTailCaller_Proxy : Proxy, ITestTailCaller { public Task Foo(int i, Capnproto_test.Capnp.Test.ITestTailCallee callee, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestTailCaller.Params_foo() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestTailCaller.Params_Foo() { I = i, Callee = callee }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(9731139705278181429UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return r_; + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x870bf40110ce3035UL)] public class TestTailCaller_Skeleton : Skeleton { public TestTailCaller_Skeleton() @@ -12656,22 +12781,25 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 9731139705278181429UL; Task Foo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.Callee, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.Callee, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestTailCaller { - [TypeId(0xb07a279515dc8ac5UL)] - public class Params_foo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb07a279515dc8ac5UL)] + public class Params_Foo : ICapnpSerializable { public const UInt64 typeId = 0xb07a279515dc8ac5UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -12746,15 +12874,17 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa38e5efe41e53a15UL), Proxy(typeof(TestHandle_Proxy)), Skeleton(typeof(TestHandle_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa38e5efe41e53a15UL), Proxy(typeof(TestHandle_Proxy)), Skeleton(typeof(TestHandle_Skeleton))] public interface ITestHandle : IDisposable { } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa38e5efe41e53a15UL)] public class TestHandle_Proxy : Proxy, ITestHandle { } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa38e5efe41e53a15UL)] public class TestHandle_Skeleton : Skeleton { public TestHandle_Skeleton() @@ -12765,7 +12895,7 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11785461720995412501UL; } - [TypeId(0xddc70bf9784133cfUL), Proxy(typeof(TestMoreStuff_Proxy)), Skeleton(typeof(TestMoreStuff_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddc70bf9784133cfUL), Proxy(typeof(TestMoreStuff_Proxy)), Skeleton(typeof(TestMoreStuff_Skeleton))] public interface ITestMoreStuff : Capnproto_test.Capnp.Test.ITestCallOrder { Task CallFoo(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default); @@ -12783,40 +12913,48 @@ namespace Capnproto_test.Capnp.Test Task MethodWithNullDefault(string a, Capnproto_test.Capnp.Test.ITestInterface b, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddc70bf9784133cfUL)] public class TestMoreStuff_Proxy : Proxy, ITestMoreStuff { public async Task CallFoo(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_callFoo() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_CallFoo() { Cap = cap }; - arg_.serialize(in_); - var d_ = await Call(15980754968839795663UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.S); + arg_?.serialize(in_); + using (var d_ = await Call(15980754968839795663UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S); + } } public async Task CallFooWhenResolved(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_callFooWhenResolved() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_CallFooWhenResolved() { Cap = cap }; - arg_.serialize(in_); - var d_ = await Call(15980754968839795663UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.S); + arg_?.serialize(in_); + using (var d_ = await Call(15980754968839795663UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S); + } } public Task NeverReturn(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_neverReturn() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_NeverReturn() { Cap = cap }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 2, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.CapCopy); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.CapCopy); + } } ); @@ -12824,36 +12962,43 @@ namespace Capnproto_test.Capnp.Test public async Task Hold(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_hold() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_Hold() { Cap = cap }; - arg_.serialize(in_); - var d_ = await Call(15980754968839795663UL, 3, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(15980754968839795663UL, 3, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task CallHeld(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_callHeld() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_CallHeld() { }; - arg_.serialize(in_); - var d_ = await Call(15980754968839795663UL, 4, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.S); + arg_?.serialize(in_); + using (var d_ = await Call(15980754968839795663UL, 4, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S); + } } public Task GetHeld(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_getHeld() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_GetHeld() { }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 5, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Cap); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Cap); + } } ); @@ -12861,14 +13006,17 @@ namespace Capnproto_test.Capnp.Test public Task Echo(Capnproto_test.Capnp.Test.ITestCallOrder cap, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_echo() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_Echo() { Cap = cap }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 6, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Cap); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Cap); + } } ); @@ -12876,36 +13024,43 @@ namespace Capnproto_test.Capnp.Test public async Task ExpectCancel(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_expectCancel() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_ExpectCancel() { Cap = cap }; - arg_.serialize(in_); - var d_ = await Call(15980754968839795663UL, 7, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(15980754968839795663UL, 7, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task<(string, string)> MethodWithDefaults(string a, uint b, string c, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_methodWithDefaults() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_MethodWithDefaults() { A = a, B = b, C = c }; - arg_.serialize(in_); - var d_ = await Call(15980754968839795663UL, 8, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.D, r_.E); + arg_?.serialize(in_); + using (var d_ = await Call(15980754968839795663UL, 8, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.D, r_.E); + } } public Task GetHandle(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_getHandle() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_GetHandle() { }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 9, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Handle); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Handle); + } } ); @@ -12913,14 +13068,17 @@ namespace Capnproto_test.Capnp.Test public Task GetNull(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_getNull() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_GetNull() { }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 10, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.NullCap); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.NullCap); + } } ); @@ -12928,38 +13086,45 @@ namespace Capnproto_test.Capnp.Test public async Task GetEnormousString(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_getEnormousString() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_GetEnormousString() { }; - arg_.serialize(in_); - var d_ = await Call(15980754968839795663UL, 11, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.Str); + arg_?.serialize(in_); + using (var d_ = await Call(15980754968839795663UL, 11, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Str); + } } public async Task MethodWithNullDefault(string a, Capnproto_test.Capnp.Test.ITestInterface b, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_methodWithNullDefault() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_MethodWithNullDefault() { A = a, B = b }; - arg_.serialize(in_); - var d_ = await Call(15980754968839795663UL, 12, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(15980754968839795663UL, 12, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestCallOrder.Params_getCallSequence() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestCallOrder.Params_GetCallSequence() { Expected = expected }; - arg_.serialize(in_); - var d_ = await Call(11594359141811814481UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.N); + arg_?.serialize(in_); + using (var d_ = await Call(11594359141811814481UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.N); + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddc70bf9784133cfUL)] public class TestMoreStuff_Skeleton : Skeleton { public TestMoreStuff_Skeleton() @@ -12970,168 +13135,207 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 15980754968839795663UL; Task CallFoo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.CallFoo(in_.Cap, cancellationToken_), s => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_callFoo { S = s }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.CallFoo(in_.Cap, cancellationToken_), s => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallFoo { S = s }; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task CallFooWhenResolved(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.CallFooWhenResolved(in_.Cap, cancellationToken_), s => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_callFooWhenResolved { S = s }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.CallFooWhenResolved(in_.Cap, cancellationToken_), s => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallFooWhenResolved { S = s }; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task NeverReturn(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.NeverReturn(in_.Cap, cancellationToken_), capCopy => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_neverReturn { CapCopy = capCopy }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.NeverReturn(in_.Cap, cancellationToken_), capCopy => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_NeverReturn { CapCopy = capCopy }; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task Hold(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.Hold(in_.Cap, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.Hold(in_.Cap, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } Task CallHeld(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.CallHeld(cancellationToken_), s => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_callHeld { S = s }; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.CallHeld(cancellationToken_), s => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallHeld { S = s }; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task GetHeld(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetHeld(cancellationToken_), cap => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_getHeld { Cap = cap }; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetHeld(cancellationToken_), cap => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetHeld { Cap = cap }; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task Echo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Echo(in_.Cap, cancellationToken_), cap => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_echo { Cap = cap }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Echo(in_.Cap, cancellationToken_), cap => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_Echo { Cap = cap }; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task ExpectCancel(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.ExpectCancel(in_.Cap, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.ExpectCancel(in_.Cap, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } Task MethodWithDefaults(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.MethodWithDefaults(in_.A, in_.B, in_.C, cancellationToken_), (d, e) => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_methodWithDefaults { D = d, E = e }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.MethodWithDefaults(in_.A, in_.B, in_.C, cancellationToken_), (d, e) => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_MethodWithDefaults { D = d, E = e }; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task GetHandle(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetHandle(cancellationToken_), handle => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_getHandle { Handle = handle }; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetHandle(cancellationToken_), handle => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetHandle { Handle = handle }; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task GetNull(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetNull(cancellationToken_), nullCap => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_getNull { NullCap = nullCap }; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetNull(cancellationToken_), nullCap => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetNull { NullCap = nullCap }; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task GetEnormousString(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetEnormousString(cancellationToken_), str => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_getEnormousString { Str = str }; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetEnormousString(cancellationToken_), str => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetEnormousString { Str = str }; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task MethodWithNullDefault(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.MethodWithNullDefault(in_.A, in_.B, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.MethodWithNullDefault(in_.A, in_.B, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestMoreStuff { - [TypeId(0x931ba418da60f6e4UL)] - public class Params_callFoo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x931ba418da60f6e4UL)] + public class Params_CallFoo : ICapnpSerializable { public const UInt64 typeId = 0x931ba418da60f6e4UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13190,8 +13394,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9a28970beccecdd0UL)] - public class Result_callFoo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9a28970beccecdd0UL)] + public class Result_CallFoo : ICapnpSerializable { public const UInt64 typeId = 0x9a28970beccecdd0UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13232,7 +13436,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -13244,14 +13448,14 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xfabc700c2ebe6378UL)] - public class Params_callFooWhenResolved : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfabc700c2ebe6378UL)] + public class Params_CallFooWhenResolved : ICapnpSerializable { public const UInt64 typeId = 0xfabc700c2ebe6378UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13310,8 +13514,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa54ce1e9aa822f90UL)] - public class Result_callFooWhenResolved : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa54ce1e9aa822f90UL)] + public class Result_CallFooWhenResolved : ICapnpSerializable { public const UInt64 typeId = 0xa54ce1e9aa822f90UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13352,7 +13556,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -13364,14 +13568,14 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0x94fe60465c95182bUL)] - public class Params_neverReturn : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x94fe60465c95182bUL)] + public class Params_NeverReturn : ICapnpSerializable { public const UInt64 typeId = 0x94fe60465c95182bUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13430,8 +13634,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdef4e5fa6999c5dcUL)] - public class Result_neverReturn : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdef4e5fa6999c5dcUL)] + public class Result_NeverReturn : ICapnpSerializable { public const UInt64 typeId = 0xdef4e5fa6999c5dcUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13490,8 +13694,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xfe7c8fbb769d8e58UL)] - public class Params_hold : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfe7c8fbb769d8e58UL)] + public class Params_Hold : ICapnpSerializable { public const UInt64 typeId = 0xfe7c8fbb769d8e58UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13550,8 +13754,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf839fb1374d003c9UL)] - public class Result_hold : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf839fb1374d003c9UL)] + public class Result_Hold : ICapnpSerializable { public const UInt64 typeId = 0xf839fb1374d003c9UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13595,8 +13799,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf8c5e5ef1edf83beUL)] - public class Params_callHeld : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf8c5e5ef1edf83beUL)] + public class Params_CallHeld : ICapnpSerializable { public const UInt64 typeId = 0xf8c5e5ef1edf83beUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13640,8 +13844,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe59935f160ac7578UL)] - public class Result_callHeld : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe59935f160ac7578UL)] + public class Result_CallHeld : ICapnpSerializable { public const UInt64 typeId = 0xe59935f160ac7578UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13682,7 +13886,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -13694,14 +13898,14 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xfeffc025fce317e3UL)] - public class Params_getHeld : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfeffc025fce317e3UL)] + public class Params_GetHeld : ICapnpSerializable { public const UInt64 typeId = 0xfeffc025fce317e3UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13745,8 +13949,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xef4e146185af67ceUL)] - public class Result_getHeld : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xef4e146185af67ceUL)] + public class Result_GetHeld : ICapnpSerializable { public const UInt64 typeId = 0xef4e146185af67ceUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13805,8 +14009,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc07526f7e2e533b9UL)] - public class Params_echo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc07526f7e2e533b9UL)] + public class Params_Echo : ICapnpSerializable { public const UInt64 typeId = 0xc07526f7e2e533b9UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13865,8 +14069,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa6224536593d5b92UL)] - public class Result_echo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa6224536593d5b92UL)] + public class Result_Echo : ICapnpSerializable { public const UInt64 typeId = 0xa6224536593d5b92UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13925,8 +14129,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa1cc32d87f3edeb1UL)] - public class Params_expectCancel : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa1cc32d87f3edeb1UL)] + public class Params_ExpectCancel : ICapnpSerializable { public const UInt64 typeId = 0xa1cc32d87f3edeb1UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -13985,8 +14189,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8a3eba1758c0916eUL)] - public class Result_expectCancel : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8a3eba1758c0916eUL)] + public class Result_ExpectCancel : ICapnpSerializable { public const UInt64 typeId = 0x8a3eba1758c0916eUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14030,8 +14234,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x99160a25fa50fbf1UL)] - public class Params_methodWithDefaults : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x99160a25fa50fbf1UL)] + public class Params_MethodWithDefaults : ICapnpSerializable { public const UInt64 typeId = 0x99160a25fa50fbf1UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14090,7 +14294,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string A => ctx.ReadText(0, ""); + public string A => ctx.ReadText(0, null); public uint B => ctx.ReadDataUInt(0UL, 123U); public string C => ctx.ReadText(1, "foo"); } @@ -14104,8 +14308,8 @@ namespace Capnproto_test.Capnp.Test public string A { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public uint B @@ -14122,8 +14326,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9c7e066f845a6c56UL)] - public class Result_methodWithDefaults : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9c7e066f845a6c56UL)] + public class Result_MethodWithDefaults : ICapnpSerializable { public const UInt64 typeId = 0x9c7e066f845a6c56UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14173,7 +14377,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string D => ctx.ReadText(0, ""); + public string D => ctx.ReadText(0, null); public string E => ctx.ReadText(1, "bar"); } @@ -14186,8 +14390,8 @@ namespace Capnproto_test.Capnp.Test public string D { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string E @@ -14198,8 +14402,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xead024a301a092a1UL)] - public class Params_getHandle : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xead024a301a092a1UL)] + public class Params_GetHandle : ICapnpSerializable { public const UInt64 typeId = 0xead024a301a092a1UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14243,8 +14447,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc3490d75420a1fe8UL)] - public class Result_getHandle : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc3490d75420a1fe8UL)] + public class Result_GetHandle : ICapnpSerializable { public const UInt64 typeId = 0xc3490d75420a1fe8UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14303,8 +14507,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd8493f0e175d61f2UL)] - public class Params_getNull : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd8493f0e175d61f2UL)] + public class Params_GetNull : ICapnpSerializable { public const UInt64 typeId = 0xd8493f0e175d61f2UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14348,8 +14552,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe6955d8ef1023671UL)] - public class Result_getNull : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe6955d8ef1023671UL)] + public class Result_GetNull : ICapnpSerializable { public const UInt64 typeId = 0xe6955d8ef1023671UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14408,8 +14612,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x805df436f55dd07aUL)] - public class Params_getEnormousString : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x805df436f55dd07aUL)] + public class Params_GetEnormousString : ICapnpSerializable { public const UInt64 typeId = 0x805df436f55dd07aUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14453,8 +14657,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x860e7512dc3925b0UL)] - public class Result_getEnormousString : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x860e7512dc3925b0UL)] + public class Result_GetEnormousString : ICapnpSerializable { public const UInt64 typeId = 0x860e7512dc3925b0UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14495,7 +14699,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Str => ctx.ReadText(0, ""); + public string Str => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -14507,14 +14711,14 @@ namespace Capnproto_test.Capnp.Test public string Str { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xfb92899aeb0ee74fUL)] - public class Params_methodWithNullDefault : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfb92899aeb0ee74fUL)] + public class Params_MethodWithNullDefault : ICapnpSerializable { public const UInt64 typeId = 0xfb92899aeb0ee74fUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14563,7 +14767,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string A => ctx.ReadText(0, ""); + public string A => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestInterface B => ctx.ReadCap(1); } @@ -14576,8 +14780,8 @@ namespace Capnproto_test.Capnp.Test public string A { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestInterface B @@ -14588,8 +14792,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8467348247305cf7UL)] - public class Result_methodWithNullDefault : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8467348247305cf7UL)] + public class Result_MethodWithNullDefault : ICapnpSerializable { public const UInt64 typeId = 0x8467348247305cf7UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14634,7 +14838,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc07d8dcd80a69c0cUL), Proxy(typeof(TestMembrane_Proxy)), Skeleton(typeof(TestMembrane_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc07d8dcd80a69c0cUL), Proxy(typeof(TestMembrane_Proxy)), Skeleton(typeof(TestMembrane_Skeleton))] public interface ITestMembrane : IDisposable { Task MakeThing(CancellationToken cancellationToken_ = default); @@ -14644,18 +14848,22 @@ namespace Capnproto_test.Capnp.Test Task WaitForever(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc07d8dcd80a69c0cUL)] public class TestMembrane_Proxy : Proxy, ITestMembrane { public Task MakeThing(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_makeThing() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_MakeThing() { }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(13870398341137210380UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Thing); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Thing); + } } ); @@ -14663,36 +14871,43 @@ namespace Capnproto_test.Capnp.Test public async Task CallPassThrough(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, bool tailCall, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_callPassThrough() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_CallPassThrough() { Thing = thing, TailCall = tailCall }; - arg_.serialize(in_); - var d_ = await Call(13870398341137210380UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + arg_?.serialize(in_); + using (var d_ = await Call(13870398341137210380UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } public async Task CallIntercept(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, bool tailCall, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_callIntercept() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_CallIntercept() { Thing = thing, TailCall = tailCall }; - arg_.serialize(in_); - var d_ = await Call(13870398341137210380UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + arg_?.serialize(in_); + using (var d_ = await Call(13870398341137210380UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } public Task Loopback(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_loopback() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_Loopback() { Thing = thing }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(13870398341137210380UL, 3, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Thing); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Thing); + } } ); @@ -14700,16 +14915,19 @@ namespace Capnproto_test.Capnp.Test public async Task WaitForever(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_waitForever() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_WaitForever() { }; - arg_.serialize(in_); - var d_ = await Call(13870398341137210380UL, 4, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(13870398341137210380UL, 4, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc07d8dcd80a69c0cUL)] public class TestMembrane_Skeleton : Skeleton { public TestMembrane_Skeleton() @@ -14720,99 +14938,120 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 13870398341137210380UL; Task MakeThing(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.MakeThing(cancellationToken_), thing => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMembrane.Result_makeThing { Thing = thing }; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.MakeThing(cancellationToken_), thing => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMembrane.Result_MakeThing { Thing = thing }; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task CallPassThrough(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.CallPassThrough(in_.Thing, in_.TailCall, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.CallPassThrough(in_.Thing, in_.TailCall, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } Task CallIntercept(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.CallIntercept(in_.Thing, in_.TailCall, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.CallIntercept(in_.Thing, in_.TailCall, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } Task Loopback(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Loopback(in_.Thing, cancellationToken_), thing => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMembrane.Result_loopback { Thing = thing }; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Loopback(in_.Thing, cancellationToken_), thing => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMembrane.Result_Loopback { Thing = thing }; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task WaitForever(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.WaitForever(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.WaitForever(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestMembrane { - [TypeId(0x9352e4e41f173917UL), Proxy(typeof(Thing_Proxy)), Skeleton(typeof(Thing_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9352e4e41f173917UL), Proxy(typeof(Thing_Proxy)), Skeleton(typeof(Thing_Skeleton))] public interface IThing : IDisposable { Task PassThrough(CancellationToken cancellationToken_ = default); Task Intercept(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9352e4e41f173917UL)] public class Thing_Proxy : Proxy, IThing { public async Task PassThrough(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Thing.Params_passThrough() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Thing.Params_PassThrough() { }; - arg_.serialize(in_); - var d_ = await Call(10615798940090972439UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + arg_?.serialize(in_); + using (var d_ = await Call(10615798940090972439UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } public async Task Intercept(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Thing.Params_intercept() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Thing.Params_Intercept() { }; - arg_.serialize(in_); - var d_ = await Call(10615798940090972439UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + arg_?.serialize(in_); + using (var d_ = await Call(10615798940090972439UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9352e4e41f173917UL)] public class Thing_Skeleton : Skeleton { public Thing_Skeleton() @@ -14823,33 +15062,39 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 10615798940090972439UL; Task PassThrough(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.PassThrough(cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.PassThrough(cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } Task Intercept(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.Intercept(cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.Intercept(cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class Thing { - [TypeId(0xff9bdcd05085d786UL)] - public class Params_passThrough : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xff9bdcd05085d786UL)] + public class Params_PassThrough : ICapnpSerializable { public const UInt64 typeId = 0xff9bdcd05085d786UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14893,8 +15138,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xee94bed3615ee745UL)] - public class Params_intercept : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xee94bed3615ee745UL)] + public class Params_Intercept : ICapnpSerializable { public const UInt64 typeId = 0xee94bed3615ee745UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -14939,7 +15184,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb0c6163faf291965UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb0c6163faf291965UL)] public class Result : ICapnpSerializable { public const UInt64 typeId = 0xb0c6163faf291965UL; @@ -14981,7 +15226,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Text => ctx.ReadText(0, ""); + public string Text => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -14993,14 +15238,14 @@ namespace Capnproto_test.Capnp.Test public string Text { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xd8ac2acc3ece6556UL)] - public class Params_makeThing : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd8ac2acc3ece6556UL)] + public class Params_MakeThing : ICapnpSerializable { public const UInt64 typeId = 0xd8ac2acc3ece6556UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15044,8 +15289,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe5d4904814ccbf29UL)] - public class Result_makeThing : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe5d4904814ccbf29UL)] + public class Result_MakeThing : ICapnpSerializable { public const UInt64 typeId = 0xe5d4904814ccbf29UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15104,8 +15349,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x945d9f634a6a29daUL)] - public class Params_callPassThrough : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x945d9f634a6a29daUL)] + public class Params_CallPassThrough : ICapnpSerializable { public const UInt64 typeId = 0x945d9f634a6a29daUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15179,8 +15424,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8749aac3375c5c71UL)] - public class Params_callIntercept : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8749aac3375c5c71UL)] + public class Params_CallIntercept : ICapnpSerializable { public const UInt64 typeId = 0x8749aac3375c5c71UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15254,8 +15499,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x869a1b7ab34b42c9UL)] - public class Params_loopback : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x869a1b7ab34b42c9UL)] + public class Params_Loopback : ICapnpSerializable { public const UInt64 typeId = 0x869a1b7ab34b42c9UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15314,8 +15559,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xecd19398fd88ab5cUL)] - public class Result_loopback : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xecd19398fd88ab5cUL)] + public class Result_Loopback : ICapnpSerializable { public const UInt64 typeId = 0xecd19398fd88ab5cUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15374,8 +15619,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8f6bb30cc62917ffUL)] - public class Params_waitForever : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8f6bb30cc62917ffUL)] + public class Params_WaitForever : ICapnpSerializable { public const UInt64 typeId = 0x8f6bb30cc62917ffUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15419,8 +15664,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc343a4907280be01UL)] - public class Result_waitForever : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc343a4907280be01UL)] + public class Result_WaitForever : ICapnpSerializable { public const UInt64 typeId = 0xc343a4907280be01UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15465,7 +15710,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x949449ad7c11fa5cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x949449ad7c11fa5cUL)] public class TestContainMembrane : ICapnpSerializable { public const UInt64 typeId = 0x949449ad7c11fa5cUL; @@ -15540,14 +15785,14 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdd2b66a791a279f0UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdd2b66a791a279f0UL)] public class TestTransferCap : ICapnpSerializable { public const UInt64 typeId = 0xdd2b66a791a279f0UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - List = reader.List.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + List = reader.List?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); applyDefaults(); } @@ -15599,7 +15844,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc7263e8f88844abcUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc7263e8f88844abcUL)] public class Element : ICapnpSerializable { public const UInt64 typeId = 0xc7263e8f88844abcUL; @@ -15649,7 +15894,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Text => ctx.ReadText(0, ""); + public string Text => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestInterface Cap => ctx.ReadCap(1); } @@ -15662,8 +15907,8 @@ namespace Capnproto_test.Capnp.Test public string Text { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestInterface Cap @@ -15675,7 +15920,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9ae342d394247cfcUL), Proxy(typeof(TestKeywordMethods_Proxy)), Skeleton(typeof(TestKeywordMethods_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9ae342d394247cfcUL), Proxy(typeof(TestKeywordMethods_Proxy)), Skeleton(typeof(TestKeywordMethods_Skeleton))] public interface ITestKeywordMethods : IDisposable { Task Delete(CancellationToken cancellationToken_ = default); @@ -15684,53 +15929,63 @@ namespace Capnproto_test.Capnp.Test Task Return(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9ae342d394247cfcUL)] public class TestKeywordMethods_Proxy : Proxy, ITestKeywordMethods { public async Task Delete(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_delete() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_Delete() { }; - arg_.serialize(in_); - var d_ = await Call(11160837778045172988UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(11160837778045172988UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Class(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_class() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_Class() { }; - arg_.serialize(in_); - var d_ = await Call(11160837778045172988UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(11160837778045172988UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Void(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_void() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_Void() { }; - arg_.serialize(in_); - var d_ = await Call(11160837778045172988UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(11160837778045172988UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Return(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_return() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_Return() { }; - arg_.serialize(in_); - var d_ = await Call(11160837778045172988UL, 3, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(11160837778045172988UL, 3, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9ae342d394247cfcUL)] public class TestKeywordMethods_Skeleton : Skeleton { public TestKeywordMethods_Skeleton() @@ -15741,37 +15996,49 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11160837778045172988UL; async Task Delete(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Delete(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Delete(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Class(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Class(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Class(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Void(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Void(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Void(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Return(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Return(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Return(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestKeywordMethods { - [TypeId(0xca3a89cdeb6bd6b7UL)] - public class Params_delete : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xca3a89cdeb6bd6b7UL)] + public class Params_Delete : ICapnpSerializable { public const UInt64 typeId = 0xca3a89cdeb6bd6b7UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15815,8 +16082,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xeeb5843598307592UL)] - public class Result_delete : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xeeb5843598307592UL)] + public class Result_Delete : ICapnpSerializable { public const UInt64 typeId = 0xeeb5843598307592UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15860,8 +16127,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9cf5a8313c5db036UL)] - public class Params_class : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9cf5a8313c5db036UL)] + public class Params_Class : ICapnpSerializable { public const UInt64 typeId = 0x9cf5a8313c5db036UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15905,8 +16172,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc0253868ac12e7d8UL)] - public class Result_class : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc0253868ac12e7d8UL)] + public class Result_Class : ICapnpSerializable { public const UInt64 typeId = 0xc0253868ac12e7d8UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15950,8 +16217,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa4a08763833c7757UL)] - public class Params_void : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa4a08763833c7757UL)] + public class Params_Void : ICapnpSerializable { public const UInt64 typeId = 0xa4a08763833c7757UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -15995,8 +16262,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xde82773089c0aeabUL)] - public class Result_void : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xde82773089c0aeabUL)] + public class Result_Void : ICapnpSerializable { public const UInt64 typeId = 0xde82773089c0aeabUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -16040,8 +16307,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x99817360625e8ca3UL)] - public class Params_return : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x99817360625e8ca3UL)] + public class Params_Return : ICapnpSerializable { public const UInt64 typeId = 0x99817360625e8ca3UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -16085,8 +16352,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb70872e07eaa992fUL)] - public class Result_return : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb70872e07eaa992fUL)] + public class Result_Return : ICapnpSerializable { public const UInt64 typeId = 0xb70872e07eaa992fUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -16131,30 +16398,35 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xea72cc77253798cdUL), Proxy(typeof(TestAuthenticatedBootstrap_Proxy<>)), Skeleton(typeof(TestAuthenticatedBootstrap_Skeleton<>))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xea72cc77253798cdUL), Proxy(typeof(TestAuthenticatedBootstrap_Proxy<>)), Skeleton(typeof(TestAuthenticatedBootstrap_Skeleton<>))] public interface ITestAuthenticatedBootstrap : IDisposable where TVatId : class { Task GetCallerId(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xea72cc77253798cdUL)] public class TestAuthenticatedBootstrap_Proxy : Proxy, ITestAuthenticatedBootstrap where TVatId : class { public Task GetCallerId(CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc.Params_getCallerId.WRITER>(); - var arg_ = new Capnproto_test.Capnp.Test.TestAuthenticatedBootstrap.Params_getCallerId() + var in_ = SerializerState.CreateForRpc.Params_GetCallerId.WRITER>(); + var arg_ = new Capnproto_test.Capnp.Test.TestAuthenticatedBootstrap.Params_GetCallerId() { }; - arg_.serialize(in_); + arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(16893789964317726925UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create.Result_getCallerId>(d_); - return (r_.Caller); + using (d_) + { + var r_ = CapnpSerializable.Create.Result_GetCallerId>(d_); + return (r_.Caller); + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xea72cc77253798cdUL)] public class TestAuthenticatedBootstrap_Skeleton : Skeleton> where TVatId : class { public TestAuthenticatedBootstrap_Skeleton() @@ -16165,23 +16437,26 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 16893789964317726925UL; Task GetCallerId(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetCallerId(cancellationToken_), caller => + using (d_) { - var s_ = SerializerState.CreateForRpc.Result_getCallerId.WRITER>(); - var r_ = new Capnproto_test.Capnp.Test.TestAuthenticatedBootstrap.Result_getCallerId { Caller = caller }; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetCallerId(cancellationToken_), caller => + { + var s_ = SerializerState.CreateForRpc.Result_GetCallerId.WRITER>(); + var r_ = new Capnproto_test.Capnp.Test.TestAuthenticatedBootstrap.Result_GetCallerId { Caller = caller }; + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestAuthenticatedBootstrap where TVatId : class { - [TypeId(0x8ec30e2451f1cffeUL)] - public class Params_getCallerId : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8ec30e2451f1cffeUL)] + public class Params_GetCallerId : ICapnpSerializable { public const UInt64 typeId = 0x8ec30e2451f1cffeUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -16225,8 +16500,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc71cf776034a3e67UL)] - public class Result_getCallerId : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc71cf776034a3e67UL)] + public class Result_GetCallerId : ICapnpSerializable { public const UInt64 typeId = 0xc71cf776034a3e67UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -16286,7 +16561,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xceba982cb629f6c2UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xceba982cb629f6c2UL)] public class TestSturdyRef : ICapnpSerializable { public const UInt64 typeId = 0xceba982cb629f6c2UL; @@ -16361,7 +16636,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe02d3bbe1010e342UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe02d3bbe1010e342UL)] public class TestSturdyRefHostId : ICapnpSerializable { public const UInt64 typeId = 0xe02d3bbe1010e342UL; @@ -16403,7 +16678,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Host => ctx.ReadText(0, ""); + public string Host => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -16415,13 +16690,13 @@ namespace Capnproto_test.Capnp.Test public string Host { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xaeb2ad168e2f5697UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xaeb2ad168e2f5697UL)] public class TestSturdyRefObjectId : ICapnpSerializable { public const UInt64 typeId = 0xaeb2ad168e2f5697UL; @@ -16480,7 +16755,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xef428f2f67c4d439UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xef428f2f67c4d439UL)] public enum Tag : ushort { testInterface, @@ -16492,7 +16767,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9e5c574772b1d462UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9e5c574772b1d462UL)] public class TestProvisionId : ICapnpSerializable { public const UInt64 typeId = 0x9e5c574772b1d462UL; @@ -16537,7 +16812,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xea2fb7dca9cdbdeaUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xea2fb7dca9cdbdeaUL)] public class TestRecipientId : ICapnpSerializable { public const UInt64 typeId = 0xea2fb7dca9cdbdeaUL; @@ -16582,7 +16857,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa805157b98b65469UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa805157b98b65469UL)] public class TestThirdPartyCapId : ICapnpSerializable { public const UInt64 typeId = 0xa805157b98b65469UL; @@ -16627,7 +16902,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf4c58a8ebcd0f600UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf4c58a8ebcd0f600UL)] public class TestJoinResult : ICapnpSerializable { public const UInt64 typeId = 0xf4c58a8ebcd0f600UL; @@ -16672,7 +16947,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd1fd8e9caf2a5d58UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd1fd8e9caf2a5d58UL)] public class TestNameAnnotation : ICapnpSerializable { public const UInt64 typeId = 0xd1fd8e9caf2a5d58UL; @@ -16697,7 +16972,7 @@ namespace Capnproto_test.Capnp.Test } AnotherBadFieldName = reader.AnotherBadFieldName; - BadlyNamedUnion = CapnpSerializable.Create(reader.BadlyNamedUnion); + BadlyNamedUnion = CapnpSerializable.Create(reader.BadlyNamedUnion); applyDefaults(); } @@ -16775,7 +17050,7 @@ namespace Capnproto_test.Capnp.Test set; } - public Capnproto_test.Capnp.Test.TestNameAnnotation.@badlyNamedUnion BadlyNamedUnion + public Capnproto_test.Capnp.Test.TestNameAnnotation.badlyNamedUnion BadlyNamedUnion { get; set; @@ -16796,7 +17071,7 @@ namespace Capnproto_test.Capnp.Test public bool BadFieldName => which == WHICH.BadFieldName ? ctx.ReadDataBool(0UL, false) : default; public sbyte Bar => which == WHICH.Bar ? ctx.ReadDataSByte(0UL, (sbyte)0) : default; public Capnproto_test.Capnp.Test.TestNameAnnotation.BadlyNamedEnum AnotherBadFieldName => (Capnproto_test.Capnp.Test.TestNameAnnotation.BadlyNamedEnum)ctx.ReadDataUShort(32UL, (ushort)0); - public @badlyNamedUnion.READER BadlyNamedUnion => new @badlyNamedUnion.READER(ctx); + public badlyNamedUnion.READER BadlyNamedUnion => new badlyNamedUnion.READER(ctx); } public class WRITER : SerializerState @@ -16830,14 +17105,14 @@ namespace Capnproto_test.Capnp.Test set => this.WriteData(32UL, (ushort)value, (ushort)0); } - public @badlyNamedUnion.WRITER BadlyNamedUnion + public badlyNamedUnion.WRITER BadlyNamedUnion { - get => Rewrap<@badlyNamedUnion.WRITER>(); + get => Rewrap(); } } - [TypeId(0x89d9d1626b34017cUL)] - public class @badlyNamedUnion : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x89d9d1626b34017cUL)] + public class badlyNamedUnion : ICapnpSerializable { public const UInt64 typeId = 0x89d9d1626b34017cUL; public enum WHICH : ushort @@ -16853,7 +17128,7 @@ namespace Capnproto_test.Capnp.Test switch (reader.which) { case WHICH.BadlyNamedGroup: - BadlyNamedGroup = CapnpSerializable.Create(reader.BadlyNamedGroup); + BadlyNamedGroup = CapnpSerializable.Create(reader.BadlyNamedGroup); break; case WHICH.Baz: Baz = CapnpSerializable.Create(reader.Baz); @@ -16908,9 +17183,9 @@ namespace Capnproto_test.Capnp.Test { } - public Capnproto_test.Capnp.Test.TestNameAnnotation.@badlyNamedUnion.@badlyNamedGroup BadlyNamedGroup + public Capnproto_test.Capnp.Test.TestNameAnnotation.badlyNamedUnion.badlyNamedGroup BadlyNamedGroup { - get => _which == WHICH.BadlyNamedGroup ? (Capnproto_test.Capnp.Test.TestNameAnnotation.@badlyNamedUnion.@badlyNamedGroup)_content : null; + get => _which == WHICH.BadlyNamedGroup ? (Capnproto_test.Capnp.Test.TestNameAnnotation.badlyNamedUnion.badlyNamedGroup)_content : null; set { _which = WHICH.BadlyNamedGroup; @@ -16940,7 +17215,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(48U, (ushort)0); - public @badlyNamedGroup.READER BadlyNamedGroup => which == WHICH.BadlyNamedGroup ? new @badlyNamedGroup.READER(ctx) : default; + public badlyNamedGroup.READER BadlyNamedGroup => which == WHICH.BadlyNamedGroup ? new badlyNamedGroup.READER(ctx) : default; public Capnproto_test.Capnp.Test.TestNameAnnotation.NestedStruct.READER Baz => which == WHICH.Baz ? ctx.ReadStruct(0, Capnproto_test.Capnp.Test.TestNameAnnotation.NestedStruct.READER.create) : default; } @@ -16956,9 +17231,9 @@ namespace Capnproto_test.Capnp.Test set => this.WriteData(48U, (ushort)value, (ushort)0); } - public @badlyNamedGroup.WRITER BadlyNamedGroup + public badlyNamedGroup.WRITER BadlyNamedGroup { - get => which == WHICH.BadlyNamedGroup ? Rewrap<@badlyNamedGroup.WRITER>() : default; + get => which == WHICH.BadlyNamedGroup ? Rewrap() : default; } public Capnproto_test.Capnp.Test.TestNameAnnotation.NestedStruct.WRITER Baz @@ -16968,8 +17243,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc3594bce5b24b722UL)] - public class @badlyNamedGroup : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc3594bce5b24b722UL)] + public class badlyNamedGroup : ICapnpSerializable { public const UInt64 typeId = 0xc3594bce5b24b722UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -17013,7 +17288,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf610d1deb4c9e84aUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf610d1deb4c9e84aUL)] public enum BadlyNamedEnum : ushort { foo, @@ -17021,7 +17296,7 @@ namespace Capnproto_test.Capnp.Test baz } - [TypeId(0xbe406b6341d52284UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbe406b6341d52284UL)] public class NestedStruct : ICapnpSerializable { public const UInt64 typeId = 0xbe406b6341d52284UL; @@ -17095,7 +17370,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf6cb3f9c7a4322e0UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf6cb3f9c7a4322e0UL)] public enum DeeplyNestedEnum : ushort { quux, @@ -17105,26 +17380,30 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd112a69d31ed918bUL), Proxy(typeof(TestNameAnnotationInterface_Proxy)), Skeleton(typeof(TestNameAnnotationInterface_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd112a69d31ed918bUL), Proxy(typeof(TestNameAnnotationInterface_Proxy)), Skeleton(typeof(TestNameAnnotationInterface_Skeleton))] public interface ITestNameAnnotationInterface : IDisposable { Task BadlyNamedMethod(byte badlyNamedParam, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd112a69d31ed918bUL)] public class TestNameAnnotationInterface_Proxy : Proxy, ITestNameAnnotationInterface { public async Task BadlyNamedMethod(byte badlyNamedParam, CancellationToken cancellationToken_ = default) { - var in_ = SerializerState.CreateForRpc(); - var arg_ = new Capnproto_test.Capnp.Test.TestNameAnnotationInterface.Params_badlyNamedMethod() + var in_ = SerializerState.CreateForRpc(); + var arg_ = new Capnproto_test.Capnp.Test.TestNameAnnotationInterface.Params_BadlyNamedMethod() { BadlyNamedParam = badlyNamedParam }; - arg_.serialize(in_); - var d_ = await Call(15065286897585459595UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + arg_?.serialize(in_); + using (var d_ = await Call(15065286897585459595UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd112a69d31ed918bUL)] public class TestNameAnnotationInterface_Skeleton : Skeleton { public TestNameAnnotationInterface_Skeleton() @@ -17135,17 +17414,20 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 15065286897585459595UL; async Task BadlyNamedMethod(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.BadlyNamedMethod(in_.BadlyNamedParam, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.BadlyNamedMethod(in_.BadlyNamedParam, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestNameAnnotationInterface { - [TypeId(0xc12efc3b075adfe9UL)] - public class Params_badlyNamedMethod : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc12efc3b075adfe9UL)] + public class Params_BadlyNamedMethod : ICapnpSerializable { public const UInt64 typeId = 0xc12efc3b075adfe9UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -17204,8 +17486,8 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdcc3cdb4b28f6c86UL)] - public class Result_badlyNamedMethod : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdcc3cdb4b28f6c86UL)] + public class Result_BadlyNamedMethod : ICapnpSerializable { public const UInt64 typeId = 0xdcc3cdb4b28f6c86UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) @@ -17255,19 +17537,22 @@ namespace Capnproto_test.Capnp.Test static readonly MemberAccessPath Path_capnproto_test_capnp_test_TestPipeline_getCap_OutBox_Cap = new MemberAccessPath(1U, 0U); public static Capnproto_test.Capnp.Test.ITestInterface OutBox_Cap(this Task<(string, Capnproto_test.Capnp.Test.TestPipeline.Box)> task) { - return (Capnproto_test.Capnp.Test.ITestInterface)CapabilityReflection.CreateProxy(Impatient.GetAnswer(task).Access(Path_capnproto_test_capnp_test_TestPipeline_getCap_OutBox_Cap)); + async Task AwaitProxy() => (await task).Item2?.Cap; + return (Capnproto_test.Capnp.Test.ITestInterface)CapabilityReflection.CreateProxy(Impatient.Access(task, Path_capnproto_test_capnp_test_TestPipeline_getCap_OutBox_Cap, AwaitProxy())); } static readonly MemberAccessPath Path_capnproto_test_capnp_test_TestPipeline_getAnyCap_OutBox_Cap = new MemberAccessPath(1U, 0U); public static BareProxy OutBox_Cap(this Task<(string, Capnproto_test.Capnp.Test.TestPipeline.AnyBox)> task) { - return (BareProxy)CapabilityReflection.CreateProxy(Impatient.GetAnswer(task).Access(Path_capnproto_test_capnp_test_TestPipeline_getAnyCap_OutBox_Cap)); + async Task AwaitProxy() => (await task).Item2?.Cap; + return (BareProxy)CapabilityReflection.CreateProxy(Impatient.Access(task, Path_capnproto_test_capnp_test_TestPipeline_getAnyCap_OutBox_Cap, AwaitProxy())); } static readonly MemberAccessPath Path_capnproto_test_capnp_test_TestTailCallee_foo_C = new MemberAccessPath(1U); public static Capnproto_test.Capnp.Test.ITestCallOrder C(this Task task) { - return (Capnproto_test.Capnp.Test.ITestCallOrder)CapabilityReflection.CreateProxy(Impatient.GetAnswer(task).Access(Path_capnproto_test_capnp_test_TestTailCallee_foo_C)); + async Task AwaitProxy() => (await task).C; + return (Capnproto_test.Capnp.Test.ITestCallOrder)CapabilityReflection.CreateProxy(Impatient.Access(task, Path_capnproto_test_capnp_test_TestTailCallee_foo_C, AwaitProxy())); } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime.Tests/ProvidedCapabilityMock.cs b/Capnp.Net.Runtime.Tests/ProvidedCapabilityMock.cs index 2e987f6..7cd187e 100644 --- a/Capnp.Net.Runtime.Tests/ProvidedCapabilityMock.cs +++ b/Capnp.Net.Runtime.Tests/ProvidedCapabilityMock.cs @@ -4,7 +4,7 @@ using Capnp.Rpc; namespace Capnp.Net.Runtime.Tests { - class ProvidedCapabilityMock : Skeleton + class ProvidedCapabilityMock : RefCountingSkeleton { readonly TaskCompletionSource<(ulong, ushort, DeserializerState, CancellationToken)> _call = new TaskCompletionSource<(ulong, ushort, DeserializerState, CancellationToken)>(); diff --git a/Capnp.Net.Runtime.Tests/ProvidedCapabilityMultiCallMock.cs b/Capnp.Net.Runtime.Tests/ProvidedCapabilityMultiCallMock.cs index 58bb57a..771c786 100644 --- a/Capnp.Net.Runtime.Tests/ProvidedCapabilityMultiCallMock.cs +++ b/Capnp.Net.Runtime.Tests/ProvidedCapabilityMultiCallMock.cs @@ -6,7 +6,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Capnp.Net.Runtime.Tests { - class ProvidedCapabilityMultiCallMock : Skeleton + class ProvidedCapabilityMultiCallMock : RefCountingSkeleton { readonly BufferBlock _ccs = new BufferBlock(); diff --git a/Capnp.Net.Runtime.Tests/RpcSchemaTests.cs b/Capnp.Net.Runtime.Tests/RpcSchemaTests.cs index 8032cc3..0a95dc6 100644 --- a/Capnp.Net.Runtime.Tests/RpcSchemaTests.cs +++ b/Capnp.Net.Runtime.Tests/RpcSchemaTests.cs @@ -1,9 +1,12 @@ using Capnp.Rpc; using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class RpcSchemaTests { [TestMethod] @@ -365,5 +368,406 @@ namespace Capnp.Net.Runtime.Tests Assert.AreEqual("reason", r.Unimplemented.Resolve.Exception.Reason); } } + + void ConstructReconstructTest(Func construct, Action verify) + where TD : class, ICapnpSerializable, new() + where TW: SerializerState, new() + { + var obj = construct(); + + var mb = MessageBuilder.Create(); + var root = mb.BuildRoot(); + obj.Serialize(root); + using (var tr = new FrameTracing.RpcFrameTracer(Console.Out)) + { + tr.TraceFrame(FrameTracing.FrameDirection.Tx, mb.Frame); + } + var d = (DeserializerState)root; + var obj2 = new TD(); + obj2.Deserialize(d); + + verify(obj2); + } + + [TestMethod] + public void DcMessageAbort() + { + ConstructReconstructTest( + () => new Message() + { + Abort = new Rpc.Exception() + { + Reason = "problem" + } + }, + msg => + { + Assert.IsNotNull(msg.Abort); + Assert.IsNull(msg.Accept); + Assert.AreEqual("problem", msg.Abort.Reason); + } + ); + } + + [TestMethod] + public void DcMessageAccept() + { + ConstructReconstructTest( + () => new Message() + { + Accept = new Accept() + { + QuestionId = 123u, + Embargo = true + } + }, + msg => + { + Assert.IsNotNull(msg.Accept); + Assert.AreEqual(123u, msg.Accept.QuestionId); + Assert.IsTrue(msg.Accept.Embargo); + } + ); + } + + [TestMethod] + public void DcMessageUnimplementedJoin() + { + ConstructReconstructTest( + () => new Message() + { + Unimplemented = new Message() + { + Join = new Join() + { + QuestionId = 456u, + Target = new MessageTarget() + { + ImportedCap = 789u + } + } + } + }, + msg => + { + Assert.IsNotNull(msg.Unimplemented); + Assert.IsNotNull(msg.Unimplemented.Join); + Assert.AreEqual(456u, msg.Unimplemented.Join.QuestionId); + Assert.IsNotNull(msg.Unimplemented.Join.Target); + Assert.AreEqual(789u, msg.Unimplemented.Join.Target.ImportedCap); + } + ); + } + + [TestMethod] + public void DcMessageCall() + { + ConstructReconstructTest( + () => new Message() + { + Call = new Call() + { + AllowThirdPartyTailCall = true, + InterfaceId = 0x12345678abcdef, + MethodId = 0x5555, + Params = new Payload() + { + CapTable = new List() + { + new CapDescriptor() + { + ReceiverAnswer = new PromisedAnswer() + { + QuestionId = 42u, + Transform = new List() + { + new PromisedAnswer.Op() + { + GetPointerField = 3 + } + } + }, + }, + new CapDescriptor() + { + ReceiverHosted = 7u + }, + new CapDescriptor() + { + SenderHosted = 8u + }, + new CapDescriptor() + { + SenderPromise = 9u + }, + new CapDescriptor() + { + ThirdPartyHosted = new ThirdPartyCapDescriptor() + { + VineId = 10u + } + } + } + }, + QuestionId = 57u, + SendResultsTo = new Call.sendResultsTo() + { + which = Call.sendResultsTo.WHICH.Caller + }, + Target = new MessageTarget() + { + PromisedAnswer = new PromisedAnswer() + { + QuestionId = 12u + } + } + } + }, + msg => + { + Assert.IsNotNull(msg.Call); + Assert.IsTrue(msg.Call.AllowThirdPartyTailCall); + Assert.AreEqual(0x12345678abcdeful, msg.Call.InterfaceId); + Assert.AreEqual(0x5555u, msg.Call.MethodId); + Assert.IsNotNull(msg.Call.Params); + Assert.IsNotNull(msg.Call.Params.CapTable); + Assert.AreEqual(5, msg.Call.Params.CapTable.Count); + Assert.IsNotNull(msg.Call.Params.CapTable[0].ReceiverAnswer); + Assert.AreEqual(42u, msg.Call.Params.CapTable[0].ReceiverAnswer.QuestionId); + Assert.IsNotNull(msg.Call.Params.CapTable[0].ReceiverAnswer.Transform); + Assert.AreEqual(1, msg.Call.Params.CapTable[0].ReceiverAnswer.Transform.Count); + Assert.AreEqual((ushort)3, msg.Call.Params.CapTable[0].ReceiverAnswer.Transform[0].GetPointerField); + Assert.AreEqual(7u, msg.Call.Params.CapTable[1].ReceiverHosted); + Assert.AreEqual(8u, msg.Call.Params.CapTable[2].SenderHosted); + Assert.AreEqual(9u, msg.Call.Params.CapTable[3].SenderPromise); + Assert.IsNotNull(msg.Call.Params.CapTable[4].ThirdPartyHosted); + Assert.AreEqual(10u, msg.Call.Params.CapTable[4].ThirdPartyHosted.VineId); + Assert.AreEqual(57u, msg.Call.QuestionId); + Assert.IsNotNull(msg.Call.SendResultsTo); + Assert.AreEqual(Call.sendResultsTo.WHICH.Caller, msg.Call.SendResultsTo.which); + Assert.IsNotNull(msg.Call.Target); + Assert.IsNotNull(msg.Call.Target.PromisedAnswer); + Assert.AreEqual(12u, msg.Call.Target.PromisedAnswer.QuestionId); + } + ); + } + + [TestMethod] + public void DcMessageReturnResults() + { + ConstructReconstructTest( + () => new Message() + { + Return = new Return() + { + AnswerId = 123u, + ReleaseParamCaps = false, + Results = new Payload() + { + CapTable = new List() + } + } + }, + msg => + { + Assert.IsNotNull(msg.Return); + Assert.AreEqual(123u, msg.Return.AnswerId); + Assert.IsFalse(msg.Return.ReleaseParamCaps); + Assert.IsNotNull(msg.Return.Results); + Assert.IsNotNull(msg.Return.Results.CapTable); + Assert.AreEqual(0, msg.Return.Results.CapTable.Count); + } + ); + } + + [TestMethod] + public void DcMessageReturnException() + { + ConstructReconstructTest( + () => new Message() + { + Return = new Return() + { + AnswerId = 123u, + ReleaseParamCaps = true, + Exception = new Rpc.Exception() + { + Reason = "bad", + TheType = Rpc.Exception.Type.overloaded + } + } + }, + msg => + { + Assert.IsNotNull(msg.Return); + Assert.AreEqual(123u, msg.Return.AnswerId); + Assert.IsTrue(msg.Return.ReleaseParamCaps); + Assert.IsNotNull(msg.Return.Exception); + Assert.AreEqual("bad", msg.Return.Exception.Reason); + Assert.AreEqual(Rpc.Exception.Type.overloaded, msg.Return.Exception.TheType); + } + ); + } + + [TestMethod] + public void DcMessageReturnTakeFromOtherQuestion() + { + ConstructReconstructTest( + () => new Message() + { + Return = new Return() + { + AnswerId = 123u, + ReleaseParamCaps = true, + TakeFromOtherQuestion = 321u + } + }, + msg => + { + Assert.IsNotNull(msg.Return); + Assert.AreEqual(123u, msg.Return.AnswerId); + Assert.IsTrue(msg.Return.ReleaseParamCaps); + Assert.AreEqual(321u, msg.Return.TakeFromOtherQuestion); + } + ); + } + + [TestMethod] + public void DcMessageFinish() + { + ConstructReconstructTest( + () => new Message() + { + Finish = new Finish() + { + QuestionId = 321u, + ReleaseResultCaps = true + } + }, + msg => + { + Assert.IsNotNull(msg.Finish); + Assert.AreEqual(321u, msg.Finish.QuestionId); + Assert.IsTrue(msg.Finish.ReleaseResultCaps); + } + ); + } + + [TestMethod] + public void DcMessageResolve() + { + ConstructReconstructTest( + () => new Message() + { + Resolve = new Resolve() + { + PromiseId = 555u, + Exception = new Rpc.Exception() + { + Reason = "error", + TheType = Rpc.Exception.Type.failed + } + } + }, + msg => + { + Assert.IsNotNull(msg.Resolve); + Assert.AreEqual(555u, msg.Resolve.PromiseId); + Assert.AreEqual("error", msg.Resolve.Exception.Reason); + Assert.AreEqual(Rpc.Exception.Type.failed, msg.Resolve.Exception.TheType); + } + ); + } + + [TestMethod] + public void DcMessageRelease() + { + ConstructReconstructTest( + () => new Message() + { + Release = new Release() + { + Id = 6000u, + ReferenceCount = 6u + } + }, + msg => + { + Assert.IsNotNull(msg.Release); + Assert.AreEqual(6000u, msg.Release.Id); + Assert.AreEqual(6u, msg.Release.ReferenceCount); + } + ); + } + + [TestMethod] + public void DcMessageBootstrap() + { + ConstructReconstructTest( + () => new Message() + { + Bootstrap = new Bootstrap() + { + QuestionId = 99u + } + }, + msg => + { + Assert.IsNotNull(msg.Bootstrap); + Assert.AreEqual(99u, msg.Bootstrap.QuestionId); + } + ); + } + + [TestMethod] + public void DcMessageProvide() + { + ConstructReconstructTest( + () => new Message() + { + Provide = new Provide() + { + Target = new MessageTarget() + { + ImportedCap = 7u + } + } + }, + msg => + { + Assert.IsNotNull(msg.Provide); + Assert.IsNotNull(msg.Provide.Target); + Assert.AreEqual(7u, msg.Provide.Target.ImportedCap); + } + ); + } + + [TestMethod] + public void DcMessageDisembargo() + { + ConstructReconstructTest( + () => new Message() + { + Disembargo = new Disembargo() + { + Context = new Disembargo.context() + { + ReceiverLoopback = 900u + }, + Target = new MessageTarget() + } + }, + msg => + { + Assert.IsNotNull(msg.Disembargo); + Assert.IsNotNull(msg.Disembargo.Context); + Assert.AreEqual(900u, msg.Disembargo.Context.ReceiverLoopback); + Assert.IsNotNull(msg.Disembargo.Target); + Assert.IsNull(msg.Disembargo.Target.ImportedCap); + Assert.IsNull(msg.Disembargo.Target.PromisedAnswer); + Assert.AreEqual(MessageTarget.WHICH.undefined, msg.Disembargo.Target.which); + } + ); + } } } diff --git a/Capnp.Net.Runtime.Tests/SegmentAllocatorTests.cs b/Capnp.Net.Runtime.Tests/SegmentAllocatorTests.cs index 7506f08..7ff67b5 100644 --- a/Capnp.Net.Runtime.Tests/SegmentAllocatorTests.cs +++ b/Capnp.Net.Runtime.Tests/SegmentAllocatorTests.cs @@ -3,6 +3,7 @@ namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class SegmentAllocatorTests { [TestMethod] diff --git a/Capnp.Net.Runtime.Tests/SerializationTests.cs b/Capnp.Net.Runtime.Tests/SerializationTests.cs new file mode 100644 index 0000000..0e53fb1 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/SerializationTests.cs @@ -0,0 +1,1212 @@ +using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Rpc; +using Capnproto_test.Capnp.Test; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Capnproto_test.Capnp.Test.TestStructUnion; + +namespace Capnp.Net.Runtime.Tests +{ + [TestClass] + [TestCategory("Coverage")] + public class SerializationTests + { + [TestMethod] + public void ListOfBits1() + { + void CheckList(IEnumerable items) + { + int i = 0; + foreach (bool bit in items) + { + if (i == 63 || i == 66 || i == 129) + Assert.IsTrue(bit); + else + Assert.IsFalse(bit); + + ++i; + } + Assert.AreEqual(130, i); + } + + var b = MessageBuilder.Create(); + var list = b.CreateObject(); + Assert.ThrowsException(() => list.Init(-1)); + // Assert.AreEqual(0, list.Count); // Bug or feature? Uninitialized list's Count is -1 + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.ThrowsException(() => { list[0] = false; }); + list.Init(130); + list[63] = true; + list[65] = true; + list[66] = true; + list[65] = false; + list[129] = true; + Assert.ThrowsException(() => { var _ = list[130]; }); + Assert.ThrowsException(() => { list[130] = false; }); + Assert.IsFalse(list[0]); + Assert.IsTrue(list[63]); + Assert.IsFalse(list[64]); + Assert.IsFalse(list[65]); + Assert.IsTrue(list[66]); + Assert.IsTrue(list[129]); + var list2 = b.CreateObject(); + list2.Init(null); + list2.Init(list.ToArray()); + Assert.IsFalse(list2[0]); + Assert.IsTrue(list2[63]); + Assert.IsFalse(list2[64]); + Assert.IsFalse(list2[65]); + Assert.IsTrue(list2[66]); + Assert.IsTrue(list2[129]); + CheckList(list2); + Assert.ThrowsException(() => list.Init(4)); + DeserializerState d = list2; + var list3 = d.RequireList().CastBool(); + CheckList(list3); + } + + [TestMethod] + public void ListOfBits2() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(8, 7); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, true)); + Assert.ThrowsException(() => wrong.ListWriteValues(new bool[7])); + var list = b.CreateObject(); + list.SetListOfValues(1, 70); + list.ListWriteValue(0, true); + Assert.ThrowsException(() => list.ListWriteValue(-1, true)); + Assert.ThrowsException(() => list.ListWriteValue(70, true)); + var values = new bool[70]; + values[63] = true; + values[65] = true; + list.ListWriteValues(values, true); + var los = list.Rewrap(); + Assert.IsTrue(!los[63]); + Assert.IsFalse(!los[64]); + Assert.IsTrue(!los[65]); + Assert.IsFalse(!los[66]); + Assert.ThrowsException(() => list.ListWriteValues(null)); + Assert.ThrowsException(() => list.ListWriteValues(new bool[1])); + Assert.ThrowsException(() => list.ListWriteValues(new bool[71])); + } + + [TestMethod] + public void ListOfCaps() + { + var b = MessageBuilder.Create(); + b.InitCapTable(); + var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.ThrowsException(() => { list[0] = null; }); + list.Init(5); + Assert.ThrowsException(() => list.Init(1)); + Assert.ThrowsException(() => { var _ = list[5]; }); + Assert.ThrowsException(() => { list[-1] = null; }); + var c1 = new Counters(); + var cap1 = new TestInterfaceImpl(c1); + var c2 = new Counters(); + var cap2 = new TestInterfaceImpl(c2); + list[0] = null; + list[1] = cap1; + list[2] = cap2; + list[3] = cap1; + list[4] = cap2; + list[3] = null; + Assert.IsTrue(list.All(p => p is Rpc.Proxy)); + var proxies = list.Cast().ToArray(); + Assert.IsTrue(proxies[0].IsNull); + Assert.IsFalse(proxies[1].IsNull); + Assert.IsTrue(proxies[3].IsNull); + list[2].Foo(123u, true).Wait(); + Assert.AreEqual(0, c1.CallCount); + Assert.AreEqual(1, c2.CallCount); + list[4].Foo(123u, true).Wait(); + Assert.AreEqual(2, c2.CallCount); + + var list2 = b.CreateObject>(); + list2.Init(null); + list2.Init(list.ToArray()); + proxies = list2.Cast().ToArray(); + Assert.IsTrue(proxies[0].IsNull); + Assert.IsFalse(proxies[1].IsNull); + Assert.IsTrue(proxies[3].IsNull); + list2[2].Foo(123u, true).Wait(); + Assert.AreEqual(0, c1.CallCount); + Assert.AreEqual(3, c2.CallCount); + list2[4].Foo(123u, true).Wait(); + Assert.AreEqual(4, c2.CallCount); + + DeserializerState d = list2; + var list3 = d.RequireList().CastCapList(); + proxies = list3.Cast().ToArray(); + Assert.IsTrue(proxies[0].IsNull); + Assert.IsFalse(proxies[1].IsNull); + Assert.IsTrue(proxies[3].IsNull); + list3[2].Foo(123u, true).Wait(); + Assert.AreEqual(0, c1.CallCount); + Assert.AreEqual(5, c2.CallCount); + list3[4].Foo(123u, true).Wait(); + Assert.AreEqual(6, c2.CallCount); + } + + [TestMethod] + public void ListOfEmpty() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject(); + Assert.ThrowsException(() => list.Init(-1)); + list.Init(987654321); + Assert.AreEqual(987654321, list.Count); + Assert.ThrowsException(() => list.Init(42)); + DeserializerState d = list; + int list2 = d.RequireList().CastVoid(); + Assert.AreEqual(987654321, list2); + } + + [TestMethod] + public void ListOfPointers() + { + var b = MessageBuilder.Create(); + b.InitCapTable(); + var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.ThrowsException(() => { list[0] = null; }); + list.Init(7); + Assert.ThrowsException(() => list.Init(1)); + Assert.AreEqual(7, list.Count); + Assert.ThrowsException(() => { var _ = list[-1]; }); + Assert.ThrowsException(() => { list[7] = null; }); + var c1 = new Counters(); + var cap1 = new TestInterfaceImpl(c1); + var obj1 = b.CreateObject(); + obj1.SetObject(cap1); + var obj2 = b.CreateObject(); + obj2.SetStruct(1, 1); + var lobs = b.CreateObject(); + lobs.Init(1); + var obj3 = lobs.Rewrap(); + list[1] = obj1; + list[2] = obj2; + list[3] = obj3; + Assert.IsNotNull(list[0]); + Assert.AreEqual(ObjectKind.Nil, list[0].Kind); + Assert.AreEqual(obj1, list[1]); + Assert.AreEqual(obj2, list[2]); + Assert.AreEqual(obj3, list[3]); + var list2 = list.ToArray(); + Assert.IsNotNull(list2[0]); + Assert.AreEqual(ObjectKind.Nil, list2[0].Kind); + Assert.AreEqual(obj1, list2[1]); + Assert.AreEqual(obj2, list2[2]); + Assert.AreEqual(obj3, list2[3]); + + DeserializerState d = list; + var list3 = d.RequireList().Cast(_ => _); + Assert.AreEqual(7, list3.Count); + Assert.IsNotNull(list3[0]); + Assert.AreEqual(ObjectKind.Nil, list3[0].Kind); + Assert.AreEqual(ObjectKind.Capability, list3[1].Kind); + Assert.AreEqual(ObjectKind.Struct, list3[2].Kind); + Assert.AreEqual(ObjectKind.ListOfBits, list3[3].Kind); + } + + [TestMethod] + public void ListOfPrimitives() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.ThrowsException(() => { list[0] = 1.0f; }); + list.Init(4); + Assert.ThrowsException(() => list.Init(1)); + Assert.AreEqual(4, list.Count); + list[0] = 0.0f; + list[1] = 1.0f; + list[2] = 2.0f; + list[3] = 3.0f; + Assert.AreEqual(0.0f, list[0]); + Assert.AreEqual(1.0f, list[1]); + Assert.AreEqual(2.0f, list[2]); + Assert.AreEqual(3.0f, list[3]); + + var list2 = b.CreateObject>(); + list2.Init(null); + list2.Init(list.ToArray()); + Assert.AreEqual(4, list2.Count); + Assert.AreEqual(0.0f, list2[0]); + Assert.AreEqual(1.0f, list2[1]); + Assert.AreEqual(2.0f, list2[2]); + Assert.AreEqual(3.0f, list2[3]); + + DeserializerState d = list2; + var list3 = d.RequireList().CastFloat(); + Assert.AreEqual(4, list3.Count); + Assert.AreEqual(0.0f, list3[0]); + Assert.AreEqual(1.0f, list3[1]); + Assert.AreEqual(2.0f, list3[2]); + Assert.AreEqual(3.0f, list3[3]); + } + + [TestMethod] + public void ListOfBytes() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(1, 64); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, (byte)1)); + Assert.ThrowsException(() => wrong.ListGetBytes()); + var list = b.CreateObject(); + list.SetListOfValues(8, 3); + Assert.ThrowsException(() => list.ListWriteValue(-1, (byte)1)); + Assert.ThrowsException(() => list.ListWriteValue(64, (byte)1)); + list.ListWriteValue(1, (byte)1); + list.ListWriteValue(2, (byte)2); + CollectionAssert.AreEqual(new byte[] { 0, 1, 2 }, list.ListGetBytes().ToArray()); + } + + [TestMethod] + public void ListOfUShortsWrongUse() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(1, 64); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, (ushort)1)); + var list = b.CreateObject(); + list.SetListOfValues(16, 3); + Assert.ThrowsException(() => list.ListWriteValue(-1, (ushort)1)); + Assert.ThrowsException(() => list.ListWriteValue(64, (ushort)1)); + } + + [TestMethod] + public void ListOfUShortsFromSegment() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + var array = new ushort[] { 1, 2, 3, 4, 5, 6 }; + var segment = new ArraySegment(array, 1, 3); + list.Init(segment); + CollectionAssert.AreEqual(segment.ToArray(), list.ToArray()); + } + + [TestMethod] + public void ListOfUShortsFromDeser() + { + var b = MessageBuilder.Create(); + var list0 = b.CreateObject>(); + var expected = new ushort[] { 2, 3, 4 }; + list0.Init(expected); + var deser = ((DeserializerState)list0).RequireList().CastUShort(); + var list = b.CreateObject>(); + list.Init(deser); + CollectionAssert.AreEqual(expected, list.ToArray()); + } + + [TestMethod] + public void ListOfUShortsFromSer() + { + var b = MessageBuilder.Create(); + var list0 = b.CreateObject>(); + var expected = new ushort[] { 2, 3, 4 }; + list0.Init(expected); + var list = b.CreateObject>(); + list.Init(list0); + CollectionAssert.AreEqual(expected, list.ToArray()); + } + + [TestMethod] + public void ListOfUShortsFromList() + { + var b = MessageBuilder.Create(); + var list0 = b.CreateObject>(); + var expected = new List { 2, 3, 4 }; + list0.Init(expected); + var list = b.CreateObject>(); + list.Init(list0); + CollectionAssert.AreEqual(expected, list.ToArray()); + } + + [TestMethod] + public void ListOfUInts() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(1, 64); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, 1u)); + var list = b.CreateObject(); + list.SetListOfValues(32, 3); + Assert.ThrowsException(() => list.ListWriteValue(-1, 1u)); + Assert.ThrowsException(() => list.ListWriteValue(64, 1u)); + } + + [TestMethod] + public void ListOfULongs() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(1, 64); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, 1ul)); + var list = b.CreateObject(); + list.SetListOfValues(64, 3); + Assert.ThrowsException(() => list.ListWriteValue(-1, 1ul)); + Assert.ThrowsException(() => list.ListWriteValue(64, 1ul)); + } + + [TestMethod] + public void ListOfStructs1() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + list.Init(4); + Assert.ThrowsException(() => list.Init(1)); + Assert.AreEqual(4, list.Count); + Assert.ThrowsException(() => { var _ = list[5]; }); + list[0].SomeText = "0"; + list[1].SomeText = "1"; + list[2].SomeText = "2"; + list[3].SomeText = "3"; + Assert.AreEqual("0", list[0].SomeText); + Assert.AreEqual("3", list[3].SomeText); + + var list2 = b.CreateObject>(); + list2.Init(list.ToArray(), (dst, src) => { dst.SomeText = src.SomeText; dst.MoreText = src.MoreText; }); + Assert.AreEqual(4, list2.Count); + Assert.AreEqual("0", list2[0].SomeText); + Assert.AreEqual("3", list2[3].SomeText); + + DeserializerState d = list2; + var list3 = d.RequireList().Cast(_ => new SomeStruct.READER(_)); + Assert.AreEqual(4, list3.Count); + Assert.AreEqual("0", list3[0].SomeText); + Assert.AreEqual("3", list3[3].SomeText); + } + + [TestMethod] + public void ListOfStructs2() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject(); + list.SetListOfStructs(3, 4, 5); + list.SetListOfStructs(3, 4, 5); + Assert.ThrowsException(() => list.SetListOfStructs(1, 4, 5)); + Assert.ThrowsException(() => list.SetListOfStructs(3, 1, 5)); + Assert.ThrowsException(() => list.SetListOfStructs(3, 4, 1)); + Assert.ThrowsException(() => list.StructWriteData(0, 1, 1)); + } + + [TestMethod] + public void ListOfStructs3() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Any()); + list.Init(3); + int i = 0; + foreach (var item in list) + { + item.SomeText = i.ToString(); + Assert.AreEqual(item, list[i]); + ++i; + } + Assert.AreEqual("0", list[0].SomeText); + Assert.AreEqual("1", list[1].SomeText); + Assert.AreEqual("2", list[2].SomeText); + } + + [TestMethod] + public void ListOfText() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject(); + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.ThrowsException(() => { list[0] = "foo"; }); + list.Init(4); + Assert.ThrowsException(() => list.Init(1)); + Assert.AreEqual(4, list.Count); + Assert.ThrowsException(() => { var _ = list[5]; }); + Assert.ThrowsException(() => { list[-1] = null; }); + list[0] = "0"; + list[2] = null; + list[3] = "3"; + Assert.AreEqual("0", list[0]); + Assert.IsNull(list[1]); + Assert.IsNull(list[2]); + Assert.AreEqual("3", list[3]); + + var list2 = b.CreateObject(); + list2.Init(list.ToArray()); + Assert.AreEqual(4, list2.Count); + Assert.AreEqual("0", list2[0]); + Assert.IsNull(list2[1]); + Assert.IsNull(list2[2]); + Assert.AreEqual("3", list2[3]); + + DeserializerState d = list2; + var tmp = d.RequireList(); + var list3 = tmp.CastText2(); + Assert.AreEqual(4, list3.Count); + Assert.AreEqual("0", list3[0]); + Assert.IsNull(list3[1]); + Assert.IsNull(list3[2]); + Assert.AreEqual("3", list3[3]); + } + + [TestMethod] + public void CapnpSerializableListBool() + { + var expected = new bool[] { true, false, true }; + var b = MessageBuilder.Create(); + var list = b.CreateObject(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListByte() + { + var expected = new byte[] { 1, 2, 3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListSByte() + { + var expected = new sbyte[] { -1, -2, -3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListUShort() + { + var expected = new ushort[] { 1, 2, 3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListShort() + { + var expected = new short[] { -1, -2, -3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListInt() + { + var expected = new int[] { -1, -2, -3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListUInt() + { + var expected = new uint[] { 1, 2, 3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListLong() + { + var expected = new long[] { -1, -2, -3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListULong() + { + var expected = new ulong[] { 1, 2, 3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListFloat() + { + var expected = new float[] { -1.0f, 2.0f, -3.0f }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableListDouble() + { + var expected = new double[] { -1, -2, -3 }; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + list.Init(expected); + DeserializerState d = list; + var list2 = CapnpSerializable.Create>(d); + CollectionAssert.AreEqual(expected, list2.ToArray()); + } + + [TestMethod] + public void CapnpSerializableStruct() + { + var b = MessageBuilder.Create(); + var obj = b.CreateObject(); + obj.SomeText = "hello"; + obj.MoreText = "world"; + DeserializerState d = obj; + var obj2 = CapnpSerializable.Create(d); + Assert.AreEqual("hello", obj2.SomeText); + Assert.AreEqual("world", obj2.MoreText); + } + + [TestMethod] + public void CapnpSerializableCapList() + { + var b = MessageBuilder.Create(); + b.InitCapTable(); + var wr = b.CreateObject>(); + var c1 = new Counters(); + var cap1 = new TestInterfaceImpl(c1); + var c2 = new Counters(); + var cap2 = new TestInterfaceImpl(c2); + wr.Init(new ITestInterface[] { null, cap1, cap2 }); + DeserializerState d = wr; + var list = CapnpSerializable.Create>(d); + list[1].Foo(123u, true); + Assert.AreEqual(1, c1.CallCount); + list[2].Foo(123u, true); + Assert.AreEqual(1, c2.CallCount); + } + + [TestMethod] + public void CapnpSerializableString() + { + string expected = "1, 2, 3"; + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + var bytes = Encoding.UTF8.GetBytes(expected); + list.Init(bytes.Length + 1); + bytes.CopyTo(list.Data); + DeserializerState d = list; + var str = CapnpSerializable.Create(d); + Assert.AreEqual(expected, str); + } + + [TestMethod] + public void CapnpSerializableAnyPointer() + { + var b = MessageBuilder.Create(); + var obj = b.CreateObject(); + obj.SomeText = "hello"; + obj.MoreText = "world"; + DeserializerState d = obj; + var any = CapnpSerializable.Create(d); + var obj2 = new SomeStruct.READER(any.State); + Assert.AreEqual("hello", obj2.SomeText); + Assert.AreEqual("world", obj2.MoreText); + + } + + class Unconstructible1 : ICapnpSerializable + { + public Unconstructible1(int annoyingParameter) + { + + } + + public void Deserialize(DeserializerState state) + { + throw new NotImplementedException(); + } + + public void Serialize(SerializerState state) + { + throw new NotImplementedException(); + } + } + + class Unconstructible2 : ICapnpSerializable + { + public Unconstructible2() + { + throw new NotImplementedException(); + } + + public void Deserialize(DeserializerState state) + { + throw new NotImplementedException(); + } + + public void Serialize(SerializerState state) + { + throw new NotImplementedException(); + } + } + + [TestMethod] + public void CapnpSerializableWrongUse() + { + var d = default(DeserializerState); + Assert.ThrowsException(() => CapnpSerializable.Create(d)); + Assert.ThrowsException(() => CapnpSerializable.Create>(d)); + Assert.ThrowsException(() => CapnpSerializable.Create>(d)); + Assert.ThrowsException(() => CapnpSerializable.Create(d)); + Assert.ThrowsException(() => CapnpSerializable.Create(d)); + } + + [TestMethod] + public void DynamicSerializerStateBytes() + { + var expected = new byte[] { 1, 2, 3 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastByte().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateSBytes() + { + var expected = new List { 1, 2, 3 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastSByte().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateShorts() + { + var expected = new List { 1, 2, 3 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastShort().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateUShorts() + { + var expected = new ushort[] { 1, 2, 3 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastUShort().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateInts() + { + var expected = new List { 1, 2, 3 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastInt().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateUInts() + { + var expected = new uint[] { 1, 2, 3 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastUInt().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateLongs() + { + var expected = new List { 1, 2, 3 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastLong().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateULongs() + { + var expected = new ulong[] { 1, 2, 3 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastULong().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateFloats() + { + var expected = new float[] { 1.0f, 2.0f, 3.0f }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastFloat().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateDoubles() + { + var expected = new double[] { 1.0, 2.0, 3.0 }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastDouble().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateBools() + { + var expected = new bool[] { true, true, false }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastBool().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateStrings() + { + var expected = new string[] { "foo", "bar", "baz" }; + + var b = MessageBuilder.Create(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + CollectionAssert.AreEqual(expected, d.RequireList().CastText2().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateObjects() + { + var c = new Counters(); + var cap = new TestInterfaceImpl(c); + var expected = new object[] { null, "foo", cap }; + + var b = MessageBuilder.Create(); + b.InitCapTable(); + var dss = b.CreateObject(); + dss.SetObject(expected); + DeserializerState d = dss; + var list = d.RequireList().Cast(_ => _); + Assert.AreEqual(3, list.Count); + Assert.IsTrue(list[0].Kind == ObjectKind.Nil); + Assert.AreEqual("foo", list[1].RequireList().CastText()); + var proxy = list[2].RequireCap(); + proxy.Foo(123u, true); + Assert.AreEqual(1, c.CallCount); + } + + [TestMethod] + public void DynamicSerializerStateFromDeserializerState() + { + var expected = new string[] { "foo", "bar", "baz" }; + + var b = MessageBuilder.Create(); + var lots = b.CreateObject(); + lots.Init(expected); + DeserializerState d = lots; + var dss = b.CreateObject(); + dss.SetObject(d); + DeserializerState d2 = dss; + CollectionAssert.AreEqual(expected, d2.RequireList().CastText2().ToArray()); + } + + [TestMethod] + public void DynamicSerializerStateFromSerializerState() + { + var expected = new string[] { "foo", "bar", "baz" }; + + var b = MessageBuilder.Create(); + var lots = b.CreateObject(); + lots.Init(expected); + var dss = b.CreateObject(); + dss.SetObject(lots); + DeserializerState d2 = dss; + CollectionAssert.AreEqual(expected, d2.RequireList().CastText2().ToArray()); + } + + [TestMethod] + public void EmptyListContract() + { + var list = new EmptyList(); + Assert.AreEqual(0, list.Count); + Assert.ThrowsException(() => { var _ = list[-1]; }); + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.AreEqual(0, list.ToArray().Length); + } + + class TestSerializerStateStruct11 : SerializerState + { + public TestSerializerStateStruct11() + { + SetStruct(1, 1); + } + } + + class TestSerializerStateStruct20 : SerializerState + { + public TestSerializerStateStruct20() + { + SetStruct(2, 0); + } + } + + class TestSerializerStateStruct11X : SerializerState + { + public TestSerializerStateStruct11X() + { + SetStruct(1, 1); + } + } + + [TestMethod] + public void SerializerStateInvalidRewrap1() + { + var dss = new DynamicSerializerState(MessageBuilder.Create()); + dss.SetListOfValues(8, 1); + Assert.ThrowsException(() => dss.Rewrap()); + } + + [TestMethod] + public void SerializerStateInvalidRewrap2() + { + var dss = new DynamicSerializerState(); + dss.SetStruct(1, 0); + Assert.ThrowsException(() => dss.Rewrap()); + } + + [TestMethod] + public void SerializerStateInvalidRewrap3() + { + var dss = new DynamicSerializerState(); + dss.SetStruct(0, 1); + Assert.ThrowsException(() => dss.Rewrap()); + } + + [TestMethod] + public void SerializerStateInvalidRewrap4() + { + var dss = new DynamicSerializerState(); + dss.SetStruct(1, 0); + Assert.ThrowsException(() => dss.Rewrap()); + } + + [TestMethod] + public void UnboundSerializerState() + { + var dss = new DynamicSerializerState(); + dss.SetStruct(1, 0); + Assert.ThrowsException(() => dss.WriteData(0, 0)); + } + + [TestMethod] + public void LinkBadUsage1() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + dss.SetStruct(0, 1); + Assert.ThrowsException(() => dss.Link(0, null)); + Assert.ThrowsException(() => dss.Link(-1, dss)); + Assert.ThrowsException(() => dss.Link(1, dss)); + dss.Link(0, dss); + Assert.ThrowsException(() => dss.Link(0, mb.CreateObject())); + } + + [TestMethod] + public void LinkBadUsage2() + { + var dss = new DynamicSerializerState(MessageBuilder.Create()); + dss.SetListOfPointers(1); + Assert.ThrowsException(() => dss.Link(0, null)); + Assert.ThrowsException(() => dss.Link(-1, dss)); + Assert.ThrowsException(() => dss.Link(1, dss)); + } + + [TestMethod] + public void NoCapTable() + { + var dss = new DynamicSerializerState(MessageBuilder.Create()); + dss.SetStruct(0, 1); + Assert.ThrowsException(() => dss.ReadCap(0)); + Assert.ThrowsException(() => dss.ProvideCapability(new TestInterfaceImpl2())); + Assert.ThrowsException(() => dss.ProvideCapability(new TestInterface_Skeleton())); + } + + [TestMethod] + public void StructReadCap1() + { + var dss = DynamicSerializerState.CreateForRpc(); + dss.SetStruct(0, 3); + Assert.ThrowsException(() => dss.ReadCap(-1)); + Assert.ThrowsException(() => dss.ReadCap(100)); + Assert.IsTrue(dss.ReadCap(0).IsNull); + dss.LinkToCapability(1, 99); + dss.Link(2, dss); + dss.Allocate(); + Assert.IsTrue(dss.ReadCap(0).IsNull); + Assert.IsTrue(dss.ReadCap(0) is Proxy proxy && proxy.IsNull); + Assert.ThrowsException(() => dss.ReadCap(1)); + Assert.ThrowsException(() => dss.ReadCap(2)); + } + + [TestMethod] + public void StructReadCap2() + { + var dss = DynamicSerializerState.CreateForRpc(); + dss.SetListOfStructs(1, 1, 1); + dss.Allocate(); + Assert.ThrowsException(() => dss.ReadCap(0)); + } + + [TestMethod] + public void Rewrap() + { + var mb = MessageBuilder.Create(); + var list1 = mb.CreateObject>(); + list1.Init(3); + var list2 = list1.Rewrap>(); + list2[0].WriteData(0, 0); + Assert.ThrowsException(() => list2.Rewrap()); + var obj = mb.CreateObject(); + var obj2 = obj.Rewrap(); + Assert.ThrowsException(() => obj2.Rewrap()); + } + + [TestMethod] + public void AllocatedNil() + { + var mb = MessageBuilder.Create(); + mb.InitCapTable(); + var dss = mb.CreateObject(); + dss.Allocate(); + Assert.ThrowsException(() => dss.SetCapability(0)); + dss.SetCapability(null); + Assert.ThrowsException(() => dss.SetListOfPointers(1)); + Assert.ThrowsException(() => dss.SetListOfStructs(1, 1, 1)); + Assert.ThrowsException(() => dss.SetListOfValues(8, 1)); + Assert.ThrowsException(() => dss.SetObject(mb.CreateObject())); + dss.SetObject(null); + Assert.ThrowsException(() => dss.SetStruct(1, 1)); + } + + [TestMethod] + public void SetCapability1() + { + var mb = MessageBuilder.Create(); + mb.InitCapTable(); + var dss = mb.CreateObject(); + dss.SetStruct(1, 1); + Assert.ThrowsException(() => dss.SetCapability(null)); + Assert.ThrowsException(() => dss.SetCapability(0)); + } + + [TestMethod] + public void SetCapability2() + { + var mb = MessageBuilder.Create(); + mb.InitCapTable(); + var dss = mb.CreateObject(); + dss.SetCapability(7); + dss.SetCapability(7); + Assert.ThrowsException(() => dss.SetCapability(8)); + Assert.ThrowsException(() => dss.SetCapability(null)); + } + + [TestMethod] + public void StructReadData() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + Assert.ThrowsException(() => dss.StructReadData(0, 1)); + dss.SetStruct(2, 0); + Assert.AreEqual(0ul, dss.StructReadData(0, 64)); + dss.Allocate(); + Assert.AreEqual(0ul, dss.StructReadData(0, 64)); + Assert.AreEqual(0ul, dss.StructReadData(256, 64)); + Assert.ThrowsException(() => dss.StructReadData(0, -1)); + Assert.ThrowsException(() => dss.StructReadData(1, 64)); + Assert.ThrowsException(() => dss.StructReadData(0, 65)); + Assert.ThrowsException(() => dss.StructReadData(ulong.MaxValue, 2)); + } + + [TestMethod] + public void TryGetPointer() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + Assert.ThrowsException(() => dss.TryGetPointer(0)); + dss.SetStruct(0, 1); + Assert.IsNull(dss.TryGetPointer(0)); + Assert.ThrowsException(() => dss.TryGetPointer(1)); + } + + [TestMethod] + public void ListBuildStruct() + { + var mb = MessageBuilder.Create(); + var dss1 = mb.CreateObject(); + dss1.SetStruct(1, 1); + Assert.ThrowsException(() => dss1.ListBuildStruct(0)); + var dss2 = mb.CreateObject(); + dss2.SetListOfStructs(2, 1, 1); + var s0 = dss2.ListBuildStruct(0); + Assert.AreEqual(s0, dss2.ListBuildStruct(0)); + Assert.ThrowsException(() => dss2.ListBuildStruct(-1)); + Assert.ThrowsException(() => dss2.ListBuildStruct(2)); + var s1 = dss2.ListBuildStruct(1); + Assert.AreEqual(s1, dss2.ListBuildStruct(1)); + Assert.ThrowsException(() => dss2.ListBuildStruct(-1)); + Assert.ThrowsException(() => dss2.ListBuildStruct(2)); + } + + [TestMethod] + public void LinkObject() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + dss.SetStruct(0, 5); + var s1 = mb.CreateObject(); + s1.SomeText = "foo"; + s1.MoreText = "bar"; + dss.LinkObject(0, s1); + var s2 = mb.CreateObject(); + s2.SomeText = "baz"; + s2.MoreText = "foobar"; + var d = (DeserializerState)s2; + dss.LinkObject(1, d); + var s3 = mb.CreateObject(); + s3.SomeText = "0"; + var s4 = mb.CreateObject(); + s4.SomeText = "1"; + var arr = new SomeStruct.WRITER[] { s3, s4 }; + dss.LinkObject(2, arr); + Assert.ThrowsException(() => dss.LinkObject(3, new object())); + dss.LinkObject(3, new SomeStruct() { SomeText = "corge" }); + + var t1 = dss.BuildPointer(0).Rewrap(); + Assert.AreEqual("foo", t1.SomeText); + Assert.AreEqual("bar", t1.MoreText); + var t2 = dss.BuildPointer(1).Rewrap(); + Assert.AreEqual("baz", t2.SomeText); + Assert.AreEqual("foobar", t2.MoreText); + var l = dss.BuildPointer(2).Rewrap>(); + Assert.AreEqual(2, l.Count); + Assert.AreEqual("0", l[0].SomeText); + Assert.AreEqual("1", l[1].SomeText); + Assert.AreEqual("corge", dss.BuildPointer(3).Rewrap().SomeText); + Assert.AreEqual(ObjectKind.Nil, dss.BuildPointer(4).Kind); + } + + [TestMethod] + public void Disposing() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + dss.Dispose(); + dss.Dispose(); + var dss2 = DynamicSerializerState.CreateForRpc(); + var cap = new TestInterfaceImpl2(); + dss2.ProvideCapability(cap); + dss2.Dispose(); + Assert.IsTrue(cap.IsDisposed); + dss2.Dispose(); + } + + [TestMethod] + public void ProvideCapability() + { + var dss = DynamicSerializerState.CreateForRpc(); + var impl = new TestInterfaceImpl2(); + var p1 = (Proxy)Proxy.Share(impl); + var p2 = (Proxy)Proxy.Share(impl); + Assert.AreEqual(0u, dss.ProvideCapability(p1)); + Assert.AreEqual(0u, dss.ProvideCapability(p2.ConsumedCap)); +#pragma warning disable CS0618 // Typ oder Element ist veraltet + Assert.AreEqual(0u, dss.ProvideCapability(CapabilityReflection.CreateSkeleton(impl))); +#pragma warning restore CS0618 // Typ oder Element ist veraltet + Assert.IsTrue(p1.IsDisposed); + Assert.IsFalse(p2.IsDisposed); + p2.Dispose(); + Assert.IsFalse(impl.IsDisposed); + dss.Dispose(); + Assert.IsTrue(impl.IsDisposed); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/TcpRpc.cs b/Capnp.Net.Runtime.Tests/TcpRpc.cs index b5482e4..fe89a30 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpc.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpc.cs @@ -7,43 +7,21 @@ using Capnp.Rpc; using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.Extensions.Logging; using System.Diagnostics; +using System.Threading.Tasks.Dataflow; +using Capnp.Net.Runtime.Tests.GenImpls; +using Capnproto_test.Capnp.Test; +using Capnp.Net.Runtime.Tests.Util; namespace Capnp.Net.Runtime.Tests { [TestClass] - public class TcpRpc + [TestCategory("Coverage")] + public class TcpRpc: TestBase { - public static int TcpPort = 49153; + bool ExpectingLogOutput { get; set; } = true; - (TcpRpcServer, TcpRpcClient) SetupClientServerPair() - { - var server = new TcpRpcServer(IPAddress.Any, TcpPort); - var client = new TcpRpcClient("localhost", TcpPort); - return (server, client); - } - - bool ExpectingLogOutput { get; set; } - - [TestInitialize] - public void InitConsoleLogging() - { - ExpectingLogOutput = true; - - Logging.LoggerFactory?.Dispose(); - Logging.LoggerFactory = new LoggerFactory().AddConsole((msg, level) => - { - if (!ExpectingLogOutput && level != LogLevel.Debug) - { - Assert.Fail("Did not expect any logging output, but got this: " + msg); - } - return true; - }); - } - - int MediumTimeout => Debugger.IsAttached ? Timeout.Infinite : 2000; - - [TestMethod, Timeout(10000)] + [TestMethod] public void CreateAndDispose() { (var server, var client) = SetupClientServerPair(); @@ -54,7 +32,7 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void ConnectAndDispose() { (var server, var client) = SetupClientServerPair(); @@ -64,8 +42,8 @@ namespace Capnp.Net.Runtime.Tests { try { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); } catch (System.Exception e) @@ -76,16 +54,17 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void ConnectNoServer() { - using (var client = new TcpRpcClient("localhost", TcpPort)) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var client = new TcpRpcClient(addr.ToString(), port)) { Assert.IsTrue(Assert.ThrowsExceptionAsync(() => client.WhenConnected).Wait(10000)); } } - [TestMethod, Timeout(10000)] + [TestMethod] public void ConnectAndBootstrap() { (var server, var client) = SetupClientServerPair(); @@ -93,18 +72,18 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); server.Main = new ProvidedCapabilityMock(); var main = client.GetMain(); var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(resolving.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); } } - [TestMethod, Timeout(10000)] + [TestMethod] public void ConnectNoBootstrap() { (var server, var client) = SetupClientServerPair(); @@ -112,17 +91,17 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var main = client.GetMain(); var resolving = main as IResolvingCapability; - Assert.IsTrue(Assert.ThrowsExceptionAsync(() => resolving.WhenResolved).Wait(MediumTimeout)); + Assert.IsTrue(Assert.ThrowsExceptionAsync(() => resolving.WhenResolved.WrappedTask).Wait(MediumNonDbgTimeout)); } } - [TestMethod, Timeout(10000)] + [TestMethod] public void CallReturn() { (var server, var client) = SetupClientServerPair(); @@ -130,20 +109,20 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; Assert.AreEqual(0x1234567812345678, interfaceId); Assert.AreEqual(0x3333, methodId); @@ -155,7 +134,7 @@ namespace Capnp.Net.Runtime.Tests result.WriteData(0, 654321); mock.Return.SetResult(result); - Assert.IsTrue(answer.WhenReturned.Wait(MediumTimeout)); + Assert.IsTrue(answer.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); var outresult = answer.WhenReturned.Result; Assert.AreEqual(ObjectKind.Struct, outresult.Kind); Assert.AreEqual(654321, outresult.ReadDataInt(0)); @@ -163,7 +142,7 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void CallCancelOnServer() { (var server, var client) = SetupClientServerPair(); @@ -171,20 +150,20 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; Assert.AreEqual(0x1234567812345678, interfaceId); Assert.AreEqual(0x3333, methodId); @@ -193,12 +172,12 @@ namespace Capnp.Net.Runtime.Tests mock.Return.SetCanceled(); - Assert.IsTrue(Assert.ThrowsExceptionAsync(() => answer.WhenReturned).Wait(MediumTimeout)); + Assert.IsTrue(Assert.ThrowsExceptionAsync(async () => await answer.WhenReturned).Wait(MediumNonDbgTimeout)); } } } - [TestMethod, Timeout(10000)] + [TestMethod] public void CallCancelOnClient() { ExpectingLogOutput = false; @@ -210,22 +189,22 @@ namespace Capnp.Net.Runtime.Tests { try { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(resolving.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); CancellationToken ctx; using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; Assert.AreEqual(0x1234567812345678, interfaceId); Assert.AreEqual(0x3333, methodId); @@ -234,7 +213,7 @@ namespace Capnp.Net.Runtime.Tests ctx = ct; } - Assert.IsTrue(SpinWait.SpinUntil(() => ctx.IsCancellationRequested, MediumTimeout)); + Assert.IsTrue(SpinWait.SpinUntil(() => ctx.IsCancellationRequested, MediumNonDbgTimeout)); } finally { @@ -243,7 +222,7 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void CallReturnAfterClientSideCancel() { ExpectingLogOutput = false; @@ -254,14 +233,14 @@ namespace Capnp.Net.Runtime.Tests { try { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); @@ -269,7 +248,7 @@ namespace Capnp.Net.Runtime.Tests IPromisedAnswer answer; using (answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; Assert.AreEqual(0x1234567812345678, interfaceId); Assert.AreEqual(0x3333, methodId); @@ -278,7 +257,7 @@ namespace Capnp.Net.Runtime.Tests ctx = ct; } - Assert.IsTrue(SpinWait.SpinUntil(() => ctx.IsCancellationRequested, MediumTimeout)); + Assert.IsTrue(SpinWait.SpinUntil(() => ctx.IsCancellationRequested, MediumNonDbgTimeout)); var mbr = MessageBuilder.Create(); mbr.InitCapTable(); @@ -289,7 +268,8 @@ namespace Capnp.Net.Runtime.Tests // Even after the client cancelled the call, the server must still send // a response. - Assert.IsTrue(answer.WhenReturned.ContinueWith(t => { }).Wait(MediumTimeout)); + async Task AwaitWhenReturned() => await answer.WhenReturned; + Assert.IsTrue(AwaitWhenReturned().ContinueWith(t => { }).Wait(MediumNonDbgTimeout)); } finally { @@ -305,7 +285,7 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void CallServerSideException() { (var server, var client) = SetupClientServerPair(); @@ -313,20 +293,20 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; Assert.AreEqual(0x1234567812345678, interfaceId); Assert.AreEqual(0x3333, methodId); @@ -335,14 +315,14 @@ namespace Capnp.Net.Runtime.Tests mock.Return.SetException(new MyTestException()); - var exTask = Assert.ThrowsExceptionAsync(() => answer.WhenReturned); - Assert.IsTrue(exTask.Wait(MediumTimeout)); + var exTask = Assert.ThrowsExceptionAsync(async () => await answer.WhenReturned); + Assert.IsTrue(exTask.Wait(MediumNonDbgTimeout)); Assert.IsTrue(exTask.Result.Message.Contains(new MyTestException().Message)); } } } - [TestMethod, Timeout(10000)] + [TestMethod] public void PipelineBeforeReturn() { (var server, var client) = SetupClientServerPair(); @@ -350,20 +330,20 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); var pipelined = (BareProxy)CapabilityReflection.CreateProxy(answer.Access( new MemberAccessPath(new MemberAccessPath.MemberAccess[] { new MemberAccessPath.StructMemberAccess(1) }))); @@ -385,15 +365,15 @@ namespace Capnp.Net.Runtime.Tests var result = DynamicSerializerState.CreateForRpc(); result.SetStruct(1, 2); result.WriteData(0, 654321); - uint id = result.ProvideCapability(mock2); + uint id = result.ProvideCapability(mock2).Value; result.LinkToCapability(1, id); mock.Return.SetResult(result); - Assert.IsTrue(answer.WhenReturned.Wait(MediumTimeout)); + Assert.IsTrue(answer.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.IsFalse(ct.IsCancellationRequested); - Assert.IsTrue(mock2.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock2.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId2, var methodId2, var inargs2, var ct2) = mock2.WhenCalled.Result; Assert.AreEqual(0x8765432187654321, interfaceId2); @@ -406,7 +386,7 @@ namespace Capnp.Net.Runtime.Tests result2.WriteData(0, 222222); mock2.Return.SetResult(result2); - Assert.IsTrue(answer2.WhenReturned.Wait(MediumTimeout)); + Assert.IsTrue(answer2.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); var outresult2 = answer2.WhenReturned.Result; Assert.AreEqual(ObjectKind.Struct, outresult2.Kind); Assert.AreEqual(222222, outresult2.ReadDataInt(0)); @@ -415,7 +395,7 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void PipelineAfterReturn() { (var server, var client) = SetupClientServerPair(); @@ -423,20 +403,20 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId, var methodId, var inargs, var ct) = mock.WhenCalled.Result; Assert.AreEqual(0x1234567812345678, interfaceId); @@ -449,7 +429,7 @@ namespace Capnp.Net.Runtime.Tests var result = DynamicSerializerState.CreateForRpc(); result.SetStruct(1, 2); result.WriteData(0, 654321); - uint id = result.ProvideCapability(mock2); + uint id = result.ProvideCapability(mock2).Value; result.LinkToCapability(1, id); mock.Return.SetResult(result); @@ -466,8 +446,8 @@ namespace Capnp.Net.Runtime.Tests using (var answer2 = pipelined.Call(0x8765432187654321, 0x4444, args2)) { - Assert.IsTrue(answer.WhenReturned.Wait(MediumTimeout)); - Assert.IsTrue(mock2.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(answer.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(mock2.WhenCalled.Wait(MediumNonDbgTimeout)); (var interfaceId2, var methodId2, var inargs2, var ct2) = mock2.WhenCalled.Result; Assert.AreEqual(0x8765432187654321, interfaceId2); @@ -480,7 +460,7 @@ namespace Capnp.Net.Runtime.Tests result2.WriteData(0, 222222); mock2.Return.SetResult(result2); - Assert.IsTrue(answer2.WhenReturned.Wait(MediumTimeout)); + Assert.IsTrue(answer2.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); var outresult2 = answer2.WhenReturned.Result; Assert.AreEqual(ObjectKind.Struct, outresult2.Kind); Assert.AreEqual(222222, outresult2.ReadDataInt(0)); @@ -491,7 +471,7 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void PipelineMultiple() { (var server, var client) = SetupClientServerPair(); @@ -499,20 +479,20 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); var pipelined = (BareProxy)CapabilityReflection.CreateProxy(answer.Access(new MemberAccessPath(new MemberAccessPath.MemberAccess[] { new MemberAccessPath.StructMemberAccess(1) }))); @@ -539,12 +519,12 @@ namespace Capnp.Net.Runtime.Tests var result = DynamicSerializerState.CreateForRpc(); result.SetStruct(1, 2); result.WriteData(0, 654321); - uint id = result.ProvideCapability(mock2); + uint id = result.ProvideCapability(mock2).Value; result.LinkToCapability(1, id); mock.Return.SetResult(result); - Assert.IsTrue(answer.WhenReturned.Wait(MediumTimeout)); + Assert.IsTrue(answer.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.IsFalse(ct.IsCancellationRequested); var args4 = DynamicSerializerState.CreateForRpc(); @@ -563,10 +543,10 @@ namespace Capnp.Net.Runtime.Tests var call4 = mock2.WhenCalled; var call5 = mock2.WhenCalled; - Assert.IsTrue(call2.Wait(MediumTimeout)); - Assert.IsTrue(call3.Wait(MediumTimeout)); - Assert.IsTrue(call4.Wait(MediumTimeout)); - Assert.IsTrue(call5.Wait(MediumTimeout)); + Assert.IsTrue(call2.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(call3.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(call4.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(call5.Wait(MediumNonDbgTimeout)); Assert.AreEqual(0x1111111111111111, call2.Result.InterfaceId); Assert.AreEqual(0x2222222222222222, call3.Result.InterfaceId); @@ -593,10 +573,10 @@ namespace Capnp.Net.Runtime.Tests ret5.WriteData(0, -4); call5.Result.Result.SetResult(ret5); - Assert.IsTrue(answer2.WhenReturned.Wait(MediumTimeout)); - Assert.IsTrue(answer3.WhenReturned.Wait(MediumTimeout)); - Assert.IsTrue(answer4.WhenReturned.Wait(MediumTimeout)); - Assert.IsTrue(answer5.WhenReturned.Wait(MediumTimeout)); + Assert.IsTrue(answer2.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(answer3.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(answer4.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(answer5.WhenReturned.WrappedTask.Wait(MediumNonDbgTimeout)); Assert.AreEqual(-1, answer2.WhenReturned.Result.ReadDataInt(0)); Assert.AreEqual(-2, answer3.WhenReturned.Result.ReadDataInt(0)); @@ -608,7 +588,7 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void PipelineCallAfterDisposal() { (var server, var client) = SetupClientServerPair(); @@ -616,21 +596,21 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); BareProxy pipelined; using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); pipelined = (BareProxy)CapabilityReflection.CreateProxy( answer.Access(new MemberAccessPath(new MemberAccessPath.MemberAccess[] { new MemberAccessPath.StructMemberAccess(1) }))); @@ -655,7 +635,7 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void PipelineCallDuringDisposal() { (var server, var client) = SetupClientServerPair(); @@ -663,21 +643,21 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); - SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumNonDbgTimeout); Assert.AreEqual(1, server.ConnectionCount); var mock = new ProvidedCapabilityMock(); server.Main = mock; var main = client.GetMain(); - Assert.IsTrue(main.WhenResolved.Wait(MediumTimeout)); + Assert.IsTrue(main.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var args = DynamicSerializerState.CreateForRpc(); args.SetStruct(1, 0); args.WriteData(0, 123456); IPromisedAnswer answer2; using (var answer = main.Call(0x1234567812345678, 0x3333, args)) { - Assert.IsTrue(mock.WhenCalled.Wait(MediumTimeout)); + Assert.IsTrue(mock.WhenCalled.Wait(MediumNonDbgTimeout)); var pipelined = (BareProxy)CapabilityReflection.CreateProxy(answer.Access(new MemberAccessPath(new MemberAccessPath.MemberAccess[] { new MemberAccessPath.StructMemberAccess(1) }))); @@ -695,7 +675,7 @@ namespace Capnp.Net.Runtime.Tests var tcs = new TaskCompletionSource(); using (ct.Register(() => tcs.SetResult(0))) { - Assert.IsTrue(tcs.Task.Wait(MediumTimeout)); + Assert.IsTrue(tcs.Task.Wait(MediumNonDbgTimeout)); } var mock2 = new ProvidedCapabilityMock(); @@ -703,15 +683,178 @@ namespace Capnp.Net.Runtime.Tests var result = DynamicSerializerState.CreateForRpc(); result.SetStruct(1, 2); result.WriteData(0, 654321); - uint id = result.ProvideCapability(mock2); + uint id = result.ProvideCapability(mock2).Value; result.LinkToCapability(1, id); mock.Return.SetResult(result); Assert.IsTrue(Assert.ThrowsExceptionAsync( - () => answer2.WhenReturned).Wait(MediumTimeout)); + async () => await answer2.WhenReturned).Wait(MediumNonDbgTimeout)); } } } + + [TestMethod] + public void Server1() + { + var cbb = new BufferBlock(); + var server = new TcpRpcServer(); + server.Main = new TestInterfaceImpl2(); + bool init = true; + var tracer = new FrameTracing.RpcFrameTracer(Console.Out); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + server.OnConnectionChanged += (s, a) => + { + var c = a.Connection; + if (init) + { + Assert.ThrowsException(() => c.AttachTracer(null)); + c.AttachTracer(tracer); + Assert.ThrowsException(() => c.InjectMidlayer(null)); + c.InjectMidlayer(_ => _); + Assert.IsFalse(c.IsComputing); + Assert.IsFalse(c.IsWaitingForData); + Assert.AreEqual(ConnectionState.Initializing, c.State); + Assert.IsNotNull(c.RemotePort); + Assert.AreEqual(port, c.LocalPort); + Assert.AreEqual(0L, c.RecvCount); + Assert.AreEqual(0L, c.SendCount); + } + else + { + Assert.ThrowsException(() => c.AttachTracer(tracer)); + Assert.ThrowsException(() => c.InjectMidlayer(_ => _)); + Assert.AreEqual(ConnectionState.Down, c.State); + } + + cbb.Post(c); + }; + + Assert.ThrowsException(() => server.StopListening()); + + server.StartAccepting(addr, port); + Assert.IsTrue(server.IsAlive); + Assert.ThrowsException(() => server.StartAccepting(addr, port)); + + var server2 = new TcpRpcServer(); + Assert.ThrowsException(() => server2.StartAccepting(addr, port)); + + var client1 = new TcpRpcClient(addr.ToString(), port); + var c1 = cbb.Receive(TimeSpan.FromMilliseconds(MediumNonDbgTimeout)); + Assert.IsNotNull(c1); + Assert.AreEqual(1, server.ConnectionCount); + Assert.AreEqual(c1, server.Connections[0]); + Assert.AreEqual(ConnectionState.Active, c1.State); + var proxy = client1.GetMain(); + Assert.IsTrue(proxy is IResolvingCapability r && r.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(c1.RecvCount > 0); + Assert.IsTrue(c1.SendCount > 0); + + var client2 = new TcpRpcClient(addr.ToString(), port); + var c2 = cbb.Receive(TimeSpan.FromMilliseconds(MediumNonDbgTimeout)); + Assert.IsNotNull(c2); + Assert.AreEqual(2, server.ConnectionCount); + Assert.AreEqual(c2, server.Connections[1]); + + init = false; + + client1.Dispose(); + var c1d = cbb.Receive(TimeSpan.FromMilliseconds(MediumNonDbgTimeout)); + Assert.IsNotNull(c1d); + Assert.AreEqual(1, server.ConnectionCount); + Assert.AreEqual(c2, server.Connections[0]); + Assert.IsTrue(SpinWait.SpinUntil(() => c1d.State == ConnectionState.Down, MediumNonDbgTimeout)); + + client2.Dispose(); + var c2d = cbb.Receive(TimeSpan.FromMilliseconds(MediumNonDbgTimeout)); + Assert.IsNotNull(c2d); + Assert.AreEqual(0, server.ConnectionCount); + Assert.IsTrue(SpinWait.SpinUntil(() => c2d.State == ConnectionState.Down, MediumNonDbgTimeout)); + + server.StopListening(); + Assert.IsFalse(server.IsAlive); + Assert.ThrowsException(() => server.StopListening()); + + for (int i = 0; i < 100; i++) + { + server.StartAccepting(addr, port); + Assert.IsTrue(server.IsAlive); + server.StopListening(); + Assert.IsFalse(server.IsAlive); + } + + server.Dispose(); + } + + [TestMethod] + public void Server2() + { + var server = new TcpRpcServer(); + server.Main = new TestInterfaceImpl2(); + var tracer = new FrameTracing.RpcFrameTracer(Console.Out); + server.OnConnectionChanged += (s, a) => + { + server.Dispose(); + }; + + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + server.StartAccepting(addr, port); + + var client1 = new TcpRpcClient(addr.ToString(), port); + Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout), "Did not connect"); + Assert.IsTrue(SpinWait.SpinUntil(() => client1.State == ConnectionState.Down, MediumNonDbgTimeout), + $"Connection did not go down: {client1.State}"); + } + + [TestMethod] + public void Server3() + { + using (var server = new TcpRpcServer()) + { + server.Main = new TestInterfaceImpl2(); + var tracer = new FrameTracing.RpcFrameTracer(Console.Out); + server.OnConnectionChanged += (s, a) => + { + a.Connection.Close(); + }; + + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + server.StartAccepting(addr, port); + + var client1 = new TcpRpcClient(addr.ToString(), port); + Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(SpinWait.SpinUntil(() => client1.State == ConnectionState.Down, MediumNonDbgTimeout)); + } + } + + [TestMethod] + public void Client() + { + using (var server = new TcpRpcServer()) + using (var client = new TcpRpcClient()) + { + Assert.IsFalse(client.IsComputing); + Assert.IsFalse(client.IsWaitingForData); + Assert.AreEqual(0L, client.SendCount); + Assert.AreEqual(0L, client.RecvCount); + Assert.ThrowsException(() => client.GetMain()); + Assert.ThrowsException(() => client.AttachTracer(null)); + Assert.ThrowsException(() => client.InjectMidlayer(null)); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + server.StartAccepting(addr, port); + client.Connect(addr.ToString(), port); + Assert.ThrowsException(() => client.Connect(addr.ToString(), port)); + Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + Assert.ThrowsException(() => client.AttachTracer(new FrameTracing.RpcFrameTracer(Console.Out, false))); + Assert.ThrowsException(() => client.InjectMidlayer(_ => _)); + Assert.AreEqual(port, client.RemotePort); + Assert.IsTrue(client.LocalPort != 0); + Assert.AreEqual(0L, client.SendCount); + Assert.AreEqual(0L, client.RecvCount); + Assert.IsTrue(SpinWait.SpinUntil(() => client.IsWaitingForData, MediumNonDbgTimeout)); + ((IConnection)client).Close(); + Assert.IsTrue(SpinWait.SpinUntil(() => client.State == ConnectionState.Down, MediumNonDbgTimeout)); + } + } } } diff --git a/Capnp.Net.Runtime.Tests/TcpRpcAdvancedStuff.cs b/Capnp.Net.Runtime.Tests/TcpRpcAdvancedStuff.cs index b708d77..a94ca6e 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcAdvancedStuff.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcAdvancedStuff.cs @@ -1,4 +1,5 @@ using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Net.Runtime.Tests.Util; using Capnp.Rpc; using Capnproto_test.Capnp.Test; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -10,12 +11,14 @@ using System.Threading.Tasks; namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class TcpRpcAdvancedStuff : TestBase { - [TestMethod, Timeout(10000)] + [TestMethod] public void MultiConnect() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); var tcs = new TaskCompletionSource(); @@ -23,9 +26,9 @@ namespace Capnp.Net.Runtime.Tests for (int i = 1; i <= 10; i++) { - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -50,19 +53,20 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void TwoClients() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - using (var client1 = SetupClient()) - using (var client2 = SetupClient()) + using (var client1 = SetupClient(addr, port)) + using (var client2 = SetupClient(addr, port)) { - Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(client2.WhenConnected.Wait(MediumNonDbgTimeout)); + //Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout)); + //Assert.IsTrue(client2.WhenConnected.Wait(MediumNonDbgTimeout)); using (var main = client1.GetMain()) { @@ -89,17 +93,18 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void ClosingServerWhileRequestingBootstrap() { for (int i = 0; i < 100; i++) { - var server = SetupServer(); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + var server = SetupServer(addr, port); var counters = new Counters(); var tcs = new TaskCompletionSource(); server.Main = new TestInterfaceImpl(counters, tcs); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { client.WhenConnected.Wait(); @@ -111,7 +116,7 @@ namespace Capnp.Net.Runtime.Tests try { - Assert.IsTrue(((IResolvingCapability)main).WhenResolved.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(((IResolvingCapability)main).WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); } catch (AggregateException) { @@ -124,14 +129,15 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void InheritFromGenericInterface() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new B2Impl(); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -147,13 +153,14 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void Issue25() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { server.Main = new Issue25BImpl(); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -172,5 +179,134 @@ namespace Capnp.Net.Runtime.Tests } } } + + [TestMethod] + public void ExportCapToThirdParty() + { + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) + { + var counters = new Counters(); + server.Main = new TestMoreStuffImpl3(); + + using (var client = SetupClient(addr, port)) + { + //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + + using (var main = client.GetMain()) + { + var held = main.GetHeld().Eager(); + + (addr, port) = TcpManager.Instance.GetLocalAddressAndPort(); + + using (var server2 = SetupServer(addr, port)) + { + server2.Main = new TestMoreStuffImpl2(); + + using (var client2 = SetupClient(addr, port)) + { + //Assert.IsTrue(client2.WhenConnected.Wait(MediumNonDbgTimeout)); + + using (var main2 = client2.GetMain()) + { + var fooTask = main2.CallFoo(held); + Assert.IsTrue(main.Hold(new TestInterfaceImpl(new Counters())).Wait(MediumNonDbgTimeout)); + Assert.IsTrue(fooTask.Wait(MediumNonDbgTimeout)); + Assert.AreEqual("bar", fooTask.Result); + } + } + } + } + } + } + } + + [TestMethod] + public void ExportTailCallCapToThirdParty() + { + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) + { + server.Main = new TestTailCallerImpl2(); + + using (var client = SetupClient(addr, port)) + { + //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + + using (var main = client.GetMain()) + { + var callee = new TestTailCalleeImpl(new Counters()); + var fooTask = main.Foo(123, callee); + Assert.IsTrue(fooTask.Wait(MediumNonDbgTimeout)); + + using (var c = fooTask.Result.C) + using (var client2 = SetupClient(addr, port)) + { + //Assert.IsTrue(client2.WhenConnected.Wait(MediumNonDbgTimeout)); + + using (var main2 = client2.GetMain()) + { + var fooTask2 = main2.Foo(123, null); + Assert.IsTrue(fooTask2.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(fooTask2.C().GetCallSequence(0).Wait(MediumNonDbgTimeout)); + } + } + } + } + } + } + + [TestMethod] + public void SalamiTactics() + { + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) + { + server.Main = new TestMoreStuffImpl3(); + + using (var client = SetupClient(addr, port)) + { + //client.WhenConnected.Wait(); + + using (var main = client.GetMain()) + { + var echoTask = main.Echo(Proxy.Share(main)); + Assert.IsTrue(echoTask.Wait(MediumNonDbgTimeout)); + using (var echo = echoTask.Result) + { + var list = new Task[200]; + for (uint i = 0; i < list.Length; i++) + { + list[i] = echo.GetCallSequence(i); + } + Assert.IsTrue(Task.WaitAll(list, MediumNonDbgTimeout)); + for (uint i = 0; i < list.Length; i++) + { + Assert.AreEqual(i, list[i].Result); + } + } + } + } + } + } + + + [TestMethod] + public void NoTailCallMt() + { + NewLocalhostTcpTestbed().RunTest(Testsuite.NoTailCallMt); + } + + [TestMethod] + public void CallAfterFinish1() + { + NewLocalhostTcpTestbed().RunTest(Testsuite.CallAfterFinish1); + } + + [TestMethod] + public void CallAfterFinish2() + { + NewLocalhostTcpTestbed().RunTest(Testsuite.CallAfterFinish2); + } } } diff --git a/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs b/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs index 929e3d2..ca821b9 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs @@ -1,13 +1,16 @@ using Capnp.FrameTracing; using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Net.Runtime.Tests.Util; using Capnp.Rpc; using Capnproto_test.Capnp.Test; +using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; +using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -36,7 +39,7 @@ namespace Capnp.Net.Runtime.Tests Process _currentProcess; - bool TryLaunchCompatTestProcess(string whichTest, Action test) + bool TryLaunchCompatTestProcess(IPAddress addr, int port, string whichTest, Action test) { string myPath = Path.GetDirectoryName(typeof(TcpRpcInterop).Assembly.Location); string config; @@ -47,7 +50,7 @@ namespace Capnp.Net.Runtime.Tests #endif string path = Path.Combine(myPath, $@"..\..\..\..\{config}\CapnpCompatTest.exe"); path = Path.GetFullPath(path); - string arguments = $"{whichTest} 127.0.0.1:{TcpPort}"; + string arguments = $"{whichTest} {addr}:{port}"; var startInfo = new ProcessStartInfo(path, arguments) { UseShellExecute = false, @@ -63,21 +66,25 @@ namespace Capnp.Net.Runtime.Tests try { - _currentProcess.StandardError.ReadToEndAsync().ContinueWith(t => Console.Error.WriteLine(t.Result)); - var firstLine = _currentProcess.StandardOutput.ReadLineAsync(); - Assert.IsTrue(firstLine.Wait(MediumNonDbgTimeout), "Problem after launching test process"); - Assert.IsNotNull(firstLine.Result, "Problem after launching test process"); - Assert.IsTrue(firstLine.Result.StartsWith("Listening") || firstLine.Result.StartsWith("Connecting"), - "Problem after launching test process"); + try + { + _currentProcess.StandardError.ReadToEndAsync().ContinueWith(t => Console.Error.WriteLine(t.Result)); + var firstLine = _currentProcess.StandardOutput.ReadLineAsync(); + Assert.IsTrue(firstLine.Wait(MediumNonDbgTimeout), "Problem after launching test process"); + Assert.IsNotNull(firstLine.Result, "Problem after launching test process"); + Assert.IsTrue(firstLine.Result.StartsWith("Listening") || firstLine.Result.StartsWith("Connecting"), + "Problem after launching test process"); + } + catch (AssertFailedException exception) + { + Logger.LogError(exception.Message); + return false; + } test(_currentProcess.StandardOutput); return true; } - catch (AssertFailedException) - { - return false; - } finally { try @@ -91,15 +98,13 @@ namespace Capnp.Net.Runtime.Tests } } - void LaunchCompatTestProcess(string whichTest, Action test) + void LaunchCompatTestProcess(string whichTest, IPAddress addr, int port, Action test) { for (int retry = 0; retry < 5; retry++) { - if (TryLaunchCompatTestProcess(whichTest, test)) + if (TryLaunchCompatTestProcess(addr, port, whichTest, test)) return; - if (whichTest.StartsWith("server:")) - PrepareNextTest(); } Assert.Fail("Problem after launching test process"); @@ -117,20 +122,15 @@ namespace Capnp.Net.Runtime.Tests Assert.AreEqual(expected, line.Result); } - [TestInitialize] - public void PrepareNextTest() - { - IncrementTcpPort(); - } - - [TestMethod, Timeout(10000)] + [TestMethod] public void BasicClient() { - LaunchCompatTestProcess("server:Interface", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:Interface", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -154,15 +154,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void BasicServer() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); - LaunchCompatTestProcess("client:Basic", stdout => + LaunchCompatTestProcess("client:Basic", addr, port, stdout => { AssertOutput(stdout, "Basic test start"); AssertOutput(stdout, "Basic test end"); @@ -171,16 +172,17 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void PipelineClient() { - LaunchCompatTestProcess("server:Pipeline", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:Pipeline", addr, port, stdout => { stdout.ReadToEndAsync().ContinueWith(t => Console.WriteLine(t.Result)); - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -208,32 +210,35 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void PipelineServer() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestPipelineImpl(counters); - LaunchCompatTestProcess("client:Pipelining", stdout => + LaunchCompatTestProcess("client:Pipelining", addr, port, stdout => { AssertOutput(stdout, "Pipelining test start"); AssertOutput(stdout, "foo 123 1"); + AssertOutput(stdout, "~"); AssertOutput(stdout, "Pipelining test end"); Assert.AreEqual(3, counters.CallCount); }); } } - [TestMethod, Timeout(10000)] + [TestMethod] public void ReleaseClient() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -259,15 +264,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void ReleaseServer() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:Release", stdout => + LaunchCompatTestProcess("client:Release", addr, port, stdout => { AssertOutput(stdout, "Release test start"); AssertOutput(stdout, "sync"); @@ -295,15 +301,16 @@ namespace Capnp.Net.Runtime.Tests // later on verify that the handle count is 0. int iterationCount = 5000; - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { - ((Proxy)main).WhenResolved.Wait(MediumNonDbgTimeout); + ((Proxy)main).WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout); async Task VerifyOutput() { @@ -342,17 +349,19 @@ namespace Capnp.Net.Runtime.Tests for (int i = 0; i < iterationCount; i++) { var task = main.GetHandle(default); - taskList.Add(task.ContinueWith(t => + async Task TerminateAnswer() { try { - t.Result.Dispose(); + using (var proxy = await task) + { + } } - catch (AggregateException ex) when (ex.InnerException is TaskCanceledException) + catch (TaskCanceledException) { } - })); - Impatient.GetAnswer(task).Dispose(); + } + taskList.Add(TerminateAnswer()); } // Ensure that all answers return (probably in canceled state) @@ -369,15 +378,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void ReleaseOnCancelServer() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:ReleaseOnCancel", stdout => + LaunchCompatTestProcess("client:ReleaseOnCancel", addr, port, stdout => { AssertOutput(stdout, "ReleaseOnCancel test start"); AssertOutput(stdout, "ReleaseOnCancel test end"); @@ -387,18 +397,20 @@ namespace Capnp.Net.Runtime.Tests } [TestMethod] + [TestCategory("Coverage")] public void TestTailCallClient() { - LaunchCompatTestProcess("server:TailCaller", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:TailCaller", addr, port, stdout => { using (var client = new TcpRpcClient()) { var tracer = new RpcFrameTracer(Console.Out); client.AttachTracer(tracer); - client.Connect("localhost", TcpPort); + client.Connect(addr.ToString(), port); - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -406,20 +418,22 @@ namespace Capnp.Net.Runtime.Tests var callee = new TestTailCalleeImpl(calleeCallCount); var promise = main.Foo(456, callee, default); - var dependentCall0 = promise.C().GetCallSequence(0, default); + using (var c = promise.C()) + { + var dependentCall0 = c.GetCallSequence(0, default); - Assert.IsTrue(promise.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(456u, promise.Result.I); - Assert.AreEqual("from TestTailCaller", promise.Result.T); + Assert.IsTrue(promise.Wait(MediumNonDbgTimeout)); + Assert.AreEqual(456u, promise.Result.I); + Assert.AreEqual("from TestTailCaller", promise.Result.T); - var dependentCall1 = promise.C().GetCallSequence(0, default); - var dependentCall2 = promise.C().GetCallSequence(0, default); - - AssertOutput(stdout, "foo"); - Assert.IsTrue(dependentCall0.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(dependentCall1.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(dependentCall2.Wait(MediumNonDbgTimeout)); + var dependentCall1 = c.GetCallSequence(1, default); + var dependentCall2 = c.GetCallSequence(2, default); + AssertOutput(stdout, "foo"); + Assert.IsTrue(dependentCall0.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(dependentCall1.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(dependentCall2.Wait(MediumNonDbgTimeout)); + } Assert.AreEqual(1, calleeCallCount.CallCount); } } @@ -430,8 +444,8 @@ namespace Capnp.Net.Runtime.Tests // For details on why this test is ignored, see https://github.com/capnproto/capnproto/issues/876 public void TestTailCallServer() { - - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var tracer = new RpcFrameTracer(Console.Out); @@ -444,7 +458,7 @@ namespace Capnp.Net.Runtime.Tests var counters = new Counters(); server.Main = new TestTailCallerImpl(counters); - LaunchCompatTestProcess("client:TailCall", stdout => + LaunchCompatTestProcess("client:TailCall", addr, port, stdout => { AssertOutput(stdout, "TailCall test start"); AssertOutput(stdout, "foo"); @@ -455,16 +469,17 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void CancelationServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { stdout.ReadToEndAsync().ContinueWith(t => Console.WriteLine(t.Result)); - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -485,15 +500,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void CancelationClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:Cancelation", stdout => + LaunchCompatTestProcess("client:Cancelation", addr, port, stdout => { AssertOutput(stdout, "Cancelation test start"); AssertOutput(stdout, "~"); @@ -502,40 +518,43 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void PromiseResolveServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { var tcs = new TaskCompletionSource(); - var eager = tcs.Task.Eager(true); + using (var eager = tcs.Task.Eager(true)) + { + var request = main.CallFoo(Proxy.Share(eager), default); + AssertOutput(stdout, "callFoo"); + var request2 = main.CallFooWhenResolved(Proxy.Share(eager), default); + AssertOutput(stdout, "callFooWhenResolved"); - var request = main.CallFoo(eager, default); - AssertOutput(stdout, "callFoo"); - var request2 = main.CallFooWhenResolved(eager, default); - AssertOutput(stdout, "callFooWhenResolved"); + var gcs = main.GetCallSequence(0, default); + AssertOutput(stdout, "getCallSequence"); + Assert.IsTrue(gcs.Wait(MediumNonDbgTimeout)); + Assert.AreEqual(2u, gcs.Result); - var gcs = main.GetCallSequence(0, default); - AssertOutput(stdout, "getCallSequence"); - Assert.IsTrue(gcs.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(2u, gcs.Result); + var chainedCallCount = new Counters(); + var tiimpl = new TestInterfaceImpl(chainedCallCount); + tcs.SetResult(tiimpl); - var chainedCallCount = new Counters(); - var tiimpl = new TestInterfaceImpl(chainedCallCount); - tcs.SetResult(tiimpl); + Assert.IsTrue(request.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(request2.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(request.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(request2.Wait(MediumNonDbgTimeout)); + Assert.AreEqual("bar", request.Result); + Assert.AreEqual("bar", request2.Result); + Assert.AreEqual(2, chainedCallCount.CallCount); - Assert.AreEqual("bar", request.Result); - Assert.AreEqual("bar", request2.Result); - Assert.AreEqual(2, chainedCallCount.CallCount); + } AssertOutput(stdout, "fin"); AssertOutput(stdout, "fin"); @@ -544,38 +563,41 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void PromiseResolveClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:PromiseResolve", stdout => + LaunchCompatTestProcess("client:PromiseResolve", addr, port, stdout => { AssertOutput(stdout, "PromiseResolve test start"); AssertOutput(stdout, "foo 123 1"); AssertOutput(stdout, "foo 123 1"); + AssertOutput(stdout, "~"); AssertOutput(stdout, "PromiseResolve test end"); Assert.AreEqual(3, counters.CallCount); }); } } - [TestMethod, Timeout(10000)] + [TestMethod] public void RetainAndReleaseServer() { var destructionPromise = new TaskCompletionSource(); var destructionTask = destructionPromise.Task; - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { stdout.ReadToEndAsync().ContinueWith(t => Console.WriteLine(t.Result)); - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -641,15 +663,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void RetainAndReleaseClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:RetainAndRelease", stdout => + LaunchCompatTestProcess("client:RetainAndRelease", addr, port, stdout => { AssertOutput(stdout, "RetainAndRelease test start"); AssertOutput(stdout, "foo 123 1"); @@ -661,14 +684,15 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void CancelServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var destructionPromise = new TaskCompletionSource(); var destructionTask = destructionPromise.Task; @@ -702,15 +726,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void CancelClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:Cancel", stdout => + LaunchCompatTestProcess("client:Cancel", addr, port, stdout => { AssertOutput(stdout, "Cancel test start"); AssertOutput(stdout, "~"); @@ -719,14 +744,15 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void SendTwiceServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -763,15 +789,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void SendTwiceClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:SendTwice", stdout => + LaunchCompatTestProcess("client:SendTwice", addr, port, stdout => { AssertOutput(stdout, "SendTwice test start"); AssertOutput(stdout, "foo 123 1"); @@ -783,41 +810,21 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void EmbargoServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - int retry = 0; - - label: - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout), "client connect"); + //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout), "client connect"); - using (var main = client.GetMain()) + using (var wrapped = client.GetMain()) { - var resolving = main as IResolvingCapability; - - bool success; - - try - { - success = resolving.WhenResolved.Wait(MediumNonDbgTimeout); - } - catch - { - success = false; - } - - if (!success) - { - if (++retry == 5) - { - Assert.Fail("Attempting to obtain bootstrap interface failed. Bailing out."); - } - goto label; - } + var unwrap = wrapped.Unwrap(); + Assert.IsTrue(unwrap.Wait(MediumNonDbgTimeout)); + var main = unwrap.Result; var cap = new TestCallOrderImpl(); cap.CountToDispose = 6; @@ -868,17 +875,18 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void EmbargoServer2() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { int retry = 0; label: - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout), "client connect"); + //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout), "client connect"); using (var main = client.GetMain()) { @@ -888,7 +896,7 @@ namespace Capnp.Net.Runtime.Tests try { - success = resolving.WhenResolved.Wait(MediumNonDbgTimeout); + success = resolving.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout); } catch { @@ -951,15 +959,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void EmbargoClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:Embargo", stdout => + LaunchCompatTestProcess("client:Embargo", addr, port, stdout => { AssertOutput(stdout, "Embargo test start"); AssertOutput(stdout, "Embargo test end"); @@ -967,17 +976,17 @@ namespace Capnp.Net.Runtime.Tests } } - public void EmbargoErrorImpl(StreamReader stdout) + public void EmbargoErrorImpl(IPAddress addr, int port, StreamReader stdout) { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); + //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); using (var main = client.GetMain()) { var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(resolving.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var cap = new TaskCompletionSource(); @@ -1021,33 +1030,36 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void EmbargoErrorServer() { - LaunchCompatTestProcess("server:MoreStuff", EmbargoErrorImpl); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, r => EmbargoErrorImpl(addr, port, r)); } [TestMethod, Timeout(240000)] public void RepeatedEmbargoError() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - for (int i = 0; i < 100; i++) + for (int i = 0; i < 20; i++) { - EmbargoErrorImpl(stdout); + EmbargoErrorImpl(addr, port, stdout); } }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void EmbargoErrorClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:EmbargoError", stdout => + LaunchCompatTestProcess("client:EmbargoError", addr, port, stdout => { AssertOutput(stdout, "EmbargoError test start"); AssertOutput(stdout, "EmbargoError test end"); @@ -1055,17 +1067,18 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void EmbargoNullServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { int retry = 0; label: - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { @@ -1075,7 +1088,7 @@ namespace Capnp.Net.Runtime.Tests try { - success = resolving.WhenResolved.Wait(MediumNonDbgTimeout); + success = resolving.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout); } catch { @@ -1115,15 +1128,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void EmbargoNullClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:EmbargoNull", stdout => + LaunchCompatTestProcess("client:EmbargoNull", addr, port, stdout => { AssertOutput(stdout, "EmbargoNull test start"); AssertOutput(stdout, "EmbargoNull test end"); @@ -1131,19 +1145,20 @@ namespace Capnp.Net.Runtime.Tests } } - [TestMethod, Timeout(10000)] + [TestMethod] public void CallBrokenPromiseServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); using (var main = client.GetMain()) { var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(resolving.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); var tcs = new TaskCompletionSource(); @@ -1168,15 +1183,16 @@ namespace Capnp.Net.Runtime.Tests }); } - [TestMethod, Timeout(10000)] + [TestMethod] public void CallBrokenPromiseClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:CallBrokenPromise", stdout => + LaunchCompatTestProcess("client:CallBrokenPromise", addr, port, stdout => { AssertOutput(stdout, "CallBrokenPromise test start"); AssertOutput(stdout, "CallBrokenPromise test end"); diff --git a/Capnp.Net.Runtime.Tests/TcpRpcPorted.cs b/Capnp.Net.Runtime.Tests/TcpRpcPorted.cs index db6a450..5dd9132 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcPorted.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcPorted.cs @@ -12,105 +12,27 @@ using Microsoft.Extensions.Logging; namespace Capnp.Net.Runtime.Tests { + [TestClass] + [TestCategory("Coverage")] public class TcpRpcPorted: TestBase { [TestMethod] public void Basic() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - server.Main = new TestInterfaceImpl(counters); - using (var main = client.GetMain()) - { - var request1 = main.Foo(123, true, default); - var request3 = Assert.ThrowsExceptionAsync(() => main.Bar(default)); - var s = new TestAllTypes(); - Common.InitTestMessage(s); - var request2 = main.Baz(s, default); - - Assert.IsTrue(request1.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(request2.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(request3.Wait(MediumNonDbgTimeout)); - - Assert.AreEqual("foo", request1.Result); - Assert.AreEqual(2, counters.CallCount); - } - } + NewLocalhostTcpTestbed().RunTest(Testsuite.Basic); } [TestMethod] public void Pipeline() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - server.Main = new TestPipelineImpl(counters); - using (var main = client.GetMain()) - { - var chainedCallCount = new Counters(); - var request = main.GetCap(234, new TestInterfaceImpl(chainedCallCount), default); - using (var outBox = request.OutBox_Cap()) - { - var pipelineRequest = outBox.Foo(321, false, default); - var pipelineRequest2 = ((Proxy)outBox).Cast(false).Grault(default); - - Assert.IsTrue(pipelineRequest.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(pipelineRequest2.Wait(MediumNonDbgTimeout)); - - Assert.AreEqual("bar", pipelineRequest.Result); - Common.CheckTestMessage(pipelineRequest2.Result); - - Assert.AreEqual(3, counters.CallCount); - Assert.AreEqual(1, chainedCallCount.CallCount); - } - } - - } + NewLocalhostTcpTestbed(TcpRpcTestOptions.ClientTracer).RunTest(Testsuite.Pipeline); } [TestMethod] public void Release() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - server.Main = new TestMoreStuffImpl(counters); - using (var main = client.GetMain()) - { - var task1 = main.GetHandle(default); - var task2 = main.GetHandle(default); - Assert.IsTrue(task1.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(task2.Wait(MediumNonDbgTimeout)); - - Assert.AreEqual(2, counters.HandleCount); - - task1.Result.Dispose(); - - Assert.IsTrue(SpinWait.SpinUntil(() => counters.HandleCount == 1, MediumNonDbgTimeout)); - - task2.Result.Dispose(); - - Assert.IsTrue(SpinWait.SpinUntil(() => counters.HandleCount == 0, MediumNonDbgTimeout)); - } - - } + NewLocalhostTcpTestbed().RunTest(Testsuite.Release); } [TestMethod] @@ -121,13 +43,13 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); using (var main = client.GetMain()) { - ((Proxy)main).WhenResolved.Wait(MediumNonDbgTimeout); + ((Proxy)main).WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout); // Since we have a threaded model, there is no way to deterministically provoke the situation // where Cancel and Finish message cross paths. Instead, we'll do a lot of such requests and @@ -159,482 +81,108 @@ namespace Capnp.Net.Runtime.Tests } [TestMethod] - public void TestTailCall() + public void TailCall() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - server.Main = new TestTailCallerImpl(counters); - using (var main = client.GetMain()) - { - var calleeCallCount = new Counters(); - var callee = new TestTailCalleeImpl(calleeCallCount); - - var promise = main.Foo(456, callee, default); - var dependentCall0 = promise.C().GetCallSequence(0, default); - - Assert.IsTrue(promise.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(456u, promise.Result.I); - Assert.AreEqual("from TestTailCaller", promise.Result.T); - - var dependentCall1 = promise.C().GetCallSequence(0, default); - var dependentCall2 = promise.C().GetCallSequence(0, default); - - Assert.IsTrue(dependentCall0.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(dependentCall1.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(dependentCall2.Wait(MediumNonDbgTimeout)); - - Assert.AreEqual(1, counters.CallCount); - Assert.AreEqual(1, calleeCallCount.CallCount); - } - } + NewLocalhostTcpTestbed().RunTest(Testsuite.TailCall); } [TestMethod] public void Cancelation() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - server.Main = new TestMoreStuffImpl(counters); - using (var main = client.GetMain()) - { - var destroyed = new TaskCompletionSource(); - var impl = new TestInterfaceImpl(counters, destroyed); - var cts = new CancellationTokenSource(); - var cancelTask = main.ExpectCancel(impl, cts.Token); - - Assert.IsFalse(SpinWait.SpinUntil(() => destroyed.Task.IsCompleted || cancelTask.IsCompleted, ShortTimeout)); - - cts.Cancel(); - - Assert.IsTrue(destroyed.Task.Wait(MediumNonDbgTimeout)); - Assert.IsFalse(cancelTask.IsCompleted && !cancelTask.IsCanceled); - } - - } + NewLocalhostTcpTestbed().RunTest(Testsuite.Cancelation); } [TestMethod] public void PromiseResolve() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - var impl = new TestMoreStuffImpl(counters); - server.Main = impl; - using (var main = client.GetMain()) - { - var tcs = new TaskCompletionSource(); - var eager = tcs.Task.Eager(true); - - var request = main.CallFoo(eager, default); - var request2 = main.CallFooWhenResolved(eager, default); - - var gcs = main.GetCallSequence(0, default); - Assert.IsTrue(gcs.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(2u, gcs.Result); - Assert.AreEqual(3, counters.CallCount); - - var chainedCallCount = new Counters(); - var tiimpl = new TestInterfaceImpl(chainedCallCount); - tcs.SetResult(tiimpl); - - Assert.IsTrue(request.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(request2.Wait(MediumNonDbgTimeout)); - - Assert.AreEqual("bar", request.Result); - Assert.AreEqual("bar", request2.Result); - Assert.AreEqual(3, counters.CallCount); - Assert.AreEqual(2, chainedCallCount.CallCount); - } - - } + NewLocalhostTcpTestbed().RunTest(Testsuite.PromiseResolve); } [TestMethod] public void RetainAndRelease() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var destructionPromise = new TaskCompletionSource(); - var destructionTask = destructionPromise.Task; - - var counters = new Counters(); - var impl = new TestMoreStuffImpl(counters); - server.Main = impl; - using (var main = client.GetMain()) - { - var holdTask = main.Hold(new TestInterfaceImpl(new Counters(), destructionPromise), default); - Assert.IsTrue(holdTask.Wait(MediumNonDbgTimeout)); - - var cstask = main.GetCallSequence(0, default); - Assert.IsTrue(cstask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(1u, cstask.Result); - - Assert.IsFalse(destructionTask.IsCompleted); - - var htask = main.CallHeld(default); - Assert.IsTrue(htask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual("bar", htask.Result); - - var gtask = main.GetHeld(default); - Assert.IsTrue(gtask.Wait(MediumNonDbgTimeout)); - // We can get the cap back from it. - using (var cap = gtask.Result) - { - // Wait for balanced state - WaitClientServerIdle(server, client); - - // And call it, without any network communications. - long oldSendCount = client.SendCount; - var ftask = cap.Foo(123, true, default); - Assert.IsTrue(ftask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual("foo", ftask.Result); - Assert.AreEqual(oldSendCount, client.SendCount); - - // We can send another copy of the same cap to another method, and it works. - var ctask = main.CallFoo(cap, default); - Assert.IsTrue(ctask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual("bar", ctask.Result); - - // Give some time to settle. - cstask = main.GetCallSequence(0, default); - Assert.IsTrue(cstask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(5u, cstask.Result); - cstask = main.GetCallSequence(0, default); - Assert.IsTrue(cstask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(6u, cstask.Result); - cstask = main.GetCallSequence(0, default); - Assert.IsTrue(cstask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(7u, cstask.Result); - - // Can't be destroyed, we haven't released it. - Assert.IsFalse(destructionTask.IsCompleted); - } - - // In deviation from original test, we have null the held capability on the main interface. - // This is because the main interface is the bootstrap capability and, as such, won't be disposed - // after disconnect. - var holdNullTask = main.Hold(null, default); - Assert.IsTrue(holdNullTask.Wait(MediumNonDbgTimeout)); - } - - Assert.IsTrue(destructionTask.Wait(MediumNonDbgTimeout)); - } + NewLocalhostTcpTestbed().RunTest(Testsuite.RetainAndRelease); } [TestMethod] public void Cancel() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var destructionPromise = new TaskCompletionSource(); - var destructionTask = destructionPromise.Task; - - var counters = new Counters(); - var impl = new TestMoreStuffImpl(counters); - server.Main = impl; - using (var main = client.GetMain()) - using (var cts = new CancellationTokenSource()) - { - var ntask = main.NeverReturn(new TestInterfaceImpl(counters, destructionPromise), cts.Token); - - // Allow some time to settle. - var cstask = main.GetCallSequence(0, default); - Assert.IsTrue(cstask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(1u, cstask.Result); - cstask = main.GetCallSequence(0, default); - Assert.IsTrue(cstask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(2u, cstask.Result); - - // The cap shouldn't have been destroyed yet because the call never returned. - Assert.IsFalse(destructionTask.IsCompleted); - - // There will be no automatic cancellation just because "ntask" goes of of scope or - // because the Proxy is disposed. Even ntask.Dispose() would not cancel the request. - // In .NET this needs to be done explicitly. - cts.Cancel(); - } - - // Now the cap should be released. - Assert.IsTrue(destructionTask.Wait(MediumNonDbgTimeout)); - } + NewLocalhostTcpTestbed().RunTest(Testsuite.Cancel); } [TestMethod] public void SendTwice() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var destructionPromise = new TaskCompletionSource(); - var destructionTask = destructionPromise.Task; - - var counters = new Counters(); - var impl = new TestMoreStuffImpl(counters); - server.Main = impl; - using (var main = client.GetMain()) - { - var cap = new TestInterfaceImpl(new Counters(), destructionPromise); - - Task ftask1, ftask2; - - using (Skeleton.Claim(cap)) - { - var ftask = main.CallFoo(cap, default); - Assert.IsTrue(ftask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual("bar", ftask.Result); - - var ctask = main.GetCallSequence(0, default); - Assert.IsTrue(ctask.Wait(MediumNonDbgTimeout)); - Assert.AreEqual(1u, ctask.Result); - - ftask1 = main.CallFoo(cap, default); - ftask2 = main.CallFoo(cap, default); - } - - Assert.IsTrue(ftask1.Wait(MediumNonDbgTimeout)); - Assert.AreEqual("bar", ftask1.Result); - Assert.IsTrue(ftask2.Wait(MediumNonDbgTimeout)); - Assert.AreEqual("bar", ftask2.Result); - - // Now the cap should be released. - Assert.IsTrue(destructionTask.Wait(MediumNonDbgTimeout)); - } - } + NewLocalhostTcpTestbed().RunTest(Testsuite.SendTwice); } [TestMethod] public void Embargo() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - var impl = new TestMoreStuffImpl(counters); - server.Main = impl; - using (var main = client.GetMain()) - { - var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumNonDbgTimeout)); - - var cap = new TestCallOrderImpl(); - cap.CountToDispose = 6; - - var earlyCall = main.GetCallSequence(0, default); - - var echo = main.Echo(cap, default); - - using (var pipeline = echo.Eager()) - { - var call0 = pipeline.GetCallSequence(0, default); - var call1 = pipeline.GetCallSequence(1, default); - - Assert.IsTrue(earlyCall.Wait(MediumNonDbgTimeout)); - - impl.EnableEcho(); - - var call2 = pipeline.GetCallSequence(2, default); - - Assert.IsTrue(echo.Wait(MediumNonDbgTimeout)); - using (var resolved = echo.Result) - { - var call3 = pipeline.GetCallSequence(3, default); - var call4 = pipeline.GetCallSequence(4, default); - var call5 = pipeline.GetCallSequence(5, default); - - try - { - bool flag = call0.Wait(MediumNonDbgTimeout); - Assert.IsTrue(flag); - } - catch (AggregateException exception) when (exception.InnerException is RpcException rpcException && rpcException.Message == "Cannot access a disposed object.") - { - Console.WriteLine($"Oops, object disposed. Counter = {cap.Count}, tx count = {client.SendCount}, rx count = {client.RecvCount}"); - throw; - } - - Assert.IsTrue(call1.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(call2.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(call3.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(call4.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(call5.Wait(MediumNonDbgTimeout)); - - Assert.AreEqual(0u, call0.Result); - Assert.AreEqual(1u, call1.Result); - Assert.AreEqual(2u, call2.Result); - Assert.AreEqual(3u, call3.Result); - Assert.AreEqual(4u, call4.Result); - Assert.AreEqual(5u, call5.Result); - } - } - } - } + NewLocalhostTcpTestbed().RunTest(Testsuite.EmbargoOnPromisedAnswer); } [TestMethod] public void EmbargoError() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - var impl = new TestMoreStuffImpl(counters); - server.Main = impl; - using (var main = client.GetMain()) - { - var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumNonDbgTimeout)); - - var cap = new TaskCompletionSource(); - - var earlyCall = main.GetCallSequence(0, default); - - var echo = main.Echo(cap.Task.Eager(true), default); - - var pipeline = echo.Eager(); - - var call0 = pipeline.GetCallSequence(0, default); - var call1 = pipeline.GetCallSequence(1, default); - - Assert.IsTrue(earlyCall.Wait(MediumNonDbgTimeout)); - - impl.EnableEcho(); - - var call2 = pipeline.GetCallSequence(2, default); - - Assert.IsTrue(echo.Wait(MediumNonDbgTimeout)); - var resolved = echo.Result; - - var call3 = pipeline.GetCallSequence(3, default); - var call4 = pipeline.GetCallSequence(4, default); - var call5 = pipeline.GetCallSequence(5, default); - - cap.SetException(new InvalidOperationException("I'm annoying")); - - ExpectPromiseThrows(call0); - ExpectPromiseThrows(call1); - ExpectPromiseThrows(call2); - ExpectPromiseThrows(call3); - ExpectPromiseThrows(call4); - ExpectPromiseThrows(call5); - - // Verify that we're still connected (there were no protocol errors). - Assert.IsTrue(main.GetCallSequence(1, default).Wait(MediumNonDbgTimeout)); - } - } + NewLocalhostTcpTestbed().RunTest(Testsuite.EmbargoError); } [TestMethod] public void EmbargoNull() { - (var server, var client) = SetupClientServerPair(); - - using (server) - using (client) - { - client.WhenConnected.Wait(); - - var counters = new Counters(); - var impl = new TestMoreStuffImpl(counters); - server.Main = impl; - using (var main = client.GetMain()) - { - var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumNonDbgTimeout)); - - var promise = main.GetNull(default); - - var cap = promise.Eager(); - - var call0 = cap.GetCallSequence(0, default); - - Assert.IsTrue(promise.Wait(MediumNonDbgTimeout)); - - var call1 = cap.GetCallSequence(1, default); - - ExpectPromiseThrows(call0); - ExpectPromiseThrows(call1); - - // Verify that we're still connected (there were no protocol errors). - Assert.IsTrue(main.GetCallSequence(1, default).Wait(MediumNonDbgTimeout)); - } - } + NewLocalhostTcpTestbed().RunTest(Testsuite.EmbargoNull); } [TestMethod] public void CallBrokenPromise() + { + NewLocalhostTcpTestbed().RunTest(Testsuite.CallBrokenPromise); + } + + [TestMethod] + public void BootstrapReuse() { (var server, var client) = SetupClientServerPair(); + var counters = new Counters(); + var impl = new TestInterfaceImpl(counters); + using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); - var counters = new Counters(); - var impl = new TestMoreStuffImpl(counters); server.Main = impl; - using (var main = client.GetMain()) + for (int i = 0; i < 10; i++) { - var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumNonDbgTimeout)); - - var tcs = new TaskCompletionSource(); - - var req = main.Hold(tcs.Task.Eager(true), default); - Assert.IsTrue(req.Wait(MediumNonDbgTimeout)); - - var req2 = main.CallHeld(default); - - Assert.IsFalse(req2.Wait(ShortTimeout)); - - tcs.SetException(new InvalidOperationException("I'm a promise-breaker!")); - - ExpectPromiseThrows(req2); - - // Verify that we're still connected (there were no protocol errors). - Assert.IsTrue(main.GetCallSequence(1, default).Wait(MediumNonDbgTimeout)); + using (var main = client.GetMain()) + { + ((Proxy)main).WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout); + } + Assert.IsFalse(impl.IsDisposed); } } + + Assert.IsTrue(impl.IsDisposed); + } + + [TestMethod] + public void Ownership1() + { + NewLocalhostTcpTestbed().RunTest(Testsuite.Ownership1); + } + + [TestMethod] + public void Ownership2() + { + NewLocalhostTcpTestbed().RunTest(Testsuite.Ownership2); + } + + [TestMethod] + public void Ownership3() + { + NewLocalhostTcpTestbed().RunTest(Testsuite.Ownership3); } } } diff --git a/Capnp.Net.Runtime.Tests/TcpRpcStress.cs b/Capnp.Net.Runtime.Tests/TcpRpcStress.cs index fd41551..2610677 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcStress.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcStress.cs @@ -1,4 +1,5 @@ using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Net.Runtime.Tests.Util; using Capnp.Rpc; using Capnproto_test.Capnp.Test; using Microsoft.Extensions.Logging; @@ -6,6 +7,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Net; +using System.Net.Sockets; using System.Text; using System.Threading; @@ -19,7 +21,6 @@ namespace Capnp.Net.Runtime.Tests for (int i = 0; i < count; i++) { Logger.LogTrace("Repetition {0}", i); - IncrementTcpPort(); action(); } } @@ -34,7 +35,7 @@ namespace Capnp.Net.Runtime.Tests using (server) using (client) { - client.WhenConnected.Wait(); + //client.WhenConnected.Wait(); var counters = new Counters(); var impl = new TestMoreStuffImpl(counters); @@ -42,7 +43,7 @@ namespace Capnp.Net.Runtime.Tests using (var main = client.GetMain()) { var resolving = main as IResolvingCapability; - Assert.IsTrue(resolving.WhenResolved.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(resolving.WhenResolved.WrappedTask.Wait(MediumNonDbgTimeout)); } } }); @@ -59,10 +60,17 @@ namespace Capnp.Net.Runtime.Tests public void Embargo() { var t = new TcpRpcPorted(); - Repeat(100, t.Embargo); + Repeat(100, + () => + NewLocalhostTcpTestbed(TcpRpcTestOptions.ClientTracer | TcpRpcTestOptions.ClientFluctStream) + .RunTest(Testsuite.EmbargoOnPromisedAnswer)); + } + [TestMethod] + public void EmbargoServer() + { var t2 = new TcpRpcInterop(); - Repeat(100, t2.EmbargoServer); + Repeat(20, t2.EmbargoServer); } [TestMethod] @@ -94,14 +102,15 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void ScatteredTransfer() { + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); - using (var server = new TcpRpcServer(IPAddress.Any, TcpPort)) + using (var server = new TcpRpcServer(addr, port)) using (var client = new TcpRpcClient()) { server.InjectMidlayer(s => new ScatteringStream(s, 7)); client.InjectMidlayer(s => new ScatteringStream(s, 10)); - client.Connect("localhost", TcpPort); - client.WhenConnected.Wait(); + client.Connect(addr.ToString(), port); + //client.WhenConnected.Wait(); var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); diff --git a/Capnp.Net.Runtime.Tests/TestBase.cs b/Capnp.Net.Runtime.Tests/TestBase.cs deleted file mode 100644 index 3eb33fd..0000000 --- a/Capnp.Net.Runtime.Tests/TestBase.cs +++ /dev/null @@ -1,130 +0,0 @@ -using Capnp.Rpc; -using Microsoft.Extensions.Logging; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Capnp.Net.Runtime.Tests -{ - public class TestBase - { - public static int TcpPort = 49152; - public static int MediumNonDbgTimeout => Debugger.IsAttached ? Timeout.Infinite : 5000; - public static int LargeNonDbgTimeout => Debugger.IsAttached ? Timeout.Infinite : 20000; - public static int ShortTimeout => 500; - - protected ILogger Logger { get; set; } - - protected TcpRpcClient SetupClient() - { - var client = new TcpRpcClient(); - client.AddBuffering(); - client.Connect("localhost", TcpPort); - return client; - } - - protected TcpRpcServer SetupServer() - { - int attempt = 0; - - while (true) - { - try - { - var server = new TcpRpcServer(IPAddress.Any, TcpPort); - server.AddBuffering(); - return server; - } - catch (SocketException) - { - // If the TCP listening port is occupied by some other process, - // retry with a different one - - if (attempt == 5) - throw; - } - - IncrementTcpPort(); - ++attempt; - } - } - - protected (TcpRpcServer, TcpRpcClient) SetupClientServerPair() - { - var server = SetupServer(); - var client = SetupClient(); - return (server, client); - } - - public static void IncrementTcpPort() - { - if (++TcpPort > 49200) - { - TcpPort = 49152; - } - } - - [TestInitialize] - public void InitConsoleLogging() - { - Logging.LoggerFactory?.Dispose(); - Logging.LoggerFactory = new LoggerFactory().AddConsole((msg, level) => true); - Logger = Logging.CreateLogger(); - if (Thread.CurrentThread.Name == null) - Thread.CurrentThread.Name = $"Test Thread {Thread.CurrentThread.ManagedThreadId}"; - } - - /// - /// Somewhat ugly helper method which ensures that both Tcp client and server - /// are waiting for data reception from each other. This is a "balanced" state, meaning - /// that nothing will ever happen in the RcpEngines without some other thread requesting - /// anything. - /// - protected void WaitClientServerIdle(TcpRpcServer server, TcpRpcClient client) - { - var conn = server.Connections[0]; - SpinWait.SpinUntil(() => conn.IsWaitingForData && client.IsWaitingForData && - conn.RecvCount == client.SendCount && - conn.SendCount == client.RecvCount, - MediumNonDbgTimeout); - } - - protected void ExpectPromiseThrows(Task task) - { - async Task ExpectPromiseThrowsAsync(Task t) - { - try - { - await t; - Assert.Fail("Did not throw"); - } - catch (InvalidOperationException) - { - // Happens if the call went to the resolution - // (thus, locally). In this case, the original - // exception is routed here. - } - catch (RpcException) - { - // Happens if the call went to the promise - // (thus, remotely). In this case, the original - // exception had to be serialized, so we receive - // the wrapped version. - } - catch (System.Exception exception) - { - Assert.Fail($"Got wrong kind of exception: {exception}"); - } - } - - Assert.IsTrue(ExpectPromiseThrowsAsync(task).Wait(MediumNonDbgTimeout)); - } - - } -} diff --git a/Capnp.Net.Runtime.Tests/TestInterfaces.cs b/Capnp.Net.Runtime.Tests/TestInterfaces.cs deleted file mode 100644 index 3d22d54..0000000 --- a/Capnp.Net.Runtime.Tests/TestInterfaces.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Capnp.Rpc; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Capnp.Net.Runtime.Tests.ManualImpls -{ - // [Skeleton(typeof(TestInterfaceSkeleton))] - // [Proxy(typeof(TestInterfaceProxy))] - // interface ITestInterface: IDisposable - // { - // Task Foo(uint i, bool j); - // Task Bar(); - // Task Baz(int s); - // } - - // [Skeleton(typeof(TestExtendsSkeleton))] - // [Proxy(typeof(TestExtendsProxy))] - // interface ITestExtends: ITestInterface, IDisposable - // { - // void Qux(); - // Task Corge(int x); - // Task Grault(); - // } - - // interface ITestExtends2: ITestExtends, IDisposable - // { - // } - - // struct Box - // { - // public ITestExtends Cap { get; set; } - // } - - // struct AnyBox - // { - // public object Cap { get; set; } - // } - - // [Skeleton(typeof(TestPipelineSkeleton))] - // [Proxy(typeof(TestPipelineProxy))] - // interface ITestPipeline: IDisposable - // { - // Task<(string, Box)> GetCap(uint n, ITestInterface inCap); - // Task TestPointers(ITestExtends cap, DeserializerState obj, IReadOnlyList list); - // Task<(string, AnyBox)> GetAnyCap(uint n, object inCap); - // } - - // [Skeleton(typeof(TestCallOrderSkeleton))] - // [Proxy(typeof(TestCallOrderProxy))] - // interface ITestCallOrder : IDisposable - // { - // Task GetCallSequence(uint expected); - // } - - // struct TailResult - // { - // public uint I { get; set; } - // public string T { get; set; } - // public ITestCallOrder C { get; set; } - //} - - // [Skeleton(typeof(TestTailCalleeSkeleton))] - // [Proxy(typeof(TestTailCalleeProxy))] - // interface ITestTailCallee: IDisposable - // { - // Task Foo(int i, string t); - // } - - // [Skeleton(typeof(TestTailCallerSkeleton))] - // [Proxy(typeof(TestTailCallerProxy))] - // interface ITestTailCaller: IDisposable - // { - // Task Foo(int i, ITestTailCallee c); - // } - - // [Skeleton(typeof(TestHandleSkeleton))] - // [Proxy(typeof(TestHandleProxy))] - // interface ITestHandle: IDisposable { } - - - // [Skeleton(typeof(TestMoreStuffSkeleton))] - // [Proxy(typeof(TestMoreStuffProxy))] - // interface ITestMoreStuff: ITestCallOrder - // { - // Task CallFoo(ITestInterface cap); - // Task CallFooWhenResolved(ITestInterface cap); - // Task NeverReturn(ITestInterface cap, CancellationToken ct); - // Task Hold(ITestInterface cap); - // Task CallHeld(); - // Task GetHeld(); - // Task Echo(ITestCallOrder cap); - // Task ExpectCancel(ITestInterface cap, CancellationToken ct); - // Task<(string, string)> MethodWithDefaults(string a, uint b, string c); - // void MethodWithNullDefault(string a, ITestInterface b); - // Task GetHandle(); - // Task GetNull(); - // Task GetEnormousString(); - // } -} - diff --git a/Capnp.Net.Runtime.Tests/Testsuite.cs b/Capnp.Net.Runtime.Tests/Testsuite.cs new file mode 100644 index 0000000..5240f1d --- /dev/null +++ b/Capnp.Net.Runtime.Tests/Testsuite.cs @@ -0,0 +1,870 @@ +using System; +using System.Linq; +using Capnp.Rpc; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Capnp.Net.Runtime.Tests.GenImpls; +using Capnproto_test.Capnp.Test; +using System.Threading.Tasks; +using System.Threading; +using System.Runtime.CompilerServices; + +namespace Capnp.Net.Runtime.Tests +{ + static class Testsuite + { + static void ExpectPromiseThrows(this ITestbed testbed, params Task[] tasks) + { + async Task ExpectPromiseThrowsAsync(Task t) + { + try + { + await t; + Assert.Fail("Did not throw"); + } + catch (InvalidOperationException) + { + // Happens if the call went to the resolution + // (thus, locally). In this case, the original + // exception is routed here. + } + catch (InvalidTimeZoneException) + { + // Happens if the call went to the resolution + // (thus, locally). In this case, the original + // exception is routed here. + } + catch (RpcException) + { + // Happens if the call went to the promise + // (thus, remotely). In this case, the original + // exception had to be serialized, so we receive + // the wrapped version. + } + catch (TaskCanceledException) + { + // Also used in some test + } + catch (System.Exception exception) + { + Assert.Fail($"Got wrong kind of exception: {exception}"); + } + } + + var ftasks = tasks.Select(ExpectPromiseThrowsAsync).ToArray(); + testbed.MustComplete(ftasks); + + foreach (var ftask in ftasks) + ftask.GetAwaiter().GetResult(); // re-throw exception + } + + public static void EmbargoOnPromisedAnswer(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + + using (var main = testbed.ConnectMain(impl)) + { + if (main is IResolvingCapability resolving) + testbed.MustComplete(resolving.WhenResolved.WrappedTask); + + var cap = new TestCallOrderImpl(); + cap.CountToDispose = 6; + + var earlyCall = main.GetCallSequence(0, default); + + var echo = main.Echo(cap, default); + testbed.MustComplete(Task.CompletedTask); + using (var pipeline = echo.Eager(true)) + { + var call0 = pipeline.GetCallSequence(0, default); + var call1 = pipeline.GetCallSequence(1, default); + + testbed.MustComplete(earlyCall); + + impl.EnableEcho(); + + var call2 = pipeline.GetCallSequence(2, default); + + testbed.MustComplete(echo); + using (var resolved = echo.Result) + { + var call3 = pipeline.GetCallSequence(3, default); + var call4 = pipeline.GetCallSequence(4, default); + var call5 = pipeline.GetCallSequence(5, default); + + testbed.MustComplete(call0); + testbed.MustComplete(call1); + testbed.MustComplete(call2); + testbed.MustComplete(call3); + testbed.MustComplete(call4); + testbed.MustComplete(call5); + + Assert.AreEqual(0u, call0.Result); + Assert.AreEqual(1u, call1.Result); + Assert.AreEqual(2u, call2.Result); + Assert.AreEqual(3u, call3.Result); + Assert.AreEqual(4u, call4.Result); + Assert.AreEqual(5u, call5.Result); + Assert.AreEqual(cap.Count, cap.CountToDispose, "counter must have reached number of calls"); + } + } + } + } + + public static void EmbargoOnImportedCap(ITestbed testbed) + { + var impl = new TestMoreStuffImpl2(); + + using (var main = testbed.ConnectMain(impl)) + { + var cap = new TestCallOrderImpl(); + cap.CountToDispose = 6; + + var earlyCall = main.GetCallSequence(0, default); + + var echo = main.Echo(cap, default); + testbed.MustComplete(echo); + using (var pipeline = echo.Result) + { + var call0 = pipeline.GetCallSequence(0, default); + var call1 = pipeline.GetCallSequence(1, default); + + testbed.MustComplete(earlyCall); + + impl.EnableEcho(); + + var call2 = pipeline.GetCallSequence(2, default); + + testbed.MustComplete(echo); + using (var resolved = echo.Result) + { + var call3 = pipeline.GetCallSequence(3, default); + var call4 = pipeline.GetCallSequence(4, default); + var call5 = pipeline.GetCallSequence(5, default); + + try + { + testbed.MustComplete(call0); + testbed.MustComplete(call1); + testbed.MustComplete(call2); + testbed.MustComplete(call3); + testbed.MustComplete(call4); + testbed.MustComplete(call5); + } + catch (System.Exception) + { + cap.CountToDispose = null; + throw; + } + + Assert.AreEqual(0u, call0.Result); + Assert.AreEqual(1u, call1.Result); + Assert.AreEqual(2u, call2.Result); + Assert.AreEqual(3u, call3.Result); + Assert.AreEqual(4u, call4.Result); + Assert.AreEqual(5u, call5.Result); + } + } + } + } + + public static void EmbargoError(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + if (main is IResolvingCapability resolving) + testbed.MustComplete(resolving.WhenResolved.WrappedTask); + + var cap = new TaskCompletionSource(); + + var earlyCall = main.GetCallSequence(0, default); + var echo = main.Echo(cap.Task.Eager(true), default); + + using (var pipeline = echo.Eager(true)) + { + var call0 = pipeline.GetCallSequence(0, default); + var call1 = pipeline.GetCallSequence(1, default); + + testbed.MustComplete(earlyCall); + + impl.EnableEcho(); + + var call2 = pipeline.GetCallSequence(2, default); + + testbed.MustComplete(echo); + var resolved = echo.Result; + var call3 = pipeline.GetCallSequence(3, default); + var call4 = pipeline.GetCallSequence(4, default); + var call5 = pipeline.GetCallSequence(5, default); + + cap.SetException(new InvalidTimeZoneException("I'm annoying")); + + testbed.ExpectPromiseThrows(call0, call1, call2, call3, call4, call5); + + // Verify that we're still connected (there were no protocol errors). + testbed.MustComplete(main.GetCallSequence(1, default)); + } + } + } + + public static void EmbargoNull(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + if (main is IResolvingCapability resolving) + testbed.MustComplete(resolving.WhenResolved.WrappedTask); + + var promise = main.GetNull(default); + + using (var cap = promise.Eager(true)) + { + var call0 = cap.GetCallSequence(0, default); + + testbed.MustComplete(promise); + + var call1 = cap.GetCallSequence(1, default); + + testbed.ExpectPromiseThrows(call0, call1); + } + + // Verify that we're still connected (there were no protocol errors). + testbed.MustComplete(main.GetCallSequence(1, default)); + } + } + + public static void CallBrokenPromise(ITestbed testbed) + { + var counters = new Counters(); + using (var impl = new TestMoreStuffImpl(counters)) + using (var main = testbed.ConnectMain(impl)) + { + if (main is IResolvingCapability resolving) + testbed.MustComplete(resolving.WhenResolved.WrappedTask); + + var tcs = new TaskCompletionSource(); + + var req = main.Hold(tcs.Task.Eager(true), default); + testbed.MustComplete(req); + + var req2 = main.CallHeld(default); + + testbed.MustNotComplete(req2); + + tcs.SetException(new InvalidOperationException("I'm a promise-breaker!")); + + testbed.ExpectPromiseThrows(req2); + + // Verify that we're still connected (there were no protocol errors). + testbed.MustComplete(main.GetCallSequence(1, default)); + } + } + + public static void TailCall(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestTailCallerImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var calleeCallCount = new Counters(); + var callee = new TestTailCalleeImpl(calleeCallCount); + + var promise = main.Foo(456, callee, default); + using (var c = promise.C()) + { + var dependentCall0 = c.GetCallSequence(0, default); + + testbed.MustComplete(promise); + Assert.AreEqual(456u, promise.Result.I); + Assert.AreEqual("from TestTailCaller", promise.Result.T); + + var dependentCall1 = c.GetCallSequence(0, default); + var dependentCall2 = c.GetCallSequence(0, default); + + testbed.MustComplete(dependentCall0, dependentCall1, dependentCall2); + + Assert.IsTrue(callee.IsDisposed); + Assert.AreEqual(1, counters.CallCount); + Assert.AreEqual(1, calleeCallCount.CallCount); + } + } + } + + public static void SendTwice(ITestbed testbed) + { + var destructionPromise = new TaskCompletionSource(); + var destructionTask = destructionPromise.Task; + + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var cap = new TestInterfaceImpl(new Counters(), destructionPromise); + + Task ftask1, ftask2; + + using (var claimer = Skeleton.Claim(cap)) + { + var ftask = main.CallFoo(Proxy.Share(cap), default); + testbed.MustComplete(ftask); + Assert.AreEqual("bar", ftask.Result); + + var ctask = main.GetCallSequence(0, default); + testbed.MustComplete(ctask); + Assert.AreEqual(1u, ctask.Result); + + ftask1 = main.CallFoo(Proxy.Share(cap), default); + ftask2 = main.CallFoo(Proxy.Share(cap), default); + } + + testbed.MustComplete(ftask1); + Assert.AreEqual("bar", ftask1.Result); + testbed.MustComplete(ftask2); + Assert.AreEqual("bar", ftask2.Result); + + // Now the cap should be released. + testbed.MustComplete(destructionTask); + } + } + + public static void Cancel(ITestbed testbed) + { + var destructionPromise = new TaskCompletionSource(); + var destructionTask = destructionPromise.Task; + + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + using (var cts = new CancellationTokenSource()) + { + var ntask = main.NeverReturn(new TestInterfaceImpl(counters, destructionPromise), cts.Token); + + // Allow some time to settle. + var cstask = main.GetCallSequence(0, default); + testbed.MustComplete(cstask); + Assert.AreEqual(1u, cstask.Result); + cstask = main.GetCallSequence(0, default); + testbed.MustComplete(cstask); + Assert.AreEqual(2u, cstask.Result); + + // The cap shouldn't have been destroyed yet because the call never returned. + Assert.IsFalse(destructionTask.IsCompleted); + + // There will be no automatic cancellation just because "ntask" goes of of scope or + // because the Proxy is disposed. Even ntask.Dispose() would not cancel the request. + // In .NET this needs to be done explicitly. + cts.Cancel(); + } + + // Now the cap should be released. + testbed.MustComplete(destructionTask); + } + + public static void RetainAndRelease(ITestbed testbed) + { + var destructionPromise = new TaskCompletionSource(); + var destructionTask = destructionPromise.Task; + + var counters = new Counters(); + using (var impl = new TestMoreStuffImpl(counters)) + using (var main = testbed.ConnectMain(impl)) + { + var holdTask = main.Hold(new TestInterfaceImpl(new Counters(), destructionPromise), default); + testbed.MustComplete(holdTask); + + var cstask = main.GetCallSequence(0, default); + testbed.MustComplete(cstask); + Assert.AreEqual(1u, cstask.Result); + + Assert.IsFalse(destructionTask.IsCompleted); + + var htask = main.CallHeld(default); + testbed.MustComplete(htask); + Assert.AreEqual("bar", htask.Result); + + var gtask = main.GetHeld(default); + testbed.MustComplete(gtask); + // We can get the cap back from it. + using (var cap = gtask.Result) + { + // Wait for balanced state + testbed.FlushCommunication(); + + // And call it, without any network communications. + long oldSendCount = testbed.ClientSendCount; + var ftask = cap.Foo(123, true, default); + testbed.MustComplete(ftask); + Assert.AreEqual("foo", ftask.Result); + Assert.AreEqual(oldSendCount, testbed.ClientSendCount); + + // We can send another copy of the same cap to another method, and it works. + // Note that this was a bug in previous versions: + // Since passing a cap has move semantics, we need to create an explicit copy. + var copy = Proxy.Share(cap); + Assert.IsFalse(((Proxy)copy).IsDisposed); + var ctask = main.CallFoo(copy, default); + Assert.IsTrue(((Proxy)copy).IsDisposed); + testbed.MustComplete(ctask); + Assert.AreEqual("bar", ctask.Result); + + // Give some time to settle. + cstask = main.GetCallSequence(0, default); + testbed.MustComplete(cstask); + Assert.AreEqual(5u, cstask.Result); + cstask = main.GetCallSequence(0, default); + testbed.MustComplete(cstask); + Assert.AreEqual(6u, cstask.Result); + cstask = main.GetCallSequence(0, default); + testbed.MustComplete(cstask); + Assert.AreEqual(7u, cstask.Result); + + // Can't be destroyed, we haven't released it. + Assert.IsFalse(destructionTask.IsCompleted); + } + } + + testbed.MustComplete(destructionTask); + } + + public static void PromiseResolve(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var tcs = new TaskCompletionSource(); + using (var eager = tcs.Task.Eager(true)) + { + var request = main.CallFoo(Proxy.Share(eager), default); + var request2 = main.CallFooWhenResolved(eager, default); + + var gcs = main.GetCallSequence(0, default); + testbed.MustComplete(gcs); + Assert.AreEqual(2u, gcs.Result); + Assert.AreEqual(3, counters.CallCount); + + var chainedCallCount = new Counters(); + var tiimpl = new TestInterfaceImpl(chainedCallCount); + tcs.SetResult(tiimpl); + + testbed.MustComplete(request, request2); + + Assert.AreEqual("bar", request.Result); + Assert.AreEqual("bar", request2.Result); + Assert.AreEqual(3, counters.CallCount); + Assert.AreEqual(2, chainedCallCount.CallCount); + } + } + } + + public static void PromiseResolveLate(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var tcs = new TaskCompletionSource(); + var disposed = new TaskCompletionSource(); + using (var eager = tcs.Task.Eager(true)) + { + var request = main.NeverReturn(Proxy.Share(eager), new CancellationToken(true)); + + testbed.MustComplete(request); + + var tiimpl = new TestInterfaceImpl(new Counters(), disposed); + tcs.SetResult(tiimpl); + + Assert.IsFalse(tiimpl.IsDisposed); + } + testbed.MustComplete(disposed.Task); + } + } + + public static void PromiseResolveError(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var tcs = new TaskCompletionSource(); + using (var eager = tcs.Task.Eager(true)) + { + var request = main.CallFoo(Proxy.Share(eager), default); + var request2 = main.CallFooWhenResolved(eager, default); + + var gcs = main.GetCallSequence(0, default); + testbed.MustComplete(gcs); + Assert.AreEqual(2u, gcs.Result); + Assert.AreEqual(3, counters.CallCount); + + tcs.SetException(new System.Exception("too bad")); + + testbed.MustComplete(request, request2); + Assert.IsTrue(request.IsFaulted); + Assert.IsTrue(request2.IsFaulted); + } + } + } + + public static void Cancelation(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var destroyed = new TaskCompletionSource(); + var impl2 = new TestInterfaceImpl(counters, destroyed); + var cts = new CancellationTokenSource(); + var cancelTask = main.ExpectCancel(impl2, cts.Token); + + testbed.MustNotComplete(destroyed.Task, cancelTask); + + cts.Cancel(); + + testbed.MustComplete(destroyed.Task); + Assert.IsFalse(cancelTask.IsCompleted && !cancelTask.IsCanceled); + } + } + + public static void ReleaseOnCancel(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + using (var cts = new CancellationTokenSource()) + { + var task = main.GetHandle(cts.Token); + testbed.MustComplete(Task.CompletedTask); // turn event loop + cts.Cancel(); + testbed.MustComplete(task); + try + { + task.Result.Dispose(); + } + catch (AggregateException ex) when (ex.InnerException is TaskCanceledException) + { + } + } + + testbed.FlushCommunication(); + Assert.AreEqual(0, counters.HandleCount); + } + } + + public static void Release(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var task1 = main.GetHandle(default); + var task2 = main.GetHandle(default); + testbed.MustComplete(task1, task2); + + Assert.AreEqual(2, counters.HandleCount); + + task1.Result.Dispose(); + + testbed.FlushCommunication(); + Assert.IsTrue(SpinWait.SpinUntil(() => counters.HandleCount == 1, TestBase.ShortTimeout)); + + task2.Result.Dispose(); + + testbed.FlushCommunication(); + Assert.IsTrue(SpinWait.SpinUntil(() => counters.HandleCount == 0, TestBase.ShortTimeout)); + } + } + + public static void Pipeline(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestPipelineImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var chainedCallCount = new Counters(); + var request = main.GetCap(234, new TestInterfaceImpl(chainedCallCount), default); + using (var outBox = request.OutBox_Cap()) + { + var pipelineRequest = outBox.Foo(321, false, default); + using (var testx = ((Proxy)outBox).Cast(false)) + { + var pipelineRequest2 = testx.Grault(default); + + testbed.MustComplete(pipelineRequest, pipelineRequest2); + + Assert.AreEqual("bar", pipelineRequest.Result); + Common.CheckTestMessage(pipelineRequest2.Result); + + Assert.AreEqual(3, counters.CallCount); + Assert.AreEqual(1, chainedCallCount.CallCount); + } + } + } + } + + public static void Basic(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestInterfaceImpl(counters); + using (var main = testbed.ConnectMain(impl)) + { + var request1 = main.Foo(123, true, default); + var request3 = Assert.ThrowsExceptionAsync(() => main.Bar(default)); + var s = new TestAllTypes(); + Common.InitTestMessage(s); + var request2 = main.Baz(s, default); + + testbed.MustComplete(request1, request2, request3); + + Assert.AreEqual("foo", request1.Result); + Assert.AreEqual(2, counters.CallCount); + } + } + + public static void BootstrapReuse(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestInterfaceImpl(counters); + for (int i = 0; i < 10; i++) + { + using (var main = testbed.ConnectMain(impl)) + { + } + Assert.IsFalse(impl.IsDisposed); + } + } + + public static void Ownership1(ITestbed testbed) + { + var impl = new TestMoreStuffImpl(new Counters()); + using (var main = testbed.ConnectMain(impl)) + { + var tcs = new TaskCompletionSource(); + var ti = new TestInterfaceImpl(new Counters(), tcs); + testbed.MustComplete(main.CallFoo(ti, default)); + testbed.MustComplete(tcs.Task); + } + } + + public static void Ownership2(ITestbed testbed) + { + var impl = new TestMoreStuffImpl(new Counters()); + using (var main = testbed.ConnectMain(impl)) + using (var nullProxy = main.GetNull().Eager(true)) + { + var tcs = new TaskCompletionSource(); + var ti = new TestInterfaceImpl(new Counters(), tcs); + testbed.MustComplete(nullProxy.CallFoo(ti, default)); + testbed.MustComplete(tcs.Task); + } + } + + public static void Ownership3(ITestbed testbed) + { + var impl = new TestMoreStuffImpl(new Counters()); + using (var main = testbed.ConnectMain(impl)) + using (var nullProxy = main.GetNull(new CancellationToken(true)).Eager(true)) + { + var tcs = new TaskCompletionSource(); + var ti = new TestInterfaceImpl(new Counters(), tcs); + testbed.MustComplete(nullProxy.CallFoo(ti, default)); + testbed.MustComplete(tcs.Task); + } + } + + class ThrowingSkeleton : RefCountingSkeleton + { + public bool WasCalled { get; private set; } + + public override Task Invoke(ulong interfaceId, ushort methodId, DeserializerState args, CancellationToken cancellationToken = default) + { + WasCalled = true; + throw new NotImplementedException(); + } + } + + public static void SillySkeleton(ITestbed testbed) + { + var impl = new ThrowingSkeleton(); + using (var main = testbed.ConnectMain(impl)) + { + var tcs = new TaskCompletionSource(); + var ti = new TestInterfaceImpl(new Counters(), tcs); + testbed.ExpectPromiseThrows(main.CallFoo(ti)); + Assert.IsTrue(impl.WasCalled); + testbed.MustComplete(tcs.Task); + } + } + + public static void ImportReceiverAnswer(ITestbed testbed) + { + var impl = new TestMoreStuffImpl2(); + using (var main = testbed.ConnectMain(impl)) + { + var held = main.GetHeld().Eager(); + var foo = main.CallFoo(held); + testbed.MustNotComplete(foo); + var tcs = new TaskCompletionSource(); + testbed.MustComplete( + main.Hold(new TestInterfaceImpl(new Counters(), tcs)), + foo, + tcs.Task); + } + } + + public static void ImportReceiverAnswerError(ITestbed testbed) + { + var impl = new TestMoreStuffImpl2(); + using (var main = testbed.ConnectMain(impl)) + using (var held = main.GetHeld().Eager()) + { + var foo = main.CallFoo(held); + testbed.MustNotComplete(foo); + var faulted = Task.FromException( + new InvalidOperationException("I faulted")).Eager(true); + testbed.MustComplete( + main.Hold(faulted), + foo); + Assert.IsTrue(foo.IsFaulted); + } + } + + public static void ImportReceiverCanceled(ITestbed testbed) + { + var impl = new TestMoreStuffImpl2(); + using (var main = testbed.ConnectMain(impl)) + using (var held = main.GetHeld().Eager()) + { + var foo = main.CallFoo(held); + testbed.MustNotComplete(foo); + var canceled = Task.FromCanceled(new CancellationToken(true)).Eager(true); + testbed.MustComplete( + main.Hold(canceled), + foo); + Assert.IsTrue(foo.IsCanceled); + } + } + + public static void ButNoTailCall(ITestbed testbed) + { + var impl = new TestMoreStuffImpl4(); + using (var main = testbed.ConnectMain(impl)) + { + var peer = new TestMoreStuffImpl5(); + var heldTask = main.Echo(peer); + + testbed.MustComplete(heldTask); + + var r = heldTask.Result as IResolvingCapability; + + peer.EnableEcho(); + + testbed.MustComplete(r.WhenResolved.WrappedTask); + + heldTask.Result.Dispose(); + } + } + + public static void SecondIsTailCall(ITestbed testbed) + { + var impl = new TestTailCallerImpl3(); + using (var main = testbed.ConnectMain(impl)) + { + var callee = new TestTailCalleeImpl(new Counters()); + var task = main.Foo(123, callee); + testbed.MustComplete(task); + Assert.AreEqual("from TestTailCaller 2", task.Result.T); + } + } + + public static void NoTailCallMt(ITestbed testbed) + { + var impl = new TestTailCallerImpl4(); + using (var main = testbed.ConnectMain(impl)) + using (var callee = Proxy.Share(new TestTailCalleeImpl(new Counters()))) + { + var tasks = ParallelEnumerable + .Range(0, 200) + .Select(async i => + { + var r = await main.Foo(i, Proxy.Share(callee)); + Assert.AreEqual((uint)i, r.I); + }) + .ToArray(); + + testbed.MustComplete(tasks); + Assert.IsFalse(tasks.Any(t => t.IsCanceled || t.IsFaulted)); + } + } + + public static void ReexportSenderPromise(ITestbed testbed) + { + var impl = new TestMoreStuffImpl(new Counters()); + using (var main = testbed.ConnectMain(impl)) + { + var tcs = new TaskCompletionSource(); + var tcsd = new TaskCompletionSource(); + using (var promise = tcs.Task.Eager(true)) + { + var task1 = main.CallFooWhenResolved(Proxy.Share(promise)); + var task2 = main.CallFooWhenResolved(Proxy.Share(promise)); + var callee = new TestInterfaceImpl(new Counters(), tcsd); + tcs.SetResult(callee); + testbed.MustComplete(task1, task2); + } + testbed.MustComplete(tcsd.Task); + } + } + + public static void CallAfterFinish1(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl3(); + using (var main = testbed.ConnectMain(impl)) + { + using (var held = main.GetHeld().Eager()) + { + testbed.CloseClient(); + testbed.ExpectPromiseThrows(held.Foo(123, true)); + } + } + } + + public static void CallAfterFinish2(ITestbed testbed) + { + var counters = new Counters(); + var impl = new TestMoreStuffImpl3(); + using (var main = testbed.ConnectMain(impl)) + { + using (var cts = new CancellationTokenSource()) + using (var held = main.GetHeld(cts.Token).Eager()) + { + cts.Cancel(); + testbed.ExpectPromiseThrows(held.Foo(123, true)); + } + } + } + + public static void LegacyAccess(ITestbed testbed) + { + var impl = new TestMoreStuffImpl(new Counters()); + using (var main = testbed.ConnectMain(impl)) + { + var task = main.Echo(new TestCallOrderImpl()); + var answer = Impatient.TryGetAnswer(task); + Assert.IsNotNull(answer); + var cap = answer.Access(new MemberAccessPath(0)); + using (var proxy = (ITestCallOrder)CapabilityReflection.CreateProxy(cap)) + { + var seq = proxy.GetCallSequence(0); + testbed.MustComplete(seq); + Assert.AreEqual(0u, seq.Result); + } + } + } + } +} diff --git a/Capnp.Net.Runtime.Tests/Util/DecisionTree.cs b/Capnp.Net.Runtime.Tests/Util/DecisionTree.cs new file mode 100644 index 0000000..038e95f --- /dev/null +++ b/Capnp.Net.Runtime.Tests/Util/DecisionTree.cs @@ -0,0 +1,98 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; + +namespace Capnp.Net.Runtime.Tests +{ + public class DecisionTree + { + readonly ILogger Logger = Logging.CreateLogger(); + + readonly List _decisions = new List(); + readonly Stack _freezeStack = new Stack(); + int _pos, _freezeCounter; + + public DecisionTree() + { + _freezeStack.Push(0); + } + + public DecisionTree(params bool[] initialDecisions): this() + { + _decisions.AddRange(initialDecisions); + } + + public bool MakeDecision() + { + if (_pos >= _decisions.Count) + { + _decisions.Add(false); + } + + try + { + return _decisions[_pos++]; + } + catch (ArgumentOutOfRangeException) + { + Logger.LogError($"WTF?! {_pos - 1}, {_decisions.Count}"); + throw; + } + } + + public void Freeze() + { + _freezeStack.Push(_pos); + } + + public bool NextRound() + { + _pos = 0; + + for (int i = 0; i < _freezeCounter; i++) + _freezeStack.Pop(); + + while (_freezeStack.Count > 1) + { + int end = _freezeStack.Pop(); + int begin = _freezeStack.Peek(); + + for (int i = end - 1; i >= begin; i--) + { + if (_decisions[i] == false) + { + _decisions[i] = true; + _freezeStack.Clear(); + _freezeStack.Push(0); + return true; + } + //else + //{ + // _decisions.RemoveAt(i); + //} + } + + ++_freezeCounter; + } + + return false; + } + + public override string ToString() + { + return "[" + string.Join("|", _decisions) + "]"; + } + + public void Iterate(Action testMethod) + { + Logger.LogInformation("Starting decision-tree based combinatorial test"); + int iter = 0; + do + { + Logger.LogInformation($"Iteration {iter}: pattern {ToString()}"); + testMethod(); + ++iter; + } while (NextRound()); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/Util/FluctStream.cs b/Capnp.Net.Runtime.Tests/Util/FluctStream.cs new file mode 100644 index 0000000..e5a9406 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/Util/FluctStream.cs @@ -0,0 +1,50 @@ +using System; +using System.IO; +using System.Threading; + +namespace Capnp.Net.Runtime.Tests +{ + class FluctStream : Stream + { + readonly Stream _baseStream; + readonly Random _rng = new Random(); + + public FluctStream(Stream baseStream) + { + _baseStream = baseStream; + } + + public override bool CanRead => _baseStream.CanRead; + + public override bool CanSeek => false; + + public override bool CanWrite => _baseStream.CanWrite; + + public override long Length => _baseStream.Length; + + public override long Position + { + get => _baseStream.Position; + set => throw new NotImplementedException(); + } + + public override void Flush() => _baseStream.Flush(); + + public override int Read(byte[] buffer, int offset, int count) + { + int n = _rng.Next(0, 8); + if (n >= 7) + Thread.Sleep(n - 7); + return _baseStream.Read(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException(); + + public override void SetLength(long value) => throw new NotImplementedException(); + + public override void Write(byte[] buffer, int offset, int count) + { + _baseStream.Write(buffer, offset, count); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/JobUtil.cs b/Capnp.Net.Runtime.Tests/Util/JobUtil.cs similarity index 100% rename from Capnp.Net.Runtime.Tests/JobUtil.cs rename to Capnp.Net.Runtime.Tests/Util/JobUtil.cs diff --git a/Capnp.Net.Runtime.Tests/ScatteringStream.cs b/Capnp.Net.Runtime.Tests/Util/ScatteringStream.cs similarity index 98% rename from Capnp.Net.Runtime.Tests/ScatteringStream.cs rename to Capnp.Net.Runtime.Tests/Util/ScatteringStream.cs index e6b44df..6335167 100644 --- a/Capnp.Net.Runtime.Tests/ScatteringStream.cs +++ b/Capnp.Net.Runtime.Tests/Util/ScatteringStream.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace Capnp.Net.Runtime.Tests diff --git a/Capnp.Net.Runtime.Tests/Util/TcpManager.cs b/Capnp.Net.Runtime.Tests/Util/TcpManager.cs new file mode 100644 index 0000000..102d352 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/Util/TcpManager.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text; + +namespace Capnp.Net.Runtime.Tests.Util +{ + class TcpManager + { + public static readonly TcpManager Instance = new TcpManager(); + + readonly byte[] _nextAddress; + int _nextPort = 50005; + + public TcpManager() + { + _nextAddress = new byte[] { 127, 0, 0, 1 }; + } + + public (IPAddress, int) GetLocalAddressAndPort() + { + if (++_nextAddress[2] == 0 && + ++_nextAddress[1] == 0 && + ++_nextAddress[0] == 0) + { + _nextAddress[0] = 2; + } + + return (new IPAddress(_nextAddress), _nextPort); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/Util/TestBase.cs b/Capnp.Net.Runtime.Tests/Util/TestBase.cs new file mode 100644 index 0000000..2899428 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/Util/TestBase.cs @@ -0,0 +1,485 @@ +using Capnp.Net.Runtime.Tests.Util; +using Capnp.Rpc; +using Capnp.Util; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Capnp.Net.Runtime.Tests +{ + public interface ITestbed + { + T ConnectMain(object main) where T : class, IDisposable; + void MustComplete(params Task[] tasks); + void MustNotComplete(params Task[] tasks); + void FlushCommunication(); + void CloseClient(); + void CloseServer(); + + long ClientSendCount { get; } + } + + public interface ITestController + { + void RunTest(Action action); + } + + public class TestBase + { + + protected class EnginePair + { + class EngineChannel : IEndpoint + { + readonly Queue _frameBuffer = new Queue(); + readonly Func _decide; + bool _recursion; + bool _dismissed; + + public EngineChannel(Func decide) + { + _decide = decide; + } + + public RpcEngine.RpcEndpoint OtherEndpoint { get; set; } + public bool HasBufferedFrames => _frameBuffer.Count > 0; + public int FrameCounter { get; private set; } + + + public void Dismiss() + { + if (!_dismissed) + { + _dismissed = true; + OtherEndpoint.Dismiss(); + } + } + + public void Forward(WireFrame frame) + { + if (_dismissed) + return; + + ++FrameCounter; + + if (_recursion || _frameBuffer.Count > 0 || _decide()) + { + _frameBuffer.Enqueue(frame); + } + else + { + _recursion = true; + OtherEndpoint.Forward(frame); + _recursion = false; + } + } + + public bool Flush() + { + if (_frameBuffer.Count > 0) + { + var frame = _frameBuffer.Dequeue(); + _recursion = true; + try + { + OtherEndpoint.Forward(frame); + } + catch (InvalidOperationException) + { + } + _recursion = false; + + return true; + } + else + { + return false; + } + } + + void IEndpoint.Flush() + { + } + } + + readonly DecisionTree _decisionTree; + readonly EngineChannel _channel1, _channel2; + + public RpcEngine Engine1 { get; } + public RpcEngine Engine2 { get; } + public RpcEngine.RpcEndpoint Endpoint1 { get; } + public RpcEngine.RpcEndpoint Endpoint2 { get; } + + public EnginePair(DecisionTree decisionTree) + { + _decisionTree = decisionTree; + Engine1 = new RpcEngine(); + Engine2 = new RpcEngine(); + _channel1 = new EngineChannel(decisionTree.MakeDecision); + Endpoint1 = Engine1.AddEndpoint(_channel1); + _channel2 = new EngineChannel(() => false); + Endpoint2 = Engine2.AddEndpoint(_channel2); + _channel1.OtherEndpoint = Endpoint2; + _channel2.OtherEndpoint = Endpoint1; + } + + public void FlushChannels(Func pred) + { + while (!pred()) + { + if (!_channel1.Flush() && + !_channel2.Flush()) + return; + } + + while ((_channel1.HasBufferedFrames || _channel2.HasBufferedFrames) && _decisionTree.MakeDecision()) + { + if (_channel1.HasBufferedFrames) + { + int mark = _channel2.FrameCounter; + + while (_channel1.Flush() && _channel2.FrameCounter == mark) + ; + } + else if (_channel2.HasBufferedFrames) + { + int mark = _channel1.FrameCounter; + + while (_channel2.Flush() && _channel1.FrameCounter == mark) + ; + } + + } + } + + public int Channel1SendCount => _channel1.FrameCounter; + public int Channel2SendCount => _channel2.FrameCounter; + } + + protected class LocalTestbed : ITestbed, ITestController + { + long ITestbed.ClientSendCount => 0; + + public void RunTest(Action action) + { + action(this); + } + + T ITestbed.ConnectMain(object main) + { + return Proxy.Share((T)main); + } + + void ITestbed.FlushCommunication() + { + } + + void ITestbed.MustComplete(params Task[] tasks) + { + Assert.IsTrue(tasks.All(t => t.IsCompleted)); + } + + void ITestbed.MustNotComplete(params Task[] tasks) + { + Assert.IsFalse(tasks.Any(t => t.IsCompleted)); + } + + void ITestbed.CloseClient() + { + throw new NotSupportedException(); + } + + void ITestbed.CloseServer() + { + throw new NotSupportedException(); + } + } + + protected class DtbdctTestbed : ITestbed, ITestController + { + readonly DecisionTree _decisionTree = new DecisionTree(); + EnginePair _enginePair; + + public void RunTest(Action action) + { + _decisionTree.Iterate(() => { + + action(this); + _enginePair.FlushChannels(() => false); + + Assert.AreEqual(0, _enginePair.Endpoint1.ExportedCapabilityCount); + Assert.AreEqual(0, _enginePair.Endpoint1.ImportedCapabilityCount); + Assert.AreEqual(0, _enginePair.Endpoint1.PendingQuestionCount); + Assert.AreEqual(0, _enginePair.Endpoint1.PendingAnswerCount); + + Assert.AreEqual(0, _enginePair.Endpoint2.ExportedCapabilityCount); + Assert.AreEqual(0, _enginePair.Endpoint2.ImportedCapabilityCount); + Assert.AreEqual(0, _enginePair.Endpoint2.PendingQuestionCount); + Assert.AreEqual(0, _enginePair.Endpoint2.PendingAnswerCount); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + GC.Collect(); + }); + } + + T ITestbed.ConnectMain(object main) + { + return SetupEnginePair(main, _decisionTree, out _enginePair); + } + + void ITestbed.MustComplete(params Task[] tasks) + { + bool AllDone() => tasks.All(t => t.IsCompleted); + _enginePair.FlushChannels(AllDone); + _decisionTree.Freeze(); + Assert.IsTrue(AllDone()); + } + + void ITestbed.MustNotComplete(params Task[] tasks) + { + Assert.IsFalse(tasks.Any(t => t.IsCompleted)); + } + + void ITestbed.FlushCommunication() + { + _enginePair.FlushChannels(() => false); + } + + long ITestbed.ClientSendCount => _enginePair.Channel2SendCount; + + void ITestbed.CloseClient() + { + _enginePair.Endpoint1.Dismiss(); + } + + void ITestbed.CloseServer() + { + _enginePair.Endpoint2.Dismiss(); + } + } + + protected class LocalhostTcpTestbed : ITestbed, ITestController + { + readonly TcpRpcTestOptions _options; + TcpRpcServer _server; + TcpRpcClient _client; + bool _prematurelyClosed; + + public LocalhostTcpTestbed(TcpRpcTestOptions options) + { + _options = options; + } + + public void RunTest(Action action) + { + (_server, _client) = SetupClientServerPair(_options); + Assert.IsTrue(SpinWait.SpinUntil(() => _server.ConnectionCount > 0, LargeNonDbgTimeout)); + var conn = _server.Connections[0]; + + using (_server) + using (_client) + { + action(this); + + if (!_prematurelyClosed) + { + Assert.IsTrue(SpinWait.SpinUntil(() => _client.SendCount == conn.RecvCount, MediumNonDbgTimeout)); + Assert.IsTrue(SpinWait.SpinUntil(() => conn.SendCount == _client.RecvCount, MediumNonDbgTimeout)); + } + } + } + + T ITestbed.ConnectMain(object main) + { + _server.Main = main; + return _client.GetMain(); + } + + static Task[] GulpExceptions(Task[] tasks) + { + async Task Gulp(Task t) + { + try + { + await t; + } + catch + { + } + } + + return tasks.Select(Gulp).ToArray(); + } + + void ITestbed.MustComplete(params Task[] tasks) + { + Assert.IsTrue(Task.WaitAll(GulpExceptions(tasks), MediumNonDbgTimeout)); + } + + void ITestbed.MustNotComplete(params Task[] tasks) + { + Assert.AreEqual(-1, Task.WaitAny(GulpExceptions(tasks), ShortTimeout)); + } + + void ITestbed.FlushCommunication() + { + WaitClientServerIdle(_server, _client); + } + + long ITestbed.ClientSendCount => _client.SendCount; + + void ITestbed.CloseClient() + { + _prematurelyClosed = true; + _client.Dispose(); + } + + void ITestbed.CloseServer() + { + _prematurelyClosed = true; + _server.Dispose(); + } + } + + public static int MediumNonDbgTimeout => Debugger.IsAttached ? Timeout.Infinite : 5000; + public static int LargeNonDbgTimeout => Debugger.IsAttached ? Timeout.Infinite : 20000; + public static int ShortTimeout => 500; + + protected ILogger Logger { get; set; } + + protected TestBase() + { + Logging.LoggerFactory?.Dispose(); +#pragma warning disable CS0618 + Logging.LoggerFactory = new LoggerFactory().AddConsole((msg, level) => true); +#pragma warning restore CS0618 + Logger = Logging.CreateLogger(); + if (Thread.CurrentThread.Name == null) + Thread.CurrentThread.Name = $"Test Thread {Thread.CurrentThread.ManagedThreadId}"; + +#if SOTASK_PERF + StrictlyOrderedTaskExtensions.Stats.Reset(); +#endif + } + + [TestCleanup] + public void TestCleanup() + { +#if SOTASK_PERF + Console.WriteLine($"StrictlyOrderedTask performance statistics:"); + Console.WriteLine($"AwaitInternal: max. {StrictlyOrderedTaskExtensions.Stats.AwaitInternalMaxOuterIterations} outer iterations"); + Console.WriteLine($"AwaitInternal: max. {StrictlyOrderedTaskExtensions.Stats.AwaitInternalMaxInnerIterations} inner iterations"); + Console.WriteLine($"OnCompleted: max. {StrictlyOrderedTaskExtensions.Stats.OnCompletedMaxSpins} iterations"); +#endif + } + + protected static TcpRpcClient SetupClient(IPAddress addr, int port, TcpRpcTestOptions options = TcpRpcTestOptions.None) + { + var client = new TcpRpcClient(); + client.AddBuffering(); + if (options.HasFlag(TcpRpcTestOptions.ClientTracer)) + client.AttachTracer(new FrameTracing.RpcFrameTracer(Console.Out, false)); + if (options.HasFlag(TcpRpcTestOptions.ClientFluctStream)) + client.InjectMidlayer(s => new FluctStream(s)); + if (!options.HasFlag(TcpRpcTestOptions.ClientNoConnect)) + client.Connect(addr.ToString(), port); + return client; + } + + [Flags] + public enum TcpRpcTestOptions + { + None = 0, + ClientTracer = 1, + ClientFluctStream = 2, + ClientNoConnect = 4 + } + + protected static TcpRpcServer SetupServer(IPAddress addr, int port) + { + var server = new TcpRpcServer(); + server.AddBuffering(); + server.StartAccepting(addr, port); + return server; + } + + protected static (TcpRpcServer, TcpRpcClient) SetupClientServerPair(TcpRpcTestOptions options = TcpRpcTestOptions.None) + { + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + + var server = SetupServer(addr, port); + var client = SetupClient(addr, port, options); + + return (server, client); + } + + protected static T SetupEnginePair(object main, DecisionTree decisionTree, out EnginePair pair) where T: class + { + pair = new EnginePair(decisionTree); + pair.Engine1.Main = main; + return (CapabilityReflection.CreateProxy(pair.Endpoint2.QueryMain()) as T); + } + + protected static DtbdctTestbed NewDtbdctTestbed() => new DtbdctTestbed(); + protected static LocalhostTcpTestbed NewLocalhostTcpTestbed(TcpRpcTestOptions options = TcpRpcTestOptions.None) => + new LocalhostTcpTestbed(options); + + protected static LocalTestbed NewLocalTestbed() => new LocalTestbed(); + + /// + /// Somewhat ugly helper method which ensures that both Tcp client and server + /// are waiting for data reception from each other. This is a "balanced" state, meaning + /// that nothing will ever happen in the RcpEngines without some other thread requesting + /// anything. + /// + static protected void WaitClientServerIdle(TcpRpcServer server, TcpRpcClient client) + { + var conn = server.Connections[0]; + SpinWait.SpinUntil(() => conn.IsWaitingForData && client.IsWaitingForData && + conn.RecvCount == client.SendCount && + conn.SendCount == client.RecvCount, + MediumNonDbgTimeout); + } + + protected void ExpectPromiseThrows(Task task) + { + async Task ExpectPromiseThrowsAsync(Task t) + { + try + { + await t; + Assert.Fail("Did not throw"); + } + catch (InvalidOperationException) + { + // Happens if the call went to the resolution + // (thus, locally). In this case, the original + // exception is routed here. + } + catch (RpcException) + { + // Happens if the call went to the promise + // (thus, remotely). In this case, the original + // exception had to be serialized, so we receive + // the wrapped version. + } + catch (System.Exception exception) + { + Assert.Fail($"Got wrong kind of exception: {exception}"); + } + } + + Assert.IsTrue(ExpectPromiseThrowsAsync(task).Wait(MediumNonDbgTimeout)); + } + + } +} diff --git a/Capnp.Net.Runtime.Tests/WirePointerTests.cs b/Capnp.Net.Runtime.Tests/WirePointerTests.cs index ba7cd91..18ec167 100644 --- a/Capnp.Net.Runtime.Tests/WirePointerTests.cs +++ b/Capnp.Net.Runtime.Tests/WirePointerTests.cs @@ -4,6 +4,7 @@ using System; namespace Capnp.Net.Runtime.Tests { [TestClass] + [TestCategory("Coverage")] public class WirePointerTests { [TestMethod] diff --git a/Capnp.Net.Runtime/Assembly.cs b/Capnp.Net.Runtime/Assembly.cs new file mode 100644 index 0000000..114f6be --- /dev/null +++ b/Capnp.Net.Runtime/Assembly.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Capnp.Net.Runtime.Tests")] diff --git a/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj b/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj index af2c400..f6bcfa4 100644 --- a/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj +++ b/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj @@ -22,14 +22,18 @@ capnp "Cap'n Proto" RPC serialization cerealization Debug;Release true + true + true + true + snupkg - + TRACE;DEBUG - DebugCapabilityLifecycle + @@ -39,6 +43,6 @@ + - diff --git a/Capnp.Net.Runtime/CapnpSerializable.cs b/Capnp.Net.Runtime/CapnpSerializable.cs index 81b86b6..91a2d97 100644 --- a/Capnp.Net.Runtime/CapnpSerializable.cs +++ b/Capnp.Net.Runtime/CapnpSerializable.cs @@ -36,7 +36,8 @@ namespace Capnp public FromList() { - _elementSerializer = (Func)GetSerializer(typeof(T)); + var deser = GetSerializer(typeof(T)); + _elementSerializer = d => (deser(d) as T)!; } public object Create(DeserializerState state) @@ -54,11 +55,22 @@ namespace Capnp } } + static object? CreateFromAny(DeserializerState state) + { + switch (state.Kind) + { + case ObjectKind.Capability: return state.RequireCap(); + case ObjectKind.Nil: return null; + default: return state; + } + } + static readonly ConditionalWeakTable> _typeMap = new ConditionalWeakTable>(); static CapnpSerializable() { + _typeMap.Add(typeof(object), CreateFromAny); _typeMap.Add(typeof(string), d => d.RequireList().CastText()); _typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastBool()); _typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastSByte()); @@ -147,29 +159,30 @@ namespace Capnp /// /// Type implementing . The type must must have a public parameterless constructor. /// A capability interface ( for further explanation) - /// - /// IReadOnlyList{Boolean} - /// IReadOnlyList{SByte}" - /// IReadOnlyList{Byte}" - /// IReadOnlyList{Int16}" - /// IReadOnlyList{UInt16}" - /// IReadOnlyList{Int32}" - /// IReadOnlyList{UInt32}" - /// IReadOnlyList{Int64}" - /// IReadOnlyList{UInt64}" - /// IReadOnlyList{Single}" - /// IReadOnlyList{Double}" - /// IReadOnlyList{T} whereby T is one of the things listed here. + /// + /// IReadOnlyList<bool>, IReadOnlyList<sbyte>, IReadOnlyList<byte> + /// IReadOnlyList<short>, IReadOnlyList<ushort>, IReadOnlyList<int> + /// IReadOnlyList<uint>, IReadOnlyList<long>, IReadOnlyList<ulong> + /// IReadOnlyList<float>, IReadOnlyList<double> + /// IReadOnlyList<T> whereby T is one of the things listed here. /// /// /// deserializer state to construct from - /// The domain object instance. Nullability note: The returned reference will be null if (and only if) is a capability interface and - /// represents the nil object (obtained from a null pointer). For all other types, when the state is nil, - /// the method still constructs a valid but "empty" object instance (such as domain object without any properties set, empty string, empty list etc.) + /// The domain object instance. Nullability note: The returned reference may be null if + /// represents the nil object. + /// Cannot construct object of type + /// Note that capability ownership is moved to the domain object public static T? Create(DeserializerState state) where T: class { - return (T?)GetSerializer(typeof(T))(state); + try + { + return (T?)GetSerializer(typeof(T))(state); + } + catch (TargetInvocationException ex) + { + throw new ArgumentException("Failed to construct domain object", ex); + } } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/DeserializerState.cs b/Capnp.Net.Runtime/DeserializerState.cs index e6afb8b..eaa24f9 100644 --- a/Capnp.Net.Runtime/DeserializerState.cs +++ b/Capnp.Net.Runtime/DeserializerState.cs @@ -9,7 +9,7 @@ namespace Capnp /// Although it is public, you should not use it directly. Instead, use the reader, writer, and domain class adapters which are produced /// by the code generator. /// - public struct DeserializerState: IStructDeserializer + public struct DeserializerState: IStructDeserializer, IDisposable { /// /// A wire message is essentially a collection of memory blocks. @@ -45,12 +45,13 @@ namespace Capnp /// The kind of object this state currently represents. /// public ObjectKind Kind { get; set; } + bool _disposed; /// /// The capabilities imported from the capability table. Only valid in RPC context. /// - public IList? Caps { get; set; } + public IList? Caps { get; set; } /// - /// Current segment (essentially Segments[CurrentSegmentIndex] + /// Current segment (essentially Segments[CurrentSegmentIndex]) /// public ReadOnlySpan CurrentSegment => Segments != null ? Segments[(int)CurrentSegmentIndex].Span : default; @@ -65,6 +66,7 @@ namespace Capnp StructPtrCount = 1; Kind = ObjectKind.Struct; Caps = null; + _disposed = false; } /// @@ -158,7 +160,6 @@ namespace Capnp /// Memory span which represents this struct's data section (given this state actually represents a struct) /// public ReadOnlySpan StructDataSection => CurrentSegment.Slice(Offset, StructDataCount); - ReadOnlySpan StructPtrSection => CurrentSegment.Slice(Offset + StructDataCount, StructPtrCount); ReadOnlySpan GetRawBits() => CurrentSegment.Slice(Offset, (ListElementCount + 63) / 64); ReadOnlySpan GetRawBytes() => CurrentSegment.Slice(Offset, (ListElementCount + 7) / 8); @@ -172,26 +173,15 @@ namespace Capnp { get { - switch (Kind) + return Kind switch { - case ObjectKind.ListOfBits: - return GetRawBits(); - - case ObjectKind.ListOfBytes: - return GetRawBytes(); - - case ObjectKind.ListOfShorts: - return GetRawShorts(); - - case ObjectKind.ListOfInts: - return GetRawInts(); - - case ObjectKind.ListOfLongs: - return GetRawLongs(); - - default: - return default; - } + ObjectKind.ListOfBits => GetRawBits(), + ObjectKind.ListOfBytes => GetRawBytes(), + ObjectKind.ListOfShorts => GetRawShorts(), + ObjectKind.ListOfInts => GetRawInts(), + ObjectKind.ListOfLongs => GetRawLongs(), + _ => default, + }; } } @@ -213,6 +203,10 @@ namespace Capnp GetRawBytes(); break; + case ObjectKind.ListOfShorts: + GetRawShorts(); + break; + case ObjectKind.ListOfInts: GetRawInts(); break; @@ -313,6 +307,8 @@ namespace Capnp case ListKind.ListOfStructs: { + if (Offset >= CurrentSegment.Length) + throw new DeserializationException("List of composites pointer exceeds segment bounds"); WirePointer tag = CurrentSegment[Offset]; if (tag.Kind != PointerKind.Struct) throw new DeserializationException("Unexpected: List of composites with non-struct type tag"); @@ -333,9 +329,16 @@ namespace Capnp case PointerKind.Far: + if (pointer.TargetSegmentIndex >= Segments.Count) + throw new DeserializationException("Error decoding pointer: Invalid target segment index"); + + CurrentSegmentIndex = pointer.TargetSegmentIndex; + if (pointer.IsDoubleFar) { - CurrentSegmentIndex = pointer.TargetSegmentIndex; + if (pointer.LandingPadOffset >= CurrentSegment.Length - 1) + throw new DeserializationException("Error decoding double-far pointer: exceeds segment bounds"); + Offset = 0; WirePointer pointer1 = CurrentSegment[pointer.LandingPadOffset]; @@ -347,15 +350,18 @@ namespace Capnp throw new DeserializationException("Error decoding double-far pointer: not followed by intra-segment pointer"); CurrentSegmentIndex = pointer1.TargetSegmentIndex; - Offset = 0; + Offset = pointer1.LandingPadOffset; pointer = pointer2; offset = -1; } else { - CurrentSegmentIndex = pointer.TargetSegmentIndex; Offset = 0; offset = pointer.LandingPadOffset; + + if (pointer.LandingPadOffset >= CurrentSegment.Length) + throw new DeserializationException("Error decoding pointer: exceeds segment bounds"); + pointer = CurrentSegment[pointer.LandingPadOffset]; } continue; @@ -383,14 +389,14 @@ namespace Capnp /// /// Offset relative to this.Offset within current segment /// the low-level capability object, or null if it is a null pointer - /// offset negative or out of range + /// offset negative or out of range /// capability table not set /// not a capability pointer or invalid capability index - internal Rpc.ConsumedCapability? DecodeCapPointer(int offset) + internal Rpc.ConsumedCapability DecodeCapPointer(int offset) { if (offset < 0) { - throw new IndexOutOfRangeException(nameof(offset)); + throw new ArgumentOutOfRangeException(nameof(offset)); } if (Caps == null) @@ -404,7 +410,7 @@ namespace Capnp { // Despite this behavior is not officially specified, // the official C++ implementation seems to send null pointers for null caps. - return null; + return Rpc.NullCapability.Instance; } if (pointer.Kind != PointerKind.Other) @@ -496,13 +502,13 @@ namespace Capnp return state; } - internal Rpc.ConsumedCapability? StructReadRawCap(int index) + internal Rpc.ConsumedCapability StructReadRawCap(int index) { if (Kind != ObjectKind.Struct && Kind != ObjectKind.Nil) throw new InvalidOperationException("Allowed on structs only"); if (index >= StructPtrCount) - return null; + return Rpc.NullCapability.Instance; return DecodeCapPointer(index + StructDataCount); } @@ -646,20 +652,14 @@ namespace Capnp /// /// Capability interface /// index within this struct's pointer table - /// debugging aid - /// debugging aid - /// debugging aid /// capability instance or null if pointer was null /// negative index /// state does not represent a struct, invalid pointer, /// non-capability pointer, traversal limit exceeded - public T? ReadCap(int index, - [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", - [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", - [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0) where T: class + public T? ReadCap(int index) where T: class { var cap = StructReadRawCap(index); - return Rpc.CapabilityReflection.CreateProxy(cap, memberName, sourceFilePath, sourceLineNumber) as T; + return Rpc.CapabilityReflection.CreateProxy(cap) as T; } /// @@ -693,9 +693,26 @@ namespace Capnp throw new DeserializationException("Expected a capability"); if (Caps == null) - throw new InvalidOperationException("Capability table not set. This is a bug."); + throw new InvalidOperationException("Capability table not set"); return (Rpc.CapabilityReflection.CreateProxy(Caps[(int)CapabilityIndex]) as T)!; } + + /// + /// Releases the capability table + /// + public void Dispose() + { + if (Caps != null && !_disposed) + { + foreach (var cap in Caps) + { + cap.Release(); + } + + Caps = null; + _disposed = true; + } + } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/DynamicSerializerState.cs b/Capnp.Net.Runtime/DynamicSerializerState.cs index 679a59f..dccfd69 100644 --- a/Capnp.Net.Runtime/DynamicSerializerState.cs +++ b/Capnp.Net.Runtime/DynamicSerializerState.cs @@ -42,7 +42,9 @@ namespace Capnp { var mb = MessageBuilder.Create(); if (state.Caps != null) + { mb.InitCapTable(); + } var sstate = mb.CreateObject(); Reserializing.DeepCopy(state, sstate); @@ -77,7 +79,7 @@ namespace Capnp /// This state does neither describe a struct, nor a list of pointers /// Another state is already linked to the specified position (sorry, no overwrite allowed) /// - public new void LinkToCapability(int slot, uint capabilityIndex) => base.LinkToCapability(slot, capabilityIndex); + public new void LinkToCapability(int slot, uint? capabilityIndex) => base.LinkToCapability(slot, capabilityIndex); /// /// Determines the underlying object to be a struct. @@ -87,6 +89,13 @@ namespace Capnp /// The object type was already set to something different public new void SetStruct(ushort dataCount, ushort ptrCount) => base.SetStruct(dataCount, ptrCount); + /// + /// Determines the underyling object to be a capability. + /// + /// Capability table index, or null to encode a null pointer + /// The object type was already set to something different + public new void SetCapability(uint? capabilityIndex) => base.SetCapability(capabilityIndex); + /// /// Determines the underlying object to be a list of (primitive) values. /// @@ -121,31 +130,27 @@ namespace Capnp /// Object representation. Must be one of the following: /// /// An instance implementing - /// null - /// A - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// Another - /// Another + /// null, + /// IReadOnlyList<byte>, IReadOnlyList<sbyte>, IReadOnlyList<ushort>, IReadOnlyList<short> + /// IReadOnlyList<int>, IReadOnlyList<uint>, IReadOnlyList<long>, IReadOnlyList<ulong> + /// IReadOnlyList<float>, IReadOnlyList<double>, IReadOnlyList<bool>, IReadOnlyList<string> + /// Another or /// Low-level capability object () /// Proxy object () /// Skeleton object () /// Capability interface implementation - /// A ]]> whereby each list item is one of the things listed here. + /// IReadOnlyList<object>, whereby each list item is one of the things listed here. /// /// public void SetObject(object? obj) { + void RewrapAndInheritBack(Action init) where T : SerializerState, new() + { + var r = Rewrap(); + init(r); + InheritFrom(r); + } + switch (obj) { case ICapnpSerializable serializable: @@ -157,55 +162,55 @@ namespace Capnp break; case IReadOnlyList bytes: - Rewrap>().Init(bytes); + RewrapAndInheritBack>(_ => _.Init(bytes)); break; case IReadOnlyList sbytes: - Rewrap>().Init(sbytes); + RewrapAndInheritBack>(_ => _.Init(sbytes)); break; case IReadOnlyList ushorts: - Rewrap>().Init(ushorts); + RewrapAndInheritBack>(_ => _.Init(ushorts)); break; case IReadOnlyList shorts: - Rewrap>().Init(shorts); + RewrapAndInheritBack>(_ => _.Init(shorts)); break; case IReadOnlyList uints: - Rewrap>().Init(uints); + RewrapAndInheritBack>(_ => _.Init(uints)); break; case IReadOnlyList ints: - Rewrap>().Init(ints); + RewrapAndInheritBack>(_ => _.Init(ints)); break; case IReadOnlyList ulongs: - Rewrap>().Init(ulongs); + RewrapAndInheritBack>(_ => _.Init(ulongs)); break; case IReadOnlyList longs: - Rewrap>().Init(longs); + RewrapAndInheritBack>(_ => _.Init(longs)); break; case IReadOnlyList floats: - Rewrap>().Init(floats); + RewrapAndInheritBack>(_ => _.Init(floats)); break; case IReadOnlyList doubles: - Rewrap>().Init(doubles); + RewrapAndInheritBack>(_ => _.Init(doubles)); break; case IReadOnlyList bools: - Rewrap().Init(bools); + RewrapAndInheritBack(_ => _.Init(bools)); break; case IReadOnlyList strings: - Rewrap().Init(strings); + RewrapAndInheritBack(_ => _.Init(strings)); break; case IReadOnlyList objects: - Rewrap>().Init(objects, (s, o) => s.SetObject(o)); + RewrapAndInheritBack>(_ => _.Init(objects, (s, o) => s.SetObject(o))); break; case DeserializerState ds: diff --git a/Capnp.Net.Runtime/EmptyList.cs b/Capnp.Net.Runtime/EmptyList.cs index 0c1ebc6..c719551 100644 --- a/Capnp.Net.Runtime/EmptyList.cs +++ b/Capnp.Net.Runtime/EmptyList.cs @@ -8,14 +8,14 @@ namespace Capnp /// /// Implements an empty . /// - /// + /// list element type public class EmptyList : IReadOnlyList { /// - /// Always throws an . + /// Always throws an . /// /// Ignored - public T this[int index] => throw new ArgumentOutOfRangeException(nameof(index)); + public T this[int index] => throw new IndexOutOfRangeException(nameof(index)); /// /// Always 0. diff --git a/Capnp.Net.Runtime/EmptyListDeserializer.cs b/Capnp.Net.Runtime/EmptyListDeserializer.cs index 76ee7d1..255f233 100644 --- a/Capnp.Net.Runtime/EmptyListDeserializer.cs +++ b/Capnp.Net.Runtime/EmptyListDeserializer.cs @@ -68,7 +68,7 @@ namespace Capnp /// /// Returns an empty string. /// - public override string CastText() => string.Empty; + public override string? CastText() => null; /// /// Returns an empty ]]>. diff --git a/Capnp.Net.Runtime/FramePump.cs b/Capnp.Net.Runtime/FramePump.cs index e2ecabc..1184f46 100644 --- a/Capnp.Net.Runtime/FramePump.cs +++ b/Capnp.Net.Runtime/FramePump.cs @@ -2,7 +2,9 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; +using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -116,8 +118,24 @@ namespace Capnp #endif _writer.Write(bytes); } + } + } - _writer.Flush(); + /// + /// Flushes all buffered frames. + /// + public void Flush() + { + if (Monitor.TryEnter(_writeLock)) + { + try + { + _writer?.Flush(); + } + finally + { + Monitor.Exit(_writeLock); + } } } @@ -160,9 +178,12 @@ namespace Capnp } } } - catch (EndOfStreamException) + catch (Exception exception) when (exception is EndOfStreamException || + exception is IOException ioex && + ioex.InnerException is SocketException sockex && + sockex.SocketErrorCode == SocketError.Interrupted) { - Logger.LogWarning("Encountered End of Stream"); + Logger.LogInformation("Encountered end of stream"); } catch (InvalidDataException e) { diff --git a/Capnp.Net.Runtime/FrameTracing/RpcFrameTracer.cs b/Capnp.Net.Runtime/FrameTracing/RpcFrameTracer.cs index fdd4ac2..62d7be9 100644 --- a/Capnp.Net.Runtime/FrameTracing/RpcFrameTracer.cs +++ b/Capnp.Net.Runtime/FrameTracing/RpcFrameTracer.cs @@ -18,15 +18,26 @@ namespace Capnp.FrameTracing readonly Stopwatch _timer = new Stopwatch(); readonly TextWriter _traceWriter; + readonly bool _disposeWriter; /// /// Constructs an instance /// /// textual logging target - public RpcFrameTracer(TextWriter traceWriter) + public RpcFrameTracer(TextWriter traceWriter): this(traceWriter, true) + { + } + + /// + /// Constructs an instance + /// + /// textual logging target + /// whether to dispose the writer when tracing is finished + public RpcFrameTracer(TextWriter traceWriter, bool dispose) { _traceWriter = traceWriter ?? throw new ArgumentNullException(nameof(traceWriter)); _traceWriter.WriteLine(Header); + _disposeWriter = dispose; } /// @@ -35,7 +46,8 @@ namespace Capnp.FrameTracing public void Dispose() { _traceWriter.WriteLine(""); - _traceWriter.Dispose(); + if (_disposeWriter) + _traceWriter.Dispose(); } void RenderMessageTarget(MessageTarget.READER target, FrameDirection dir) diff --git a/Capnp.Net.Runtime/ListDeserializer.cs b/Capnp.Net.Runtime/ListDeserializer.cs index e28b90c..75a944b 100644 --- a/Capnp.Net.Runtime/ListDeserializer.cs +++ b/Capnp.Net.Runtime/ListDeserializer.cs @@ -11,6 +11,9 @@ namespace Capnp static class GenericCasts { public static Func? CastFunc; + + public static Func GetCastFunc() => CastFunc ?? + throw new NotSupportedException("Requested cast is not supported"); } static ListDeserializer() @@ -26,7 +29,7 @@ namespace Capnp GenericCasts>.CastFunc = _ => _.CastULong(); GenericCasts>.CastFunc = _ => _.CastFloat(); GenericCasts>.CastFunc = _ => _.CastDouble(); - GenericCasts.CastFunc = _ => _.CastText(); + GenericCasts.CastFunc = _ => _.CastText()!; // it *may* return null, but how to express this syntactically correct? } /// @@ -45,12 +48,7 @@ namespace Capnp T Cast() { - var func = GenericCasts.CastFunc; - - if (func == null) - throw new NotSupportedException("Requested cast is not supported"); - - return func(this); + return GenericCasts.GetCastFunc()(this); } /// @@ -89,9 +87,9 @@ namespace Capnp /// Capability list representation /// If this kind of list cannot be represented as list of capabilities (because it is a list of non-pointers) /// If does not qualify as capability interface. - public virtual IReadOnlyList> CastCapList() where T: class + public virtual IReadOnlyList CastCapList() where T: class { - throw new NotSupportedException("This kind of list does not contain nested lists"); + throw new NotSupportedException("This kind of list cannot be represented as list of capabilities"); } object CastND(int n, Func func) @@ -158,6 +156,7 @@ namespace Capnp /// If this list cannot be represented in the desired manner. public IReadOnlyList> Cast2D() { + GenericCasts>.GetCastFunc(); // Probe to avoid lazy NotSupportedException return CastList().LazyListSelect(ld => ld.Cast>()); } @@ -269,7 +268,7 @@ namespace Capnp /// /// The desired representation /// If this list cannot be represented in the desired manner. - public IReadOnlyList CastText2() => CastList().LazyListSelect(ld => ld.CastText()); + public IReadOnlyList CastText2() => CastList().LazyListSelect(ld => ld.CastText()); /// /// Represents this list as Text. For representing it as List(Text), use . @@ -285,7 +284,7 @@ namespace Capnp /// /// The decoded text /// If this list cannot be represented in the desired manner. - public virtual string CastText() + public virtual string? CastText() { throw new NotSupportedException("This kind of list does not represent text"); } diff --git a/Capnp.Net.Runtime/ListOfBitsSerializer.cs b/Capnp.Net.Runtime/ListOfBitsSerializer.cs index 6c00c7a..3e90aa8 100644 --- a/Capnp.Net.Runtime/ListOfBitsSerializer.cs +++ b/Capnp.Net.Runtime/ListOfBitsSerializer.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; namespace Capnp { @@ -10,7 +11,6 @@ namespace Capnp /// public class ListOfBitsSerializer: SerializerState, IReadOnlyList { - /// /// Gets or sets the element at given index. /// @@ -22,6 +22,8 @@ namespace Capnp { get { + ListSerializerHelper.EnsureAllocated(this); + if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); @@ -32,6 +34,8 @@ namespace Capnp } set { + ListSerializerHelper.EnsureAllocated(this); + if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); @@ -88,11 +92,17 @@ namespace Capnp } } + IEnumerable Enumerate() + { + for (int i = 0; i < Count; i++) + yield return this[i]; + } + /// /// Implements /// - public IEnumerator GetEnumerator() => (IEnumerator)this.ToArray().GetEnumerator(); + public IEnumerator GetEnumerator() => Enumerate().GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => this.ToArray().GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/ListOfCapsSerializer.cs b/Capnp.Net.Runtime/ListOfCapsSerializer.cs index eef1d7c..3b71b21 100644 --- a/Capnp.Net.Runtime/ListOfCapsSerializer.cs +++ b/Capnp.Net.Runtime/ListOfCapsSerializer.cs @@ -35,16 +35,29 @@ namespace Capnp [AllowNull] public T this[int index] { - get => (Rpc.CapabilityReflection.CreateProxy(DecodeCapPointer(index)) as T)!; + get + { + ListSerializerHelper.EnsureAllocated(this); + + try + { + return (Rpc.CapabilityReflection.CreateProxy(DecodeCapPointer(index)) as T)!; + } + catch (ArgumentOutOfRangeException) + { + throw new IndexOutOfRangeException(); + } + } set { - if (!IsAllocated) - throw new InvalidOperationException("Call Init() first"); + ListSerializerHelper.EnsureAllocated(this); if (index < 0 || index >= RawData.Length) throw new IndexOutOfRangeException("index out of range"); - RawData[index] = ProvideCapability(value); + var p = default(WirePointer); + p.SetCapability(ProvideCapability(value)); + RawData[index] = p; } } diff --git a/Capnp.Net.Runtime/ListOfPointersDeserializer.cs b/Capnp.Net.Runtime/ListOfPointersDeserializer.cs index 3611461..1f63401 100644 --- a/Capnp.Net.Runtime/ListOfPointersDeserializer.cs +++ b/Capnp.Net.Runtime/ListOfPointersDeserializer.cs @@ -83,9 +83,9 @@ namespace Capnp /// /// Capability interface /// The desired representation. Since it is evaluated lazily, type conflicts will not happen before accessing the resulting list's elements. - public override IReadOnlyList> CastCapList() + public override IReadOnlyList CastCapList() { - return this.LazyListSelect(d => d.RequireCapList()); + return State.RequireCapList(); } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs b/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs index 072d371..a2f4616 100644 --- a/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs +++ b/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs @@ -31,7 +31,7 @@ namespace Capnp var state = _lpd.State; if (index < 0 || index >= _lpd.Count) - throw new ArgumentOutOfRangeException(nameof(index)); + throw new IndexOutOfRangeException(); state.Offset += index; state.Kind = ObjectKind.Struct; diff --git a/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs b/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs index a67df9a..5729e74 100644 --- a/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs +++ b/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs @@ -29,9 +29,9 @@ namespace Capnp } /// - /// Retrieves the underlying memory span of the represented items. + /// The list's data /// - public Span Span => MemoryMarshal.Cast(RawData); + public Span Data => MemoryMarshal.Cast(RawData).Slice(0, Count); /// /// Gets or sets the value at given index. @@ -40,8 +40,16 @@ namespace Capnp /// Element value public T this[int index] { - get => Span[index]; - set => Span[index] = value; + get + { + ListSerializerHelper.EnsureAllocated(this); + return Data[index]; + } + set + { + ListSerializerHelper.EnsureAllocated(this); + Data[index] = value; + } } /// @@ -84,19 +92,19 @@ namespace Capnp switch (items) { case T[] array: - array.CopyTo(Span); + array.CopyTo(Data); break; case ArraySegment segment: - segment.AsSpan().CopyTo(Span); + segment.AsSpan().CopyTo(Data); break; case ListOfPrimitivesDeserializer deser: - deser.Span.CopyTo(Span); + deser.Span.CopyTo(Data); break; case ListOfPrimitivesSerializer ser: - ser.Span.CopyTo(Span); + ser.Data.CopyTo(Data); break; default: @@ -108,11 +116,18 @@ namespace Capnp } } + IEnumerable Enumerate() + { + for (int i = 0; i < Count; i++) + yield return Data[i]; + } + /// /// Implements . /// - public IEnumerator GetEnumerator() => (IEnumerator)Span.ToArray().GetEnumerator(); + /// + public IEnumerator GetEnumerator() => Enumerate().GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => Span.ToArray().GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/ListOfTextSerializer.cs b/Capnp.Net.Runtime/ListOfTextSerializer.cs index 5bd63e7..c1dabbf 100644 --- a/Capnp.Net.Runtime/ListOfTextSerializer.cs +++ b/Capnp.Net.Runtime/ListOfTextSerializer.cs @@ -22,8 +22,7 @@ namespace Capnp { get { - if (!IsAllocated) - throw new InvalidOperationException("Not initialized"); + ListSerializerHelper.EnsureAllocated(this); if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); @@ -32,8 +31,7 @@ namespace Capnp } set { - if (!IsAllocated) - throw new InvalidOperationException("Not initialized"); + ListSerializerHelper.EnsureAllocated(this); if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); @@ -53,7 +51,7 @@ namespace Capnp for (int i = 0; i < count; i++) { - yield return TryGetPointer(i)?.ListReadAsText(); + yield return this[i]; } } diff --git a/Capnp.Net.Runtime/ListSerializerHelper.cs b/Capnp.Net.Runtime/ListSerializerHelper.cs new file mode 100644 index 0000000..5e76b8d --- /dev/null +++ b/Capnp.Net.Runtime/ListSerializerHelper.cs @@ -0,0 +1,13 @@ +using System; + +namespace Capnp +{ + static class ListSerializerHelper + { + public static void EnsureAllocated(SerializerState serializer) + { + if (!serializer.IsAllocated) + throw new InvalidOperationException("Call Init() first"); + } + } +} \ No newline at end of file diff --git a/Capnp.Net.Runtime/MessageBuilder.cs b/Capnp.Net.Runtime/MessageBuilder.cs index 9a5d826..ba2f556 100644 --- a/Capnp.Net.Runtime/MessageBuilder.cs +++ b/Capnp.Net.Runtime/MessageBuilder.cs @@ -10,7 +10,7 @@ namespace Capnp { readonly ISegmentAllocator _allocator; readonly DynamicSerializerState _rootPtrBuilder; - List? _capTable; + List? _capTable; MessageBuilder(ISegmentAllocator allocator) { @@ -64,7 +64,7 @@ namespace Capnp /// /// Creates an object and sets it as root object. /// - /// Serializer state specialization + /// Serializer state specialization (must be a struct) /// Serializer state instance representing the new object public TS BuildRoot() where TS: SerializerState, new() { @@ -72,6 +72,9 @@ namespace Capnp throw new InvalidOperationException("Root already set"); var root = CreateObject(); + if (root.Kind != ObjectKind.Struct) + throw new InvalidOperationException("Root object must be a struct"); + Root = root; return root; } @@ -89,13 +92,13 @@ namespace Capnp if (_capTable != null) throw new InvalidOperationException("Capability table was already initialized"); - _capTable = new List(); + _capTable = new List(); } /// /// Returns this message builder's segment allocator. /// public ISegmentAllocator Allocator => _allocator; - internal List? Caps => _capTable; + internal List? Caps => _capTable; } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/ObjectKind.cs b/Capnp.Net.Runtime/ObjectKind.cs index bdabf6f..80909eb 100644 --- a/Capnp.Net.Runtime/ObjectKind.cs +++ b/Capnp.Net.Runtime/ObjectKind.cs @@ -4,9 +4,7 @@ namespace Capnp { /// /// The different kinds of Cap'n Proto objects. - /// Despite this is a [Flags] enum, it does not make sense to mutually combine literals. /// - [Flags] public enum ObjectKind: byte { /// diff --git a/Capnp.Net.Runtime/PrimitiveCoder.cs b/Capnp.Net.Runtime/PrimitiveCoder.cs deleted file mode 100644 index 9feee41..0000000 --- a/Capnp.Net.Runtime/PrimitiveCoder.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; - -namespace Capnp -{ - class PrimitiveCoder - { - class Coder - { - public static Func? Fn { get; set; } - } - - static PrimitiveCoder() - { - Coder.Fn = (x, y) => x != y; - Coder.Fn = (x, y) => (sbyte)(x ^ y); - Coder.Fn = (x, y) => (byte)(x ^ y); - Coder.Fn = (x, y) => (short)(x ^ y); - Coder.Fn = (x, y) => (ushort)(x ^ y); - Coder.Fn = (x, y) => x ^ y; - Coder.Fn = (x, y) => x ^ y; - Coder.Fn = (x, y) => x ^ y; - Coder.Fn = (x, y) => x ^ y; - Coder.Fn = (x, y) => - { - int xi = x.ReplacementSingleToInt32Bits(); - int yi = y.ReplacementSingleToInt32Bits(); - int zi = xi ^ yi; - return BitConverter.ToSingle(BitConverter.GetBytes(zi), 0); - }; - Coder.Fn = (x, y) => - { - long xi = BitConverter.DoubleToInt64Bits(x); - long yi = BitConverter.DoubleToInt64Bits(y); - long zi = xi ^ yi; - return BitConverter.Int64BitsToDouble(zi); - }; - } - - public static Func Get() - { - return Coder.Fn ?? - throw new NotSupportedException("Generic type argument is not a supported primitive type, no coder defined"); - } - } -} \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/BareProxy.cs b/Capnp.Net.Runtime/Rpc/BareProxy.cs index 5f9dca5..71c4dbe 100644 --- a/Capnp.Net.Runtime/Rpc/BareProxy.cs +++ b/Capnp.Net.Runtime/Rpc/BareProxy.cs @@ -19,7 +19,7 @@ /// Problem with building the Skeleton type, or problem with loading some dependent class. public static BareProxy FromImpl(object impl) { - return new BareProxy(LocalCapability.Create(CapabilityReflection.CreateSkeleton(impl))); + return new BareProxy(CapabilityReflection.CreateSkeletonInternal(impl).AsCapability()); } /// @@ -33,7 +33,7 @@ /// Constructs an instance and binds it to the given low-level capability. /// /// low-level capability - public BareProxy(ConsumedCapability? cap): base(cap) + public BareProxy(ConsumedCapability cap): base(cap) { } diff --git a/Capnp.Net.Runtime/Rpc/CapabilityReflection.cs b/Capnp.Net.Runtime/Rpc/CapabilityReflection.cs index 42ae7ca..57dfa8b 100644 --- a/Capnp.Net.Runtime/Rpc/CapabilityReflection.cs +++ b/Capnp.Net.Runtime/Rpc/CapabilityReflection.cs @@ -94,6 +94,8 @@ namespace Capnp.Rpc new ConditionalWeakTable(); static ConditionalWeakTable _skeletonMap = new ConditionalWeakTable(); + static ConditionalWeakTable _implMap = + new ConditionalWeakTable(); static CapabilityReflection() { @@ -155,15 +157,23 @@ namespace Capnp.Rpc /// Problem with instatiating the Skeleton (constructor threw exception). /// Caller does not have permission to invoke the Skeleton constructor. /// Problem with building the Skeleton type, or problem with loading some dependent class. - public static Skeleton CreateSkeleton(object obj) + [Obsolete("Do not use this method directly. Instead, pass objects directly or use Proxy.Share(). This method will be removed with next release.")] + public static Skeleton CreateSkeleton(object obj) => CreateSkeletonInternal(obj); + + internal static Skeleton CreateSkeletonInternal(object obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); - var factory = GetSkeletonFactory(obj.GetType()); - var skeleton = factory.NewSkeleton(); - skeleton.Bind(obj); - return skeleton; + var result = _implMap.GetValue(obj, _ => + { + var factory = GetSkeletonFactory(_.GetType()); + var skeleton = factory.NewSkeleton(); + skeleton.Bind(obj); + return skeleton; + }); + + return result; } static ProxyFactory GetProxyFactory(Type type) @@ -229,7 +239,7 @@ namespace Capnp.Rpc } /// - /// Checkes whether a given type qualifies as cpapbility interface./> on failure. + /// Checks whether a given type qualifies as capability interface. /// /// type to check /// true when is a capability interface @@ -251,9 +261,6 @@ namespace Capnp.Rpc /// /// Capability interface. Must be annotated with . /// low-level capability - /// debugging aid - /// debugging aid - /// debugging aid /// The Proxy instance which implements . /// is null. /// did not qualify as capability interface. @@ -262,25 +269,11 @@ namespace Capnp.Rpc /// Problem with instatiating the Proxy (constructor threw exception). /// Caller does not have permission to invoke the Proxy constructor. /// Problem with building the Proxy type, or problem with loading some dependent class. - public static Proxy CreateProxy(ConsumedCapability? cap, - [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", - [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", - [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0) + public static Proxy CreateProxy(ConsumedCapability cap) { var factory = GetProxyFactory(typeof(TInterface)); var proxy = factory.NewProxy(); proxy.Bind(cap); -#if DebugFinalizers - proxy.CreatorMemberName = memberName; - proxy.CreatorFilePath = sourceFilePath; - proxy.CreatorLineNumber = sourceLineNumber; - if (cap != null) - { - cap.CreatorFilePath = proxy.CreatorFilePath; - cap.CreatorLineNumber = proxy.CreatorLineNumber; - cap.CreatorMemberName = proxy.CreatorMemberName; - } -#endif return proxy; } } diff --git a/Capnp.Net.Runtime/Rpc/ConsumedCapability.cs b/Capnp.Net.Runtime/Rpc/ConsumedCapability.cs index 1035f0b..ea8c5b3 100644 --- a/Capnp.Net.Runtime/Rpc/ConsumedCapability.cs +++ b/Capnp.Net.Runtime/Rpc/ConsumedCapability.cs @@ -1,4 +1,6 @@ -namespace Capnp.Rpc +using System; + +namespace Capnp.Rpc { /// /// Base class for a low-level capability at consumer side. It is created by the . An application does not directly interact with it @@ -13,20 +15,14 @@ /// which usually also means to remove it from the remote peer's export table. /// protected abstract void ReleaseRemotely(); - internal abstract void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer); - internal abstract void Freeze(out IRpcEndpoint? boundEndpoint); - internal abstract void Unfreeze(); - + internal abstract Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer); internal abstract void AddRef(); - internal abstract void Release( - [System.Runtime.CompilerServices.CallerMemberName] string methodName = "", - [System.Runtime.CompilerServices.CallerFilePath] string filePath = "", - [System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0); + internal abstract void Release(); + internal abstract Skeleton AsSkeleton(); #if DebugFinalizers - public string CreatorMemberName { get; set; } - public string CreatorFilePath { get; set; } - public int CreatorLineNumber { get; set; } + internal Proxy? OwningProxy { get; set; } + internal ConsumedCapability? ResolvingCap { get; set; } #endif } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/IEndpoint.cs b/Capnp.Net.Runtime/Rpc/IEndpoint.cs index 267cafa..e7e37b6 100644 --- a/Capnp.Net.Runtime/Rpc/IEndpoint.cs +++ b/Capnp.Net.Runtime/Rpc/IEndpoint.cs @@ -10,6 +10,11 @@ /// void Forward(WireFrame frame); + /// + /// Indicates that the endpoint should flush any buffered frames. + /// + void Flush(); + /// /// Close this endpoint. /// diff --git a/Capnp.Net.Runtime/Rpc/IPromisedAnswer.cs b/Capnp.Net.Runtime/Rpc/IPromisedAnswer.cs index 250aa18..5bb9d9c 100644 --- a/Capnp.Net.Runtime/Rpc/IPromisedAnswer.cs +++ b/Capnp.Net.Runtime/Rpc/IPromisedAnswer.cs @@ -1,4 +1,5 @@ -using System; +using Capnp.Util; +using System; using System.Threading.Tasks; namespace Capnp.Rpc @@ -15,13 +16,26 @@ namespace Capnp.Rpc /// /// Task which will complete when the RPC returns, delivering its result struct. /// - Task WhenReturned { get; } + StrictlyOrderedAwaitTask WhenReturned { get; } /// /// Creates a low-level capability for promise pipelining. /// /// Path to the desired capability inside the result struct. /// Pipelined low-level capability - ConsumedCapability? Access(MemberAccessPath access); + ConsumedCapability Access(MemberAccessPath access); + + /// + /// + /// + /// Creates a low-level capability for promise pipelining. + /// Task returning the proxy whose ownership will be taken over + /// + ConsumedCapability Access(MemberAccessPath access, Task proxyTask); + + /// + /// Whether the question was asked as tail call + /// + bool IsTailCall { get; } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/IResolvingCapability.cs b/Capnp.Net.Runtime/Rpc/IResolvingCapability.cs index 36f8bf0..f041890 100644 --- a/Capnp.Net.Runtime/Rpc/IResolvingCapability.cs +++ b/Capnp.Net.Runtime/Rpc/IResolvingCapability.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using Capnp.Util; +using System.Threading.Tasks; namespace Capnp.Rpc { @@ -8,8 +9,15 @@ namespace Capnp.Rpc public interface IResolvingCapability { /// - /// Will eventually give the resolved capability. + /// Completes when the capability gets resolved. /// - Task WhenResolved { get; } + StrictlyOrderedAwaitTask WhenResolved { get; } + + /// + /// Returns the resolved capability + /// + /// Capability interface or + /// the resolved capability, or null if it did not resolve yet + T? GetResolvedCapability() where T: class; } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/IRpcEndpoint.cs b/Capnp.Net.Runtime/Rpc/IRpcEndpoint.cs index 339ec26..fccfc6c 100644 --- a/Capnp.Net.Runtime/Rpc/IRpcEndpoint.cs +++ b/Capnp.Net.Runtime/Rpc/IRpcEndpoint.cs @@ -8,7 +8,6 @@ namespace Capnp.Rpc PendingQuestion BeginQuestion(ConsumedCapability target, SerializerState inParams); void SendQuestion(SerializerState inParams, Payload.WRITER payload); uint AllocateExport(Skeleton providedCapability, out bool first); - void RequestPostAction(Action postAction); void Finish(uint questionId); void ReleaseImport(uint importId); void Resolve(uint preliminaryId, Skeleton preliminaryCap, Func resolvedCapGetter); diff --git a/Capnp.Net.Runtime/Rpc/Impatient.cs b/Capnp.Net.Runtime/Rpc/Impatient.cs index 1a0a81e..c3a3804 100644 --- a/Capnp.Net.Runtime/Rpc/Impatient.cs +++ b/Capnp.Net.Runtime/Rpc/Impatient.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -11,7 +12,7 @@ namespace Capnp.Rpc public static class Impatient { static readonly ConditionalWeakTable _taskTable = new ConditionalWeakTable(); - static readonly ThreadLocal _askingEndpoint = new ThreadLocal(); + static readonly ThreadLocal> _askingEndpoint = new ThreadLocal>(() => new Stack()); /// /// Attaches a continuation to the given promise and registers the resulting task for pipelining. @@ -26,45 +27,20 @@ namespace Capnp.Rpc { async Task AwaitAnswer() { - return then(await promise.WhenReturned); + var result = await promise.WhenReturned; + if (promise.IsTailCall) + throw new NoResultsException(); + + return then(result); } var rtask = AwaitAnswer(); - try - { - // Really weird: We'd expect AwaitAnswer() to initialize a new Task instance upon each invocation. - // However, this does not seem to be always true (as indicated by CI test suite). An explanation might be - // that the underlying implementation recycles Task instances (um, really? doesn't make sense. But the - // observation doesn't make sense, either). - - _taskTable.Add(rtask, promise); - } - catch (ArgumentException) - { - if (rtask.IsCompleted) - { - // Force .NET to create a new Task instance - if (rtask.IsCanceled) - { - rtask = Task.FromCanceled(new CancellationToken(true)); - } - else if (rtask.IsFaulted) - { - rtask = Task.FromException(rtask.Exception!.InnerException!); - } - else - { - rtask = Task.FromResult(rtask.Result); - } - - _taskTable.Add(rtask, promise); - } - else - { - throw new InvalidOperationException("What the heck is wrong with Task?"); - } - } + // Rare situation: .NET maintains a cache of some pre-computed tasks for standard results (such as (int)0, (object)null). + // AwaitAnswer() might indeed have chosen a fast-path optimization, such that rtask is a cached object instead of a new instance. + // Once this happens the second time, and we return the same rtask for a different promise. GetAnswer()/TryGetAnswer() may return the "wrong" + // promise! Fortunately, this does not really matter, since the "wrong" promise is guaranteed to return exactly the same answer. :-) + _taskTable.GetValue(rtask, _ => promise); return rtask; } @@ -76,6 +52,7 @@ namespace Capnp.Rpc /// The underlying promise /// is null. /// The task was not registered using MakePipelineAware. + [Obsolete("Please re-generate capnp code-behind. GetAnswer(task).Access(...) was replaced by Access(task, ...)")] public static IPromisedAnswer GetAnswer(Task task) { if (!_taskTable.TryGetValue(task, out var answer)) @@ -92,22 +69,18 @@ namespace Capnp.Rpc return answer; } - static async Task AwaitProxy(Task task) where T: class + /// + /// Returns a promise-pipelined capability for a remote method invocation Task. + /// + /// remote method invocation task + /// path to the desired capability + /// task returning a proxy to the desired capability + /// Pipelined low-level capability + public static ConsumedCapability Access(Task task, MemberAccessPath access, Task proxyTask) { - var item = await task; - - switch (item) - { - case Proxy proxy: - return proxy; - - case null: - return CapabilityReflection.CreateProxy(null); - } - - var skel = Skeleton.GetOrCreateSkeleton(item!, false); - var localCap = LocalCapability.Create(skel); - return CapabilityReflection.CreateProxy(localCap); + var answer = TryGetAnswer(task); + if (answer != null) return answer.Access(access, proxyTask); + return new LazyCapability(proxyTask.AsProxyTask()); } /// @@ -116,22 +89,16 @@ namespace Capnp.Rpc /// /// Capability interface type /// The task - /// debugging aid - /// debugging aid - /// debugging aid /// A proxy for the given task. /// is null. /// did not /// quality as capability interface. [Obsolete("Call Eager(task, true) instead")] - public static TInterface PseudoEager(this Task task, - [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", - [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", - [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0) - where TInterface : class + public static TInterface PseudoEager(this Task task) + where TInterface : class, IDisposable { - var lazyCap = new LazyCapability(AwaitProxy(task)); - return (CapabilityReflection.CreateProxy(lazyCap, memberName, sourceFilePath, sourceLineNumber) as TInterface)!; + var lazyCap = new LazyCapability(task.AsProxyTask()); + return (CapabilityReflection.CreateProxy(lazyCap) as TInterface)!; } static readonly MemberAccessPath Path_OneAndOnly = new MemberAccessPath(0U); @@ -157,7 +124,7 @@ namespace Capnp.Rpc /// Caller does not have permission to invoke the Proxy constructor. /// Problem with building the Proxy type, or problem with loading some dependent class. public static TInterface Eager(this Task task, bool allowNoPipeliningFallback = false) - where TInterface : class + where TInterface : class, IDisposable { var answer = TryGetAnswer(task); if (answer == null) @@ -167,19 +134,65 @@ namespace Capnp.Rpc throw new ArgumentException("The task was not returned from a remote method invocation. See documentation for details."); } - var lazyCap = new LazyCapability(AwaitProxy(task)); - return (CapabilityReflection.CreateProxy(lazyCap) as TInterface)!; + var proxyTask = task.AsProxyTask(); + if (proxyTask.ReplacementTaskIsCompletedSuccessfully()) + { + return proxyTask.Result.Cast(true); + } + else + { + var lazyCap = new LazyCapability(proxyTask); + return (CapabilityReflection.CreateProxy(lazyCap) as TInterface)!; + } } else { - return (CapabilityReflection.CreateProxy(answer.Access(Path_OneAndOnly)) as TInterface)!; + async Task AsDisposableTask() + { + return await task; + } + + return (CapabilityReflection.CreateProxy(answer.Access(Path_OneAndOnly, AsDisposableTask())) as TInterface)!; } } + /// + /// Unwraps given capability. Unwrapping walks the chain of promised capabilities and awaits their resolutions, + /// until we get the finally resolved capability. If it is the capability, the method returns a null reference. + /// If the capability is broken (resolved to exception, dependent answer faulted or cancelled, RPC endpoint closed), + /// it throws an exception. + /// + /// Capability interface + /// capability to unwrap + /// Task returning the eventually resolved capability + /// Capability is broken + public static async Task Unwrap(this TInterface cap) where TInterface: class, IDisposable + { + using var proxy = cap as Proxy; + + if (proxy == null) + return cap; + + var unwrapped = await proxy.ConsumedCap.Unwrap(); + if (unwrapped == null || unwrapped == NullCapability.Instance) + return null; + + return ((CapabilityReflection.CreateProxy(unwrapped)) as TInterface)!; + } + internal static IRpcEndpoint? AskingEndpoint { - get => _askingEndpoint.Value; - set { _askingEndpoint.Value = value; } + get => _askingEndpoint.Value!.Count > 0 ? _askingEndpoint.Value.Peek() : null; + } + + internal static void PushAskingEndpoint(IRpcEndpoint endpoint) + { + _askingEndpoint.Value!.Push(endpoint); + } + + internal static void PopAskingEndpoint() + { + _askingEndpoint.Value!.Pop(); } /// diff --git a/Capnp.Net.Runtime/Rpc/ImportedCapability.cs b/Capnp.Net.Runtime/Rpc/ImportedCapability.cs index 9645022..1635e8b 100644 --- a/Capnp.Net.Runtime/Rpc/ImportedCapability.cs +++ b/Capnp.Net.Runtime/Rpc/ImportedCapability.cs @@ -1,4 +1,6 @@ -namespace Capnp.Rpc +using System; + +namespace Capnp.Rpc { /// /// Low-level capability which as imported from a remote peer. @@ -26,16 +28,7 @@ return call; } - internal override void Freeze(out IRpcEndpoint boundEndpoint) - { - boundEndpoint = _ep; - } - - internal override void Unfreeze() - { - } - - internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER capDesc) + internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER capDesc) { if (endpoint == _ep) { @@ -45,8 +38,9 @@ else { capDesc.which = CapDescriptor.WHICH.SenderHosted; - capDesc.SenderHosted = endpoint.AllocateExport(Vine.Create(this), out var _); + capDesc.SenderHosted = endpoint.AllocateExport(AsSkeleton(), out var _); } + return null; } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/Interception/CallContext.cs b/Capnp.Net.Runtime/Rpc/Interception/CallContext.cs index c8ea190..b8b3a52 100644 --- a/Capnp.Net.Runtime/Rpc/Interception/CallContext.cs +++ b/Capnp.Net.Runtime/Rpc/Interception/CallContext.cs @@ -1,4 +1,5 @@ -using System; +using Capnp.Util; +using System; using System.Threading; using System.Threading.Tasks; @@ -18,36 +19,23 @@ namespace Capnp.Rpc.Interception readonly CancellationTokenSource _cancelFromAlice = new CancellationTokenSource(); public PromisedAnswer(CallContext callContext) - { + { _callContext = callContext; + WhenReturned = _futureResult.Task.EnforceAwaitOrder(); } - public Task WhenReturned => _futureResult.Task; + public StrictlyOrderedAwaitTask WhenReturned { get; } public CancellationToken CancelFromAlice => _cancelFromAlice.Token; - async Task AccessWhenReturned(MemberAccessPath access) + public ConsumedCapability Access(MemberAccessPath access) { - await WhenReturned; - return new Proxy(Access(access)); + return _callContext._censorCapability.Policy.Attach(new LocalAnswerCapability(WhenReturned, access)); } - public ConsumedCapability? Access(MemberAccessPath access) + public ConsumedCapability Access(MemberAccessPath _, Task task) { - if (_futureResult.Task.IsCompleted) - { - try - { - return access.Eval(WhenReturned.Result); - } - catch (AggregateException exception) - { - throw exception.InnerException!; - } - } - else - { - return new LazyCapability(AccessWhenReturned(access)); - } + var proxyTask = task.AsProxyTask(); + return _callContext._censorCapability.Policy.Attach(new LocalAnswerCapability(proxyTask)); } public void Dispose() @@ -84,6 +72,8 @@ namespace Capnp.Rpc.Interception _cancelFromAlice.Dispose(); } } + + public bool IsTailCall => false; } /// @@ -101,10 +91,16 @@ namespace Capnp.Rpc.Interception /// public InterceptionState State { get; private set; } + SerializerState _inArgs; + /// /// Input arguments /// - public SerializerState? InArgs { get; set; } + public SerializerState InArgs + { + get => _inArgs; + set { _inArgs = value ?? throw new ArgumentNullException(nameof(value)); } + } /// /// Output arguments ("return value") @@ -150,45 +146,47 @@ namespace Capnp.Rpc.Interception /// A -derived object /// A -derived object /// A -derived object (low level capability) - /// null /// /// - public object? Bob + /// + /// Note that getting/setting this property does NOT transfer ownership. + /// + public object Bob { get => _bob; set { if (value != _bob) { - BobProxy?.Dispose(); - BobProxy = null; - - _bob = value; - switch (value) { + case null: + throw new ArgumentNullException(nameof(value)); + case Proxy proxy: - BobProxy = proxy; + BobProxy = proxy.Cast(false); + break; + + case ConsumedCapability cap: + using (var temp = CapabilityReflection.CreateProxy(cap)) + { + Bob = temp; + } break; case Skeleton skeleton: - BobProxy = CapabilityReflection.CreateProxy( - LocalCapability.Create(skeleton)); - break; - - case ConsumedCapability cap: - BobProxy = CapabilityReflection.CreateProxy(cap); - break; - - case null: + using (var nullProxy = new Proxy()) + { + Bob = (object?)skeleton.AsCapability() ?? nullProxy; + } break; default: - BobProxy = CapabilityReflection.CreateProxy( - LocalCapability.Create( - Skeleton.GetOrCreateSkeleton(value, false))); + Bob = CapabilityReflection.CreateSkeletonInternal(value); break; } + + _bob = value; } } } @@ -197,7 +195,7 @@ namespace Capnp.Rpc.Interception readonly CensorCapability _censorCapability; PromisedAnswer _promisedAnswer; - object? _bob; + object _bob; internal IPromisedAnswer Answer => _promisedAnswer; @@ -205,13 +203,14 @@ namespace Capnp.Rpc.Interception { _censorCapability = censorCapability; _promisedAnswer = new PromisedAnswer(this); + _inArgs = inArgs; + _bob = null!; // Will be initialized later here CancelFromAlice = _promisedAnswer.CancelFromAlice; CancelToBob = CancelFromAlice; Bob = censorCapability.InterceptedCapability; InterfaceId = interfaceId; MethodId = methodId; - InArgs = inArgs; State = InterceptionState.RequestedFromAlice; } @@ -253,12 +252,8 @@ namespace Capnp.Rpc.Interception /// Intercepts all capabilies inside the input arguments /// /// Policy to use, or null to further use present policy - /// InArgs not set public void InterceptInCaps(IInterceptionPolicy? policyOverride = null) { - if (InArgs == null) - throw new InvalidOperationException("InArgs not set"); - InterceptCaps(InArgs, policyOverride ?? _censorCapability.Policy); } @@ -275,12 +270,8 @@ namespace Capnp.Rpc.Interception /// Unintercepts all capabilies inside the input arguments /// /// Policy to remove, or null to remove present policy - /// InArgs not set public void UninterceptInCaps(IInterceptionPolicy? policyOverride = null) { - if (InArgs == null) - throw new InvalidOperationException("InArgs not set"); - UninterceptCaps(InArgs, policyOverride ?? _censorCapability.Policy); } @@ -296,15 +287,8 @@ namespace Capnp.Rpc.Interception /// /// Forwards this intercepted call to the target capability ("Bob"). /// - /// Bob/InArgs not set public void ForwardToBob() { - if (Bob == null) - throw new InvalidOperationException("Bob is null"); - - if (InArgs == null) - throw new InvalidOperationException("InArgs not set"); - var answer = BobProxy!.Call(InterfaceId, MethodId, InArgs.Rewrap(), default, CancelToBob); State = InterceptionState.ForwardedToBob; diff --git a/Capnp.Net.Runtime/Rpc/Interception/CensorCapability.cs b/Capnp.Net.Runtime/Rpc/Interception/CensorCapability.cs index 89573ba..cef2dc2 100644 --- a/Capnp.Net.Runtime/Rpc/Interception/CensorCapability.cs +++ b/Capnp.Net.Runtime/Rpc/Interception/CensorCapability.cs @@ -1,4 +1,6 @@ -namespace Capnp.Rpc.Interception +using System; + +namespace Capnp.Rpc.Interception { class CensorCapability : RefCountingCapability { @@ -7,12 +9,10 @@ InterceptedCapability = interceptedCapability; interceptedCapability.AddRef(); Policy = policy; - MyVine = Vine.Create(this); } public ConsumedCapability InterceptedCapability { get; } public IInterceptionPolicy Policy { get; } - internal Skeleton MyVine { get; } protected override void ReleaseRemotely() { @@ -26,19 +26,11 @@ return cc.Answer; } - internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) + internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) { writer.which = CapDescriptor.WHICH.SenderHosted; - writer.SenderHosted = endpoint.AllocateExport(MyVine, out bool _); - } - - internal override void Freeze(out IRpcEndpoint? boundEndpoint) - { - boundEndpoint = null; - } - - internal override void Unfreeze() - { + writer.SenderHosted = endpoint.AllocateExport(AsSkeleton(), out bool _); + return null; } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/Interception/Interceptor.cs b/Capnp.Net.Runtime/Rpc/Interception/Interceptor.cs index 1413f6c..ae692fd 100644 --- a/Capnp.Net.Runtime/Rpc/Interception/Interceptor.cs +++ b/Capnp.Net.Runtime/Rpc/Interception/Interceptor.cs @@ -9,9 +9,6 @@ namespace Capnp.Rpc.Interception /// public static class Interceptor { - static readonly ConditionalWeakTable _interceptMap = - new ConditionalWeakTable(); - /// /// Attach this policy to given capability. /// @@ -45,16 +42,16 @@ namespace Capnp.Rpc.Interception switch (cap) { case Proxy proxy: - return (CapabilityReflection.CreateProxy(Attach(policy, proxy.ConsumedCap!)) as TCap)!; + return (CapabilityReflection.CreateProxy( + Attach(policy, proxy.ConsumedCap!)) as TCap)!; case ConsumedCapability ccap: return (new CensorCapability(ccap, policy) as TCap)!; default: - return (Attach(policy, - (CapabilityReflection.CreateProxy( - LocalCapability.Create( - Skeleton.GetOrCreateSkeleton(cap, false))) as TCap)!)); + var temp = (CapabilityReflection.CreateProxy( + CapabilityReflection.CreateSkeletonInternal(cap).AsCapability())) as TCap; + return Attach(policy, temp!)!; } } diff --git a/Capnp.Net.Runtime/Rpc/LazyCapability.cs b/Capnp.Net.Runtime/Rpc/LazyCapability.cs index 965d054..d1e2f4a 100644 --- a/Capnp.Net.Runtime/Rpc/LazyCapability.cs +++ b/Capnp.Net.Runtime/Rpc/LazyCapability.cs @@ -1,39 +1,76 @@ -using System; +using Capnp.Util; +using System; using System.Threading; using System.Threading.Tasks; namespace Capnp.Rpc { + class LazyCapability : RefCountingCapability, IResolvingCapability { public static LazyCapability CreateBrokenCap(string message) { - var cap = new LazyCapability(Task.FromException(new RpcException(message))); - cap.AddRef(); // Instance shall be persistent - return cap; + return new LazyCapability(Task.FromException(new RpcException(message))); } public static LazyCapability CreateCanceledCap(CancellationToken token) { - var cap = new LazyCapability(Task.FromCanceled(token)); - cap.AddRef(); // Instance shall be persistent - return cap; + return new LazyCapability(Task.FromCanceled(token)); } - public static LazyCapability Null { get; } = CreateBrokenCap("Null capability"); + readonly StrictlyOrderedAwaitTask? _proxyTask; + readonly StrictlyOrderedAwaitTask _capTask; - public LazyCapability(Task capabilityTask) + public LazyCapability(Task capabilityTask) { - WhenResolved = capabilityTask; + _capTask = capabilityTask.EnforceAwaitOrder(); } - internal override void Freeze(out IRpcEndpoint? boundEndpoint) + public LazyCapability(Task proxyTask) { - if (WhenResolved.IsCompleted) + _proxyTask = proxyTask.EnforceAwaitOrder(); + + async Task AwaitCap() => (await _proxyTask!).ConsumedCap; + + _capTask = AwaitCap().EnforceAwaitOrder(); + } + + internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) + { + if (WhenResolved.IsCompleted && WhenResolved.WrappedTask.ReplacementTaskIsCompletedSuccessfully()) + { + using var proxy = GetResolvedCapability()!; + return proxy.Export(endpoint, writer); + } + else + { + return this.ExportAsSenderPromise(endpoint, writer); + } + } + + protected override void ReleaseRemotely() + { + if (_proxyTask != null) + { + async void DisposeProxyWhenResolved() + { + try { using var _ = await _proxyTask!; } + catch { } + } + + DisposeProxyWhenResolved(); + } + } + + public StrictlyOrderedAwaitTask WhenResolved => _capTask; + + public T? GetResolvedCapability() where T: class + { + if (_capTask.WrappedTask.IsCompleted) { try { - WhenResolved.Result.Freeze(out boundEndpoint); + return (CapabilityReflection.CreateProxy(_capTask.Result) as T)!; } catch (AggregateException exception) { @@ -42,55 +79,31 @@ namespace Capnp.Rpc } else { - boundEndpoint = null; + return null; } } - internal override void Unfreeze() - { - } - - internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) - { - if (WhenResolved.ReplacementTaskIsCompletedSuccessfully()) - { - WhenResolved.Result.Export(endpoint, writer); - } - else - { - this.ExportAsSenderPromise(endpoint, writer); - } - } - - async void DisposeProxyWhenResolved() - { - try - { - var cap = await WhenResolved; - if (cap != null) cap.Dispose(); - } - catch - { - } - } - - protected override void ReleaseRemotely() - { - DisposeProxyWhenResolved(); - } - - public Task WhenResolved { get; } - async Task CallImpl(ulong interfaceId, ushort methodId, DynamicSerializerState args, CancellationToken cancellationToken) { - var cap = await WhenResolved; + ConsumedCapability cap; + try + { + cap = await _capTask; + } + catch + { + args.Dispose(); + throw; + } - cancellationToken.ThrowIfCancellationRequested(); + if (cancellationToken.IsCancellationRequested) + { + args.Dispose(); + cancellationToken.ThrowIfCancellationRequested(); + } - if (cap == null) - throw new RpcException("Broken capability"); - - var call = cap.Call(interfaceId, methodId, args, default); + using var proxy = new Proxy(cap); + var call = proxy.Call(interfaceId, methodId, args, default); var whenReturned = call.WhenReturned; using (var registration = cancellationToken.Register(call.Dispose)) diff --git a/Capnp.Net.Runtime/Rpc/LocalAnswer.cs b/Capnp.Net.Runtime/Rpc/LocalAnswer.cs index 8744cb6..294412e 100644 --- a/Capnp.Net.Runtime/Rpc/LocalAnswer.cs +++ b/Capnp.Net.Runtime/Rpc/LocalAnswer.cs @@ -1,4 +1,5 @@ -using System; +using Capnp.Util; +using System; using System.Threading; using System.Threading.Tasks; @@ -11,42 +12,36 @@ namespace Capnp.Rpc public LocalAnswer(CancellationTokenSource cts, Task call) { _cts = cts ?? throw new ArgumentNullException(nameof(cts)); - WhenReturned = call ?? throw new ArgumentNullException(nameof(call)); + WhenReturned = call?.EnforceAwaitOrder() ?? throw new ArgumentNullException(nameof(call)); CleanupAfterReturn(); } async void CleanupAfterReturn() { - try - { - await WhenReturned; - } - catch - { - } - finally - { - _cts.Dispose(); - } + try { await WhenReturned; } + catch { } + finally { _cts.Dispose(); } } - public Task WhenReturned { get; } + public StrictlyOrderedAwaitTask WhenReturned { get; } + + public bool IsTailCall => false; public ConsumedCapability Access(MemberAccessPath access) { return new LocalAnswerCapability(WhenReturned, access); } + public ConsumedCapability Access(MemberAccessPath _, Task task) + { + return new LocalAnswerCapability(task.AsProxyTask()); + } + public void Dispose() { - try - { - _cts.Cancel(); - } - catch (ObjectDisposedException) - { - } + try { _cts.Cancel(); } + catch (ObjectDisposedException) { } } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/LocalAnswerCapability.cs b/Capnp.Net.Runtime/Rpc/LocalAnswerCapability.cs index 195d139..f615ec5 100644 --- a/Capnp.Net.Runtime/Rpc/LocalAnswerCapability.cs +++ b/Capnp.Net.Runtime/Rpc/LocalAnswerCapability.cs @@ -1,78 +1,77 @@ -using System; +using Capnp.Util; +using System; using System.Threading; using System.Threading.Tasks; namespace Capnp.Rpc { + class LocalAnswerCapability : RefCountingCapability, IResolvingCapability { - readonly Task _answer; - readonly MemberAccessPath _access; - - public LocalAnswerCapability(Task answer, MemberAccessPath access) + static async Task TransferOwnershipToDummyProxy(StrictlyOrderedAwaitTask answer, MemberAccessPath access) { - _answer = answer; - _access = access; + var result = await answer; + var cap = access.Eval(result); + var proxy = new Proxy(cap); + cap?.Release(); + return proxy; } - internal override void Freeze(out IRpcEndpoint? boundEndpoint) + readonly StrictlyOrderedAwaitTask _whenResolvedProxy; + + public LocalAnswerCapability(Task proxyTask) { - boundEndpoint = null; + _whenResolvedProxy = proxyTask.EnforceAwaitOrder(); } - internal override void Unfreeze() + public LocalAnswerCapability(StrictlyOrderedAwaitTask answer, MemberAccessPath access): + this(TransferOwnershipToDummyProxy(answer, access)) { + } - async Task AwaitResolved() - { - var state = await _answer; - return new Proxy(_access.Eval(state)); - } + public StrictlyOrderedAwaitTask WhenResolved => _whenResolvedProxy; - public Task WhenResolved => AwaitResolved(); + public T? GetResolvedCapability() where T : class => _whenResolvedProxy.WrappedTask.GetResolvedCapability(); - internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) + internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) { - if (_answer.IsCompleted) + if (_whenResolvedProxy.IsCompleted) { - DeserializerState result; try { - result = _answer.Result; + _whenResolvedProxy.Result.Export(endpoint, writer); } catch (AggregateException exception) { throw exception.InnerException!; } - using (var proxy = new Proxy(_access.Eval(result))) - { - proxy.Export(endpoint, writer); - } + return null; } else { - this.ExportAsSenderPromise(endpoint, writer); + return this.ExportAsSenderPromise(endpoint, writer); } } async Task CallImpl(ulong interfaceId, ushort methodId, DynamicSerializerState args, CancellationToken cancellationToken) { - var cap = await AwaitResolved(); + var proxy = await _whenResolvedProxy; cancellationToken.ThrowIfCancellationRequested(); - if (cap == null) + if (proxy.IsNull) + { + args.Dispose(); throw new RpcException("Broken capability"); + } - var call = cap.Call(interfaceId, methodId, args, default); + var call = proxy.Call(interfaceId, methodId, args, default); var whenReturned = call.WhenReturned; - using (var registration = cancellationToken.Register(() => call.Dispose())) - { - return await whenReturned; - } + using var registration = cancellationToken.Register(() => call.Dispose()); + return await whenReturned; } internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args) @@ -81,9 +80,10 @@ namespace Capnp.Rpc return new LocalAnswer(cts, CallImpl(interfaceId, methodId, args, cts.Token)); } - protected override void ReleaseRemotely() + protected async override void ReleaseRemotely() { - this.DisposeWhenResolved(); + try { using var _ = await _whenResolvedProxy; } + catch { } } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/LocalCapability.cs b/Capnp.Net.Runtime/Rpc/LocalCapability.cs index 23b0ced..4024f32 100644 --- a/Capnp.Net.Runtime/Rpc/LocalCapability.cs +++ b/Capnp.Net.Runtime/Rpc/LocalCapability.cs @@ -7,17 +7,6 @@ namespace Capnp.Rpc { class LocalCapability : ConsumedCapability { - static readonly ConditionalWeakTable _localCaps = - new ConditionalWeakTable(); - - public static ConsumedCapability Create(Skeleton skeleton) - { - if (skeleton is Vine vine) - return vine.Proxy.ConsumedCap!; - else - return _localCaps.GetValue(skeleton, _ => new LocalCapability(_)); - } - static async Task AwaitAnswer(Task call) { var aorcq = await call; @@ -26,7 +15,9 @@ namespace Capnp.Rpc public Skeleton ProvidedCap { get; } - LocalCapability(Skeleton providedCap) + internal override Skeleton AsSkeleton() => ProvidedCap; + + public LocalCapability(Skeleton providedCap) { ProvidedCap = providedCap ?? throw new ArgumentNullException(nameof(providedCap)); } @@ -36,10 +27,7 @@ namespace Capnp.Rpc ProvidedCap.Claim(); } - internal override void Release( - [System.Runtime.CompilerServices.CallerMemberName] string methodName = "", - [System.Runtime.CompilerServices.CallerFilePath] string filePath = "", - [System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0) + internal override void Release() { ProvidedCap.Relinquish(); } @@ -51,19 +39,11 @@ namespace Capnp.Rpc return new LocalAnswer(cts, AwaitAnswer(call)); } - internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER capDesc) + internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER capDesc) { capDesc.which = CapDescriptor.WHICH.SenderHosted; capDesc.SenderHosted = endpoint.AllocateExport(ProvidedCap, out bool _); - } - - internal override void Freeze(out IRpcEndpoint? boundEndpoint) - { - boundEndpoint = null; - } - - internal override void Unfreeze() - { + return null; } protected override void ReleaseRemotely() diff --git a/Capnp.Net.Runtime/Rpc/MemberAccessPath.cs b/Capnp.Net.Runtime/Rpc/MemberAccessPath.cs index 4843c08..1eaed67 100644 --- a/Capnp.Net.Runtime/Rpc/MemberAccessPath.cs +++ b/Capnp.Net.Runtime/Rpc/MemberAccessPath.cs @@ -132,7 +132,7 @@ namespace Capnp.Rpc { if (state.Kind == ObjectKind.Nil) { - return default(DeserializerState); + return default; } if (state.Kind != ObjectKind.Struct) @@ -169,7 +169,7 @@ namespace Capnp.Rpc /// The object (usually "params struct") on which to evaluate this path. /// Resulting low-level capability /// Evaluation of this path did not give a capability - public ConsumedCapability? Eval(DeserializerState rpcState) + public ConsumedCapability Eval(DeserializerState rpcState) { var cur = rpcState; @@ -181,7 +181,7 @@ namespace Capnp.Rpc switch (cur.Kind) { case ObjectKind.Nil: - return null; + return NullCapability.Instance; case ObjectKind.Capability: return rpcState.Caps![(int)cur.CapabilityIndex]; diff --git a/Capnp.Net.Runtime/Rpc/NoResultsException.cs b/Capnp.Net.Runtime/Rpc/NoResultsException.cs new file mode 100644 index 0000000..5bb0269 --- /dev/null +++ b/Capnp.Net.Runtime/Rpc/NoResultsException.cs @@ -0,0 +1,16 @@ +namespace Capnp.Rpc +{ + /// + /// Thrown when a pending question did return, but was not configured to deliver the result back to the sender + /// (typcial for tail calls). + /// + public class NoResultsException: System.Exception + { + /// + /// Creates an instance + /// + public NoResultsException(): base("Pending question did return, but was not configured to deliver the result back to the sender") + { + } + } +} \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/NullCapability.cs b/Capnp.Net.Runtime/Rpc/NullCapability.cs new file mode 100644 index 0000000..55e20d0 --- /dev/null +++ b/Capnp.Net.Runtime/Rpc/NullCapability.cs @@ -0,0 +1,54 @@ +using System; + +namespace Capnp.Rpc +{ + /// + /// Null capability + /// + public sealed class NullCapability : ConsumedCapability + { + /// + /// Singleton instance + /// + public static readonly NullCapability Instance = new NullCapability(); + + NullCapability() + { + } + + /// + /// Does nothing + /// + protected override void ReleaseRemotely() + { + } + + internal override void AddRef() + { + } + + internal override Skeleton AsSkeleton() => NullSkeleton.Instance; + + internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args) + { + args.Dispose(); + throw new InvalidOperationException("Cannot call null capability"); + } + + internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) + { + writer.which = CapDescriptor.WHICH.None; + return null; + } + + internal override void Release() + { + } + + /// + /// String hint + /// + /// "Null capability" + public override string ToString() => "Null capability"; + } +} \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/NullSkeleton.cs b/Capnp.Net.Runtime/Rpc/NullSkeleton.cs new file mode 100644 index 0000000..17cd828 --- /dev/null +++ b/Capnp.Net.Runtime/Rpc/NullSkeleton.cs @@ -0,0 +1,41 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Capnp.Rpc +{ + /// + /// Null skeleton + /// + public sealed class NullSkeleton : Skeleton + { + /// + /// Singleton instance + /// + public static readonly NullSkeleton Instance = new NullSkeleton(); + + NullSkeleton() + { + } + + /// + /// Always throws an exception + /// + /// always thrown + public override Task Invoke(ulong interfaceId, ushort methodId, DeserializerState args, CancellationToken cancellationToken = default) + { + args.Dispose(); + throw new InvalidOperationException("Cannot call null capability"); + } + + internal override ConsumedCapability AsCapability() => NullCapability.Instance; + + internal override void Claim() + { + } + + internal override void Relinquish() + { + } + } +} \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/PendingAnswer.cs b/Capnp.Net.Runtime/Rpc/PendingAnswer.cs index 5959b7e..e4fb99f 100644 --- a/Capnp.Net.Runtime/Rpc/PendingAnswer.cs +++ b/Capnp.Net.Runtime/Rpc/PendingAnswer.cs @@ -1,4 +1,6 @@ -using System; +using Capnp.Util; +using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -8,7 +10,7 @@ namespace Capnp.Rpc { readonly CancellationTokenSource? _cts; readonly TaskCompletionSource _cancelCompleter; - readonly Task _answerTask; + readonly StrictlyOrderedAwaitTask _answerTask; public PendingAnswer(Task callTask, CancellationTokenSource? cts) { @@ -22,92 +24,136 @@ namespace Capnp.Rpc _cts = cts; _cancelCompleter = new TaskCompletionSource(); - _answerTask = CancelableAwaitWhenReady(); + _answerTask = CancelableAwaitWhenReady().EnforceAwaitOrder(); + + TakeCapTableOwnership(); + } + + async void TakeCapTableOwnership() + { + try + { + var aorcq = await _answerTask; + + if (aorcq.Answer != null) + { + if (aorcq.Answer.Caps != null) + { + foreach (var cap in aorcq.Answer.Caps) + { + cap.AddRef(); + } + } + } + } + catch + { + } + } + + async void ReleaseCapTableOwnership() + { + try + { + var aorcq = await _answerTask; + if (aorcq.Answer != null) + { + if (aorcq.Answer.Caps != null) + { + foreach (var cap in aorcq.Answer.Caps) + { + cap?.Release(); + } + } + } + } + catch + { + } } public CancellationToken CancellationToken => _cts?.Token ?? CancellationToken.None; + public IReadOnlyList? CapTable { get; set; } + public void Cancel() { _cts?.Cancel(); _cancelCompleter.SetCanceled(); } - public void Chain(Action> func) + public void Chain(Action> func) { func(_answerTask); } public void Chain(PromisedAnswer.READER rd, Action> func) { - Chain(t => + async Task EvaluateProxy() { - async Task EvaluateProxy() + var aorcq = await _answerTask; + + if (aorcq.Answer != null) { - var aorcq = await t; + DeserializerState cur = aorcq.Answer; - if (aorcq.Answer != null) + foreach (var op in rd.Transform) { - DeserializerState cur = aorcq.Answer; - - foreach (var op in rd.Transform) + switch (op.which) { - switch (op.which) - { - case PromisedAnswer.Op.WHICH.GetPointerField: - try - { - cur = cur.StructReadPointer(op.GetPointerField); - } - catch (System.Exception) - { - throw new ArgumentOutOfRangeException("Illegal pointer field in transformation operation"); - } - break; - - case PromisedAnswer.Op.WHICH.Noop: - break; - - default: - throw new ArgumentOutOfRangeException("Unknown transformation operation"); - } - } - - Proxy proxy; - - switch (cur.Kind) - { - case ObjectKind.Capability: + case PromisedAnswer.Op.WHICH.GetPointerField: try { - var cap = aorcq.Answer.Caps![(int)cur.CapabilityIndex]; - proxy = new Proxy(cap ?? LazyCapability.Null); + cur = cur.StructReadPointer(op.GetPointerField); } - catch (ArgumentOutOfRangeException) + catch (System.Exception) { - throw new ArgumentOutOfRangeException("Bad capability table in internal answer - internal error?"); + throw new RpcException("Illegal pointer field in transformation operation"); } - return proxy; + break; + + case PromisedAnswer.Op.WHICH.Noop: + break; default: - throw new ArgumentOutOfRangeException("Transformation did not result in a capability"); + throw new ArgumentOutOfRangeException("Unknown transformation operation"); } } - else + + switch (cur.Kind) { - var path = MemberAccessPath.Deserialize(rd); - var cap = new RemoteAnswerCapability(aorcq.Counterquestion!, path); - return new Proxy(cap); + case ObjectKind.Capability: + try + { + return new Proxy(aorcq.Answer.Caps![(int)cur.CapabilityIndex]); + } + catch (ArgumentOutOfRangeException) + { + throw new RpcException("Capability index out of range"); + } + + case ObjectKind.Nil: + return new Proxy(NullCapability.Instance); + + default: + throw new ArgumentOutOfRangeException("Transformation did not result in a capability"); } } + else + { + var path = MemberAccessPath.Deserialize(rd); + var cap = new RemoteAnswerCapability(aorcq.Counterquestion!, path); + return new Proxy(cap); + } + } - func(EvaluateProxy()); - }); + func(EvaluateProxy()); } public void Dispose() { _cts?.Dispose(); + ReleaseCapTableOwnership(); } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/PendingQuestion.cs b/Capnp.Net.Runtime/Rpc/PendingQuestion.cs index 227f189..73e074c 100644 --- a/Capnp.Net.Runtime/Rpc/PendingQuestion.cs +++ b/Capnp.Net.Runtime/Rpc/PendingQuestion.cs @@ -1,4 +1,6 @@ -using System; +using Capnp.Util; +using System; +using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; @@ -48,36 +50,25 @@ namespace Capnp.Rpc /// /// Question object was disposed. /// - Disposed = 16, - - /// - /// Question object was finalized by GC. - /// This flag should only be observable when debugging the finalizer itself. - /// - Finalized = 32 + CanceledByDispose = 16 } readonly TaskCompletionSource _tcs = new TaskCompletionSource(); + readonly StrictlyOrderedAwaitTask _whenReturned; readonly uint _questionId; ConsumedCapability? _target; SerializerState? _inParams; - int _inhibitFinishCounter; + int _inhibitFinishCounter, _refCounter; - internal PendingQuestion(IRpcEndpoint ep, uint id, ConsumedCapability? target, SerializerState? inParams) + internal PendingQuestion(IRpcEndpoint ep, uint id, ConsumedCapability target, SerializerState? inParams) { RpcEndpoint = ep ?? throw new ArgumentNullException(nameof(ep)); _questionId = id; _target = target; _inParams = inParams; - StateFlags = inParams == null ? State.Sent : State.None; + _whenReturned = _tcs.Task.EnforceAwaitOrder(); - if (inParams != null) - { - foreach (var cap in inParams.Caps!) - { - cap?.AddRef(); - } - } + StateFlags = inParams == null ? State.Sent : State.None; if (target != null) { @@ -89,16 +80,20 @@ namespace Capnp.Rpc internal object ReentrancyBlocker { get; } = new object(); internal uint QuestionId => _questionId; internal State StateFlags { get; private set; } + internal IReadOnlyList? CapTable { get; set; } /// /// Eventually returns the server answer /// - public Task WhenReturned => _tcs.Task; + public StrictlyOrderedAwaitTask WhenReturned => _whenReturned; - internal bool IsTailCall + /// + /// Whether this question represents a tail call + /// + public bool IsTailCall { get => StateFlags.HasFlag(State.TailCall); - set + internal set { if (value) StateFlags |= State.TailCall; @@ -106,7 +101,6 @@ namespace Capnp.Rpc StateFlags &= ~State.TailCall; } } - internal bool IsReturned => StateFlags.HasFlag(State.Returned); internal void DisallowFinish() { @@ -119,7 +113,25 @@ namespace Capnp.Rpc AutoFinish(); } + internal void AddRef() + { + lock (ReentrancyBlocker) + { + ++_refCounter; + } + } + + internal void Release() + { + lock (ReentrancyBlocker) + { + --_refCounter; + AutoFinish(); + } + } + const string ReturnDespiteTailCallMessage = "Peer sent actual results despite the question was sent as tail call. This was not expected and is a protocol error."; + const string UnexpectedTailCallReturnMessage = "Peer sent the results of this questions somewhere else. This was not expected and is a protocol error."; internal void OnReturn(DeserializerState results) { @@ -131,6 +143,7 @@ namespace Capnp.Rpc if (StateFlags.HasFlag(State.TailCall)) { _tcs.TrySetException(new RpcException(ReturnDespiteTailCallMessage)); + throw new RpcProtocolErrorException(ReturnDespiteTailCallMessage); } else { @@ -150,7 +163,8 @@ namespace Capnp.Rpc if (!StateFlags.HasFlag(State.TailCall)) { - _tcs.TrySetException(new RpcException("Peer sent the results of this questions somewhere else. This was not expected and is a protocol error.")); + _tcs.TrySetException(new RpcException(UnexpectedTailCallReturnMessage)); + throw new RpcProtocolErrorException(UnexpectedTailCallReturnMessage); } else { @@ -165,7 +179,7 @@ namespace Capnp.Rpc SetReturned(); } - _tcs.TrySetException(new RpcException(exception.Reason)); + _tcs.TrySetException(new RpcException(exception.Reason ?? "unknown reason")); } internal void OnException(System.Exception exception) @@ -193,11 +207,6 @@ namespace Capnp.Rpc RpcEndpoint.DeleteQuestion(this); } - internal void RequestFinish() - { - RpcEndpoint.Finish(_questionId); - } - void AutoFinish() { if (StateFlags.HasFlag(State.FinishRequested)) @@ -205,12 +214,13 @@ namespace Capnp.Rpc return; } - if ((_inhibitFinishCounter == 0 && StateFlags.HasFlag(State.Returned) && !StateFlags.HasFlag(State.TailCall)) - || StateFlags.HasFlag(State.Disposed)) + if ((!IsTailCall && _inhibitFinishCounter == 0 && StateFlags.HasFlag(State.Returned)) || + ( IsTailCall && _refCounter == 0 && StateFlags.HasFlag(State.Returned)) || + StateFlags.HasFlag(State.CanceledByDispose)) { StateFlags |= State.FinishRequested; - RequestFinish(); + RpcEndpoint.Finish(_questionId); } } @@ -234,50 +244,27 @@ namespace Capnp.Rpc /// Access path /// Low-level capability /// The referenced member does not exist or does not resolve to a capability pointer. - public ConsumedCapability? Access(MemberAccessPath access) - { - lock (ReentrancyBlocker) - { - if ( StateFlags.HasFlag(State.Returned) && - !StateFlags.HasFlag(State.TailCall)) - { - try - { - return access.Eval(WhenReturned.Result); - } - catch (AggregateException exception) - { - throw exception.InnerException!; - } - } - else - { - return new RemoteAnswerCapability(this, access); - } - } - } + public ConsumedCapability Access(MemberAccessPath access) => new RemoteAnswerCapability(this, access); - static void ReleaseCaps(ConsumedCapability? target, SerializerState? inParams) + /// + /// Refer to a (possibly nested) member of this question's (possibly future) result and return + /// it as a capability. + /// + /// Access path + /// promises the cap whose ownership is transferred to this object + /// Low-level capability + /// The referenced member does not exist or does not resolve to a capability pointer. + public ConsumedCapability Access(MemberAccessPath access, Task task) { - if (inParams != null) - { - foreach (var cap in inParams.Caps!) - { - cap?.Release(); - } - } - - if (target != null) - { - target.Release(); - } + var proxyTask = task.AsProxyTask(); + return new RemoteAnswerCapability(this, access, proxyTask); } static void ReleaseOutCaps(DeserializerState outParams) { foreach (var cap in outParams.Caps!) { - cap?.Release(); + cap.Release(); } } @@ -299,70 +286,24 @@ namespace Capnp.Rpc } var msg = (Message.WRITER)inParams!.MsgBuilder!.Root!; - Debug.Assert(msg.Call.Target.which != MessageTarget.WHICH.undefined); + Debug.Assert(msg.Call!.Target.which != MessageTarget.WHICH.undefined); var call = msg.Call; call.QuestionId = QuestionId; - call.SendResultsTo.which = IsTailCall ? - Call.sendResultsTo.WHICH.Yourself : + call.SendResultsTo.which = IsTailCall ? + Call.sendResultsTo.WHICH.Yourself : Call.sendResultsTo.WHICH.Caller; try { RpcEndpoint.SendQuestion(inParams, call.Params); + CapTable = call.Params.CapTable; } catch (System.Exception exception) { OnException(exception); } - ReleaseCaps(target!, inParams); - } - - #region IDisposable Support - - void Dispose(bool disposing) - { - SerializerState? inParams; - ConsumedCapability? target; - bool justDisposed = false; - - lock (ReentrancyBlocker) - { - inParams = _inParams; - _inParams = null; - target = _target; - _target = null; - - if (disposing) - { - if (!StateFlags.HasFlag(State.Disposed)) - { - StateFlags |= State.Disposed; - justDisposed = true; - - AutoFinish(); - } - } - else - { - StateFlags |= State.Finalized; - } - } - - ReleaseCaps(target, inParams); - - if (justDisposed) - { - _tcs.TrySetCanceled(); - } - } - - /// - /// Finalizer - /// - ~PendingQuestion() - { - Dispose(false); + target?.Release(); } /// @@ -370,9 +311,23 @@ namespace Capnp.Rpc /// public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); + bool justDisposed = false; + + lock (ReentrancyBlocker) + { + if (!StateFlags.HasFlag(State.CanceledByDispose)) + { + StateFlags |= State.CanceledByDispose; + justDisposed = true; + + AutoFinish(); + } + } + + if (justDisposed) + { + _tcs.TrySetCanceled(); + } } - #endregion } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/PolySkeleton.cs b/Capnp.Net.Runtime/Rpc/PolySkeleton.cs index 002a75f..cf08a03 100644 --- a/Capnp.Net.Runtime/Rpc/PolySkeleton.cs +++ b/Capnp.Net.Runtime/Rpc/PolySkeleton.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -8,7 +9,7 @@ namespace Capnp.Rpc /// /// Combines multiple skeletons to represent objects which implement multiple interfaces. /// - public class PolySkeleton: Skeleton + public class PolySkeleton: RefCountingSkeleton { readonly Dictionary _ifmap = new Dictionary(); @@ -24,8 +25,9 @@ namespace Capnp.Rpc if (skeleton == null) throw new ArgumentNullException(nameof(skeleton)); - skeleton.Claim(); _ifmap.Add(interfaceId, skeleton); + if (_ifmap.Count == 1) // Claiming only the first one is sufficient + skeleton.Claim(); } internal void AddInterface(Skeleton skeleton) @@ -54,17 +56,16 @@ namespace Capnp.Rpc /// protected override void Dispose(bool disposing) { - foreach (var cap in _ifmap.Values) + foreach (var cap in _ifmap.Values.Take(1)) + // releasing first skeleton is sufficient. Avoid double-Dispose! { cap.Relinquish(); } - - base.Dispose(disposing); } internal override void Bind(object impl) { - foreach (Skeleton skel in _ifmap.Values) + foreach (Skeleton skel in _ifmap.Values) { skel.Bind(impl); } diff --git a/Capnp.Net.Runtime/Rpc/PromisedCapability.cs b/Capnp.Net.Runtime/Rpc/PromisedCapability.cs index 083a13d..652dc71 100644 --- a/Capnp.Net.Runtime/Rpc/PromisedCapability.cs +++ b/Capnp.Net.Runtime/Rpc/PromisedCapability.cs @@ -1,4 +1,5 @@ -using System; +using Capnp.Util; +using System; using System.Diagnostics; using System.Threading.Tasks; @@ -8,78 +9,30 @@ namespace Capnp.Rpc { readonly uint _remoteId; readonly object _reentrancyBlocker = new object(); - readonly TaskCompletionSource _resolvedCap = new TaskCompletionSource(); + readonly TaskCompletionSource _resolvedCap = new TaskCompletionSource(); + readonly StrictlyOrderedAwaitTask _whenResolvedProxy; bool _released; public PromisedCapability(IRpcEndpoint ep, uint remoteId): base(ep) { _remoteId = remoteId; + + async Task AwaitProxy() => new Proxy(await _resolvedCap.Task); + _whenResolvedProxy = AwaitProxy().EnforceAwaitOrder(); } - public override Task WhenResolved => _resolvedCap.Task; + public override StrictlyOrderedAwaitTask WhenResolved => _whenResolvedProxy; + public override T? GetResolvedCapability() where T: class => _whenResolvedProxy.WrappedTask.GetResolvedCapability(); - internal override void Freeze(out IRpcEndpoint? boundEndpoint) - { - lock (_reentrancyBlocker) - { - if (_resolvedCap.Task.IsCompleted && _pendingCallsOnPromise == 0) - { - try - { - _resolvedCap.Task.Result.Freeze(out boundEndpoint); - } - catch (AggregateException exception) - { - throw exception.InnerException!; - } - } - else - { - Debug.Assert(!_released); - ++_pendingCallsOnPromise; - - boundEndpoint = _ep; - } - } - } - - internal override void Unfreeze() - { - bool release = false; - - lock (_reentrancyBlocker) - { - if (_pendingCallsOnPromise == 0) - { - _resolvedCap.Task.Result.Unfreeze(); - } - else - { - Debug.Assert(_pendingCallsOnPromise > 0); - Debug.Assert(!_released); - - if (--_pendingCallsOnPromise == 0 && _resolvedCap.Task.IsCompleted) - { - release = true; - _released = true; - } - } - } - - if (release) - { - _ep.ReleaseImport(_remoteId); - } - } - - internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) + internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) { lock (_reentrancyBlocker) { if (_resolvedCap.Task.ReplacementTaskIsCompletedSuccessfully()) { - _resolvedCap.Task.Result.Export(endpoint, writer); + using var proxy = new Proxy(_resolvedCap.Task.Result); + proxy.Export(endpoint, writer); } else { @@ -91,7 +44,7 @@ namespace Capnp.Rpc Debug.Assert(!_released); ++_pendingCallsOnPromise; - _ep.RequestPostAction(() => + return () => { bool release = false; @@ -108,7 +61,7 @@ namespace Capnp.Rpc { _ep.ReleaseImport(_remoteId); } - }); + }; } else { @@ -116,9 +69,11 @@ namespace Capnp.Rpc } } } + + return null; } - async void TrackCall(Task call) + async void TrackCall(StrictlyOrderedAwaitTask call) { try { @@ -147,7 +102,7 @@ namespace Capnp.Rpc } } - protected override Proxy? ResolvedCap + protected override ConsumedCapability? ResolvedCap { get { @@ -194,7 +149,11 @@ namespace Capnp.Rpc lock (_reentrancyBlocker) { - _resolvedCap.SetResult(new Proxy(resolvedCap)); +#if DebugFinalizers + if (resolvedCap != null) + resolvedCap.ResolvingCap = this; +#endif + _resolvedCap.SetResult(resolvedCap!); if (_pendingCallsOnPromise == 0) { @@ -218,7 +177,7 @@ namespace Capnp.Rpc #if false _resolvedCap.SetException(new RpcException(message)); #else - _resolvedCap.SetResult(new Proxy(LazyCapability.CreateBrokenCap(message))); + _resolvedCap.SetResult(LazyCapability.CreateBrokenCap(message)); #endif if (_pendingCallsOnPromise == 0) @@ -234,16 +193,16 @@ namespace Capnp.Rpc } } - protected override void ReleaseRemotely() + protected async override void ReleaseRemotely() { if (!_released) { + _released = true; _ep.ReleaseImport(_remoteId); } - _ep.ReleaseImport(_remoteId); - - this.DisposeWhenResolved(); + try { using var _ = await _whenResolvedProxy; } + catch { } } protected override Call.WRITER SetupMessage(DynamicSerializerState args, ulong interfaceId, ushort methodId) diff --git a/Capnp.Net.Runtime/Rpc/Proxy.cs b/Capnp.Net.Runtime/Rpc/Proxy.cs index ed0a976..715b341 100644 --- a/Capnp.Net.Runtime/Rpc/Proxy.cs +++ b/Capnp.Net.Runtime/Rpc/Proxy.cs @@ -1,4 +1,7 @@ -using System; +using Capnp.Util; +using Microsoft.Extensions.Logging; +using System; +using System.Diagnostics; using System.Threading; using System.Threading.Tasks; @@ -10,53 +13,70 @@ namespace Capnp.Rpc /// public class Proxy : IDisposable, IResolvingCapability { -#if DebugFinalizers - ILogger Logger { get; } = Logging.CreateLogger(); -#endif + /// + /// Creates a new proxy object for an existing implementation or proxy, sharing its ownership. + /// + /// Capability interface + /// instance to share + /// + public static T Share(T obj) where T : class + { + if (obj is Proxy proxy) + return proxy.Cast(false); + else + return BareProxy.FromImpl(obj).Cast(true); + } bool _disposedValue = false; /// - /// Will eventually give the resolved capability, if this is a promised capability. + /// Completes when the capability gets resolved. /// - public Task WhenResolved + public StrictlyOrderedAwaitTask WhenResolved { get { - if (ConsumedCap is IResolvingCapability resolving) - { - return resolving.WhenResolved; - } - else - { - return Task.FromResult(this); - } + return ConsumedCap is IResolvingCapability resolving ? + resolving.WhenResolved : Task.CompletedTask.EnforceAwaitOrder(); } } + /// + /// Returns the resolved capability + /// + /// Capability interface or + /// the resolved capability, or null if it did not resolve yet + public T? GetResolvedCapability() where T : class + { + if (ConsumedCap is IResolvingCapability resolving) + return resolving.GetResolvedCapability(); + else + return CapabilityReflection.CreateProxy(ConsumedCap) as T; + } + + ConsumedCapability _consumedCap = NullCapability.Instance; + /// /// Underlying low-level capability /// - protected internal ConsumedCapability? ConsumedCap { get; private set; } + public ConsumedCapability ConsumedCap => _disposedValue ? + throw new ObjectDisposedException(nameof(Proxy)) : _consumedCap; /// /// Whether is this a broken capability. /// - public bool IsNull => ConsumedCap == null; + public bool IsNull => _consumedCap == NullCapability.Instance; + + /// + /// Whether was called on this Proxy. + /// + public bool IsDisposed => _disposedValue; static async void DisposeCtrWhenReturned(CancellationTokenRegistration ctr, IPromisedAnswer answer) { - try - { - await answer.WhenReturned; - } - catch - { - } - finally - { - ctr.Dispose(); - } + try { await answer.WhenReturned; } + catch { } + finally { ctr.Dispose(); } } /// @@ -76,10 +96,10 @@ namespace Capnp.Rpc bool obsoleteAndIgnored, CancellationToken cancellationToken = default) { if (_disposedValue) + { + args.Dispose(); throw new ObjectDisposedException(nameof(Proxy)); - - if (ConsumedCap == null) - throw new InvalidOperationException("Cannot call null capability"); + } var answer = ConsumedCap.DoCall(interfaceId, methodId, args); @@ -96,38 +116,34 @@ namespace Capnp.Rpc /// public Proxy() { +#if DebugFinalizers + CreatorStackTrace = Environment.StackTrace; +#endif } - internal Proxy(ConsumedCapability? cap) + internal Proxy(ConsumedCapability cap): this() { Bind(cap); } - internal void Bind(ConsumedCapability? cap) + internal void Bind(ConsumedCapability cap) { - if (ConsumedCap != null) + if (ConsumedCap != NullCapability.Instance) throw new InvalidOperationException("Proxy was already bound"); - if (cap == null) - return; - - ConsumedCap = cap; + _consumedCap = cap ?? throw new ArgumentNullException(nameof(cap)); cap.AddRef(); + +#if DebugFinalizers + if (_consumedCap != null) + _consumedCap.OwningProxy = this; +#endif } - internal IProvidedCapability? GetProvider() + internal async Task GetProvider() { - switch (ConsumedCap) - { - case LocalCapability lcap: - return lcap.ProvidedCap; - - case null: - return null; - - default: - return Vine.Create(ConsumedCap); - } + var unwrapped = await ConsumedCap.Unwrap(); + return unwrapped.AsSkeleton(); } /// @@ -139,20 +155,15 @@ namespace Capnp.Rpc { if (disposing) { - ConsumedCap?.Release(); + _consumedCap.Release(); } else { // When called from the Finalizer, we must not throw. // But when reference counting goes wrong, ConsumedCapability.Release() will throw an InvalidOperationException. // The only option here is to suppress that exception. - try - { - ConsumedCap?.Release(); - } - catch - { - } + try { _consumedCap?.Release(); } + catch { } } _disposedValue = true; @@ -165,7 +176,7 @@ namespace Capnp.Rpc ~Proxy() { #if DebugFinalizers - Logger.LogWarning($"Caught orphaned Proxy, created from {CreatorMemberName} in {CreatorFilePath}, line {CreatorLineNumber}."); + Debugger.Log(0, "DebugFinalizers", $"Caught orphaned Proxy, created from here: {CreatorStackTrace}."); #endif Dispose(false); @@ -187,54 +198,37 @@ namespace Capnp.Rpc /// Whether to Dispose() this Proxy instance /// Proxy for desired capability interface /// did not qualify as capability interface. - /// This capability is broken, or mismatch between generic type arguments (if capability interface is generic). + /// Mismatch between generic type arguments (if capability interface is generic). /// Mismatch between generic type arguments (if capability interface is generic). /// Problem with instatiating the Proxy (constructor threw exception). /// Caller does not have permission to invoke the Proxy constructor. /// Problem with building the Proxy type, or problem with loading some dependent class. public T Cast(bool disposeThis) where T: class { - if (IsNull) - throw new InvalidOperationException("Capability is broken"); - using (disposeThis ? this : null) { return (CapabilityReflection.CreateProxy(ConsumedCap) as T)!; } } - internal void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) + internal Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) { if (_disposedValue) throw new ObjectDisposedException(nameof(Proxy)); if (ConsumedCap == null) + { writer.which = CapDescriptor.WHICH.None; + return null; + } else - ConsumedCap.Export(endpoint, writer); - } - - internal void Freeze(out IRpcEndpoint? boundEndpoint) - { - if (_disposedValue) - throw new ObjectDisposedException(nameof(Proxy)); - - boundEndpoint = null; - ConsumedCap?.Freeze(out boundEndpoint); - } - - internal void Unfreeze() - { - if (_disposedValue) - throw new ObjectDisposedException(nameof(Proxy)); - - ConsumedCap?.Unfreeze(); + { + return ConsumedCap.Export(endpoint, writer); + } } #if DebugFinalizers - public string CreatorMemberName { get; set; } - public string CreatorFilePath { get; set; } - public int CreatorLineNumber { get; set; } + string CreatorStackTrace { get; set; } #endif } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/RefCountingCapability.cs b/Capnp.Net.Runtime/Rpc/RefCountingCapability.cs index e64378c..f8ae439 100644 --- a/Capnp.Net.Runtime/Rpc/RefCountingCapability.cs +++ b/Capnp.Net.Runtime/Rpc/RefCountingCapability.cs @@ -7,6 +7,7 @@ namespace Capnp.Rpc abstract class RefCountingCapability: ConsumedCapability { readonly object _reentrancyBlocker = new object(); + Vine? _vine; // Note on reference counting: Works in analogy to COM. AddRef() adds a reference, // Release() removes it. When the reference count reaches zero, the capability must be @@ -26,16 +27,24 @@ namespace Capnp.Rpc // Value 0 has the special meaning of being in state C. long _refCount = 1; -#if DebugCapabilityLifecycle +#if DebugFinalizers ILogger Logger { get; } = Logging.CreateLogger(); - - string? _releasingMethodName; - string? _releasingFilePath; - int _releasingLineNumber; + string CreatorStackTrace { get; set; } #endif + public RefCountingCapability() + { +#if DebugFinalizers + CreatorStackTrace = Environment.StackTrace; +#endif + } + ~RefCountingCapability() { +#if DebugFinalizers + Logger?.LogWarning($"Caught orphaned capability, created from here: {CreatorStackTrace}."); +#endif + Dispose(false); } @@ -46,13 +55,8 @@ namespace Capnp.Rpc { if (disposing) { - try - { - ReleaseRemotely(); - } - catch - { - } + try { ReleaseRemotely(); } + catch { } } else { @@ -60,19 +64,14 @@ namespace Capnp.Rpc { Task.Run(() => { - try - { - ReleaseRemotely(); - } - catch - { - } + try { ReleaseRemotely(); } + catch { } }); } } } - internal sealed override void AddRef() + internal override void AddRef() { lock (_reentrancyBlocker) { @@ -90,10 +89,7 @@ namespace Capnp.Rpc } } - internal sealed override void Release( - [System.Runtime.CompilerServices.CallerMemberName] string methodName = "", - [System.Runtime.CompilerServices.CallerFilePath] string filePath = "", - [System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0) + internal override void Release() { lock (_reentrancyBlocker) { @@ -103,12 +99,6 @@ namespace Capnp.Rpc case 2: // actually ref. count 1 _refCount = 0; -#if DebugCapabilityLifecycle - _releasingMethodName = methodName; - _releasingFilePath = filePath; - _releasingLineNumber = lineNumber; -#endif - Dispose(true); GC.SuppressFinalize(this); break; @@ -133,5 +123,15 @@ namespace Capnp.Rpc } } } + + internal override Skeleton AsSkeleton() + { + lock (_reentrancyBlocker) + { + if (_vine == null) + _vine = new Vine(this); + return _vine; + } + } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/RefCountingSkeleton.cs b/Capnp.Net.Runtime/Rpc/RefCountingSkeleton.cs new file mode 100644 index 0000000..7c1359a --- /dev/null +++ b/Capnp.Net.Runtime/Rpc/RefCountingSkeleton.cs @@ -0,0 +1,80 @@ +using System; +using System.Threading; + +namespace Capnp.Rpc +{ + /// + /// Skeleton with reference counting and dispose pattern + /// + public abstract class RefCountingSkeleton: Skeleton + { + int _refCount; + LocalCapability? _localCap; + + /// + /// Dispose pattern implementation + /// + protected virtual void Dispose(bool disposing) + { + } + + /// + /// Finalizer + /// + ~RefCountingSkeleton() + { + Dispose(false); + } + + internal sealed override void Claim() + { + int count, newCount; + + do + { + count = Volatile.Read(ref _refCount); + if (count < 0) + throw new ObjectDisposedException(nameof(RefCountingSkeleton)); + + newCount = count + 1; + + } while (Interlocked.CompareExchange(ref _refCount, newCount, count) != count); + } + + internal override void Relinquish() + { + int count, newCount; + + do + { + count = Volatile.Read(ref _refCount); + if (count < 0) + throw new ObjectDisposedException(nameof(RefCountingSkeleton)); + + newCount = count > 0 ? count - 1 : int.MinValue; + + } while (Interlocked.CompareExchange(ref _refCount, newCount, count) != count); + + if (newCount == 0) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + /// + /// Whether this instance is in disposed state. + /// + public bool IsDisposed => Volatile.Read(ref _refCount) < 0; + + internal override ConsumedCapability AsCapability() + { + var cap = Volatile.Read(ref _localCap); + if (cap == null) + { + Interlocked.CompareExchange(ref _localCap, new LocalCapability(this), null); + } + return Volatile.Read(ref _localCap)!; + } + } +} \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/RemoteAnswerCapability.cs b/Capnp.Net.Runtime/Rpc/RemoteAnswerCapability.cs index e3269e6..d09bd49 100644 --- a/Capnp.Net.Runtime/Rpc/RemoteAnswerCapability.cs +++ b/Capnp.Net.Runtime/Rpc/RemoteAnswerCapability.cs @@ -1,4 +1,5 @@ -using System; +using Capnp.Util; +using System; using System.Threading.Tasks; namespace Capnp.Rpc @@ -16,17 +17,29 @@ namespace Capnp.Rpc readonly PendingQuestion _question; readonly MemberAccessPath _access; - Proxy? _resolvedCap; + readonly StrictlyOrderedAwaitTask _whenResolvedProxy; - public RemoteAnswerCapability(PendingQuestion question, MemberAccessPath access): base(question.RpcEndpoint) + public RemoteAnswerCapability(PendingQuestion question, MemberAccessPath access, Task proxyTask) : base(question.RpcEndpoint) { _question = question ?? throw new ArgumentNullException(nameof(question)); _access = access ?? throw new ArgumentNullException(nameof(access)); - - _ = AwaitWhenResolved(); + _whenResolvedProxy = (proxyTask ?? throw new ArgumentNullException(nameof(proxyTask))).EnforceAwaitOrder(); } - async void ReAllowFinishWhenDone(Task task) + static async Task TransferOwnershipToDummyProxy(PendingQuestion question, MemberAccessPath access) + { + var result = await question.WhenReturned; + var cap = access.Eval(result); + var proxy = new Proxy(cap); + cap?.Release(); + return proxy; + } + + public RemoteAnswerCapability(PendingQuestion question, MemberAccessPath access) : this(question, access, TransferOwnershipToDummyProxy(question, access)) + { + } + + async void ReAllowFinishWhenDone(StrictlyOrderedAwaitTask task) { try { @@ -47,57 +60,39 @@ namespace Capnp.Rpc } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - lock (_question.ReentrancyBlocker) - { - _resolvedCap?.Dispose(); - } - } - - protected override Proxy? ResolvedCap + protected override ConsumedCapability? ResolvedCap { get { lock (_question.ReentrancyBlocker) { - if (_resolvedCap == null && !_question.IsTailCall && _question.IsReturned) + if (!_question.IsTailCall && _question.StateFlags.HasFlag(PendingQuestion.State.Returned)) { - DeserializerState result; try { - result = _question.WhenReturned.Result; + return _whenResolvedProxy.Result.ConsumedCap; } catch (AggregateException exception) { throw exception.InnerException!; } - - _resolvedCap = new Proxy(_access.Eval(result)); } - return _resolvedCap; + else + { + return null; + } } } } - async Task AwaitWhenResolved() - { - await _question.WhenReturned; + public override StrictlyOrderedAwaitTask WhenResolved => _whenResolvedProxy; - if (_question.IsTailCall) - throw new InvalidOperationException("Question is a tail call, so won't resolve back."); - - return ResolvedCap!; - } - - public override Task WhenResolved => AwaitWhenResolved(); + public override T? GetResolvedCapability() where T: class => _whenResolvedProxy.WrappedTask.GetResolvedCapability(); protected override void GetMessageTarget(MessageTarget.WRITER wr) { wr.which = MessageTarget.WHICH.PromisedAnswer; - wr.PromisedAnswer.QuestionId = _question.QuestionId; + wr.PromisedAnswer!.QuestionId = _question.QuestionId; _access.Serialize(wr.PromisedAnswer); } @@ -105,14 +100,9 @@ namespace Capnp.Rpc { lock (_question.ReentrancyBlocker) { - if (_question.StateFlags.HasFlag(PendingQuestion.State.Returned) && - !_question.StateFlags.HasFlag(PendingQuestion.State.TailCall)) + if (!_question.StateFlags.HasFlag(PendingQuestion.State.TailCall) && + _question.StateFlags.HasFlag(PendingQuestion.State.Returned)) { - if (ResolvedCap == null) - { - throw new RpcException("Answer did not resolve to expected capability"); - } - return CallOnResolution(interfaceId, methodId, args); } else @@ -120,16 +110,13 @@ namespace Capnp.Rpc #if DebugEmbargos Logger.LogDebug("Call by proxy"); #endif - if (_question.StateFlags.HasFlag(PendingQuestion.State.Disposed)) + if (_question.StateFlags.HasFlag(PendingQuestion.State.CanceledByDispose) || + _question.StateFlags.HasFlag(PendingQuestion.State.FinishRequested)) { + args.Dispose(); throw new ObjectDisposedException(nameof(PendingQuestion)); } - if (_question.StateFlags.HasFlag(PendingQuestion.State.FinishRequested)) - { - throw new InvalidOperationException("Finish request was already sent"); - } - _question.DisallowFinish(); ++_pendingCallsOnPromise; var promisedAnswer = base.DoCall(interfaceId, methodId, args); @@ -164,61 +151,22 @@ namespace Capnp.Rpc var call = base.SetupMessage(args, interfaceId, methodId); call.Target.which = MessageTarget.WHICH.PromisedAnswer; - call.Target.PromisedAnswer.QuestionId = _question.QuestionId; + call.Target.PromisedAnswer!.QuestionId = _question.QuestionId; _access.Serialize(call.Target.PromisedAnswer); return call; } - internal override void Freeze(out IRpcEndpoint? boundEndpoint) + internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) { lock (_question.ReentrancyBlocker) { - if (_question.StateFlags.HasFlag(PendingQuestion.State.Returned) && - _pendingCallsOnPromise == 0) - { - if (ResolvedCap == null) - { - throw new RpcException("Answer did not resolve to expected capability"); - } - - ResolvedCap.Freeze(out boundEndpoint); - } - else - { - ++_pendingCallsOnPromise; - _question.DisallowFinish(); - boundEndpoint = _ep; - } - } - } - - internal override void Unfreeze() - { - lock (_question.ReentrancyBlocker) - { - if (_pendingCallsOnPromise > 0) - { - --_pendingCallsOnPromise; - _question.AllowFinish(); - } - else - { - ResolvedCap?.Unfreeze(); - } - } - } - - internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer) - { - lock (_question.ReentrancyBlocker) - { - if (_question.StateFlags.HasFlag(PendingQuestion.State.Disposed)) + if (_question.StateFlags.HasFlag(PendingQuestion.State.CanceledByDispose)) throw new ObjectDisposedException(nameof(PendingQuestion)); - if (_question.StateFlags.HasFlag(PendingQuestion.State.Returned)) + if (_question.StateFlags.HasFlag(PendingQuestion.State.Returned) && !_question.IsTailCall) { - ResolvedCap?.Export(endpoint, writer); + ResolvedCap!.Export(endpoint, writer); } else { @@ -228,32 +176,45 @@ namespace Capnp.Rpc if (endpoint == _ep) { writer.which = CapDescriptor.WHICH.ReceiverAnswer; - _access.Serialize(writer.ReceiverAnswer); - writer.ReceiverAnswer.QuestionId = _question.QuestionId; + _access.Serialize(writer.ReceiverAnswer!); + writer.ReceiverAnswer!.QuestionId = _question.QuestionId; } else if (_question.IsTailCall) { - // FIXME: Resource management! We should prevent finishing this - // cap as long as it is exported. Unfortunately, we cannot determine - // when it gets removed from the export table. - - var vine = Vine.Create(this); - uint id = endpoint.AllocateExport(vine, out bool first); + uint id = endpoint.AllocateExport(AsSkeleton(), out bool first); writer.which = CapDescriptor.WHICH.SenderHosted; writer.SenderHosted = id; } else { - this.ExportAsSenderPromise(endpoint, writer); + return this.ExportAsSenderPromise(endpoint, writer); } } } + + return null; } - protected override void ReleaseRemotely() + protected async override void ReleaseRemotely() { - this.DisposeWhenResolved(); + if (!_question.IsTailCall) + { + try { using var _ = await _whenResolvedProxy; } + catch { } + } + } + + internal override void AddRef() + { + base.AddRef(); + _question.AddRef(); + } + + internal override void Release() + { + _question.Release(); + base.Release(); } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/RemoteCapability.cs b/Capnp.Net.Runtime/Rpc/RemoteCapability.cs index f198b29..f767fff 100644 --- a/Capnp.Net.Runtime/Rpc/RemoteCapability.cs +++ b/Capnp.Net.Runtime/Rpc/RemoteCapability.cs @@ -13,6 +13,8 @@ namespace Capnp.Rpc _ep = ep; } + internal IRpcEndpoint Endpoint => _ep; + internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args) { var call = SetupMessage(args, interfaceId, methodId); @@ -29,7 +31,7 @@ namespace Capnp.Rpc callMsg.which = Message.WHICH.Call; - var call = callMsg.Call; + var call = callMsg.Call!; call.AllowThirdPartyTailCall = false; call.InterfaceId = interfaceId; call.MethodId = methodId; diff --git a/Capnp.Net.Runtime/Rpc/RemoteResolvingCapability.cs b/Capnp.Net.Runtime/Rpc/RemoteResolvingCapability.cs index 225c8e1..0c39e5c 100644 --- a/Capnp.Net.Runtime/Rpc/RemoteResolvingCapability.cs +++ b/Capnp.Net.Runtime/Rpc/RemoteResolvingCapability.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Logging; +using Capnp.Util; +using Microsoft.Extensions.Logging; using System; using System.Threading; using System.Threading.Tasks; @@ -16,105 +17,89 @@ namespace Capnp.Rpc ILogger Logger { get; } = Logging.CreateLogger(); #endif - public abstract Task WhenResolved { get; } + public abstract StrictlyOrderedAwaitTask WhenResolved { get; } + public abstract T? GetResolvedCapability() where T : class; protected RemoteResolvingCapability(IRpcEndpoint ep) : base(ep) { } protected int _pendingCallsOnPromise; - Task? _disembargo; + StrictlyOrderedAwaitTask? _disembargo; - protected abstract Proxy? ResolvedCap { get; } + protected abstract ConsumedCapability? ResolvedCap { get; } protected abstract void GetMessageTarget(MessageTarget.WRITER wr); protected IPromisedAnswer CallOnResolution(ulong interfaceId, ushort methodId, DynamicSerializerState args) { - if (ResolvedCap == null) - throw new InvalidOperationException("Capability not yet resolved, calling on resolution not possible"); + var resolvedCap = ResolvedCap!; try { - ResolvedCap.Freeze(out var resolvedCapEndpoint); + if (resolvedCap is NullCapability || + // Must not request disembargo on null cap - try + resolvedCap is RemoteCapability || + //# Note that in the case where Carol actually lives in Vat B (i.e., the same vat that the promise + //# already pointed at), no embargo is needed, because the pipelined calls are delivered over the + //# same path as the later direct calls. + + (_disembargo == null && _pendingCallsOnPromise == 0) || + // No embargo is needed since all outstanding replies have returned + + _disembargo?.IsCompleted == true + // Disembargo has returned + ) { - if (resolvedCapEndpoint != null && resolvedCapEndpoint != _ep) - { - // Carol lives in a different Vat C. - throw new NotImplementedException("Sorry, level 3 RPC is not yet supported."); - } - - if (ResolvedCap.IsNull || - // If the capability resolves to null, disembargo must not be requested. - // Take the direct path, well-knowing that the call will result in an exception. - - resolvedCapEndpoint != null || - //# Note that in the case where Carol actually lives in Vat B (i.e., the same vat that the promise - //# already pointed at), no embargo is needed, because the pipelined calls are delivered over the - //# same path as the later direct calls. - - (_disembargo == null && _pendingCallsOnPromise == 0) || - // No embargo is needed since all outstanding replies have returned - - _disembargo?.IsCompleted == true - // Disembargo has returned - ) +#if DebugEmbargos + Logger.LogDebug("Direct call"); +#endif + using var proxy = new Proxy(resolvedCap); + return proxy.Call(interfaceId, methodId, args, default); + } + else + { + if (_disembargo == null) { #if DebugEmbargos - Logger.LogDebug("Direct call"); + Logger.LogDebug("Requesting disembargo"); #endif - return ResolvedCap.Call(interfaceId, methodId, args, default); + _disembargo = _ep.RequestSenderLoopback(GetMessageTarget).EnforceAwaitOrder(); } else { - if (_disembargo == null) - { #if DebugEmbargos - Logger.LogDebug("Requesting disembargo"); + Logger.LogDebug("Waiting for requested disembargo"); #endif - _disembargo = _ep.RequestSenderLoopback(GetMessageTarget); - } - else - { -#if DebugEmbargos - Logger.LogDebug("Waiting for requested disembargo"); -#endif - } - - var cancellationTokenSource = new CancellationTokenSource(); - - var callAfterDisembargo = _disembargo.ContinueWith(_ => - { - // Two reasons for ignoring exceptions on the previous task (i.e. not _.Wait()ing): - // 1. A faulting predecessor, especially due to cancellation, must not have any impact on this one. - // 2. A faulting disembargo request would be a fatal protocol error, resulting in Abort() - we're dead anyway. - - cancellationTokenSource.Token.ThrowIfCancellationRequested(); - - return ResolvedCap.Call(interfaceId, methodId, args, default); - - }, TaskContinuationOptions.ExecuteSynchronously); - - _disembargo = callAfterDisembargo; - - async Task AwaitAnswer() - { - var promisedAnswer = await callAfterDisembargo; - - using (cancellationTokenSource.Token.Register(promisedAnswer.Dispose)) - { - return await promisedAnswer.WhenReturned; - } - } - - return new LocalAnswer(cancellationTokenSource, AwaitAnswer()); } - } - finally - { - ResolvedCap.Unfreeze(); + + var cancellationTokenSource = new CancellationTokenSource(); + + async Task AwaitAnswer() + { + await _disembargo!; + + // Two reasons for ignoring exceptions on the previous task (i.e. not _.Wait()ing): + // 1. A faulting predecessor, especially due to cancellation, must not have any impact on this one. + // 2. A faulting disembargo request would imply that the other side cannot send pending requests anyway. + + if (cancellationTokenSource.Token.IsCancellationRequested) + { + args.Dispose(); + cancellationTokenSource.Token.ThrowIfCancellationRequested(); + } + + using var proxy = new Proxy(resolvedCap); + var promisedAnswer = proxy.Call(interfaceId, methodId, args, default); + + using (cancellationTokenSource.Token.Register(promisedAnswer.Dispose)) + { + return await promisedAnswer.WhenReturned; + } + } + + return new LocalAnswer(cancellationTokenSource, AwaitAnswer()); } } catch (System.Exception exception) diff --git a/Capnp.Net.Runtime/Rpc/ResolvingCapabilityExtensions.cs b/Capnp.Net.Runtime/Rpc/ResolvingCapabilityExtensions.cs index 9b68f7e..3fb8cbc 100644 --- a/Capnp.Net.Runtime/Rpc/ResolvingCapabilityExtensions.cs +++ b/Capnp.Net.Runtime/Rpc/ResolvingCapabilityExtensions.cs @@ -1,11 +1,27 @@ -namespace Capnp.Rpc +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Capnp.Rpc { static class ResolvingCapabilityExtensions { - public static void ExportAsSenderPromise(this T cap, IRpcEndpoint endpoint, CapDescriptor.WRITER writer) + public static async Task Unwrap(this ConsumedCapability cap) + { + while (cap is IResolvingCapability resolving) + { + await resolving.WhenResolved; + using var proxy = resolving.GetResolvedCapability()!; + cap = proxy.ConsumedCap; + } + + return cap; + } + + public static Action? ExportAsSenderPromise(this T cap, IRpcEndpoint endpoint, CapDescriptor.WRITER writer) where T: ConsumedCapability, IResolvingCapability { - var vine = Vine.Create(cap); + var vine = cap.AsSkeleton(); uint preliminaryId = endpoint.AllocateExport(vine, out bool first); writer.which = CapDescriptor.WHICH.SenderPromise; @@ -13,31 +29,70 @@ if (first) { - endpoint.RequestPostAction(async () => { + return async () => { try { - var resolvedCap = await cap.WhenResolved; - - endpoint.Resolve(preliminaryId, vine, () => resolvedCap.ConsumedCap!); + await cap.WhenResolved; + using var proxy = cap.GetResolvedCapability()!; + var resolvedCap = await Unwrap(proxy.ConsumedCap); + endpoint.Resolve(preliminaryId, vine, () => resolvedCap!); } catch (System.Exception exception) { endpoint.Resolve(preliminaryId, vine, () => throw exception); } - }); + }; + } + + return null; + } + + public static async Task AsProxyTask(this Task task) + where T: IDisposable? + { + IDisposable? obj; + try + { + obj = await task; + } + catch (TaskCanceledException exception) + { + var token = exception.CancellationToken; + if (!token.IsCancellationRequested) + token = new CancellationToken(true); + return new Proxy(LazyCapability.CreateCanceledCap(token)); + } + catch (System.Exception exception) + { + return new Proxy(LazyCapability.CreateBrokenCap(exception.Message)); + } + + switch (obj) + { + case Proxy proxy: return proxy; + case null: return new Proxy(NullCapability.Instance); + default: return BareProxy.FromImpl(obj); } } - public static async void DisposeWhenResolved(this IResolvingCapability cap) + public static T? GetResolvedCapability(this Task proxyTask) where T: class { - try + if (proxyTask.IsCompleted) { - (await cap.WhenResolved)?.Dispose(); + try + { + return proxyTask.Result.Cast(false); + } + catch (AggregateException exception) + { + throw exception.InnerException!; + } } - catch + else { + return null; } } } diff --git a/Capnp.Net.Runtime/Rpc/RpcEngine.cs b/Capnp.Net.Runtime/Rpc/RpcEngine.cs index d38e7aa..787b711 100644 --- a/Capnp.Net.Runtime/Rpc/RpcEngine.cs +++ b/Capnp.Net.Runtime/Rpc/RpcEngine.cs @@ -30,16 +30,9 @@ namespace Capnp.Rpc ++RefCount; } - public void Release() - { - --RefCount; - CheckDispose(); - } - public void ReleaseAll() { RefCount = 0; - CheckDispose(); } public void Release(int count) @@ -48,36 +41,98 @@ namespace Capnp.Rpc throw new ArgumentOutOfRangeException(nameof(count)); RefCount -= count; - CheckDispose(); - } - - void CheckDispose() - { - if (RefCount == 0 && Cap is IDisposable disposable) - { - disposable.Dispose(); - } } } - internal class RpcEndpoint : IEndpoint, IRpcEndpoint + /// + /// Stateful implementation for hosting a two-party RPC session. may own multiple mutually + /// independent endpoints. + /// + public class RpcEndpoint : IEndpoint, IRpcEndpoint { - static readonly ThreadLocal _exportCapTablePostActions = new ThreadLocal(); - static readonly ThreadLocal _tailCall = new ThreadLocal(); + /// + /// Endpoint state + /// + public enum EndpointState + { + /// + /// Active means ready for exchanging RPC messages. + /// + Active, + + /// + /// The session is closed, either deliberately or due to an error condition. + /// + Dismissed + } + + class FlushContext + { + readonly FlushContext? _prev; + readonly RpcEndpoint _ep; + bool _requested; + + public FlushContext(FlushContext? prev, RpcEndpoint ep) + { + _prev = prev; + _ep = ep; + _requested = false; + } + + public RpcEndpoint Ep => _ep; + + public void Request() + { + _requested = true; + } + + public void Remove() + { + _flushRequests.Value = _prev; + + if (_requested) + _ep._tx.Flush(); + } + } + + readonly struct FlushContextKeeper: IDisposable + { + readonly FlushContext _context; + readonly bool _owner; + + public FlushContextKeeper(FlushContext context, bool owner) + { + _context = context; + _owner = owner; + } + + public void Dispose() + { + if (_owner) + { + _context.Remove(); + } + } + + } + + static readonly ThreadLocal _deferredCall = new ThreadLocal(); static readonly ThreadLocal _canDeferCalls = new ThreadLocal(); + static readonly ThreadLocal _flushRequests = new ThreadLocal(); ILogger Logger { get; } = Logging.CreateLogger(); readonly RpcEngine _host; readonly IEndpoint _tx; - readonly Dictionary>> _importTable = new Dictionary>>(); + readonly Dictionary> _importTable = new Dictionary>(); readonly Dictionary> _exportTable = new Dictionary>(); readonly Dictionary _revExportTable = new Dictionary(); readonly Dictionary _questionTable = new Dictionary(); readonly Dictionary _answerTable = new Dictionary(); readonly Dictionary> _pendingDisembargos = new Dictionary>(); readonly object _reentrancyBlocker = new object(); + readonly object _callReturnBlocker = new object(); long _recvCount; long _sendCount; @@ -87,8 +142,17 @@ namespace Capnp.Rpc { _host = host; _tx = tx; + State = EndpointState.Active; } + /// + /// Session state + /// + public EndpointState State { get; private set; } + + /// + /// Closes the session, clears export table, terminates all pending questions and enters 'Dismissed' state. + /// public void Dismiss() { lock (_reentrancyBlocker) @@ -105,25 +169,127 @@ namespace Capnp.Rpc _answerTable.Clear(); _pendingDisembargos.Clear(); + + State = EndpointState.Dismissed; } _tx.Dismiss(); } + /// + /// Feeds a frame for processing + /// + /// frame to process public void Forward(WireFrame frame) { + if (State == EndpointState.Dismissed) + throw new InvalidOperationException("Endpoint is in dismissed state and doesn't accept frames anymore"); + Interlocked.Increment(ref _recvCount); ProcessFrame(frame); } + void IEndpoint.Flush() + { + } + + /// + /// Number of frames sent so far + /// public long SendCount => Interlocked.Read(ref _sendCount); + + /// + /// Number of frames received so far + /// public long RecvCount => Interlocked.Read(ref _recvCount); + /// + /// Current number of entries in import table + /// + public int ImportedCapabilityCount + { + get + { + lock (_reentrancyBlocker) + { + return _importTable.Count; + } + } + } + + /// + /// Current number of entries in export table + /// + public int ExportedCapabilityCount + { + get + { + lock (_reentrancyBlocker) + { + return _exportTable.Count; + } + } + } + + /// + /// Current number of unanswered questions + /// + public int PendingQuestionCount + { + get + { + lock (_reentrancyBlocker) + { + return _questionTable.Count; + } + } + } + + /// + /// Current number of unfinished answers + /// + public int PendingAnswerCount + { + get + { + lock (_reentrancyBlocker) + { + return _answerTable.Count; + } + } + } + + FlushContextKeeper SetupFlushContext() + { + if (_flushRequests.Value?.Ep == this) + { + return new FlushContextKeeper(_flushRequests.Value, false); + } + else + { + _flushRequests.Value = new FlushContext(_flushRequests.Value, this); + return new FlushContextKeeper(_flushRequests.Value, true); + } + } + + void RequestFlush() + { + if (_flushRequests.Value?.Ep == this) + { + _flushRequests.Value.Request(); + } + else + { + _tx.Flush(); + } + } + void Tx(WireFrame frame) { try { _tx.Forward(frame); + RequestFlush(); Interlocked.Increment(ref _sendCount); } catch (System.Exception exception) @@ -135,20 +301,27 @@ namespace Capnp.Rpc void SendAbort(string reason) { - var mb = MessageBuilder.Create(); - var msg = mb.BuildRoot(); - msg.which = Message.WHICH.Abort; - msg.Abort.Reason = reason; - Tx(mb.Frame); + try + { + var mb = MessageBuilder.Create(); + var msg = mb.BuildRoot(); + msg.which = Message.WHICH.Abort; + msg.Abort!.Reason = reason; + Tx(mb.Frame); + } + catch // Take care that an exception does not prevent shutdown. + { + } } void IRpcEndpoint.Resolve(uint preliminaryId, Skeleton preliminaryCap, Func resolvedCapGetter) { + using var fc = SetupFlushContext(); + lock (_reentrancyBlocker) { if (!_exportTable.TryGetValue(preliminaryId, out var existing) || - existing.Cap != preliminaryCap || - existing.RefCount == 0) + existing.Cap != preliminaryCap) { // Resolved too late. Capability was already released. return; @@ -161,18 +334,18 @@ namespace Capnp.Rpc var mb = MessageBuilder.Create(); var msg = mb.BuildRoot(); msg.which = Message.WHICH.Resolve; - var resolve = msg.Resolve; + var resolve = msg.Resolve!; try { var resolvedCap = resolvedCapGetter(); resolve.which = Resolve.WHICH.Cap; - resolvedCap.Export(this, resolve.Cap); + resolvedCap.Export(this, resolve.Cap!); } catch (System.Exception ex) { resolve.which = Resolve.WHICH.Exception; - resolve.Exception.Reason = ex.Message; + resolve.Exception!.Reason = ex.Message; } resolve.PromiseId = preliminaryId; @@ -194,16 +367,8 @@ namespace Capnp.Rpc if (_revExportTable.TryGetValue(providedCapability, out uint id)) { + _exportTable[id].AddRef(); first = false; - - if (_exportTable.TryGetValue(id, out var rc)) - { - rc.AddRef(); - } - else - { - Logger.LogError("Inconsistent export table: Capability with id {0} exists in reverse table only", id); - } } else { @@ -215,7 +380,6 @@ namespace Capnp.Rpc _revExportTable.Add(providedCapability, id); _exportTable.Add(id, new RefCounted(providedCapability)); - first = true; } @@ -228,45 +392,21 @@ namespace Capnp.Rpc return AllocateExport(providedCapability, out first); } - PendingQuestion AllocateQuestion(ConsumedCapability? target, SerializerState? inParams) + PendingQuestion AllocateQuestion(ConsumedCapability target, SerializerState? inParams) { lock (_reentrancyBlocker) { uint questionId = NextId(); - var question = new PendingQuestion(this, questionId, target, inParams); - - while (!_questionTable.ReplacementTryAdd(questionId, question)) - { + while (_questionTable.ContainsKey(questionId)) questionId = NextId(); - var oldQuestion = question; - question = new PendingQuestion(this, questionId, target, inParams); - oldQuestion.Dispose(); - } + + var question = new PendingQuestion(this, questionId, target, inParams); + _questionTable.Add(questionId, question); return question; } } - void DeleteQuestion(uint id, PendingQuestion question) - { - lock (_reentrancyBlocker) - { - if (!_questionTable.TryGetValue(id, out var existingQuestion)) - { - Logger.LogError("Attempting to delete unknown question ID. Race condition?"); - return; - } - - if (question != existingQuestion) - { - Logger.LogError("Found different question under given ID. WTF???"); - return; - } - - _questionTable.Remove(id); - } - } - (TaskCompletionSource, uint) AllocateDisembargo() { var tcs = new TaskCompletionSource(); @@ -292,7 +432,7 @@ namespace Capnp.Rpc var ans = bootstrap.MsgBuilder!.BuildRoot(); ans.which = Message.WHICH.Return; - var ret = ans.Return; + var ret = ans.Return!; ret.AnswerId = q; Task bootstrapTask; @@ -301,8 +441,8 @@ namespace Capnp.Rpc if (bootstrapCap != null) { ret.which = Return.WHICH.Results; - bootstrap.SetCapability(bootstrap.ProvideCapability(LocalCapability.Create(bootstrapCap))); - ret.Results.Content = bootstrap; + bootstrap.SetCapability(bootstrap.ProvideCapability(bootstrapCap.AsCapability())); + ret.Results!.Content = bootstrap; bootstrapTask = Task.FromResult(bootstrap); } @@ -311,7 +451,7 @@ namespace Capnp.Rpc Logger.LogWarning("Peer asked for bootstrap capability, but no bootstrap capability was set."); ret.which = Return.WHICH.Exception; - ret.Exception.Reason = "No bootstrap capability present"; + ret.Exception!.Reason = "No bootstrap capability present"; bootstrapTask = Task.FromException(new RpcException(ret.Exception.Reason)); } @@ -327,10 +467,11 @@ namespace Capnp.Rpc if (!added) { Logger.LogWarning("Incoming bootstrap request: Peer specified duplicate (not yet released?) answer ID."); + throw new RpcProtocolErrorException("Duplicate question ID"); } - if (bootstrapCap != null) + if (ret.Results != null) { ExportCapTableAndSend(bootstrap, ret.Results); } @@ -340,21 +481,37 @@ namespace Capnp.Rpc } } + void DispatchDeferredCalls() + { + var call = _deferredCall.Value; + _deferredCall.Value = null; + call?.Send(); + } void ProcessCall(Call.READER req) + { + lock (_callReturnBlocker) + { + ProcessCallLocked(req); + } + } + + void ProcessCallLocked(Call.READER req) { Return.WRITER SetupReturn(MessageBuilder mb) { var rmsg = mb.BuildRoot(); rmsg.which = Message.WHICH.Return; - var ret = rmsg.Return; + var ret = rmsg.Return!; ret.AnswerId = req.QuestionId; return ret; } - void ReturnCall(Action why) + void ReturnCallNoCapTable(Action why) { + DispatchDeferredCalls(); + var mb = MessageBuilder.Create(); mb.InitCapTable(); var ret = SetupReturn(mb); @@ -371,9 +528,9 @@ namespace Capnp.Rpc } } - IProvidedCapability? cap; + Skeleton callTargetCap; PendingAnswer pendingAnswer; - bool releaseParamCaps = false; + bool releaseParamCaps = true; void AwaitAnswerAndReply() { @@ -390,9 +547,7 @@ namespace Capnp.Rpc pendingAnswer.Cancel(); pendingAnswer.Dispose(); - SendAbort($"There is another pending answer for the same question ID {req.QuestionId}."); - - return; + throw new RpcProtocolErrorException($"There is another pending answer for the same question ID {req.QuestionId}."); } switch (req.SendResultsTo.which) @@ -408,7 +563,7 @@ namespace Capnp.Rpc { Debug.Fail("Either answer or counter question must be present"); } - else if (aorcq.Answer != null || aorcq.Counterquestion != _tailCall.Value) + else if (aorcq.Answer != null || aorcq.Counterquestion != _deferredCall.Value) { var results = aorcq.Answer ?? (DynamicSerializerState)(await aorcq.Counterquestion!.WhenReturned); var ret = SetupReturn(results.MsgBuilder!); @@ -417,13 +572,15 @@ namespace Capnp.Rpc { case Call.sendResultsTo.WHICH.Caller: ret.which = Return.WHICH.Results; - ret.Results.Content = results.Rewrap(); + ret.Results!.Content = results.Rewrap(); ret.ReleaseParamCaps = releaseParamCaps; + DispatchDeferredCalls(); ExportCapTableAndSend(results, ret.Results); + pendingAnswer.CapTable = ret.Results.CapTable; break; case Call.sendResultsTo.WHICH.Yourself: - ReturnCall(ret2 => + ReturnCallNoCapTable(ret2 => { ret2.which = Return.WHICH.ResultsSentElsewhere; ret2.ReleaseParamCaps = releaseParamCaps; @@ -433,11 +590,11 @@ namespace Capnp.Rpc } else if (aorcq.Counterquestion != null) { - _tailCall.Value = null; + _deferredCall.Value = null; aorcq.Counterquestion.IsTailCall = true; aorcq.Counterquestion.Send(); - ReturnCall(ret2 => + ReturnCallNoCapTable(ret2 => { ret2.which = Return.WHICH.TakeFromOtherQuestion; ret2.TakeFromOtherQuestion = aorcq.Counterquestion.QuestionId; @@ -447,7 +604,7 @@ namespace Capnp.Rpc } catch (TaskCanceledException) { - ReturnCall(ret => + ReturnCallNoCapTable(ret => { ret.which = Return.WHICH.Canceled; ret.ReleaseParamCaps = releaseParamCaps; @@ -455,10 +612,10 @@ namespace Capnp.Rpc } catch (System.Exception exception) { - ReturnCall(ret => + ReturnCallNoCapTable(ret => { ret.which = Return.WHICH.Exception; - ret.Exception.Reason = exception.Message; + ret.Exception!.Reason = exception.Message; ret.ReleaseParamCaps = releaseParamCaps; }); } @@ -477,7 +634,7 @@ namespace Capnp.Rpc } finally { - ReturnCall(ret => + ReturnCallNoCapTable(ret => { ret.which = Return.WHICH.ResultsSentElsewhere; ret.ReleaseParamCaps = releaseParamCaps; @@ -492,28 +649,27 @@ namespace Capnp.Rpc { var inParams = req.Params.Content; inParams.Caps = ImportCapTable(req.Params); + releaseParamCaps = false; - if (cap == null) + try { - releaseParamCaps = true; - pendingAnswer = new PendingAnswer( - Task.FromException( - new RpcException("Call target resolved to null")), null); + var cts = new CancellationTokenSource(); + var callTask = callTargetCap.Invoke(req.InterfaceId, req.MethodId, inParams, cts.Token); + pendingAnswer = new PendingAnswer(callTask, cts); } - else + catch (System.Exception exception) { - try + foreach (var cap in inParams.Caps) { - var cts = new CancellationTokenSource(); - var callTask = cap.Invoke(req.InterfaceId, req.MethodId, inParams, cts.Token); - pendingAnswer = new PendingAnswer(callTask, cts); - } - catch (System.Exception exception) - { - releaseParamCaps = true; - pendingAnswer = new PendingAnswer( - Task.FromException(exception), null); + cap.Release(); } + + pendingAnswer = new PendingAnswer( + Task.FromException(exception), null); + } + finally + { + callTargetCap.Relinquish(); } AwaitAnswerAndReply(); @@ -535,7 +691,7 @@ namespace Capnp.Rpc } _canDeferCalls.Value = true; - Impatient.AskingEndpoint = this; + Impatient.PushAskingEndpoint(this); try { @@ -547,14 +703,14 @@ namespace Capnp.Rpc { if (_exportTable.TryGetValue(req.Target.ImportedCap, out var rc)) { - cap = rc.Cap; + callTargetCap = rc.Cap; + callTargetCap.Claim(); } else { Logger.LogWarning("Incoming RPC call: Peer asked for invalid (already released?) capability ID."); - SendAbort($"Requested capability with ID {req.Target.ImportedCap} does not exist."); - return; + throw new RpcProtocolErrorException($"Requested capability with ID {req.Target.ImportedCap} does not exist."); } } @@ -580,11 +736,10 @@ namespace Capnp.Rpc { try { - using (var proxy = await t) - { - cap = proxy?.GetProvider(); - CreateAnswerAwaitItAndReply(); - } + using var proxy = await t; + callTargetCap = await proxy.GetProvider(); + callTargetCap.Claim(); + CreateAnswerAwaitItAndReply(); } catch (TaskCanceledException) { @@ -605,8 +760,7 @@ namespace Capnp.Rpc else { Logger.LogWarning("Incoming RPC call: Peer asked for non-existing answer ID."); - SendAbort($"Did not find a promised answer for given ID {req.Target.PromisedAnswer.QuestionId}"); - return; + throw new RpcProtocolErrorException($"Did not find a promised answer for given ID {req.Target.PromisedAnswer.QuestionId}"); } } break; @@ -620,9 +774,8 @@ namespace Capnp.Rpc finally { _canDeferCalls.Value = false; - Impatient.AskingEndpoint = null; - _tailCall.Value?.Send(); - _tailCall.Value = null; + Impatient.PopAskingEndpoint(); + DispatchDeferredCalls(); } } @@ -636,10 +789,15 @@ namespace Capnp.Rpc { Logger.LogWarning("Incoming RPC return: Unknown answer ID."); - return; + throw new RpcProtocolErrorException("Unknown answer ID"); } } + if (req.ReleaseParamCaps) + { + ReleaseExports(question.CapTable); + } + switch (req.which) { case Return.WHICH.Results: @@ -707,6 +865,7 @@ namespace Capnp.Rpc else { Logger.LogWarning("Incoming RPC return: Peer requested to take results from other question, but specified ID is unknown (already released?)"); + throw new RpcProtocolErrorException("Invalid ID"); } } break; @@ -718,43 +877,53 @@ namespace Capnp.Rpc void ProcessResolve(Resolve.READER resolve) { - if (!_importTable.TryGetValue(resolve.PromiseId, out var rcw)) + lock (_reentrancyBlocker) { - Logger.LogWarning("Received a resolve message with invalid ID"); - return; - } + if (!_importTable.TryGetValue(resolve.PromiseId, out var rcc)) + { + // May happen if Resolve arrives late. Not an actual error. - if (!rcw.Cap.TryGetTarget(out var cap)) - { - // Silently discard - return; - } - - if (!(cap is PromisedCapability resolvableCap)) - { - Logger.LogWarning("Received a resolve message for a capability which is not a promise"); - return; - } - - switch (resolve.which) - { - case Resolve.WHICH.Cap: - lock (_reentrancyBlocker) + if (resolve.which == Resolve.WHICH.Cap) { - var resolvedCap = ImportCap(resolve.Cap); - if (resolvedCap == null) - resolvedCap = LazyCapability.CreateBrokenCap("Failed to resolve this capability"); - resolvableCap.ResolveTo(resolvedCap); + // Import and release immediately + var imp = ImportCap(resolve.Cap); + imp.AddRef(); + imp.Release(); } - break; - case Resolve.WHICH.Exception: - resolvableCap.Break(resolve.Exception.Reason); - break; + return; + } - default: - Logger.LogWarning("Received a resolve message with unknown category."); - throw new RpcUnimplementedException(); + var cap = rcc.Cap; + + if (!(cap is PromisedCapability resolvableCap)) + { + Logger.LogWarning("Received a resolve message for a capability which is not a promise"); + throw new RpcProtocolErrorException($"Not a promise {resolve.PromiseId}"); + } + + try + { + switch (resolve.which) + { + case Resolve.WHICH.Cap: + var resolvedCap = ImportCap(resolve.Cap); + resolvableCap.ResolveTo(resolvedCap); + break; + + case Resolve.WHICH.Exception: + resolvableCap.Break(resolve.Exception.Reason ?? "unknown reason"); + break; + + default: + Logger.LogWarning("Received a resolve message with unknown category."); + throw new RpcUnimplementedException(); + } + } + catch (InvalidOperationException) + { + throw new RpcProtocolErrorException($"Capability {resolve.PromiseId} was already resolved"); + } } } @@ -764,8 +933,8 @@ namespace Capnp.Rpc mb.InitCapTable(); var wr = mb.BuildRoot(); wr.which = Message.WHICH.Disembargo; - wr.Disembargo.Context.which = Disembargo.context.WHICH.ReceiverLoopback; - wr.Disembargo.Context.ReceiverLoopback = disembargo.Context.SenderLoopback; + wr.Disembargo!.Context.which = Disembargo.context.WHICH.ReceiverLoopback; + wr.Disembargo!.Context.ReceiverLoopback = disembargo.Context.SenderLoopback; var reply = wr.Disembargo; switch (disembargo.Target.which) @@ -776,10 +945,7 @@ namespace Capnp.Rpc { Logger.LogWarning("Sender loopback request: Peer asked for invalid (already released?) capability ID."); - SendAbort("'Disembargo': Invalid capability ID"); - Dismiss(); - - return; + throw new RpcProtocolErrorException("'Disembargo': Invalid capability ID"); } reply.Target.which = MessageTarget.WHICH.ImportedCap; @@ -794,7 +960,7 @@ namespace Capnp.Rpc var promisedAnswer = disembargo.Target.PromisedAnswer; reply.Target.which = MessageTarget.WHICH.PromisedAnswer; var replyPromisedAnswer = reply.Target.PromisedAnswer; - replyPromisedAnswer.QuestionId = disembargo.Target.PromisedAnswer.QuestionId; + replyPromisedAnswer!.QuestionId = disembargo.Target.PromisedAnswer.QuestionId; int count = promisedAnswer.Transform.Count; replyPromisedAnswer.Transform.Init(count); @@ -810,42 +976,20 @@ namespace Capnp.Rpc disembargo.Target.PromisedAnswer, async t => { - try - { - using (var proxy = await t) - { - proxy.Freeze(out var boundEndpoint); + using var proxy = await t; - try - { - if (boundEndpoint == this) - { + if (proxy.ConsumedCap is RemoteCapability remote && remote.Endpoint == this) + { #if DebugEmbargos - Logger.LogDebug($"Sender loopback disembargo. Thread = {Thread.CurrentThread.Name}"); + Logger.LogDebug($"Sender loopback disembargo. Thread = {Thread.CurrentThread.Name}"); #endif - Tx(mb.Frame); - } - else - { - Logger.LogWarning("Sender loopback request: Peer asked for disembargoing an answer which does not resolve back to the sender."); - - SendAbort("'Disembargo': Answer does not resolve back to me"); - Dismiss(); - } - } - finally - { - proxy.Unfreeze(); - } - } + Tx(mb.Frame); } - catch (System.Exception exception) + else { - Logger.LogWarning($"Sender loopback request: Peer asked for disembargoing an answer which either has not yet returned, was canceled, or faulted: {exception.Message}"); - - SendAbort($"'Disembargo' failure: {exception}"); - Dismiss(); + Logger.LogWarning("Sender loopback request: Peer asked for disembargoing an answer which does not resolve back to the sender."); + throw new RpcProtocolErrorException("'Disembargo': Answer does not resolve back to me"); } }); } @@ -853,10 +997,7 @@ namespace Capnp.Rpc { Logger.LogWarning("Sender loopback request: Peer asked for non-existing answer ID."); - SendAbort("'Disembargo': Invalid answer ID"); - Dismiss(); - - return; + throw new RpcProtocolErrorException("'Disembargo': Invalid answer ID"); } break; @@ -889,14 +1030,12 @@ namespace Capnp.Rpc Logger.LogDebug($"Receiver loopback disembargo, Thread = {Thread.CurrentThread.Name}"); #endif - if (!tcs.TrySetResult(0)) - { - Logger.LogError("Attempting to grant disembargo failed. Looks like an internal error / race condition."); - } + tcs.SetResult(0); } else { Logger.LogWarning("Peer sent receiver loopback with unknown ID"); + throw new RpcProtocolErrorException("Invalid ID"); } } @@ -919,6 +1058,26 @@ namespace Capnp.Rpc } } + void ReleaseExports(IReadOnlyList? caps) + { + if (caps != null) + { + foreach (var capDesc in caps) + { + switch (capDesc.which) + { + case CapDescriptor.WHICH.SenderHosted: + ReleaseExport(capDesc.SenderHosted, 1); + break; + + case CapDescriptor.WHICH.SenderPromise: + ReleaseExport(capDesc.SenderPromise, 1); + break; + } + } + } + } + void ReleaseResultCaps(PendingAnswer answer) { answer.Chain(async t => @@ -926,15 +1085,7 @@ namespace Capnp.Rpc try { var aorcq = await t; - var results = aorcq.Answer; - - if (results != null && results.Caps != null) - { - foreach (var cap in results.Caps) - { - cap?.Release(); - } - } + ReleaseExports(answer.CapTable); } catch { @@ -965,6 +1116,8 @@ namespace Capnp.Rpc else { Logger.LogWarning("Peer sent 'finish' message with unknown question ID"); + + throw new RpcProtocolErrorException("unknown question ID"); } } @@ -993,6 +1146,8 @@ namespace Capnp.Rpc catch (System.Exception exception) { Logger.LogWarning($"Attempting to release capability with invalid reference count: {exception.Message}"); + + throw new RpcProtocolErrorException("Invalid reference count"); } } } @@ -1000,6 +1155,8 @@ namespace Capnp.Rpc if (!exists) { Logger.LogWarning("Attempting to release unknown capability ID"); + + throw new RpcProtocolErrorException("Invalid export ID"); } } @@ -1019,6 +1176,7 @@ namespace Capnp.Rpc break; case CapDescriptor.WHICH.SenderPromise: + // Not really expected that a promise gets resolved to another promise. ReleaseExport(resolve.Cap.SenderPromise, 1); break; @@ -1030,7 +1188,19 @@ namespace Capnp.Rpc void ProcessUnimplementedCall(Call.READER call) { - Finish(call.QuestionId); + PendingQuestion? question; + + lock (_reentrancyBlocker) + { + if (!_questionTable.TryGetValue(call.QuestionId, out question)) + { + Logger.LogWarning("Unimplemented call: Unknown question ID."); + + throw new RpcProtocolErrorException("Unknown question ID"); + } + } + + ReleaseExports(question.CapTable); } void ProcessUnimplemented(Message.READER unimplemented) @@ -1055,9 +1225,7 @@ namespace Capnp.Rpc //# In cases where there is no sensible way to react to an `unimplemented` message (without //# resource leaks or other serious problems), the connection may need to be aborted. This is //# a gray area; different implementations may take different approaches. - SendAbort("It's hopeless if you don't implement the bootstrap message"); - Dismiss(); - break; + throw new RpcProtocolErrorException("It's hopeless if you don't implement the bootstrap message"); default: // Looking at the various message types it feels OK to just not care about other 'unimplemented' @@ -1069,16 +1237,21 @@ namespace Capnp.Rpc } } + /// + /// Queries the peer for its bootstrap capability + /// + /// low-level capability public ConsumedCapability QueryMain() { var mb = MessageBuilder.Create(); mb.InitCapTable(); var req = mb.BuildRoot(); req.which = Message.WHICH.Bootstrap; - var pendingBootstrap = AllocateQuestion(null, null); - req.Bootstrap.QuestionId = pendingBootstrap.QuestionId; + var pendingBootstrap = AllocateQuestion(NullCapability.Instance, null); + req.Bootstrap!.QuestionId = pendingBootstrap.QuestionId; Tx(mb.Frame); + _tx.Flush(); var main = new RemoteAnswerCapability( pendingBootstrap, @@ -1089,6 +1262,7 @@ namespace Capnp.Rpc void ProcessFrame(WireFrame frame) { + using var fc = SetupFlushContext(); var dec = DeserializerState.CreateRoot(frame); var msg = Message.READER.create(dec); @@ -1151,10 +1325,15 @@ namespace Capnp.Rpc mb.InitCapTable(); var reply = mb.BuildRoot(); reply.which = Message.WHICH.Unimplemented; - Reserializing.DeepCopy(msg, reply.Unimplemented.Rewrap()); + Reserializing.DeepCopy(msg, reply.Unimplemented!.Rewrap()); Tx(mb.Frame); } + catch (RpcProtocolErrorException error) + { + SendAbort(error.Message); + Dismiss(); + } catch (System.Exception exception) { Logger.LogError(exception, "Uncaught exception during message processing."); @@ -1163,81 +1342,57 @@ namespace Capnp.Rpc // First, we send implementation specific details of a - maybe internal - error, not very valuable for the // receiver. But worse: From a security point of view, we might even reveil a secret here. SendAbort("Uncaught exception during RPC processing. This may also happen due to invalid input."); - Dismiss(); } } - ConsumedCapability? ImportCap(CapDescriptor.READER capDesc) + ConsumedCapability ImportCap(CapDescriptor.READER capDesc) { lock (_reentrancyBlocker) { switch (capDesc.which) { case CapDescriptor.WHICH.SenderHosted: - if (_importTable.TryGetValue(capDesc.SenderHosted, out var rcw)) + if (_importTable.TryGetValue(capDesc.SenderHosted, out var rcc)) { - if (rcw.Cap.TryGetTarget(out var impCap)) - { - impCap.Validate(); - rcw.AddRef(); - return impCap; - } - else - { - impCap = new ImportedCapability(this, capDesc.SenderHosted); - rcw.Cap.SetTarget(impCap); - } - - return impCap!; + var impCap = rcc.Cap; + impCap.Validate(); + rcc.AddRef(); + return impCap; } else { var newCap = new ImportedCapability(this, capDesc.SenderHosted); - rcw = new RefCounted>( - new WeakReference(newCap)); - _importTable.Add(capDesc.SenderHosted, rcw); - Debug.Assert(newCap != null); + rcc = new RefCounted(newCap); + _importTable.Add(capDesc.SenderHosted, rcc); return newCap; } case CapDescriptor.WHICH.SenderPromise: - if (_importTable.TryGetValue(capDesc.SenderPromise, out var rcwp)) + if (_importTable.TryGetValue(capDesc.SenderPromise, out var rccp)) { - if (rcwp.Cap.TryGetTarget(out var impCap)) - { - impCap.Validate(); - rcwp.AddRef(); - return impCap; - } - else - { - impCap = new PromisedCapability(this, capDesc.SenderPromise); - rcwp.Cap.SetTarget(impCap); - } - - Debug.Assert(impCap != null); + var impCap = rccp.Cap; + impCap.Validate(); + rccp.AddRef(); return impCap; } else { var newCap = new PromisedCapability(this, capDesc.SenderPromise); - rcw = new RefCounted>( - new WeakReference(newCap)); - _importTable.Add(capDesc.SenderPromise, rcw); - Debug.Assert(newCap != null); + rccp = new RefCounted(newCap); + _importTable.Add(capDesc.SenderPromise, rccp); return newCap; } case CapDescriptor.WHICH.ReceiverHosted: if (_exportTable.TryGetValue(capDesc.ReceiverHosted, out var rc)) { - return LocalCapability.Create(rc.Cap); + return rc.Cap.AsCapability(); } else { Logger.LogWarning("Peer refers to receiver-hosted capability which does not exist."); - return null; + throw new RpcProtocolErrorException($"Receiver-hosted capability {capDesc.ReceiverHosted} does not exist."); } case CapDescriptor.WHICH.ReceiverAnswer: @@ -1269,36 +1424,27 @@ namespace Capnp.Rpc else { Logger.LogWarning("Peer refers to pending answer which does not exist."); - return null; + throw new RpcProtocolErrorException($"Invalid question ID {capDesc.ReceiverAnswer.QuestionId}"); } case CapDescriptor.WHICH.ThirdPartyHosted: if (_importTable.TryGetValue(capDesc.ThirdPartyHosted.VineId, out var rcv)) { - if (rcv.Cap.TryGetTarget(out var impCap)) - { - rcv.AddRef(); - impCap.Validate(); - return impCap; - } - else - { - impCap = new ImportedCapability(this, capDesc.ThirdPartyHosted.VineId); - rcv.Cap.SetTarget(impCap); - } - - Debug.Assert(impCap != null); + var impCap = rcv.Cap; + rcv.AddRef(); + impCap.Validate(); return impCap; } else { var newCap = new ImportedCapability(this, capDesc.ThirdPartyHosted.VineId); - rcv = new RefCounted>( - new WeakReference(newCap)); - Debug.Assert(newCap != null); + rcv = new RefCounted(newCap); return newCap; } + case CapDescriptor.WHICH.None: + return NullCapability.Instance; + default: Logger.LogWarning("Unknown capability descriptor category"); throw new RpcUnimplementedException(); @@ -1306,9 +1452,9 @@ namespace Capnp.Rpc } } - public IList ImportCapTable(Payload.READER payload) + internal IList ImportCapTable(Payload.READER payload) { - var list = new List(); + var list = new List(); if (payload.CapTable != null) { @@ -1316,7 +1462,9 @@ namespace Capnp.Rpc { foreach (var capDesc in payload.CapTable) { - list.Add(ImportCap(capDesc)); + var cap = ImportCap(capDesc); + cap.AddRef(); + list.Add(cap); } } } @@ -1324,34 +1472,19 @@ namespace Capnp.Rpc return list; } - void IRpcEndpoint.RequestPostAction(Action postAction) - { - _exportCapTablePostActions.Value += postAction; - } - void ExportCapTableAndSend( SerializerState state, Payload.WRITER payload) { - Debug.Assert(_exportCapTablePostActions.Value == null); - _exportCapTablePostActions.Value = null; - payload.CapTable.Init(state.MsgBuilder!.Caps!.Count); + Action? postAction = null; int i = 0; foreach (var cap in state.MsgBuilder.Caps) { var capDesc = payload.CapTable[i++]; - - if (cap == null) - { - LazyCapability.Null.Export(this, capDesc); - } - else - { - cap.Export(this, capDesc); - cap.Release(); - } + postAction += cap.Export(this, capDesc); + cap.Release(); } Tx(state.MsgBuilder.Frame); @@ -1362,19 +1495,18 @@ namespace Capnp.Rpc // To avoid that situation, calls to "ReExportCapWhenResolved" are queued (and // therefore deferred) to the postAction. - var pa = _exportCapTablePostActions.Value; - _exportCapTablePostActions.Value = null; - pa?.Invoke(); + postAction?.Invoke(); } PendingQuestion IRpcEndpoint.BeginQuestion(ConsumedCapability target, SerializerState inParams) { + using var fc = SetupFlushContext(); var question = AllocateQuestion(target, inParams); if (_canDeferCalls.Value) { - _tailCall.Value?.Send(); - _tailCall.Value = question; + DispatchDeferredCalls(); + _deferredCall.Value = question; } else { @@ -1394,8 +1526,8 @@ namespace Capnp.Rpc var mb = MessageBuilder.Create(); var msg = mb.BuildRoot(); msg.which = Message.WHICH.Finish; - msg.Finish.QuestionId = questionId; - msg.Finish.ReleaseResultCaps = false; + msg.Finish!.QuestionId = questionId; + msg.Finish!.ReleaseResultCaps = false; try { @@ -1412,11 +1544,14 @@ namespace Capnp.Rpc void IRpcEndpoint.Finish(uint questionId) { + using var fc = SetupFlushContext(); Finish(questionId); } void IRpcEndpoint.ReleaseImport(uint importId) { + using var fc = SetupFlushContext(); + bool exists; int count = 0; @@ -1440,12 +1575,13 @@ namespace Capnp.Rpc var mb = MessageBuilder.Create(); var msg = mb.BuildRoot(); msg.which = Message.WHICH.Release; - msg.Release.Id = importId; - msg.Release.ReferenceCount = (uint)count; + msg.Release!.Id = importId; + msg.Release!.ReferenceCount = (uint)count; try { Tx(mb.Frame); + RequestFlush(); } catch (RpcException exception) { @@ -1456,13 +1592,15 @@ namespace Capnp.Rpc Task IRpcEndpoint.RequestSenderLoopback(Action describe) { + using var fc = SetupFlushContext(); + (var tcs, uint id) = AllocateDisembargo(); var mb = MessageBuilder.Create(); mb.InitCapTable(); var msg = mb.BuildRoot(); msg.which = Message.WHICH.Disembargo; - describe(msg.Disembargo.Target); + describe(msg.Disembargo!.Target); var ctx = msg.Disembargo.Context; ctx.which = Disembargo.context.WHICH.SenderLoopback; ctx.SenderLoopback = id; @@ -1474,13 +1612,26 @@ namespace Capnp.Rpc void IRpcEndpoint.DeleteQuestion(PendingQuestion question) { - DeleteQuestion(question.QuestionId, question); + using var fc = SetupFlushContext(); + + lock (_reentrancyBlocker) + { + if (!_questionTable.Remove(question.QuestionId)) + { + Logger.LogError("Attempting to delete unknown question ID."); + } + } } } readonly ConcurrentBag _inboundEndpoints = new ConcurrentBag(); - internal RpcEndpoint AddEndpoint(IEndpoint outboundEndpoint) + /// + /// Adds an endpoint + /// + /// endpoint for handling outgoing messages + /// endpoint for handling incoming messages + public RpcEndpoint AddEndpoint(IEndpoint outboundEndpoint) { var inboundEndpoint = new RpcEndpoint(this, outboundEndpoint); _inboundEndpoints.Add(inboundEndpoint); @@ -1502,5 +1653,14 @@ namespace Capnp.Rpc _bootstrapCap = value; } } + + /// + /// Sets the bootstrap capability. It must be an object which implements a valid capability interface + /// (). + /// + public object Main + { + set { BootstrapCap = value is Skeleton skeleton ? skeleton : CapabilityReflection.CreateSkeletonInternal(value); } + } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/RpcProtocolErrorException.cs b/Capnp.Net.Runtime/Rpc/RpcProtocolErrorException.cs new file mode 100644 index 0000000..6b4885d --- /dev/null +++ b/Capnp.Net.Runtime/Rpc/RpcProtocolErrorException.cs @@ -0,0 +1,9 @@ +namespace Capnp.Rpc +{ + class RpcProtocolErrorException : System.Exception + { + public RpcProtocolErrorException(string reason): base(reason) + { + } + } +} \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/Skeleton.cs b/Capnp.Net.Runtime/Rpc/Skeleton.cs index 842bf06..f8ffaa0 100644 --- a/Capnp.Net.Runtime/Rpc/Skeleton.cs +++ b/Capnp.Net.Runtime/Rpc/Skeleton.cs @@ -18,6 +18,7 @@ namespace Capnp.Rpc public SkeletonRelinquisher(Skeleton skeleton) { _skeleton = skeleton; + _skeleton.Claim(); } public void Dispose() @@ -26,32 +27,6 @@ namespace Capnp.Rpc } } -#if DEBUG_DISPOSE - const int NoDisposeFlag = 0x4000000; -#endif - - static readonly ConditionalWeakTable _implMap = - new ConditionalWeakTable(); - - internal static Skeleton GetOrCreateSkeleton(T impl, bool addRef) - where T: class - { - if (impl == null) - throw new ArgumentNullException(nameof(impl)); - - if (impl is Skeleton skel) - return skel; - - skel = _implMap.GetValue(impl, _ => CapabilityReflection.CreateSkeleton(_)); - - if (addRef) - { - skel.Claim(); - } - - return skel; - } - /// /// Claims ownership on the given capability, preventing its automatic disposal. /// @@ -60,34 +35,9 @@ namespace Capnp.Rpc /// A disposable object. Calling Dispose() on the returned instance relinquishes ownership again. public static IDisposable Claim(T impl) where T: class { - return new SkeletonRelinquisher(GetOrCreateSkeleton(impl, true)); + return new SkeletonRelinquisher(CapabilityReflection.CreateSkeletonInternal(impl)); } -#if DEBUG_DISPOSE - /// - /// This DEBUG-only diagnostic method states that the Skeleton corresponding to a given capability is not expected to - /// be disposed until the next call to EndAssertNotDisposed(). - /// - /// Capability interface - /// Capability implementation - public static void BeginAssertNotDisposed(T impl) where T : class - { - GetOrCreateSkeleton(impl, false).BeginAssertNotDisposed(); - } - - /// - /// This DEBUG-only diagnostic method ends a non-disposal period started with BeginAssertNotDisposed. - /// - /// Capability interface - /// Capability implementation - public static void EndAssertNotDisposed(T impl) where T : class - { - GetOrCreateSkeleton(impl, false).EndAssertNotDisposed(); - } -#endif - - int _refCount = 0; - /// /// Calls an interface method of this capability. /// @@ -98,43 +48,8 @@ namespace Capnp.Rpc /// A Task which will resolve to the call result public abstract Task Invoke(ulong interfaceId, ushort methodId, DeserializerState args, CancellationToken cancellationToken = default); - internal void Claim() - { - Interlocked.Increment(ref _refCount); - } - -#if DEBUG_DISPOSE - internal void BeginAssertNotDisposed() - { - if ((Interlocked.Add(ref _refCount, NoDisposeFlag) & NoDisposeFlag) == 0) - { - throw new InvalidOperationException("Flag already set. State is now broken."); - } - } - internal void EndAssertNotDisposed() - { - if ((Interlocked.Add(ref _refCount, -NoDisposeFlag) & NoDisposeFlag) != 0) - { - throw new InvalidOperationException("Flag already cleared. State is now broken."); - } - } -#endif - - internal void Relinquish() - { - int count = Interlocked.Decrement(ref _refCount); - - if (0 == count) - { -#if DEBUG_DISPOSE - if ((count & NoDisposeFlag) != 0) - throw new InvalidOperationException("Unexpected Skeleton disposal"); -#endif - - Dispose(true); - GC.SuppressFinalize(this); - } - } + internal abstract void Claim(); + internal abstract void Relinquish(); internal void Relinquish(int count) { @@ -145,41 +60,21 @@ namespace Capnp.Rpc Relinquish(); } - /// - /// Dispose pattern implementation - /// - protected virtual void Dispose(bool disposing) - { - } - - /// - /// Finalizer - /// - ~Skeleton() - { - Dispose(false); - } - internal virtual void Bind(object impl) { - throw new NotSupportedException(); + throw new NotSupportedException("Cannot bind"); } + + internal abstract ConsumedCapability AsCapability(); } /// /// Skeleton for a specific capability interface. /// /// Capability interface - public abstract class Skeleton : Skeleton, IMonoSkeleton + public abstract class Skeleton : RefCountingSkeleton, IMonoSkeleton { -#if DebugEmbargos - ILogger Logger { get; } = Logging.CreateLogger>(); -#endif - Func>[] _methods = null!; - CancellationTokenSource? _disposed = new CancellationTokenSource(); - readonly object _reentrancyBlocker = new object(); - int _pendingCalls; /// /// Constructs an instance. @@ -225,45 +120,7 @@ namespace Capnp.Rpc if (methodId >= _methods.Length) throw new NotImplementedException("Wrong method id"); - lock (_reentrancyBlocker) - { - if (_disposed == null || _disposed.IsCancellationRequested) - { - throw new ObjectDisposedException(nameof(Skeleton)); - } - - ++_pendingCalls; - } - - var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(_disposed.Token, cancellationToken); - - try - { - return await _methods[methodId](args, linkedSource.Token); - } - catch (System.Exception) - { - throw; - } - finally - { - lock (_reentrancyBlocker) - { - --_pendingCalls; - } - - linkedSource.Dispose(); - CheckCtsDisposal(); - } - } - - void CheckCtsDisposal() - { - if (_pendingCalls == 0 && _disposed != null && _disposed.IsCancellationRequested) - { - _disposed.Dispose(); - _disposed = null; - } + return await _methods[methodId](args, cancellationToken); } /// @@ -271,17 +128,7 @@ namespace Capnp.Rpc /// protected override void Dispose(bool disposing) { - lock (_reentrancyBlocker) - { - if (_disposed == null || _disposed.IsCancellationRequested) - return; - - _disposed.Cancel(); - - CheckCtsDisposal(); - } - - if (Impl is IDisposable disposable) + if (disposing && Impl is IDisposable disposable) { disposable.Dispose(); } diff --git a/Capnp.Net.Runtime/Rpc/TcpRpcClient.cs b/Capnp.Net.Runtime/Rpc/TcpRpcClient.cs index 02a975d..216d280 100644 --- a/Capnp.Net.Runtime/Rpc/TcpRpcClient.cs +++ b/Capnp.Net.Runtime/Rpc/TcpRpcClient.cs @@ -1,4 +1,5 @@ using Capnp.FrameTracing; +using Capnp.Util; using Microsoft.Extensions.Logging; using System; using System.IO; @@ -19,12 +20,10 @@ namespace Capnp.Rpc class OutboundTcpEndpoint : IEndpoint { - readonly TcpRpcClient _client; readonly FramePump _pump; - public OutboundTcpEndpoint(TcpRpcClient client, FramePump pump) + public OutboundTcpEndpoint(FramePump pump) { - _client = client; _pump = pump; } @@ -37,6 +36,11 @@ namespace Capnp.Rpc { _pump.Send(frame); } + + public void Flush() + { + _pump.Flush(); + } } readonly RpcEngine _rpcEngine; @@ -84,7 +88,7 @@ namespace Capnp.Rpc var stream = _createLayers(_client.GetStream()); _pump = new FramePump(stream); _attachTracerAction?.Invoke(); - _outboundEndpoint = new OutboundTcpEndpoint(this, _pump); + _outboundEndpoint = new OutboundTcpEndpoint(_pump); _inboundEndpoint = _rpcEngine.AddEndpoint(_outboundEndpoint); _pumpThread = new Thread(() => { @@ -94,6 +98,10 @@ namespace Capnp.Rpc _pump.Run(); } + catch (ThreadInterruptedException) + { + Logger.LogError($"{Thread.CurrentThread.Name} interrupted at {Environment.StackTrace}"); + } finally { State = ConnectionState.Down; @@ -153,24 +161,20 @@ namespace Capnp.Rpc /// Bootstrap capability interface /// A proxy for the bootstrap capability /// Not connected - public TProxy GetMain() where TProxy: class + public TProxy GetMain() where TProxy: class, IDisposable { if (WhenConnected == null) { throw new InvalidOperationException("Not connecting"); } - if (!WhenConnected.IsCompleted) + async Task GetMainAsync() { - throw new InvalidOperationException("Connection not yet established"); + await WhenConnected!; + return (CapabilityReflection.CreateProxy(_inboundEndpoint!.QueryMain()) as TProxy)!; } - if (!WhenConnected.ReplacementTaskIsCompletedSuccessfully()) - { - throw new InvalidOperationException("Connection not successfully established"); - } - - return (CapabilityReflection.CreateProxy(_inboundEndpoint!.QueryMain()) as TProxy)!; + return GetMainAsync().Eager(true); } /// @@ -192,10 +196,7 @@ namespace Capnp.Rpc Logger.LogError(e, "Failure disposing client"); } - if (_pumpThread != null && !_pumpThread.Join(500)) - { - Logger.LogError("Unable to join pump thread within timeout"); - } + _pumpThread?.SafeJoin(Logger); GC.SuppressFinalize(this); } diff --git a/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs b/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs index 4db3cd8..758ae3d 100644 --- a/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs +++ b/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs @@ -1,4 +1,5 @@ using Capnp.FrameTracing; +using Capnp.Util; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -56,10 +57,17 @@ namespace Capnp.Rpc { _pump.Send(frame); } + + public void Flush() + { + _pump.Flush(); + } } class Connection: IConnection { + ILogger Logger { get; } = Logging.CreateLogger(); + readonly List _tracers = new List(); readonly TcpRpcServer _server; Stream _stream; @@ -95,6 +103,10 @@ namespace Capnp.Rpc Pump.Run(); } + catch (ThreadInterruptedException) + { + Logger.LogError($"{Thread.CurrentThread.Name} interrupted at {Environment.StackTrace}"); + } finally { OutboundEp.Dismiss(); @@ -110,6 +122,7 @@ namespace Capnp.Rpc } } }); + PumpRunner.Start(); } public ConnectionState State { get; set; } = ConnectionState.Initializing; @@ -191,8 +204,6 @@ namespace Capnp.Rpc OnConnectionChanged?.Invoke(this, new ConnectionEventArgs(connection)); connection.Start(); } - - connection.PumpRunner!.Start(); } } catch (SocketException) @@ -200,6 +211,10 @@ namespace Capnp.Rpc // Listener was stopped. Maybe a little bit rude, but this is // our way of shutting down the acceptor thread. } + catch (ThreadInterruptedException) + { + Logger.LogError($"{Thread.CurrentThread.Name} interrupted at {Environment.StackTrace}"); + } catch (System.Exception exception) { // Any other exception might be due to some other problem. @@ -207,38 +222,6 @@ namespace Capnp.Rpc } } - void SafeJoin(Thread? thread) - { - if (thread == null) - { - return; - } - - for (int retry = 0; retry < 5; ++retry) - { - try - { - if (!thread.Join(500)) - { - Logger.LogError($"Unable to join {thread.Name} within timeout"); - } - break; - } - catch (ThreadStateException) - { - // In rare cases it happens that despite thread.Start() was called, the thread did not actually start yet. - Logger.LogDebug("Waiting for thread to start in order to join it"); - Thread.Sleep(100); - } - catch (System.Exception exception) - { - Logger.LogError($"Unable to join {thread.Name}: {exception.Message}"); - break; - } - } - } - - /// /// Stops accepting incoming attempts and closes all existing connections. /// @@ -260,9 +243,11 @@ namespace Capnp.Rpc { connection.Client.Dispose(); connection.Pump?.Dispose(); - SafeJoin(connection.PumpRunner); + connection.PumpRunner?.SafeJoin(Logger); } + _rpcEngine.BootstrapCap = null; + GC.SuppressFinalize(this); } @@ -284,7 +269,8 @@ namespace Capnp.Rpc finally { _listener = null; - SafeJoin(_acceptorThread); + if (Thread.CurrentThread != _acceptorThread) + _acceptorThread?.Join(); _acceptorThread = null; } } @@ -391,7 +377,7 @@ namespace Capnp.Rpc /// public object Main { - set { _rpcEngine.BootstrapCap = Skeleton.GetOrCreateSkeleton(value, false); } + set { _rpcEngine.Main = value; } } /// diff --git a/Capnp.Net.Runtime/Rpc/Vine.cs b/Capnp.Net.Runtime/Rpc/Vine.cs index 52f10c1..c17c1be 100644 --- a/Capnp.Net.Runtime/Rpc/Vine.cs +++ b/Capnp.Net.Runtime/Rpc/Vine.cs @@ -1,70 +1,48 @@ -using System; +using Microsoft.Extensions.Logging; +using System; using System.Threading; using System.Threading.Tasks; namespace Capnp.Rpc { + class Vine : Skeleton { - public static Skeleton Create(ConsumedCapability cap) + public Vine(ConsumedCapability consumedCap) { - if (cap is LocalCapability lcap) - return lcap.ProvidedCap; - else - return new Vine(cap); + Cap = consumedCap; } - Vine(ConsumedCapability consumedCap) + public ConsumedCapability Cap { get; } + + internal override ConsumedCapability AsCapability() => Cap; + + internal override void Claim() { - Proxy = new Proxy(consumedCap ?? throw new ArgumentNullException(nameof(consumedCap))); + Cap.AddRef(); } - internal override void Bind(object impl) + internal override void Relinquish() { - throw new NotImplementedException(); + Cap.Release(); } - public Proxy Proxy { get; } - public async override Task Invoke( ulong interfaceId, ushort methodId, DeserializerState args, CancellationToken cancellationToken = default) { - var promisedAnswer = Proxy.Call(interfaceId, methodId, (DynamicSerializerState)args, default); + using var proxy = new Proxy(Cap); + var promisedAnswer = proxy.Call(interfaceId, methodId, (DynamicSerializerState)args, false, cancellationToken); if (promisedAnswer is PendingQuestion pendingQuestion && pendingQuestion.RpcEndpoint == Impatient.AskingEndpoint) { - async void SetupCancellation() - { - try - { - using (var registration = cancellationToken.Register(promisedAnswer.Dispose)) - { - await promisedAnswer.WhenReturned; - } - } - catch - { - } - } - - SetupCancellation(); - return pendingQuestion; } else { - using (var registration = cancellationToken.Register(promisedAnswer.Dispose)) - { - return (DynamicSerializerState)await promisedAnswer.WhenReturned; - } + using var registration = cancellationToken.Register(promisedAnswer.Dispose); + return (DynamicSerializerState)await promisedAnswer.WhenReturned; } } - - protected override void Dispose(bool disposing) - { - Proxy.Dispose(); - base.Dispose(disposing); - } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Rpc/rpc.cs b/Capnp.Net.Runtime/Rpc/rpc.cs index 066bd98..c48f8d0 100644 --- a/Capnp.Net.Runtime/Rpc/rpc.cs +++ b/Capnp.Net.Runtime/Rpc/rpc.cs @@ -1,17 +1,19 @@ #pragma warning disable CS1591 -#nullable disable - using Capnp; using Capnp.Rpc; using System; +using System.CodeDom.Compiler; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; namespace Capnp.Rpc { + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x91b79f1f808db032UL)] public class Message : ICapnpSerializable { + public const UInt64 typeId = 0x91b79f1f808db032UL; public enum WHICH : ushort { Unimplemented = 0, @@ -58,13 +60,13 @@ namespace Capnp.Rpc Release = CapnpSerializable.Create(reader.Release); break; case WHICH.ObsoleteSave: - ObsoleteSave = CapnpSerializable.Create(reader.ObsoleteSave); + ObsoleteSave = CapnpSerializable.Create(reader.ObsoleteSave); break; case WHICH.Bootstrap: Bootstrap = CapnpSerializable.Create(reader.Bootstrap); break; case WHICH.ObsoleteDelete: - ObsoleteDelete = CapnpSerializable.Create(reader.ObsoleteDelete); + ObsoleteDelete = CapnpSerializable.Create(reader.ObsoleteDelete); break; case WHICH.Provide: Provide = CapnpSerializable.Create(reader.Provide); @@ -84,7 +86,7 @@ namespace Capnp.Rpc } private WHICH _which = WHICH.undefined; - private object _content; + private object? _content; public WHICH which { get => _which; @@ -147,46 +149,46 @@ namespace Capnp.Rpc switch (which) { case WHICH.Unimplemented: - Unimplemented?.serialize(writer.Unimplemented); + Unimplemented?.serialize(writer.Unimplemented!); break; case WHICH.Abort: - Abort?.serialize(writer.Abort); + Abort?.serialize(writer.Abort!); break; case WHICH.Call: - Call?.serialize(writer.Call); + Call?.serialize(writer.Call!); break; case WHICH.Return: - Return?.serialize(writer.Return); + Return?.serialize(writer.Return!); break; case WHICH.Finish: - Finish?.serialize(writer.Finish); + Finish?.serialize(writer.Finish!); break; case WHICH.Resolve: - Resolve?.serialize(writer.Resolve); + Resolve?.serialize(writer.Resolve!); break; case WHICH.Release: - Release?.serialize(writer.Release); + Release?.serialize(writer.Release!); break; case WHICH.ObsoleteSave: - writer.ObsoleteSave.SetObject(ObsoleteSave); + writer.ObsoleteSave!.SetObject(ObsoleteSave); break; case WHICH.Bootstrap: - Bootstrap?.serialize(writer.Bootstrap); + Bootstrap?.serialize(writer.Bootstrap!); break; case WHICH.ObsoleteDelete: - writer.ObsoleteDelete.SetObject(ObsoleteDelete); + writer.ObsoleteDelete!.SetObject(ObsoleteDelete); break; case WHICH.Provide: - Provide?.serialize(writer.Provide); + Provide?.serialize(writer.Provide!); break; case WHICH.Accept: - Accept?.serialize(writer.Accept); + Accept?.serialize(writer.Accept!); break; case WHICH.Join: - Join?.serialize(writer.Join); + Join?.serialize(writer.Join!); break; case WHICH.Disembargo: - Disembargo?.serialize(writer.Disembargo); + Disembargo?.serialize(writer.Disembargo!); break; } } @@ -200,9 +202,9 @@ namespace Capnp.Rpc { } - public Capnp.Rpc.Message Unimplemented + public Capnp.Rpc.Message? Unimplemented { - get => _which == WHICH.Unimplemented ? (Capnp.Rpc.Message)_content : null; + get => _which == WHICH.Unimplemented ? (Capnp.Rpc.Message?)_content : null; set { _which = WHICH.Unimplemented; @@ -210,9 +212,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Exception Abort + public Capnp.Rpc.Exception? Abort { - get => _which == WHICH.Abort ? (Capnp.Rpc.Exception)_content : null; + get => _which == WHICH.Abort ? (Capnp.Rpc.Exception?)_content : null; set { _which = WHICH.Abort; @@ -220,9 +222,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Call Call + public Capnp.Rpc.Call? Call { - get => _which == WHICH.Call ? (Capnp.Rpc.Call)_content : null; + get => _which == WHICH.Call ? (Capnp.Rpc.Call?)_content : null; set { _which = WHICH.Call; @@ -230,9 +232,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Return Return + public Capnp.Rpc.Return? Return { - get => _which == WHICH.Return ? (Capnp.Rpc.Return)_content : null; + get => _which == WHICH.Return ? (Capnp.Rpc.Return?)_content : null; set { _which = WHICH.Return; @@ -240,9 +242,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Finish Finish + public Capnp.Rpc.Finish? Finish { - get => _which == WHICH.Finish ? (Capnp.Rpc.Finish)_content : null; + get => _which == WHICH.Finish ? (Capnp.Rpc.Finish?)_content : null; set { _which = WHICH.Finish; @@ -250,9 +252,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Resolve Resolve + public Capnp.Rpc.Resolve? Resolve { - get => _which == WHICH.Resolve ? (Capnp.Rpc.Resolve)_content : null; + get => _which == WHICH.Resolve ? (Capnp.Rpc.Resolve?)_content : null; set { _which = WHICH.Resolve; @@ -260,9 +262,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Release Release + public Capnp.Rpc.Release? Release { - get => _which == WHICH.Release ? (Capnp.Rpc.Release)_content : null; + get => _which == WHICH.Release ? (Capnp.Rpc.Release?)_content : null; set { _which = WHICH.Release; @@ -270,9 +272,9 @@ namespace Capnp.Rpc } } - public AnyPointer ObsoleteSave + public object? ObsoleteSave { - get => _which == WHICH.ObsoleteSave ? (AnyPointer)_content : null; + get => _which == WHICH.ObsoleteSave ? (object?)_content : null; set { _which = WHICH.ObsoleteSave; @@ -280,9 +282,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Bootstrap Bootstrap + public Capnp.Rpc.Bootstrap? Bootstrap { - get => _which == WHICH.Bootstrap ? (Capnp.Rpc.Bootstrap)_content : null; + get => _which == WHICH.Bootstrap ? (Capnp.Rpc.Bootstrap?)_content : null; set { _which = WHICH.Bootstrap; @@ -290,9 +292,9 @@ namespace Capnp.Rpc } } - public AnyPointer ObsoleteDelete + public object? ObsoleteDelete { - get => _which == WHICH.ObsoleteDelete ? (AnyPointer)_content : null; + get => _which == WHICH.ObsoleteDelete ? (object?)_content : null; set { _which = WHICH.ObsoleteDelete; @@ -300,9 +302,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Provide Provide + public Capnp.Rpc.Provide? Provide { - get => _which == WHICH.Provide ? (Capnp.Rpc.Provide)_content : null; + get => _which == WHICH.Provide ? (Capnp.Rpc.Provide?)_content : null; set { _which = WHICH.Provide; @@ -310,9 +312,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Accept Accept + public Capnp.Rpc.Accept? Accept { - get => _which == WHICH.Accept ? (Capnp.Rpc.Accept)_content : null; + get => _which == WHICH.Accept ? (Capnp.Rpc.Accept?)_content : null; set { _which = WHICH.Accept; @@ -320,9 +322,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Join Join + public Capnp.Rpc.Join? Join { - get => _which == WHICH.Join ? (Capnp.Rpc.Join)_content : null; + get => _which == WHICH.Join ? (Capnp.Rpc.Join?)_content : null; set { _which = WHICH.Join; @@ -330,9 +332,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Disembargo Disembargo + public Capnp.Rpc.Disembargo? Disembargo { - get => _which == WHICH.Disembargo ? (Capnp.Rpc.Disembargo)_content : null; + get => _which == WHICH.Disembargo ? (Capnp.Rpc.Disembargo?)_content : null; set { _which = WHICH.Disembargo; @@ -381,99 +383,115 @@ namespace Capnp.Rpc set => this.WriteData(0U, (ushort)value, (ushort)0); } - public Capnp.Rpc.Message.WRITER Unimplemented + [DisallowNull] + public Capnp.Rpc.Message.WRITER? Unimplemented { get => which == WHICH.Unimplemented ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Exception.WRITER Abort + [DisallowNull] + public Capnp.Rpc.Exception.WRITER? Abort { get => which == WHICH.Abort ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Call.WRITER Call + [DisallowNull] + public Capnp.Rpc.Call.WRITER? Call { get => which == WHICH.Call ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Return.WRITER Return + [DisallowNull] + public Capnp.Rpc.Return.WRITER? Return { get => which == WHICH.Return ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Finish.WRITER Finish + [DisallowNull] + public Capnp.Rpc.Finish.WRITER? Finish { get => which == WHICH.Finish ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Resolve.WRITER Resolve + [DisallowNull] + public Capnp.Rpc.Resolve.WRITER? Resolve { get => which == WHICH.Resolve ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Release.WRITER Release + [DisallowNull] + public Capnp.Rpc.Release.WRITER? Release { get => which == WHICH.Release ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public DynamicSerializerState ObsoleteSave + [DisallowNull] + public DynamicSerializerState? ObsoleteSave { get => which == WHICH.ObsoleteSave ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Bootstrap.WRITER Bootstrap + [DisallowNull] + public Capnp.Rpc.Bootstrap.WRITER? Bootstrap { get => which == WHICH.Bootstrap ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public DynamicSerializerState ObsoleteDelete + [DisallowNull] + public DynamicSerializerState? ObsoleteDelete { get => which == WHICH.ObsoleteDelete ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Provide.WRITER Provide + [DisallowNull] + public Capnp.Rpc.Provide.WRITER? Provide { get => which == WHICH.Provide ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Accept.WRITER Accept + [DisallowNull] + public Capnp.Rpc.Accept.WRITER? Accept { get => which == WHICH.Accept ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Join.WRITER Join + [DisallowNull] + public Capnp.Rpc.Join.WRITER? Join { get => which == WHICH.Join ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Disembargo.WRITER Disembargo + [DisallowNull] + public Capnp.Rpc.Disembargo.WRITER? Disembargo { get => which == WHICH.Disembargo ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe94ccf8031176ec4UL)] public class Bootstrap : ICapnpSerializable { + public const UInt64 typeId = 0xe94ccf8031176ec4UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); QuestionId = reader.QuestionId; - DeprecatedObjectId = CapnpSerializable.Create(reader.DeprecatedObjectId); + DeprecatedObjectId = CapnpSerializable.Create(reader.DeprecatedObjectId); applyDefaults(); } @@ -498,7 +516,7 @@ namespace Capnp.Rpc set; } - public AnyPointer DeprecatedObjectId + public object? DeprecatedObjectId { get; set; @@ -540,8 +558,10 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x836a53ce789d4cd4UL)] public class Call : ICapnpSerializable { + public const UInt64 typeId = 0x836a53ce789d4cd4UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); @@ -550,7 +570,7 @@ namespace Capnp.Rpc InterfaceId = reader.InterfaceId; MethodId = reader.MethodId; Params = CapnpSerializable.Create(reader.Params); - SendResultsTo = CapnpSerializable.Create(reader.SendResultsTo); + SendResultsTo = CapnpSerializable.Create(reader.SendResultsTo); AllowThirdPartyTailCall = reader.AllowThirdPartyTailCall; applyDefaults(); } @@ -581,7 +601,7 @@ namespace Capnp.Rpc set; } - public Capnp.Rpc.MessageTarget Target + public Capnp.Rpc.MessageTarget? Target { get; set; @@ -599,13 +619,13 @@ namespace Capnp.Rpc set; } - public Capnp.Rpc.Payload Params + public Capnp.Rpc.Payload? Params { get; set; } - public Capnp.Rpc.Call.@sendResultsTo SendResultsTo + public Capnp.Rpc.Call.sendResultsTo? SendResultsTo { get; set; @@ -634,7 +654,7 @@ namespace Capnp.Rpc public ulong InterfaceId => ctx.ReadDataULong(64UL, 0UL); public ushort MethodId => ctx.ReadDataUShort(32UL, (ushort)0); public Capnp.Rpc.Payload.READER Params => ctx.ReadStruct(1, Capnp.Rpc.Payload.READER.create); - public @sendResultsTo.READER SendResultsTo => new @sendResultsTo.READER(ctx); + public sendResultsTo.READER SendResultsTo => new sendResultsTo.READER(ctx); public bool AllowThirdPartyTailCall => ctx.ReadDataBool(128UL, false); } @@ -675,9 +695,9 @@ namespace Capnp.Rpc set => Link(1, value); } - public @sendResultsTo.WRITER SendResultsTo + public sendResultsTo.WRITER SendResultsTo { - get => Rewrap<@sendResultsTo.WRITER>(); + get => Rewrap(); } public bool AllowThirdPartyTailCall @@ -687,8 +707,10 @@ namespace Capnp.Rpc } } - public class @sendResultsTo : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdae8b0f61aab5f99UL)] + public class sendResultsTo : ICapnpSerializable { + public const UInt64 typeId = 0xdae8b0f61aab5f99UL; public enum WHICH : ushort { Caller = 0, @@ -709,7 +731,7 @@ namespace Capnp.Rpc which = reader.which; break; case WHICH.ThirdParty: - ThirdParty = CapnpSerializable.Create(reader.ThirdParty); + ThirdParty = CapnpSerializable.Create(reader.ThirdParty); break; } @@ -717,7 +739,7 @@ namespace Capnp.Rpc } private WHICH _which = WHICH.undefined; - private object _content; + private object? _content; public WHICH which { get => _which; @@ -749,7 +771,7 @@ namespace Capnp.Rpc case WHICH.Yourself: break; case WHICH.ThirdParty: - writer.ThirdParty.SetObject(ThirdParty); + writer.ThirdParty!.SetObject(ThirdParty); break; } } @@ -763,9 +785,9 @@ namespace Capnp.Rpc { } - public AnyPointer ThirdParty + public object? ThirdParty { - get => _which == WHICH.ThirdParty ? (AnyPointer)_content : null; + get => _which == WHICH.ThirdParty ? (object?)_content : null; set { _which = WHICH.ThirdParty; @@ -800,17 +822,20 @@ namespace Capnp.Rpc set => this.WriteData(48U, (ushort)value, (ushort)0); } - public DynamicSerializerState ThirdParty + [DisallowNull] + public DynamicSerializerState? ThirdParty { get => which == WHICH.ThirdParty ? BuildPointer(2) : default; - set => Link(2, value); + set => Link(2, value!); } } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9e19b28d3db3573aUL)] public class Return : ICapnpSerializable { + public const UInt64 typeId = 0x9e19b28d3db3573aUL; public enum WHICH : ushort { Results = 0, @@ -843,7 +868,7 @@ namespace Capnp.Rpc TakeFromOtherQuestion = reader.TakeFromOtherQuestion; break; case WHICH.AcceptFromThirdParty: - AcceptFromThirdParty = CapnpSerializable.Create(reader.AcceptFromThirdParty); + AcceptFromThirdParty = CapnpSerializable.Create(reader.AcceptFromThirdParty); break; } @@ -853,7 +878,7 @@ namespace Capnp.Rpc } private WHICH _which = WHICH.undefined; - private object _content; + private object? _content; public WHICH which { get => _which; @@ -890,20 +915,20 @@ namespace Capnp.Rpc switch (which) { case WHICH.Results: - Results?.serialize(writer.Results); + Results?.serialize(writer.Results!); break; case WHICH.Exception: - Exception?.serialize(writer.Exception); + Exception?.serialize(writer.Exception!); break; case WHICH.Canceled: break; case WHICH.ResultsSentElsewhere: break; case WHICH.TakeFromOtherQuestion: - writer.TakeFromOtherQuestion = TakeFromOtherQuestion.Value; + writer.TakeFromOtherQuestion = TakeFromOtherQuestion!.Value; break; case WHICH.AcceptFromThirdParty: - writer.AcceptFromThirdParty.SetObject(AcceptFromThirdParty); + writer.AcceptFromThirdParty!.SetObject(AcceptFromThirdParty); break; } @@ -933,9 +958,9 @@ namespace Capnp.Rpc } = true; - public Capnp.Rpc.Payload Results + public Capnp.Rpc.Payload? Results { - get => _which == WHICH.Results ? (Capnp.Rpc.Payload)_content : null; + get => _which == WHICH.Results ? (Capnp.Rpc.Payload?)_content : null; set { _which = WHICH.Results; @@ -943,9 +968,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Exception Exception + public Capnp.Rpc.Exception? Exception { - get => _which == WHICH.Exception ? (Capnp.Rpc.Exception)_content : null; + get => _which == WHICH.Exception ? (Capnp.Rpc.Exception?)_content : null; set { _which = WHICH.Exception; @@ -955,7 +980,7 @@ namespace Capnp.Rpc public uint? TakeFromOtherQuestion { - get => _which == WHICH.TakeFromOtherQuestion ? (uint? )_content : null; + get => _which == WHICH.TakeFromOtherQuestion ? (uint?)_content : null; set { _which = WHICH.TakeFromOtherQuestion; @@ -963,9 +988,9 @@ namespace Capnp.Rpc } } - public AnyPointer AcceptFromThirdParty + public object? AcceptFromThirdParty { - get => _which == WHICH.AcceptFromThirdParty ? (AnyPointer)_content : null; + get => _which == WHICH.AcceptFromThirdParty ? (object?)_content : null; set { _which = WHICH.AcceptFromThirdParty; @@ -1018,16 +1043,18 @@ namespace Capnp.Rpc set => this.WriteData(32UL, value, true); } - public Capnp.Rpc.Payload.WRITER Results + [DisallowNull] + public Capnp.Rpc.Payload.WRITER? Results { get => which == WHICH.Results ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Exception.WRITER Exception + [DisallowNull] + public Capnp.Rpc.Exception.WRITER? Exception { get => which == WHICH.Exception ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } public uint TakeFromOtherQuestion @@ -1036,16 +1063,19 @@ namespace Capnp.Rpc set => this.WriteData(64UL, value, 0U); } - public DynamicSerializerState AcceptFromThirdParty + [DisallowNull] + public DynamicSerializerState? AcceptFromThirdParty { get => which == WHICH.AcceptFromThirdParty ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd37d2eb2c2f80e63UL)] public class Finish : ICapnpSerializable { + public const UInt64 typeId = 0xd37d2eb2c2f80e63UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); @@ -1118,8 +1148,10 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbbc29655fa89086eUL)] public class Resolve : ICapnpSerializable { + public const UInt64 typeId = 0xbbc29655fa89086eUL; public enum WHICH : ushort { Cap = 0, @@ -1145,7 +1177,7 @@ namespace Capnp.Rpc } private WHICH _which = WHICH.undefined; - private object _content; + private object? _content; public WHICH which { get => _which; @@ -1172,10 +1204,10 @@ namespace Capnp.Rpc switch (which) { case WHICH.Cap: - Cap?.serialize(writer.Cap); + Cap?.serialize(writer.Cap!); break; case WHICH.Exception: - Exception?.serialize(writer.Exception); + Exception?.serialize(writer.Exception!); break; } @@ -1197,9 +1229,9 @@ namespace Capnp.Rpc set; } - public Capnp.Rpc.CapDescriptor Cap + public Capnp.Rpc.CapDescriptor? Cap { - get => _which == WHICH.Cap ? (Capnp.Rpc.CapDescriptor)_content : null; + get => _which == WHICH.Cap ? (Capnp.Rpc.CapDescriptor?)_content : null; set { _which = WHICH.Cap; @@ -1207,9 +1239,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.Exception Exception + public Capnp.Rpc.Exception? Exception { - get => _which == WHICH.Exception ? (Capnp.Rpc.Exception)_content : null; + get => _which == WHICH.Exception ? (Capnp.Rpc.Exception?)_content : null; set { _which = WHICH.Exception; @@ -1253,22 +1285,26 @@ namespace Capnp.Rpc set => this.WriteData(0UL, value, 0U); } - public Capnp.Rpc.CapDescriptor.WRITER Cap + [DisallowNull] + public Capnp.Rpc.CapDescriptor.WRITER? Cap { get => which == WHICH.Cap ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.Exception.WRITER Exception + [DisallowNull] + public Capnp.Rpc.Exception.WRITER? Exception { get => which == WHICH.Exception ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xad1a6c0d7dd07497UL)] public class Release : ICapnpSerializable { + public const UInt64 typeId = 0xad1a6c0d7dd07497UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); @@ -1340,13 +1376,15 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf964368b0fbd3711UL)] public class Disembargo : ICapnpSerializable { + public const UInt64 typeId = 0xf964368b0fbd3711UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); Target = CapnpSerializable.Create(reader.Target); - Context = CapnpSerializable.Create(reader.Context); + Context = CapnpSerializable.Create(reader.Context); applyDefaults(); } @@ -1365,13 +1403,13 @@ namespace Capnp.Rpc { } - public Capnp.Rpc.MessageTarget Target + public Capnp.Rpc.MessageTarget? Target { get; set; } - public Capnp.Rpc.Disembargo.@context Context + public Capnp.Rpc.Disembargo.context? Context { get; set; @@ -1389,7 +1427,7 @@ namespace Capnp.Rpc public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public Capnp.Rpc.MessageTarget.READER Target => ctx.ReadStruct(0, Capnp.Rpc.MessageTarget.READER.create); - public @context.READER Context => new @context.READER(ctx); + public context.READER Context => new context.READER(ctx); } public class WRITER : SerializerState @@ -1405,14 +1443,16 @@ namespace Capnp.Rpc set => Link(0, value); } - public @context.WRITER Context + public context.WRITER Context { - get => Rewrap<@context.WRITER>(); + get => Rewrap(); } } - public class @context : ICapnpSerializable + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd562b4df655bdd4dUL)] + public class context : ICapnpSerializable { + public const UInt64 typeId = 0xd562b4df655bdd4dUL; public enum WHICH : ushort { SenderLoopback = 0, @@ -1445,7 +1485,7 @@ namespace Capnp.Rpc } private WHICH _which = WHICH.undefined; - private object _content; + private object? _content; public WHICH which { get => _which; @@ -1477,15 +1517,15 @@ namespace Capnp.Rpc switch (which) { case WHICH.SenderLoopback: - writer.SenderLoopback = SenderLoopback.Value; + writer.SenderLoopback = SenderLoopback!.Value; break; case WHICH.ReceiverLoopback: - writer.ReceiverLoopback = ReceiverLoopback.Value; + writer.ReceiverLoopback = ReceiverLoopback!.Value; break; case WHICH.Accept: break; case WHICH.Provide: - writer.Provide = Provide.Value; + writer.Provide = Provide!.Value; break; } } @@ -1501,7 +1541,7 @@ namespace Capnp.Rpc public uint? SenderLoopback { - get => _which == WHICH.SenderLoopback ? (uint? )_content : null; + get => _which == WHICH.SenderLoopback ? (uint?)_content : null; set { _which = WHICH.SenderLoopback; @@ -1511,7 +1551,7 @@ namespace Capnp.Rpc public uint? ReceiverLoopback { - get => _which == WHICH.ReceiverLoopback ? (uint? )_content : null; + get => _which == WHICH.ReceiverLoopback ? (uint?)_content : null; set { _which = WHICH.ReceiverLoopback; @@ -1521,7 +1561,7 @@ namespace Capnp.Rpc public uint? Provide { - get => _which == WHICH.Provide ? (uint? )_content : null; + get => _which == WHICH.Provide ? (uint?)_content : null; set { _which = WHICH.Provide; @@ -1579,14 +1619,16 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9c6a046bfbc1ac5aUL)] public class Provide : ICapnpSerializable { + public const UInt64 typeId = 0x9c6a046bfbc1ac5aUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); QuestionId = reader.QuestionId; Target = CapnpSerializable.Create(reader.Target); - Recipient = CapnpSerializable.Create(reader.Recipient); + Recipient = CapnpSerializable.Create(reader.Recipient); applyDefaults(); } @@ -1612,13 +1654,13 @@ namespace Capnp.Rpc set; } - public Capnp.Rpc.MessageTarget Target + public Capnp.Rpc.MessageTarget? Target { get; set; } - public AnyPointer Recipient + public object? Recipient { get; set; @@ -1667,13 +1709,15 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd4c9b56290554016UL)] public class Accept : ICapnpSerializable { + public const UInt64 typeId = 0xd4c9b56290554016UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); QuestionId = reader.QuestionId; - Provision = CapnpSerializable.Create(reader.Provision); + Provision = CapnpSerializable.Create(reader.Provision); Embargo = reader.Embargo; applyDefaults(); } @@ -1700,7 +1744,7 @@ namespace Capnp.Rpc set; } - public AnyPointer Provision + public object? Provision { get; set; @@ -1755,14 +1799,16 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfbe1980490e001afUL)] public class Join : ICapnpSerializable { + public const UInt64 typeId = 0xfbe1980490e001afUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); QuestionId = reader.QuestionId; Target = CapnpSerializable.Create(reader.Target); - KeyPart = CapnpSerializable.Create(reader.KeyPart); + KeyPart = CapnpSerializable.Create(reader.KeyPart); applyDefaults(); } @@ -1788,13 +1834,13 @@ namespace Capnp.Rpc set; } - public Capnp.Rpc.MessageTarget Target + public Capnp.Rpc.MessageTarget? Target { get; set; } - public AnyPointer KeyPart + public object? KeyPart { get; set; @@ -1843,8 +1889,10 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x95bc14545813fbc1UL)] public class MessageTarget : ICapnpSerializable { + public const UInt64 typeId = 0x95bc14545813fbc1UL; public enum WHICH : ushort { ImportedCap = 0, @@ -1869,7 +1917,7 @@ namespace Capnp.Rpc } private WHICH _which = WHICH.undefined; - private object _content; + private object? _content; public WHICH which { get => _which; @@ -1896,10 +1944,10 @@ namespace Capnp.Rpc switch (which) { case WHICH.ImportedCap: - writer.ImportedCap = ImportedCap.Value; + writer.ImportedCap = ImportedCap!.Value; break; case WHICH.PromisedAnswer: - PromisedAnswer?.serialize(writer.PromisedAnswer); + PromisedAnswer?.serialize(writer.PromisedAnswer!); break; } } @@ -1915,7 +1963,7 @@ namespace Capnp.Rpc public uint? ImportedCap { - get => _which == WHICH.ImportedCap ? (uint? )_content : null; + get => _which == WHICH.ImportedCap ? (uint?)_content : null; set { _which = WHICH.ImportedCap; @@ -1923,9 +1971,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.PromisedAnswer PromisedAnswer + public Capnp.Rpc.PromisedAnswer? PromisedAnswer { - get => _which == WHICH.PromisedAnswer ? (Capnp.Rpc.PromisedAnswer)_content : null; + get => _which == WHICH.PromisedAnswer ? (Capnp.Rpc.PromisedAnswer?)_content : null; set { _which = WHICH.PromisedAnswer; @@ -1968,21 +2016,24 @@ namespace Capnp.Rpc set => this.WriteData(0UL, value, 0U); } - public Capnp.Rpc.PromisedAnswer.WRITER PromisedAnswer + [DisallowNull] + public Capnp.Rpc.PromisedAnswer.WRITER? PromisedAnswer { get => which == WHICH.PromisedAnswer ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9a0e61223d96743bUL)] public class Payload : ICapnpSerializable { + public const UInt64 typeId = 0x9a0e61223d96743bUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - Content = CapnpSerializable.Create(reader.Content); - CapTable = reader.CapTable.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + Content = CapnpSerializable.Create(reader.Content); + CapTable = reader.CapTable?.ToReadOnlyList(_ => CapnpSerializable.Create(_)!); applyDefaults(); } @@ -2001,13 +2052,13 @@ namespace Capnp.Rpc { } - public AnyPointer Content + public object? Content { get; set; } - public IReadOnlyList CapTable + public IReadOnlyList? CapTable { get; set; @@ -2049,8 +2100,10 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8523ddc40b86b8b0UL)] public class CapDescriptor : ICapnpSerializable { + public const UInt64 typeId = 0x8523ddc40b86b8b0UL; public enum WHICH : ushort { None = 0, @@ -2091,7 +2144,7 @@ namespace Capnp.Rpc } private WHICH _which = WHICH.undefined; - private object _content; + private object? _content; public WHICH which { get => _which; @@ -2131,19 +2184,19 @@ namespace Capnp.Rpc case WHICH.None: break; case WHICH.SenderHosted: - writer.SenderHosted = SenderHosted.Value; + writer.SenderHosted = SenderHosted!.Value; break; case WHICH.SenderPromise: - writer.SenderPromise = SenderPromise.Value; + writer.SenderPromise = SenderPromise!.Value; break; case WHICH.ReceiverHosted: - writer.ReceiverHosted = ReceiverHosted.Value; + writer.ReceiverHosted = ReceiverHosted!.Value; break; case WHICH.ReceiverAnswer: - ReceiverAnswer?.serialize(writer.ReceiverAnswer); + ReceiverAnswer?.serialize(writer.ReceiverAnswer!); break; case WHICH.ThirdPartyHosted: - ThirdPartyHosted?.serialize(writer.ThirdPartyHosted); + ThirdPartyHosted?.serialize(writer.ThirdPartyHosted!); break; } } @@ -2159,7 +2212,7 @@ namespace Capnp.Rpc public uint? SenderHosted { - get => _which == WHICH.SenderHosted ? (uint? )_content : null; + get => _which == WHICH.SenderHosted ? (uint?)_content : null; set { _which = WHICH.SenderHosted; @@ -2169,7 +2222,7 @@ namespace Capnp.Rpc public uint? SenderPromise { - get => _which == WHICH.SenderPromise ? (uint? )_content : null; + get => _which == WHICH.SenderPromise ? (uint?)_content : null; set { _which = WHICH.SenderPromise; @@ -2179,7 +2232,7 @@ namespace Capnp.Rpc public uint? ReceiverHosted { - get => _which == WHICH.ReceiverHosted ? (uint? )_content : null; + get => _which == WHICH.ReceiverHosted ? (uint?)_content : null; set { _which = WHICH.ReceiverHosted; @@ -2187,9 +2240,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.PromisedAnswer ReceiverAnswer + public Capnp.Rpc.PromisedAnswer? ReceiverAnswer { - get => _which == WHICH.ReceiverAnswer ? (Capnp.Rpc.PromisedAnswer)_content : null; + get => _which == WHICH.ReceiverAnswer ? (Capnp.Rpc.PromisedAnswer?)_content : null; set { _which = WHICH.ReceiverAnswer; @@ -2197,9 +2250,9 @@ namespace Capnp.Rpc } } - public Capnp.Rpc.ThirdPartyCapDescriptor ThirdPartyHosted + public Capnp.Rpc.ThirdPartyCapDescriptor? ThirdPartyHosted { - get => _which == WHICH.ThirdPartyHosted ? (Capnp.Rpc.ThirdPartyCapDescriptor)_content : null; + get => _which == WHICH.ThirdPartyHosted ? (Capnp.Rpc.ThirdPartyCapDescriptor?)_content : null; set { _which = WHICH.ThirdPartyHosted; @@ -2257,27 +2310,31 @@ namespace Capnp.Rpc set => this.WriteData(32UL, value, 0U); } - public Capnp.Rpc.PromisedAnswer.WRITER ReceiverAnswer + [DisallowNull] + public Capnp.Rpc.PromisedAnswer.WRITER? ReceiverAnswer { get => which == WHICH.ReceiverAnswer ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } - public Capnp.Rpc.ThirdPartyCapDescriptor.WRITER ThirdPartyHosted + [DisallowNull] + public Capnp.Rpc.ThirdPartyCapDescriptor.WRITER? ThirdPartyHosted { get => which == WHICH.ThirdPartyHosted ? BuildPointer(0) : default; - set => Link(0, value); + set => Link(0, value!); } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd800b1d6cd6f1ca0UL)] public class PromisedAnswer : ICapnpSerializable { + public const UInt64 typeId = 0xd800b1d6cd6f1ca0UL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); QuestionId = reader.QuestionId; - Transform = reader.Transform.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + Transform = reader.Transform?.ToReadOnlyList(_ => CapnpSerializable.Create(_)!); applyDefaults(); } @@ -2302,7 +2359,7 @@ namespace Capnp.Rpc set; } - public IReadOnlyList Transform + public IReadOnlyList? Transform { get; set; @@ -2343,8 +2400,10 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf316944415569081UL)] public class Op : ICapnpSerializable { + public const UInt64 typeId = 0xf316944415569081UL; public enum WHICH : ushort { Noop = 0, @@ -2369,7 +2428,7 @@ namespace Capnp.Rpc } private WHICH _which = WHICH.undefined; - private object _content; + private object? _content; public WHICH which { get => _which; @@ -2397,7 +2456,7 @@ namespace Capnp.Rpc case WHICH.Noop: break; case WHICH.GetPointerField: - writer.GetPointerField = GetPointerField.Value; + writer.GetPointerField = GetPointerField!.Value; break; } } @@ -2413,7 +2472,7 @@ namespace Capnp.Rpc public ushort? GetPointerField { - get => _which == WHICH.GetPointerField ? (ushort? )_content : null; + get => _which == WHICH.GetPointerField ? (ushort?)_content : null; set { _which = WHICH.GetPointerField; @@ -2458,12 +2517,14 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd37007fde1f0027dUL)] public class ThirdPartyCapDescriptor : ICapnpSerializable { + public const UInt64 typeId = 0xd37007fde1f0027dUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); - Id = CapnpSerializable.Create(reader.Id); + Id = CapnpSerializable.Create(reader.Id); VineId = reader.VineId; applyDefaults(); } @@ -2483,7 +2544,7 @@ namespace Capnp.Rpc { } - public AnyPointer Id + public object? Id { get; set; @@ -2531,8 +2592,10 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd625b7063acf691aUL)] public class Exception : ICapnpSerializable { + public const UInt64 typeId = 0xd625b7063acf691aUL; void ICapnpSerializable.Deserialize(DeserializerState arg_) { var reader = READER.create(arg_); @@ -2560,7 +2623,7 @@ namespace Capnp.Rpc { } - public string Reason + public string? Reason { get; set; @@ -2595,7 +2658,7 @@ namespace Capnp.Rpc public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Reason => ctx.ReadText(0, ""); + public string? Reason => ctx.ReadText(0, null); public bool ObsoleteIsCallersFault => ctx.ReadDataBool(0UL, false); public ushort ObsoleteDurability => ctx.ReadDataUShort(16UL, (ushort)0); public Capnp.Rpc.Exception.Type TheType => (Capnp.Rpc.Exception.Type)ctx.ReadDataUShort(32UL, (ushort)0); @@ -2608,10 +2671,10 @@ namespace Capnp.Rpc this.SetStruct(1, 1); } - public string Reason + public string? Reason { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public bool ObsoleteIsCallersFault @@ -2633,6 +2696,7 @@ namespace Capnp.Rpc } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb28c96e23f4cbd58UL)] public enum Type : ushort { failed, @@ -2641,6 +2705,4 @@ namespace Capnp.Rpc unimplemented } } -} - -#nullable restore \ No newline at end of file +} \ No newline at end of file diff --git a/Capnp.Net.Runtime/SerializerState.cs b/Capnp.Net.Runtime/SerializerState.cs index 4490ada..629f940 100644 --- a/Capnp.Net.Runtime/SerializerState.cs +++ b/Capnp.Net.Runtime/SerializerState.cs @@ -11,7 +11,7 @@ namespace Capnp /// by the code generator. Particularly, those writer classes are actually specializations of SerializerState, adding convenience methods /// for accessing the struct's fields. /// - public class SerializerState : IStructSerializer + public class SerializerState : IStructSerializer, IDisposable { /// /// Constructs a SerializerState instance for use in RPC context. @@ -30,7 +30,7 @@ namespace Capnp internal MessageBuilder? MsgBuilder { get; set; } internal ISegmentAllocator? Allocator => MsgBuilder?.Allocator; - internal List? Caps => MsgBuilder?.Caps; + internal List? Caps => MsgBuilder?.Caps; internal SerializerState? Owner { get; set; } internal int OwnerSlot { get; set; } internal uint SegmentIndex { get; set; } @@ -39,10 +39,10 @@ namespace Capnp internal int ListElementCount { get; set; } internal ushort StructDataCount { get; set; } internal ushort StructPtrCount { get; set; } - internal ObjectKind Kind { get; set; } internal uint CapabilityIndex { get; set; } SerializerState[]? _linkedStates; + bool _disposed; /// /// Constructs an unbound serializer state. @@ -76,6 +76,19 @@ namespace Capnp MsgBuilder = owner.MsgBuilder; } + internal void InheritFrom(SerializerState other) + { + SegmentIndex = other.SegmentIndex; + Offset = other.Offset; + WordsAllocated = other.WordsAllocated; + ListElementCount = other.ListElementCount; + StructDataCount = other.StructDataCount; + StructPtrCount = other.StructPtrCount; + Kind = other.Kind; + CapabilityIndex = other.CapabilityIndex; + _linkedStates = other._linkedStates; + } + /// /// Represents this state by a different serializer state specialization. This is similar to a type-cast: The underlying object remains the same, /// but the specialization adds a particular "view" on that data. @@ -93,7 +106,7 @@ namespace Capnp if (Kind != ObjectKind.Nil) { - InvalidOperationException InvalidWrap() => + static InvalidOperationException InvalidWrap() => new InvalidOperationException("Incompatible cast"); switch (ts.Kind) @@ -115,14 +128,7 @@ namespace Capnp break; } - ts.SegmentIndex = SegmentIndex; - ts.Offset = Offset; - ts.ListElementCount = ListElementCount; - ts.StructDataCount = StructDataCount; - ts.StructPtrCount = StructPtrCount; - ts.Kind = Kind; - ts.CapabilityIndex = CapabilityIndex; - ts._linkedStates = _linkedStates; + ts.InheritFrom(this); } if (Owner != null) @@ -133,18 +139,6 @@ namespace Capnp return ts; } - internal void InheritFrom(SerializerState other) - { - SegmentIndex = other.SegmentIndex; - Offset = other.Offset; - ListElementCount = other.ListElementCount; - StructDataCount = other.StructDataCount; - StructPtrCount = other.StructPtrCount; - Kind = other.Kind; - CapabilityIndex = other.CapabilityIndex; - _linkedStates = other._linkedStates; - } - /// /// Whether storage space for the underlying object was already allocated. Note that allocation happens /// lazily, i.e. constructing a SerializerState and binding it to a MessageBuilder does NOT yet result in allocation. @@ -163,7 +157,12 @@ namespace Capnp /// Returns the allocated memory slice (given this state already is allocated). Note that this definition is somewhat /// non-symmetric to DeserializerState.RawData. Never mind: You should not use it directly, anyway. /// - public Span RawData => SegmentSpan.Slice(Offset, (int)WordsAllocated); + public Span RawData => IsAllocated ? SegmentSpan.Slice(Offset, (int)WordsAllocated) : Span.Empty; + + /// + /// The kind of object this state currently represents. + /// + public ObjectKind Kind { get; internal set; } void AllocateWords(uint count) { @@ -172,12 +171,6 @@ namespace Capnp SegmentIndex = 0; Offset = 0; } - else if (Owner?.Kind == ObjectKind.ListOfStructs) - { - Owner.Allocate(); - SegmentIndex = Owner.SegmentIndex; - Offset = Owner.Offset + OwnerSlot + 1; - } else { if (Allocator == null) @@ -244,25 +237,41 @@ namespace Capnp } } - internal void EncodePointer(int offset, SerializerState target, bool allowCopy) + internal Rpc.ConsumedCapability DecodeCapPointer(int offset) { - if (target == null) - throw new ArgumentNullException(nameof(target)); + if (Caps == null) + throw new InvalidOperationException("Capbility table not set"); - if (!target.IsAllocated) - throw new InvalidOperationException("Target must be allocated before a pointer can be built"); - - if (MsgBuilder == null) - throw Unbound(); - - try + if (!IsAllocated) { - if (SegmentSpan[offset] != 0) - throw new InvalidOperationException("Won't replace an already allocated pointer to prevent memory leaks and security flaws"); + return Rpc.NullCapability.Instance; } - catch (IndexOutOfRangeException) + + WirePointer pointer = RawData[offset]; + + if (pointer.IsNull) { - throw new ArgumentOutOfRangeException(nameof(offset)); + return Rpc.NullCapability.Instance; + } + + if (pointer.Kind != PointerKind.Other) + { + throw new Rpc.RpcException("Expected a capability pointer, but got something different"); + } + + if (pointer.CapabilityIndex >= Caps.Count) + { + throw new Rpc.RpcException("Capability index out of range"); + } + + return Caps[(int)pointer.CapabilityIndex]; + } + + void EncodePointer(int offset, SerializerState target, bool allowCopy) + { + if (SegmentSpan[offset] != 0) + { + throw new InvalidOperationException("Won't replace an already allocated pointer to prevent memory leaks and security flaws"); } if (target.Allocator != null && @@ -272,7 +281,7 @@ namespace Capnp { Allocate(); - var targetCopy = new DynamicSerializerState(MsgBuilder); + var targetCopy = new DynamicSerializerState(MsgBuilder!); Reserializing.DeepCopy(target, targetCopy); target = targetCopy; } @@ -286,7 +295,7 @@ namespace Capnp Allocate(); } - WirePointer targetPtr = default(WirePointer); + WirePointer targetPtr = default; switch (target.Kind) { @@ -366,7 +375,7 @@ namespace Capnp farPtr2.SetFarPointer(target.SegmentIndex, target.Offset, false); var farSpan = FarSpan(landingPadSlice.SegmentIndex); farSpan[landingPadSlice.Offset] = farPtr2; - targetPtr.Offset = target.Offset; + targetPtr.Offset = 0; farSpan[landingPadSlice.Offset + 1] = targetPtr; } } @@ -377,31 +386,6 @@ namespace Capnp } } - internal Rpc.ConsumedCapability? DecodeCapPointer(int offset) - { - if (offset < 0) - throw new IndexOutOfRangeException(nameof(offset)); - - if (Caps == null) - throw new InvalidOperationException("Capbility table not set"); - - WirePointer pointer = RawData[offset]; - - if (pointer.Kind != PointerKind.Other) - { - throw new Rpc.RpcException( - "Expected a capability pointer, but got something different"); - } - - if (pointer.CapabilityIndex >= Caps.Count) - { - throw new Rpc.RpcException( - "Capability index out of range"); - } - - return Caps[(int)pointer.CapabilityIndex]; - } - /// /// Links a sub-item (struct field or list element) of this state to another state. Usually, this operation is not necessary, since objects are constructed top-down. /// However, there might be some advanced scenarios where you want to reference the same object twice (also interesting for designing amplification attacks). @@ -473,7 +457,7 @@ namespace Capnp /// This state does neither describe a struct, nor a list of pointers /// Another state is already linked to the specified position (sorry, no overwrite allowed) /// - protected void LinkToCapability(int slot, uint capabilityIndex) + protected void LinkToCapability(int slot, uint? capabilityIndex) { var cstate = new SerializerState(); cstate.SetCapability(capabilityIndex); @@ -513,19 +497,34 @@ namespace Capnp } } - internal void SetCapability(uint capabilityIndex) + /// + /// Determines the underyling object to be a capability. + /// + /// Capability table index, or null to encode a null pointer + /// The object type was already set to something different + protected void SetCapability(uint? capabilityIndex) { - if (Kind == ObjectKind.Nil) + if (capabilityIndex.HasValue) { - VerifyNotYetAllocated(); + if (Kind == ObjectKind.Nil) + { + VerifyNotYetAllocated(); - Kind = ObjectKind.Capability; - CapabilityIndex = capabilityIndex; - Allocate(); + Kind = ObjectKind.Capability; + CapabilityIndex = capabilityIndex.Value; + Allocate(); + } + else if (Kind != ObjectKind.Capability || CapabilityIndex != capabilityIndex) + { + throw AlreadySet(); + } } - else if (Kind != ObjectKind.Capability || CapabilityIndex != capabilityIndex) + else { - throw AlreadySet(); + if (Kind != ObjectKind.Nil) + { + throw AlreadySet(); + } } } @@ -539,38 +538,16 @@ namespace Capnp /// negative or exceeding 2^29-1 protected void SetListOfValues(byte bitsPerElement, int totalCount) { - ObjectKind kind; - - switch (bitsPerElement) + var kind = bitsPerElement switch { - case 0: - kind = ObjectKind.ListOfEmpty; - break; - - case 1: - kind = ObjectKind.ListOfBits; - break; - - case 8: - kind = ObjectKind.ListOfBytes; - break; - - case 16: - kind = ObjectKind.ListOfShorts; - break; - - case 32: - kind = ObjectKind.ListOfInts; - break; - - case 64: - kind = ObjectKind.ListOfLongs; - break; - - default: - throw new ArgumentOutOfRangeException(nameof(bitsPerElement)); - } - + 0 => ObjectKind.ListOfEmpty, + 1 => ObjectKind.ListOfBits, + 8 => ObjectKind.ListOfBytes, + 16 => ObjectKind.ListOfShorts, + 32 => ObjectKind.ListOfInts, + 64 => ObjectKind.ListOfLongs, + _ => throw new ArgumentOutOfRangeException(nameof(bitsPerElement)), + }; if (Kind == ObjectKind.Nil) { if (totalCount < 0) @@ -702,8 +679,6 @@ namespace Capnp if (relBitOffset + bitCount > 64) throw new ArgumentOutOfRangeException(nameof(bitCount)); - ulong word = data[index]; - if (bitCount == 64) { data[index] = value; @@ -741,6 +716,9 @@ namespace Capnp if (index >= data.Length) return 0; // Assume backwards-compatible change + if (count < 0) + throw new ArgumentOutOfRangeException(nameof(count)); + if (relBitOffset + count > 64) throw new ArgumentOutOfRangeException(nameof(count)); @@ -802,6 +780,9 @@ namespace Capnp if (Kind != ObjectKind.Struct && Kind != ObjectKind.ListOfPointers) throw new InvalidOperationException("This is not a struct or list of pointers"); + if (index < 0 || index >= _linkedStates!.Length) + throw new ArgumentOutOfRangeException(nameof(index)); + var state = _linkedStates![index]; if (state == null) return null; @@ -875,14 +856,14 @@ namespace Capnp /// If the underlying object is a struct: index into the struct's pointer section. /// If the underlying object is a list of pointers: Element index /// Text to encode - /// Default text of > is null + /// Default text if > is null /// Both and are null /// /// The underlying object was not determined to be a struct or list of pointers. /// Object at given position was already set. /// /// is out of bounds. - public void WriteText(int index, string? text, string defaultText) + public void WriteText(int index, string? text, string? defaultText) { BuildPointer(index).WriteText(text ?? defaultText); } @@ -899,6 +880,9 @@ namespace Capnp if (Kind != ObjectKind.ListOfStructs) throw new InvalidOperationException("This is not a list of structs"); + if (index < 0 || index >= _linkedStates!.Length) + throw new ArgumentOutOfRangeException(nameof(index)); + ref var state = ref _linkedStates![index]; if (state == null) @@ -926,6 +910,9 @@ namespace Capnp if (Kind != ObjectKind.ListOfStructs) throw new InvalidOperationException("This is not a list of structs"); + if (index < 0 || index >= _linkedStates!.Length) + throw new ArgumentOutOfRangeException(nameof(index)); + ref var state = ref _linkedStates![index]; if (state == null) @@ -1074,7 +1061,7 @@ namespace Capnp /// /// The list bytes /// The underlying object was not set to a list of bytes. - Span ListGetBytes() + public Span ListGetBytes() { if (Kind != ObjectKind.ListOfBytes) throw new InvalidOperationException("This is not a list of bytes"); @@ -1251,10 +1238,13 @@ namespace Capnp /// Adds an entry to the capability table if the provided capability does not yet exist. /// /// The low-level capability object to provide. - /// Index of the given capability in the capability table + /// Index of the given capability in the capability table, null if capability is null /// The underlying message builder was not configured for capability table support. - public uint ProvideCapability(Rpc.ConsumedCapability? capability) + public uint? ProvideCapability(Rpc.ConsumedCapability capability) { + if (capability == null || capability == Rpc.NullCapability.Instance) + return null; + if (Caps == null) throw new InvalidOperationException("Underlying MessageBuilder was not enabled to support capabilities"); @@ -1264,7 +1254,7 @@ namespace Capnp { index = Caps.Count; Caps.Add(capability); - capability?.AddRef(); + capability.AddRef(); } return (uint)index; @@ -1276,34 +1266,38 @@ namespace Capnp /// The capability to provide, in terms of its skeleton. /// Index of the given capability in the capability table /// The underlying message builder was not configured for capability table support. - public uint ProvideCapability(Rpc.Skeleton capability) + public uint? ProvideCapability(Rpc.Skeleton capability) { - return ProvideCapability(Rpc.LocalCapability.Create(capability)); + return ProvideCapability(capability.AsCapability()); } /// /// Adds an entry to the capability table if the provided capability does not yet exist. /// /// The capability, in one of the following forms: - /// Low-level capability object (Rpc.ConsumedCapability) - /// Proxy object (Rpc.Proxy) - /// Skeleton object (Rpc.Skeleton) + /// Low-level capability () + /// Proxy object (). Note that the provision has "move semantics": SerializerState + /// takes ownership, so the Proxy object will be disposed. + /// instance /// Capability interface implementation /// /// Index of the given capability in the capability table /// The underlying message builder was not configured for capability table support. - public uint ProvideCapability(object? obj) + public uint? ProvideCapability(object? obj) { - if (obj == null) - return ProvideCapability(default(Rpc.ConsumedCapability)); - else if (obj is Rpc.Proxy proxy) - return ProvideCapability(proxy.ConsumedCap); - else if (obj is Rpc.ConsumedCapability consumedCapability) - return ProvideCapability(consumedCapability); - else if (obj is Rpc.Skeleton providedCapability) - return ProvideCapability(providedCapability); - else - return ProvideCapability(Rpc.Skeleton.GetOrCreateSkeleton(obj, false)); + switch (obj) + { + case null: + return null; + case Rpc.Proxy proxy: using (proxy) + return ProvideCapability(proxy.ConsumedCap); + case Rpc.ConsumedCapability consumedCapability: + return ProvideCapability(consumedCapability); + case Rpc.Skeleton providedCapability: + return ProvideCapability(providedCapability); + default: + return ProvideCapability(Rpc.CapabilityReflection.CreateSkeletonInternal(obj)); + } } /// @@ -1325,7 +1319,7 @@ namespace Capnp /// /// is out of range. /// - /// This state does neither describe a struct, nor a list of pointers + /// Object neither describes a struct, nor a list of pointers, nor a capability /// Another state is already linked to the specified position (sorry, no overwrite allowed) /// public void LinkObject(int slot, T obj) @@ -1357,21 +1351,27 @@ namespace Capnp break; default: - if (Rpc.CapabilityReflection.IsValidCapabilityInterface(typeof(T))) + try { LinkToCapability(slot, ProvideCapability(obj)); } + catch (Exception exception) when ( + exception is Rpc.InvalidCapabilityInterfaceException || + exception is InvalidOperationException) + { + throw new InvalidOperationException("Object neither describes a struct, nor a list of pointers, nor a capability", exception); + } break; } } - internal Rpc.ConsumedCapability? StructReadRawCap(int index) + internal Rpc.ConsumedCapability StructReadRawCap(int index) { if (Kind != ObjectKind.Struct && Kind != ObjectKind.Nil) throw new InvalidOperationException("Allowed on structs only"); - if (index >= StructPtrCount) - return null; + if (index < 0 || index >= StructPtrCount) + throw new ArgumentOutOfRangeException(nameof(index)); return DecodeCapPointer(index + StructDataCount); } @@ -1385,10 +1385,10 @@ namespace Capnp /// is out of range. /// The desired interface does not qualify as capability interface () /// This state does not represent a struct. - public T? ReadCap(int slot) where T : class + public T ReadCap(int slot) where T : class { var cap = StructReadRawCap(slot); - return Rpc.CapabilityReflection.CreateProxy(cap) as T; + return (Rpc.CapabilityReflection.CreateProxy(cap) as T)!; } /// @@ -1403,5 +1403,22 @@ namespace Capnp var cap = StructReadRawCap(slot); return new Rpc.BareProxy(cap); } + + /// + /// Releases the capability table + /// + public void Dispose() + { + if (Caps != null && !_disposed) + { + foreach (var cap in Caps) + { + cap.Release(); + } + + Caps.Clear(); + _disposed = true; + } + } } } \ No newline at end of file diff --git a/Capnp.Net.Runtime/Util/StrictlyOrderedAwaitTask.cs b/Capnp.Net.Runtime/Util/StrictlyOrderedAwaitTask.cs new file mode 100644 index 0000000..c5137c9 --- /dev/null +++ b/Capnp.Net.Runtime/Util/StrictlyOrderedAwaitTask.cs @@ -0,0 +1,269 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Capnp.Util +{ + /// + /// A task-like object which enforces that all await operations from the same thread leave in the exact order they were issued. + /// Note that an ordinary .NET Task does not fulfill this requirement if completed by a thread which is different from the + /// awaiting thread. + /// + public class StrictlyOrderedAwaitTask: INotifyCompletion + { + class Cover { } + class Seal { } + + static readonly Cover s_cover = new Cover(); + static readonly Seal s_seal = new Seal(); + + readonly Task _awaitedTask; + object? _state; + + /// + /// Constructs an instance + /// + /// Task on which the order shall be enforced + public StrictlyOrderedAwaitTask(Task awaitedTask) + { + _awaitedTask = awaitedTask; + _state = s_cover; + } + + /// + /// await pattern implementation + /// + /// An object suitable for the await pattern + public StrictlyOrderedAwaitTask GetAwaiter() + { + return this; + } + + async void AwaitInternal() + { + try + { + await _awaitedTask; + } + catch + { + } + finally + { +#if SOTASK_PERF + long outerCount = 0, innerCount = 0; +#endif + + SpinWait.SpinUntil(() => + { + Action? continuations; + + while (true) + { +#if SOTASK_PERF + ++innerCount; +#endif + + continuations = (Action?)Interlocked.Exchange(ref _state, null); + + if (continuations != null) + continuations(); + else + break; + } + +#if SOTASK_PERF + ++outerCount; +#endif + return Interlocked.CompareExchange(ref _state, s_seal, null) == null; + }); + +#if SOTASK_PERF + StrictlyOrderedTaskExtensions.Stats.UpdateAwaitInternal(outerCount, innerCount); +#endif + } + } + + /// + /// Part of await pattern implementation. Do not use directly. + /// + public void OnCompleted(Action continuation) + { + bool first = false; + +#if SOTASK_PERF + long spinCount = 0; +#endif + + SpinWait.SpinUntil(() => { + +#if SOTASK_PERF + ++spinCount; +#endif + + object? cur, next; + cur = Volatile.Read(ref _state); + first = false; + switch (cur) + { + case Cover cover: + next = continuation; + first = true; + break; + + case null: + next = continuation; + break; + + case Action action: + next = action + continuation; + break; + + default: + continuation(); + return true; + } + + return Interlocked.CompareExchange(ref _state, next, cur) == cur; + }); + +#if SOTASK_PERF + StrictlyOrderedTaskExtensions.Stats.UpdateOnCompleted(spinCount); +#endif + + if (first) + { + AwaitInternal(); + } + } + + /// + /// Whether the underlying task did complete and it is safe to skip continuation registration. + /// + public bool IsCompleted => _awaitedTask.IsCompleted && (_state == s_cover || _state == s_seal); + + /// + /// Part of await pattern implementation. Do not use directly. + /// + public void GetResult() => _awaitedTask.GetAwaiter().GetResult(); + + /// + /// Task on which the order shall be enforced. + /// + public Task WrappedTask => _awaitedTask; + } + + /// + /// A task-like object which enforces that all await operations from the same thread leave in the exact order they were issued. + /// Note that an ordinary .NET Task does not fulfill this requirement if completed by a thread which is different from the + /// awaiting thread. + /// + public class StrictlyOrderedAwaitTask : StrictlyOrderedAwaitTask + { + + /// + /// Constructs an instance + /// + /// Task on which the order shall be enforced + public StrictlyOrderedAwaitTask(Task awaitedTask): base(awaitedTask) + { + } + + /// + /// Task on which the order shall be enforced. + /// + public new Task WrappedTask => (Task)base.WrappedTask; + + /// + /// await pattern implementation + /// + /// An object suitable for the await pattern + public new StrictlyOrderedAwaitTask GetAwaiter() => this; + + /// + /// Part of await pattern implementation. Do not use directly. + /// + public new T GetResult() => WrappedTask.GetAwaiter().GetResult(); + + /// + /// Redirects to the wrapped Task's result. + /// + public T Result => WrappedTask.Result; + + } + + /// + /// Extension methods to simplify the use of + /// + public static class StrictlyOrderedTaskExtensions + { +#if SOTASK_PERF + public class Statistics + { + internal long _awaitInternalMaxOuterIterations; + internal long _awaitInternalMaxInnerIterations; + internal long _onCompletedMaxSpins; + + public long AwaitInternalMaxOuterIterations => Volatile.Read(ref _awaitInternalMaxOuterIterations); + public long AwaitInternalMaxInnerIterations => Volatile.Read(ref _awaitInternalMaxInnerIterations); + public long OnCompletedMaxSpins => Volatile.Read(ref _onCompletedMaxSpins); + + public void Reset() + { + Volatile.Write(ref _awaitInternalMaxOuterIterations, 0); + Volatile.Write(ref _awaitInternalMaxInnerIterations, 0); + Volatile.Write(ref _onCompletedMaxSpins, 0); + } + + internal static void InterlockedMax(ref long current, long value) + { + long existing; + do + { + existing = Volatile.Read(ref current); + if (value <= existing) return; + } while (Interlocked.CompareExchange(ref current, value, existing) != existing); + } + + internal void UpdateAwaitInternal(long outerCount, long innerCount) + { + InterlockedMax(ref _awaitInternalMaxOuterIterations, outerCount); + InterlockedMax(ref _awaitInternalMaxInnerIterations, innerCount); + } + + internal void UpdateOnCompleted(long spinCount) + { + InterlockedMax(ref _onCompletedMaxSpins, spinCount); + } + } + + /// + /// Performance profiling statistics + /// + public static readonly Statistics Stats = new Statistics(); +#endif + /// + /// Converts the task to a task-like object which enforces that all await operations from the same thread leave in the exact order they were issued. + /// + /// The type of the result produced by the Task + /// Task to wrap + /// awaitable object + public static StrictlyOrderedAwaitTask EnforceAwaitOrder(this Task task) + { + return new StrictlyOrderedAwaitTask(task); + } + + /// + /// Converts the task to a task-like object which enforces that all await operations from the same thread leave in the exact order they were issued. + /// + /// Task to wrap + /// awaitable object + public static StrictlyOrderedAwaitTask EnforceAwaitOrder(this Task task) + { + return new StrictlyOrderedAwaitTask(task); + } + } +} diff --git a/Capnp.Net.Runtime/Util/ThreadExtensions.cs b/Capnp.Net.Runtime/Util/ThreadExtensions.cs new file mode 100644 index 0000000..a53da32 --- /dev/null +++ b/Capnp.Net.Runtime/Util/ThreadExtensions.cs @@ -0,0 +1,49 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; + +namespace Capnp.Util +{ + internal static class ThreadExtensions + { + class ThreadExtensionsLoggingContext + { + public ILogger Logger { get; } = Logging.CreateLogger(); + } + + static Lazy LoggingContext = new Lazy( + () => new ThreadExtensionsLoggingContext(), + LazyThreadSafetyMode.PublicationOnly); + + public static void SafeJoin(this Thread thread, ILogger? logger = null, int timeout = 5000) + { + if (!thread.Join(timeout)) + { + logger ??= LoggingContext.Value.Logger; + + string name = thread.Name ?? thread.ManagedThreadId.ToString(); + + try + { + logger.LogError($"Unable to join thread {name}. Thread is in state {thread.ThreadState}."); + thread.Interrupt(); + if (!thread.Join(timeout / 10)) + { + logger.LogError($"Still unable to join thread {name} after Interrupt(). Thread is in state {thread.ThreadState}."); + thread.Abort(); + if (thread.Join(timeout / 10)) + { + logger.LogError($"Still unable to join thread {name} after Abort(). Thread is in state {thread.ThreadState}."); + } + } + } + catch + { + } + } + } + } +} diff --git a/Capnp.Net.Runtime/WirePointer.cs b/Capnp.Net.Runtime/WirePointer.cs index 197886e..5f17dca 100644 --- a/Capnp.Net.Runtime/WirePointer.cs +++ b/Capnp.Net.Runtime/WirePointer.cs @@ -219,10 +219,13 @@ namespace Capnp /// /// Encodes a capability pointer. /// - /// capability index - public void SetCapability(uint index) + /// capability index, 'null' means 'null pointer' + public void SetCapability(uint? index) { - _ptrData = ((ulong)index << 32) | (ulong)PointerKind.Other; + if (index.HasValue) + _ptrData = ((ulong)index << 32) | (ulong)PointerKind.Other; + else + _ptrData = 0; } } } \ No newline at end of file diff --git a/Capnp.Net.sln b/Capnp.Net.sln index ff53c1c..70a4fcf 100644 --- a/Capnp.Net.sln +++ b/Capnp.Net.sln @@ -7,9 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime", "Capnp. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "capnpc-csharp", "capnpc-csharp\capnpc-csharp.csproj", "{D19E5EA7-D35B-4A1F-99CB-ED136316B577}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime.Tests.Std20", "Capnp.Net.Runtime.Tests\Capnp.Net.Runtime.Tests.Std20.csproj", "{9ED38750-F83F-4B10-B3A3-4FD6183F9E86}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime.Tests.Core21", "Capnp.Net.Runtime.Tests.Core21\Capnp.Net.Runtime.Tests.Core21.csproj", "{58E8FFC8-D207-4B0F-842A-58ED9D3D9EEF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime.Tests", "Capnp.Net.Runtime.Tests\Capnp.Net.Runtime.Tests.csproj", "{9ED38750-F83F-4B10-B3A3-4FD6183F9E86}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CapnpC.CSharp.Generator.Tests", "CapnpC.CSharp.Generator.Tests\CapnpC.CSharp.Generator.Tests.csproj", "{B77AC567-E232-4072-85C3-8689566BF3D4}" EndProject @@ -37,10 +35,6 @@ Global {9ED38750-F83F-4B10-B3A3-4FD6183F9E86}.Debug|Any CPU.Build.0 = Debug|Any CPU {9ED38750-F83F-4B10-B3A3-4FD6183F9E86}.Release|Any CPU.ActiveCfg = Release|Any CPU {9ED38750-F83F-4B10-B3A3-4FD6183F9E86}.Release|Any CPU.Build.0 = Release|Any CPU - {58E8FFC8-D207-4B0F-842A-58ED9D3D9EEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {58E8FFC8-D207-4B0F-842A-58ED9D3D9EEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {58E8FFC8-D207-4B0F-842A-58ED9D3D9EEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {58E8FFC8-D207-4B0F-842A-58ED9D3D9EEF}.Release|Any CPU.Build.0 = Release|Any CPU {B77AC567-E232-4072-85C3-8689566BF3D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B77AC567-E232-4072-85C3-8689566BF3D4}.Debug|Any CPU.Build.0 = Debug|Any CPU {B77AC567-E232-4072-85C3-8689566BF3D4}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj b/CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj index 77462b1..86f1a6b 100644 --- a/CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj +++ b/CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj @@ -30,6 +30,10 @@ + + + + diff --git a/CapnpC.CSharp.Generator.Tests/CodeGenerator.feature b/CapnpC.CSharp.Generator.Tests/CodeGenerator.feature index 6d8d53f..2da098b 100644 --- a/CapnpC.CSharp.Generator.Tests/CodeGenerator.feature +++ b/CapnpC.CSharp.Generator.Tests/CodeGenerator.feature @@ -70,4 +70,6 @@ Examples: | NullableDisable2.capnp.bin | false | false | errors | | NullableDisable2.capnp.bin | false | true | success | | NullableEnable2.capnp.bin | false | false | errors | - | NullableEnable2.capnp.bin | false | true | success | \ No newline at end of file + | NullableEnable2.capnp.bin | false | true | success | + | rpc-csharp.capnp.bin | true | true | warnings | + | schema-csharp.capnp.bin | false | false | success | \ No newline at end of file diff --git a/CapnpC.CSharp.Generator.Tests/CodeGenerator.feature.cs b/CapnpC.CSharp.Generator.Tests/CodeGenerator.feature.cs index 3fa5c2c..8070e3f 100644 --- a/CapnpC.CSharp.Generator.Tests/CodeGenerator.feature.cs +++ b/CapnpC.CSharp.Generator.Tests/CodeGenerator.feature.cs @@ -647,6 +647,36 @@ this.ValidGeneratorOutput("NullableEnable2.capnp.bin", "false", "false", "errors { #line 50 this.ValidGeneratorOutput("NullableEnable2.capnp.bin", "false", "true", "success", ((string[])(null))); +#line hidden + } + + [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()] + [Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("Valid generator output: Variant 15")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("FeatureTitle", "CodeGenerator")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("VariantName", "Variant 15")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:bin", "rpc-csharp.capnp.bin")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:nullablegen", "true")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:nullablesupp", "true")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:outcome", "warnings")] + public virtual void ValidGeneratorOutput_Variant15() + { +#line 50 +this.ValidGeneratorOutput("rpc-csharp.capnp.bin", "true", "true", "warnings", ((string[])(null))); +#line hidden + } + + [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()] + [Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("Valid generator output: Variant 16")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("FeatureTitle", "CodeGenerator")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("VariantName", "Variant 16")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:bin", "schema-csharp.capnp.bin")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:nullablegen", "false")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:nullablesupp", "false")] + [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:outcome", "success")] + public virtual void ValidGeneratorOutput_Variant16() + { +#line 50 +this.ValidGeneratorOutput("schema-csharp.capnp.bin", "false", "false", "success", ((string[])(null))); #line hidden } } diff --git a/CapnpC.CSharp.Generator.Tests/CodeGeneratorUnitTests.cs b/CapnpC.CSharp.Generator.Tests/CodeGeneratorUnitTests.cs index 4ccbd9b..9f71803 100644 --- a/CapnpC.CSharp.Generator.Tests/CodeGeneratorUnitTests.cs +++ b/CapnpC.CSharp.Generator.Tests/CodeGeneratorUnitTests.cs @@ -45,13 +45,13 @@ namespace CapnpC.CSharp.Generator.Tests [TestMethod] public void Test04MutualDependencies() { - LoadAndGenerate("UnitTest4.capnp.bin"); + LoadAndGenerate("UnitTest4.capnp.bin", "UnitTest4b.capnp.bin"); } [TestMethod] public void Test10ImportedNamespaces() { - var (model, codegen, _) = LoadAndGenerate("UnitTest10.capnp.bin"); + var (model, codegen, _) = LoadAndGenerate("UnitTest10.capnp.bin", "UnitTest10b.capnp.bin"); var outerTypeDef = GetGeneratedFile("UnitTest10.capnp", model).NestedTypes.First(); var outerType = Model.Types.FromDefinition(outerTypeDef); var innerType = outerTypeDef.Fields[0].Type; @@ -72,7 +72,7 @@ namespace CapnpC.CSharp.Generator.Tests [TestMethod] public void Test11ImportedConst() { - LoadAndGenerate("UnitTest11.capnp.bin"); + LoadAndGenerate("UnitTest11.capnp.bin", "UnitTest11b.capnp.bin"); } [TestMethod] @@ -147,20 +147,54 @@ namespace CapnpC.CSharp.Generator.Tests LoadAndGenerate("schema-with-offsets.capnp.bin"); } - static (Model.SchemaModel, CodeGen.CodeGenerator, string) LoadAndGenerate(string inputName) + [TestMethod] + public void Issue45() { - var model = Load(inputName); - var codegen = new CodeGen.CodeGenerator(model, new CodeGen.GeneratorOptions()); + var input = CodeGeneratorSteps.LoadResource("Issue45.capnp.bin"); + using (input) + { + var frame = Framing.ReadSegments(input); + var ds = DeserializerState.CreateRoot(frame); + var cgr = CapnpSerializable.Create(ds); + Assert.IsTrue(cgr.Nodes.Count > 0); + } + + } + + static (Model.SchemaModel, CodeGen.CodeGenerator, string) LoadAndGenerate(params string[] inputNames) + { + Model.SchemaModel firstModel = null; + CodeGen.CodeGenerator firstCodeGen = null; + + Model.SchemaModel LocalLoad(string name) + { + var model = Load(name); + firstModel = firstModel ?? model; + return model; + } + + CodeGen.CodeGenerator CreateCodeGen(Model.SchemaModel model) + { + var codegen = new CodeGen.CodeGenerator(model, new CodeGen.GeneratorOptions()); + firstCodeGen = firstCodeGen ?? codegen; + return codegen; + } + + var codes = ( + from name in inputNames + let model = LocalLoad(name) + let codegen = CreateCodeGen(model) + from file in model.FilesToGenerate + select codegen.Transform(file)).ToArray(); - var code = model.FilesToGenerate.Select(f => codegen.Transform(f)).ToArray(); Assert.AreEqual( Util.InlineAssemblyCompiler.CompileSummary.Success, Util.InlineAssemblyCompiler.TryCompileCapnp( Microsoft.CodeAnalysis.NullableContextOptions.Disable, - code), + codes), "Compilation was not successful with no warnings"); - return (model, codegen, code[0]); + return (firstModel, firstCodeGen, codes[0]); } static Model.GenFile GetGeneratedFile(string name, Model.SchemaModel model) @@ -199,7 +233,7 @@ namespace CapnpC.CSharp.Generator.Tests segments = Framing.ReadSegments(input); } var dec = DeserializerState.CreateRoot(segments); - var reader = CodeGeneratorRequest.Reader.Create(dec); + var reader = CodeGeneratorRequest.READER.create(dec); var model = Model.SchemaModel.Create(reader); return model; } diff --git a/CapnpC.CSharp.Generator.Tests/Embedded b/CapnpC.CSharp.Generator.Tests/Embedded new file mode 100644 index 0000000..79d5e7d Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/Embedded differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/Issue45.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/Issue45.capnp.bin new file mode 100644 index 0000000..7bc8073 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/Issue45.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableDisable.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableDisable.capnp.bin index 14f05c8..0195af5 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableDisable.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableDisable.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableDisable2.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableDisable2.capnp.bin index dcc032a..5681502 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableDisable2.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableDisable2.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableEnable.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableEnable.capnp.bin index 4a92c1a..6c81ea6 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableEnable.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableEnable.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableEnable2.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableEnable2.capnp.bin index 45ae2c0..28fe926 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableEnable2.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/NullableEnable2.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest1.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest1.capnp.bin index ae47486..c417bd7 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest1.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest1.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest10.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest10.capnp.bin index 03a927d..7c2df5d 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest10.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest10.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest10b.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest10b.capnp.bin new file mode 100644 index 0000000..a940975 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest10b.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest11.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest11.capnp.bin index 1d702ab..85d58d0 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest11.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest11.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest11b.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest11b.capnp.bin new file mode 100644 index 0000000..be1a002 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest11b.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest12.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest12.capnp.bin index 988e7d0..c861841 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest12.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest12.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest13.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest13.capnp.bin index bcf65cb..805357e 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest13.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest13.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest14.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest14.capnp.bin index 0e48988..ade1157 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest14.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest14.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest15.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest15.capnp.bin index 2cd9b98..267ea05 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest15.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest15.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest2.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest2.capnp.bin index 5a2eafc..e980262 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest2.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest2.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest20.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest20.capnp.bin index 48f5e96..92195af 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest20.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest20.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest3.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest3.capnp.bin index c0a1dae..010bfe1 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest3.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest3.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest4.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest4.capnp.bin index edcead0..710cca6 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest4.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest4.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest4b.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest4b.capnp.bin new file mode 100644 index 0000000..79d5e7d Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest4b.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/rpc-csharp.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/rpc-csharp.capnp.bin new file mode 100644 index 0000000..0a66adb Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/rpc-csharp.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/schema-csharp.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/schema-csharp.capnp.bin new file mode 100644 index 0000000..4060d87 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/schema-csharp.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.capnp.bin b/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.capnp.bin index 66c8d13..199c9d3 100644 Binary files a/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.capnp.bin and b/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.capnp.bin differ diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs b/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs index 3a90610..ac83045 100644 --- a/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs +++ b/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs @@ -1,13 +1,14 @@ using Capnp; using Capnp.Rpc; using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace Capnproto_test.Capnp.Test { - [TypeId(0x9c8e9318b29d9cd3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9c8e9318b29d9cd3UL)] public enum TestEnum : ushort { foo, @@ -20,7 +21,7 @@ namespace Capnproto_test.Capnp.Test garply } - [TypeId(0xa0a8f314b80b63fdUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa0a8f314b80b63fdUL)] public class TestAllTypes : ICapnpSerializable { public const UInt64 typeId = 0xa0a8f314b80b63fdUL; @@ -321,7 +322,7 @@ namespace Capnproto_test.Capnp.Test public ulong UInt64Field => ctx.ReadDataULong(192UL, 0UL); public float Float32Field => ctx.ReadDataFloat(256UL, 0F); public double Float64Field => ctx.ReadDataDouble(320UL, 0); - public string TextField => ctx.ReadText(0, ""); + public string TextField => ctx.ReadText(0, null); public IReadOnlyList DataField => ctx.ReadList(1).CastByte(); public Capnproto_test.Capnp.Test.TestAllTypes.READER StructField => ctx.ReadStruct(2, Capnproto_test.Capnp.Test.TestAllTypes.READER.create); public Capnproto_test.Capnp.Test.TestEnum EnumField => (Capnproto_test.Capnp.Test.TestEnum)ctx.ReadDataUShort(288UL, (ushort)0); @@ -419,8 +420,8 @@ namespace Capnproto_test.Capnp.Test public string TextField { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ListOfPrimitivesSerializer DataField @@ -545,7 +546,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xeb3f9ebe98c73cb6UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xeb3f9ebe98c73cb6UL)] public class TestDefaults : ICapnpSerializable { public const UInt64 typeId = 0xeb3f9ebe98c73cb6UL; @@ -1117,7 +1118,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe3da5a2ccd28c0d8UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe3da5a2ccd28c0d8UL)] public class TestAnyPointer : ICapnpSerializable { public const UInt64 typeId = 0xe3da5a2ccd28c0d8UL; @@ -1177,7 +1178,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf49850f63c2bfa59UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf49850f63c2bfa59UL)] public class TestAnyOthers : ICapnpSerializable { public const UInt64 typeId = 0xf49850f63c2bfa59UL; @@ -1267,7 +1268,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa9d5f8efe770022bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9d5f8efe770022bUL)] public class TestOutOfOrder : ICapnpSerializable { public const UInt64 typeId = 0xa9d5f8efe770022bUL; @@ -1373,15 +1374,15 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Qux => ctx.ReadText(0, ""); - public string Grault => ctx.ReadText(1, ""); - public string Bar => ctx.ReadText(2, ""); - public string Foo => ctx.ReadText(3, ""); - public string Corge => ctx.ReadText(4, ""); - public string Waldo => ctx.ReadText(5, ""); - public string Quux => ctx.ReadText(6, ""); - public string Garply => ctx.ReadText(7, ""); - public string Baz => ctx.ReadText(8, ""); + public string Qux => ctx.ReadText(0, null); + public string Grault => ctx.ReadText(1, null); + public string Bar => ctx.ReadText(2, null); + public string Foo => ctx.ReadText(3, null); + public string Corge => ctx.ReadText(4, null); + public string Waldo => ctx.ReadText(5, null); + public string Quux => ctx.ReadText(6, null); + public string Garply => ctx.ReadText(7, null); + public string Baz => ctx.ReadText(8, null); } public class WRITER : SerializerState @@ -1393,61 +1394,61 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Grault { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } public string Bar { - get => this.ReadText(2, ""); - set => this.WriteText(2, value, ""); + get => this.ReadText(2, null); + set => this.WriteText(2, value, null); } public string Foo { - get => this.ReadText(3, ""); - set => this.WriteText(3, value, ""); + get => this.ReadText(3, null); + set => this.WriteText(3, value, null); } public string Corge { - get => this.ReadText(4, ""); - set => this.WriteText(4, value, ""); + get => this.ReadText(4, null); + set => this.WriteText(4, value, null); } public string Waldo { - get => this.ReadText(5, ""); - set => this.WriteText(5, value, ""); + get => this.ReadText(5, null); + set => this.WriteText(5, value, null); } public string Quux { - get => this.ReadText(6, ""); - set => this.WriteText(6, value, ""); + get => this.ReadText(6, null); + set => this.WriteText(6, value, null); } public string Garply { - get => this.ReadText(7, ""); - set => this.WriteText(7, value, ""); + get => this.ReadText(7, null); + set => this.WriteText(7, value, null); } public string Baz { - get => this.ReadText(8, ""); - set => this.WriteText(8, value, ""); + get => this.ReadText(8, null); + set => this.WriteText(8, value, null); } } } - [TypeId(0xf47697362233ce52UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf47697362233ce52UL)] public class TestUnion : ICapnpSerializable { public const UInt64 typeId = 0xf47697362233ce52UL; @@ -1667,7 +1668,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xfc76a82eecb7a718UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfc76a82eecb7a718UL)] public class union0 : ICapnpSerializable { public const UInt64 typeId = 0xfc76a82eecb7a718UL; @@ -1992,13 +1993,13 @@ namespace Capnproto_test.Capnp.Test public short U0f0s16 => which == WHICH.U0f0s16 ? ctx.ReadDataShort(64UL, (short)0) : default; public int U0f0s32 => which == WHICH.U0f0s32 ? ctx.ReadDataInt(64UL, 0) : default; public long U0f0s64 => which == WHICH.U0f0s64 ? ctx.ReadDataLong(64UL, 0L) : default; - public string U0f0sp => which == WHICH.U0f0sp ? ctx.ReadText(0, "") : default; + public string U0f0sp => which == WHICH.U0f0sp ? ctx.ReadText(0, null) : default; public bool U0f1s1 => which == WHICH.U0f1s1 ? ctx.ReadDataBool(64UL, false) : default; public sbyte U0f1s8 => which == WHICH.U0f1s8 ? ctx.ReadDataSByte(64UL, (sbyte)0) : default; public short U0f1s16 => which == WHICH.U0f1s16 ? ctx.ReadDataShort(64UL, (short)0) : default; public int U0f1s32 => which == WHICH.U0f1s32 ? ctx.ReadDataInt(64UL, 0) : default; public long U0f1s64 => which == WHICH.U0f1s64 ? ctx.ReadDataLong(64UL, 0L) : default; - public string U0f1sp => which == WHICH.U0f1sp ? ctx.ReadText(0, "") : default; + public string U0f1sp => which == WHICH.U0f1sp ? ctx.ReadText(0, null) : default; } public class WRITER : SerializerState @@ -2045,8 +2046,8 @@ namespace Capnproto_test.Capnp.Test public string U0f0sp { - get => which == WHICH.U0f0sp ? this.ReadText(0, "") : default; - set => this.WriteText(0, value, ""); + get => which == WHICH.U0f0sp ? this.ReadText(0, null) : default; + set => this.WriteText(0, value, null); } public bool U0f1s1 @@ -2081,13 +2082,13 @@ namespace Capnproto_test.Capnp.Test public string U0f1sp { - get => which == WHICH.U0f1sp ? this.ReadText(0, "") : default; - set => this.WriteText(0, value, ""); + get => which == WHICH.U0f1sp ? this.ReadText(0, null) : default; + set => this.WriteText(0, value, null); } } } - [TypeId(0xee0a6b99b7dc7ab2UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xee0a6b99b7dc7ab2UL)] public class union1 : ICapnpSerializable { public const UInt64 typeId = 0xee0a6b99b7dc7ab2UL; @@ -2537,14 +2538,14 @@ namespace Capnproto_test.Capnp.Test public int U1f1s32 => which == WHICH.U1f1s32 ? ctx.ReadDataInt(160UL, 0) : default; public long U1f0s64 => which == WHICH.U1f0s64 ? ctx.ReadDataLong(192UL, 0L) : default; public long U1f1s64 => which == WHICH.U1f1s64 ? ctx.ReadDataLong(192UL, 0L) : default; - public string U1f0sp => which == WHICH.U1f0sp ? ctx.ReadText(1, "") : default; - public string U1f1sp => which == WHICH.U1f1sp ? ctx.ReadText(1, "") : default; + public string U1f0sp => which == WHICH.U1f0sp ? ctx.ReadText(1, null) : default; + public string U1f1sp => which == WHICH.U1f1sp ? ctx.ReadText(1, null) : default; public bool U1f2s1 => which == WHICH.U1f2s1 ? ctx.ReadDataBool(129UL, false) : default; public sbyte U1f2s8 => which == WHICH.U1f2s8 ? ctx.ReadDataSByte(136UL, (sbyte)0) : default; public short U1f2s16 => which == WHICH.U1f2s16 ? ctx.ReadDataShort(144UL, (short)0) : default; public int U1f2s32 => which == WHICH.U1f2s32 ? ctx.ReadDataInt(160UL, 0) : default; public long U1f2s64 => which == WHICH.U1f2s64 ? ctx.ReadDataLong(192UL, 0L) : default; - public string U1f2sp => which == WHICH.U1f2sp ? ctx.ReadText(1, "") : default; + public string U1f2sp => which == WHICH.U1f2sp ? ctx.ReadText(1, null) : default; } public class WRITER : SerializerState @@ -2621,14 +2622,14 @@ namespace Capnproto_test.Capnp.Test public string U1f0sp { - get => which == WHICH.U1f0sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f0sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public string U1f1sp { - get => which == WHICH.U1f1sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f1sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public bool U1f2s1 @@ -2663,13 +2664,13 @@ namespace Capnproto_test.Capnp.Test public string U1f2sp { - get => which == WHICH.U1f2sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f2sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } } } - [TypeId(0xafc5fd419f0d66d4UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xafc5fd419f0d66d4UL)] public class union2 : ICapnpSerializable { public const UInt64 typeId = 0xafc5fd419f0d66d4UL; @@ -2884,7 +2885,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa2fb022ec7f30053UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa2fb022ec7f30053UL)] public class union3 : ICapnpSerializable { public const UInt64 typeId = 0xa2fb022ec7f30053UL; @@ -3100,7 +3101,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9e2e784c915329b6UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9e2e784c915329b6UL)] public class TestUnnamedUnion : ICapnpSerializable { public const UInt64 typeId = 0x9e2e784c915329b6UL; @@ -3229,11 +3230,11 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(32U, (ushort)0); - public string Before => ctx.ReadText(0, ""); + public string Before => ctx.ReadText(0, null); public ushort Foo => which == WHICH.Foo ? ctx.ReadDataUShort(0UL, (ushort)0) : default; public ushort Middle => ctx.ReadDataUShort(16UL, (ushort)0); public uint Bar => which == WHICH.Bar ? ctx.ReadDataUInt(64UL, 0U) : default; - public string After => ctx.ReadText(1, ""); + public string After => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -3251,8 +3252,8 @@ namespace Capnproto_test.Capnp.Test public string Before { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ushort Foo @@ -3275,13 +3276,13 @@ namespace Capnproto_test.Capnp.Test public string After { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } - [TypeId(0x89a9494f1b900f22UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x89a9494f1b900f22UL)] public class TestUnionInUnion : ICapnpSerializable { public const UInt64 typeId = 0x89a9494f1b900f22UL; @@ -3339,7 +3340,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd005f6c63707670cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd005f6c63707670cUL)] public class outer : ICapnpSerializable { public const UInt64 typeId = 0xd005f6c63707670cUL; @@ -3471,7 +3472,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xff9ce111c6f8e5dbUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xff9ce111c6f8e5dbUL)] public class inner : ICapnpSerializable { public const UInt64 typeId = 0xff9ce111c6f8e5dbUL; @@ -3607,7 +3608,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdc841556134c3103UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdc841556134c3103UL)] public class TestGroups : ICapnpSerializable { public const UInt64 typeId = 0xdc841556134c3103UL; @@ -3665,7 +3666,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe22ae74ff9113268UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe22ae74ff9113268UL)] public class groups : ICapnpSerializable { public const UInt64 typeId = 0xe22ae74ff9113268UL; @@ -3822,7 +3823,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf5fcba89c0c1196fUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf5fcba89c0c1196fUL)] public class foo : ICapnpSerializable { public const UInt64 typeId = 0xf5fcba89c0c1196fUL; @@ -3882,7 +3883,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); public long Grault => ctx.ReadDataLong(64UL, 0L); - public string Garply => ctx.ReadText(0, ""); + public string Garply => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -3905,13 +3906,13 @@ namespace Capnproto_test.Capnp.Test public string Garply { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xf0fa30304066a4b3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf0fa30304066a4b3UL)] public class baz : ICapnpSerializable { public const UInt64 typeId = 0xf0fa30304066a4b3UL; @@ -3970,8 +3971,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); - public string Grault => ctx.ReadText(0, ""); - public string Garply => ctx.ReadText(1, ""); + public string Grault => ctx.ReadText(0, null); + public string Garply => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -3988,19 +3989,19 @@ namespace Capnproto_test.Capnp.Test public string Grault { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Garply { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } - [TypeId(0xb727c0d0091a001dUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb727c0d0091a001dUL)] public class bar : ICapnpSerializable { public const UInt64 typeId = 0xb727c0d0091a001dUL; @@ -4059,7 +4060,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); - public string Grault => ctx.ReadText(0, ""); + public string Grault => ctx.ReadText(0, null); public long Garply => ctx.ReadDataLong(64UL, 0L); } @@ -4077,8 +4078,8 @@ namespace Capnproto_test.Capnp.Test public string Grault { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public long Garply @@ -4091,7 +4092,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf77ed6f7454eec40UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf77ed6f7454eec40UL)] public class TestInterleavedGroups : ICapnpSerializable { public const UInt64 typeId = 0xf77ed6f7454eec40UL; @@ -4163,7 +4164,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc7485a3516c7d3c8UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc7485a3516c7d3c8UL)] public class group1 : ICapnpSerializable { public const UInt64 typeId = 0xc7485a3516c7d3c8UL; @@ -4316,8 +4317,8 @@ namespace Capnproto_test.Capnp.Test public ulong Bar => ctx.ReadDataULong(64UL, 0UL); public ushort Qux => which == WHICH.Qux ? ctx.ReadDataUShort(192UL, (ushort)0) : default; public corge.READER Corge => which == WHICH.Corge ? new corge.READER(ctx) : default; - public string Waldo => ctx.ReadText(0, ""); - public string Fred => which == WHICH.Fred ? ctx.ReadText(2, "") : default; + public string Waldo => ctx.ReadText(0, null); + public string Fred => which == WHICH.Fred ? ctx.ReadText(2, null) : default; } public class WRITER : SerializerState @@ -4357,18 +4358,18 @@ namespace Capnproto_test.Capnp.Test public string Waldo { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Fred { - get => which == WHICH.Fred ? this.ReadText(2, "") : default; - set => this.WriteText(2, value, ""); + get => which == WHICH.Fred ? this.ReadText(2, null) : default; + set => this.WriteText(2, value, null); } } - [TypeId(0xdb0afd413f4a313aUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdb0afd413f4a313aUL)] public class corge : ICapnpSerializable { public const UInt64 typeId = 0xdb0afd413f4a313aUL; @@ -4436,8 +4437,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong Grault => ctx.ReadDataULong(256UL, 0UL); public ushort Garply => ctx.ReadDataUShort(192UL, (ushort)0); - public string Plugh => ctx.ReadText(2, ""); - public string Xyzzy => ctx.ReadText(4, ""); + public string Plugh => ctx.ReadText(2, null); + public string Xyzzy => ctx.ReadText(4, null); } public class WRITER : SerializerState @@ -4460,20 +4461,20 @@ namespace Capnproto_test.Capnp.Test public string Plugh { - get => this.ReadText(2, ""); - set => this.WriteText(2, value, ""); + get => this.ReadText(2, null); + set => this.WriteText(2, value, null); } public string Xyzzy { - get => this.ReadText(4, ""); - set => this.WriteText(4, value, ""); + get => this.ReadText(4, null); + set => this.WriteText(4, value, null); } } } } - [TypeId(0xcc85a335569990e9UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xcc85a335569990e9UL)] public class group2 : ICapnpSerializable { public const UInt64 typeId = 0xcc85a335569990e9UL; @@ -4626,8 +4627,8 @@ namespace Capnproto_test.Capnp.Test public ulong Bar => ctx.ReadDataULong(128UL, 0UL); public ushort Qux => which == WHICH.Qux ? ctx.ReadDataUShort(208UL, (ushort)0) : default; public corge.READER Corge => which == WHICH.Corge ? new corge.READER(ctx) : default; - public string Waldo => ctx.ReadText(1, ""); - public string Fred => which == WHICH.Fred ? ctx.ReadText(3, "") : default; + public string Waldo => ctx.ReadText(1, null); + public string Fred => which == WHICH.Fred ? ctx.ReadText(3, null) : default; } public class WRITER : SerializerState @@ -4667,18 +4668,18 @@ namespace Capnproto_test.Capnp.Test public string Waldo { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } public string Fred { - get => which == WHICH.Fred ? this.ReadText(3, "") : default; - set => this.WriteText(3, value, ""); + get => which == WHICH.Fred ? this.ReadText(3, null) : default; + set => this.WriteText(3, value, null); } } - [TypeId(0xa017f0366827ee37UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa017f0366827ee37UL)] public class corge : ICapnpSerializable { public const UInt64 typeId = 0xa017f0366827ee37UL; @@ -4746,8 +4747,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong Grault => ctx.ReadDataULong(320UL, 0UL); public ushort Garply => ctx.ReadDataUShort(208UL, (ushort)0); - public string Plugh => ctx.ReadText(3, ""); - public string Xyzzy => ctx.ReadText(5, ""); + public string Plugh => ctx.ReadText(3, null); + public string Xyzzy => ctx.ReadText(5, null); } public class WRITER : SerializerState @@ -4770,21 +4771,21 @@ namespace Capnproto_test.Capnp.Test public string Plugh { - get => this.ReadText(3, ""); - set => this.WriteText(3, value, ""); + get => this.ReadText(3, null); + set => this.WriteText(3, value, null); } public string Xyzzy { - get => this.ReadText(5, ""); - set => this.WriteText(5, value, ""); + get => this.ReadText(5, null); + set => this.WriteText(5, value, null); } } } } } - [TypeId(0x94f7e0b103b4b718UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x94f7e0b103b4b718UL)] public class TestUnionDefaults : ICapnpSerializable { public const UInt64 typeId = 0x94f7e0b103b4b718UL; @@ -4905,7 +4906,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd9f2b5941a343bcdUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd9f2b5941a343bcdUL)] public class TestNestedTypes : ICapnpSerializable { public const UInt64 typeId = 0xd9f2b5941a343bcdUL; @@ -4996,14 +4997,14 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb651d2fba42056d4UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb651d2fba42056d4UL)] public enum NestedEnum : ushort { foo, bar } - [TypeId(0x82cd03a53b29d76bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x82cd03a53b29d76bUL)] public class NestedStruct : ICapnpSerializable { public const UInt64 typeId = 0x82cd03a53b29d76bUL; @@ -5079,7 +5080,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xcfa0d546993a3df3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xcfa0d546993a3df3UL)] public enum NestedEnum : ushort { baz, @@ -5089,7 +5090,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe78aac389e77b065UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe78aac389e77b065UL)] public class TestUsing : ICapnpSerializable { public const UInt64 typeId = 0xe78aac389e77b065UL; @@ -5166,7 +5167,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe41885c94393277eUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe41885c94393277eUL)] public class TestLists : ICapnpSerializable { public const UInt64 typeId = 0xe41885c94393277eUL; @@ -5360,7 +5361,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8412c03b75b2cfeeUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8412c03b75b2cfeeUL)] public class Struct0 : ICapnpSerializable { public const UInt64 typeId = 0x8412c03b75b2cfeeUL; @@ -5405,7 +5406,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe0fe5870b141ad69UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe0fe5870b141ad69UL)] public class Struct1 : ICapnpSerializable { public const UInt64 typeId = 0xe0fe5870b141ad69UL; @@ -5465,7 +5466,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa6411a353090145bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa6411a353090145bUL)] public class Struct8 : ICapnpSerializable { public const UInt64 typeId = 0xa6411a353090145bUL; @@ -5525,7 +5526,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa8abf7a82928986cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa8abf7a82928986cUL)] public class Struct16 : ICapnpSerializable { public const UInt64 typeId = 0xa8abf7a82928986cUL; @@ -5585,7 +5586,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xad7beedc4ed30742UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xad7beedc4ed30742UL)] public class Struct32 : ICapnpSerializable { public const UInt64 typeId = 0xad7beedc4ed30742UL; @@ -5645,7 +5646,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xef9a34f2ff7cc646UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xef9a34f2ff7cc646UL)] public class Struct64 : ICapnpSerializable { public const UInt64 typeId = 0xef9a34f2ff7cc646UL; @@ -5705,7 +5706,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc6abf1b0329e6227UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc6abf1b0329e6227UL)] public class StructP : ICapnpSerializable { public const UInt64 typeId = 0xc6abf1b0329e6227UL; @@ -5747,7 +5748,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string F => ctx.ReadText(0, ""); + public string F => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5759,13 +5760,13 @@ namespace Capnproto_test.Capnp.Test public string F { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0x943a234ca336b16aUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x943a234ca336b16aUL)] public class Struct0c : ICapnpSerializable { public const UInt64 typeId = 0x943a234ca336b16aUL; @@ -5807,7 +5808,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5819,13 +5820,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0x8991bc0e74a594cdUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8991bc0e74a594cdUL)] public class Struct1c : ICapnpSerializable { public const UInt64 typeId = 0x8991bc0e74a594cdUL; @@ -5876,7 +5877,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public bool F => ctx.ReadDataBool(0UL, false); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5894,13 +5895,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xed267416528c7a24UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xed267416528c7a24UL)] public class Struct8c : ICapnpSerializable { public const UInt64 typeId = 0xed267416528c7a24UL; @@ -5951,7 +5952,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public byte F => ctx.ReadDataByte(0UL, (byte)0); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5969,13 +5970,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0x9978837b037d58e6UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9978837b037d58e6UL)] public class Struct16c : ICapnpSerializable { public const UInt64 typeId = 0x9978837b037d58e6UL; @@ -6026,7 +6027,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ushort F => ctx.ReadDataUShort(0UL, (ushort)0); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6044,13 +6045,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xed5fa940f54a7904UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xed5fa940f54a7904UL)] public class Struct32c : ICapnpSerializable { public const UInt64 typeId = 0xed5fa940f54a7904UL; @@ -6101,7 +6102,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public uint F => ctx.ReadDataUInt(0UL, 0U); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6119,13 +6120,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xbc743778f2597c7dUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbc743778f2597c7dUL)] public class Struct64c : ICapnpSerializable { public const UInt64 typeId = 0xbc743778f2597c7dUL; @@ -6176,7 +6177,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong F => ctx.ReadDataULong(0UL, 0UL); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6194,13 +6195,13 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xc2e364a40182013dUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc2e364a40182013dUL)] public class StructPc : ICapnpSerializable { public const UInt64 typeId = 0xc2e364a40182013dUL; @@ -6250,7 +6251,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string F => ctx.ReadText(0, ""); + public string F => ctx.ReadText(0, null); public ulong Pad => ctx.ReadDataULong(0UL, 0UL); } @@ -6263,8 +6264,8 @@ namespace Capnproto_test.Capnp.Test public string F { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ulong Pad @@ -6276,7 +6277,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x92fc29a80f3ddd5cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x92fc29a80f3ddd5cUL)] public class TestFieldZeroIsBit : ICapnpSerializable { public const UInt64 typeId = 0x92fc29a80f3ddd5cUL; @@ -6368,7 +6369,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa851ad32cbc2ffeaUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa851ad32cbc2ffeaUL)] public class TestListDefaults : ICapnpSerializable { public const UInt64 typeId = 0xa851ad32cbc2ffeaUL; @@ -6452,7 +6453,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa76e3c9bb7fd56d3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa76e3c9bb7fd56d3UL)] public class TestLateUnion : ICapnpSerializable { public const UInt64 typeId = 0xa76e3c9bb7fd56d3UL; @@ -6527,7 +6528,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Foo => ctx.ReadDataInt(0UL, 0); - public string Bar => ctx.ReadText(0, ""); + public string Bar => ctx.ReadText(0, null); public short Baz => ctx.ReadDataShort(32UL, (short)0); public theUnion.READER TheUnion => new theUnion.READER(ctx); public anotherUnion.READER AnotherUnion => new anotherUnion.READER(ctx); @@ -6548,8 +6549,8 @@ namespace Capnproto_test.Capnp.Test public string Bar { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public short Baz @@ -6569,7 +6570,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x807280a2901aa079UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x807280a2901aa079UL)] public class theUnion : ICapnpSerializable { public const UInt64 typeId = 0x807280a2901aa079UL; @@ -6693,7 +6694,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(48U, (ushort)0); - public string Qux => which == WHICH.Qux ? ctx.ReadText(1, "") : default; + public string Qux => which == WHICH.Qux ? ctx.ReadText(1, null) : default; public IReadOnlyList Corge => which == WHICH.Corge ? ctx.ReadList(1).CastInt() : default; public float Grault => which == WHICH.Grault ? ctx.ReadDataFloat(64UL, 0F) : default; } @@ -6712,8 +6713,8 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => which == WHICH.Qux ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.Qux ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public ListOfPrimitivesSerializer Corge @@ -6730,7 +6731,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc1973984dee98e3aUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc1973984dee98e3aUL)] public class anotherUnion : ICapnpSerializable { public const UInt64 typeId = 0xc1973984dee98e3aUL; @@ -6854,7 +6855,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(96U, (ushort)0); - public string Qux => which == WHICH.Qux ? ctx.ReadText(2, "") : default; + public string Qux => which == WHICH.Qux ? ctx.ReadText(2, null) : default; public IReadOnlyList Corge => which == WHICH.Corge ? ctx.ReadList(2).CastInt() : default; public float Grault => which == WHICH.Grault ? ctx.ReadDataFloat(128UL, 0F) : default; } @@ -6873,8 +6874,8 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => which == WHICH.Qux ? this.ReadText(2, "") : default; - set => this.WriteText(2, value, ""); + get => which == WHICH.Qux ? this.ReadText(2, null) : default; + set => this.WriteText(2, value, null); } public ListOfPrimitivesSerializer Corge @@ -6892,7 +6893,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x95b30dd14e01dda8UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x95b30dd14e01dda8UL)] public class TestOldVersion : ICapnpSerializable { public const UInt64 typeId = 0x95b30dd14e01dda8UL; @@ -6951,7 +6952,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public long Old1 => ctx.ReadDataLong(0UL, 0L); - public string Old2 => ctx.ReadText(0, ""); + public string Old2 => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestOldVersion.READER Old3 => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestOldVersion.READER.create); } @@ -6970,8 +6971,8 @@ namespace Capnproto_test.Capnp.Test public string Old2 { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestOldVersion.WRITER Old3 @@ -6982,7 +6983,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8ed75a7469f04ce3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8ed75a7469f04ce3UL)] public class TestNewVersion : ICapnpSerializable { public const UInt64 typeId = 0x8ed75a7469f04ce3UL; @@ -7059,7 +7060,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public long Old1 => ctx.ReadDataLong(0UL, 0L); - public string Old2 => ctx.ReadText(0, ""); + public string Old2 => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestNewVersion.READER Old3 => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestNewVersion.READER.create); public long New1 => ctx.ReadDataLong(64UL, 987L); public string New2 => ctx.ReadText(2, "baz"); @@ -7080,8 +7081,8 @@ namespace Capnproto_test.Capnp.Test public string Old2 { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestNewVersion.WRITER Old3 @@ -7104,7 +7105,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xbd5fe16e5170c492UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbd5fe16e5170c492UL)] public class TestOldUnionVersion : ICapnpSerializable { public const UInt64 typeId = 0xbd5fe16e5170c492UL; @@ -7220,7 +7221,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc7e4c513a975492bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc7e4c513a975492bUL)] public class TestNewUnionVersion : ICapnpSerializable { public const UInt64 typeId = 0xc7e4c513a975492bUL; @@ -7353,7 +7354,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x86232c1de4513e84UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x86232c1de4513e84UL)] public class a : ICapnpSerializable { public const UInt64 typeId = 0x86232c1de4513e84UL; @@ -7469,7 +7470,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xfaf781ef89a00e39UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfaf781ef89a00e39UL)] public class TestStructUnion : ICapnpSerializable { public const UInt64 typeId = 0xfaf781ef89a00e39UL; @@ -7527,7 +7528,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x992edc677bef5a3cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x992edc677bef5a3cUL)] public class un : ICapnpSerializable { public const UInt64 typeId = 0x992edc677bef5a3cUL; @@ -7661,7 +7662,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9daec9823f171085UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9daec9823f171085UL)] public class SomeStruct : ICapnpSerializable { public const UInt64 typeId = 0x9daec9823f171085UL; @@ -7711,8 +7712,8 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string SomeText => ctx.ReadText(0, ""); - public string MoreText => ctx.ReadText(1, ""); + public string SomeText => ctx.ReadText(0, null); + public string MoreText => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -7724,20 +7725,20 @@ namespace Capnproto_test.Capnp.Test public string SomeText { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string MoreText { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } } - [TypeId(0xdec497819d097c3cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdec497819d097c3cUL)] public class TestPrintInlineStructs : ICapnpSerializable { public const UInt64 typeId = 0xdec497819d097c3cUL; @@ -7787,7 +7788,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string SomeText => ctx.ReadText(0, ""); + public string SomeText => ctx.ReadText(0, null); public IReadOnlyList StructList => ctx.ReadList(1).Cast(Capnproto_test.Capnp.Test.TestPrintInlineStructs.InlineStruct.READER.create); } @@ -7800,8 +7801,8 @@ namespace Capnproto_test.Capnp.Test public string SomeText { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ListOfStructsSerializer StructList @@ -7811,7 +7812,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8e4936003708dac2UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8e4936003708dac2UL)] public class InlineStruct : ICapnpSerializable { public const UInt64 typeId = 0x8e4936003708dac2UL; @@ -7862,7 +7863,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Int32Field => ctx.ReadDataInt(0UL, 0); - public string TextField => ctx.ReadText(0, ""); + public string TextField => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -7880,14 +7881,14 @@ namespace Capnproto_test.Capnp.Test public string TextField { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } } - [TypeId(0x91afd4a864dbb030UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x91afd4a864dbb030UL)] public class TestWholeFloatDefault : ICapnpSerializable { public const UInt64 typeId = 0x91afd4a864dbb030UL; @@ -7964,7 +7965,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9d5b8cd8de9922ebUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9d5b8cd8de9922ebUL)] public class TestGenerics : ICapnpSerializable where TFoo : class where TBar : class { public const UInt64 typeId = 0x9d5b8cd8de9922ebUL; @@ -8124,7 +8125,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb46a779beaf3384eUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb46a779beaf3384eUL)] public class ug : ICapnpSerializable { public const UInt64 typeId = 0xb46a779beaf3384eUL; @@ -8183,7 +8184,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf6a841117e19ac73UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf6a841117e19ac73UL)] public class Inner : ICapnpSerializable { public const UInt64 typeId = 0xf6a841117e19ac73UL; @@ -8258,7 +8259,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa9ab42b118d6d435UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9ab42b118d6d435UL)] public class Inner2 : ICapnpSerializable where TBaz : class { public const UInt64 typeId = 0xa9ab42b118d6d435UL; @@ -8362,7 +8363,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb6a0829c762b06f3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb6a0829c762b06f3UL)] public class DeepNest : ICapnpSerializable where TQux : class { public const UInt64 typeId = 0xb6a0829c762b06f3UL; @@ -8466,12 +8467,13 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8839ed86c9794287UL), Proxy(typeof(DeepNestInterface_Proxy<>)), Skeleton(typeof(DeepNestInterface_Skeleton<>))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8839ed86c9794287UL), Proxy(typeof(DeepNestInterface_Proxy<>)), Skeleton(typeof(DeepNestInterface_Skeleton<>))] public interface IDeepNestInterface : IDisposable where TQuux : class { Task Call(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8839ed86c9794287UL)] public class DeepNestInterface_Proxy : Proxy, IDeepNestInterface where TQuux : class { public async Task Call(CancellationToken cancellationToken_ = default) @@ -8480,12 +8482,15 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestGenerics.Inner2.DeepNest.DeepNestInterface.Params_Call() {}; arg_?.serialize(in_); - var d_ = await Call(9816138025992274567UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create.Inner2.DeepNest.DeepNestInterface.Result_Call>(d_); - return; + using (var d_ = await Call(9816138025992274567UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create.Inner2.DeepNest.DeepNestInterface.Result_Call>(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8839ed86c9794287UL)] public class DeepNestInterface_Skeleton : Skeleton> where TQuux : class { public DeepNestInterface_Skeleton() @@ -8496,16 +8501,19 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 9816138025992274567UL; async Task Call(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Call(cancellationToken_); - var s_ = SerializerState.CreateForRpc.Inner2.DeepNest.DeepNestInterface.Result_Call.WRITER>(); - return s_; + using (d_) + { + await Impl.Call(cancellationToken_); + var s_ = SerializerState.CreateForRpc.Inner2.DeepNest.DeepNestInterface.Result_Call.WRITER>(); + return s_; + } } } public static class DeepNestInterface where TQuux : class { - [TypeId(0xb84eecc799437049UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb84eecc799437049UL)] public class Params_Call : ICapnpSerializable { public const UInt64 typeId = 0xb84eecc799437049UL; @@ -8550,7 +8558,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe080f0fc54614f6fUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe080f0fc54614f6fUL)] public class Result_Call : ICapnpSerializable { public const UInt64 typeId = 0xe080f0fc54614f6fUL; @@ -8598,12 +8606,13 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc9e749e8dd54da5cUL), Proxy(typeof(Interface_Proxy<>)), Skeleton(typeof(Interface_Skeleton<>))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc9e749e8dd54da5cUL), Proxy(typeof(Interface_Proxy<>)), Skeleton(typeof(Interface_Skeleton<>))] public interface IInterface : IDisposable where TQux : class { Task<(TQux, Capnproto_test.Capnp.Test.TestGenerics)> Call(Capnproto_test.Capnp.Test.TestGenerics.Inner2 arg_, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc9e749e8dd54da5cUL)] public class Interface_Proxy : Proxy, IInterface where TQux : class { public Task<(TQux, Capnproto_test.Capnp.Test.TestGenerics)> Call(Capnproto_test.Capnp.Test.TestGenerics.Inner2 arg_, CancellationToken cancellationToken_ = default) @@ -8612,14 +8621,18 @@ namespace Capnproto_test.Capnp.Test arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(14548678385738242652UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create.Interface.Result_Call>(d_); - return (r_.Qux, r_.Gen); + using (d_) + { + var r_ = CapnpSerializable.Create.Interface.Result_Call>(d_); + return (r_.Qux, r_.Gen); + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc9e749e8dd54da5cUL)] public class Interface_Skeleton : Skeleton> where TQux : class { public Interface_Skeleton() @@ -8630,22 +8643,25 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 14548678385738242652UL; Task Call(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.Call(CapnpSerializable.Create.Inner2>(d_), cancellationToken_), (qux, gen) => + using (d_) { - var s_ = SerializerState.CreateForRpc.Interface.Result_Call.WRITER>(); - var r_ = new Capnproto_test.Capnp.Test.TestGenerics.Interface.Result_Call{Qux = qux, Gen = gen}; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.Call(CapnpSerializable.Create.Inner2>(d_), cancellationToken_), (qux, gen) => + { + var s_ = SerializerState.CreateForRpc.Interface.Result_Call.WRITER>(); + var r_ = new Capnproto_test.Capnp.Test.TestGenerics.Interface.Result_Call{Qux = qux, Gen = gen}; + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class Interface where TQux : class { - [TypeId(0xa5b46224e33581adUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa5b46224e33581adUL)] public class Result_Call : ICapnpSerializable { public const UInt64 typeId = 0xa5b46224e33581adUL; @@ -8721,7 +8737,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8e656edfb45ba6cfUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8e656edfb45ba6cfUL)] public class UseAliases : ICapnpSerializable { public const UInt64 typeId = 0x8e656edfb45ba6cfUL; @@ -8857,7 +8873,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa9b2b1f52dde845dUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9b2b1f52dde845dUL)] public class TestGenericsWrapper : ICapnpSerializable where TFoo : class where TBar : class { public const UInt64 typeId = 0xa9b2b1f52dde845dUL; @@ -8917,7 +8933,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf28f83667a557a04UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf28f83667a557a04UL)] public class TestGenericsWrapper2 : ICapnpSerializable { public const UInt64 typeId = 0xf28f83667a557a04UL; @@ -8977,32 +8993,37 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8b9717a3f8d85a9aUL), Proxy(typeof(TestImplicitMethodParams_Proxy)), Skeleton(typeof(TestImplicitMethodParams_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8b9717a3f8d85a9aUL), Proxy(typeof(TestImplicitMethodParams_Proxy)), Skeleton(typeof(TestImplicitMethodParams_Skeleton))] public interface ITestImplicitMethodParams : IDisposable { - Task> Call(TT Foo, TU Bar, CancellationToken cancellationToken_ = default) + Task> Call(TT foo, TU bar, CancellationToken cancellationToken_ = default) where TT : class where TU : class; } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8b9717a3f8d85a9aUL)] public class TestImplicitMethodParams_Proxy : Proxy, ITestImplicitMethodParams { - public Task> Call(TT Foo, TU Bar, CancellationToken cancellationToken_ = default) + public Task> Call(TT foo, TU bar, CancellationToken cancellationToken_ = default) where TT : class where TU : class { var in_ = SerializerState.CreateForRpc.WRITER>(); var arg_ = new Capnproto_test.Capnp.Test.TestImplicitMethodParams.Params_Call() - {Foo = Foo, Bar = Bar}; + {Foo = foo, Bar = bar}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(10058534285777328794UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create>(d_); - return r_; + using (d_) + { + var r_ = CapnpSerializable.Create>(d_); + return r_; + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8b9717a3f8d85a9aUL)] public class TestImplicitMethodParams_Skeleton : Skeleton { public TestImplicitMethodParams_Skeleton() @@ -9014,21 +9035,24 @@ namespace Capnproto_test.Capnp.Test Task Call(DeserializerState d_, CancellationToken cancellationToken_) where TT : class where TU : class { - var in_ = CapnpSerializable.Create>(d_); - return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc.WRITER>(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create>(d_); + return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc.WRITER>(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestImplicitMethodParams { - [TypeId(0xf83f8caf54bdc486UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf83f8caf54bdc486UL)] public class Params_Call : ICapnpSerializable where TT : class where TU : class { public const UInt64 typeId = 0xf83f8caf54bdc486UL; @@ -9104,32 +9128,37 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdf9ccdeb81a704c9UL), Proxy(typeof(TestImplicitMethodParamsInGeneric_Proxy<>)), Skeleton(typeof(TestImplicitMethodParamsInGeneric_Skeleton<>))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdf9ccdeb81a704c9UL), Proxy(typeof(TestImplicitMethodParamsInGeneric_Proxy<>)), Skeleton(typeof(TestImplicitMethodParamsInGeneric_Skeleton<>))] public interface ITestImplicitMethodParamsInGeneric : IDisposable where TV : class { - Task> Call(TT Foo, TU Bar, CancellationToken cancellationToken_ = default) + Task> Call(TT foo, TU bar, CancellationToken cancellationToken_ = default) where TT : class where TU : class; } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdf9ccdeb81a704c9UL)] public class TestImplicitMethodParamsInGeneric_Proxy : Proxy, ITestImplicitMethodParamsInGeneric where TV : class { - public Task> Call(TT Foo, TU Bar, CancellationToken cancellationToken_ = default) + public Task> Call(TT foo, TU bar, CancellationToken cancellationToken_ = default) where TT : class where TU : class { var in_ = SerializerState.CreateForRpc.Params_Call.WRITER>(); var arg_ = new Capnproto_test.Capnp.Test.TestImplicitMethodParamsInGeneric.Params_Call() - {Foo = Foo, Bar = Bar}; + {Foo = foo, Bar = bar}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(16112979978201007305UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create>(d_); - return r_; + using (d_) + { + var r_ = CapnpSerializable.Create>(d_); + return r_; + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdf9ccdeb81a704c9UL)] public class TestImplicitMethodParamsInGeneric_Skeleton : Skeleton> where TV : class { public TestImplicitMethodParamsInGeneric_Skeleton() @@ -9141,22 +9170,25 @@ namespace Capnproto_test.Capnp.Test Task Call(DeserializerState d_, CancellationToken cancellationToken_) where TT : class where TU : class { - var in_ = CapnpSerializable.Create.Params_Call>(d_); - return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc.WRITER>(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create.Params_Call>(d_); + return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc.WRITER>(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestImplicitMethodParamsInGeneric where TV : class { - [TypeId(0x9aab8e25c808d71eUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9aab8e25c808d71eUL)] public class Params_Call : ICapnpSerializable where TT : class where TU : class { public const UInt64 typeId = 0x9aab8e25c808d71eUL; @@ -9232,7 +9264,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa54870440e919063UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa54870440e919063UL)] public class TestGenericsUnion : ICapnpSerializable where TFoo : class where TBar : class { public const UInt64 typeId = 0xa54870440e919063UL; @@ -9367,7 +9399,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9427b2a71030338fUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9427b2a71030338fUL)] public class TestUseGenerics : ICapnpSerializable { public const UInt64 typeId = 0x9427b2a71030338fUL; @@ -9818,7 +9850,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc5598844441096dcUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc5598844441096dcUL)] public class TestEmptyStruct : ICapnpSerializable { public const UInt64 typeId = 0xc5598844441096dcUL; @@ -9863,7 +9895,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xabed745cd8c92095UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xabed745cd8c92095UL)] public class TestConstants : ICapnpSerializable { public const UInt64 typeId = 0xabed745cd8c92095UL; @@ -9908,7 +9940,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xddc280dbee9c99b3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddc280dbee9c99b3UL)] public class TestAnyPointerConstants : ICapnpSerializable { public const UInt64 typeId = 0xddc280dbee9c99b3UL; @@ -10013,25 +10045,28 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x88eb12a0e0af92b2UL), Proxy(typeof(TestInterface_Proxy)), Skeleton(typeof(TestInterface_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x88eb12a0e0af92b2UL), Proxy(typeof(TestInterface_Proxy)), Skeleton(typeof(TestInterface_Skeleton))] public interface ITestInterface : IDisposable { - Task Foo(uint I, bool J, CancellationToken cancellationToken_ = default); + Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default); Task Bar(CancellationToken cancellationToken_ = default); - Task Baz(Capnproto_test.Capnp.Test.TestAllTypes S, CancellationToken cancellationToken_ = default); + Task Baz(Capnproto_test.Capnp.Test.TestAllTypes s, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x88eb12a0e0af92b2UL)] public class TestInterface_Proxy : Proxy, ITestInterface { - public async Task Foo(uint I, bool J, CancellationToken cancellationToken_ = default) + public async Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Foo() - {I = I, J = J}; + {I = i, J = j}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.X); + using (var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.X); + } } public async Task Bar(CancellationToken cancellationToken_ = default) @@ -10040,23 +10075,28 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Bar() {}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } - public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes S, CancellationToken cancellationToken_ = default) + public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes s, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Baz() - {S = S}; + {S = s}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x88eb12a0e0af92b2UL)] public class TestInterface_Skeleton : Skeleton { public TestInterface_Skeleton() @@ -10067,37 +10107,46 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 9865999890858873522UL; Task Foo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.J, cancellationToken_), x => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestInterface.Result_Foo{X = x}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.J, cancellationToken_), x => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestInterface.Result_Foo{X = x}; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task Bar(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Bar(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Bar(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Baz(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.Baz(in_.S, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.Baz(in_.S, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestInterface { - [TypeId(0xb874edc0d559b391UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb874edc0d559b391UL)] public class Params_Foo : ICapnpSerializable { public const UInt64 typeId = 0xb874edc0d559b391UL; @@ -10172,7 +10221,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb04fcaddab714ba4UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb04fcaddab714ba4UL)] public class Result_Foo : ICapnpSerializable { public const UInt64 typeId = 0xb04fcaddab714ba4UL; @@ -10214,7 +10263,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string X => ctx.ReadText(0, ""); + public string X => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -10226,13 +10275,13 @@ namespace Capnproto_test.Capnp.Test public string X { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xd044893357b42568UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd044893357b42568UL)] public class Params_Bar : ICapnpSerializable { public const UInt64 typeId = 0xd044893357b42568UL; @@ -10277,7 +10326,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9bf141df4247d52fUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9bf141df4247d52fUL)] public class Result_Bar : ICapnpSerializable { public const UInt64 typeId = 0x9bf141df4247d52fUL; @@ -10322,7 +10371,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd9ac8abb2a91cfbcUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd9ac8abb2a91cfbcUL)] public class Params_Baz : ICapnpSerializable { public const UInt64 typeId = 0xd9ac8abb2a91cfbcUL; @@ -10382,7 +10431,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9b99d14f2f375b2dUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9b99d14f2f375b2dUL)] public class Result_Baz : ICapnpSerializable { public const UInt64 typeId = 0x9b99d14f2f375b2dUL; @@ -10428,7 +10477,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe4e9bac98670b748UL), Proxy(typeof(TestExtends_Proxy)), Skeleton(typeof(TestExtends_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe4e9bac98670b748UL), Proxy(typeof(TestExtends_Proxy)), Skeleton(typeof(TestExtends_Skeleton))] public interface ITestExtends : Capnproto_test.Capnp.Test.ITestInterface { Task Qux(CancellationToken cancellationToken_ = default); @@ -10436,6 +10485,7 @@ namespace Capnproto_test.Capnp.Test Task Grault(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe4e9bac98670b748UL)] public class TestExtends_Proxy : Proxy, ITestExtends { public async Task Qux(CancellationToken cancellationToken_ = default) @@ -10444,18 +10494,22 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_Qux() {}; arg_?.serialize(in_); - var d_ = await Call(16494920484927878984UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(16494920484927878984UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Corge(Capnproto_test.Capnp.Test.TestAllTypes arg_, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); arg_?.serialize(in_); - var d_ = await Call(16494920484927878984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(16494920484927878984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Grault(CancellationToken cancellationToken_ = default) @@ -10464,20 +10518,24 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_Grault() {}; arg_?.serialize(in_); - var d_ = await Call(16494920484927878984UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + using (var d_ = await Call(16494920484927878984UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } - public async Task Foo(uint I, bool J, CancellationToken cancellationToken_ = default) + public async Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Foo() - {I = I, J = J}; + {I = i, J = j}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.X); + using (var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.X); + } } public async Task Bar(CancellationToken cancellationToken_ = default) @@ -10486,23 +10544,28 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Bar() {}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } - public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes S, CancellationToken cancellationToken_ = default) + public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes s, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Baz() - {S = S}; + {S = s}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe4e9bac98670b748UL)] public class TestExtends_Skeleton : Skeleton { public TestExtends_Skeleton() @@ -10513,34 +10576,43 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 16494920484927878984UL; async Task Qux(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Qux(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Qux(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Corge(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Corge(CapnpSerializable.Create(d_), cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Corge(CapnpSerializable.Create(d_), cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } Task Grault(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.Grault(cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.Grault(cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestExtends { - [TypeId(0x83a4bc5471363f17UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x83a4bc5471363f17UL)] public class Params_Qux : ICapnpSerializable { public const UInt64 typeId = 0x83a4bc5471363f17UL; @@ -10585,7 +10657,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8e4b3d1a3e2753ddUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8e4b3d1a3e2753ddUL)] public class Result_Qux : ICapnpSerializable { public const UInt64 typeId = 0x8e4b3d1a3e2753ddUL; @@ -10630,7 +10702,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xacf67532a7e7bad9UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xacf67532a7e7bad9UL)] public class Result_Corge : ICapnpSerializable { public const UInt64 typeId = 0xacf67532a7e7bad9UL; @@ -10675,7 +10747,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf3b834e851ea8af6UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf3b834e851ea8af6UL)] public class Params_Grault : ICapnpSerializable { public const UInt64 typeId = 0xf3b834e851ea8af6UL; @@ -10721,11 +10793,12 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x98d7e0ef61488783UL), Proxy(typeof(TestExtends2_Proxy)), Skeleton(typeof(TestExtends2_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x98d7e0ef61488783UL), Proxy(typeof(TestExtends2_Proxy)), Skeleton(typeof(TestExtends2_Skeleton))] public interface ITestExtends2 : Capnproto_test.Capnp.Test.ITestExtends { } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x98d7e0ef61488783UL)] public class TestExtends2_Proxy : Proxy, ITestExtends2 { public async Task Qux(CancellationToken cancellationToken_ = default) @@ -10734,18 +10807,22 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_Qux() {}; arg_?.serialize(in_); - var d_ = await Call(16494920484927878984UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(16494920484927878984UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Corge(Capnproto_test.Capnp.Test.TestAllTypes arg_, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); arg_?.serialize(in_); - var d_ = await Call(16494920484927878984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(16494920484927878984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Grault(CancellationToken cancellationToken_ = default) @@ -10754,20 +10831,24 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestExtends.Params_Grault() {}; arg_?.serialize(in_); - var d_ = await Call(16494920484927878984UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + using (var d_ = await Call(16494920484927878984UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } - public async Task Foo(uint I, bool J, CancellationToken cancellationToken_ = default) + public async Task Foo(uint i, bool j, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Foo() - {I = I, J = J}; + {I = i, J = j}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.X); + using (var d_ = await Call(9865999890858873522UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.X); + } } public async Task Bar(CancellationToken cancellationToken_ = default) @@ -10776,23 +10857,28 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Bar() {}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(9865999890858873522UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } - public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes S, CancellationToken cancellationToken_ = default) + public async Task Baz(Capnproto_test.Capnp.Test.TestAllTypes s, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestInterface.Params_Baz() - {S = S}; + {S = s}; arg_?.serialize(in_); - var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(9865999890858873522UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x98d7e0ef61488783UL)] public class TestExtends2_Skeleton : Skeleton { public TestExtends2_Skeleton() @@ -10803,58 +10889,68 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11013518732491786115UL; } - [TypeId(0xa5a404caa61d4cd0UL), Proxy(typeof(TestPipeline_Proxy)), Skeleton(typeof(TestPipeline_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa5a404caa61d4cd0UL), Proxy(typeof(TestPipeline_Proxy)), Skeleton(typeof(TestPipeline_Skeleton))] public interface ITestPipeline : IDisposable { - Task<(string, Capnproto_test.Capnp.Test.TestPipeline.Box)> GetCap(uint N, Capnproto_test.Capnp.Test.ITestInterface InCap, CancellationToken cancellationToken_ = default); - Task TestPointers(Capnproto_test.Capnp.Test.ITestInterface Cap, object Obj, IReadOnlyList List, CancellationToken cancellationToken_ = default); - Task<(string, Capnproto_test.Capnp.Test.TestPipeline.AnyBox)> GetAnyCap(uint N, BareProxy InCap, CancellationToken cancellationToken_ = default); + Task<(string, Capnproto_test.Capnp.Test.TestPipeline.Box)> GetCap(uint n, Capnproto_test.Capnp.Test.ITestInterface inCap, CancellationToken cancellationToken_ = default); + Task TestPointers(Capnproto_test.Capnp.Test.ITestInterface cap, object obj, IReadOnlyList list, CancellationToken cancellationToken_ = default); + Task<(string, Capnproto_test.Capnp.Test.TestPipeline.AnyBox)> GetAnyCap(uint n, BareProxy inCap, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa5a404caa61d4cd0UL)] public class TestPipeline_Proxy : Proxy, ITestPipeline { - public Task<(string, Capnproto_test.Capnp.Test.TestPipeline.Box)> GetCap(uint N, Capnproto_test.Capnp.Test.ITestInterface InCap, CancellationToken cancellationToken_ = default) + public Task<(string, Capnproto_test.Capnp.Test.TestPipeline.Box)> GetCap(uint n, Capnproto_test.Capnp.Test.ITestInterface inCap, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_GetCap() - {N = N, InCap = InCap}; + {N = n, InCap = inCap}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(11935670180855499984UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.S, r_.OutBox); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S, r_.OutBox); + } } ); } - public async Task TestPointers(Capnproto_test.Capnp.Test.ITestInterface Cap, object Obj, IReadOnlyList List, CancellationToken cancellationToken_ = default) + public async Task TestPointers(Capnproto_test.Capnp.Test.ITestInterface cap, object obj, IReadOnlyList list, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_TestPointers() - {Cap = Cap, Obj = Obj, List = List}; + {Cap = cap, Obj = obj, List = list}; arg_?.serialize(in_); - var d_ = await Call(11935670180855499984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(11935670180855499984UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } - public Task<(string, Capnproto_test.Capnp.Test.TestPipeline.AnyBox)> GetAnyCap(uint N, BareProxy InCap, CancellationToken cancellationToken_ = default) + public Task<(string, Capnproto_test.Capnp.Test.TestPipeline.AnyBox)> GetAnyCap(uint n, BareProxy inCap, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestPipeline.Params_GetAnyCap() - {N = N, InCap = InCap}; + {N = n, InCap = inCap}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(11935670180855499984UL, 2, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.S, r_.OutBox); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S, r_.OutBox); + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa5a404caa61d4cd0UL)] public class TestPipeline_Skeleton : Skeleton { public TestPipeline_Skeleton() @@ -10865,44 +10961,53 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11935670180855499984UL; Task GetCap(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.GetCap(in_.N, in_.InCap, cancellationToken_), (s, outBox) => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestPipeline.Result_GetCap{S = s, OutBox = outBox}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.GetCap(in_.N, in_.InCap, cancellationToken_), (s, outBox) => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestPipeline.Result_GetCap{S = s, OutBox = outBox}; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task TestPointers(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.TestPointers(in_.Cap, in_.Obj, in_.List, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.TestPointers(in_.Cap, in_.Obj, in_.List, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } Task GetAnyCap(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.GetAnyCap(in_.N, in_.InCap, cancellationToken_), (s, outBox) => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestPipeline.Result_GetAnyCap{S = s, OutBox = outBox}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.GetAnyCap(in_.N, in_.InCap, cancellationToken_), (s, outBox) => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestPipeline.Result_GetAnyCap{S = s, OutBox = outBox}; + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestPipeline { - [TypeId(0xb0b29e51db0e26b1UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb0b29e51db0e26b1UL)] public class Box : ICapnpSerializable { public const UInt64 typeId = 0xb0b29e51db0e26b1UL; @@ -10962,7 +11067,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9442ad5a1d2c8acbUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9442ad5a1d2c8acbUL)] public class AnyBox : ICapnpSerializable { public const UInt64 typeId = 0x9442ad5a1d2c8acbUL; @@ -11022,7 +11127,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc7e8df5096257034UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc7e8df5096257034UL)] public class Params_GetCap : ICapnpSerializable { public const UInt64 typeId = 0xc7e8df5096257034UL; @@ -11097,7 +11202,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb2442a9e0ba28fdfUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb2442a9e0ba28fdfUL)] public class Result_GetCap : ICapnpSerializable { public const UInt64 typeId = 0xb2442a9e0ba28fdfUL; @@ -11147,7 +11252,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestPipeline.Box.READER OutBox => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestPipeline.Box.READER.create); } @@ -11160,8 +11265,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestPipeline.Box.WRITER OutBox @@ -11172,7 +11277,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa604ee63cf37819fUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa604ee63cf37819fUL)] public class Params_TestPointers : ICapnpSerializable { public const UInt64 typeId = 0xa604ee63cf37819fUL; @@ -11262,7 +11367,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8eda54756c6070d6UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8eda54756c6070d6UL)] public class Result_TestPointers : ICapnpSerializable { public const UInt64 typeId = 0x8eda54756c6070d6UL; @@ -11307,7 +11412,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf8e36b53ab093d4eUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf8e36b53ab093d4eUL)] public class Params_GetAnyCap : ICapnpSerializable { public const UInt64 typeId = 0xf8e36b53ab093d4eUL; @@ -11382,7 +11487,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xbf44b4c94c26ef79UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbf44b4c94c26ef79UL)] public class Result_GetAnyCap : ICapnpSerializable { public const UInt64 typeId = 0xbf44b4c94c26ef79UL; @@ -11432,7 +11537,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestPipeline.AnyBox.READER OutBox => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestPipeline.AnyBox.READER.create); } @@ -11445,8 +11550,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestPipeline.AnyBox.WRITER OutBox @@ -11458,26 +11563,30 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa0e77035bdff0051UL), Proxy(typeof(TestCallOrder_Proxy)), Skeleton(typeof(TestCallOrder_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa0e77035bdff0051UL), Proxy(typeof(TestCallOrder_Proxy)), Skeleton(typeof(TestCallOrder_Skeleton))] public interface ITestCallOrder : IDisposable { - Task GetCallSequence(uint Expected, CancellationToken cancellationToken_ = default); + Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa0e77035bdff0051UL)] public class TestCallOrder_Proxy : Proxy, ITestCallOrder { - public async Task GetCallSequence(uint Expected, CancellationToken cancellationToken_ = default) + public async Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestCallOrder.Params_GetCallSequence() - {Expected = Expected}; + {Expected = expected}; arg_?.serialize(in_); - var d_ = await Call(11594359141811814481UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.N); + using (var d_ = await Call(11594359141811814481UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.N); + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa0e77035bdff0051UL)] public class TestCallOrder_Skeleton : Skeleton { public TestCallOrder_Skeleton() @@ -11488,22 +11597,25 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11594359141811814481UL; Task GetCallSequence(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.GetCallSequence(in_.Expected, cancellationToken_), n => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestCallOrder.Result_GetCallSequence{N = n}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.GetCallSequence(in_.Expected, cancellationToken_), n => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestCallOrder.Result_GetCallSequence{N = n}; + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestCallOrder { - [TypeId(0x8f1e8cd56ceb74dcUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8f1e8cd56ceb74dcUL)] public class Params_GetCallSequence : ICapnpSerializable { public const UInt64 typeId = 0x8f1e8cd56ceb74dcUL; @@ -11563,7 +11675,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdedbb6bf3810eab7UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdedbb6bf3810eab7UL)] public class Result_GetCallSequence : ICapnpSerializable { public const UInt64 typeId = 0xdedbb6bf3810eab7UL; @@ -11624,30 +11736,35 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xddd699207eb8e23bUL), Proxy(typeof(TestTailCallee_Proxy)), Skeleton(typeof(TestTailCallee_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddd699207eb8e23bUL), Proxy(typeof(TestTailCallee_Proxy)), Skeleton(typeof(TestTailCallee_Skeleton))] public interface ITestTailCallee : IDisposable { - Task Foo(int I, string T, CancellationToken cancellationToken_ = default); + Task Foo(int i, string t, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddd699207eb8e23bUL)] public class TestTailCallee_Proxy : Proxy, ITestTailCallee { - public Task Foo(int I, string T, CancellationToken cancellationToken_ = default) + public Task Foo(int i, string t, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestTailCallee.Params_Foo() - {I = I, T = T}; + {I = i, T = t}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15985132292242203195UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return r_; + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddd699207eb8e23bUL)] public class TestTailCallee_Skeleton : Skeleton { public TestTailCallee_Skeleton() @@ -11658,21 +11775,24 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 15985132292242203195UL; Task Foo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.T, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.T, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestTailCallee { - [TypeId(0xa9ed2e5a9fd53d19UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9ed2e5a9fd53d19UL)] public class TailResult : ICapnpSerializable { public const UInt64 typeId = 0xa9ed2e5a9fd53d19UL; @@ -11731,7 +11851,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public uint I => ctx.ReadDataUInt(0UL, 0U); - public string T => ctx.ReadText(0, ""); + public string T => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestCallOrder C => ctx.ReadCap(1); } @@ -11750,8 +11870,8 @@ namespace Capnproto_test.Capnp.Test public string T { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestCallOrder C @@ -11762,7 +11882,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc5e1efc325614957UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc5e1efc325614957UL)] public class Params_Foo : ICapnpSerializable { public const UInt64 typeId = 0xc5e1efc325614957UL; @@ -11813,7 +11933,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int I => ctx.ReadDataInt(0UL, 0); - public string T => ctx.ReadText(0, ""); + public string T => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -11831,37 +11951,42 @@ namespace Capnproto_test.Capnp.Test public string T { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } } - [TypeId(0x870bf40110ce3035UL), Proxy(typeof(TestTailCaller_Proxy)), Skeleton(typeof(TestTailCaller_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x870bf40110ce3035UL), Proxy(typeof(TestTailCaller_Proxy)), Skeleton(typeof(TestTailCaller_Skeleton))] public interface ITestTailCaller : IDisposable { - Task Foo(int I, Capnproto_test.Capnp.Test.ITestTailCallee Callee, CancellationToken cancellationToken_ = default); + Task Foo(int i, Capnproto_test.Capnp.Test.ITestTailCallee callee, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x870bf40110ce3035UL)] public class TestTailCaller_Proxy : Proxy, ITestTailCaller { - public Task Foo(int I, Capnproto_test.Capnp.Test.ITestTailCallee Callee, CancellationToken cancellationToken_ = default) + public Task Foo(int i, Capnproto_test.Capnp.Test.ITestTailCallee callee, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestTailCaller.Params_Foo() - {I = I, Callee = Callee}; + {I = i, Callee = callee}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(9731139705278181429UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return r_; + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x870bf40110ce3035UL)] public class TestTailCaller_Skeleton : Skeleton { public TestTailCaller_Skeleton() @@ -11872,21 +11997,24 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 9731139705278181429UL; Task Foo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.Callee, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Foo(in_.I, in_.Callee, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestTailCaller { - [TypeId(0xb07a279515dc8ac5UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb07a279515dc8ac5UL)] public class Params_Foo : ICapnpSerializable { public const UInt64 typeId = 0xb07a279515dc8ac5UL; @@ -11962,15 +12090,17 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa38e5efe41e53a15UL), Proxy(typeof(TestHandle_Proxy)), Skeleton(typeof(TestHandle_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa38e5efe41e53a15UL), Proxy(typeof(TestHandle_Proxy)), Skeleton(typeof(TestHandle_Skeleton))] public interface ITestHandle : IDisposable { } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa38e5efe41e53a15UL)] public class TestHandle_Proxy : Proxy, ITestHandle { } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa38e5efe41e53a15UL)] public class TestHandle_Skeleton : Skeleton { public TestHandle_Skeleton() @@ -11981,72 +12111,82 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11785461720995412501UL; } - [TypeId(0xddc70bf9784133cfUL), Proxy(typeof(TestMoreStuff_Proxy)), Skeleton(typeof(TestMoreStuff_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddc70bf9784133cfUL), Proxy(typeof(TestMoreStuff_Proxy)), Skeleton(typeof(TestMoreStuff_Skeleton))] public interface ITestMoreStuff : Capnproto_test.Capnp.Test.ITestCallOrder { - Task CallFoo(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default); - Task CallFooWhenResolved(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default); - Task NeverReturn(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default); - Task Hold(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default); + Task CallFoo(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default); + Task CallFooWhenResolved(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default); + Task NeverReturn(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default); + Task Hold(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default); Task CallHeld(CancellationToken cancellationToken_ = default); Task GetHeld(CancellationToken cancellationToken_ = default); - Task Echo(Capnproto_test.Capnp.Test.ITestCallOrder Cap, CancellationToken cancellationToken_ = default); - Task ExpectCancel(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default); - Task<(string, string)> MethodWithDefaults(string A, uint B, string C, CancellationToken cancellationToken_ = default); + Task Echo(Capnproto_test.Capnp.Test.ITestCallOrder cap, CancellationToken cancellationToken_ = default); + Task ExpectCancel(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default); + Task<(string, string)> MethodWithDefaults(string a, uint b, string c, CancellationToken cancellationToken_ = default); Task GetHandle(CancellationToken cancellationToken_ = default); Task GetNull(CancellationToken cancellationToken_ = default); Task GetEnormousString(CancellationToken cancellationToken_ = default); - Task MethodWithNullDefault(string A, Capnproto_test.Capnp.Test.ITestInterface B, CancellationToken cancellationToken_ = default); + Task MethodWithNullDefault(string a, Capnproto_test.Capnp.Test.ITestInterface b, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddc70bf9784133cfUL)] public class TestMoreStuff_Proxy : Proxy, ITestMoreStuff { - public async Task CallFoo(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default) + public async Task CallFoo(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_CallFoo() - {Cap = Cap}; + {Cap = cap}; arg_?.serialize(in_); - var d_ = await Call(15980754968839795663UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.S); + using (var d_ = await Call(15980754968839795663UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S); + } } - public async Task CallFooWhenResolved(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default) + public async Task CallFooWhenResolved(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_CallFooWhenResolved() - {Cap = Cap}; + {Cap = cap}; arg_?.serialize(in_); - var d_ = await Call(15980754968839795663UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.S); + using (var d_ = await Call(15980754968839795663UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S); + } } - public Task NeverReturn(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default) + public Task NeverReturn(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_NeverReturn() - {Cap = Cap}; + {Cap = cap}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 2, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.CapCopy); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.CapCopy); + } } ); } - public async Task Hold(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default) + public async Task Hold(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_Hold() - {Cap = Cap}; + {Cap = cap}; arg_?.serialize(in_); - var d_ = await Call(15980754968839795663UL, 3, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(15980754968839795663UL, 3, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task CallHeld(CancellationToken cancellationToken_ = default) @@ -12055,9 +12195,11 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_CallHeld() {}; arg_?.serialize(in_); - var d_ = await Call(15980754968839795663UL, 4, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.S); + using (var d_ = await Call(15980754968839795663UL, 4, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.S); + } } public Task GetHeld(CancellationToken cancellationToken_ = default) @@ -12068,48 +12210,58 @@ namespace Capnproto_test.Capnp.Test arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 5, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Cap); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Cap); + } } ); } - public Task Echo(Capnproto_test.Capnp.Test.ITestCallOrder Cap, CancellationToken cancellationToken_ = default) + public Task Echo(Capnproto_test.Capnp.Test.ITestCallOrder cap, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_Echo() - {Cap = Cap}; + {Cap = cap}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 6, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Cap); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Cap); + } } ); } - public async Task ExpectCancel(Capnproto_test.Capnp.Test.ITestInterface Cap, CancellationToken cancellationToken_ = default) + public async Task ExpectCancel(Capnproto_test.Capnp.Test.ITestInterface cap, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_ExpectCancel() - {Cap = Cap}; + {Cap = cap}; arg_?.serialize(in_); - var d_ = await Call(15980754968839795663UL, 7, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(15980754968839795663UL, 7, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } - public async Task<(string, string)> MethodWithDefaults(string A, uint B, string C, CancellationToken cancellationToken_ = default) + public async Task<(string, string)> MethodWithDefaults(string a, uint b, string c, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_MethodWithDefaults() - {A = A, B = B, C = C}; + {A = a, B = b, C = c}; arg_?.serialize(in_); - var d_ = await Call(15980754968839795663UL, 8, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.D, r_.E); + using (var d_ = await Call(15980754968839795663UL, 8, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.D, r_.E); + } } public Task GetHandle(CancellationToken cancellationToken_ = default) @@ -12120,8 +12272,11 @@ namespace Capnproto_test.Capnp.Test arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 9, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Handle); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Handle); + } } ); @@ -12135,8 +12290,11 @@ namespace Capnproto_test.Capnp.Test arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(15980754968839795663UL, 10, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.NullCap); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.NullCap); + } } ); @@ -12148,34 +12306,41 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_GetEnormousString() {}; arg_?.serialize(in_); - var d_ = await Call(15980754968839795663UL, 11, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.Str); + using (var d_ = await Call(15980754968839795663UL, 11, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Str); + } } - public async Task MethodWithNullDefault(string A, Capnproto_test.Capnp.Test.ITestInterface B, CancellationToken cancellationToken_ = default) + public async Task MethodWithNullDefault(string a, Capnproto_test.Capnp.Test.ITestInterface b, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Params_MethodWithNullDefault() - {A = A, B = B}; + {A = a, B = b}; arg_?.serialize(in_); - var d_ = await Call(15980754968839795663UL, 12, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(15980754968839795663UL, 12, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } - public async Task GetCallSequence(uint Expected, CancellationToken cancellationToken_ = default) + public async Task GetCallSequence(uint expected, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestCallOrder.Params_GetCallSequence() - {Expected = Expected}; + {Expected = expected}; arg_?.serialize(in_); - var d_ = await Call(11594359141811814481UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return (r_.N); + using (var d_ = await Call(11594359141811814481UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.N); + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xddc70bf9784133cfUL)] public class TestMoreStuff_Skeleton : Skeleton { public TestMoreStuff_Skeleton() @@ -12186,167 +12351,206 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 15980754968839795663UL; Task CallFoo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.CallFoo(in_.Cap, cancellationToken_), s => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallFoo{S = s}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.CallFoo(in_.Cap, cancellationToken_), s => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallFoo{S = s}; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task CallFooWhenResolved(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.CallFooWhenResolved(in_.Cap, cancellationToken_), s => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallFooWhenResolved{S = s}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.CallFooWhenResolved(in_.Cap, cancellationToken_), s => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallFooWhenResolved{S = s}; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task NeverReturn(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.NeverReturn(in_.Cap, cancellationToken_), capCopy => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_NeverReturn{CapCopy = capCopy}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.NeverReturn(in_.Cap, cancellationToken_), capCopy => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_NeverReturn{CapCopy = capCopy}; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task Hold(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.Hold(in_.Cap, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.Hold(in_.Cap, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } Task CallHeld(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.CallHeld(cancellationToken_), s => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallHeld{S = s}; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.CallHeld(cancellationToken_), s => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_CallHeld{S = s}; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task GetHeld(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetHeld(cancellationToken_), cap => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetHeld{Cap = cap}; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetHeld(cancellationToken_), cap => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetHeld{Cap = cap}; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task Echo(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Echo(in_.Cap, cancellationToken_), cap => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_Echo{Cap = cap}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Echo(in_.Cap, cancellationToken_), cap => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_Echo{Cap = cap}; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task ExpectCancel(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.ExpectCancel(in_.Cap, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.ExpectCancel(in_.Cap, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } Task MethodWithDefaults(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.MethodWithDefaults(in_.A, in_.B, in_.C, cancellationToken_), (d, e) => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_MethodWithDefaults{D = d, E = e}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.MethodWithDefaults(in_.A, in_.B, in_.C, cancellationToken_), (d, e) => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_MethodWithDefaults{D = d, E = e}; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task GetHandle(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetHandle(cancellationToken_), handle => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetHandle{Handle = handle}; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetHandle(cancellationToken_), handle => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetHandle{Handle = handle}; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task GetNull(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetNull(cancellationToken_), nullCap => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetNull{NullCap = nullCap}; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetNull(cancellationToken_), nullCap => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetNull{NullCap = nullCap}; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task GetEnormousString(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetEnormousString(cancellationToken_), str => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetEnormousString{Str = str}; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetEnormousString(cancellationToken_), str => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMoreStuff.Result_GetEnormousString{Str = str}; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task MethodWithNullDefault(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.MethodWithNullDefault(in_.A, in_.B, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.MethodWithNullDefault(in_.A, in_.B, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestMoreStuff { - [TypeId(0x931ba418da60f6e4UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x931ba418da60f6e4UL)] public class Params_CallFoo : ICapnpSerializable { public const UInt64 typeId = 0x931ba418da60f6e4UL; @@ -12406,7 +12610,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9a28970beccecdd0UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9a28970beccecdd0UL)] public class Result_CallFoo : ICapnpSerializable { public const UInt64 typeId = 0x9a28970beccecdd0UL; @@ -12448,7 +12652,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -12460,13 +12664,13 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xfabc700c2ebe6378UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfabc700c2ebe6378UL)] public class Params_CallFooWhenResolved : ICapnpSerializable { public const UInt64 typeId = 0xfabc700c2ebe6378UL; @@ -12526,7 +12730,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa54ce1e9aa822f90UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa54ce1e9aa822f90UL)] public class Result_CallFooWhenResolved : ICapnpSerializable { public const UInt64 typeId = 0xa54ce1e9aa822f90UL; @@ -12568,7 +12772,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -12580,13 +12784,13 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0x94fe60465c95182bUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x94fe60465c95182bUL)] public class Params_NeverReturn : ICapnpSerializable { public const UInt64 typeId = 0x94fe60465c95182bUL; @@ -12646,7 +12850,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdef4e5fa6999c5dcUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdef4e5fa6999c5dcUL)] public class Result_NeverReturn : ICapnpSerializable { public const UInt64 typeId = 0xdef4e5fa6999c5dcUL; @@ -12706,7 +12910,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xfe7c8fbb769d8e58UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfe7c8fbb769d8e58UL)] public class Params_Hold : ICapnpSerializable { public const UInt64 typeId = 0xfe7c8fbb769d8e58UL; @@ -12766,7 +12970,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf839fb1374d003c9UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf839fb1374d003c9UL)] public class Result_Hold : ICapnpSerializable { public const UInt64 typeId = 0xf839fb1374d003c9UL; @@ -12811,7 +13015,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf8c5e5ef1edf83beUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf8c5e5ef1edf83beUL)] public class Params_CallHeld : ICapnpSerializable { public const UInt64 typeId = 0xf8c5e5ef1edf83beUL; @@ -12856,7 +13060,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe59935f160ac7578UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe59935f160ac7578UL)] public class Result_CallHeld : ICapnpSerializable { public const UInt64 typeId = 0xe59935f160ac7578UL; @@ -12898,7 +13102,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -12910,13 +13114,13 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xfeffc025fce317e3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfeffc025fce317e3UL)] public class Params_GetHeld : ICapnpSerializable { public const UInt64 typeId = 0xfeffc025fce317e3UL; @@ -12961,7 +13165,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xef4e146185af67ceUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xef4e146185af67ceUL)] public class Result_GetHeld : ICapnpSerializable { public const UInt64 typeId = 0xef4e146185af67ceUL; @@ -13021,7 +13225,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc07526f7e2e533b9UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc07526f7e2e533b9UL)] public class Params_Echo : ICapnpSerializable { public const UInt64 typeId = 0xc07526f7e2e533b9UL; @@ -13081,7 +13285,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa6224536593d5b92UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa6224536593d5b92UL)] public class Result_Echo : ICapnpSerializable { public const UInt64 typeId = 0xa6224536593d5b92UL; @@ -13141,7 +13345,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa1cc32d87f3edeb1UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa1cc32d87f3edeb1UL)] public class Params_ExpectCancel : ICapnpSerializable { public const UInt64 typeId = 0xa1cc32d87f3edeb1UL; @@ -13201,7 +13405,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8a3eba1758c0916eUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8a3eba1758c0916eUL)] public class Result_ExpectCancel : ICapnpSerializable { public const UInt64 typeId = 0x8a3eba1758c0916eUL; @@ -13246,7 +13450,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x99160a25fa50fbf1UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x99160a25fa50fbf1UL)] public class Params_MethodWithDefaults : ICapnpSerializable { public const UInt64 typeId = 0x99160a25fa50fbf1UL; @@ -13306,7 +13510,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string A => ctx.ReadText(0, ""); + public string A => ctx.ReadText(0, null); public uint B => ctx.ReadDataUInt(0UL, 123U); public string C => ctx.ReadText(1, "foo"); } @@ -13320,8 +13524,8 @@ namespace Capnproto_test.Capnp.Test public string A { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public uint B @@ -13338,7 +13542,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9c7e066f845a6c56UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9c7e066f845a6c56UL)] public class Result_MethodWithDefaults : ICapnpSerializable { public const UInt64 typeId = 0x9c7e066f845a6c56UL; @@ -13389,7 +13593,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string D => ctx.ReadText(0, ""); + public string D => ctx.ReadText(0, null); public string E => ctx.ReadText(1, "bar"); } @@ -13402,8 +13606,8 @@ namespace Capnproto_test.Capnp.Test public string D { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string E @@ -13414,7 +13618,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xead024a301a092a1UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xead024a301a092a1UL)] public class Params_GetHandle : ICapnpSerializable { public const UInt64 typeId = 0xead024a301a092a1UL; @@ -13459,7 +13663,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc3490d75420a1fe8UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc3490d75420a1fe8UL)] public class Result_GetHandle : ICapnpSerializable { public const UInt64 typeId = 0xc3490d75420a1fe8UL; @@ -13519,7 +13723,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd8493f0e175d61f2UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd8493f0e175d61f2UL)] public class Params_GetNull : ICapnpSerializable { public const UInt64 typeId = 0xd8493f0e175d61f2UL; @@ -13564,7 +13768,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe6955d8ef1023671UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe6955d8ef1023671UL)] public class Result_GetNull : ICapnpSerializable { public const UInt64 typeId = 0xe6955d8ef1023671UL; @@ -13624,7 +13828,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x805df436f55dd07aUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x805df436f55dd07aUL)] public class Params_GetEnormousString : ICapnpSerializable { public const UInt64 typeId = 0x805df436f55dd07aUL; @@ -13669,7 +13873,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x860e7512dc3925b0UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x860e7512dc3925b0UL)] public class Result_GetEnormousString : ICapnpSerializable { public const UInt64 typeId = 0x860e7512dc3925b0UL; @@ -13711,7 +13915,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Str => ctx.ReadText(0, ""); + public string Str => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -13723,13 +13927,13 @@ namespace Capnproto_test.Capnp.Test public string Str { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xfb92899aeb0ee74fUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xfb92899aeb0ee74fUL)] public class Params_MethodWithNullDefault : ICapnpSerializable { public const UInt64 typeId = 0xfb92899aeb0ee74fUL; @@ -13779,7 +13983,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string A => ctx.ReadText(0, ""); + public string A => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestInterface B => ctx.ReadCap(1); } @@ -13792,8 +13996,8 @@ namespace Capnproto_test.Capnp.Test public string A { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestInterface B @@ -13804,7 +14008,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8467348247305cf7UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8467348247305cf7UL)] public class Result_MethodWithNullDefault : ICapnpSerializable { public const UInt64 typeId = 0x8467348247305cf7UL; @@ -13850,16 +14054,17 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc07d8dcd80a69c0cUL), Proxy(typeof(TestMembrane_Proxy)), Skeleton(typeof(TestMembrane_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc07d8dcd80a69c0cUL), Proxy(typeof(TestMembrane_Proxy)), Skeleton(typeof(TestMembrane_Skeleton))] public interface ITestMembrane : IDisposable { Task MakeThing(CancellationToken cancellationToken_ = default); - Task CallPassThrough(Capnproto_test.Capnp.Test.TestMembrane.IThing Thing, bool TailCall, CancellationToken cancellationToken_ = default); - Task CallIntercept(Capnproto_test.Capnp.Test.TestMembrane.IThing Thing, bool TailCall, CancellationToken cancellationToken_ = default); - Task Loopback(Capnproto_test.Capnp.Test.TestMembrane.IThing Thing, CancellationToken cancellationToken_ = default); + Task CallPassThrough(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, bool tailCall, CancellationToken cancellationToken_ = default); + Task CallIntercept(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, bool tailCall, CancellationToken cancellationToken_ = default); + Task Loopback(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, CancellationToken cancellationToken_ = default); Task WaitForever(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc07d8dcd80a69c0cUL)] public class TestMembrane_Proxy : Proxy, ITestMembrane { public Task MakeThing(CancellationToken cancellationToken_ = default) @@ -13870,45 +14075,55 @@ namespace Capnproto_test.Capnp.Test arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(13870398341137210380UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Thing); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Thing); + } } ); } - public async Task CallPassThrough(Capnproto_test.Capnp.Test.TestMembrane.IThing Thing, bool TailCall, CancellationToken cancellationToken_ = default) + public async Task CallPassThrough(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, bool tailCall, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_CallPassThrough() - {Thing = Thing, TailCall = TailCall}; + {Thing = thing, TailCall = tailCall}; arg_?.serialize(in_); - var d_ = await Call(13870398341137210380UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + using (var d_ = await Call(13870398341137210380UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } - public async Task CallIntercept(Capnproto_test.Capnp.Test.TestMembrane.IThing Thing, bool TailCall, CancellationToken cancellationToken_ = default) + public async Task CallIntercept(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, bool tailCall, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_CallIntercept() - {Thing = Thing, TailCall = TailCall}; + {Thing = thing, TailCall = tailCall}; arg_?.serialize(in_); - var d_ = await Call(13870398341137210380UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + using (var d_ = await Call(13870398341137210380UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } - public Task Loopback(Capnproto_test.Capnp.Test.TestMembrane.IThing Thing, CancellationToken cancellationToken_ = default) + public Task Loopback(Capnproto_test.Capnp.Test.TestMembrane.IThing thing, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_Loopback() - {Thing = Thing}; + {Thing = thing}; arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(13870398341137210380UL, 3, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create(d_); - return (r_.Thing); + using (d_) + { + var r_ = CapnpSerializable.Create(d_); + return (r_.Thing); + } } ); @@ -13920,12 +14135,15 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Params_WaitForever() {}; arg_?.serialize(in_); - var d_ = await Call(13870398341137210380UL, 4, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(13870398341137210380UL, 4, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc07d8dcd80a69c0cUL)] public class TestMembrane_Skeleton : Skeleton { public TestMembrane_Skeleton() @@ -13936,74 +14154,90 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 13870398341137210380UL; Task MakeThing(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.MakeThing(cancellationToken_), thing => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMembrane.Result_MakeThing{Thing = thing}; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.MakeThing(cancellationToken_), thing => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMembrane.Result_MakeThing{Thing = thing}; + r_.serialize(s_); + return s_; + } - ); + ); + } } Task CallPassThrough(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.CallPassThrough(in_.Thing, in_.TailCall, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.CallPassThrough(in_.Thing, in_.TailCall, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } Task CallIntercept(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.CallIntercept(in_.Thing, in_.TailCall, cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.CallIntercept(in_.Thing, in_.TailCall, cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } Task Loopback(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - return Impatient.MaybeTailCall(Impl.Loopback(in_.Thing, cancellationToken_), thing => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - var r_ = new Capnproto_test.Capnp.Test.TestMembrane.Result_Loopback{Thing = thing}; - r_.serialize(s_); - return s_; - } + var in_ = CapnpSerializable.Create(d_); + return Impatient.MaybeTailCall(Impl.Loopback(in_.Thing, cancellationToken_), thing => + { + var s_ = SerializerState.CreateForRpc(); + var r_ = new Capnproto_test.Capnp.Test.TestMembrane.Result_Loopback{Thing = thing}; + r_.serialize(s_); + return s_; + } - ); + ); + } } async Task WaitForever(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.WaitForever(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.WaitForever(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestMembrane { - [TypeId(0x9352e4e41f173917UL), Proxy(typeof(Thing_Proxy)), Skeleton(typeof(Thing_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9352e4e41f173917UL), Proxy(typeof(Thing_Proxy)), Skeleton(typeof(Thing_Skeleton))] public interface IThing : IDisposable { Task PassThrough(CancellationToken cancellationToken_ = default); Task Intercept(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9352e4e41f173917UL)] public class Thing_Proxy : Proxy, IThing { public async Task PassThrough(CancellationToken cancellationToken_ = default) @@ -14012,9 +14246,11 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Thing.Params_PassThrough() {}; arg_?.serialize(in_); - var d_ = await Call(10615798940090972439UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + using (var d_ = await Call(10615798940090972439UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } public async Task Intercept(CancellationToken cancellationToken_ = default) @@ -14023,12 +14259,15 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestMembrane.Thing.Params_Intercept() {}; arg_?.serialize(in_); - var d_ = await Call(10615798940090972439UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return r_; + using (var d_ = await Call(10615798940090972439UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return r_; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9352e4e41f173917UL)] public class Thing_Skeleton : Skeleton { public Thing_Skeleton() @@ -14039,32 +14278,38 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 10615798940090972439UL; Task PassThrough(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.PassThrough(cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.PassThrough(cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } Task Intercept(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.Intercept(cancellationToken_), r_ => + using (d_) { - var s_ = SerializerState.CreateForRpc(); - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.Intercept(cancellationToken_), r_ => + { + var s_ = SerializerState.CreateForRpc(); + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class Thing { - [TypeId(0xff9bdcd05085d786UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xff9bdcd05085d786UL)] public class Params_PassThrough : ICapnpSerializable { public const UInt64 typeId = 0xff9bdcd05085d786UL; @@ -14109,7 +14354,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xee94bed3615ee745UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xee94bed3615ee745UL)] public class Params_Intercept : ICapnpSerializable { public const UInt64 typeId = 0xee94bed3615ee745UL; @@ -14155,7 +14400,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb0c6163faf291965UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb0c6163faf291965UL)] public class Result : ICapnpSerializable { public const UInt64 typeId = 0xb0c6163faf291965UL; @@ -14197,7 +14442,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Text => ctx.ReadText(0, ""); + public string Text => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -14209,13 +14454,13 @@ namespace Capnproto_test.Capnp.Test public string Text { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xd8ac2acc3ece6556UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd8ac2acc3ece6556UL)] public class Params_MakeThing : ICapnpSerializable { public const UInt64 typeId = 0xd8ac2acc3ece6556UL; @@ -14260,7 +14505,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe5d4904814ccbf29UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe5d4904814ccbf29UL)] public class Result_MakeThing : ICapnpSerializable { public const UInt64 typeId = 0xe5d4904814ccbf29UL; @@ -14320,7 +14565,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x945d9f634a6a29daUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x945d9f634a6a29daUL)] public class Params_CallPassThrough : ICapnpSerializable { public const UInt64 typeId = 0x945d9f634a6a29daUL; @@ -14395,7 +14640,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8749aac3375c5c71UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8749aac3375c5c71UL)] public class Params_CallIntercept : ICapnpSerializable { public const UInt64 typeId = 0x8749aac3375c5c71UL; @@ -14470,7 +14715,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x869a1b7ab34b42c9UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x869a1b7ab34b42c9UL)] public class Params_Loopback : ICapnpSerializable { public const UInt64 typeId = 0x869a1b7ab34b42c9UL; @@ -14530,7 +14775,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xecd19398fd88ab5cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xecd19398fd88ab5cUL)] public class Result_Loopback : ICapnpSerializable { public const UInt64 typeId = 0xecd19398fd88ab5cUL; @@ -14590,7 +14835,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x8f6bb30cc62917ffUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8f6bb30cc62917ffUL)] public class Params_WaitForever : ICapnpSerializable { public const UInt64 typeId = 0x8f6bb30cc62917ffUL; @@ -14635,7 +14880,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc343a4907280be01UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc343a4907280be01UL)] public class Result_WaitForever : ICapnpSerializable { public const UInt64 typeId = 0xc343a4907280be01UL; @@ -14681,7 +14926,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x949449ad7c11fa5cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x949449ad7c11fa5cUL)] public class TestContainMembrane : ICapnpSerializable { public const UInt64 typeId = 0x949449ad7c11fa5cUL; @@ -14756,7 +15001,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdd2b66a791a279f0UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdd2b66a791a279f0UL)] public class TestTransferCap : ICapnpSerializable { public const UInt64 typeId = 0xdd2b66a791a279f0UL; @@ -14815,7 +15060,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc7263e8f88844abcUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc7263e8f88844abcUL)] public class Element : ICapnpSerializable { public const UInt64 typeId = 0xc7263e8f88844abcUL; @@ -14865,7 +15110,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Text => ctx.ReadText(0, ""); + public string Text => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestInterface Cap => ctx.ReadCap(1); } @@ -14878,8 +15123,8 @@ namespace Capnproto_test.Capnp.Test public string Text { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestInterface Cap @@ -14891,7 +15136,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9ae342d394247cfcUL), Proxy(typeof(TestKeywordMethods_Proxy)), Skeleton(typeof(TestKeywordMethods_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9ae342d394247cfcUL), Proxy(typeof(TestKeywordMethods_Proxy)), Skeleton(typeof(TestKeywordMethods_Skeleton))] public interface ITestKeywordMethods : IDisposable { Task Delete(CancellationToken cancellationToken_ = default); @@ -14900,6 +15145,7 @@ namespace Capnproto_test.Capnp.Test Task Return(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9ae342d394247cfcUL)] public class TestKeywordMethods_Proxy : Proxy, ITestKeywordMethods { public async Task Delete(CancellationToken cancellationToken_ = default) @@ -14908,9 +15154,11 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_Delete() {}; arg_?.serialize(in_); - var d_ = await Call(11160837778045172988UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(11160837778045172988UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Class(CancellationToken cancellationToken_ = default) @@ -14919,9 +15167,11 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_Class() {}; arg_?.serialize(in_); - var d_ = await Call(11160837778045172988UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(11160837778045172988UL, 1, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Void(CancellationToken cancellationToken_ = default) @@ -14930,9 +15180,11 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_Void() {}; arg_?.serialize(in_); - var d_ = await Call(11160837778045172988UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(11160837778045172988UL, 2, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } public async Task Return(CancellationToken cancellationToken_ = default) @@ -14941,12 +15193,15 @@ namespace Capnproto_test.Capnp.Test var arg_ = new Capnproto_test.Capnp.Test.TestKeywordMethods.Params_Return() {}; arg_?.serialize(in_); - var d_ = await Call(11160837778045172988UL, 3, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(11160837778045172988UL, 3, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9ae342d394247cfcUL)] public class TestKeywordMethods_Skeleton : Skeleton { public TestKeywordMethods_Skeleton() @@ -14957,36 +15212,48 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 11160837778045172988UL; async Task Delete(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Delete(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Delete(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Class(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Class(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Class(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Void(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Void(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Void(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } async Task Return(DeserializerState d_, CancellationToken cancellationToken_) { - await Impl.Return(cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + await Impl.Return(cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestKeywordMethods { - [TypeId(0xca3a89cdeb6bd6b7UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xca3a89cdeb6bd6b7UL)] public class Params_Delete : ICapnpSerializable { public const UInt64 typeId = 0xca3a89cdeb6bd6b7UL; @@ -15031,7 +15298,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xeeb5843598307592UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xeeb5843598307592UL)] public class Result_Delete : ICapnpSerializable { public const UInt64 typeId = 0xeeb5843598307592UL; @@ -15076,7 +15343,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9cf5a8313c5db036UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9cf5a8313c5db036UL)] public class Params_Class : ICapnpSerializable { public const UInt64 typeId = 0x9cf5a8313c5db036UL; @@ -15121,7 +15388,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc0253868ac12e7d8UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc0253868ac12e7d8UL)] public class Result_Class : ICapnpSerializable { public const UInt64 typeId = 0xc0253868ac12e7d8UL; @@ -15166,7 +15433,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa4a08763833c7757UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa4a08763833c7757UL)] public class Params_Void : ICapnpSerializable { public const UInt64 typeId = 0xa4a08763833c7757UL; @@ -15211,7 +15478,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xde82773089c0aeabUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xde82773089c0aeabUL)] public class Result_Void : ICapnpSerializable { public const UInt64 typeId = 0xde82773089c0aeabUL; @@ -15256,7 +15523,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x99817360625e8ca3UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x99817360625e8ca3UL)] public class Params_Return : ICapnpSerializable { public const UInt64 typeId = 0x99817360625e8ca3UL; @@ -15301,7 +15568,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xb70872e07eaa992fUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb70872e07eaa992fUL)] public class Result_Return : ICapnpSerializable { public const UInt64 typeId = 0xb70872e07eaa992fUL; @@ -15347,12 +15614,13 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xea72cc77253798cdUL), Proxy(typeof(TestAuthenticatedBootstrap_Proxy<>)), Skeleton(typeof(TestAuthenticatedBootstrap_Skeleton<>))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xea72cc77253798cdUL), Proxy(typeof(TestAuthenticatedBootstrap_Proxy<>)), Skeleton(typeof(TestAuthenticatedBootstrap_Skeleton<>))] public interface ITestAuthenticatedBootstrap : IDisposable where TVatId : class { Task GetCallerId(CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xea72cc77253798cdUL)] public class TestAuthenticatedBootstrap_Proxy : Proxy, ITestAuthenticatedBootstrap where TVatId : class { public Task GetCallerId(CancellationToken cancellationToken_ = default) @@ -15363,14 +15631,18 @@ namespace Capnproto_test.Capnp.Test arg_?.serialize(in_); return Impatient.MakePipelineAware(Call(16893789964317726925UL, 0, in_.Rewrap(), false, cancellationToken_), d_ => { - var r_ = CapnpSerializable.Create.Result_GetCallerId>(d_); - return (r_.Caller); + using (d_) + { + var r_ = CapnpSerializable.Create.Result_GetCallerId>(d_); + return (r_.Caller); + } } ); } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xea72cc77253798cdUL)] public class TestAuthenticatedBootstrap_Skeleton : Skeleton> where TVatId : class { public TestAuthenticatedBootstrap_Skeleton() @@ -15381,22 +15653,25 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 16893789964317726925UL; Task GetCallerId(DeserializerState d_, CancellationToken cancellationToken_) { - return Impatient.MaybeTailCall(Impl.GetCallerId(cancellationToken_), caller => + using (d_) { - var s_ = SerializerState.CreateForRpc.Result_GetCallerId.WRITER>(); - var r_ = new Capnproto_test.Capnp.Test.TestAuthenticatedBootstrap.Result_GetCallerId{Caller = caller}; - r_.serialize(s_); - return s_; - } + return Impatient.MaybeTailCall(Impl.GetCallerId(cancellationToken_), caller => + { + var s_ = SerializerState.CreateForRpc.Result_GetCallerId.WRITER>(); + var r_ = new Capnproto_test.Capnp.Test.TestAuthenticatedBootstrap.Result_GetCallerId{Caller = caller}; + r_.serialize(s_); + return s_; + } - ); + ); + } } } public static class TestAuthenticatedBootstrap where TVatId : class { - [TypeId(0x8ec30e2451f1cffeUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8ec30e2451f1cffeUL)] public class Params_GetCallerId : ICapnpSerializable { public const UInt64 typeId = 0x8ec30e2451f1cffeUL; @@ -15441,7 +15716,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc71cf776034a3e67UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc71cf776034a3e67UL)] public class Result_GetCallerId : ICapnpSerializable { public const UInt64 typeId = 0xc71cf776034a3e67UL; @@ -15502,7 +15777,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xceba982cb629f6c2UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xceba982cb629f6c2UL)] public class TestSturdyRef : ICapnpSerializable { public const UInt64 typeId = 0xceba982cb629f6c2UL; @@ -15577,7 +15852,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xe02d3bbe1010e342UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe02d3bbe1010e342UL)] public class TestSturdyRefHostId : ICapnpSerializable { public const UInt64 typeId = 0xe02d3bbe1010e342UL; @@ -15619,7 +15894,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Host => ctx.ReadText(0, ""); + public string Host => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -15631,13 +15906,13 @@ namespace Capnproto_test.Capnp.Test public string Host { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } - [TypeId(0xaeb2ad168e2f5697UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xaeb2ad168e2f5697UL)] public class TestSturdyRefObjectId : ICapnpSerializable { public const UInt64 typeId = 0xaeb2ad168e2f5697UL; @@ -15696,7 +15971,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xef428f2f67c4d439UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xef428f2f67c4d439UL)] public enum Tag : ushort { testInterface, @@ -15708,7 +15983,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x9e5c574772b1d462UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9e5c574772b1d462UL)] public class TestProvisionId : ICapnpSerializable { public const UInt64 typeId = 0x9e5c574772b1d462UL; @@ -15753,7 +16028,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xea2fb7dca9cdbdeaUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xea2fb7dca9cdbdeaUL)] public class TestRecipientId : ICapnpSerializable { public const UInt64 typeId = 0xea2fb7dca9cdbdeaUL; @@ -15798,7 +16073,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xa805157b98b65469UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa805157b98b65469UL)] public class TestThirdPartyCapId : ICapnpSerializable { public const UInt64 typeId = 0xa805157b98b65469UL; @@ -15843,7 +16118,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf4c58a8ebcd0f600UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf4c58a8ebcd0f600UL)] public class TestJoinResult : ICapnpSerializable { public const UInt64 typeId = 0xf4c58a8ebcd0f600UL; @@ -15888,7 +16163,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd1fd8e9caf2a5d58UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd1fd8e9caf2a5d58UL)] public class TestNameAnnotation : ICapnpSerializable { public const UInt64 typeId = 0xd1fd8e9caf2a5d58UL; @@ -16052,7 +16327,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0x89d9d1626b34017cUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x89d9d1626b34017cUL)] public class badlyNamedUnion : ICapnpSerializable { public const UInt64 typeId = 0x89d9d1626b34017cUL; @@ -16184,7 +16459,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xc3594bce5b24b722UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc3594bce5b24b722UL)] public class badlyNamedGroup : ICapnpSerializable { public const UInt64 typeId = 0xc3594bce5b24b722UL; @@ -16229,7 +16504,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf610d1deb4c9e84aUL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf610d1deb4c9e84aUL)] public enum BadlyNamedEnum : ushort { foo, @@ -16237,7 +16512,7 @@ namespace Capnproto_test.Capnp.Test baz } - [TypeId(0xbe406b6341d52284UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbe406b6341d52284UL)] public class NestedStruct : ICapnpSerializable { public const UInt64 typeId = 0xbe406b6341d52284UL; @@ -16311,7 +16586,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xf6cb3f9c7a4322e0UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf6cb3f9c7a4322e0UL)] public enum DeeplyNestedEnum : ushort { quux, @@ -16321,26 +16596,30 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xd112a69d31ed918bUL), Proxy(typeof(TestNameAnnotationInterface_Proxy)), Skeleton(typeof(TestNameAnnotationInterface_Skeleton))] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd112a69d31ed918bUL), Proxy(typeof(TestNameAnnotationInterface_Proxy)), Skeleton(typeof(TestNameAnnotationInterface_Skeleton))] public interface ITestNameAnnotationInterface : IDisposable { - Task BadlyNamedMethod(byte BadlyNamedParam, CancellationToken cancellationToken_ = default); + Task BadlyNamedMethod(byte badlyNamedParam, CancellationToken cancellationToken_ = default); } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd112a69d31ed918bUL)] public class TestNameAnnotationInterface_Proxy : Proxy, ITestNameAnnotationInterface { - public async Task BadlyNamedMethod(byte BadlyNamedParam, CancellationToken cancellationToken_ = default) + public async Task BadlyNamedMethod(byte badlyNamedParam, CancellationToken cancellationToken_ = default) { var in_ = SerializerState.CreateForRpc(); var arg_ = new Capnproto_test.Capnp.Test.TestNameAnnotationInterface.Params_BadlyNamedMethod() - {BadlyNamedParam = BadlyNamedParam}; + {BadlyNamedParam = badlyNamedParam}; arg_?.serialize(in_); - var d_ = await Call(15065286897585459595UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned; - var r_ = CapnpSerializable.Create(d_); - return; + using (var d_ = await Call(15065286897585459595UL, 0, in_.Rewrap(), false, cancellationToken_).WhenReturned) + { + var r_ = CapnpSerializable.Create(d_); + return; + } } } + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd112a69d31ed918bUL)] public class TestNameAnnotationInterface_Skeleton : Skeleton { public TestNameAnnotationInterface_Skeleton() @@ -16351,16 +16630,19 @@ namespace Capnproto_test.Capnp.Test public override ulong InterfaceId => 15065286897585459595UL; async Task BadlyNamedMethod(DeserializerState d_, CancellationToken cancellationToken_) { - var in_ = CapnpSerializable.Create(d_); - await Impl.BadlyNamedMethod(in_.BadlyNamedParam, cancellationToken_); - var s_ = SerializerState.CreateForRpc(); - return s_; + using (d_) + { + var in_ = CapnpSerializable.Create(d_); + await Impl.BadlyNamedMethod(in_.BadlyNamedParam, cancellationToken_); + var s_ = SerializerState.CreateForRpc(); + return s_; + } } } public static class TestNameAnnotationInterface { - [TypeId(0xc12efc3b075adfe9UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc12efc3b075adfe9UL)] public class Params_BadlyNamedMethod : ICapnpSerializable { public const UInt64 typeId = 0xc12efc3b075adfe9UL; @@ -16420,7 +16702,7 @@ namespace Capnproto_test.Capnp.Test } } - [TypeId(0xdcc3cdb4b28f6c86UL)] + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdcc3cdb4b28f6c86UL)] public class Result_BadlyNamedMethod : ICapnpSerializable { public const UInt64 typeId = 0xdcc3cdb4b28f6c86UL; @@ -16471,19 +16753,22 @@ namespace Capnproto_test.Capnp.Test static readonly MemberAccessPath Path_capnproto_test_capnp_test_TestPipeline_getCap_OutBox_Cap = new MemberAccessPath(1U, 0U); public static Capnproto_test.Capnp.Test.ITestInterface OutBox_Cap(this Task<(string, Capnproto_test.Capnp.Test.TestPipeline.Box)> task) { - return (Capnproto_test.Capnp.Test.ITestInterface)CapabilityReflection.CreateProxy(Impatient.GetAnswer(task).Access(Path_capnproto_test_capnp_test_TestPipeline_getCap_OutBox_Cap)); + async Task AwaitProxy() => (await task).Item2?.Cap; + return (Capnproto_test.Capnp.Test.ITestInterface)CapabilityReflection.CreateProxy(Impatient.Access(task, Path_capnproto_test_capnp_test_TestPipeline_getCap_OutBox_Cap, AwaitProxy())); } static readonly MemberAccessPath Path_capnproto_test_capnp_test_TestPipeline_getAnyCap_OutBox_Cap = new MemberAccessPath(1U, 0U); public static BareProxy OutBox_Cap(this Task<(string, Capnproto_test.Capnp.Test.TestPipeline.AnyBox)> task) { - return (BareProxy)CapabilityReflection.CreateProxy(Impatient.GetAnswer(task).Access(Path_capnproto_test_capnp_test_TestPipeline_getAnyCap_OutBox_Cap)); + async Task AwaitProxy() => (await task).Item2?.Cap; + return (BareProxy)CapabilityReflection.CreateProxy(Impatient.Access(task, Path_capnproto_test_capnp_test_TestPipeline_getAnyCap_OutBox_Cap, AwaitProxy())); } static readonly MemberAccessPath Path_capnproto_test_capnp_test_TestTailCallee_foo_C = new MemberAccessPath(1U); public static Capnproto_test.Capnp.Test.ITestCallOrder C(this Task task) { - return (Capnproto_test.Capnp.Test.ITestCallOrder)CapabilityReflection.CreateProxy(Impatient.GetAnswer(task).Access(Path_capnproto_test_capnp_test_TestTailCallee_foo_C)); + async Task AwaitProxy() => (await task).C; + return (Capnproto_test.Capnp.Test.ITestCallOrder)CapabilityReflection.CreateProxy(Impatient.Access(task, Path_capnproto_test_capnp_test_TestTailCallee_foo_C, AwaitProxy())); } } } \ No newline at end of file diff --git a/CapnpC.CSharp.Generator.Tests/FeatureSteps/CodeGeneratorSteps.cs b/CapnpC.CSharp.Generator.Tests/FeatureSteps/CodeGeneratorSteps.cs index 8537a48..12b5070 100644 --- a/CapnpC.CSharp.Generator.Tests/FeatureSteps/CodeGeneratorSteps.cs +++ b/CapnpC.CSharp.Generator.Tests/FeatureSteps/CodeGeneratorSteps.cs @@ -241,14 +241,12 @@ namespace CapnpC.CSharp.Generator.Tests } } - catch (AssertFailedException) + finally { string generated = _result.GeneratedFiles.Single().GeneratedContent; string path = Path.ChangeExtension(Path.GetTempFileName(), ".capnp.cs"); File.WriteAllText(path, generated); Console.WriteLine($"Generated code was saved to {path}"); - - throw; } } } diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest1.capnp b/CapnpC.CSharp.Generator.Tests/No Resources/UnitTest1.capnp similarity index 100% rename from CapnpC.CSharp.Generator.Tests/Embedded Resources/UnitTest1.capnp rename to CapnpC.CSharp.Generator.Tests/No Resources/UnitTest1.capnp diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/rpc-csharp.capnp b/CapnpC.CSharp.Generator.Tests/No Resources/rpc-csharp.capnp new file mode 100644 index 0000000..730a740 --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/rpc-csharp.capnp @@ -0,0 +1,1417 @@ +# Copyright (c) 2020 Christian Köllner and contributors +# This is a modified version of rpc.capnp, found in the original distribution +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xb312981b2552a250; +# Recall that Cap'n Proto RPC allows messages to contain references to remote objects that +# implement interfaces. These references are called "capabilities", because they both designate +# the remote object to use and confer permission to use it. +# +# Recall also that Cap'n Proto RPC has the feature that when a method call itself returns a +# capability, the caller can begin calling methods on that capability _before the first call has +# returned_. The caller essentially sends a message saying "Hey server, as soon as you finish +# that previous call, do this with the result!". Cap'n Proto's RPC protocol makes this possible. +# +# The protocol is significantly more complicated than most RPC protocols. However, this is +# implementation complexity that underlies an easy-to-grasp higher-level model of object oriented +# programming. That is, just like TCP is a surprisingly complicated protocol that implements a +# conceptually-simple byte stream abstraction, Cap'n Proto is a surprisingly complicated protocol +# that implements a conceptually-simple object abstraction. +# +# Cap'n Proto RPC is based heavily on CapTP, the object-capability protocol used by the E +# programming language: +# http://www.erights.org/elib/distrib/captp/index.html +# +# Cap'n Proto RPC takes place between "vats". A vat hosts some set of objects and talks to other +# vats through direct bilateral connections. Typically, there is a 1:1 correspondence between vats +# and processes (in the unix sense of the word), although this is not strictly always true (one +# process could run multiple vats, or a distributed virtual vat might live across many processes). +# +# Cap'n Proto does not distinguish between "clients" and "servers" -- this is up to the application. +# Either end of any connection can potentially hold capabilities pointing to the other end, and +# can call methods on those capabilities. In the doc comments below, we use the words "sender" +# and "receiver". These refer to the sender and receiver of an instance of the struct or field +# being documented. Sometimes we refer to a "third-party" that is neither the sender nor the +# receiver. Documentation is generally written from the point of view of the sender. +# +# It is generally up to the vat network implementation to securely verify that connections are made +# to the intended vat as well as to encrypt transmitted data for privacy and integrity. See the +# `VatNetwork` example interface near the end of this file. +# +# When a new connection is formed, the only interesting things that can be done are to send a +# `Bootstrap` (level 0) or `Accept` (level 3) message. +# +# Unless otherwise specified, messages must be delivered to the receiving application in the same +# order in which they were initiated by the sending application. The goal is to support "E-Order", +# which states that two calls made on the same reference must be delivered in the order which they +# were made: +# http://erights.org/elib/concurrency/partial-order.html +# +# Since the full protocol is complicated, we define multiple levels of support that an +# implementation may target. For many applications, level 1 support will be sufficient. +# Comments in this file indicate which level requires the corresponding feature to be +# implemented. +# +# * **Level 0:** The implementation does not support object references. Only the bootstrap interface +# can be called. At this level, the implementation does not support object-oriented protocols and +# is similar in complexity to JSON-RPC or Protobuf services. This level should be considered only +# a temporary stepping-stone toward level 1 as the lack of object references drastically changes +# how protocols are designed. Applications _should not_ attempt to design their protocols around +# the limitations of level 0 implementations. +# +# * **Level 1:** The implementation supports simple bilateral interaction with object references +# and promise pipelining, but interactions between three or more parties are supported only via +# proxying of objects. E.g. if Alice (in Vat A) wants to send Bob (in Vat B) a capability +# pointing to Carol (in Vat C), Alice must create a proxy of Carol within Vat A and send Bob a +# reference to that; Bob cannot form a direct connection to Carol. Level 1 implementations do +# not support checking if two capabilities received from different vats actually point to the +# same object ("join"), although they should be able to do this check on capabilities received +# from the same vat. +# +# * **Level 2:** The implementation supports saving persistent capabilities -- i.e. capabilities +# that remain valid even after disconnect, and can be restored on a future connection. When a +# capability is saved, the requester receives a `SturdyRef`, which is a token that can be used +# to restore the capability later. +# +# * **Level 3:** The implementation supports three-way interactions. That is, if Alice (in Vat A) +# sends Bob (in Vat B) a capability pointing to Carol (in Vat C), then Vat B will automatically +# form a direct connection to Vat C rather than have requests be proxied through Vat A. +# +# * **Level 4:** The entire protocol is implemented, including joins (checking if two capabilities +# are equivalent). +# +# Note that an implementation must also support specific networks (transports), as described in +# the "Network-specific Parameters" section below. An implementation might have different levels +# depending on the network used. +# +# New implementations of Cap'n Proto should start out targeting the simplistic two-party network +# type as defined in `rpc-twoparty.capnp`. With this network type, level 3 is irrelevant and +# levels 2 and 4 are much easier than usual to implement. When such an implementation is paired +# with a container proxy, the contained app effectively gets to make full use of the proxy's +# network at level 4. And since Cap'n Proto IPC is extremely fast, it may never make sense to +# bother implementing any other vat network protocol -- just use the correct container type and get +# it for free. +# $$embed +# #pragma warning disable CS1591 + +using CSharp = import "/csharp.capnp"; +$CSharp.namespace("Capnp.Rpc"); +$CSharp.nullableEnable(true); +$CSharp.emitNullableDirective(false); +$CSharp.emitDomainClassesAndInterfaces(true); +$CSharp.typeVisibility(public); + +# ======================================================================================== +# The Four Tables +# +# Cap'n Proto RPC connections are stateful (although an application built on Cap'n Proto could +# export a stateless interface). As in CapTP, for each open connection, a vat maintains four state +# tables: questions, answers, imports, and exports. See the diagram at: +# http://www.erights.org/elib/distrib/captp/4tables.html +# +# The question table corresponds to the other end's answer table, and the imports table corresponds +# to the other end's exports table. +# +# The entries in each table are identified by ID numbers (defined below as 32-bit integers). These +# numbers are always specific to the connection; a newly-established connection starts with no +# valid IDs. Since low-numbered IDs will pack better, it is suggested that IDs be assigned like +# Unix file descriptors -- prefer the lowest-number ID that is currently available. +# +# IDs in the questions/answers tables are chosen by the questioner and generally represent method +# calls that are in progress. +# +# IDs in the imports/exports tables are chosen by the exporter and generally represent objects on +# which methods may be called. Exports may be "settled", meaning the exported object is an actual +# object living in the exporter's vat, or they may be "promises", meaning the exported object is +# the as-yet-unknown result of an ongoing operation and will eventually be resolved to some other +# object once that operation completes. Calls made to a promise will be forwarded to the eventual +# target once it is known. The eventual replacement object does *not* get the same ID as the +# promise, as it may turn out to be an object that is already exported (so already has an ID) or +# may even live in a completely different vat (and so won't get an ID on the same export table +# at all). +# +# IDs can be reused over time. To make this safe, we carefully define the lifetime of IDs. Since +# messages using the ID could be traveling in both directions simultaneously, we must define the +# end of life of each ID _in each direction_. The ID is only safe to reuse once it has been +# released by both sides. +# +# When a Cap'n Proto connection is lost, everything on the four tables is lost. All questions are +# canceled and throw exceptions. All imports become broken (all future calls to them throw +# exceptions). All exports and answers are implicitly released. The only things not lost are +# persistent capabilities (`SturdyRef`s). The application must plan for this and should respond by +# establishing a new connection and restoring from these persistent capabilities. + +using QuestionId = UInt32; +# **(level 0)** +# +# Identifies a question in the sender's question table (which corresponds to the receiver's answer +# table). The questioner (caller) chooses an ID when making a call. The ID remains valid in +# caller -> callee messages until a Finish message is sent, and remains valid in callee -> caller +# messages until a Return message is sent. + +using AnswerId = QuestionId; +# **(level 0)** +# +# Identifies an answer in the sender's answer table (which corresponds to the receiver's question +# table). +# +# AnswerId is physically equivalent to QuestionId, since the question and answer tables correspond, +# but we define a separate type for documentation purposes: we always use the type representing +# the sender's point of view. + +using ExportId = UInt32; +# **(level 1)** +# +# Identifies an exported capability or promise in the sender's export table (which corresponds +# to the receiver's import table). The exporter chooses an ID before sending a capability over the +# wire. If the capability is already in the table, the exporter should reuse the same ID. If the +# ID is a promise (as opposed to a settled capability), this must be indicated at the time the ID +# is introduced (e.g. by using `senderPromise` instead of `senderHosted` in `CapDescriptor`); in +# this case, the importer shall expect a later `Resolve` message that replaces the promise. +# +# ExportId/ImportIds are subject to reference counting. Whenever an `ExportId` is sent over the +# wire (from the exporter to the importer), the export's reference count is incremented (unless +# otherwise specified). The reference count is later decremented by a `Release` message. Since +# the `Release` message can specify an arbitrary number by which to reduce the reference count, the +# importer should usually batch reference decrements and only send a `Release` when it believes the +# reference count has hit zero. Of course, it is possible that a new reference to the export is +# in-flight at the time that the `Release` message is sent, so it is necessary for the exporter to +# keep track of the reference count on its end as well to avoid race conditions. +# +# When a connection is lost, all exports are implicitly released. It is not possible to restore +# a connection state after disconnect (although a transport layer could implement a concept of +# persistent connections if it is transparent to the RPC layer). + +using ImportId = ExportId; +# **(level 1)** +# +# Identifies an imported capability or promise in the sender's import table (which corresponds to +# the receiver's export table). +# +# ImportId is physically equivalent to ExportId, since the export and import tables correspond, +# but we define a separate type for documentation purposes: we always use the type representing +# the sender's point of view. +# +# An `ImportId` remains valid in importer -> exporter messages until the importer has sent +# `Release` messages that (it believes) have reduced the reference count to zero. + +# ======================================================================================== +# Messages + +struct Message { + # An RPC connection is a bi-directional stream of Messages. + + union { + unimplemented @0 :Message; + # The sender previously received this message from the peer but didn't understand it or doesn't + # yet implement the functionality that was requested. So, the sender is echoing the message + # back. In some cases, the receiver may be able to recover from this by pretending the sender + # had taken some appropriate "null" action. + # + # For example, say `resolve` is received by a level 0 implementation (because a previous call + # or return happened to contain a promise). The level 0 implementation will echo it back as + # `unimplemented`. The original sender can then simply release the cap to which the promise + # had resolved, thus avoiding a leak. + # + # For any message type that introduces a question, if the message comes back unimplemented, + # the original sender may simply treat it as if the question failed with an exception. + # + # In cases where there is no sensible way to react to an `unimplemented` message (without + # resource leaks or other serious problems), the connection may need to be aborted. This is + # a gray area; different implementations may take different approaches. + + abort @1 :Exception; + # Sent when a connection is being aborted due to an unrecoverable error. This could be e.g. + # because the sender received an invalid or nonsensical message or because the sender had an + # internal error. The sender will shut down the outgoing half of the connection after `abort` + # and will completely close the connection shortly thereafter (it's up to the sender how much + # of a time buffer they want to offer for the client to receive the `abort` before the + # connection is reset). + + # Level 0 features ----------------------------------------------- + + bootstrap @8 :Bootstrap; # Request the peer's bootstrap interface. + call @2 :Call; # Begin a method call. + return @3 :Return; # Complete a method call. + finish @4 :Finish; # Release a returned answer / cancel a call. + + # Level 1 features ----------------------------------------------- + + resolve @5 :Resolve; # Resolve a previously-sent promise. + release @6 :Release; # Release a capability so that the remote object can be deallocated. + disembargo @13 :Disembargo; # Lift an embargo used to enforce E-order over promise resolution. + + # Level 2 features ----------------------------------------------- + + obsoleteSave @7 :AnyPointer; + # Obsolete request to save a capability, resulting in a SturdyRef. This has been replaced + # by the `Persistent` interface defined in `persistent.capnp`. This operation was never + # implemented. + + obsoleteDelete @9 :AnyPointer; + # Obsolete way to delete a SturdyRef. This operation was never implemented. + + # Level 3 features ----------------------------------------------- + + provide @10 :Provide; # Provide a capability to a third party. + accept @11 :Accept; # Accept a capability provided by a third party. + + # Level 4 features ----------------------------------------------- + + join @12 :Join; # Directly connect to the common root of two or more proxied caps. + } +} + +# Level 0 message types ---------------------------------------------- + +struct Bootstrap { + # **(level 0)** + # + # Get the "bootstrap" interface exported by the remote vat. + # + # For level 0, 1, and 2 implementations, the "bootstrap" interface is simply the main interface + # exported by a vat. If the vat acts as a server fielding connections from clients, then the + # bootstrap interface defines the basic functionality available to a client when it connects. + # The exact interface definition obviously depends on the application. + # + # We call this a "bootstrap" because in an ideal Cap'n Proto world, bootstrap interfaces would + # never be used. In such a world, any time you connect to a new vat, you do so because you + # received an introduction from some other vat (see `ThirdPartyCapId`). Thus, the first message + # you send is `Accept`, and further communications derive from there. `Bootstrap` is not used. + # + # In such an ideal world, DNS itself would support Cap'n Proto -- performing a DNS lookup would + # actually return a new Cap'n Proto capability, thus introducing you to the target system via + # level 3 RPC. Applications would receive the capability to talk to DNS in the first place as + # an initial endowment or part of a Powerbox interaction. Therefore, an app can form arbitrary + # connections without ever using `Bootstrap`. + # + # Of course, in the real world, DNS is not Cap'n-Proto-based, and we don't want Cap'n Proto to + # require a whole new internet infrastructure to be useful. Therefore, we offer bootstrap + # interfaces as a way to get up and running without a level 3 introduction. Thus, bootstrap + # interfaces are used to "bootstrap" from other, non-Cap'n-Proto-based means of service discovery, + # such as legacy DNS. + # + # Note that a vat need not provide a bootstrap interface, and in fact many vats (especially those + # acting as clients) do not. In this case, the vat should either reply to `Bootstrap` with a + # `Return` indicating an exception, or should return a dummy capability with no methods. + + questionId @0 :QuestionId; + # A new question ID identifying this request, which will eventually receive a Return message + # containing the restored capability. + + deprecatedObjectId @1 :AnyPointer; + # ** DEPRECATED ** + # + # A Vat may export multiple bootstrap interfaces. In this case, `deprecatedObjectId` specifies + # which one to return. If this pointer is null, then the default bootstrap interface is returned. + # + # As of verison 0.5, use of this field is deprecated. If a service wants to export multiple + # bootstrap interfaces, it should instead define a single bootstrap interface that has methods + # that return each of the other interfaces. + # + # **History** + # + # In the first version of Cap'n Proto RPC (0.4.x) the `Bootstrap` message was called `Restore`. + # At the time, it was thought that this would eventually serve as the way to restore SturdyRefs + # (level 2). Meanwhile, an application could offer its "main" interface on a well-known + # (non-secret) SturdyRef. + # + # Since level 2 RPC was not implemented at the time, the `Restore` message was in practice only + # used to obtain the main interface. Since most applications had only one main interface that + # they wanted to restore, they tended to designate this with a null `objectId`. + # + # Unfortunately, the earliest version of the EZ RPC interfaces set a precedent of exporting + # multiple main interfaces by allowing them to be exported under string names. In this case, + # `objectId` was a Text value specifying the name. + # + # All of this proved problematic for several reasons: + # + # - The arrangement assumed that a client wishing to restore a SturdyRef would know exactly what + # machine to connect to and would be able to immediately restore a SturdyRef on connection. + # However, in practice, the ability to restore SturdyRefs is itself a capability that may + # require going through an authentication process to obtain. Thus, it makes more sense to + # define a "restorer service" as a full Cap'n Proto interface. If this restorer interface is + # offered as the vat's bootstrap interface, then this is equivalent to the old arrangement. + # + # - Overloading "Restore" for the purpose of obtaining well-known capabilities encouraged the + # practice of exporting singleton services with string names. If singleton services are desired, + # it is better to have one main interface that has methods that can be used to obtain each + # service, in order to get all the usual benefits of schemas and type checking. + # + # - Overloading "Restore" also had a security problem: Often, "main" or "well-known" + # capabilities exported by a vat are in fact not public: they are intended to be accessed only + # by clients who are capable of forming a connection to the vat. This can lead to trouble if + # the client itself has other clients and wishes to foward some `Restore` requests from those + # external clients -- it has to be very careful not to allow through `Restore` requests + # addressing the default capability. + # + # For example, consider the case of a sandboxed Sandstorm application and its supervisor. The + # application exports a default capability to its supervisor that provides access to + # functionality that only the supervisor is supposed to access. Meanwhile, though, applications + # may publish other capabilities that may be persistent, in which case the application needs + # to field `Restore` requests that could come from anywhere. These requests of course have to + # pass through the supervisor, as all communications with the outside world must. But, the + # supervisor has to be careful not to honor an external request addressing the application's + # default capability, since this capability is privileged. Unfortunately, the default + # capability cannot be given an unguessable name, because then the supervisor itself would not + # be able to address it! + # + # As of Cap'n Proto 0.5, `Restore` has been renamed to `Bootstrap` and is no longer planned for + # use in restoring SturdyRefs. + # + # Note that 0.4 also defined a message type called `Delete` that, like `Restore`, addressed a + # SturdyRef, but indicated that the client would not restore the ref again in the future. This + # operation was never implemented, so it was removed entirely. If a "delete" operation is desired, + # it should exist as a method on the same interface that handles restoring SturdyRefs. However, + # the utility of such an operation is questionable. You wouldn't be able to rely on it for + # garbage collection since a client could always disappear permanently without remembering to + # delete all its SturdyRefs, thus leaving them dangling forever. Therefore, it is advisable to + # design systems such that SturdyRefs never represent "owned" pointers. + # + # For example, say a SturdyRef points to an image file hosted on some server. That image file + # should also live inside a collection (a gallery, perhaps) hosted on the same server, owned by + # a user who can delete the image at any time. If the user deletes the image, the SturdyRef + # stops working. On the other hand, if the SturdyRef is discarded, this has no effect on the + # existence of the image in its collection. +} + +struct Call { + # **(level 0)** + # + # Message type initiating a method call on a capability. + + questionId @0 :QuestionId; + # A number, chosen by the caller, that identifies this call in future messages. This number + # must be different from all other calls originating from the same end of the connection (but + # may overlap with question IDs originating from the opposite end). A fine strategy is to use + # sequential question IDs, but the recipient should not assume this. + # + # A question ID can be reused once both: + # - A matching Return has been received from the callee. + # - A matching Finish has been sent from the caller. + + target @1 :MessageTarget; + # The object that should receive this call. + + interfaceId @2 :UInt64; + # The type ID of the interface being called. Each capability may implement multiple interfaces. + + methodId @3 :UInt16; + # The ordinal number of the method to call within the requested interface. + + allowThirdPartyTailCall @8 :Bool = false; + # Indicates whether or not the receiver is allowed to send a `Return` containing + # `acceptFromThirdParty`. Level 3 implementations should set this true. Otherwise, the callee + # will have to proxy the return in the case of a tail call to a third-party vat. + + params @4 :Payload; + # The call parameters. `params.content` is a struct whose fields correspond to the parameters of + # the method. + + sendResultsTo :union { + # Where should the return message be sent? + + caller @5 :Void; + # Send the return message back to the caller (the usual). + + yourself @6 :Void; + # **(level 1)** + # + # Don't actually return the results to the sender. Instead, hold on to them and await + # instructions from the sender regarding what to do with them. In particular, the sender + # may subsequently send a `Return` for some other call (which the receiver had previously made + # to the sender) with `takeFromOtherQuestion` set. The results from this call are then used + # as the results of the other call. + # + # When `yourself` is used, the receiver must still send a `Return` for the call, but sets the + # field `resultsSentElsewhere` in that `Return` rather than including the results. + # + # This feature can be used to implement tail calls in which a call from Vat A to Vat B ends up + # returning the result of a call from Vat B back to Vat A. + # + # In particular, the most common use case for this feature is when Vat A makes a call to a + # promise in Vat B, and then that promise ends up resolving to a capability back in Vat A. + # Vat B must forward all the queued calls on that promise back to Vat A, but can set `yourself` + # in the calls so that the results need not pass back through Vat B. + # + # For example: + # - Alice, in Vat A, calls foo() on Bob in Vat B. + # - Alice makes a pipelined call bar() on the promise returned by foo(). + # - Later on, Bob resolves the promise from foo() to point at Carol, who lives in Vat A (next + # to Alice). + # - Vat B dutifully forwards the bar() call to Carol. Let us call this forwarded call bar'(). + # Notice that bar() and bar'() are travelling in opposite directions on the same network + # link. + # - The `Call` for bar'() has `sendResultsTo` set to `yourself`. + # - Vat B sends a `Return` for bar() with `takeFromOtherQuestion` set in place of the results, + # with the value set to the question ID of bar'(). Vat B does not wait for bar'() to return, + # as doing so would introduce unnecessary round trip latency. + # - Vat A receives bar'() and delivers it to Carol. + # - When bar'() returns, Vat A sends a `Return` for bar'() to Vat B, with `resultsSentElsewhere` + # set in place of results. + # - Vat A sends a `Finish` for the bar() call to Vat B. + # - Vat B receives the `Finish` for bar() and sends a `Finish` for bar'(). + + thirdParty @7 :RecipientId; + # **(level 3)** + # + # The call's result should be returned to a different vat. The receiver (the callee) expects + # to receive an `Accept` message from the indicated vat, and should return the call's result + # to it, rather than to the sender of the `Call`. + # + # This operates much like `yourself`, above, except that Carol is in a separate Vat C. `Call` + # messages are sent from Vat A -> Vat B and Vat B -> Vat C. A `Return` message is sent from + # Vat B -> Vat A that contains `acceptFromThirdParty` in place of results. When Vat A sends + # an `Accept` to Vat C, it receives back a `Return` containing the call's actual result. Vat C + # also sends a `Return` to Vat B with `resultsSentElsewhere`. + } +} + +struct Return { + # **(level 0)** + # + # Message type sent from callee to caller indicating that the call has completed. + + answerId @0 :AnswerId; + # Equal to the QuestionId of the corresponding `Call` message. + + releaseParamCaps @1 :Bool = true; + # If true, all capabilities that were in the params should be considered released. The sender + # must not send separate `Release` messages for them. Level 0 implementations in particular + # should always set this true. This defaults true because if level 0 implementations forget to + # set it they'll never notice (just silently leak caps), but if level >=1 implementations forget + # to set it to false they'll quickly get errors. + # + # The receiver should act as if the sender had sent a release message with count=1 for each + # CapDescriptor in the original Call message. + + union { + results @2 :Payload; + # The result. + # + # For regular method calls, `results.content` points to the result struct. + # + # For a `Return` in response to an `Accept` or `Bootstrap`, `results` contains a single + # capability (rather than a struct), and `results.content` is just a capability pointer with + # index 0. A `Finish` is still required in this case. + + exception @3 :Exception; + # Indicates that the call failed and explains why. + + canceled @4 :Void; + # Indicates that the call was canceled due to the caller sending a Finish message + # before the call had completed. + + resultsSentElsewhere @5 :Void; + # This is set when returning from a `Call` that had `sendResultsTo` set to something other + # than `caller`. + # + # It doesn't matter too much when this is sent, as the receiver doesn't need to do anything + # with it, but the C++ implementation appears to wait for the call to finish before sending + # this. + + takeFromOtherQuestion @6 :QuestionId; + # The sender has also sent (before this message) a `Call` with the given question ID and with + # `sendResultsTo.yourself` set, and the results of that other call should be used as the + # results here. `takeFromOtherQuestion` can only used once per question. + + acceptFromThirdParty @7 :ThirdPartyCapId; + # **(level 3)** + # + # The caller should contact a third-party vat to pick up the results. An `Accept` message + # sent to the vat will return the result. This pairs with `Call.sendResultsTo.thirdParty`. + # It should only be used if the corresponding `Call` had `allowThirdPartyTailCall` set. + } +} + +struct Finish { + # **(level 0)** + # + # Message type sent from the caller to the callee to indicate: + # 1) The questionId will no longer be used in any messages sent by the callee (no further + # pipelined requests). + # 2) If the call has not returned yet, the caller no longer cares about the result. If nothing + # else cares about the result either (e.g. there are no other outstanding calls pipelined on + # the result of this one) then the callee may wish to immediately cancel the operation and + # send back a Return message with "canceled" set. However, implementations are not required + # to support premature cancellation -- instead, the implementation may wait until the call + # actually completes and send a normal `Return` message. + # + # TODO(someday): Should we separate (1) and implicitly releasing result capabilities? It would be + # possible and useful to notify the server that it doesn't need to keep around the response to + # service pipeline requests even though the caller still wants to receive it / hasn't yet + # finished processing it. It could also be useful to notify the server that it need not marshal + # the results because the caller doesn't want them anyway, even if the caller is still sending + # pipelined calls, although this seems less useful (just saving some bytes on the wire). + + questionId @0 :QuestionId; + # ID of the call whose result is to be released. + + releaseResultCaps @1 :Bool = true; + # If true, all capabilities that were in the results should be considered released. The sender + # must not send separate `Release` messages for them. Level 0 implementations in particular + # should always set this true. This defaults true because if level 0 implementations forget to + # set it they'll never notice (just silently leak caps), but if level >=1 implementations forget + # set it false they'll quickly get errors. +} + +# Level 1 message types ---------------------------------------------- + +struct Resolve { + # **(level 1)** + # + # Message type sent to indicate that a previously-sent promise has now been resolved to some other + # object (possibly another promise) -- or broken, or canceled. + # + # Keep in mind that it's possible for a `Resolve` to be sent to a level 0 implementation that + # doesn't implement it. For example, a method call or return might contain a capability in the + # payload. Normally this is fine even if the receiver is level 0, because they will implicitly + # release all such capabilities on return / finish. But if the cap happens to be a promise, then + # a follow-up `Resolve` may be sent regardless of this release. The level 0 receiver will reply + # with an `unimplemented` message, and the sender (of the `Resolve`) can respond to this as if the + # receiver had immediately released any capability to which the promise resolved. + # + # When implementing promise resolution, it's important to understand how embargos work and the + # tricky case of the Tribble 4-way race condition. See the comments for the Disembargo message, + # below. + + promiseId @0 :ExportId; + # The ID of the promise to be resolved. + # + # Unlike all other instances of `ExportId` sent from the exporter, the `Resolve` message does + # _not_ increase the reference count of `promiseId`. In fact, it is expected that the receiver + # will release the export soon after receiving `Resolve`, and the sender will not send this + # `ExportId` again until it has been released and recycled. + # + # When an export ID sent over the wire (e.g. in a `CapDescriptor`) is indicated to be a promise, + # this indicates that the sender will follow up at some point with a `Resolve` message. If the + # same `promiseId` is sent again before `Resolve`, still only one `Resolve` is sent. If the + # same ID is sent again later _after_ a `Resolve`, it can only be because the export's + # reference count hit zero in the meantime and the ID was re-assigned to a new export, therefore + # this later promise does _not_ correspond to the earlier `Resolve`. + # + # If a promise ID's reference count reaches zero before a `Resolve` is sent, the `Resolve` + # message may or may not still be sent (the `Resolve` may have already been in-flight when + # `Release` was sent, but if the `Release` is received before `Resolve` then there is no longer + # any reason to send a `Resolve`). Thus a `Resolve` may be received for a promise of which + # the receiver has no knowledge, because it already released it earlier. In this case, the + # receiver should simply release the capability to which the promise resolved. + + union { + cap @1 :CapDescriptor; + # The object to which the promise resolved. + # + # The sender promises that from this point forth, until `promiseId` is released, it shall + # simply forward all messages to the capability designated by `cap`. This is true even if + # `cap` itself happens to desigate another promise, and that other promise later resolves -- + # messages sent to `promiseId` shall still go to that other promise, not to its resolution. + # This is important in the case that the receiver of the `Resolve` ends up sending a + # `Disembargo` message towards `promiseId` in order to control message ordering -- that + # `Disembargo` really needs to reflect back to exactly the object designated by `cap` even + # if that object is itself a promise. + + exception @2 :Exception; + # Indicates that the promise was broken. + } +} + +struct Release { + # **(level 1)** + # + # Message type sent to indicate that the sender is done with the given capability and the receiver + # can free resources allocated to it. + + id @0 :ImportId; + # What to release. + + referenceCount @1 :UInt32; + # The amount by which to decrement the reference count. The export is only actually released + # when the reference count reaches zero. +} + +struct Disembargo { + # **(level 1)** + # + # Message sent to indicate that an embargo on a recently-resolved promise may now be lifted. + # + # Embargos are used to enforce E-order in the presence of promise resolution. That is, if an + # application makes two calls foo() and bar() on the same capability reference, in that order, + # the calls should be delivered in the order in which they were made. But if foo() is called + # on a promise, and that promise happens to resolve before bar() is called, then the two calls + # may travel different paths over the network, and thus could arrive in the wrong order. In + # this case, the call to `bar()` must be embargoed, and a `Disembargo` message must be sent along + # the same path as `foo()` to ensure that the `Disembargo` arrives after `foo()`. Once the + # `Disembargo` arrives, `bar()` can then be delivered. + # + # There are two particular cases where embargos are important. Consider object Alice, in Vat A, + # who holds a promise P, pointing towards Vat B, that eventually resolves to Carol. The two + # cases are: + # - Carol lives in Vat A, i.e. next to Alice. In this case, Vat A needs to send a `Disembargo` + # message that echos through Vat B and back, to ensure that all pipelined calls on the promise + # have been delivered. + # - Carol lives in a different Vat C. When the promise resolves, a three-party handoff occurs + # (see `Provide` and `Accept`, which constitute level 3 of the protocol). In this case, we + # piggyback on the state that has already been set up to handle the handoff: the `Accept` + # message (from Vat A to Vat C) is embargoed, as are all pipelined messages sent to it, while + # a `Disembargo` message is sent from Vat A through Vat B to Vat C. See `Accept.embargo` for + # an example. + # + # Note that in the case where Carol actually lives in Vat B (i.e., the same vat that the promise + # already pointed at), no embargo is needed, because the pipelined calls are delivered over the + # same path as the later direct calls. + # + # Keep in mind that promise resolution happens both in the form of Resolve messages as well as + # Return messages (which resolve PromisedAnswers). Embargos apply in both cases. + # + # An alternative strategy for enforcing E-order over promise resolution could be for Vat A to + # implement the embargo internally. When Vat A is notified of promise resolution, it could + # send a dummy no-op call to promise P and wait for it to complete. Until that call completes, + # all calls to the capability are queued locally. This strategy works, but is pessimistic: + # in the three-party case, it requires an A -> B -> C -> B -> A round trip before calls can start + # being delivered directly to from Vat A to Vat C. The `Disembargo` message allows latency to be + # reduced. (In the two-party loopback case, the `Disembargo` message is just a more explicit way + # of accomplishing the same thing as a no-op call, but isn't any faster.) + # + # *The Tribble 4-way Race Condition* + # + # Any implementation of promise resolution and embargos must be aware of what we call the + # "Tribble 4-way race condition", after Dean Tribble, who explained the problem in a lively + # Friam meeting. + # + # Embargos are designed to work in the case where a two-hop path is being shortened to one hop. + # But sometimes there are more hops. Imagine that Alice has a reference to a remote promise P1 + # that eventually resolves to _another_ remote promise P2 (in a third vat), which _at the same + # time_ happens to resolve to Bob (in a fourth vat). In this case, we're shortening from a 3-hop + # path (with four parties) to a 1-hop path (Alice -> Bob). + # + # Extending the embargo/disembargo protocol to be able to shorted multiple hops at once seems + # difficult. Instead, we make a rule that prevents this case from coming up: + # + # One a promise P has been resolved to a remote object reference R, then all further messages + # received addressed to P will be forwarded strictly to R. Even if it turns out later that R is + # itself a promise, and has resolved to some other object Q, messages sent to P will still be + # forwarded to R, not directly to Q (R will of course further forward the messages to Q). + # + # This rule does not cause a significant performance burden because once P has resolved to R, it + # is expected that people sending messages to P will shortly start sending them to R instead and + # drop P. P is at end-of-life anyway, so it doesn't matter if it ignores chances to further + # optimize its path. + + target @0 :MessageTarget; + # What is to be disembargoed. + + using EmbargoId = UInt32; + # Used in `senderLoopback` and `receiverLoopback`, below. + + context :union { + senderLoopback @1 :EmbargoId; + # The sender is requesting a disembargo on a promise that is known to resolve back to a + # capability hosted by the sender. As soon as the receiver has echoed back all pipelined calls + # on this promise, it will deliver the Disembargo back to the sender with `receiverLoopback` + # set to the same value as `senderLoopback`. This value is chosen by the sender, and since + # it is also consumed be the sender, the sender can use whatever strategy it wants to make sure + # the value is unambiguous. + # + # The receiver must verify that the target capability actually resolves back to the sender's + # vat. Otherwise, the sender has committed a protocol error and should be disconnected. + + receiverLoopback @2 :EmbargoId; + # The receiver previously sent a `senderLoopback` Disembargo towards a promise resolving to + # this capability, and that Disembargo is now being echoed back. + + accept @3 :Void; + # **(level 3)** + # + # The sender is requesting a disembargo on a promise that is known to resolve to a third-party + # capability that the sender is currently in the process of accepting (using `Accept`). + # The receiver of this `Disembargo` has an outstanding `Provide` on said capability. The + # receiver should now send a `Disembargo` with `provide` set to the question ID of that + # `Provide` message. + # + # See `Accept.embargo` for an example. + + provide @4 :QuestionId; + # **(level 3)** + # + # The sender is requesting a disembargo on a capability currently being provided to a third + # party. The question ID identifies the `Provide` message previously sent by the sender to + # this capability. On receipt, the receiver (the capability host) shall release the embargo + # on the `Accept` message that it has received from the third party. See `Accept.embargo` for + # an example. + } +} + +# Level 2 message types ---------------------------------------------- + +# See persistent.capnp. + +# Level 3 message types ---------------------------------------------- + +struct Provide { + # **(level 3)** + # + # Message type sent to indicate that the sender wishes to make a particular capability implemented + # by the receiver available to a third party for direct access (without the need for the third + # party to proxy through the sender). + # + # (In CapTP, `Provide` and `Accept` are methods of the global `NonceLocator` object exported by + # every vat. In Cap'n Proto, we bake this into the core protocol.) + + questionId @0 :QuestionId; + # Question ID to be held open until the recipient has received the capability. A result will be + # returned once the third party has successfully received the capability. The sender must at some + # point send a `Finish` message as with any other call, and that message can be used to cancel the + # whole operation. + + target @1 :MessageTarget; + # What is to be provided to the third party. + + recipient @2 :RecipientId; + # Identity of the third party that is expected to pick up the capability. +} + +struct Accept { + # **(level 3)** + # + # Message type sent to pick up a capability hosted by the receiving vat and provided by a third + # party. The third party previously designated the capability using `Provide`. + # + # This message is also used to pick up a redirected return -- see `Return.acceptFromThirdParty`. + + questionId @0 :QuestionId; + # A new question ID identifying this accept message, which will eventually receive a Return + # message containing the provided capability (or the call result in the case of a redirected + # return). + + provision @1 :ProvisionId; + # Identifies the provided object to be picked up. + + embargo @2 :Bool; + # If true, this accept shall be temporarily embargoed. The resulting `Return` will not be sent, + # and any pipelined calls will not be delivered, until the embargo is released. The receiver + # (the capability host) will expect the provider (the vat that sent the `Provide` message) to + # eventually send a `Disembargo` message with the field `context.provide` set to the question ID + # of the original `Provide` message. At that point, the embargo is released and the queued + # messages are delivered. + # + # For example: + # - Alice, in Vat A, holds a promise P, which currently points toward Vat B. + # - Alice calls foo() on P. The `Call` message is sent to Vat B. + # - The promise P in Vat B ends up resolving to Carol, in Vat C. + # - Vat B sends a `Provide` message to Vat C, identifying Vat A as the recipient. + # - Vat B sends a `Resolve` message to Vat A, indicating that the promise has resolved to a + # `ThirdPartyCapId` identifying Carol in Vat C. + # - Vat A sends an `Accept` message to Vat C to pick up the capability. Since Vat A knows that + # it has an outstanding call to the promise, it sets `embargo` to `true` in the `Accept` + # message. + # - Vat A sends a `Disembargo` message to Vat B on promise P, with `context.accept` set. + # - Alice makes a call bar() to promise P, which is now pointing towards Vat C. Alice doesn't + # know anything about the mechanics of promise resolution happening under the hood, but she + # expects that bar() will be delivered after foo() because that is the order in which she + # initiated the calls. + # - Vat A sends the bar() call to Vat C, as a pipelined call on the result of the `Accept` (which + # hasn't returned yet, due to the embargo). Since calls to the newly-accepted capability + # are embargoed, Vat C does not deliver the call yet. + # - At some point, Vat B forwards the foo() call from the beginning of this example on to Vat C. + # - Vat B forwards the `Disembargo` from Vat A on to vat C. It sets `context.provide` to the + # question ID of the `Provide` message it had sent previously. + # - Vat C receives foo() before `Disembargo`, thus allowing it to correctly deliver foo() + # before delivering bar(). + # - Vat C receives `Disembargo` from Vat B. It can now send a `Return` for the `Accept` from + # Vat A, as well as deliver bar(). +} + +# Level 4 message types ---------------------------------------------- + +struct Join { + # **(level 4)** + # + # Message type sent to implement E.join(), which, given a number of capabilities that are + # expected to be equivalent, finds the underlying object upon which they all agree and forms a + # direct connection to it, skipping any proxies that may have been constructed by other vats + # while transmitting the capability. See: + # http://erights.org/elib/equality/index.html + # + # Note that this should only serve to bypass fully-transparent proxies -- proxies that were + # created merely for convenience, without any intention of hiding the underlying object. + # + # For example, say Bob holds two capabilities hosted by Alice and Carol, but he expects that both + # are simply proxies for a capability hosted elsewhere. He then issues a join request, which + # operates as follows: + # - Bob issues Join requests on both Alice and Carol. Each request contains a different piece + # of the JoinKey. + # - Alice is proxying a capability hosted by Dana, so forwards the request to Dana's cap. + # - Dana receives the first request and sees that the JoinKeyPart is one of two. She notes that + # she doesn't have the other part yet, so she records the request and responds with a + # JoinResult. + # - Alice relays the JoinAswer back to Bob. + # - Carol is also proxying a capability from Dana, and so forwards her Join request to Dana as + # well. + # - Dana receives Carol's request and notes that she now has both parts of a JoinKey. She + # combines them in order to form information needed to form a secure connection to Bob. She + # also responds with another JoinResult. + # - Bob receives the responses from Alice and Carol. He uses the returned JoinResults to + # determine how to connect to Dana and attempts to form the connection. Since Bob and Dana now + # agree on a secret key that neither Alice nor Carol ever saw, this connection can be made + # securely even if Alice or Carol is conspiring against the other. (If Alice and Carol are + # conspiring _together_, they can obviously reproduce the key, but this doesn't matter because + # the whole point of the join is to verify that Alice and Carol agree on what capability they + # are proxying.) + # + # If the two capabilities aren't actually proxies of the same object, then the join requests + # will come back with conflicting `hostId`s and the join will fail before attempting to form any + # connection. + + questionId @0 :QuestionId; + # Question ID used to respond to this Join. (Note that this ID only identifies one part of the + # request for one hop; each part has a different ID and relayed copies of the request have + # (probably) different IDs still.) + # + # The receiver will reply with a `Return` whose `results` is a JoinResult. This `JoinResult` + # is relayed from the joined object's host, possibly with transformation applied as needed + # by the network. + # + # Like any return, the result must be released using a `Finish`. However, this release + # should not occur until the joiner has either successfully connected to the joined object. + # Vats relaying a `Join` message similarly must not release the result they receive until the + # return they relayed back towards the joiner has itself been released. This allows the + # joined object's host to detect when the Join operation is canceled before completing -- if + # it receives a `Finish` for one of the join results before the joiner successfully + # connects. It can then free any resources it had allocated as part of the join. + + target @1 :MessageTarget; + # The capability to join. + + keyPart @2 :JoinKeyPart; + # A part of the join key. These combine to form the complete join key, which is used to establish + # a direct connection. + + # TODO(before implementing): Change this so that multiple parts can be sent in a single Join + # message, so that if multiple join parts are going to cross the same connection they can be sent + # together, so that the receive can potentially optimize its handling of them. In the case where + # all parts are bundled together, should the recipient be expected to simply return a cap, so + # that the caller can immediately start pipelining to it? +} + +# ======================================================================================== +# Common structures used in messages + +struct MessageTarget { + # The target of a `Call` or other messages that target a capability. + + union { + importedCap @0 :ImportId; + # This message is to a capability or promise previously imported by the caller (exported by + # the receiver). + + promisedAnswer @1 :PromisedAnswer; + # This message is to a capability that is expected to be returned by another call that has not + # yet been completed. + # + # At level 0, this is supported only for addressing the result of a previous `Bootstrap`, so + # that initial startup doesn't require a round trip. + } +} + +struct Payload { + # Represents some data structure that might contain capabilities. + + content @0 :AnyPointer; + # Some Cap'n Proto data structure. Capability pointers embedded in this structure index into + # `capTable`. + + capTable @1 :List(CapDescriptor); + # Descriptors corresponding to the cap pointers in `content`. +} + +struct CapDescriptor { + # **(level 1)** + # + # When an application-defined type contains an interface pointer, that pointer contains an index + # into the message's capability table -- i.e. the `capTable` part of the `Payload`. Each + # capability in the table is represented as a `CapDescriptor`. The runtime API should not reveal + # the CapDescriptor directly to the application, but should instead wrap it in some kind of + # callable object with methods corresponding to the interface that the capability implements. + # + # Keep in mind that `ExportIds` in a `CapDescriptor` are subject to reference counting. See the + # description of `ExportId`. + # + # Note that it is currently not possible to include a broken capability in the CapDescriptor + # table. Instead, create a new export (`senderPromise`) for each broken capability and then + # immediately follow the payload-bearing Call or Return message with one Resolve message for each + # broken capability, resolving it to an exception. + + union { + none @0 :Void; + # There is no capability here. This `CapDescriptor` should not appear in the payload content. + # A `none` CapDescriptor can be generated when an application inserts a capability into a + # message and then later changes its mind and removes it -- rewriting all of the other + # capability pointers may be hard, so instead a tombstone is left, similar to the way a removed + # struct or list instance is zeroed out of the message but the space is not reclaimed. + # Hopefully this is unusual. + + senderHosted @1 :ExportId; + # The ID of a capability in the sender's export table (receiver's import table). It may be a + # newly allocated table entry, or an existing entry (increments the reference count). + + senderPromise @2 :ExportId; + # A promise that the sender will resolve later. The sender will send exactly one Resolve + # message at a future point in time to replace this promise. Note that even if the same + # `senderPromise` is received multiple times, only one `Resolve` is sent to cover all of + # them. If `senderPromise` is released before the `Resolve` is sent, the sender (of this + # `CapDescriptor`) may choose not to send the `Resolve` at all. + + receiverHosted @3 :ImportId; + # A capability (or promise) previously exported by the receiver (imported by the sender). + + receiverAnswer @4 :PromisedAnswer; + # A capability expected to be returned in the results of a currently-outstanding call posed + # by the sender. + + thirdPartyHosted @5 :ThirdPartyCapDescriptor; + # **(level 3)** + # + # A capability that lives in neither the sender's nor the receiver's vat. The sender needs + # to form a direct connection to a third party to pick up the capability. + # + # Level 1 and 2 implementations that receive a `thirdPartyHosted` may simply send calls to its + # `vine` instead. + } +} + +struct PromisedAnswer { + # **(mostly level 1)** + # + # Specifies how to derive a promise from an unanswered question, by specifying the path of fields + # to follow from the root of the eventual result struct to get to the desired capability. Used + # to address method calls to a not-yet-returned capability or to pass such a capability as an + # input to some other method call. + # + # Level 0 implementations must support `PromisedAnswer` only for the case where the answer is + # to a `Bootstrap` message. In this case, `path` is always empty since `Bootstrap` always returns + # a raw capability. + + questionId @0 :QuestionId; + # ID of the question (in the sender's question table / receiver's answer table) whose answer is + # expected to contain the capability. + + transform @1 :List(Op); + # Operations / transformations to apply to the result in order to get the capability actually + # being addressed. E.g. if the result is a struct and you want to call a method on a capability + # pointed to by a field of the struct, you need a `getPointerField` op. + + struct Op { + union { + noop @0 :Void; + # Does nothing. This member is mostly defined so that we can make `Op` a union even + # though (as of this writing) only one real operation is defined. + + getPointerField @1 :UInt16; + # Get a pointer field within a struct. The number is an index into the pointer section, NOT + # a field ordinal, so that the receiver does not need to understand the schema. + + # TODO(someday): We could add: + # - For lists, the ability to address every member of the list, or a slice of the list, the + # result of which would be another list. This is useful for implementing the equivalent of + # a SQL table join (not to be confused with the `Join` message type). + # - Maybe some ability to test a union. + # - Probably not a good idea: the ability to specify an arbitrary script to run on the + # result. We could define a little stack-based language where `Op` specifies one + # "instruction" or transformation to apply. Although this is not a good idea + # (over-engineered), any narrower additions to `Op` should be designed as if this + # were the eventual goal. + } + } +} + +struct ThirdPartyCapDescriptor { + # **(level 3)** + # + # Identifies a capability in a third-party vat that the sender wants the receiver to pick up. + + id @0 :ThirdPartyCapId; + # Identifies the third-party host and the specific capability to accept from it. + + vineId @1 :ExportId; + # A proxy for the third-party object exported by the sender. In CapTP terminology this is called + # a "vine", because it is an indirect reference to the third-party object that snakes through the + # sender vat. This serves two purposes: + # + # * Level 1 and 2 implementations that don't understand how to connect to a third party may + # simply send calls to the vine. Such calls will be forwarded to the third-party by the + # sender. + # + # * Level 3 implementations must release the vine only once they have successfully picked up the + # object from the third party. This ensures that the capability is not released by the sender + # prematurely. + # + # The sender will close the `Provide` request that it has sent to the third party as soon as + # it receives either a `Call` or a `Release` message directed at the vine. +} + +struct Exception { + # **(level 0)** + # + # Describes an arbitrary error that prevented an operation (e.g. a call) from completing. + # + # Cap'n Proto exceptions always indicate that something went wrong. In other words, in a fantasy + # world where everything always works as expected, no exceptions would ever be thrown. Clients + # should only ever catch exceptions as a means to implement fault-tolerance, where "fault" can + # mean: + # - Bugs. + # - Invalid input. + # - Configuration errors. + # - Network problems. + # - Insufficient resources. + # - Version skew (unimplemented functionality). + # - Other logistical problems. + # + # Exceptions should NOT be used to flag application-specific conditions that a client is expected + # to handle in an application-specific way. Put another way, in the Cap'n Proto world, + # "checked exceptions" (where an interface explicitly defines the exceptions it throws and + # clients are forced by the type system to handle those exceptions) do NOT make sense. + + reason @0 :Text; + # Human-readable failure description. + + type @3 :Type; + # The type of the error. The purpose of this enum is not to describe the error itself, but + # rather to describe how the client might want to respond to the error. + + enum Type { + failed @0; + # A generic problem occurred, and it is believed that if the operation were repeated without + # any change in the state of the world, the problem would occur again. + # + # A client might respond to this error by logging it for investigation by the developer and/or + # displaying it to the user. + + overloaded @1; + # The request was rejected due to a temporary lack of resources. + # + # Examples include: + # - There's not enough CPU time to keep up with incoming requests, so some are rejected. + # - The server ran out of RAM or disk space during the request. + # - The operation timed out (took significantly longer than it should have). + # + # A client might respond to this error by scheduling to retry the operation much later. The + # client should NOT retry again immediately since this would likely exacerbate the problem. + + disconnected @2; + # The method failed because a connection to some necessary capability was lost. + # + # Examples include: + # - The client introduced the server to a third-party capability, the connection to that third + # party was subsequently lost, and then the client requested that the server use the dead + # capability for something. + # - The client previously requested that the server obtain a capability from some third party. + # The server returned a capability to an object wrapping the third-party capability. Later, + # the server's connection to the third party was lost. + # - The capability has been revoked. Revocation does not necessarily mean that the client is + # no longer authorized to use the capability; it is often used simply as a way to force the + # client to repeat the setup process, perhaps to efficiently move them to a new back-end or + # get them to recognize some other change that has occurred. + # + # A client should normally respond to this error by releasing all capabilities it is currently + # holding related to the one it called and then re-creating them by restoring SturdyRefs and/or + # repeating the method calls used to create them originally. In other words, disconnect and + # start over. This should in turn cause the server to obtain a new copy of the capability that + # it lost, thus making everything work. + # + # If the client receives another `disconnencted` error in the process of rebuilding the + # capability and retrying the call, it should treat this as an `overloaded` error: the network + # is currently unreliable, possibly due to load or other temporary issues. + + unimplemented @3; + # The server doesn't implement the requested method. If there is some other method that the + # client could call (perhaps an older and/or slower interface), it should try that instead. + # Otherwise, this should be treated like `failed`. + } + + obsoleteIsCallersFault @1 :Bool; + # OBSOLETE. Ignore. + + obsoleteDurability @2 :UInt16; + # OBSOLETE. See `type` instead. +} + +# ======================================================================================== +# Network-specific Parameters +# +# Some parts of the Cap'n Proto RPC protocol are not specified here because different vat networks +# may wish to use different approaches to solving them. For example, on the public internet, you +# may want to authenticate vats using public-key cryptography, but on a local intranet with trusted +# infrastructure, you may be happy to authenticate based on network address only, or some other +# lightweight mechanism. +# +# To accommodate this, we specify several "parameter" types. Each type is defined here as an +# alias for `AnyPointer`, but a specific network will want to define a specific set of types to use. +# All vats in a vat network must agree on these parameters in order to be able to communicate. +# Inter-network communication can be accomplished through "gateways" that perform translation +# between the primitives used on each network; these gateways may need to be deeply stateful, +# depending on the translations they perform. +# +# For interaction over the global internet between parties with no other prior arrangement, a +# particular set of bindings for these types is defined elsewhere. (TODO(someday): Specify where +# these common definitions live.) +# +# Another common network type is the two-party network, in which one of the parties typically +# interacts with the outside world entirely through the other party. In such a connection between +# Alice and Bob, all objects that exist on Bob's other networks appear to Alice as if they were +# hosted by Bob himself, and similarly all objects on Alice's network (if she even has one) appear +# to Bob as if they were hosted by Alice. This network type is interesting because from the point +# of view of a simple application that communicates with only one other party via the two-party +# protocol, there are no three-party interactions at all, and joins are unusually simple to +# implement, so implementing at level 4 is barely more complicated than implementing at level 1. +# Moreover, if you pair an app implementing the two-party network with a container that implements +# some other network, the app can then participate on the container's network just as if it +# implemented that network directly. The types used by the two-party network are defined in +# `rpc-twoparty.capnp`. +# +# The things that we need to parameterize are: +# - How to store capabilities long-term without holding a connection open (mostly level 2). +# - How to authenticate vats in three-party introductions (level 3). +# - How to implement `Join` (level 4). +# +# Persistent references +# --------------------- +# +# **(mostly level 2)** +# +# We want to allow some capabilities to be stored long-term, even if a connection is lost and later +# recreated. ExportId is a short-term identifier that is specific to a connection, so it doesn't +# help here. We need a way to specify long-term identifiers, as well as a strategy for +# reconnecting to a referenced capability later. +# +# Three-party interactions +# ------------------------ +# +# **(level 3)** +# +# In cases where more than two vats are interacting, we have situations where VatA holds a +# capability hosted by VatB and wants to send that capability to VatC. This can be accomplished +# by VatA proxying requests on the new capability, but doing so has two big problems: +# - It's inefficient, requiring an extra network hop. +# - If VatC receives another capability to the same object from VatD, it is difficult for VatC to +# detect that the two capabilities are really the same and to implement the E "join" operation, +# which is necessary for certain four-or-more-party interactions, such as the escrow pattern. +# See: http://www.erights.org/elib/equality/grant-matcher/index.html +# +# Instead, we want a way for VatC to form a direct, authenticated connection to VatB. +# +# Join +# ---- +# +# **(level 4)** +# +# The `Join` message type and corresponding operation arranges for a direct connection to be formed +# between the joiner and the host of the joined object, and this connection must be authenticated. +# Thus, the details are network-dependent. + +using SturdyRef = AnyPointer; +# **(level 2)** +# +# Identifies a persisted capability that can be restored in the future. How exactly a SturdyRef +# is restored to a live object is specified along with the SturdyRef definition (i.e. not by +# rpc.capnp). +# +# Generally a SturdyRef needs to specify three things: +# - How to reach the vat that can restore the ref (e.g. a hostname or IP address). +# - How to authenticate the vat after connecting (e.g. a public key fingerprint). +# - The identity of a specific object hosted by the vat. Generally, this is an opaque pointer whose +# format is defined by the specific vat -- the client has no need to inspect the object ID. +# It is important that the objec ID be unguessable if the object is not public (and objects +# should almost never be public). +# +# The above are only suggestions. Some networks might work differently. For example, a private +# network might employ a special restorer service whose sole purpose is to restore SturdyRefs. +# In this case, the entire contents of SturdyRef might be opaque, because they are intended only +# to be forwarded to the restorer service. + +using ProvisionId = AnyPointer; +# **(level 3)** +# +# The information that must be sent in an `Accept` message to identify the object being accepted. +# +# In a network where each vat has a public/private key pair, this could simply be the public key +# fingerprint of the provider vat along with a nonce matching the one in the `RecipientId` used +# in the `Provide` message sent from that provider. + +using RecipientId = AnyPointer; +# **(level 3)** +# +# The information that must be sent in a `Provide` message to identify the recipient of the +# capability. +# +# In a network where each vat has a public/private key pair, this could simply be the public key +# fingerprint of the recipient along with a nonce matching the one in the `ProvisionId`. + +using ThirdPartyCapId = AnyPointer; +# **(level 3)** +# +# The information needed to connect to a third party and accept a capability from it. +# +# In a network where each vat has a public/private key pair, this could be a combination of the +# third party's public key fingerprint, hints on how to connect to the third party (e.g. an IP +# address), and the nonce used in the corresponding `Provide` message's `RecipientId` as sent +# to that third party (used to identify which capability to pick up). + +using JoinKeyPart = AnyPointer; +# **(level 4)** +# +# A piece of a secret key. One piece is sent along each path that is expected to lead to the same +# place. Once the pieces are combined, a direct connection may be formed between the sender and +# the receiver, bypassing any men-in-the-middle along the paths. See the `Join` message type. +# +# The motivation for Joins is discussed under "Supporting Equality" in the "Unibus" protocol +# sketch: http://www.erights.org/elib/distrib/captp/unibus.html +# +# In a network where each vat has a public/private key pair and each vat forms no more than one +# connection to each other vat, Joins will rarely -- perhaps never -- be needed, as objects never +# need to be transparently proxied and references to the same object sent over the same connection +# have the same export ID. Thus, a successful join requires only checking that the two objects +# come from the same connection and have the same ID, and then completes immediately. +# +# However, in networks where two vats may form more than one connection between each other, or +# where proxying of objects occurs, joins are necessary. +# +# Typically, each JoinKeyPart would include a fixed-length data value such that all value parts +# XOR'd together forms a shared secret that can be used to form an encrypted connection between +# the joiner and the joined object's host. Each JoinKeyPart should also include an indication of +# how many parts to expect and a hash of the shared secret (used to match up parts). + +using JoinResult = AnyPointer; +# **(level 4)** +# +# Information returned as the result to a `Join` message, needed by the joiner in order to form a +# direct connection to a joined object. This might simply be the address of the joined object's +# host vat, since the `JoinKey` has already been communicated so the two vats already have a shared +# secret to use to authenticate each other. +# +# The `JoinResult` should also contain information that can be used to detect when the Join +# requests ended up reaching different objects, so that this situation can be detected easily. +# This could be a simple matter of including a sequence number -- if the joiner receives two +# `JoinResult`s with sequence number 0, then they must have come from different objects and the +# whole join is a failure. + +# ======================================================================================== +# Network interface sketch +# +# The interfaces below are meant to be pseudo-code to illustrate how the details of a particular +# vat network might be abstracted away. They are written like Cap'n Proto interfaces, but in +# practice you'd probably define these interfaces manually in the target programming language. A +# Cap'n Proto RPC implementation should be able to use these interfaces without knowing the +# definitions of the various network-specific parameters defined above. + +# interface VatNetwork { +# # Represents a vat network, with the ability to connect to particular vats and receive +# # connections from vats. +# # +# # Note that methods returning a `Connection` may return a pre-existing `Connection`, and the +# # caller is expected to find and share state with existing users of the connection. +# +# # Level 0 features ----------------------------------------------- +# +# connect(vatId :VatId) :Connection; +# # Connect to the given vat. The transport should return a promise that does not +# # resolve until authentication has completed, but allows messages to be pipelined in before +# # that; the transport either queues these messages until authenticated, or sends them encrypted +# # such that only the authentic vat would be able to decrypt them. The latter approach avoids a +# # round trip for authentication. +# +# accept() :Connection; +# # Wait for the next incoming connection and return it. Only connections formed by +# # connect() are returned by this method. +# +# # Level 4 features ----------------------------------------------- +# +# newJoiner(count :UInt32) :NewJoinerResponse; +# # Prepare a new Join operation, which will eventually lead to forming a new direct connection +# # to the host of the joined capability. `count` is the number of capabilities to join. +# +# struct NewJoinerResponse { +# joinKeyParts :List(JoinKeyPart); +# # Key parts to send in Join messages to each capability. +# +# joiner :Joiner; +# # Used to establish the final connection. +# } +# +# interface Joiner { +# addJoinResult(result :JoinResult) :Void; +# # Add a JoinResult received in response to one of the `Join` messages. All `JoinResult`s +# # returned from all paths must be added before trying to connect. +# +# connect() :ConnectionAndProvisionId; +# # Try to form a connection to the joined capability's host, verifying that it has received +# # all of the JoinKeyParts. Once the connection is formed, the caller should send an `Accept` +# # message on it with the specified `ProvisionId` in order to receive the final capability. +# } +# +# acceptConnectionFromJoiner(parts :List(JoinKeyPart), paths :List(VatPath)) +# :ConnectionAndProvisionId; +# # Called on a joined capability's host to receive the connection from the joiner, once all +# # key parts have arrived. The caller should expect to receive an `Accept` message over the +# # connection with the given ProvisionId. +# } +# +# interface Connection { +# # Level 0 features ----------------------------------------------- +# +# send(message :Message) :Void; +# # Send the message. Returns successfully when the message (and all preceding messages) has +# # been acknowledged by the recipient. +# +# receive() :Message; +# # Receive the next message, and acknowledges receipt to the sender. Messages are received in +# # the order in which they are sent. +# +# # Level 3 features ----------------------------------------------- +# +# introduceTo(recipient :Connection) :IntroductionInfo; +# # Call before starting a three-way introduction, assuming a `Provide` message is to be sent on +# # this connection and a `ThirdPartyCapId` is to be sent to `recipient`. +# +# struct IntroductionInfo { +# sendToRecipient :ThirdPartyCapId; +# sendToTarget :RecipientId; +# } +# +# connectToIntroduced(capId :ThirdPartyCapId) :ConnectionAndProvisionId; +# # Given a ThirdPartyCapId received over this connection, connect to the third party. The +# # caller should then send an `Accept` message over the new connection. +# +# acceptIntroducedConnection(recipientId :RecipientId) :Connection; +# # Given a RecipientId received in a `Provide` message on this `Connection`, wait for the +# # recipient to connect, and return the connection formed. Usually, the first message received +# # on the new connection will be an `Accept` message. +# } +# +# struct ConnectionAndProvisionId { +# # **(level 3)** +# +# connection :Connection; +# # Connection on which to issue `Accept` message. +# +# provision :ProvisionId; +# # `ProvisionId` to send in the `Accept` message. +# } diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/schema-csharp.capnp b/CapnpC.CSharp.Generator.Tests/No Resources/schema-csharp.capnp new file mode 100644 index 0000000..05a6edc --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/schema-csharp.capnp @@ -0,0 +1,537 @@ +# Copyright (c) 2020 Christian Köllner and contributors +# This is a modified version of schema.capnp, found in the original distribution +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xa93fc509624c72d9; +# $$embed +# #pragma warning disable CS1591 + +using CSharp = import "/csharp.capnp"; +$CSharp.namespace("CapnpC.CSharp.Generator.Schema"); +$CSharp.nullableEnable(false); +$CSharp.emitNullableDirective(false); +$CSharp.emitDomainClassesAndInterfaces(true); +$CSharp.typeVisibility(public); + +using Id = UInt64; +# The globally-unique ID of a file, type, or annotation. + +struct Node { + id @0 :Id; + + displayName @1 :Text; + # Name to present to humans to identify this Node. You should not attempt to parse this. Its + # format could change. It is not guaranteed to be unique. + # + # (On Zooko's triangle, this is the node's nickname.) + + displayNamePrefixLength @2 :UInt32; + # If you want a shorter version of `displayName` (just naming this node, without its surrounding + # scope), chop off this many characters from the beginning of `displayName`. + + scopeId @3 :Id; + # ID of the lexical parent node. Typically, the scope node will have a NestedNode pointing back + # at this node, but robust code should avoid relying on this (and, in fact, group nodes are not + # listed in the outer struct's nestedNodes, since they are listed in the fields). `scopeId` is + # zero if the node has no parent, which is normally only the case with files, but should be + # allowed for any kind of node (in order to make runtime type generation easier). + + parameters @32 :List(Parameter); + # If this node is parameterized (generic), the list of parameters. Empty for non-generic types. + + isGeneric @33 :Bool; + # True if this node is generic, meaning that it or one of its parent scopes has a non-empty + # `parameters`. + + struct Parameter { + # Information about one of the node's parameters. + + name @0 :Text; + } + + nestedNodes @4 :List(NestedNode); + # List of nodes nested within this node, along with the names under which they were declared. + + struct NestedNode { + name @0 :Text; + # Unqualified symbol name. Unlike Node.displayName, this *can* be used programmatically. + # + # (On Zooko's triangle, this is the node's petname according to its parent scope.) + + id @1 :Id; + # ID of the nested node. Typically, the target node's scopeId points back to this node, but + # robust code should avoid relying on this. + } + + annotations @5 :List(Annotation); + # Annotations applied to this node. + + union { + # Info specific to each kind of node. + + file @6 :Void; + + struct :group { + dataWordCount @7 :UInt16; + # Size of the data section, in words. + + pointerCount @8 :UInt16; + # Size of the pointer section, in pointers (which are one word each). + + preferredListEncoding @9 :ElementSize; + # The preferred element size to use when encoding a list of this struct. If this is anything + # other than `inlineComposite` then the struct is one word or less in size and is a candidate + # for list packing optimization. + + isGroup @10 :Bool; + # If true, then this "struct" node is actually not an independent node, but merely represents + # some named union or group within a particular parent struct. This node's scopeId refers + # to the parent struct, which may itself be a union/group in yet another struct. + # + # All group nodes share the same dataWordCount and pointerCount as the top-level + # struct, and their fields live in the same ordinal and offset spaces as all other fields in + # the struct. + # + # Note that a named union is considered a special kind of group -- in fact, a named union + # is exactly equivalent to a group that contains nothing but an unnamed union. + + discriminantCount @11 :UInt16; + # Number of fields in this struct which are members of an anonymous union, and thus may + # overlap. If this is non-zero, then a 16-bit discriminant is present indicating which + # of the overlapping fields is active. This can never be 1 -- if it is non-zero, it must be + # two or more. + # + # Note that the fields of an unnamed union are considered fields of the scope containing the + # union -- an unnamed union is not its own group. So, a top-level struct may contain a + # non-zero discriminant count. Named unions, on the other hand, are equivalent to groups + # containing unnamed unions. So, a named union has its own independent schema node, with + # `isGroup` = true. + + discriminantOffset @12 :UInt32; + # If `discriminantCount` is non-zero, this is the offset of the union discriminant, in + # multiples of 16 bits. + + fields @13 :List(Field); + # Fields defined within this scope (either the struct's top-level fields, or the fields of + # a particular group; see `isGroup`). + # + # The fields are sorted by ordinal number, but note that because groups share the same + # ordinal space, the field's index in this list is not necessarily exactly its ordinal. + # On the other hand, the field's position in this list does remain the same even as the + # protocol evolves, since it is not possible to insert or remove an earlier ordinal. + # Therefore, for most use cases, if you want to identify a field by number, it may make the + # most sense to use the field's index in this list rather than its ordinal. + } + + enum :group { + enumerants@14 :List(Enumerant); + # Enumerants ordered by numeric value (ordinal). + } + + interface :group { + methods @15 :List(Method); + # Methods ordered by ordinal. + + superclasses @31 :List(Superclass); + # Superclasses of this interface. + } + + const :group { + type @16 :Type; + value @17 :Value; + } + + annotation :group { + type @18 :Type; + + targetsFile @19 :Bool; + targetsConst @20 :Bool; + targetsEnum @21 :Bool; + targetsEnumerant @22 :Bool; + targetsStruct @23 :Bool; + targetsField @24 :Bool; + targetsUnion @25 :Bool; + targetsGroup @26 :Bool; + targetsInterface @27 :Bool; + targetsMethod @28 :Bool; + targetsParam @29 :Bool; + targetsAnnotation @30 :Bool; + } + } + + struct SourceInfo { + # Additional information about a node which is not needed at runtime, but may be useful for + # documentation or debugging purposes. This is kept in a separate struct to make sure it + # doesn't accidentally get included in contexts where it is not needed. The + # `CodeGeneratorRequest` includes this information in a separate array. + + id @0 :Id; + # ID of the Node which this info describes. + + docComment @1 :Text; + # The top-level doc comment for the Node. + + members @2 :List(Member); + # Information about each member -- i.e. fields (for structs), enumerants (for enums), or + # methods (for interfaces). + # + # This list is the same length and order as the corresponding list in the Node, i.e. + # Node.struct.fields, Node.enum.enumerants, or Node.interface.methods. + + struct Member { + docComment @0 :Text; + # Doc comment on the member. + } + + # TODO(someday): Record location of the declaration in the original source code. + } +} + +struct Field { + # Schema for a field of a struct. + + name @0 :Text; + + codeOrder @1 :UInt16; + # Indicates where this member appeared in the code, relative to other members. + # Code ordering may have semantic relevance -- programmers tend to place related fields + # together. So, using code ordering makes sense in human-readable formats where ordering is + # otherwise irrelevant, like JSON. The values of codeOrder are tightly-packed, so the maximum + # value is count(members) - 1. Fields that are members of a union are only ordered relative to + # the other members of that union, so the maximum value there is count(union.members). + + annotations @2 :List(Annotation); + + const noDiscriminant :UInt16 = 0xffff; + + discriminantValue @3 :UInt16 = Field.noDiscriminant; + # If the field is in a union, this is the value which the union's discriminant should take when + # the field is active. If the field is not in a union, this is 0xffff. + + union { + slot :group { + # A regular, non-group, non-fixed-list field. + + offset @4 :UInt32; + # Offset, in units of the field's size, from the beginning of the section in which the field + # resides. E.g. for a UInt32 field, multiply this by 4 to get the byte offset from the + # beginning of the data section. + + type @5 :Type; + defaultValue @6 :Value; + + hadExplicitDefault @10 :Bool; + # Whether the default value was specified explicitly. Non-explicit default values are always + # zero or empty values. Usually, whether the default value was explicit shouldn't matter. + # The main use case for this flag is for structs representing method parameters: + # explicitly-defaulted parameters may be allowed to be omitted when calling the method. + } + + group :group { + # A group. + + typeId @7 :Id; + # The ID of the group's node. + } + } + + ordinal :union { + implicit @8 :Void; + explicit @9 :UInt16; + # The original ordinal number given to the field. You probably should NOT use this; if you need + # a numeric identifier for a field, use its position within the field array for its scope. + # The ordinal is given here mainly just so that the original schema text can be reproduced given + # the compiled version -- i.e. so that `capnp compile -ocapnp` can do its job. + } +} + +struct Enumerant { + # Schema for member of an enum. + + name @0 :Text; + + codeOrder @1 :UInt16; + # Specifies order in which the enumerants were declared in the code. + # Like Struct.Field.codeOrder. + + annotations @2 :List(Annotation); +} + +struct Superclass { + id @0 :Id; + brand @1 :Brand; +} + +struct Method { + # Schema for method of an interface. + + name @0 :Text; + + codeOrder @1 :UInt16; + # Specifies order in which the methods were declared in the code. + # Like Struct.Field.codeOrder. + + implicitParameters @7 :List(Node.Parameter); + # The parameters listed in [] (typically, type / generic parameters), whose bindings are intended + # to be inferred rather than specified explicitly, although not all languages support this. + + paramStructType @2 :Id; + # ID of the parameter struct type. If a named parameter list was specified in the method + # declaration (rather than a single struct parameter type) then a corresponding struct type is + # auto-generated. Such an auto-generated type will not be listed in the interface's + # `nestedNodes` and its `scopeId` will be zero -- it is completely detached from the namespace. + # (Awkwardly, it does of course inherit generic parameters from the method's scope, which makes + # this a situation where you can't just climb the scope chain to find where a particular + # generic parameter was introduced. Making the `scopeId` zero was a mistake.) + + paramBrand @5 :Brand; + # Brand of param struct type. + + resultStructType @3 :Id; + # ID of the return struct type; similar to `paramStructType`. + + resultBrand @6 :Brand; + # Brand of result struct type. + + annotations @4 :List(Annotation); +} + +struct Type { + # Represents a type expression. + + union { + # The ordinals intentionally match those of Value. + + void @0 :Void; + bool @1 :Void; + int8 @2 :Void; + int16 @3 :Void; + int32 @4 :Void; + int64 @5 :Void; + uint8 @6 :Void; + uint16 @7 :Void; + uint32 @8 :Void; + uint64 @9 :Void; + float32 @10 :Void; + float64 @11 :Void; + text @12 :Void; + data @13 :Void; + + list :group { + elementType @14 :Type; + } + + enum :group { + typeId @15 :Id; + brand @21 :Brand; + } + struct :group { + typeId @16 :Id; + brand @22 :Brand; + } + interface :group { + typeId @17 :Id; + brand @23 :Brand; + } + + anyPointer :union { + unconstrained :union { + # A regular AnyPointer. + # + # The name "unconstrained" means as opposed to constraining it to match a type parameter. + # In retrospect this name is probably a poor choice given that it may still be constrained + # to be a struct, list, or capability. + + anyKind @18 :Void; # truly AnyPointer + struct @25 :Void; # AnyStruct + list @26 :Void; # AnyList + capability @27 :Void; # Capability + } + + parameter :group { + # This is actually a reference to a type parameter defined within this scope. + + scopeId @19 :Id; + # ID of the generic type whose parameter we're referencing. This should be a parent of the + # current scope. + + parameterIndex @20 :UInt16; + # Index of the parameter within the generic type's parameter list. + } + + implicitMethodParameter :group { + # This is actually a reference to an implicit (generic) parameter of a method. The only + # legal context for this type to appear is inside Method.paramBrand or Method.resultBrand. + + parameterIndex @24 :UInt16; + } + } + } +} + +struct Brand { + # Specifies bindings for parameters of generics. Since these bindings turn a generic into a + # non-generic, we call it the "brand". + + scopes @0 :List(Scope); + # For each of the target type and each of its parent scopes, a parameterization may be included + # in this list. If no parameterization is included for a particular relevant scope, then either + # that scope has no parameters or all parameters should be considered to be `AnyPointer`. + + struct Scope { + scopeId @0 :Id; + # ID of the scope to which these params apply. + + union { + bind @1 :List(Binding); + # List of parameter bindings. + + inherit @2 :Void; + # The place where this Brand appears is actually within this scope or a sub-scope, + # and the bindings for this scope should be inherited from the reference point. + } + } + + struct Binding { + union { + unbound @0 :Void; + type @1 :Type; + + # TODO(someday): Allow non-type parameters? Unsure if useful. + } + } +} + +struct Value { + # Represents a value, e.g. a field default value, constant value, or annotation value. + + union { + # The ordinals intentionally match those of Type. + + void @0 :Void; + bool @1 :Bool; + int8 @2 :Int8; + int16 @3 :Int16; + int32 @4 :Int32; + int64 @5 :Int64; + uint8 @6 :UInt8; + uint16 @7 :UInt16; + uint32 @8 :UInt32; + uint64 @9 :UInt64; + float32 @10 :Float32; + float64 @11 :Float64; + text @12 :Text; + data @13 :Data; + + list @14 :AnyPointer; + + enum @15 :UInt16; + struct @16 :AnyPointer; + + interface @17 :Void; + # The only interface value that can be represented statically is "null", whose methods always + # throw exceptions. + + anyPointer @18 :AnyPointer; + } +} + +struct Annotation { + # Describes an annotation applied to a declaration. Note AnnotationNode describes the + # annotation's declaration, while this describes a use of the annotation. + + id @0 :Id; + # ID of the annotation node. + + brand @2 :Brand; + # Brand of the annotation. + # + # Note that the annotation itself is not allowed to be parameterized, but its scope might be. + + value @1 :Value; +} + +enum ElementSize { + # Possible element sizes for encoded lists. These correspond exactly to the possible values of + # the 3-bit element size component of a list pointer. + + empty @0; # aka "void", but that's a keyword. + bit @1; + byte @2; + twoBytes @3; + fourBytes @4; + eightBytes @5; + pointer @6; + inlineComposite @7; +} + +struct CapnpVersion { + major @0 :UInt16; + minor @1 :UInt8; + micro @2 :UInt8; +} + +struct CodeGeneratorRequest { + capnpVersion @2 :CapnpVersion; + # Version of the `capnp` executable. Generally, code generators should ignore this, but the code + # generators that ship with `capnp` itself will print a warning if this mismatches since that + # probably indicates something is misconfigured. + # + # The first version of 'capnp' to set this was 0.6.0. So, if it's missing, the compiler version + # is older than that. + + nodes @0 :List(Node); + # All nodes parsed by the compiler, including for the files on the command line and their + # imports. + + sourceInfo @3 :List(Node.SourceInfo); + # Information about the original source code for each node, where available. This array may be + # omitted or may be missing some nodes if no info is available for them. + + requestedFiles @1 :List(RequestedFile); + # Files which were listed on the command line. + + struct RequestedFile { + id @0 :Id; + # ID of the file. + + filename @1 :Text; + # Name of the file as it appeared on the command-line (minus the src-prefix). You may use + # this to decide where to write the output. + + imports @2 :List(Import); + # List of all imported paths seen in this file. + + struct Import { + id @0 :Id; + # ID of the imported file. + + name @1 :Text; + # Name which *this* file used to refer to the foreign file. This may be a relative name. + # This information is provided because it might be useful for code generation, e.g. to + # generate #include directives in C++. We don't put this in Node.file because this + # information is only meaningful at compile time anyway. + # + # (On Zooko's triangle, this is the import's petname according to the importing file.) + } + } +} diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/test.capnp b/CapnpC.CSharp.Generator.Tests/No Resources/test.capnp index 0a4a507..d68c71c 100644 --- a/CapnpC.CSharp.Generator.Tests/No Resources/test.capnp +++ b/CapnpC.CSharp.Generator.Tests/No Resources/test.capnp @@ -21,7 +21,7 @@ @0xd508eebdc2dc42b8; -using Cxx = import "c++.capnp"; +using Cxx = import "/capnp/c++.capnp"; # Use a namespace likely to cause trouble if the generated code doesn't use fully-qualified # names for stuff in the capnproto namespace. diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/annotated-json.binary b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/annotated-json.binary new file mode 100644 index 0000000..6c54755 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/annotated-json.binary differ diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/annotated.json b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/annotated.json new file mode 100644 index 0000000..bb51400 --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/annotated.json @@ -0,0 +1,22 @@ +{ "names-can_contain!anything Really": "foo", + "flatFoo": 123, + "flatBar": "abc", + "renamed-flatBaz": {"hello": true}, + "flatQux": "cba", + "pfx.foo": "this is a long string in order to force multi-line pretty printing", + "pfx.renamed-bar": 321, + "pfx.baz": {"hello": true}, + "pfx.xfp.qux": "fed", + "union-type": "renamed-bar", + "barMember": 789, + "multiMember": "ghi", + "dependency": {"renamed-foo": "corge"}, + "simpleGroup": {"renamed-grault": "garply"}, + "enums": ["qux", "renamed-bar", "foo", "renamed-baz"], + "innerJson": [123, "hello", {"object": true}], + "testBase64": "ZnJlZA==", + "testHex": "706c756768", + "bUnion": "renamed-bar", + "bValue": 678, + "externalUnion": {"type": "bar", "value": "cba"}, + "unionWithVoid": {"type": "voidValue"} } diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/binary b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/binary new file mode 100644 index 0000000..ea39763 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/binary differ diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/errors.capnp.nobuild b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/errors.capnp.nobuild new file mode 100644 index 0000000..a909e97 --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/errors.capnp.nobuild @@ -0,0 +1,161 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# This file is intended to test that various error cases are detected as errors. The error +# output is matched against a golden file. The file name has the .nobuild extension to make +# sure that a build system which automatically builds .capnp files does not try to build this one. + +# + +@0xccd0890aa4926a9b; +# Can't really test the missing-ID error because the output is intentionally unpredictable. + +const notType :Int32 = 123; +annotation notFieldAnnotation(struct) :Int32; +annotation fieldAnnotation(field) :Int32; + +struct Foo { + dupName @0 :Int32; + dupName @1 :Int32; + dupNumber1 @2 :Int32; + dupNumber2 @2 :Int32; + + missingNumber @4 :Int32; + next @5 :Int32; + + emptyUnion :union {} + emptyGroup :group {} + + singletonUnion :union { + field @6 :Int32; + } + + union { + dupName @7 :Int32; + f8 @8 :Int32; + } + union { + f9 @9 :Int32; + f10 @10 :Int32; + } + + struct wrongTypeStyle {} + WrongFieldStyle @11 :Int32; + under_score @12 :Int32; + + containsStruct :group { + f13 @13 :Int32; + struct CantNestHere {} + } + + retroUnion @16! :union { + f14 @14 :Int32; + f15 @15 :Int32; + } + + missingColonAndEclamation @18 union { + f19 @19 :Int32; + f20 @20 :Int32; + } + + missingExclamation @21 :union { + f22 @22 :Int32; + f23 @23 :Int32; + } + + missingColon @24! union { + f19 @25 :Int32; + f20 @26 :Int32; + } + + unnamedInNamed :union { + f27 @27 :Int32; + f28 @28 :Int32; + union { + # content is ignored + } + } + + listWithoutParam @31 :List; + listWithTooManyParams @32 :List(Int32, Int64); + listAnyPointer @33 :List(AnyPointer); + notAType @34 :notType; + noParams @35 :Foo(Int32); + + defaultOutOfRange @36 :Int16 = 1234567; + defaultOutOfRange2 @37 :UInt16 = -1; + defaultWrongType @38 :Text = 123; + defaultWrongType2 @39 :Text = [123]; + defaultWrongType3 @40 :Text = (foo = 123, bar = 456); + defaultTooBigToBeNegative @41 :Int64 = -0x8000000000000001; + defaultNotConstant @42 :Int32 = .Foo; + defaultConstantNotQualified @43 :Int32 = notType; + + notAnnotation @44 :Int32 $Foo(123); + badAnnotation @45 :Int32 $notFieldAnnotation(123); + notVoidAnnotation @46 :Int32 $fieldAnnotation; + + undefinedImport @17 :import "noshuchfile.capnp".Bar; + undefinedAbsolute @47 : .NoSuch; + undefinedRelative @29 :NoSuch; + undefinedMember @30 :Foo.NoSuch; +} + +struct Bar { + x @3 :Text; + someGroup :group { + defaultMissingFieldName @2 :Bar = (x = "abcd", 456); + defaultNoSuchField @0 :Bar = (nosuchfield = 123); + defaultGroupMismatch @1 :Bar = (someGroup = 123); + } +} + + +using Bar; + +enum DupEnumerants { + dupName @0; + dupName @1; + dupNumber1 @2; + dupNumber2 @2; +} + +const recursive: UInt32 = .recursive; + +struct Generic(T, U) { +} + +struct UseGeneric { + tooFew @0 :Generic(Text); + tooMany @1 :Generic(Text, Data, List(Int32)); + doubleBind @2 :Generic(Text, Data)(Data, Text); + primitiveBinding @3 :Generic(Text, Int32); +} + +const embedBadType :UInt32 = embed "binary"; +const embedNoSuchFile :Data = embed "no-such-file"; + +using Baz = import "nosuchfile-unused.capnp".Baz; +# Check that an import in an unused `using` still reports error. + +interface TestInterface { + foo @0 (a :UInt32 = null); +} diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/errors.txt b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/errors.txt new file mode 100644 index 0000000..ed238e4 --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/errors.txt @@ -0,0 +1,60 @@ +file:74:30-32: error: As of Cap'n Proto v0.3, it is no longer necessary to assign numbers to unions. However, removing the number will break binary compatibility. If this is an old protocol and you need to retain compatibility, please add an exclamation point after the number to indicate that it is really needed, e.g. `foo @1! :union {`. If this is a new protocol or compatibility doesn't matter, just remove the @n entirely. Sorry for the inconvenience, and thanks for being an early adopter! :) +file:74:30-32: error: As of Cap'n Proto v0.3, the 'union' keyword should be prefixed with a colon for named unions, e.g. `foo :union {`. +file:79:23-25: error: As of Cap'n Proto v0.3, it is no longer necessary to assign numbers to unions. However, removing the number will break binary compatibility. If this is an old protocol and you need to retain compatibility, please add an exclamation point after the number to indicate that it is really needed, e.g. `foo @1! :union {`. If this is a new protocol or compatibility doesn't matter, just remove the @n entirely. Sorry for the inconvenience, and thanks for being an early adopter! :) +file:84:17-19: error: As of Cap'n Proto v0.3, the 'union' keyword should be prefixed with a colon for named unions, e.g. `foo :union {`. +file:132:7-10: error: 'using' declaration without '=' must specify a named declaration from a different scope. +file:37:3-10: error: 'dupName' is already defined in this scope. +file:36:3-10: error: 'dupName' previously defined here. +file:52:5-12: error: 'dupName' is already defined in this scope. +file:36:3-10: error: 'dupName' previously defined here. +file:55:3-8: error: An unnamed union is already defined in this scope. +file:51:3-8: error: Previously defined here. +file:60:10-24: error: Type names must begin with a capital letter. +file:61:3-18: error: Non-type names must begin with a lower-case letter. +file:62:3-14: error: Cap'n Proto declaration names should use camelCase and must not contain underscores. (Code generators may convert names to the appropriate style for the target language.) +file:66:5-27: error: This kind of declaration doesn't belong here. +file:44:3-23: error: Union must have at least two members. +file:45:3-23: error: Group must have at least one member. +file:47: error: Union must have at least two members. +file:92: error: Unions cannot contain unnamed unions. +file:39:15-16: error: Duplicate ordinal number. +file:38:15-16: error: Ordinal @2 originally used here. +file:41:18-19: error: Skipped ordinal @3. Ordinals must be sequential with no holes. +file:69:15-17: error: Union ordinal, if specified, must be greater than no more than one of its member ordinals (i.e. there can only be one field retroactively unionized). +file:116:31-50: error: Import failed: noshuchfile.capnp +file:118:26-32: error: Not defined: NoSuch +file:119:28-34: error: 'Foo' has no member named 'NoSuch' +file:97:25-29: error: 'List' requires exactly one parameter. +file:98:30-48: error: Too many generic parameters. +file:98:30-34: error: 'List' requires exactly one parameter. +file:99:23-39: error: 'List(AnyPointer)' is not supported. +file:100:17-24: error: 'notType' is not a type. +file:101:17-27: error: Declaration does not accept generic parameters. +file:103:34-41: error: Integer value out of range. +file:104:37-38: error: Integer value out of range. +file:105:32-35: error: Type mismatch; expected Text. +file:106:33-38: error: Type mismatch; expected Text. +file:107:33-55: error: Type mismatch; expected Text. +file:108:43-61: error: Integer is too big to be negative. +file:109:35-39: error: '.Foo' does not refer to a constant. +file:110:44-51: error: Constant names must be qualified to avoid confusion. Please replace 'notType' with '.notType', if that's what you intended. +file:117:28-34: error: Not defined: NoSuch +file:112:29-32: error: 'Foo' is not an annotation. +file:113:29-47: error: 'notFieldAnnotation' cannot be applied to this kind of declaration. +file:114:33-48: error: 'fieldAnnotation' requires a value. +file:126:35-46: error: Struct has no field named 'nosuchfield'. +file:127:49-52: error: Type mismatch; expected group. +file:125:52-55: error: Missing field name. +file:136:3-10: error: 'dupName' is already defined in this scope. +file:135:3-10: error: 'dupName' previously defined here. +file:138:15-16: error: Duplicate ordinal number. +file:137:15-16: error: Ordinal @2 originally used here. +file:141:7-16: error: Declaration recursively depends on itself. +file:147:14-27: error: Not enough generic parameters. +file:148:15-47: error: Too many generic parameters. +file:149:18-49: error: Double-application of generic parameters. +file:150:38-43: error: Sorry, only pointer types can be used as generic parameters. +file:153:30-44: error: Embeds can only be used when Text, Data, or a struct is expected. +file:154:37-51: error: Couldn't read file for embed: no-such-file +file:160:23-27: error: Only pointer parameters can declare their default as 'null'. +file:156:20-45: error: Import failed: nosuchfile-unused.capnp diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/flat b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/flat new file mode 100644 index 0000000..427fc31 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/flat differ diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/lists.binary b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/lists.binary new file mode 100644 index 0000000..30ae630 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/lists.binary differ diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/packed b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/packed new file mode 100644 index 0000000..8627833 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/packed differ diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/packedflat b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/packedflat new file mode 100644 index 0000000..7c304a9 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/packedflat differ diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/pretty.json b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/pretty.json new file mode 100644 index 0000000..abf82d6 --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/pretty.json @@ -0,0 +1,88 @@ +{ "voidField": null, + "boolField": true, + "int8Field": -123, + "int16Field": -12345, + "int32Field": -12345678, + "int64Field": "-123456789012345", + "uInt8Field": 234, + "uInt16Field": 45678, + "uInt32Field": 3456789012, + "uInt64Field": "12345678901234567890", + "float32Field": 1234.5, + "float64Field": -1.23e47, + "textField": "foo", + "dataField": [98, 97, 114], + "structField": { + "voidField": null, + "boolField": true, + "int8Field": -12, + "int16Field": 3456, + "int32Field": -78901234, + "int64Field": "56789012345678", + "uInt8Field": 90, + "uInt16Field": 1234, + "uInt32Field": 56789012, + "uInt64Field": "345678901234567890", + "float32Field": -1.2499999646475857e-10, + "float64Field": 345, + "textField": "baz", + "dataField": [113, 117, 120], + "structField": { + "voidField": null, + "boolField": false, + "int8Field": 0, + "int16Field": 0, + "int32Field": 0, + "int64Field": "0", + "uInt8Field": 0, + "uInt16Field": 0, + "uInt32Field": 0, + "uInt64Field": "0", + "float32Field": 0, + "float64Field": 0, + "textField": "nested", + "structField": {"voidField": null, "boolField": false, "int8Field": 0, "int16Field": 0, "int32Field": 0, "int64Field": "0", "uInt8Field": 0, "uInt16Field": 0, "uInt32Field": 0, "uInt64Field": "0", "float32Field": 0, "float64Field": 0, "textField": "really nested", "enumField": "foo", "interfaceField": null}, + "enumField": "foo", + "interfaceField": null }, + "enumField": "baz", + "interfaceField": null, + "voidList": [null, null, null], + "boolList": [false, true, false, true, true], + "int8List": [12, -34, -128, 127], + "int16List": [1234, -5678, -32768, 32767], + "int32List": [12345678, -90123456, -2147483648, 2147483647], + "int64List": ["123456789012345", "-678901234567890", "-9223372036854775808", "9223372036854775807"], + "uInt8List": [12, 34, 0, 255], + "uInt16List": [1234, 5678, 0, 65535], + "uInt32List": [12345678, 90123456, 0, 4294967295], + "uInt64List": ["123456789012345", "678901234567890", "0", "18446744073709551615"], + "float32List": [0, 1234567, 9.9999999338158125e36, -9.9999999338158125e36, 9.99999991097579e-38, -9.99999991097579e-38], + "float64List": [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306], + "textList": ["quux", "corge", "grault"], + "dataList": [[103, 97, 114, 112, 108, 121], [119, 97, 108, 100, 111], [102, 114, 101, 100]], + "structList": [ + {"voidField": null, "boolField": false, "int8Field": 0, "int16Field": 0, "int32Field": 0, "int64Field": "0", "uInt8Field": 0, "uInt16Field": 0, "uInt32Field": 0, "uInt64Field": "0", "float32Field": 0, "float64Field": 0, "textField": "x structlist 1", "enumField": "foo", "interfaceField": null}, + {"voidField": null, "boolField": false, "int8Field": 0, "int16Field": 0, "int32Field": 0, "int64Field": "0", "uInt8Field": 0, "uInt16Field": 0, "uInt32Field": 0, "uInt64Field": "0", "float32Field": 0, "float64Field": 0, "textField": "x structlist 2", "enumField": "foo", "interfaceField": null}, + {"voidField": null, "boolField": false, "int8Field": 0, "int16Field": 0, "int32Field": 0, "int64Field": "0", "uInt8Field": 0, "uInt16Field": 0, "uInt32Field": 0, "uInt64Field": "0", "float32Field": 0, "float64Field": 0, "textField": "x structlist 3", "enumField": "foo", "interfaceField": null} ], + "enumList": ["qux", "bar", "grault"] }, + "enumField": "corge", + "interfaceField": null, + "voidList": [null, null, null, null, null, null], + "boolList": [true, false, false, true], + "int8List": [111, -111], + "int16List": [11111, -11111], + "int32List": [111111111, -111111111], + "int64List": ["1111111111111111111", "-1111111111111111111"], + "uInt8List": [111, 222], + "uInt16List": [33333, 44444], + "uInt32List": [3333333333], + "uInt64List": ["11111111111111111111"], + "float32List": [5555.5, "Infinity", "-Infinity", "NaN"], + "float64List": [7777.75, "Infinity", "-Infinity", "NaN"], + "textList": ["plugh", "xyzzy", "thud"], + "dataList": [[111, 111, 112, 115], [101, 120, 104, 97, 117, 115, 116, 101, 100], [114, 102, 99, 51, 48, 57, 50]], + "structList": [ + {"voidField": null, "boolField": false, "int8Field": 0, "int16Field": 0, "int32Field": 0, "int64Field": "0", "uInt8Field": 0, "uInt16Field": 0, "uInt32Field": 0, "uInt64Field": "0", "float32Field": 0, "float64Field": 0, "textField": "structlist 1", "enumField": "foo", "interfaceField": null}, + {"voidField": null, "boolField": false, "int8Field": 0, "int16Field": 0, "int32Field": 0, "int64Field": "0", "uInt8Field": 0, "uInt16Field": 0, "uInt32Field": 0, "uInt64Field": "0", "float32Field": 0, "float64Field": 0, "textField": "structlist 2", "enumField": "foo", "interfaceField": null}, + {"voidField": null, "boolField": false, "int8Field": 0, "int16Field": 0, "int32Field": 0, "int64Field": "0", "uInt8Field": 0, "uInt16Field": 0, "uInt32Field": 0, "uInt64Field": "0", "float32Field": 0, "float64Field": 0, "textField": "structlist 3", "enumField": "foo", "interfaceField": null} ], + "enumList": ["foo", "garply"] } diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/pretty.txt b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/pretty.txt new file mode 100644 index 0000000..079ff8d --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/pretty.txt @@ -0,0 +1,187 @@ +( voidField = void, + boolField = true, + int8Field = -123, + int16Field = -12345, + int32Field = -12345678, + int64Field = -123456789012345, + uInt8Field = 234, + uInt16Field = 45678, + uInt32Field = 3456789012, + uInt64Field = 12345678901234567890, + float32Field = 1234.5, + float64Field = -1.23e47, + textField = "foo", + dataField = "bar", + structField = ( + voidField = void, + boolField = true, + int8Field = -12, + int16Field = 3456, + int32Field = -78901234, + int64Field = 56789012345678, + uInt8Field = 90, + uInt16Field = 1234, + uInt32Field = 56789012, + uInt64Field = 345678901234567890, + float32Field = -1.25e-10, + float64Field = 345, + textField = "baz", + dataField = "qux", + structField = ( + voidField = void, + boolField = false, + int8Field = 0, + int16Field = 0, + int32Field = 0, + int64Field = 0, + uInt8Field = 0, + uInt16Field = 0, + uInt32Field = 0, + uInt64Field = 0, + float32Field = 0, + float64Field = 0, + textField = "nested", + structField = ( + voidField = void, + boolField = false, + int8Field = 0, + int16Field = 0, + int32Field = 0, + int64Field = 0, + uInt8Field = 0, + uInt16Field = 0, + uInt32Field = 0, + uInt64Field = 0, + float32Field = 0, + float64Field = 0, + textField = "really nested", + enumField = foo, + interfaceField = void ), + enumField = foo, + interfaceField = void ), + enumField = baz, + interfaceField = void, + voidList = [void, void, void], + boolList = [false, true, false, true, true], + int8List = [12, -34, -128, 127], + int16List = [1234, -5678, -32768, 32767], + int32List = [12345678, -90123456, -2147483648, 2147483647], + int64List = [123456789012345, -678901234567890, -9223372036854775808, 9223372036854775807], + uInt8List = [12, 34, 0, 255], + uInt16List = [1234, 5678, 0, 65535], + uInt32List = [12345678, 90123456, 0, 4294967295], + uInt64List = [123456789012345, 678901234567890, 0, 18446744073709551615], + float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37], + float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306], + textList = ["quux", "corge", "grault"], + dataList = ["garply", "waldo", "fred"], + structList = [ + ( voidField = void, + boolField = false, + int8Field = 0, + int16Field = 0, + int32Field = 0, + int64Field = 0, + uInt8Field = 0, + uInt16Field = 0, + uInt32Field = 0, + uInt64Field = 0, + float32Field = 0, + float64Field = 0, + textField = "x structlist 1", + enumField = foo, + interfaceField = void ), + ( voidField = void, + boolField = false, + int8Field = 0, + int16Field = 0, + int32Field = 0, + int64Field = 0, + uInt8Field = 0, + uInt16Field = 0, + uInt32Field = 0, + uInt64Field = 0, + float32Field = 0, + float64Field = 0, + textField = "x structlist 2", + enumField = foo, + interfaceField = void ), + ( voidField = void, + boolField = false, + int8Field = 0, + int16Field = 0, + int32Field = 0, + int64Field = 0, + uInt8Field = 0, + uInt16Field = 0, + uInt32Field = 0, + uInt64Field = 0, + float32Field = 0, + float64Field = 0, + textField = "x structlist 3", + enumField = foo, + interfaceField = void ) ], + enumList = [qux, bar, grault] ), + enumField = corge, + interfaceField = void, + voidList = [void, void, void, void, void, void], + boolList = [true, false, false, true], + int8List = [111, -111], + int16List = [11111, -11111], + int32List = [111111111, -111111111], + int64List = [1111111111111111111, -1111111111111111111], + uInt8List = [111, 222], + uInt16List = [33333, 44444], + uInt32List = [3333333333], + uInt64List = [11111111111111111111], + float32List = [5555.5, inf, -inf, nan], + float64List = [7777.75, inf, -inf, nan], + textList = ["plugh", "xyzzy", "thud"], + dataList = ["oops", "exhausted", "rfc3092"], + structList = [ + ( voidField = void, + boolField = false, + int8Field = 0, + int16Field = 0, + int32Field = 0, + int64Field = 0, + uInt8Field = 0, + uInt16Field = 0, + uInt32Field = 0, + uInt64Field = 0, + float32Field = 0, + float64Field = 0, + textField = "structlist 1", + enumField = foo, + interfaceField = void ), + ( voidField = void, + boolField = false, + int8Field = 0, + int16Field = 0, + int32Field = 0, + int64Field = 0, + uInt8Field = 0, + uInt16Field = 0, + uInt32Field = 0, + uInt64Field = 0, + float32Field = 0, + float64Field = 0, + textField = "structlist 2", + enumField = foo, + interfaceField = void ), + ( voidField = void, + boolField = false, + int8Field = 0, + int16Field = 0, + int32Field = 0, + int64Field = 0, + uInt8Field = 0, + uInt16Field = 0, + uInt32Field = 0, + uInt64Field = 0, + float32Field = 0, + float64Field = 0, + textField = "structlist 3", + enumField = foo, + interfaceField = void ) ], + enumList = [foo, garply] ) diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/segmented b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/segmented new file mode 100644 index 0000000..c2840b4 Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/segmented differ diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/segmented-packed b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/segmented-packed new file mode 100644 index 0000000..c4a968e Binary files /dev/null and b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/segmented-packed differ diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/short.json b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/short.json new file mode 100644 index 0000000..26cbfd0 --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/short.json @@ -0,0 +1 @@ +{"voidField":null,"boolField":true,"int8Field":-123,"int16Field":-12345,"int32Field":-12345678,"int64Field":"-123456789012345","uInt8Field":234,"uInt16Field":45678,"uInt32Field":3456789012,"uInt64Field":"12345678901234567890","float32Field":1234.5,"float64Field":-1.23e47,"textField":"foo","dataField":[98,97,114],"structField":{"voidField":null,"boolField":true,"int8Field":-12,"int16Field":3456,"int32Field":-78901234,"int64Field":"56789012345678","uInt8Field":90,"uInt16Field":1234,"uInt32Field":56789012,"uInt64Field":"345678901234567890","float32Field":-1.2499999646475857e-10,"float64Field":345,"textField":"baz","dataField":[113,117,120],"structField":{"voidField":null,"boolField":false,"int8Field":0,"int16Field":0,"int32Field":0,"int64Field":"0","uInt8Field":0,"uInt16Field":0,"uInt32Field":0,"uInt64Field":"0","float32Field":0,"float64Field":0,"textField":"nested","structField":{"voidField":null,"boolField":false,"int8Field":0,"int16Field":0,"int32Field":0,"int64Field":"0","uInt8Field":0,"uInt16Field":0,"uInt32Field":0,"uInt64Field":"0","float32Field":0,"float64Field":0,"textField":"really nested","enumField":"foo","interfaceField":null},"enumField":"foo","interfaceField":null},"enumField":"baz","interfaceField":null,"voidList":[null,null,null],"boolList":[false,true,false,true,true],"int8List":[12,-34,-128,127],"int16List":[1234,-5678,-32768,32767],"int32List":[12345678,-90123456,-2147483648,2147483647],"int64List":["123456789012345","-678901234567890","-9223372036854775808","9223372036854775807"],"uInt8List":[12,34,0,255],"uInt16List":[1234,5678,0,65535],"uInt32List":[12345678,90123456,0,4294967295],"uInt64List":["123456789012345","678901234567890","0","18446744073709551615"],"float32List":[0,1234567,9.9999999338158125e36,-9.9999999338158125e36,9.99999991097579e-38,-9.99999991097579e-38],"float64List":[0,123456789012345,1e306,-1e306,1e-306,-1e-306],"textList":["quux","corge","grault"],"dataList":[[103,97,114,112,108,121],[119,97,108,100,111],[102,114,101,100]],"structList":[{"voidField":null,"boolField":false,"int8Field":0,"int16Field":0,"int32Field":0,"int64Field":"0","uInt8Field":0,"uInt16Field":0,"uInt32Field":0,"uInt64Field":"0","float32Field":0,"float64Field":0,"textField":"x structlist 1","enumField":"foo","interfaceField":null},{"voidField":null,"boolField":false,"int8Field":0,"int16Field":0,"int32Field":0,"int64Field":"0","uInt8Field":0,"uInt16Field":0,"uInt32Field":0,"uInt64Field":"0","float32Field":0,"float64Field":0,"textField":"x structlist 2","enumField":"foo","interfaceField":null},{"voidField":null,"boolField":false,"int8Field":0,"int16Field":0,"int32Field":0,"int64Field":"0","uInt8Field":0,"uInt16Field":0,"uInt32Field":0,"uInt64Field":"0","float32Field":0,"float64Field":0,"textField":"x structlist 3","enumField":"foo","interfaceField":null}],"enumList":["qux","bar","grault"]},"enumField":"corge","interfaceField":null,"voidList":[null,null,null,null,null,null],"boolList":[true,false,false,true],"int8List":[111,-111],"int16List":[11111,-11111],"int32List":[111111111,-111111111],"int64List":["1111111111111111111","-1111111111111111111"],"uInt8List":[111,222],"uInt16List":[33333,44444],"uInt32List":[3333333333],"uInt64List":["11111111111111111111"],"float32List":[5555.5,"Infinity","-Infinity","NaN"],"float64List":[7777.75,"Infinity","-Infinity","NaN"],"textList":["plugh","xyzzy","thud"],"dataList":[[111,111,112,115],[101,120,104,97,117,115,116,101,100],[114,102,99,51,48,57,50]],"structList":[{"voidField":null,"boolField":false,"int8Field":0,"int16Field":0,"int32Field":0,"int64Field":"0","uInt8Field":0,"uInt16Field":0,"uInt32Field":0,"uInt64Field":"0","float32Field":0,"float64Field":0,"textField":"structlist 1","enumField":"foo","interfaceField":null},{"voidField":null,"boolField":false,"int8Field":0,"int16Field":0,"int32Field":0,"int64Field":"0","uInt8Field":0,"uInt16Field":0,"uInt32Field":0,"uInt64Field":"0","float32Field":0,"float64Field":0,"textField":"structlist 2","enumField":"foo","interfaceField":null},{"voidField":null,"boolField":false,"int8Field":0,"int16Field":0,"int32Field":0,"int64Field":"0","uInt8Field":0,"uInt16Field":0,"uInt32Field":0,"uInt64Field":"0","float32Field":0,"float64Field":0,"textField":"structlist 3","enumField":"foo","interfaceField":null}],"enumList":["foo","garply"]} diff --git a/CapnpC.CSharp.Generator.Tests/No Resources/testdata/short.txt b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/short.txt new file mode 100644 index 0000000..d738fb3 --- /dev/null +++ b/CapnpC.CSharp.Generator.Tests/No Resources/testdata/short.txt @@ -0,0 +1 @@ +(voidField = void, boolField = true, int8Field = -123, int16Field = -12345, int32Field = -12345678, int64Field = -123456789012345, uInt8Field = 234, uInt16Field = 45678, uInt32Field = 3456789012, uInt64Field = 12345678901234567890, float32Field = 1234.5, float64Field = -1.23e47, textField = "foo", dataField = "bar", structField = (voidField = void, boolField = true, int8Field = -12, int16Field = 3456, int32Field = -78901234, int64Field = 56789012345678, uInt8Field = 90, uInt16Field = 1234, uInt32Field = 56789012, uInt64Field = 345678901234567890, float32Field = -1.25e-10, float64Field = 345, textField = "baz", dataField = "qux", structField = (voidField = void, boolField = false, int8Field = 0, int16Field = 0, int32Field = 0, int64Field = 0, uInt8Field = 0, uInt16Field = 0, uInt32Field = 0, uInt64Field = 0, float32Field = 0, float64Field = 0, textField = "nested", structField = (voidField = void, boolField = false, int8Field = 0, int16Field = 0, int32Field = 0, int64Field = 0, uInt8Field = 0, uInt16Field = 0, uInt32Field = 0, uInt64Field = 0, float32Field = 0, float64Field = 0, textField = "really nested", enumField = foo, interfaceField = void), enumField = foo, interfaceField = void), enumField = baz, interfaceField = void, voidList = [void, void, void], boolList = [false, true, false, true, true], int8List = [12, -34, -128, 127], int16List = [1234, -5678, -32768, 32767], int32List = [12345678, -90123456, -2147483648, 2147483647], int64List = [123456789012345, -678901234567890, -9223372036854775808, 9223372036854775807], uInt8List = [12, 34, 0, 255], uInt16List = [1234, 5678, 0, 65535], uInt32List = [12345678, 90123456, 0, 4294967295], uInt64List = [123456789012345, 678901234567890, 0, 18446744073709551615], float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37], float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306], textList = ["quux", "corge", "grault"], dataList = ["garply", "waldo", "fred"], structList = [(voidField = void, boolField = false, int8Field = 0, int16Field = 0, int32Field = 0, int64Field = 0, uInt8Field = 0, uInt16Field = 0, uInt32Field = 0, uInt64Field = 0, float32Field = 0, float64Field = 0, textField = "x structlist 1", enumField = foo, interfaceField = void), (voidField = void, boolField = false, int8Field = 0, int16Field = 0, int32Field = 0, int64Field = 0, uInt8Field = 0, uInt16Field = 0, uInt32Field = 0, uInt64Field = 0, float32Field = 0, float64Field = 0, textField = "x structlist 2", enumField = foo, interfaceField = void), (voidField = void, boolField = false, int8Field = 0, int16Field = 0, int32Field = 0, int64Field = 0, uInt8Field = 0, uInt16Field = 0, uInt32Field = 0, uInt64Field = 0, float32Field = 0, float64Field = 0, textField = "x structlist 3", enumField = foo, interfaceField = void)], enumList = [qux, bar, grault]), enumField = corge, interfaceField = void, voidList = [void, void, void, void, void, void], boolList = [true, false, false, true], int8List = [111, -111], int16List = [11111, -11111], int32List = [111111111, -111111111], int64List = [1111111111111111111, -1111111111111111111], uInt8List = [111, 222], uInt16List = [33333, 44444], uInt32List = [3333333333], uInt64List = [11111111111111111111], float32List = [5555.5, inf, -inf, nan], float64List = [7777.75, inf, -inf, nan], textList = ["plugh", "xyzzy", "thud"], dataList = ["oops", "exhausted", "rfc3092"], structList = [(voidField = void, boolField = false, int8Field = 0, int16Field = 0, int32Field = 0, int64Field = 0, uInt8Field = 0, uInt16Field = 0, uInt32Field = 0, uInt64Field = 0, float32Field = 0, float64Field = 0, textField = "structlist 1", enumField = foo, interfaceField = void), (voidField = void, boolField = false, int8Field = 0, int16Field = 0, int32Field = 0, int64Field = 0, uInt8Field = 0, uInt16Field = 0, uInt32Field = 0, uInt64Field = 0, float32Field = 0, float64Field = 0, textField = "structlist 2", enumField = foo, interfaceField = void), (voidField = void, boolField = false, int8Field = 0, int16Field = 0, int32Field = 0, int64Field = 0, uInt8Field = 0, uInt16Field = 0, uInt32Field = 0, uInt64Field = 0, float32Field = 0, float64Field = 0, textField = "structlist 3", enumField = foo, interfaceField = void)], enumList = [foo, garply]) diff --git a/CapnpC.CSharp.Generator.Tests/Util/InlineAssemblyCompiler.cs b/CapnpC.CSharp.Generator.Tests/Util/InlineAssemblyCompiler.cs index 2ab94cb..372b3d0 100644 --- a/CapnpC.CSharp.Generator.Tests/Util/InlineAssemblyCompiler.cs +++ b/CapnpC.CSharp.Generator.Tests/Util/InlineAssemblyCompiler.cs @@ -45,6 +45,7 @@ namespace CapnpC.CSharp.Generator.Tests.Util MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "mscorlib.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Core.dll")), + MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Diagnostics.Tools.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Runtime.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Private.CoreLib.dll")), MetadataReference.CreateFromFile(capnpRuntimePath) }, diff --git a/CapnpC.CSharp.Generator/CapnpCompilation.cs b/CapnpC.CSharp.Generator/CapnpCompilation.cs index 2bbf913..bfef9c5 100644 --- a/CapnpC.CSharp.Generator/CapnpCompilation.cs +++ b/CapnpC.CSharp.Generator/CapnpCompilation.cs @@ -40,7 +40,7 @@ namespace CapnpC.CSharp.Generator { var segments = Framing.ReadSegments(input); var dec = DeserializerState.CreateRoot(segments); - var reader = Schema.CodeGeneratorRequest.Reader.Create(dec); + var reader = Schema.CodeGeneratorRequest.READER.create(dec); var model = Model.SchemaModel.Create(reader); var codeGen = new CodeGen.CodeGenerator(model, options ?? new CodeGen.GeneratorOptions()); return new GenerationResult(codeGen.Generate()); diff --git a/CapnpC.CSharp.Generator/CodeGen/CodeGenerator.cs b/CapnpC.CSharp.Generator/CodeGen/CodeGenerator.cs index 3b8f809..7ef67e9 100644 --- a/CapnpC.CSharp.Generator/CodeGen/CodeGenerator.cs +++ b/CapnpC.CSharp.Generator/CodeGen/CodeGenerator.cs @@ -61,9 +61,18 @@ IEnumerable TransformStruct(TypeDefinition def) { - var topDecl = ClassDeclaration(_names.MakeTypeName(def).Identifier) - .AddModifiers(Public) - .AddBaseListTypes(SimpleBaseType(_names.Type(Nullability.NonNullable))); + var topDecl = ClassDeclaration(_names.MakeTypeName(def).Identifier) + .AddModifiers(_names.TypeVisibilityModifier); + + if (_names.EmitDomainClassesAndInterfaces) + { + topDecl = topDecl.AddBaseListTypes(SimpleBaseType(_names.Type(Nullability.NonNullable))); + } + else + { + topDecl = topDecl.AddModifiers(Static); + } + if (def.GenericParameters.Count > 0) { @@ -72,17 +81,23 @@ .AddConstraintClauses(MakeTypeParameterConstraints(def).ToArray()); } - topDecl = topDecl.AddMembers(CommonSnippetGen.MakeTypeIdConst(def.Id, _names)); - topDecl = topDecl.WithAttributeLists(CommonSnippetGen.MakeTypeIdAttributeLists(def.Id)); + topDecl = topDecl + .AddMembers(_names.MakeTypeIdConst(def.Id)) + .AddAttributeLists(_names.MakeTypeDecorationAttributes(def.Id)); if (def.UnionInfo != null) { topDecl = topDecl.AddMembers(_commonGen.MakeUnionSelectorEnum(def)); } - topDecl = topDecl.AddMembers(_domClassGen.MakeDomainClassMembers(def)); - topDecl = topDecl.AddMembers(_readerGen.MakeReaderStruct(def)); - topDecl = topDecl.AddMembers(_writerGen.MakeWriterStruct(def)); + if (_names.EmitDomainClassesAndInterfaces) + { + topDecl = topDecl.AddMembers(_domClassGen.MakeDomainClassMembers(def)); + } + + topDecl = topDecl.AddMembers( + _readerGen.MakeReaderStruct(def), + _writerGen.MakeWriterStruct(def)); foreach (var nestedGroup in def.NestedGroups) { @@ -99,6 +114,9 @@ IEnumerable TransformInterface(TypeDefinition def) { + if (!_names.EmitDomainClassesAndInterfaces) + yield break; + yield return _interfaceGen.MakeInterface(def); yield return _interfaceGen.MakeProxy(def); yield return _interfaceGen.MakeSkeleton(def); @@ -168,7 +186,7 @@ if (classDecl == null) { classDecl = ClassDeclaration(_names.MakePipeliningSupportExtensionClassName(file).Identifier) - .AddModifiers(Public, Static, Partial); + .AddModifiers(_names.TypeVisibilityModifier, Static, Partial); } classDecl = classDecl.AddMembers(members); @@ -187,6 +205,8 @@ internal string Transform(GenFile file) { _names.NullableEnable = file.NullableEnable ?? _options.NullableEnableDefault; + _names.EmitDomainClassesAndInterfaces = file.EmitDomainClassesAndInterfaces; + _names.TypeVisibility = file.TypeVisibility; NameSyntax topNamespace = GenNames.NamespaceName(file.Namespace) ?? _names.TopNamespace; @@ -211,17 +231,21 @@ ns = ns.AddMembers(Transform(def).ToArray()); } - var psc = TransformForPipeliningSupport(file); - - if (psc != null) + if (_names.EmitDomainClassesAndInterfaces) { - ns = ns.AddMembers(psc); + var psc = TransformForPipeliningSupport(file); + + if (psc != null) + { + ns = ns.AddMembers(psc); + } } var cu = CompilationUnit().AddUsings( UsingDirective(ParseName("Capnp")), UsingDirective(ParseName("Capnp.Rpc")), UsingDirective(ParseName("System")), + UsingDirective(ParseName("System.CodeDom.Compiler")), UsingDirective(ParseName("System.Collections.Generic"))); if (_names.NullableEnable) @@ -236,7 +260,14 @@ cu = cu.AddMembers(ns); - return cu.NormalizeWhitespace(" ", Environment.NewLine).ToFullString(); + string content = cu.NormalizeWhitespace(" ", Environment.NewLine).ToFullString(); + + if (!string.IsNullOrWhiteSpace(file.HeaderText)) + { + content = file.HeaderText + content; + } + + return content; } public IReadOnlyList Generate() diff --git a/CapnpC.CSharp.Generator/CodeGen/CommonSnippetGen.cs b/CapnpC.CSharp.Generator/CodeGen/CommonSnippetGen.cs index 72de969..64c1f48 100644 --- a/CapnpC.CSharp.Generator/CodeGen/CommonSnippetGen.cs +++ b/CapnpC.CSharp.Generator/CodeGen/CommonSnippetGen.cs @@ -40,7 +40,7 @@ namespace CapnpC.CSharp.Generator.CodeGen EqualsValueClause( LiteralExpression( SyntaxKind.NumericLiteralExpression, - Literal(Schema.Field.Reader.NoDiscriminant)))); + Literal(SchemaModel.NoDiscriminant)))); whichEnum = whichEnum.AddMembers(ndecl); @@ -50,8 +50,8 @@ namespace CapnpC.CSharp.Generator.CodeGen public EnumDeclarationSyntax MakeEnum(TypeDefinition def) { var decl = EnumDeclaration(_names.GetCodeIdentifier(def)) - .WithAttributeLists(MakeTypeIdAttributeLists(def.Id)) - .AddModifiers(Public) + .AddAttributeLists(_names.MakeTypeDecorationAttributes(def.Id)) + .AddModifiers(_names.TypeVisibilityModifier) .AddBaseListTypes(SimpleBaseType(_names.Type(Nullability.NonNullable))); foreach (var enumerant in def.Enumerants.OrderBy(e => e.CodeOrder)) @@ -87,39 +87,5 @@ namespace CapnpC.CSharp.Generator.CodeGen yield return expr; } } - - static LiteralExpressionSyntax HexLiteral(ulong id) => - LiteralExpression( - SyntaxKind.NumericLiteralExpression, - Literal($"0x{id:x}UL", id)); - - public static FieldDeclarationSyntax MakeTypeIdConst(ulong id, GenNames names) => - FieldDeclaration( - VariableDeclaration( - IdentifierName("UInt64")) - .WithVariables( - SingletonSeparatedList( - VariableDeclarator(names.TypeIdField.Identifier) - .WithInitializer( - EqualsValueClause(HexLiteral(id)))))) - .WithModifiers( - TokenList( - new[]{ - Token(SyntaxKind.PublicKeyword), - Token(SyntaxKind.ConstKeyword)})); - - public static AttributeSyntax MakeTypeIdAttribute(ulong id) => - Attribute( - IdentifierName("TypeId")) - .WithArgumentList( - AttributeArgumentList( - SingletonSeparatedList( - AttributeArgument(HexLiteral(id))))); - - public static SyntaxList MakeTypeIdAttributeLists(ulong id) => - SingletonList( - AttributeList( - SingletonSeparatedList( - CommonSnippetGen.MakeTypeIdAttribute(id)))); } } diff --git a/CapnpC.CSharp.Generator/CodeGen/DomainClassSnippetGen.cs b/CapnpC.CSharp.Generator/CodeGen/DomainClassSnippetGen.cs index 17af353..fe7ba90 100644 --- a/CapnpC.CSharp.Generator/CodeGen/DomainClassSnippetGen.cs +++ b/CapnpC.CSharp.Generator/CodeGen/DomainClassSnippetGen.cs @@ -284,7 +284,8 @@ namespace CapnpC.CSharp.Generator.CodeGen value.Decode(); return ArrayCreationExpression(ArrayType( - _names.MakeTypeSyntax(value.Type.ElementType, scope, TypeUsage.DomainClass, Nullability.NullableRef)) + _names.MakeTypeSyntax(value.Type.ElementType, scope, TypeUsage.DomainClass, + _names.GetDefaultElementTypeNullability(value.Type.ElementType))) .WithRankSpecifiers( SingletonList( ArrayRankSpecifier( @@ -619,13 +620,14 @@ namespace CapnpC.CSharp.Generator.CodeGen IdentifierName(nameof(Capnp.ReadOnlyListExtensions.ToReadOnlyList)))) .AddArgumentListArguments(Argument( SimpleLambdaExpression(Parameter(Identifier("_")), - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(nameof(Capnp.CapnpSerializable)), - GenericName(nameof(Capnp.CapnpSerializable.Create)) - .AddTypeArgumentListArguments(MakeNonNullableType(elementType)))) - .AddArgumentListArguments(Argument(IdentifierName("_"))))))); + _names.SuppressNullableWarning( + InvocationExpression( + MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + IdentifierName(nameof(Capnp.CapnpSerializable)), + GenericName(nameof(Capnp.CapnpSerializable.Create)) + .AddTypeArgumentListArguments(MakeNonNullableType(elementType)))) + .AddArgumentListArguments(Argument(IdentifierName("_")))))))); } ExpressionSyntax MakeStructListConversion(ExpressionSyntax context, TypeSyntax elementType, int rank) diff --git a/CapnpC.CSharp.Generator/CodeGen/GenNames.cs b/CapnpC.CSharp.Generator/CodeGen/GenNames.cs index b16ff99..5d3d0de 100644 --- a/CapnpC.CSharp.Generator/CodeGen/GenNames.cs +++ b/CapnpC.CSharp.Generator/CodeGen/GenNames.cs @@ -1,4 +1,5 @@ using CapnpC.CSharp.Generator.Model; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using System; @@ -46,7 +47,6 @@ namespace CapnpC.CSharp.Generator.CodeGen public Name ReaderContextField { get; } public Name ContextParameter { get; } public Name GroupReaderContextArg { get; } - public Name GroupWriterContextArg { get; } public Name UnionDiscriminatorEnum { get; } public Name UnionDiscriminatorProp { get; } public Name UnionDiscriminatorUndefined { get; } @@ -60,19 +60,23 @@ namespace CapnpC.CSharp.Generator.CodeGen public Name ResultLocal { get; } public Name SerializeMethod { get; } public Name ApplyDefaultsMethod { get; } - public Name InstLocalName { get; } public string ParamsStructFormat { get; } public string ResultStructFormat { get; } public string PropertyNamedLikeTypeRenameFormat { get; } public string GenericTypeParameterFormat { get; } public string MemberAccessPathNameFormat { get; } public Name TaskParameter { get; } - public Name EagerMethod { get; } public Name TypeIdField { get; } public string PipeliningExtensionsClassFormat { get; } public string ProxyClassFormat { get; } public string SkeletonClassFormat { get; } + public Name AwaitProxy { get; } public bool NullableEnable { get; set; } + public bool EmitDomainClassesAndInterfaces { get; set; } + public SupportedAnnotations.TypeVisibility TypeVisibility { get; set; } + public string GeneratorToolName { get; } + public string GeneratorToolVersion { get; } + public GenNames(GeneratorOptions options) { TopNamespace = new Name(options.TopNamespaceName).IdentifierName; @@ -84,7 +88,6 @@ namespace CapnpC.CSharp.Generator.CodeGen ReaderContextField = new Name(options.ReaderContextFieldName); ContextParameter = new Name(options.ContextParameterName); GroupReaderContextArg = new Name(options.GroupReaderContextArgName); - GroupWriterContextArg = new Name(options.GroupWriterContextArgName); UnionDiscriminatorEnum = new Name(options.UnionDiscriminatorEnumName); UnionDiscriminatorProp = new Name(options.UnionDiscriminatorPropName); UnionDiscriminatorUndefined = new Name(options.UnionDiscriminatorUndefinedName); @@ -98,18 +101,19 @@ namespace CapnpC.CSharp.Generator.CodeGen DeserializerLocal = new Name(options.DeserializerLocalName); SerializerLocal = new Name(options.SerializerLocalName); ResultLocal = new Name(options.ResultLocalName); - InstLocalName = new Name(options.InstLocalName); ParamsStructFormat = options.ParamsStructFormat; ResultStructFormat = options.ResultStructFormat; PropertyNamedLikeTypeRenameFormat = options.PropertyNamedLikeTypeRenameFormat; GenericTypeParameterFormat = options.GenericTypeParameterFormat; MemberAccessPathNameFormat = options.MemberAccessPathNameFormat; TaskParameter = new Name(options.TaskParameterName); - EagerMethod = new Name(options.EagerMethodName); TypeIdField = new Name(options.TypeIdFieldName); PipeliningExtensionsClassFormat = options.PipeliningExtensionsClassFormat; ProxyClassFormat = options.ProxyClassFormat; SkeletonClassFormat = options.SkeletonClassFormat; + AwaitProxy = new Name(options.AwaitProxyName); + GeneratorToolName = options.GeneratorToolName; + GeneratorToolVersion = options.GeneratorToolVersion; } public Name MakeTypeName(TypeDefinition def, NameUsage usage = NameUsage.Default) @@ -387,6 +391,23 @@ namespace CapnpC.CSharp.Generator.CodeGen } } + public Nullability GetDefaultElementTypeNullability(Model.Type type) + { + switch (type.Tag) + { + case TypeTag.Data: + case TypeTag.Text: + case TypeTag.Interface: + case TypeTag.List: + case TypeTag.ListPointer: + case TypeTag.StructPointer: + return Nullability.NullableRef; + + default: + return Nullability.NonNullable; + } + } + public TypeSyntax MakeTypeSyntax(Model.Type type, TypeDefinition scope, TypeUsage usage, Nullability nullability) { switch (type.Tag) @@ -483,11 +504,13 @@ namespace CapnpC.CSharp.Generator.CodeGen case TypeUsage.Reader: return MaybeNullableRefType(GenericName(Identifier("IReadOnlyList")) - .AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.Reader, Nullability.NonNullable)), nullability); + .AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.Reader, + GetDefaultElementTypeNullability(type.ElementType))), nullability); case TypeUsage.DomainClass: return MaybeNullableRefType(GenericName(Identifier("IReadOnlyList")) - .AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.DomainClass, Nullability.NullableRef)), nullability); + .AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.DomainClass, + GetDefaultElementTypeNullability(type.ElementType))), nullability); default: throw new NotImplementedException(); @@ -565,7 +588,7 @@ namespace CapnpC.CSharp.Generator.CodeGen } string GetCodeIdentifierUpperCamel(Field field) => field.CsName ?? SyntaxHelpers.MakeUpperCamel(field.Name); - string GetCodeIdentifierLowerCamel(Field field) => field.CsName ?? IdentifierRenamer.ToNonKeyword(SyntaxHelpers.MakeLowerCamel(field.Name)); + public string GetCodeIdentifierLowerCamel(Field field) => field.CsName ?? IdentifierRenamer.ToNonKeyword(SyntaxHelpers.MakeLowerCamel(field.Name)); public Name GetCodeIdentifier(Field field) { @@ -576,13 +599,6 @@ namespace CapnpC.CSharp.Generator.CodeGen var def = field.DeclaringType; - if (def == null) - { - // Method parameters are internally represented with the same class "Field". - // They do not have a declaring type. Anyway, they don't suffer from the field-name-equals-nested-type-name problem. - return new Name(GetCodeIdentifierLowerCamel(field)); - } - var typeNames = new HashSet(def.NestedTypes.Select(t => MakeTypeName(t))); typeNames.Add(MakeTypeName(def)); @@ -618,10 +634,7 @@ namespace CapnpC.CSharp.Generator.CodeGen public Name MakePipeliningSupportExtensionMethodName(IReadOnlyList path) { - if (path.Count == 1 && path[0].Offset == 0) - return EagerMethod; - else - return new Name(string.Join("_", path.Select(f => GetCodeIdentifier(f).ToString()))); + return new Name(string.Join("_", path.Select(f => GetCodeIdentifier(f).ToString()))); } public Name MakePipeliningSupportExtensionClassName(GenFile file) @@ -687,5 +700,66 @@ namespace CapnpC.CSharp.Generator.CodeGen PostfixUnaryExpression(SyntaxKind.SuppressNullableWarningExpression, expression) : expression; } + + public SyntaxToken TypeVisibilityModifier + { + get + { + switch (TypeVisibility) + { + case SupportedAnnotations.TypeVisibility.Public: + return Token(SyntaxKind.PublicKeyword); + + case SupportedAnnotations.TypeVisibility.Internal: + return Token(SyntaxKind.InternalKeyword); + + default: + throw new NotImplementedException(); + } + } + } + + static LiteralExpressionSyntax HexLiteral(ulong id) => + LiteralExpression( + SyntaxKind.NumericLiteralExpression, + Literal($"0x{id:x}UL", id)); + + static LiteralExpressionSyntax StringLiteral(string text) => + LiteralExpression( + SyntaxKind.StringLiteralExpression, + Literal(text)); + + public FieldDeclarationSyntax MakeTypeIdConst(ulong id) => + FieldDeclaration( + VariableDeclaration( + IdentifierName("UInt64")) + .WithVariables( + SingletonSeparatedList( + VariableDeclarator(TypeIdField.Identifier) + .WithInitializer( + EqualsValueClause(HexLiteral(id)))))) + .WithModifiers( + TokenList( + new[]{ + Token(SyntaxKind.PublicKeyword), + Token(SyntaxKind.ConstKeyword)})); + + static AttributeSyntax MakeTypeIdAttribute(ulong id) => + Attribute( + IdentifierName("TypeId")) + .WithArgumentList( + AttributeArgumentList( + SingletonSeparatedList( + AttributeArgument(HexLiteral(id))))); + + public AttributeSyntax MakeGeneratedCodeAttribute() => + Attribute( + IdentifierName("System.CodeDom.Compiler.GeneratedCode")) + .AddArgumentListArguments( + AttributeArgument(StringLiteral(GeneratorToolName)), + AttributeArgument(StringLiteral(GeneratorToolVersion))); + + public AttributeListSyntax MakeTypeDecorationAttributes(ulong typeId) => + AttributeList().AddAttributes(MakeGeneratedCodeAttribute(), MakeTypeIdAttribute(typeId)); } } diff --git a/CapnpC.CSharp.Generator/CodeGen/GeneratorOptions.cs b/CapnpC.CSharp.Generator/CodeGen/GeneratorOptions.cs index 3a3eccf..133cfa4 100644 --- a/CapnpC.CSharp.Generator/CodeGen/GeneratorOptions.cs +++ b/CapnpC.CSharp.Generator/CodeGen/GeneratorOptions.cs @@ -11,7 +11,6 @@ public string ReaderContextFieldName { get; set; } = "ctx"; public string ContextParameterName { get; set; } = "ctx"; public string GroupReaderContextArgName { get; set; } = "ctx"; - public string GroupWriterContextArgName { get; set; } = "ctx"; public string UnionDiscriminatorEnumName { get; set; } = "WHICH"; public string UnionDiscriminatorPropName { get; set; } = "which"; public string UnionDiscriminatorFieldName { get; set; } = "_which"; @@ -28,15 +27,16 @@ public string ParamsStructFormat { get; set; } = "Params_{0}"; public string ResultStructFormat { get; set; } = "Result_{0}"; public string PropertyNamedLikeTypeRenameFormat { get; set; } = "The{0}"; - public string InstLocalName { get; set; } = "inst"; public string GenericTypeParameterFormat { get; set; } = "T{0}"; public string PipeliningExtensionsClassFormat { get; set; } = "PipeliningSupportExtensions_{0}"; public string ProxyClassFormat { get; set; } = "{0}_Proxy"; public string SkeletonClassFormat { get; set; } = "{0}_Skeleton"; public string MemberAccessPathNameFormat { get; set; } = "Path_{0}_{1}_{2}_{3}"; public string TaskParameterName { get; set; } = "task"; - public string EagerMethodName { get; set; } = "Eager"; public string TypeIdFieldName { get; set; } = "typeId"; + public string AwaitProxyName { get; set; } = "AwaitProxy"; public bool NullableEnableDefault { get; set; } = false; + public string GeneratorToolName { get; set; } = "capnpc-csharp"; + public string GeneratorToolVersion = ThisAssembly.AssemblyVersion; } } diff --git a/CapnpC.CSharp.Generator/CodeGen/InterfaceSnippetGen.cs b/CapnpC.CSharp.Generator/CodeGen/InterfaceSnippetGen.cs index c683f3b..398286b 100644 --- a/CapnpC.CSharp.Generator/CodeGen/InterfaceSnippetGen.cs +++ b/CapnpC.CSharp.Generator/CodeGen/InterfaceSnippetGen.cs @@ -61,7 +61,7 @@ namespace CapnpC.CSharp.Generator.CodeGen { foreach (var arg in method.Params) { - list.Add(Parameter(_names.GetCodeIdentifier(arg).Identifier) + list.Add(Parameter(Identifier(_names.GetCodeIdentifierLowerCamel(arg))) .WithType(_names.MakeTypeSyntax(arg.Type, method.DeclaringInterface, TypeUsage.DomainClass, Nullability.NullableRef))); } } @@ -99,9 +99,8 @@ namespace CapnpC.CSharp.Generator.CodeGen var ifaceDecl = InterfaceDeclaration(_names.MakeTypeName(type, NameUsage.Interface).Identifier) .AddModifiers(Public) .AddAttributeLists( - AttributeList() + _names.MakeTypeDecorationAttributes(type.Id) .AddAttributes( - CommonSnippetGen.MakeTypeIdAttribute(type.Id), Attribute(IdentifierName("Proxy")) .AddArgumentListArguments( AttributeArgument( @@ -195,8 +194,8 @@ namespace CapnpC.CSharp.Generator.CodeGen yield return AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, - _names.GetCodeIdentifier(field).IdentifierName, - _names.GetCodeIdentifier(methodParam).IdentifierName); + _names.GetCodeIdentifier(methodParam).IdentifierName, + IdentifierName(_names.GetCodeIdentifierLowerCamel(field))); } } @@ -285,6 +284,7 @@ namespace CapnpC.CSharp.Generator.CodeGen public MemberDeclarationSyntax MakeProxy(TypeDefinition type) { var classDecl = ClassDeclaration(_names.MakeTypeName(type, NameUsage.Proxy).Identifier) + .AddAttributeLists(_names.MakeTypeDecorationAttributes(type.Id)) .AddModifiers(Public) .AddBaseListTypes( SimpleBaseType(_names.Type(Nullability.NonNullable)), @@ -404,8 +404,11 @@ namespace CapnpC.CSharp.Generator.CodeGen Argument(SimpleLambdaExpression( Parameter(_names.DeserializerLocal.Identifier), Block( - MakeProxyCreateResult(method), - MakeProxyReturnResult(method))))); + UsingStatement( + Block( + MakeProxyCreateResult(method), + MakeProxyReturnResult(method))) + .WithExpression(_names.DeserializerLocal.IdentifierName))))); bodyStmts.Add(ReturnStatement(pipelineAwareCall)); } @@ -422,19 +425,18 @@ namespace CapnpC.CSharp.Generator.CodeGen call, IdentifierName(nameof(Capnp.Rpc.IPromisedAnswer.WhenReturned))); - var assignAwaited = LocalDeclarationStatement( - VariableDeclaration( + bodyStmts.Add(UsingStatement( + Block( + MakeProxyCreateResult(method), + MakeProxyReturnResult(method))) + .WithDeclaration(VariableDeclaration( IdentifierName("var")) - .AddVariables( - VariableDeclarator( - _names.DeserializerLocal.Identifier) - .WithInitializer( - EqualsValueClause( - AwaitExpression(whenReturned))))); - - bodyStmts.Add(assignAwaited); - bodyStmts.Add(MakeProxyCreateResult(method)); - bodyStmts.Add(MakeProxyReturnResult(method)); + .AddVariables( + VariableDeclarator( + _names.DeserializerLocal.Identifier) + .WithInitializer( + EqualsValueClause( + AwaitExpression(whenReturned)))))); } if (method.GenericParameters.Count > 0) @@ -479,7 +481,7 @@ namespace CapnpC.CSharp.Generator.CodeGen yield return AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, _names.GetCodeIdentifier(arg).IdentifierName, - IdentifierName(IdentifierRenamer.ToNonKeyword(arg.Name))); + IdentifierName(_names.GetCodeIdentifierLowerCamel(arg))); } } @@ -649,7 +651,7 @@ namespace CapnpC.CSharp.Generator.CodeGen if (method.Results.Count == 1) { lambdaArg = SimpleLambdaExpression( - Parameter(Identifier(method.Results.Single().Name)), + Parameter(Identifier(_names.GetCodeIdentifierLowerCamel(method.Results.Single()))), MakeMaybeTailCallLambdaBody(method)); } else @@ -661,7 +663,7 @@ namespace CapnpC.CSharp.Generator.CodeGen { if (paramList.Count > 0) paramList.Add(Token(SyntaxKind.CommaToken)); - paramList.Add(Parameter(Identifier(arg.Name))); + paramList.Add(Parameter(Identifier(_names.GetCodeIdentifierLowerCamel(arg)))); } lambdaArg = ParenthesizedLambdaExpression( ParameterList( @@ -703,7 +705,10 @@ namespace CapnpC.CSharp.Generator.CodeGen Parameter(_names.CancellationTokenParameter.Identifier) .WithType(_names.Type(Nullability.NonNullable))) .AddBodyStatements( - MakeSkeletonMethodBody(method).ToArray()); + UsingStatement( + Block( + MakeSkeletonMethodBody(method).ToArray())) + .WithExpression(_names.DeserializerLocal.IdentifierName)); if (method.Results.Count == 0) { @@ -725,6 +730,7 @@ namespace CapnpC.CSharp.Generator.CodeGen { var name = _names.MakeTypeName(type, NameUsage.Skeleton).Identifier; var classDecl = ClassDeclaration(name) + .AddAttributeLists(_names.MakeTypeDecorationAttributes(type.Id)) .AddModifiers(Public) .AddBaseListTypes( SimpleBaseType( @@ -808,6 +814,59 @@ namespace CapnpC.CSharp.Generator.CodeGen readonly HashSet<(string, string)> _existingExtensionMethods = new HashSet<(string, string)>(); + LocalFunctionStatementSyntax MakeLocalAwaitProxyFunction(Method method, IReadOnlyList path) + { + var members = new List(); + IEnumerable fields = path; + + if (method.Results.Count >= 2) + { + int index = Array.IndexOf(method.ResultStruct.Fields.ToArray(), path[0]) + 1; + members.Add(new Name($"Item{index}")); + fields = path.Skip(1); + } + + foreach (var field in fields) + { + members.Add(_names.GetCodeIdentifier(field)); + } + + ExpressionSyntax memberAccess = + ParenthesizedExpression( + AwaitExpression( + _names.TaskParameter.IdentifierName)); + + memberAccess = MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + memberAccess, + members.First().IdentifierName); + + foreach (var member in members.Skip(1)) + { + memberAccess = ConditionalAccessExpression( + memberAccess, + MemberBindingExpression(member.IdentifierName)); + } + + var idisposable = _names.MakeNullableRefType(IdentifierName(nameof(IDisposable))); + + return LocalFunctionStatement( + GenericName( + Identifier(nameof(Task))) + .WithTypeArgumentList( + TypeArgumentList( + SingletonSeparatedList( + idisposable))), + _names.AwaitProxy.Identifier) + .WithModifiers( + TokenList( + Token(SyntaxKind.AsyncKeyword))) + .WithExpressionBody( + ArrowExpressionClause(memberAccess)) + .WithSemicolonToken( + Token(SyntaxKind.SemicolonToken)); + } + public IEnumerable MakePipeliningSupport(TypeDefinition type) { foreach (var method in type.Methods) @@ -856,6 +915,7 @@ namespace CapnpC.CSharp.Generator.CodeGen .AddModifiers(This) .WithType(TransformReturnType(method))) .AddBodyStatements( + MakeLocalAwaitProxyFunction(method, path), ReturnStatement( CastExpression( capTypeSyntax, @@ -872,18 +932,16 @@ namespace CapnpC.CSharp.Generator.CodeGen InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, + IdentifierName(nameof(Capnp.Rpc.Impatient)), + IdentifierName(nameof(Capnp.Rpc.Impatient.Access)))) + .AddArgumentListArguments( + Argument( + _names.TaskParameter.IdentifierName), + Argument( + accessPath.IdentifierName), + Argument( InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(nameof(Capnp.Rpc.Impatient)), - IdentifierName(nameof(Capnp.Rpc.Impatient.GetAnswer)))) - .AddArgumentListArguments( - Argument( - _names.TaskParameter.IdentifierName)), - IdentifierName(nameof(Capnp.Rpc.IPromisedAnswer.Access)))) - .AddArgumentListArguments( - Argument( - accessPath.IdentifierName))))))); + _names.AwaitProxy.IdentifierName)))))))); yield return pathDecl; yield return methodDecl; diff --git a/CapnpC.CSharp.Generator/CodeGen/SkeletonWorder.cs b/CapnpC.CSharp.Generator/CodeGen/SkeletonWorder.cs index 703ee3b..6887804 100644 --- a/CapnpC.CSharp.Generator/CodeGen/SkeletonWorder.cs +++ b/CapnpC.CSharp.Generator/CodeGen/SkeletonWorder.cs @@ -2,10 +2,8 @@ namespace CapnpC.CSharp.Generator.CodeGen { - class SkeletonWorder : Capnp.Rpc.Skeleton + abstract class SkeletonWorder : Capnp.Rpc.Skeleton { - public override ulong InterfaceId => throw new NotImplementedException(); - public const string SetMethodTableName = nameof(SkeletonWorder.SetMethodTable); public const string ImplName = nameof(SkeletonWorder.Impl); } diff --git a/CapnpC.CSharp.Generator/Model/GenFile.cs b/CapnpC.CSharp.Generator/Model/GenFile.cs index 098c8a6..468315e 100644 --- a/CapnpC.CSharp.Generator/Model/GenFile.cs +++ b/CapnpC.CSharp.Generator/Model/GenFile.cs @@ -13,6 +13,9 @@ namespace CapnpC.CSharp.Generator.Model public string[] Namespace { get; set; } public bool? NullableEnable { get; set; } public bool EmitNullableDirective { get; set; } + public bool EmitDomainClassesAndInterfaces { get; set; } + public string HeaderText { get; set; } + public SupportedAnnotations.TypeVisibility TypeVisibility { get; set; } public IEnumerable NestedTypes { get => this.GetNestedTypes(); } public ICollection NestedDefinitions { get; } = new List(); diff --git a/CapnpC.CSharp.Generator/Model/SchemaModel.cs b/CapnpC.CSharp.Generator/Model/SchemaModel.cs index 8c0e9d6..3262f8f 100644 --- a/CapnpC.CSharp.Generator/Model/SchemaModel.cs +++ b/CapnpC.CSharp.Generator/Model/SchemaModel.cs @@ -8,20 +8,23 @@ namespace CapnpC.CSharp.Generator.Model { class SchemaModel { - readonly Schema.CodeGeneratorRequest.Reader _request; + public const ushort NoDiscriminant = 65535; + + readonly Schema.CodeGeneratorRequest.READER _request; readonly List _generatedFiles = new List(); readonly DefinitionManager _typeDefMgr = new DefinitionManager(); - readonly Dictionary _id2node = new Dictionary(); + readonly Dictionary _id2node = new Dictionary(); + readonly Dictionary _id2sourceInfo = new Dictionary(); - public SchemaModel(Schema.CodeGeneratorRequest.Reader request) + public SchemaModel(Schema.CodeGeneratorRequest.READER request) { _request = request; } public IReadOnlyList FilesToGenerate => _generatedFiles; - Schema.Node.Reader? IdToNode(ulong id, bool mustExist) + Schema.Node.READER? IdToNode(ulong id, bool mustExist) { if (_id2node.TryGetValue(id, out var node)) return node; @@ -30,9 +33,9 @@ namespace CapnpC.CSharp.Generator.Model return null; } - Schema.Node.Reader IdToNode(ulong id) + Schema.Node.READER IdToNode(ulong id) { - return (Schema.Node.Reader)IdToNode(id, true); + return (Schema.Node.READER)IdToNode(id, true); } void Build() @@ -51,6 +54,17 @@ namespace CapnpC.CSharp.Generator.Model _id2node[node.Id] = node; } + foreach (var reader in _request.SourceInfo) + { + var sourceInfo = new SourceInfo() + { + DocComment = reader.DocComment, + MemberDocComments = reader.Members.Select(m => m.DocComment).ToList() + }; + + _id2sourceInfo.Add(reader.Id, sourceInfo); + } + var requestedFiles = _request.RequestedFiles.ToDictionary(req => req.Id); BuildPass1(requestedFiles); BuildPass2(requestedFiles); @@ -64,13 +78,13 @@ namespace CapnpC.CSharp.Generator.Model public IHasNestedDefinitions parent; } - void BuildPass1(Dictionary requestedFiles) + void BuildPass1(Dictionary requestedFiles) { Pass1State state = new Pass1State() { unprocessedNodes = new HashSet(_id2node.Keys) }; - foreach (var node in _id2node.Values.Where(n => n.IsFile)) + foreach (var node in _id2node.Values.Where(n => n.which == Schema.Node.WHICH.File)) { GenFile file; bool isGenerated = requestedFiles.TryGetValue(node.Id, out var req); @@ -94,13 +108,19 @@ namespace CapnpC.CSharp.Generator.Model file.Name = name; file.NullableEnable = GetNullableEnable(node); file.EmitNullableDirective = GetEmitNullableDirective(node) ?? false; + file.EmitDomainClassesAndInterfaces = GetEmitDomainClassesAndInterfaces(node) ?? true; + file.TypeVisibility = GetTypeVisibility(node) ?? TypeVisibility.Public; + if (_id2sourceInfo.TryGetValue(node.Id, out var sourceInfo)) + { + file.HeaderText = GetHeaderText(sourceInfo); + } return ProcessNodePass1(id, name, state) as GenFile; } IDefinition ProcessNodePass1(ulong id, string name, Pass1State state) { bool mustExist = state.parent == null || (state.parent as IDefinition).IsGenerated; - if (!(IdToNode(id, mustExist) is Schema.Node.Reader node)) + if (!(IdToNode(id, mustExist) is Schema.Node.READER node)) return null; if (!state.unprocessedNodes.Remove(id)) return null; @@ -157,18 +177,18 @@ namespace CapnpC.CSharp.Generator.Model { ProcessNodePass1(nested.Id, nested.Name, state); } - if (processFields && node.Fields != null) - foreach (var field in node.Fields.Where(f => f.IsGroup)) + if (processFields && node.Struct.Fields != null) + foreach (var field in node.Struct.Fields.Where(f => f.which == Schema.Field.WHICH.Group)) { - var group = IdToNode(field.Group_TypeId); - if (!group.IsStruct || !group.Struct_IsGroup) + var group = IdToNode(field.Group.TypeId); + if (group.which != Schema.Node.WHICH.Struct || !group.Struct.IsGroup) { throw new InvalidSchemaException($"Expected node with id {group.StrId()} to be a struct definition"); } - ProcessNodePass1(field.Group_TypeId, field.Name, state); + ProcessNodePass1(field.Group.TypeId, field.Name, state); } - if (processInterfaceMethods && node.Interface_Methods != null) - foreach (var method in node.Interface_Methods) + if (processInterfaceMethods && node.Interface.Methods != null) + foreach (var method in node.Interface.Methods) { var pnode = IdToNode(method.ParamStructType); if (pnode.ScopeId == 0) ProcessNodePass1(pnode.Id, null, state); // Anonymous generated type @@ -186,7 +206,7 @@ namespace CapnpC.CSharp.Generator.Model public HashSet processedNodes; } - void BuildPass2(Dictionary requestedFiles) + void BuildPass2(Dictionary requestedFiles) { var state = new Pass2State() { processedNodes = new HashSet() }; foreach (var file in _typeDefMgr.Files) @@ -196,7 +216,7 @@ namespace CapnpC.CSharp.Generator.Model } } - void ProcessNestedNodes(IEnumerable nestedNodes, Pass2State state, bool mustExist) + void ProcessNestedNodes(IEnumerable nestedNodes, Pass2State state, bool mustExist) { foreach (var nestedNode in nestedNodes) { @@ -204,16 +224,16 @@ namespace CapnpC.CSharp.Generator.Model } } - void ProcessBrand(Schema.Brand.Reader brandReader, Type type, Pass2State state) + void ProcessBrand(Schema.Brand.READER brandReader, Type type, Pass2State state) { foreach (var scopeReader in brandReader.Scopes) { var whatToBind = ProcessTypeDef(scopeReader.ScopeId, state); int index = 0; - switch (0) + switch (scopeReader.which) { - case 0 when scopeReader.IsBind: + case Schema.Brand.Scope.WHICH.Bind: foreach (var bindingReader in scopeReader.Bind) { var typeParameter = new GenericParameter() @@ -222,20 +242,20 @@ namespace CapnpC.CSharp.Generator.Model Index = index++ }; - switch (0) + switch (bindingReader.which) { - case 0 when bindingReader.IsType: + case Schema.Brand.Binding.WHICH.Type: type.BindGenericParameter(typeParameter, ProcessType(bindingReader.Type, state)); break; - case 0 when bindingReader.IsUnbound: + case Schema.Brand.Binding.WHICH.Unbound: type.BindGenericParameter(typeParameter, Types.FromParameter(typeParameter)); break; } } break; - case 0 when scopeReader.IsInherit: + case Schema.Brand.Scope.WHICH.Inherit: for (index = 0; index < type.DeclaringType.Definition.GenericParameters.Count; index++) { var typeParameter = new GenericParameter() @@ -251,45 +271,44 @@ namespace CapnpC.CSharp.Generator.Model } } - Type ProcessType(Schema.Type.Reader typeReader, Pass2State state) + Type ProcessType(Schema.Type.READER typeReader, Pass2State state) { Type result; - switch (0) + switch (typeReader.which) { - case 0 when typeReader.IsAnyPointer: - switch (0) + case Schema.Type.WHICH.AnyPointer: + switch (typeReader.AnyPointer.which) { - case 0 when typeReader.AnyPointer_IsParameter: + case Schema.Type.anyPointer.WHICH.Parameter: return Types.FromParameter( new GenericParameter() { - DeclaringEntity = ProcessTypeDef(typeReader.AnyPointer_Parameter_ScopeId, state), - Index = typeReader.AnyPointer_Parameter_ParameterIndex + DeclaringEntity = ProcessTypeDef(typeReader.AnyPointer.Parameter.ScopeId, state), + Index = typeReader.AnyPointer.Parameter.ParameterIndex }); - case 0 when typeReader.AnyPointer_IsImplicitMethodParameter: + case Schema.Type.anyPointer.WHICH.ImplicitMethodParameter: return Types.FromParameter( new GenericParameter() { DeclaringEntity = state.currentMethod ?? throw new InvalidOperationException("current method not set"), - Index = typeReader.AnyPointer_ImplicitMethodParameter_ParameterIndex + Index = typeReader.AnyPointer.ImplicitMethodParameter.ParameterIndex }); - case 0 when typeReader.AnyPointer_IsUnconstrained: - - switch (0) + case Schema.Type.anyPointer.WHICH.Unconstrained: + switch (typeReader.AnyPointer.Unconstrained.which) { - case 0 when typeReader.AnyPointer_Unconstrained_IsAnyKind: + case Schema.Type.anyPointer.unconstrained.WHICH.AnyKind: return Types.AnyPointer; - case 0 when typeReader.AnyPointer_Unconstrained_IsCapability: + case Schema.Type.anyPointer.unconstrained.WHICH.Capability: return Types.CapabilityPointer; - case 0 when typeReader.AnyPointer_Unconstrained_IsList: + case Schema.Type.anyPointer.unconstrained.WHICH.List: return Types.ListPointer; - case 0 when typeReader.AnyPointer_Unconstrained_IsStruct: + case Schema.Type.anyPointer.unconstrained.WHICH.Struct: return Types.StructPointer; default: @@ -300,62 +319,62 @@ namespace CapnpC.CSharp.Generator.Model throw new NotImplementedException(); } - case 0 when typeReader.IsBool: + case Schema.Type.WHICH.Bool: return Types.Bool; - case 0 when typeReader.IsData: + case Schema.Type.WHICH.Data: return Types.Data; - case 0 when typeReader.IsFloat64: + case Schema.Type.WHICH.Float64: return Types.F64; - case 0 when typeReader.IsEnum: - return Types.FromDefinition(ProcessTypeDef(typeReader.Enum_TypeId, state, TypeTag.Enum)); + case Schema.Type.WHICH.Enum: + return Types.FromDefinition(ProcessTypeDef(typeReader.Enum.TypeId, state, TypeTag.Enum)); - case 0 when typeReader.IsFloat32: + case Schema.Type.WHICH.Float32: return Types.F32; - case 0 when typeReader.IsInt16: + case Schema.Type.WHICH.Int16: return Types.S16; - case 0 when typeReader.IsInt32: + case Schema.Type.WHICH.Int32: return Types.S32; - case 0 when typeReader.IsInt64: + case Schema.Type.WHICH.Int64: return Types.S64; - case 0 when typeReader.IsInt8: + case Schema.Type.WHICH.Int8: return Types.S8; - case 0 when typeReader.IsInterface: - result = Types.FromDefinition(ProcessTypeDef(typeReader.Interface_TypeId, state, TypeTag.Interface)); - ProcessBrand(typeReader.Interface_Brand, result, state); + case Schema.Type.WHICH.Interface: + result = Types.FromDefinition(ProcessTypeDef(typeReader.Interface.TypeId, state, TypeTag.Interface)); + ProcessBrand(typeReader.Interface.Brand, result, state); return result; - case 0 when typeReader.IsList: - return Types.List(ProcessType(typeReader.List_ElementType, state)); + case Schema.Type.WHICH.List: + return Types.List(ProcessType(typeReader.List.ElementType, state)); - case 0 when typeReader.IsStruct: - result = Types.FromDefinition(ProcessTypeDef(typeReader.Struct_TypeId, state, TypeTag.Struct)); - ProcessBrand(typeReader.Struct_Brand, result, state); + case Schema.Type.WHICH.Struct: + result = Types.FromDefinition(ProcessTypeDef(typeReader.Struct.TypeId, state, TypeTag.Struct)); + ProcessBrand(typeReader.Struct.Brand, result, state); return result; - case 0 when typeReader.IsText: + case Schema.Type.WHICH.Text: return Types.Text; - case 0 when typeReader.IsUInt16: + case Schema.Type.WHICH.Uint16: return Types.U16; - case 0 when typeReader.IsUInt32: + case Schema.Type.WHICH.Uint32: return Types.U32; - case 0 when typeReader.IsUInt64: + case Schema.Type.WHICH.Uint64: return Types.U64; - case 0 when typeReader.IsUInt8: + case Schema.Type.WHICH.Uint8: return Types.U8; - case 0 when typeReader.IsVoid: + case Schema.Type.WHICH.Void: return Types.Void; default: @@ -363,103 +382,103 @@ namespace CapnpC.CSharp.Generator.Model } } - Value ProcessValue(Schema.Value.Reader valueReader) + Value ProcessValue(Schema.Value.READER valueReader) { var value = new Value(); - switch (0) + switch (valueReader.which) { - case 0 when valueReader.IsAnyPointer: + case Schema.Value.WHICH.AnyPointer: value.ScalarValue = valueReader.AnyPointer; value.Type = Types.AnyPointer; break; - case 0 when valueReader.IsBool: + case Schema.Value.WHICH.Bool: value.ScalarValue = valueReader.Bool; value.Type = Types.Bool; break; - case 0 when valueReader.IsData: - value.Items.AddRange(valueReader.Data.CastByte().Select(Value.Scalar)); + case Schema.Value.WHICH.Data: + value.Items.AddRange(valueReader.Data.Select(Value.Scalar)); value.Type = Types.Data; break; - case 0 when valueReader.IsEnum: + case Schema.Value.WHICH.Enum: value.ScalarValue = valueReader.Enum; value.Type = Types.AnyEnum; break; - case 0 when valueReader.IsFloat32: + case Schema.Value.WHICH.Float32: value.ScalarValue = valueReader.Float32; value.Type = Types.F32; break; - case 0 when valueReader.IsFloat64: + case Schema.Value.WHICH.Float64: value.ScalarValue = valueReader.Float64; value.Type = Types.F64; break; - case 0 when valueReader.IsInt16: + case Schema.Value.WHICH.Int16: value.ScalarValue = valueReader.Int16; value.Type = Types.S16; break; - case 0 when valueReader.IsInt32: + case Schema.Value.WHICH.Int32: value.ScalarValue = valueReader.Int32; value.Type = Types.S32; break; - case 0 when valueReader.IsInt64: + case Schema.Value.WHICH.Int64: value.ScalarValue = valueReader.Int64; value.Type = Types.S64; break; - case 0 when valueReader.IsInt8: + case Schema.Value.WHICH.Int8: value.ScalarValue = valueReader.Int8; value.Type = Types.S8; break; - case 0 when valueReader.IsInterface: + case Schema.Value.WHICH.Interface: value.ScalarValue = null; value.Type = Types.CapabilityPointer; break; - case 0 when valueReader.IsList: + case Schema.Value.WHICH.List: value.RawValue = valueReader.List; value.Type = Types.ListPointer; break; - case 0 when valueReader.IsStruct: + case Schema.Value.WHICH.Struct: value.RawValue = valueReader.Struct; value.Type = Types.StructPointer; break; - case 0 when valueReader.IsText: + case Schema.Value.WHICH.Text: value.ScalarValue = valueReader.Text; value.Type = Types.Text; break; - case 0 when valueReader.IsUInt16: - value.ScalarValue = valueReader.UInt16; + case Schema.Value.WHICH.Uint16: + value.ScalarValue = valueReader.Uint16; value.Type = Types.U16; break; - case 0 when valueReader.IsUInt32: - value.ScalarValue = valueReader.UInt32; + case Schema.Value.WHICH.Uint32: + value.ScalarValue = valueReader.Uint32; value.Type = Types.U32; break; - case 0 when valueReader.IsUInt64: - value.ScalarValue = valueReader.UInt64; + case Schema.Value.WHICH.Uint64: + value.ScalarValue = valueReader.Uint64; value.Type = Types.U64; break; - case 0 when valueReader.IsUInt8: - value.ScalarValue = valueReader.UInt8; + case Schema.Value.WHICH.Uint8: + value.ScalarValue = valueReader.Uint8; value.Type = Types.U8; break; - case 0 when valueReader.IsVoid: + case Schema.Value.WHICH.Void: value.Type = Types.Void; break; @@ -470,14 +489,14 @@ namespace CapnpC.CSharp.Generator.Model return value; } - void ProcessFields(Schema.Node.Reader reader, TypeDefinition declaringType, List fields, Pass2State state) + void ProcessFields(Schema.Node.READER reader, TypeDefinition declaringType, List fields, Pass2State state) { - if (reader.Fields == null) + if (reader.Struct.Fields == null) { return; } - foreach (var fieldReader in reader.Fields) + foreach (var fieldReader in reader.Struct.Fields) { var field = new Field() { @@ -487,25 +506,25 @@ namespace CapnpC.CSharp.Generator.Model CodeOrder = fieldReader.CodeOrder }; - if (fieldReader.DiscriminantValue != Schema.Field.Reader.NoDiscriminant) + if (fieldReader.DiscriminantValue != NoDiscriminant) { field.DiscValue = fieldReader.DiscriminantValue; } - switch (0) + switch (fieldReader.which) { - case 0 when fieldReader.IsGroup: - var def = ProcessTypeDef(fieldReader.Group_TypeId, state, TypeTag.Group); + case Schema.Field.WHICH.Group: + var def = ProcessTypeDef(fieldReader.Group.TypeId, state, TypeTag.Group); field.Type = Types.FromDefinition(def); def.CsName = field.CsName; // Type definitions for unions are artificially generated. // Transfer the C# name of the using field. break; - case 0 when fieldReader.IsSlot: - field.DefaultValue = ProcessValue(fieldReader.Slot_DefaultValue); - field.DefaultValueIsExplicit = fieldReader.Slot_HadExplicitDefault; - field.Offset = fieldReader.Slot_Offset; - field.Type = ProcessType(fieldReader.Slot_Type, state); + case Schema.Field.WHICH.Slot: + field.DefaultValue = ProcessValue(fieldReader.Slot.DefaultValue); + field.DefaultValueIsExplicit = fieldReader.Slot.HadExplicitDefault; + field.Offset = fieldReader.Slot.Offset; + field.Type = ProcessType(fieldReader.Slot.Type, state); field.DefaultValue.Type = field.Type; break; @@ -519,7 +538,7 @@ namespace CapnpC.CSharp.Generator.Model } } - TypeDefinition ProcessInterfaceOrStructTail(TypeDefinition def, Schema.Node.Reader reader, Pass2State state) + TypeDefinition ProcessInterfaceOrStructTail(TypeDefinition def, Schema.Node.READER reader, Pass2State state) { def.IsGeneric = reader.IsGeneric; @@ -535,9 +554,9 @@ namespace CapnpC.CSharp.Generator.Model ProcessFields(reader, def, def.Fields, state); - if (reader.IsInterface) + if (reader.which == Schema.Node.WHICH.Interface) { - foreach (var methodReader in reader.Interface_Methods) + foreach (var methodReader in reader.Interface.Methods) { var method = new Method() { @@ -590,22 +609,22 @@ namespace CapnpC.CSharp.Generator.Model return def; } - TypeDefinition ProcessStruct(Schema.Node.Reader structReader, TypeDefinition def, Pass2State state) + TypeDefinition ProcessStruct(Schema.Node.READER structReader, TypeDefinition def, Pass2State state) { - def.StructDataWordCount = structReader.Struct_DataWordCount; - def.StructPointerCount = structReader.Struct_PointerCount; + def.StructDataWordCount = structReader.Struct.DataWordCount; + def.StructPointerCount = structReader.Struct.PointerCount; - if (structReader.Struct_DiscriminantCount > 0) + if (structReader.Struct.DiscriminantCount > 0) { def.UnionInfo = new TypeDefinition.DiscriminationInfo( - structReader.Struct_DiscriminantCount, - 16u * structReader.Struct_DiscriminantOffset); + structReader.Struct.DiscriminantCount, + 16u * structReader.Struct.DiscriminantOffset); } return ProcessInterfaceOrStructTail(def, structReader, state); } - TypeDefinition ProcessParameterList(Schema.Node.Reader reader, Schema.Brand.Reader brandReader, List list, Pass2State state) + TypeDefinition ProcessParameterList(Schema.Node.READER reader, Schema.Brand.READER brandReader, List list, Pass2State state) { //# If a named parameter list was specified in the method //# declaration (rather than a single struct parameter type) then a corresponding struct type is @@ -615,7 +634,7 @@ namespace CapnpC.CSharp.Generator.Model //# this a situation where you can't just climb the scope chain to find where a particular //# generic parameter was introduced. Making the `scopeId` zero was a mistake.) - if (!reader.IsStruct) + if (reader.which != Schema.Node.WHICH.Struct) { throw new InvalidSchemaException("Expected a struct"); } @@ -639,9 +658,9 @@ namespace CapnpC.CSharp.Generator.Model } } - TypeDefinition ProcessInterface(Schema.Node.Reader ifaceReader, TypeDefinition def, Pass2State state) + TypeDefinition ProcessInterface(Schema.Node.READER ifaceReader, TypeDefinition def, Pass2State state) { - foreach (var superClassReader in ifaceReader.Interface_Superclasses) + foreach (var superClassReader in ifaceReader.Interface.Superclasses) { var superClass = Types.FromDefinition(ProcessTypeDef(superClassReader.Id, state, TypeTag.Interface)); ProcessBrand(superClassReader.Brand, superClass, state); @@ -651,9 +670,9 @@ namespace CapnpC.CSharp.Generator.Model return ProcessInterfaceOrStructTail(def, ifaceReader, state); } - TypeDefinition ProcessEnum(Schema.Node.Reader enumReader, TypeDefinition def, Pass2State state) + TypeDefinition ProcessEnum(Schema.Node.READER enumReader, TypeDefinition def, Pass2State state) { - foreach (var fieldReader in enumReader.Enumerants) + foreach (var fieldReader in enumReader.Enum.Enumerants) { var field = new Enumerant() { @@ -663,20 +682,15 @@ namespace CapnpC.CSharp.Generator.Model CodeOrder = fieldReader.CodeOrder }; - if (fieldReader.Ordinal_IsExplicit) - { - field.Ordinal = fieldReader.Ordinal_Explicit; - } - def.Enumerants.Add(field); } return def; } - Constant ProcessConst(Schema.Node.Reader constReader, Constant @const, Pass2State state) + Constant ProcessConst(Schema.Node.READER constReader, Constant @const, Pass2State state) { - var value = ProcessValue(constReader.Const_Value); - value.Type = ProcessType(constReader.Const_Type, state); + var value = ProcessValue(constReader.Const.Value); + value.Type = ProcessType(constReader.Const.Type, state); @const.Value = value; return @const; } @@ -694,7 +708,7 @@ namespace CapnpC.CSharp.Generator.Model IDefinition ProcessNode(ulong id, Pass2State state, bool mustExist, TypeTag tag = default) { - if (!(IdToNode(id, mustExist) is Schema.Node.Reader node)) return null; + if (!(IdToNode(id, mustExist) is Schema.Node.READER node)) return null; var kind = node.GetKind(); if (tag == TypeTag.Unknown) tag = kind.GetTypeTag(); var def = _typeDefMgr.GetExistingDef(id, tag); @@ -719,7 +733,7 @@ namespace CapnpC.CSharp.Generator.Model } } - public static SchemaModel Create(Schema.CodeGeneratorRequest.Reader request) + public static SchemaModel Create(Schema.CodeGeneratorRequest.READER request) { var model = new SchemaModel(request); model.Build(); @@ -741,22 +755,24 @@ namespace CapnpC.CSharp.Generator.Model public static class SchemaExtensions { - public static string StrId(this Schema.Node.Reader node) + public static string StrId(this Schema.Node.READER node) => $"0x{node.Id:X}"; public static string StrId(this ulong nodeId) => $"0x{nodeId:X}"; - public static NodeKind GetKind(this Schema.Node.Reader node) + public static NodeKind GetKind(this Schema.Node.READER node) { - if (node.IsStruct) - return node.Struct_IsGroup ? NodeKind.Group : NodeKind.Struct; - if (node.IsInterface) return NodeKind.Interface; - if (node.IsEnum) return NodeKind.Enum; - if (node.IsConst) return NodeKind.Const; - if (node.IsAnnotation) return NodeKind.Annotation; - if (node.IsFile) return NodeKind.File; - return NodeKind.Unknown; + switch (node.which) + { + case Schema.Node.WHICH.Struct: return node.Struct.IsGroup ? NodeKind.Group : NodeKind.Struct; + case Schema.Node.WHICH.Interface: return NodeKind.Interface; + case Schema.Node.WHICH.Enum: return NodeKind.Enum; + case Schema.Node.WHICH.Const: return NodeKind.Const; + case Schema.Node.WHICH.Annotation: return NodeKind.Annotation; + case Schema.Node.WHICH.File: return NodeKind.File; + default: return NodeKind.Unknown; + } } internal static TypeTag GetTypeTag(this NodeKind kind) @@ -771,7 +787,6 @@ namespace CapnpC.CSharp.Generator.Model } } - internal static TypeTag GetTypeTag(this Schema.Node.Reader node) - => node.GetKind().GetTypeTag(); + internal static TypeTag GetTypeTag(this Schema.Node.READER node) => node.GetKind().GetTypeTag(); } } diff --git a/CapnpC.CSharp.Generator/Model/SourceInfo.cs b/CapnpC.CSharp.Generator/Model/SourceInfo.cs new file mode 100644 index 0000000..28ac508 --- /dev/null +++ b/CapnpC.CSharp.Generator/Model/SourceInfo.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CapnpC.CSharp.Generator.Model +{ + class SourceInfo + { + public string DocComment { get; set; } + public IReadOnlyList MemberDocComments { get; set; } + } +} diff --git a/CapnpC.CSharp.Generator/Model/SupportedAnnotations.cs b/CapnpC.CSharp.Generator/Model/SupportedAnnotations.cs index 5951f16..feb3980 100644 --- a/CapnpC.CSharp.Generator/Model/SupportedAnnotations.cs +++ b/CapnpC.CSharp.Generator/Model/SupportedAnnotations.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace CapnpC.CSharp.Generator.Model @@ -19,10 +20,18 @@ namespace CapnpC.CSharp.Generator.Model public const ulong NullableEnable = 0xeb0d831668c6eda1; public const ulong Name = 0xeb0d831668c6eda2; public const ulong EmitNullableDirective = 0xeb0d831668c6eda3; + public const ulong EmitDomainClassesAndInterfaces = 0xeb0d831668c6eda4; + public const ulong TypeVisibility = 0xeb0d831668c6eda6; } } - public static string[] GetNamespaceAnnotation(Schema.Node.Reader fileNode) + public enum TypeVisibility + { + Public = 0, + Internal = 1 + } + + public static string[] GetNamespaceAnnotation(Schema.Node.READER fileNode) { foreach (var annotation in fileNode.Annotations) { @@ -39,7 +48,7 @@ namespace CapnpC.CSharp.Generator.Model return null; } - public static string GetCsName(Schema.Field.Reader node) + public static string GetCsName(Schema.Field.READER node) { foreach (var annotation in node.Annotations) { @@ -51,7 +60,7 @@ namespace CapnpC.CSharp.Generator.Model return null; } - public static string GetCsName(Schema.Node.Reader node) + public static string GetCsName(Schema.Enumerant.READER node) { foreach (var annotation in node.Annotations) { @@ -63,7 +72,7 @@ namespace CapnpC.CSharp.Generator.Model return null; } - public static string GetCsName(Schema.Method.Reader node) + public static string GetCsName(Schema.Node.READER node) { foreach (var annotation in node.Annotations) { @@ -75,11 +84,23 @@ namespace CapnpC.CSharp.Generator.Model return null; } - public static bool? GetNullableEnable(Schema.Node.Reader node) + public static string GetCsName(Schema.Method.READER node) { foreach (var annotation in node.Annotations) { - if (annotation.Id == AnnotationIds.Cs.NullableEnable && annotation.Value.IsBool) + if (annotation.Id == AnnotationIds.Cs.Name) + { + return annotation.Value.Text; + } + } + return null; + } + + public static bool? GetNullableEnable(Schema.Node.READER node) + { + foreach (var annotation in node.Annotations) + { + if (annotation.Id == AnnotationIds.Cs.NullableEnable && annotation.Value.which == Schema.Value.WHICH.Bool) { return annotation.Value.Bool; } @@ -87,16 +108,54 @@ namespace CapnpC.CSharp.Generator.Model return null; } - public static bool? GetEmitNullableDirective(Schema.Node.Reader node) + public static bool? GetEmitNullableDirective(Schema.Node.READER node) { foreach (var annotation in node.Annotations) { - if (annotation.Id == AnnotationIds.Cs.EmitNullableDirective && annotation.Value.IsBool) + if (annotation.Id == AnnotationIds.Cs.EmitNullableDirective && annotation.Value.which == Schema.Value.WHICH.Bool) { return annotation.Value.Bool; } } return null; } + + public static bool? GetEmitDomainClassesAndInterfaces(Schema.Node.READER node) + { + foreach (var annotation in node.Annotations) + { + if (annotation.Id == AnnotationIds.Cs.EmitDomainClassesAndInterfaces && annotation.Value.which == Schema.Value.WHICH.Bool) + { + return annotation.Value.Bool; + } + } + return null; + } + + public static TypeVisibility? GetTypeVisibility(Schema.Node.READER node) + { + foreach (var annotation in node.Annotations) + { + if (annotation.Id == AnnotationIds.Cs.TypeVisibility && annotation.Value.which == Schema.Value.WHICH.Enum) + { + return (TypeVisibility)annotation.Value.Enum; + } + } + return null; + } + + public static string GetHeaderText(SourceInfo sourceInfo) + { + if (sourceInfo.DocComment == null) + return null; + + var lines = sourceInfo.DocComment + .Split('\n') + .Select(line => line.Trim()) + .SkipWhile(line => !line.Equals("$$embed", StringComparison.OrdinalIgnoreCase)) + .Skip(1); + + return string.Join(Environment.NewLine, lines); + } } } diff --git a/CapnpC.CSharp.Generator/Schema/SchemaSerialization.cs b/CapnpC.CSharp.Generator/Schema/SchemaSerialization.cs index 0655f7d..81729b4 100644 --- a/CapnpC.CSharp.Generator/Schema/SchemaSerialization.cs +++ b/CapnpC.CSharp.Generator/Schema/SchemaSerialization.cs @@ -1,1575 +1,4381 @@ -using Capnp; +#pragma warning disable CS1591 +using Capnp; +using Capnp.Rpc; +using System; +using System.CodeDom.Compiler; using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace CapnpC.CSharp.Generator.Schema { - namespace Superclass + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe682ab4cf923a417UL)] + public class Node : ICapnpSerializable { - public struct Reader + public const UInt64 typeId = 0xe682ab4cf923a417UL; + public enum WHICH : ushort { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ulong Id => State.ReadDataULong(0); - public Brand.Reader Brand => State.ReadStruct(0, Schema.Brand.Reader.Create); + File = 0, + Struct = 1, + Enum = 2, + Interface = 3, + Const = 4, + Annotation = 5, + undefined = 65535 } - public class Writer: SerializerState + void ICapnpSerializable.Deserialize(DeserializerState arg_) { - public Writer() + var reader = READER.create(arg_); + switch (reader.which) { - SetStruct(1, 1); + case WHICH.File: + which = reader.which; + break; + case WHICH.Struct: + Struct = CapnpSerializable.Create(reader.Struct); + break; + case WHICH.Enum: + Enum = CapnpSerializable.Create(reader.Enum); + break; + case WHICH.Interface: + Interface = CapnpSerializable.Create(reader.Interface); + break; + case WHICH.Const: + Const = CapnpSerializable.Create(reader.Const); + break; + case WHICH.Annotation: + Annotation = CapnpSerializable.Create(reader.Annotation); + break; + } + + Id = reader.Id; + DisplayName = reader.DisplayName; + DisplayNamePrefixLength = reader.DisplayNamePrefixLength; + ScopeId = reader.ScopeId; + NestedNodes = reader.NestedNodes?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + Annotations = reader.Annotations?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + Parameters = reader.Parameters?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + IsGeneric = reader.IsGeneric; + applyDefaults(); + } + + private WHICH _which = WHICH.undefined; + private object _content; + public WHICH which + { + get => _which; + set + { + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.File: + break; + case WHICH.Struct: + _content = null; + break; + case WHICH.Enum: + _content = null; + break; + case WHICH.Interface: + _content = null; + break; + case WHICH.Const: + _content = null; + break; + case WHICH.Annotation: + _content = null; + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.File: + break; + case WHICH.Struct: + Struct?.serialize(writer.Struct); + break; + case WHICH.Enum: + Enum?.serialize(writer.Enum); + break; + case WHICH.Interface: + Interface?.serialize(writer.Interface); + break; + case WHICH.Const: + Const?.serialize(writer.Const); + break; + case WHICH.Annotation: + Annotation?.serialize(writer.Annotation); + break; + } + + writer.Id = Id; + writer.DisplayName = DisplayName; + writer.DisplayNamePrefixLength = DisplayNamePrefixLength; + writer.ScopeId = ScopeId; + writer.NestedNodes.Init(NestedNodes, (_s1, _v1) => _v1?.serialize(_s1)); + writer.Annotations.Init(Annotations, (_s1, _v1) => _v1?.serialize(_s1)); + writer.Parameters.Init(Parameters, (_s1, _v1) => _v1?.serialize(_s1)); + writer.IsGeneric = IsGeneric; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong Id + { + get; + set; + } + + public string DisplayName + { + get; + set; + } + + public uint DisplayNamePrefixLength + { + get; + set; + } + + public ulong ScopeId + { + get; + set; + } + + public IReadOnlyList NestedNodes + { + get; + set; + } + + public IReadOnlyList Annotations + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Node.@struct Struct + { + get => _which == WHICH.Struct ? (CapnpC.CSharp.Generator.Schema.Node.@struct)_content : null; + set + { + _which = WHICH.Struct; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Node.@enum Enum + { + get => _which == WHICH.Enum ? (CapnpC.CSharp.Generator.Schema.Node.@enum)_content : null; + set + { + _which = WHICH.Enum; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Node.@interface Interface + { + get => _which == WHICH.Interface ? (CapnpC.CSharp.Generator.Schema.Node.@interface)_content : null; + set + { + _which = WHICH.Interface; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Node.@const Const + { + get => _which == WHICH.Const ? (CapnpC.CSharp.Generator.Schema.Node.@const)_content : null; + set + { + _which = WHICH.Const; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Node.annotation Annotation + { + get => _which == WHICH.Annotation ? (CapnpC.CSharp.Generator.Schema.Node.annotation)_content : null; + set + { + _which = WHICH.Annotation; + _content = value; + } + } + + public IReadOnlyList Parameters + { + get; + set; + } + + public bool IsGeneric + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(96U, (ushort)0); + public ulong Id => ctx.ReadDataULong(0UL, 0UL); + public string DisplayName => ctx.ReadText(0, null); + public uint DisplayNamePrefixLength => ctx.ReadDataUInt(64UL, 0U); + public ulong ScopeId => ctx.ReadDataULong(128UL, 0UL); + public IReadOnlyList NestedNodes => ctx.ReadList(1).Cast(CapnpC.CSharp.Generator.Schema.Node.NestedNode.READER.create); + public IReadOnlyList Annotations => ctx.ReadList(2).Cast(CapnpC.CSharp.Generator.Schema.Annotation.READER.create); + public @struct.READER Struct => which == WHICH.Struct ? new @struct.READER(ctx) : default; + public @enum.READER Enum => which == WHICH.Enum ? new @enum.READER(ctx) : default; + public @interface.READER Interface => which == WHICH.Interface ? new @interface.READER(ctx) : default; + public @const.READER Const => which == WHICH.Const ? new @const.READER(ctx) : default; + public annotation.READER Annotation => which == WHICH.Annotation ? new annotation.READER(ctx) : default; + public IReadOnlyList Parameters => ctx.ReadList(5).Cast(CapnpC.CSharp.Generator.Schema.Node.Parameter.READER.create); + public bool IsGeneric => ctx.ReadDataBool(288UL, false); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(5, 6); + } + + public WHICH which + { + get => (WHICH)this.ReadDataUShort(96U, (ushort)0); + set => this.WriteData(96U, (ushort)value, (ushort)0); } public ulong Id { - get => this.ReadDataULong(0); - set => this.WriteData(0, value); - } - - public Brand.Writer Brand - { - get => BuildPointer(0); - set => Link(0, value); - } - } - } - - namespace Method - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public string Name => State.ReadText(0); - public ushort CodeOrder => State.ReadDataUShort(0); - public IReadOnlyList ImplicitParameters => State.ReadListOfStructs(4, Node.Parameter.Reader.Create); - public ulong ParamStructType => State.ReadDataULong(64); - public Brand.Reader ParamBrand => State.ReadStruct(2, Brand.Reader.Create); - public ulong ResultStructType => State.ReadDataULong(128); - public Brand.Reader ResultBrand => State.ReadStruct(3, Brand.Reader.Create); - public IReadOnlyList Annotations => State.ReadListOfStructs(1, Annotation.Reader.Create); - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(5, 3); - } - - public string Name - { - get => ReadText(0); - set => WriteText(0, value); - } - - public ushort CodeOrder - { - get => this.ReadDataUShort(0); - set => this.WriteData(0, value); - } - - public ListOfStructsSerializer ImplicitParameters - { - get => BuildPointer>(4); - set => Link(4, value); - } - - public ref ulong ParamStructType => ref this.RefData(8); - - public Brand.Writer ParamBrand - { - get => BuildPointer(2); - set => Link(2, value); - } - - public ulong ResultStructType - { - get => this.ReadDataULong(128); - set => this.WriteData(128, value); - } - - public Brand.Writer ResultBrand - { - get => BuildPointer(3); - set => Link(3, value); - } - - public ListOfStructsSerializer Annotations - { - get => BuildPointer>(1); - set => Link(1, value); - } - } - } - - namespace Type - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ushort Tag => State.ReadDataUShort(0); - public bool IsVoid => Tag == 0; - public bool IsBool => Tag == 1; - public bool IsInt8 => Tag == 2; - public bool IsInt16 => Tag == 3; - public bool IsInt32 => Tag == 4; - public bool IsInt64 => Tag == 5; - public bool IsUInt8 => Tag == 6; - public bool IsUInt16 => Tag == 7; - public bool IsUInt32 => Tag == 8; - public bool IsUInt64 => Tag == 9; - public bool IsFloat32 => Tag == 10; - public bool IsFloat64 => Tag == 11; - public bool IsText => Tag == 12; - public bool IsData => Tag == 13; - public bool IsList => Tag == 14; - public Reader List_ElementType => IsList ? State.ReadStruct(0, Create) : default; - public bool IsEnum => Tag == 15; - public ulong Enum_TypeId => IsEnum ? State.ReadDataULong(64) : 0; - public Brand.Reader Enum_Brand => IsEnum ? State.ReadStruct(0, Brand.Reader.Create) : default; - public bool IsStruct => Tag == 16; - public ulong Struct_TypeId => IsStruct ? State.ReadDataULong(64) : 0; - public Brand.Reader Struct_Brand => IsStruct ? State.ReadStruct(0, Brand.Reader.Create) : default; - public bool IsInterface => Tag == 17; - public ulong Interface_TypeId => IsInterface ? State.ReadDataULong(64) : 0; - public Brand.Reader Interface_Brand => IsInterface ? State.ReadStruct(0, Brand.Reader.Create) : default; - public bool IsAnyPointer => Tag == 18; - public ushort AnyPointer_Tag => IsAnyPointer ? State.ReadDataUShort(64) : default; - public bool AnyPointer_IsUnconstrained => IsAnyPointer && AnyPointer_Tag == 0; - public ushort AnyPointer_Unconstrained_Tag => AnyPointer_IsUnconstrained ? State.ReadDataUShort(80) : (ushort)0; - public bool AnyPointer_Unconstrained_IsAnyKind => AnyPointer_IsUnconstrained && AnyPointer_Unconstrained_Tag == 0; - public bool AnyPointer_Unconstrained_IsStruct => AnyPointer_IsUnconstrained && AnyPointer_Unconstrained_Tag == 1; - public bool AnyPointer_Unconstrained_IsList => AnyPointer_IsUnconstrained && AnyPointer_Unconstrained_Tag == 2; - public bool AnyPointer_Unconstrained_IsCapability => AnyPointer_IsUnconstrained && AnyPointer_Unconstrained_Tag == 3; - public bool AnyPointer_IsParameter => IsAnyPointer && AnyPointer_Tag == 1; - public ulong AnyPointer_Parameter_ScopeId => AnyPointer_IsParameter ? State.ReadDataULong(128) : 0; - public ushort AnyPointer_Parameter_ParameterIndex => AnyPointer_IsParameter ? State.ReadDataUShort(80) : (ushort)0; - public bool AnyPointer_IsImplicitMethodParameter => AnyPointer_Tag == 2; - public ushort AnyPointer_ImplicitMethodParameter_ParameterIndex => AnyPointer_IsImplicitMethodParameter ? State.ReadDataUShort(80) : default; - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(3, 1); - } - - public ref ushort Tag => ref this.RefData(0); - - public bool IsVoid - { - get => Tag == 0; - set => Tag = 0; - } - - public bool IsBool - { - get => Tag == 1; - set => Tag = 1; - } - - public bool IsInt8 - { - get => Tag == 2; - set => Tag = 2; - } - - public bool IsInt16 - { - get => Tag == 3; - set => Tag = 3; - } - - public bool IsInt32 - { - get => Tag == 4; - set => Tag = 4; - } - - public bool IsInt64 - { - get => Tag == 5; - set => Tag = 5; - } - - public bool IsUInt8 - { - get => Tag == 6; - set => Tag = 6; - } - - public bool IsUInt16 - { - get => Tag == 7; - set => Tag = 7; - } - - public bool IsUInt32 - { - get => Tag == 8; - set => Tag = 8; - } - - public bool IsUInt64 - { - get => Tag == 9; - set => Tag = 9; - } - - public bool IsFloat32 - { - get => Tag == 10; - set => Tag = 10; - } - - public bool IsFloat64 - { - get => Tag == 11; - set => Tag = 11; - } - - public bool IsText - { - get => Tag == 12; - set => Tag = 12; - } - - public bool IsData - { - get => Tag == 13; - set => Tag = 13; - } - - public bool IsList - { - get => Tag == 14; - set => Tag = 14; - } - - public Writer List_ElementType - { - get => IsList ? BuildPointer(0) : default; - set { Link(0, value); } - } - - public bool IsEnum - { - get => Tag == 15; - set => Tag = 15; - } - - public ulong Enum_TypeId - { - get => IsEnum ? this.ReadDataULong(64) : 0; - set { this.WriteData(64, value); } - } - - public Brand.Writer Enum_Brand - { - get => IsEnum ? BuildPointer(0) : default; - set => Link(0, value); - } - - public bool IsStruct - { - get => Tag == 16; - set => Tag = 16; - } - - public ulong Struct_TypeId - { - get => IsStruct ? this.ReadDataULong(64) : 0; - set => this.WriteData(64, value); - } - - public Brand.Writer Struct_Brand - { - get => IsStruct ? BuildPointer(0) : default; - set => Link(0, value); - } - - public bool IsInterface - { - get => Tag == 17; - set => Tag = 17; - } - - public ulong Interface_TypeId - { - get => IsStruct ? this.ReadDataULong(64) : 0; - set => this.WriteData(64, value); - } - - public Brand.Writer Interface_Brand - { - get => IsStruct ? BuildPointer(0) : default; - set => Link(0, value); - } - - public bool IsAnyPointer - { - get => Tag == 18; - set => Tag = 18; - } - - public ushort AnyPointer_Tag - { - get => IsAnyPointer ? this.ReadDataUShort(64) : default; - set => this.WriteData(64, value); - } - - public bool AnyPointer_IsUnconstrained - { - get => IsAnyPointer && AnyPointer_Tag == 0; - set => AnyPointer_Tag = 0; - } - - public ushort AnyPointer_Unconstrained_Tag - { - get => AnyPointer_IsUnconstrained ? this.ReadDataUShort(80) : (ushort)0; - set => this.WriteData(80, value); - } - - public bool AnyPointer_Unconstrained_IsAnyKind - { - get => AnyPointer_IsUnconstrained && AnyPointer_Unconstrained_Tag == 0; - set => AnyPointer_Unconstrained_Tag = 0; - } - - public bool AnyPointer_Unconstrained_IsStruct - { - get => AnyPointer_IsUnconstrained && AnyPointer_Unconstrained_Tag == 1; - set => AnyPointer_Unconstrained_Tag = 1; - } - - public bool AnyPointer_Unconstrained_IsList - { - get => AnyPointer_IsUnconstrained && AnyPointer_Unconstrained_Tag == 2; - set => AnyPointer_Unconstrained_Tag = 2; - } - - public bool AnyPointer_Unconstrained_IsCapability - { - get => AnyPointer_IsUnconstrained && AnyPointer_Unconstrained_Tag == 3; - set => AnyPointer_Unconstrained_Tag = 3; - } - - public bool AnyPointer_IsParameter - { - get => IsAnyPointer && AnyPointer_Tag == 1; - set => AnyPointer_Tag = 1; - } - - public ulong AnyPointer_Parameter_ScopeId - { - get => AnyPointer_IsParameter ? this.ReadDataULong(128) : 0; - set => this.WriteData(128, value); - } - - public ushort AnyPointer_Parameter_ParameterIndex - { - get => AnyPointer_IsParameter ? this.ReadDataUShort(80) : (ushort)0; - set => this.WriteData(80, value); - } - - public bool AnyPointer_IsImplicitMethodParameter - { - get => AnyPointer_Tag == 2; - set => AnyPointer_Tag = 2; - } - - public ushort AnyPointer_ImplicitMethodParameter_ParameterIndex - { - get => AnyPointer_IsImplicitMethodParameter ? this.ReadDataUShort(80) : default; - set => this.WriteData(80, value); - } - } - } - - namespace Brand - { - namespace Scope - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ulong ScopeId => State.ReadDataULong(0); - public ushort Tag => State.ReadDataUShort(64); - public bool IsBind => Tag == 0; - public IReadOnlyList Bind => IsBind ? State.ReadListOfStructs(0, Binding.Reader.Create) : null; - public bool IsInherit => Tag == 1; - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(2, 1); - } - - public ulong ScopeId - { - get => this.ReadDataULong(0); - set => this.WriteData(0, value); - } - - public ushort Tag - { - get => this.ReadDataUShort(64); - set => this.WriteData(64, value); - } - - public bool IsBind - { - get => Tag == 0; - set => Tag = 0; - } - - public ListOfStructsSerializer Bind - { - get => IsBind ? BuildPointer>(0) : default; - set => Link(0, value); - } - - public bool IsInherit - { - get => Tag == 1; - set => Tag = 1; - } - } - - namespace Binding - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ushort Tag => State.ReadDataUShort(0); - public bool IsUnbound => Tag == 0; - public bool IsType => Tag == 1; - public Type.Reader Type => IsType ? State.ReadStruct(0, Schema.Type.Reader.Create) : default; - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(1, 1); - } - - public ushort Tag - { - get => this.ReadDataUShort(0); - set => this.WriteData(0, value); - } - - public bool IsUnbound - { - get => Tag == 0; - set => Tag = 0; - } - - public bool IsType - { - get => Tag == 1; - set => Tag = 1; - } - - public Type.Writer Type - { - get => IsType ? BuildPointer(0) : default; - set => Link(0, value); - } - } - } - } - - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public IReadOnlyList Scopes => State.ReadListOfStructs(0, Scope.Reader.Create); - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(0, 1); - } - - public ListOfStructsSerializer Scopes - { - get => BuildPointer>(0); - set => Link(0, value); - } - } - } - - namespace Value - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ushort Tag => State.ReadDataUShort(0); - public bool IsVoid => Tag == 0; - public bool IsBool => Tag == 1; - public bool Bool => IsBool ? State.ReadDataBool(16) : default; - public bool IsInt8 => Tag == 2; - public sbyte Int8 => IsInt8 ? State.ReadDataSByte(16) : default; - public bool IsInt16 => Tag == 3; - public short Int16 => IsInt16 ? State.ReadDataShort(16) : default; - public bool IsInt32 => Tag == 4; - public int Int32 => IsInt32 ? State.ReadDataInt(32) : default; - public bool IsInt64 => Tag == 5; - public long Int64 => IsInt64 ? State.ReadDataLong(64) : default; - public bool IsUInt8 => Tag == 6; - public byte UInt8 => IsUInt8 ? State.ReadDataByte(16) : default; - public bool IsUInt16 => Tag == 7; - public ushort UInt16 => IsUInt16 ? State.ReadDataUShort(16) : default; - public bool IsUInt32 => Tag == 8; - public uint UInt32 => IsUInt32 ? State.ReadDataUInt(32) : default; - public bool IsUInt64 => Tag == 9; - public ulong UInt64 => IsUInt64 ? State.ReadDataULong(64) : default; - public bool IsFloat32 => Tag == 10; - public float Float32 => IsFloat32 ? State.ReadDataFloat(32) : default; - public bool IsFloat64 => Tag == 11; - public double Float64 => IsFloat64 ? State.ReadDataDouble(64) : default; - public bool IsText => Tag == 12; - public string Text => IsText ? State.ReadText(0) : default; - public bool IsData => Tag == 13; - public ListDeserializer Data => IsData ? State.ReadList(0) : default; - public bool IsList => Tag == 14; - public DeserializerState List => IsList ? State.StructReadPointer(0) : default; - public bool IsEnum => Tag == 15; - public ushort Enum => IsEnum ? State.ReadDataUShort(16) : default; - public bool IsStruct => Tag == 16; - public DeserializerState Struct => IsStruct ? State.StructReadPointer(0) : default; - public bool IsInterface => Tag == 17; - public bool IsAnyPointer => Tag == 18; - public DeserializerState AnyPointer => IsAnyPointer ? State.StructReadPointer(0) : default; - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(2, 1); - } - - public ushort Tag - { - get => this.ReadDataUShort(0); - set => this.WriteData(0, value); - } - - public bool IsVoid - { - get => Tag == 0; - set => Tag = 0; - } - - public bool IsBool - { - get => Tag == 1; - set => Tag = 1; - } - - public bool Bool - { - get => IsBool ? this.ReadDataBool(16) : default; - set => this.WriteData(16, value); - } - - public bool IsInt8 - { - get => Tag == 2; - set => Tag = 2; - } - - public sbyte Int8 - { - get => IsInt8 ? this.ReadDataSByte(16) : default; - set => this.WriteData(16, value); - } - - public bool IsInt16 - { - get => Tag == 3; - set => Tag = 3; - } - - public short Int16 - { - get => IsInt16 ? this.ReadDataShort(16) : default; - set => this.WriteData(16, value); - } - - public bool IsInt32 - { - get => Tag == 4; - set => Tag = 4; - } - - public int Int32 - { - get => IsInt32 ? this.ReadDataInt(32) : default; - set => this.WriteData(32, value); - } - - public bool IsInt64 - { - get => Tag == 5; - set => Tag = 5; - } - - public long Int64 - { - get => IsInt64 ? this.ReadDataLong(64) : default; - set => this.WriteData(64, value); - } - - public bool IsUInt8 - { - get => Tag == 6; - set => Tag = 6; - } - - public byte UInt8 - { - get => IsUInt8 ? this.ReadDataByte(16) : default; - set => this.WriteData(16, value); - } - - public bool IsUInt16 - { - get => Tag == 7; - set => Tag = 7; - } - - public ushort UInt16 - { - get => IsUInt16 ? this.ReadDataUShort(16) : default; - set => this.WriteData(16, value); - } - - public bool IsUInt32 - { - get => Tag == 8; - set => Tag = 8; - } - - public uint UInt32 - { - get => IsUInt32 ? this.ReadDataUInt(32) : default; - set => this.WriteData(32, value); - } - - public bool IsUInt64 - { - get => Tag == 9; - set => Tag = 9; - } - - public ulong UInt64 - { - get => IsUInt64 ? this.ReadDataULong(64) : default; - set => this.WriteData(64, value); - } - - public bool IsFloat32 - { - get => Tag == 10; - set => Tag = 10; - } - - public float Float32 - { - get => IsFloat32 ? this.ReadDataFloat(32) : default; - set => this.WriteData(32, value); - } - - public bool IsFloat64 - { - get => Tag == 11; - set => Tag = 11; - } - - public double Float64 - { - get => IsFloat64 ? this.ReadDataDouble(64) : default; - set => this.WriteData(64, value); - } - - public bool IsText - { - get => Tag == 12; - set => Tag = 12; - } - - public string Text - { - get => IsText ? ReadText(0) : default; - set => WriteText(0, value); - } - - public bool IsData - { - get => Tag == 13; - set => Tag = 13; - } - - public SerializerState Data - { - get => IsData ? BuildPointer(0) : default; - set => Link(0, value); - } - - public bool IsList - { - get => Tag == 14; - set => Tag = 14; - } - - public SerializerState List - { - get => IsList ? BuildPointer(0) : default; - set => Link(0, value); - } - - public bool IsEnum - { - get => Tag == 15; - set => Tag = 15; - } - - public ushort Enum - { - get => IsEnum ? this.ReadDataUShort(16) : default; - set => this.WriteData(16, value); - } - - public bool IsStruct - { - get => Tag == 16; - set => Tag = 16; - } - - public SerializerState Struct - { - get => IsStruct ? BuildPointer(0) : default; - set => Link(0, value); - } - - public bool IsInterface - { - get => Tag == 17; - set => Tag = 17; - } - - public bool IsAnyPointer - { - get => Tag == 18; - set => Tag = 18; - } - - public SerializerState AnyPointer - { - get => IsAnyPointer ? BuildPointer(0) : default; - set => Link(0, value); - } - } - } - - namespace Annotation - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ulong Id => State.ReadDataULong(0); - public Brand.Reader Brand => State.ReadStruct(1, Schema.Brand.Reader.Create); - public Value.Reader Value => State.ReadStruct(0, Schema.Value.Reader.Create); - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(1, 2); - } - - public ref ulong Id => ref this.RefData(0); - - public Brand.Writer Brand - { - get => BuildPointer(1); - set => Link(1, value); - } - - public Value.Writer Value - { - get => BuildPointer(0); - set => Link(0, value); - } - } - } - - public enum ElementSize: ushort - { - Empty = 0, - Bit = 1, - Byte = 2, - TwoBytes = 3, - FourBytes = 4, - EightBytes = 5, - Pointer = 6, - InlineComposite = 7 - } - - namespace Field - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public string Name => State.ReadText(0); - public ushort CodeOrder => State.ReadDataUShort(0); - public IReadOnlyList Annotations => State.ReadListOfStructs(1, Annotation.Reader.Create); - public ushort DiscriminantValue => State.ReadDataUShort(16, 65535); - public ushort Tag => State.ReadDataUShort(64); - public bool IsSlot => Tag == 0; - public uint Slot_Offset => IsSlot ? State.ReadDataUInt(32) : default; - public Type.Reader Slot_Type => IsSlot ? State.ReadStruct(2, Type.Reader.Create) : default; - public Value.Reader Slot_DefaultValue => IsSlot ? State.ReadStruct(3, Value.Reader.Create) : default; - public bool Slot_HadExplicitDefault => IsSlot ? State.ReadDataBool(128) : default; - public bool IsGroup => Tag == 1; - public ulong Group_TypeId => IsGroup ? State.ReadDataULong(128) : default; - public ushort Ordinal_Tag => State.ReadDataUShort(80); - public bool Ordinal_IsImplicit => Ordinal_Tag == 0; - public bool Ordinal_IsExplicit => Ordinal_Tag == 1; - public ushort Ordinal_Explicit => Ordinal_IsExplicit ? State.ReadDataUShort(96) : default; - - public const ushort NoDiscriminant = 0xffff; - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(3, 3); - } - - public string Name - { - get => ReadText(0); - set => WriteText(0, value); - } - - public ref ushort CodeOrder => ref this.RefData(0); - - public ListOfStructsSerializer Annotations - { - get => BuildPointer>(1); - set => Link(1, value); - } - - public ushort DiscriminantValue - { - get => this.ReadDataUShort(16, 65535); - set => this.WriteData(16, value, (ushort)65535); - } - - public ref ushort Tag => ref this.RefData(8); - - public bool IsSlot - { - get => Tag == 0; - set => Tag = 0; - } - - public uint Slot_Offset - { - get => IsSlot ? this.ReadDataUInt(32) : default; - set => this.WriteData(32, value); - } - - public Type.Writer Slot_Type - { - get => IsSlot ? BuildPointer(2) : default; - set => Link(2, value); - } - - public Value.Writer Slot_DefaultValue - { - get => IsSlot ? BuildPointer(3) : default; - set => Link(3, value); - } - - public bool Slot_HadExplicitDefault - { - get => IsSlot ? this.ReadDataBool(128) : default; - set => this.WriteData(128, value); - } - - public bool IsGroup - { - get => Tag == 1; - set => Tag = 1; - } - - public ref ulong Group_TypeId => ref this.RefData(2); - - public ref ushort Ordinal_Tag => ref this.RefData(5); - - public bool Ordinal_IsImplicit - { - get => Ordinal_Tag == 0; - set => Ordinal_Tag = 0; - } - - public bool Ordinal_IsExplicit - { - get => Ordinal_Tag == 1; - set => Ordinal_Tag = 1; - } - - public ref ushort Ordinal_Explicit => ref this.RefData(6); - } - } - - namespace Node - { - namespace Parameter - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public string Name => State.ReadText(0); - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(0, 1); - } - - public string Name - { - get => ReadText(0); - set => WriteText(0, value); - } - } - } - - namespace NestedNode - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public string Name => State.ReadText(0); - public ulong Id => State.ReadDataULong(0); - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(1, 1); - } - - public string Name - { - get => ReadText(0); - set => WriteText(0, value); - } - - public ref ulong Id => ref this.RefData(0); - } - } - - namespace SourceInfo - { - namespace Member - { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public string DocComment => State.ReadText(0); - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(0, 1); - } - - public string DocComment - { - get => ReadText(0); - set => WriteText(0, value); - } - } - } - - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ulong Id => State.ReadDataULong(0); - public string DocComment => State.ReadText(0); - public IReadOnlyList Members => State.ReadListOfStructs(1, Member.Reader.Create); - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(1, 2); - } - - public ref ulong Id => ref this.RefData(0); - - public string DocComment - { - get => ReadText(0); - set => WriteText(0, value); - } - - public ListOfStructsSerializer Members - { - get => BuildPointer>(1); - set => Link(1, value); - } - } - } - - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ulong Id => State.ReadDataULong(0); - public string DisplayName => State.ReadText(0); - public uint DisplayNamePrefixLength => State.ReadDataUInt(64); - public ulong ScopeId => State.ReadDataULong(128); - public IReadOnlyList Parameters => State.ReadListOfStructs(5, Parameter.Reader.Create); - public bool IsGeneric => State.ReadDataBool(288); - public IReadOnlyList NestedNodes => State.ReadListOfStructs(1, NestedNode.Reader.Create); - public IReadOnlyList Annotations => State.ReadListOfStructs(2, Annotation.Reader.Create); - public ushort Tag => State.ReadDataUShort(96); - public bool IsFile => Tag == 0; - public bool IsStruct => Tag == 1; - public ushort Struct_DataWordCount => IsStruct ? State.ReadDataUShort(112) : default; - public ushort Struct_PointerCount => IsStruct ? State.ReadDataUShort(192) : default; - public ElementSize Struct_PreferredListEncoding => IsStruct ? (ElementSize)State.ReadDataUShort(208) : default; - public bool Struct_IsGroup => IsStruct ? State.ReadDataBool(224) : default; - public ushort Struct_DiscriminantCount => IsStruct ? State.ReadDataUShort(240) : default; - public uint Struct_DiscriminantOffset => IsStruct ? State.ReadDataUInt(256) : default; - public IReadOnlyList Fields => IsStruct ? State.ReadListOfStructs(3, Field.Reader.Create) : default; - public bool IsEnum => Tag == 2; - public IReadOnlyList Enumerants => IsEnum ? State.ReadListOfStructs(3, Field.Reader.Create) : default; - public bool IsInterface => Tag == 3; - public IReadOnlyList Interface_Methods => IsInterface ? State.ReadListOfStructs(3, Method.Reader.Create) : default; - public IReadOnlyList Interface_Superclasses => IsInterface ? State.ReadListOfStructs(4, Superclass.Reader.Create) : default; - public bool IsConst => Tag == 4; - public Type.Reader Const_Type => IsConst ? State.ReadStruct(3, Type.Reader.Create) : default; - public Value.Reader Const_Value => IsConst ? State.ReadStruct(4, Value.Reader.Create) : default; - public bool IsAnnotation => Tag == 5; - public Type.Reader Annotation_Type => IsAnnotation ? State.ReadStruct(3, Type.Reader.Create) : default; - public bool Annotation_TargetsFile => IsAnnotation ? State.ReadDataBool(112) : default; - public bool Annotation_TargetsConst => IsAnnotation ? State.ReadDataBool(113) : default; - public bool Annotation_TargetsEnum => IsAnnotation ? State.ReadDataBool(114) : default; - public bool Annotation_TargetsEnumerant => IsAnnotation ? State.ReadDataBool(115) : default; - public bool Annotation_TargetsStruct => IsAnnotation ? State.ReadDataBool(116) : default; - public bool Annotation_TargetsField => IsAnnotation ? State.ReadDataBool(117) : default; - public bool Annotation_TargetsUnion => IsAnnotation ? State.ReadDataBool(118) : default; - public bool Annotation_TargetsGroup => IsAnnotation ? State.ReadDataBool(119) : default; - public bool Annotation_TargetsInterface => IsAnnotation ? State.ReadDataBool(120) : default; - public bool Annotation_TargetsMethod => IsAnnotation ? State.ReadDataBool(121) : default; - public bool Annotation_TargetsParam => IsAnnotation ? State.ReadDataBool(122) : default; - public bool Annotation_TargetsAnnotation => IsAnnotation ? State.ReadDataBool(123) : default; - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(5, 6); - } - - public ulong Id - { - get => this.ReadDataULong(0); - set => this.WriteData(0, value); + get => this.ReadDataULong(0UL, 0UL); + set => this.WriteData(0UL, value, 0UL); } public string DisplayName { - get => ReadText(0); - set => WriteText(0, value); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } - public ref uint DisplayNamePrefixLength => ref this.RefData(2); - - public ref ulong ScopeId => ref this.RefData(2); - - public ListOfStructsSerializer Parameters + public uint DisplayNamePrefixLength { - get => BuildPointer>(5); + get => this.ReadDataUInt(64UL, 0U); + set => this.WriteData(64UL, value, 0U); + } + + public ulong ScopeId + { + get => this.ReadDataULong(128UL, 0UL); + set => this.WriteData(128UL, value, 0UL); + } + + public ListOfStructsSerializer NestedNodes + { + get => BuildPointer>(1); + set => Link(1, value); + } + + public ListOfStructsSerializer Annotations + { + get => BuildPointer>(2); + set => Link(2, value); + } + + public @struct.WRITER Struct + { + get => which == WHICH.Struct ? Rewrap<@struct.WRITER>() : default; + } + + public @enum.WRITER Enum + { + get => which == WHICH.Enum ? Rewrap<@enum.WRITER>() : default; + } + + public @interface.WRITER Interface + { + get => which == WHICH.Interface ? Rewrap<@interface.WRITER>() : default; + } + + public @const.WRITER Const + { + get => which == WHICH.Const ? Rewrap<@const.WRITER>() : default; + } + + public annotation.WRITER Annotation + { + get => which == WHICH.Annotation ? Rewrap() : default; + } + + public ListOfStructsSerializer Parameters + { + get => BuildPointer>(5); set => Link(5, value); } public bool IsGeneric { - get => this.ReadDataBool(288); - set => this.WriteData(288, value); - } - - public ListOfStructsSerializer NestedNodes - { - get => BuildPointer>(1); - set => Link(1, value); - } - - public ListOfStructsSerializer Annotations - { - get => BuildPointer>(2); - set => Link(2, value); - } - - public ref ushort Tag => ref this.RefData(6); - - public bool IsFile - { - get => Tag == 0; - set => Tag = 0; - } - - public bool IsStruct - { - get => Tag == 1; - set => Tag = 1; - } - - public ref ushort Struct_DataWordCount => ref this.RefData(7); - - public ref ushort Struct_PointerCount => ref this.RefData(12); - - public ref ElementSize Struct_PreferredListEncoding => ref this.RefData(13); - - public bool Struct_IsGroup - { - get => IsStruct ? this.ReadDataBool(224) : default; - set => this.WriteData(224, value); - } - - public ref ushort Struct_DiscriminantCount => ref this.RefData(15); - - public ref uint Struct_DiscriminantOffset => ref this.RefData(8); - - public ListOfStructsSerializer Fields - { - get => BuildPointer>(3); - set => Link(3, value); - } - - public bool IsEnum - { - get => Tag == 2; - set => Tag = 2; - } - - public ListOfStructsSerializer Enumerants - { - get => BuildPointer>(3); - set => Link(3, value); - } - - public bool IsInterface - { - get => Tag == 3; - set => Tag = 3; - } - - public ListOfStructsSerializer Interface_Methods - { - get => BuildPointer>(3); - set => Link(3, value); - } - - public ListOfStructsSerializer Interface_Superclasses - { - get => IsInterface ? BuildPointer>(4) : default; - set => Link(4, value); - } - - public bool IsConst - { - get => Tag == 4; - set => Tag = 4; - } - - public Type.Writer Const_Type - { - get => IsConst ? BuildPointer(3) : default; - set => Link(3, value); - } - - public Value.Writer Const_Value - { - get => IsConst ? BuildPointer(4) : default; - set => Link(4, value); - } - - public bool IsAnnotation - { - get => Tag == 5; - set => Tag = 5; - } - - public Type.Writer Annotation_Type - { - get => IsAnnotation ? BuildPointer(3) : default; - set => Link(3, value); - } - - public bool Annotation_TargetsFile - { - get => IsAnnotation ? this.ReadDataBool(112) : default; - set => this.WriteData(112, value); - } - - public bool Annotation_TargetsConst - { - get => IsAnnotation ? this.ReadDataBool(113) : default; - set => this.WriteData(113, value); - } - - public bool Annotation_TargetsEnum - { - get => IsAnnotation ? this.ReadDataBool(114) : default; - set => this.WriteData(114, value); - } - - public bool Annotation_TargetsEnumerant - { - get => IsAnnotation ? this.ReadDataBool(115) : default; - set => this.WriteData(115, value); - } - - public bool Annotation_TargetsStruct - { - get => IsAnnotation ? this.ReadDataBool(116) : default; - set => this.WriteData(116, value); - } - - public bool Annotation_TargetsField - { - get => IsAnnotation ? this.ReadDataBool(117) : default; - set => this.WriteData(117, value); - } - - public bool Annotation_TargetsUnion - { - get => IsAnnotation ? this.ReadDataBool(118) : default; - set => this.WriteData(118, value); - } - - public bool Annotation_TargetsGroup - { - get => IsAnnotation ? this.ReadDataBool(119) : default; - set => this.WriteData(119, value); - } - - public bool Annotation_TargetsInterface - { - get => IsAnnotation ? this.ReadDataBool(120) : default; - set => this.WriteData(120, value); - } - - public bool Annotation_TargetsMethod - { - get => IsAnnotation ? this.ReadDataBool(121) : default; - set => this.WriteData(121, value); - } - - public bool Annotation_TargetsParam - { - get => IsAnnotation ? this.ReadDataBool(122) : default; - set => this.WriteData(122, value); - } - - public bool Annotation_TargetsAnnotation - { - get => IsAnnotation ? this.ReadDataBool(123) : default; - set => this.WriteData(123, value); + get => this.ReadDataBool(288UL, false); + set => this.WriteData(288UL, value, false); } } - } - namespace CapnpVersion - { - public struct Reader + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9ea0b19b37fb4435UL)] + public class @struct : ICapnpSerializable { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) + public const UInt64 typeId = 0x9ea0b19b37fb4435UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) { - State = ctx; + var reader = READER.create(arg_); + DataWordCount = reader.DataWordCount; + PointerCount = reader.PointerCount; + PreferredListEncoding = reader.PreferredListEncoding; + IsGroup = reader.IsGroup; + DiscriminantCount = reader.DiscriminantCount; + DiscriminantOffset = reader.DiscriminantOffset; + Fields = reader.Fields?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); } - public static Reader Create(DeserializerState ctx) => new Reader(ctx); + public void serialize(WRITER writer) + { + writer.DataWordCount = DataWordCount; + writer.PointerCount = PointerCount; + writer.PreferredListEncoding = PreferredListEncoding; + writer.IsGroup = IsGroup; + writer.DiscriminantCount = DiscriminantCount; + writer.DiscriminantOffset = DiscriminantOffset; + writer.Fields.Init(Fields, (_s1, _v1) => _v1?.serialize(_s1)); + } - public ushort Major => State.ReadDataUShort(0); - public byte Minor => State.ReadDataByte(16); - public byte Micro => State.ReadDataByte(24); + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ushort DataWordCount + { + get; + set; + } + + public ushort PointerCount + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.ElementSize PreferredListEncoding + { + get; + set; + } + + public bool IsGroup + { + get; + set; + } + + public ushort DiscriminantCount + { + get; + set; + } + + public uint DiscriminantOffset + { + get; + set; + } + + public IReadOnlyList Fields + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ushort DataWordCount => ctx.ReadDataUShort(112UL, (ushort)0); + public ushort PointerCount => ctx.ReadDataUShort(192UL, (ushort)0); + public CapnpC.CSharp.Generator.Schema.ElementSize PreferredListEncoding => (CapnpC.CSharp.Generator.Schema.ElementSize)ctx.ReadDataUShort(208UL, (ushort)0); + public bool IsGroup => ctx.ReadDataBool(224UL, false); + public ushort DiscriminantCount => ctx.ReadDataUShort(240UL, (ushort)0); + public uint DiscriminantOffset => ctx.ReadDataUInt(256UL, 0U); + public IReadOnlyList Fields => ctx.ReadList(3).Cast(CapnpC.CSharp.Generator.Schema.Field.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public ushort DataWordCount + { + get => this.ReadDataUShort(112UL, (ushort)0); + set => this.WriteData(112UL, value, (ushort)0); + } + + public ushort PointerCount + { + get => this.ReadDataUShort(192UL, (ushort)0); + set => this.WriteData(192UL, value, (ushort)0); + } + + public CapnpC.CSharp.Generator.Schema.ElementSize PreferredListEncoding + { + get => (CapnpC.CSharp.Generator.Schema.ElementSize)this.ReadDataUShort(208UL, (ushort)0); + set => this.WriteData(208UL, (ushort)value, (ushort)0); + } + + public bool IsGroup + { + get => this.ReadDataBool(224UL, false); + set => this.WriteData(224UL, value, false); + } + + public ushort DiscriminantCount + { + get => this.ReadDataUShort(240UL, (ushort)0); + set => this.WriteData(240UL, value, (ushort)0); + } + + public uint DiscriminantOffset + { + get => this.ReadDataUInt(256UL, 0U); + set => this.WriteData(256UL, value, 0U); + } + + public ListOfStructsSerializer Fields + { + get => BuildPointer>(3); + set => Link(3, value); + } + } } - public class Writer: SerializerState + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb54ab3364333f598UL)] + public class @enum : ICapnpSerializable { - public Writer() + public const UInt64 typeId = 0xb54ab3364333f598UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) { - SetStruct(1, 0); + var reader = READER.create(arg_); + Enumerants = reader.Enumerants?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); } - public ref ushort Major => ref this.RefData(0); - public ref byte Minor => ref this.RefData(2); - public ref byte Micro => ref this.RefData(3); + public void serialize(WRITER writer) + { + writer.Enumerants.Init(Enumerants, (_s1, _v1) => _v1?.serialize(_s1)); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public IReadOnlyList Enumerants + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public IReadOnlyList Enumerants => ctx.ReadList(3).Cast(CapnpC.CSharp.Generator.Schema.Enumerant.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public ListOfStructsSerializer Enumerants + { + get => BuildPointer>(3); + set => Link(3, value); + } + } } - } - namespace CodeGeneratorRequest - { - namespace RequestedFile + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xe82753cff0c2218fUL)] + public class @interface : ICapnpSerializable { - namespace Import + public const UInt64 typeId = 0xe82753cff0c2218fUL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) { - public struct Reader - { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ulong Id => State.ReadDataULong(0); - public string Name => State.ReadText(0); - } - - public class Writer: SerializerState - { - public Writer() - { - SetStruct(1, 1); - } - - public ref ulong Id => ref this.RefData(0); - - public string Name - { - get => ReadText(0); - set => WriteText(0, value); - } - } + var reader = READER.create(arg_); + Methods = reader.Methods?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + Superclasses = reader.Superclasses?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); } - public struct Reader + public void serialize(WRITER writer) { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) - { - State = ctx; - } - - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public ulong Id => State.ReadDataULong(0); - public string Filename => State.ReadText(0); - public IReadOnlyList Imports => State.ReadListOfStructs(1, Import.Reader.Create); + writer.Methods.Init(Methods, (_s1, _v1) => _v1?.serialize(_s1)); + writer.Superclasses.Init(Superclasses, (_s1, _v1) => _v1?.serialize(_s1)); } - public class Writer: SerializerState + void ICapnpSerializable.Serialize(SerializerState arg_) { - public Writer() + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public IReadOnlyList Methods + { + get; + set; + } + + public IReadOnlyList Superclasses + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) { - SetStruct(1, 2); + this.ctx = ctx; } - public ref ulong Id => ref this.RefData(0); + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public IReadOnlyList Methods => ctx.ReadList(3).Cast(CapnpC.CSharp.Generator.Schema.Method.READER.create); + public IReadOnlyList Superclasses => ctx.ReadList(4).Cast(CapnpC.CSharp.Generator.Schema.Superclass.READER.create); + } - public string Filename + public class WRITER : SerializerState + { + public WRITER() { - get => ReadText(0); - set => WriteText(0, value); } - public ListOfStructsSerializer Imports + public ListOfStructsSerializer Methods { - get => BuildPointer>(1); + get => BuildPointer>(3); + set => Link(3, value); + } + + public ListOfStructsSerializer Superclasses + { + get => BuildPointer>(4); + set => Link(4, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb18aa5ac7a0d9420UL)] + public class @const : ICapnpSerializable + { + public const UInt64 typeId = 0xb18aa5ac7a0d9420UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Type = CapnpSerializable.Create(reader.Type); + Value = CapnpSerializable.Create(reader.Value); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + Type?.serialize(writer.Type); + Value?.serialize(writer.Value); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public CapnpC.CSharp.Generator.Schema.Type Type + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Value Value + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public CapnpC.CSharp.Generator.Schema.Type.READER Type => ctx.ReadStruct(3, CapnpC.CSharp.Generator.Schema.Type.READER.create); + public CapnpC.CSharp.Generator.Schema.Value.READER Value => ctx.ReadStruct(4, CapnpC.CSharp.Generator.Schema.Value.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public CapnpC.CSharp.Generator.Schema.Type.WRITER Type + { + get => BuildPointer(3); + set => Link(3, value); + } + + public CapnpC.CSharp.Generator.Schema.Value.WRITER Value + { + get => BuildPointer(4); + set => Link(4, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xec1619d4400a0290UL)] + public class annotation : ICapnpSerializable + { + public const UInt64 typeId = 0xec1619d4400a0290UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Type = CapnpSerializable.Create(reader.Type); + TargetsFile = reader.TargetsFile; + TargetsConst = reader.TargetsConst; + TargetsEnum = reader.TargetsEnum; + TargetsEnumerant = reader.TargetsEnumerant; + TargetsStruct = reader.TargetsStruct; + TargetsField = reader.TargetsField; + TargetsUnion = reader.TargetsUnion; + TargetsGroup = reader.TargetsGroup; + TargetsInterface = reader.TargetsInterface; + TargetsMethod = reader.TargetsMethod; + TargetsParam = reader.TargetsParam; + TargetsAnnotation = reader.TargetsAnnotation; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + Type?.serialize(writer.Type); + writer.TargetsFile = TargetsFile; + writer.TargetsConst = TargetsConst; + writer.TargetsEnum = TargetsEnum; + writer.TargetsEnumerant = TargetsEnumerant; + writer.TargetsStruct = TargetsStruct; + writer.TargetsField = TargetsField; + writer.TargetsUnion = TargetsUnion; + writer.TargetsGroup = TargetsGroup; + writer.TargetsInterface = TargetsInterface; + writer.TargetsMethod = TargetsMethod; + writer.TargetsParam = TargetsParam; + writer.TargetsAnnotation = TargetsAnnotation; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public CapnpC.CSharp.Generator.Schema.Type Type + { + get; + set; + } + + public bool TargetsFile + { + get; + set; + } + + public bool TargetsConst + { + get; + set; + } + + public bool TargetsEnum + { + get; + set; + } + + public bool TargetsEnumerant + { + get; + set; + } + + public bool TargetsStruct + { + get; + set; + } + + public bool TargetsField + { + get; + set; + } + + public bool TargetsUnion + { + get; + set; + } + + public bool TargetsGroup + { + get; + set; + } + + public bool TargetsInterface + { + get; + set; + } + + public bool TargetsMethod + { + get; + set; + } + + public bool TargetsParam + { + get; + set; + } + + public bool TargetsAnnotation + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public CapnpC.CSharp.Generator.Schema.Type.READER Type => ctx.ReadStruct(3, CapnpC.CSharp.Generator.Schema.Type.READER.create); + public bool TargetsFile => ctx.ReadDataBool(112UL, false); + public bool TargetsConst => ctx.ReadDataBool(113UL, false); + public bool TargetsEnum => ctx.ReadDataBool(114UL, false); + public bool TargetsEnumerant => ctx.ReadDataBool(115UL, false); + public bool TargetsStruct => ctx.ReadDataBool(116UL, false); + public bool TargetsField => ctx.ReadDataBool(117UL, false); + public bool TargetsUnion => ctx.ReadDataBool(118UL, false); + public bool TargetsGroup => ctx.ReadDataBool(119UL, false); + public bool TargetsInterface => ctx.ReadDataBool(120UL, false); + public bool TargetsMethod => ctx.ReadDataBool(121UL, false); + public bool TargetsParam => ctx.ReadDataBool(122UL, false); + public bool TargetsAnnotation => ctx.ReadDataBool(123UL, false); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public CapnpC.CSharp.Generator.Schema.Type.WRITER Type + { + get => BuildPointer(3); + set => Link(3, value); + } + + public bool TargetsFile + { + get => this.ReadDataBool(112UL, false); + set => this.WriteData(112UL, value, false); + } + + public bool TargetsConst + { + get => this.ReadDataBool(113UL, false); + set => this.WriteData(113UL, value, false); + } + + public bool TargetsEnum + { + get => this.ReadDataBool(114UL, false); + set => this.WriteData(114UL, value, false); + } + + public bool TargetsEnumerant + { + get => this.ReadDataBool(115UL, false); + set => this.WriteData(115UL, value, false); + } + + public bool TargetsStruct + { + get => this.ReadDataBool(116UL, false); + set => this.WriteData(116UL, value, false); + } + + public bool TargetsField + { + get => this.ReadDataBool(117UL, false); + set => this.WriteData(117UL, value, false); + } + + public bool TargetsUnion + { + get => this.ReadDataBool(118UL, false); + set => this.WriteData(118UL, value, false); + } + + public bool TargetsGroup + { + get => this.ReadDataBool(119UL, false); + set => this.WriteData(119UL, value, false); + } + + public bool TargetsInterface + { + get => this.ReadDataBool(120UL, false); + set => this.WriteData(120UL, value, false); + } + + public bool TargetsMethod + { + get => this.ReadDataBool(121UL, false); + set => this.WriteData(121UL, value, false); + } + + public bool TargetsParam + { + get => this.ReadDataBool(122UL, false); + set => this.WriteData(122UL, value, false); + } + + public bool TargetsAnnotation + { + get => this.ReadDataBool(123UL, false); + set => this.WriteData(123UL, value, false); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xb9521bccf10fa3b1UL)] + public class Parameter : ICapnpSerializable + { + public const UInt64 typeId = 0xb9521bccf10fa3b1UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Name = reader.Name; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Name = Name; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public string Name + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public string Name => ctx.ReadText(0, null); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(0, 1); + } + + public string Name + { + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xdebf55bbfa0fc242UL)] + public class NestedNode : ICapnpSerializable + { + public const UInt64 typeId = 0xdebf55bbfa0fc242UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Name = reader.Name; + Id = reader.Id; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Name = Name; + writer.Id = Id; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public string Name + { + get; + set; + } + + public ulong Id + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public string Name => ctx.ReadText(0, null); + public ulong Id => ctx.ReadDataULong(0UL, 0UL); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 1); + } + + public string Name + { + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + + public ulong Id + { + get => this.ReadDataULong(0UL, 0UL); + set => this.WriteData(0UL, value, 0UL); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf38e1de3041357aeUL)] + public class SourceInfo : ICapnpSerializable + { + public const UInt64 typeId = 0xf38e1de3041357aeUL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Id = reader.Id; + DocComment = reader.DocComment; + Members = reader.Members?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Id = Id; + writer.DocComment = DocComment; + writer.Members.Init(Members, (_s1, _v1) => _v1?.serialize(_s1)); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong Id + { + get; + set; + } + + public string DocComment + { + get; + set; + } + + public IReadOnlyList Members + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong Id => ctx.ReadDataULong(0UL, 0UL); + public string DocComment => ctx.ReadText(0, null); + public IReadOnlyList Members => ctx.ReadList(1).Cast(CapnpC.CSharp.Generator.Schema.Node.SourceInfo.Member.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 2); + } + + public ulong Id + { + get => this.ReadDataULong(0UL, 0UL); + set => this.WriteData(0UL, value, 0UL); + } + + public string DocComment + { + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + + public ListOfStructsSerializer Members + { + get => BuildPointer>(1); set => Link(1, value); } } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc2ba9038898e1fa2UL)] + public class Member : ICapnpSerializable + { + public const UInt64 typeId = 0xc2ba9038898e1fa2UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + DocComment = reader.DocComment; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.DocComment = DocComment; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public string DocComment + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public string DocComment => ctx.ReadText(0, null); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(0, 1); + } + + public string DocComment + { + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + } + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9aad50a41f4af45fUL)] + public class Field : ICapnpSerializable + { + public const UInt64 typeId = 0x9aad50a41f4af45fUL; + public enum WHICH : ushort + { + Slot = 0, + Group = 1, + undefined = 65535 } - public struct Reader + void ICapnpSerializable.Deserialize(DeserializerState arg_) { - public DeserializerState State { get; } - - public Reader(DeserializerState ctx) + var reader = READER.create(arg_); + switch (reader.which) { - State = ctx; + case WHICH.Slot: + Slot = CapnpSerializable.Create(reader.Slot); + break; + case WHICH.Group: + Group = CapnpSerializable.Create(reader.Group); + break; } - public static Reader Create(DeserializerState ctx) => new Reader(ctx); - - public CapnpVersion.Reader CapnpVersion => State.ReadStruct(2, Schema.CapnpVersion.Reader.Create); - public IReadOnlyList Nodes => State.ReadListOfStructs(0, Node.Reader.Create); - public IReadOnlyList SourceInfo => State.ReadListOfStructs(3, Node.SourceInfo.Reader.Create); - public IReadOnlyList RequestedFiles => State.ReadListOfStructs(1, RequestedFile.Reader.Create); + Name = reader.Name; + CodeOrder = reader.CodeOrder; + Annotations = reader.Annotations?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + DiscriminantValue = reader.DiscriminantValue; + Ordinal = CapnpSerializable.Create(reader.Ordinal); + applyDefaults(); } - public class Writer: SerializerState + private WHICH _which = WHICH.undefined; + private object _content; + public WHICH which { - public Writer() + get => _which; + set { - SetStruct(0, 3); + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.Slot: + _content = null; + break; + case WHICH.Group: + _content = null; + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.Slot: + Slot?.serialize(writer.Slot); + break; + case WHICH.Group: + Group?.serialize(writer.Group); + break; } - public CapnpVersion.Writer CapnpVersion + writer.Name = Name; + writer.CodeOrder = CodeOrder; + writer.Annotations.Init(Annotations, (_s1, _v1) => _v1?.serialize(_s1)); + writer.DiscriminantValue = DiscriminantValue; + Ordinal?.serialize(writer.Ordinal); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public string Name + { + get; + set; + } + + public ushort CodeOrder + { + get; + set; + } + + public IReadOnlyList Annotations + { + get; + set; + } + + public ushort DiscriminantValue + { + get; + set; + } + + = 65535; + public CapnpC.CSharp.Generator.Schema.Field.slot Slot + { + get => _which == WHICH.Slot ? (CapnpC.CSharp.Generator.Schema.Field.slot)_content : null; + set { - get => BuildPointer(2); - set => Link(2, value); + _which = WHICH.Slot; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Field.@group Group + { + get => _which == WHICH.Group ? (CapnpC.CSharp.Generator.Schema.Field.@group)_content : null; + set + { + _which = WHICH.Group; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Field.ordinal Ordinal + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; } - public ListOfStructsSerializer Nodes + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(64U, (ushort)0); + public string Name => ctx.ReadText(0, null); + public ushort CodeOrder => ctx.ReadDataUShort(0UL, (ushort)0); + public IReadOnlyList Annotations => ctx.ReadList(1).Cast(CapnpC.CSharp.Generator.Schema.Annotation.READER.create); + public ushort DiscriminantValue => ctx.ReadDataUShort(16UL, (ushort)65535); + public slot.READER Slot => which == WHICH.Slot ? new slot.READER(ctx) : default; + public @group.READER Group => which == WHICH.Group ? new @group.READER(ctx) : default; + public ordinal.READER Ordinal => new ordinal.READER(ctx); + } + + public class WRITER : SerializerState + { + public WRITER() { - get => BuildPointer>(0); - set => Link(0, value); + this.SetStruct(3, 4); } - public ListOfStructsSerializer SourceInfo + public WHICH which { - get => BuildPointer>(3); - set => Link(3, value); + get => (WHICH)this.ReadDataUShort(64U, (ushort)0); + set => this.WriteData(64U, (ushort)value, (ushort)0); } - public ListOfStructsSerializer RequestedFiles + public string Name { - get => BuildPointer>(1); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + + public ushort CodeOrder + { + get => this.ReadDataUShort(0UL, (ushort)0); + set => this.WriteData(0UL, value, (ushort)0); + } + + public ListOfStructsSerializer Annotations + { + get => BuildPointer>(1); + set => Link(1, value); + } + + public ushort DiscriminantValue + { + get => this.ReadDataUShort(16UL, (ushort)65535); + set => this.WriteData(16UL, value, (ushort)65535); + } + + public slot.WRITER Slot + { + get => which == WHICH.Slot ? Rewrap() : default; + } + + public @group.WRITER Group + { + get => which == WHICH.Group ? Rewrap<@group.WRITER>() : default; + } + + public ordinal.WRITER Ordinal + { + get => Rewrap(); + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc42305476bb4746fUL)] + public class slot : ICapnpSerializable + { + public const UInt64 typeId = 0xc42305476bb4746fUL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Offset = reader.Offset; + Type = CapnpSerializable.Create(reader.Type); + DefaultValue = CapnpSerializable.Create(reader.DefaultValue); + HadExplicitDefault = reader.HadExplicitDefault; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Offset = Offset; + Type?.serialize(writer.Type); + DefaultValue?.serialize(writer.DefaultValue); + writer.HadExplicitDefault = HadExplicitDefault; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public uint Offset + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Type Type + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Value DefaultValue + { + get; + set; + } + + public bool HadExplicitDefault + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public uint Offset => ctx.ReadDataUInt(32UL, 0U); + public CapnpC.CSharp.Generator.Schema.Type.READER Type => ctx.ReadStruct(2, CapnpC.CSharp.Generator.Schema.Type.READER.create); + public CapnpC.CSharp.Generator.Schema.Value.READER DefaultValue => ctx.ReadStruct(3, CapnpC.CSharp.Generator.Schema.Value.READER.create); + public bool HadExplicitDefault => ctx.ReadDataBool(128UL, false); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public uint Offset + { + get => this.ReadDataUInt(32UL, 0U); + set => this.WriteData(32UL, value, 0U); + } + + public CapnpC.CSharp.Generator.Schema.Type.WRITER Type + { + get => BuildPointer(2); + set => Link(2, value); + } + + public CapnpC.CSharp.Generator.Schema.Value.WRITER DefaultValue + { + get => BuildPointer(3); + set => Link(3, value); + } + + public bool HadExplicitDefault + { + get => this.ReadDataBool(128UL, false); + set => this.WriteData(128UL, value, false); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xcafccddb68db1d11UL)] + public class @group : ICapnpSerializable + { + public const UInt64 typeId = 0xcafccddb68db1d11UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + TypeId = reader.TypeId; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.TypeId = TypeId; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong TypeId + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong TypeId => ctx.ReadDataULong(128UL, 0UL); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public ulong TypeId + { + get => this.ReadDataULong(128UL, 0UL); + set => this.WriteData(128UL, value, 0UL); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbb90d5c287870be6UL)] + public class ordinal : ICapnpSerializable + { + public const UInt64 typeId = 0xbb90d5c287870be6UL; + public enum WHICH : ushort + { + Implicit = 0, + Explicit = 1, + undefined = 65535 + } + + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + switch (reader.which) + { + case WHICH.Implicit: + which = reader.which; + break; + case WHICH.Explicit: + Explicit = reader.Explicit; + break; + } + + applyDefaults(); + } + + private WHICH _which = WHICH.undefined; + private object _content; + public WHICH which + { + get => _which; + set + { + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.Implicit: + break; + case WHICH.Explicit: + _content = 0; + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.Implicit: + break; + case WHICH.Explicit: + writer.Explicit = Explicit.Value; + break; + } + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ushort? Explicit + { + get => _which == WHICH.Explicit ? (ushort?)_content : null; + set + { + _which = WHICH.Explicit; + _content = value; + } + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(80U, (ushort)0); + public ushort Explicit => which == WHICH.Explicit ? ctx.ReadDataUShort(96UL, (ushort)0) : default; + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public WHICH which + { + get => (WHICH)this.ReadDataUShort(80U, (ushort)0); + set => this.WriteData(80U, (ushort)value, (ushort)0); + } + + public ushort Explicit + { + get => which == WHICH.Explicit ? this.ReadDataUShort(96UL, (ushort)0) : default; + set => this.WriteData(96UL, value, (ushort)0); + } + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x978a7cebdc549a4dUL)] + public class Enumerant : ICapnpSerializable + { + public const UInt64 typeId = 0x978a7cebdc549a4dUL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Name = reader.Name; + CodeOrder = reader.CodeOrder; + Annotations = reader.Annotations?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Name = Name; + writer.CodeOrder = CodeOrder; + writer.Annotations.Init(Annotations, (_s1, _v1) => _v1?.serialize(_s1)); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public string Name + { + get; + set; + } + + public ushort CodeOrder + { + get; + set; + } + + public IReadOnlyList Annotations + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public string Name => ctx.ReadText(0, null); + public ushort CodeOrder => ctx.ReadDataUShort(0UL, (ushort)0); + public IReadOnlyList Annotations => ctx.ReadList(1).Cast(CapnpC.CSharp.Generator.Schema.Annotation.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 2); + } + + public string Name + { + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + + public ushort CodeOrder + { + get => this.ReadDataUShort(0UL, (ushort)0); + set => this.WriteData(0UL, value, (ushort)0); + } + + public ListOfStructsSerializer Annotations + { + get => BuildPointer>(1); set => Link(1, value); } } } -} + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xa9962a9ed0a4d7f8UL)] + public class Superclass : ICapnpSerializable + { + public const UInt64 typeId = 0xa9962a9ed0a4d7f8UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Id = reader.Id; + Brand = CapnpSerializable.Create(reader.Brand); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Id = Id; + Brand?.serialize(writer.Brand); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong Id + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Brand Brand + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong Id => ctx.ReadDataULong(0UL, 0UL); + public CapnpC.CSharp.Generator.Schema.Brand.READER Brand => ctx.ReadStruct(0, CapnpC.CSharp.Generator.Schema.Brand.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 1); + } + + public ulong Id + { + get => this.ReadDataULong(0UL, 0UL); + set => this.WriteData(0UL, value, 0UL); + } + + public CapnpC.CSharp.Generator.Schema.Brand.WRITER Brand + { + get => BuildPointer(0); + set => Link(0, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9500cce23b334d80UL)] + public class Method : ICapnpSerializable + { + public const UInt64 typeId = 0x9500cce23b334d80UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Name = reader.Name; + CodeOrder = reader.CodeOrder; + ParamStructType = reader.ParamStructType; + ResultStructType = reader.ResultStructType; + Annotations = reader.Annotations?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + ParamBrand = CapnpSerializable.Create(reader.ParamBrand); + ResultBrand = CapnpSerializable.Create(reader.ResultBrand); + ImplicitParameters = reader.ImplicitParameters?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Name = Name; + writer.CodeOrder = CodeOrder; + writer.ParamStructType = ParamStructType; + writer.ResultStructType = ResultStructType; + writer.Annotations.Init(Annotations, (_s1, _v1) => _v1?.serialize(_s1)); + ParamBrand?.serialize(writer.ParamBrand); + ResultBrand?.serialize(writer.ResultBrand); + writer.ImplicitParameters.Init(ImplicitParameters, (_s1, _v1) => _v1?.serialize(_s1)); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public string Name + { + get; + set; + } + + public ushort CodeOrder + { + get; + set; + } + + public ulong ParamStructType + { + get; + set; + } + + public ulong ResultStructType + { + get; + set; + } + + public IReadOnlyList Annotations + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Brand ParamBrand + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Brand ResultBrand + { + get; + set; + } + + public IReadOnlyList ImplicitParameters + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public string Name => ctx.ReadText(0, null); + public ushort CodeOrder => ctx.ReadDataUShort(0UL, (ushort)0); + public ulong ParamStructType => ctx.ReadDataULong(64UL, 0UL); + public ulong ResultStructType => ctx.ReadDataULong(128UL, 0UL); + public IReadOnlyList Annotations => ctx.ReadList(1).Cast(CapnpC.CSharp.Generator.Schema.Annotation.READER.create); + public CapnpC.CSharp.Generator.Schema.Brand.READER ParamBrand => ctx.ReadStruct(2, CapnpC.CSharp.Generator.Schema.Brand.READER.create); + public CapnpC.CSharp.Generator.Schema.Brand.READER ResultBrand => ctx.ReadStruct(3, CapnpC.CSharp.Generator.Schema.Brand.READER.create); + public IReadOnlyList ImplicitParameters => ctx.ReadList(4).Cast(CapnpC.CSharp.Generator.Schema.Node.Parameter.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(3, 5); + } + + public string Name + { + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + + public ushort CodeOrder + { + get => this.ReadDataUShort(0UL, (ushort)0); + set => this.WriteData(0UL, value, (ushort)0); + } + + public ulong ParamStructType + { + get => this.ReadDataULong(64UL, 0UL); + set => this.WriteData(64UL, value, 0UL); + } + + public ulong ResultStructType + { + get => this.ReadDataULong(128UL, 0UL); + set => this.WriteData(128UL, value, 0UL); + } + + public ListOfStructsSerializer Annotations + { + get => BuildPointer>(1); + set => Link(1, value); + } + + public CapnpC.CSharp.Generator.Schema.Brand.WRITER ParamBrand + { + get => BuildPointer(2); + set => Link(2, value); + } + + public CapnpC.CSharp.Generator.Schema.Brand.WRITER ResultBrand + { + get => BuildPointer(3); + set => Link(3, value); + } + + public ListOfStructsSerializer ImplicitParameters + { + get => BuildPointer>(4); + set => Link(4, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd07378ede1f9cc60UL)] + public class Type : ICapnpSerializable + { + public const UInt64 typeId = 0xd07378ede1f9cc60UL; + public enum WHICH : ushort + { + Void = 0, + Bool = 1, + Int8 = 2, + Int16 = 3, + Int32 = 4, + Int64 = 5, + Uint8 = 6, + Uint16 = 7, + Uint32 = 8, + Uint64 = 9, + Float32 = 10, + Float64 = 11, + Text = 12, + Data = 13, + List = 14, + Enum = 15, + Struct = 16, + Interface = 17, + AnyPointer = 18, + undefined = 65535 + } + + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + switch (reader.which) + { + case WHICH.Void: + which = reader.which; + break; + case WHICH.Bool: + which = reader.which; + break; + case WHICH.Int8: + which = reader.which; + break; + case WHICH.Int16: + which = reader.which; + break; + case WHICH.Int32: + which = reader.which; + break; + case WHICH.Int64: + which = reader.which; + break; + case WHICH.Uint8: + which = reader.which; + break; + case WHICH.Uint16: + which = reader.which; + break; + case WHICH.Uint32: + which = reader.which; + break; + case WHICH.Uint64: + which = reader.which; + break; + case WHICH.Float32: + which = reader.which; + break; + case WHICH.Float64: + which = reader.which; + break; + case WHICH.Text: + which = reader.which; + break; + case WHICH.Data: + which = reader.which; + break; + case WHICH.List: + List = CapnpSerializable.Create(reader.List); + break; + case WHICH.Enum: + Enum = CapnpSerializable.Create(reader.Enum); + break; + case WHICH.Struct: + Struct = CapnpSerializable.Create(reader.Struct); + break; + case WHICH.Interface: + Interface = CapnpSerializable.Create(reader.Interface); + break; + case WHICH.AnyPointer: + AnyPointer = CapnpSerializable.Create(reader.AnyPointer); + break; + } + + applyDefaults(); + } + + private WHICH _which = WHICH.undefined; + private object _content; + public WHICH which + { + get => _which; + set + { + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.Void: + break; + case WHICH.Bool: + break; + case WHICH.Int8: + break; + case WHICH.Int16: + break; + case WHICH.Int32: + break; + case WHICH.Int64: + break; + case WHICH.Uint8: + break; + case WHICH.Uint16: + break; + case WHICH.Uint32: + break; + case WHICH.Uint64: + break; + case WHICH.Float32: + break; + case WHICH.Float64: + break; + case WHICH.Text: + break; + case WHICH.Data: + break; + case WHICH.List: + _content = null; + break; + case WHICH.Enum: + _content = null; + break; + case WHICH.Struct: + _content = null; + break; + case WHICH.Interface: + _content = null; + break; + case WHICH.AnyPointer: + _content = null; + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.Void: + break; + case WHICH.Bool: + break; + case WHICH.Int8: + break; + case WHICH.Int16: + break; + case WHICH.Int32: + break; + case WHICH.Int64: + break; + case WHICH.Uint8: + break; + case WHICH.Uint16: + break; + case WHICH.Uint32: + break; + case WHICH.Uint64: + break; + case WHICH.Float32: + break; + case WHICH.Float64: + break; + case WHICH.Text: + break; + case WHICH.Data: + break; + case WHICH.List: + List?.serialize(writer.List); + break; + case WHICH.Enum: + Enum?.serialize(writer.Enum); + break; + case WHICH.Struct: + Struct?.serialize(writer.Struct); + break; + case WHICH.Interface: + Interface?.serialize(writer.Interface); + break; + case WHICH.AnyPointer: + AnyPointer?.serialize(writer.AnyPointer); + break; + } + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public CapnpC.CSharp.Generator.Schema.Type.list List + { + get => _which == WHICH.List ? (CapnpC.CSharp.Generator.Schema.Type.list)_content : null; + set + { + _which = WHICH.List; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Type.@enum Enum + { + get => _which == WHICH.Enum ? (CapnpC.CSharp.Generator.Schema.Type.@enum)_content : null; + set + { + _which = WHICH.Enum; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Type.@struct Struct + { + get => _which == WHICH.Struct ? (CapnpC.CSharp.Generator.Schema.Type.@struct)_content : null; + set + { + _which = WHICH.Struct; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Type.@interface Interface + { + get => _which == WHICH.Interface ? (CapnpC.CSharp.Generator.Schema.Type.@interface)_content : null; + set + { + _which = WHICH.Interface; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Type.anyPointer AnyPointer + { + get => _which == WHICH.AnyPointer ? (CapnpC.CSharp.Generator.Schema.Type.anyPointer)_content : null; + set + { + _which = WHICH.AnyPointer; + _content = value; + } + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(0U, (ushort)0); + public list.READER List => which == WHICH.List ? new list.READER(ctx) : default; + public @enum.READER Enum => which == WHICH.Enum ? new @enum.READER(ctx) : default; + public @struct.READER Struct => which == WHICH.Struct ? new @struct.READER(ctx) : default; + public @interface.READER Interface => which == WHICH.Interface ? new @interface.READER(ctx) : default; + public anyPointer.READER AnyPointer => which == WHICH.AnyPointer ? new anyPointer.READER(ctx) : default; + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(3, 1); + } + + public WHICH which + { + get => (WHICH)this.ReadDataUShort(0U, (ushort)0); + set => this.WriteData(0U, (ushort)value, (ushort)0); + } + + public list.WRITER List + { + get => which == WHICH.List ? Rewrap() : default; + } + + public @enum.WRITER Enum + { + get => which == WHICH.Enum ? Rewrap<@enum.WRITER>() : default; + } + + public @struct.WRITER Struct + { + get => which == WHICH.Struct ? Rewrap<@struct.WRITER>() : default; + } + + public @interface.WRITER Interface + { + get => which == WHICH.Interface ? Rewrap<@interface.WRITER>() : default; + } + + public anyPointer.WRITER AnyPointer + { + get => which == WHICH.AnyPointer ? Rewrap() : default; + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x87e739250a60ea97UL)] + public class list : ICapnpSerializable + { + public const UInt64 typeId = 0x87e739250a60ea97UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + ElementType = CapnpSerializable.Create(reader.ElementType); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + ElementType?.serialize(writer.ElementType); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public CapnpC.CSharp.Generator.Schema.Type ElementType + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public CapnpC.CSharp.Generator.Schema.Type.READER ElementType => ctx.ReadStruct(0, CapnpC.CSharp.Generator.Schema.Type.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public CapnpC.CSharp.Generator.Schema.Type.WRITER ElementType + { + get => BuildPointer(0); + set => Link(0, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9e0e78711a7f87a9UL)] + public class @enum : ICapnpSerializable + { + public const UInt64 typeId = 0x9e0e78711a7f87a9UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + TypeId = reader.TypeId; + Brand = CapnpSerializable.Create(reader.Brand); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.TypeId = TypeId; + Brand?.serialize(writer.Brand); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong TypeId + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Brand Brand + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong TypeId => ctx.ReadDataULong(64UL, 0UL); + public CapnpC.CSharp.Generator.Schema.Brand.READER Brand => ctx.ReadStruct(0, CapnpC.CSharp.Generator.Schema.Brand.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public ulong TypeId + { + get => this.ReadDataULong(64UL, 0UL); + set => this.WriteData(64UL, value, 0UL); + } + + public CapnpC.CSharp.Generator.Schema.Brand.WRITER Brand + { + get => BuildPointer(0); + set => Link(0, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xac3a6f60ef4cc6d3UL)] + public class @struct : ICapnpSerializable + { + public const UInt64 typeId = 0xac3a6f60ef4cc6d3UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + TypeId = reader.TypeId; + Brand = CapnpSerializable.Create(reader.Brand); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.TypeId = TypeId; + Brand?.serialize(writer.Brand); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong TypeId + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Brand Brand + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong TypeId => ctx.ReadDataULong(64UL, 0UL); + public CapnpC.CSharp.Generator.Schema.Brand.READER Brand => ctx.ReadStruct(0, CapnpC.CSharp.Generator.Schema.Brand.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public ulong TypeId + { + get => this.ReadDataULong(64UL, 0UL); + set => this.WriteData(64UL, value, 0UL); + } + + public CapnpC.CSharp.Generator.Schema.Brand.WRITER Brand + { + get => BuildPointer(0); + set => Link(0, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xed8bca69f7fb0cbfUL)] + public class @interface : ICapnpSerializable + { + public const UInt64 typeId = 0xed8bca69f7fb0cbfUL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + TypeId = reader.TypeId; + Brand = CapnpSerializable.Create(reader.Brand); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.TypeId = TypeId; + Brand?.serialize(writer.Brand); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong TypeId + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Brand Brand + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong TypeId => ctx.ReadDataULong(64UL, 0UL); + public CapnpC.CSharp.Generator.Schema.Brand.READER Brand => ctx.ReadStruct(0, CapnpC.CSharp.Generator.Schema.Brand.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public ulong TypeId + { + get => this.ReadDataULong(64UL, 0UL); + set => this.WriteData(64UL, value, 0UL); + } + + public CapnpC.CSharp.Generator.Schema.Brand.WRITER Brand + { + get => BuildPointer(0); + set => Link(0, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc2573fe8a23e49f1UL)] + public class anyPointer : ICapnpSerializable + { + public const UInt64 typeId = 0xc2573fe8a23e49f1UL; + public enum WHICH : ushort + { + Unconstrained = 0, + Parameter = 1, + ImplicitMethodParameter = 2, + undefined = 65535 + } + + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + switch (reader.which) + { + case WHICH.Unconstrained: + Unconstrained = CapnpSerializable.Create(reader.Unconstrained); + break; + case WHICH.Parameter: + Parameter = CapnpSerializable.Create(reader.Parameter); + break; + case WHICH.ImplicitMethodParameter: + ImplicitMethodParameter = CapnpSerializable.Create(reader.ImplicitMethodParameter); + break; + } + + applyDefaults(); + } + + private WHICH _which = WHICH.undefined; + private object _content; + public WHICH which + { + get => _which; + set + { + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.Unconstrained: + _content = null; + break; + case WHICH.Parameter: + _content = null; + break; + case WHICH.ImplicitMethodParameter: + _content = null; + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.Unconstrained: + Unconstrained?.serialize(writer.Unconstrained); + break; + case WHICH.Parameter: + Parameter?.serialize(writer.Parameter); + break; + case WHICH.ImplicitMethodParameter: + ImplicitMethodParameter?.serialize(writer.ImplicitMethodParameter); + break; + } + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public CapnpC.CSharp.Generator.Schema.Type.anyPointer.unconstrained Unconstrained + { + get => _which == WHICH.Unconstrained ? (CapnpC.CSharp.Generator.Schema.Type.anyPointer.unconstrained)_content : null; + set + { + _which = WHICH.Unconstrained; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Type.anyPointer.parameter Parameter + { + get => _which == WHICH.Parameter ? (CapnpC.CSharp.Generator.Schema.Type.anyPointer.parameter)_content : null; + set + { + _which = WHICH.Parameter; + _content = value; + } + } + + public CapnpC.CSharp.Generator.Schema.Type.anyPointer.implicitMethodParameter ImplicitMethodParameter + { + get => _which == WHICH.ImplicitMethodParameter ? (CapnpC.CSharp.Generator.Schema.Type.anyPointer.implicitMethodParameter)_content : null; + set + { + _which = WHICH.ImplicitMethodParameter; + _content = value; + } + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(64U, (ushort)0); + public unconstrained.READER Unconstrained => which == WHICH.Unconstrained ? new unconstrained.READER(ctx) : default; + public parameter.READER Parameter => which == WHICH.Parameter ? new parameter.READER(ctx) : default; + public implicitMethodParameter.READER ImplicitMethodParameter => which == WHICH.ImplicitMethodParameter ? new implicitMethodParameter.READER(ctx) : default; + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public WHICH which + { + get => (WHICH)this.ReadDataUShort(64U, (ushort)0); + set => this.WriteData(64U, (ushort)value, (ushort)0); + } + + public unconstrained.WRITER Unconstrained + { + get => which == WHICH.Unconstrained ? Rewrap() : default; + } + + public parameter.WRITER Parameter + { + get => which == WHICH.Parameter ? Rewrap() : default; + } + + public implicitMethodParameter.WRITER ImplicitMethodParameter + { + get => which == WHICH.ImplicitMethodParameter ? Rewrap() : default; + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x8e3b5f79fe593656UL)] + public class unconstrained : ICapnpSerializable + { + public const UInt64 typeId = 0x8e3b5f79fe593656UL; + public enum WHICH : ushort + { + AnyKind = 0, + Struct = 1, + List = 2, + Capability = 3, + undefined = 65535 + } + + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + switch (reader.which) + { + case WHICH.AnyKind: + which = reader.which; + break; + case WHICH.Struct: + which = reader.which; + break; + case WHICH.List: + which = reader.which; + break; + case WHICH.Capability: + which = reader.which; + break; + } + + applyDefaults(); + } + + private WHICH _which = WHICH.undefined; + public WHICH which + { + get => _which; + set + { + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.AnyKind: + break; + case WHICH.Struct: + break; + case WHICH.List: + break; + case WHICH.Capability: + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.AnyKind: + break; + case WHICH.Struct: + break; + case WHICH.List: + break; + case WHICH.Capability: + break; + } + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(80U, (ushort)0); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public WHICH which + { + get => (WHICH)this.ReadDataUShort(80U, (ushort)0); + set => this.WriteData(80U, (ushort)value, (ushort)0); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x9dd1f724f4614a85UL)] + public class parameter : ICapnpSerializable + { + public const UInt64 typeId = 0x9dd1f724f4614a85UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + ScopeId = reader.ScopeId; + ParameterIndex = reader.ParameterIndex; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.ScopeId = ScopeId; + writer.ParameterIndex = ParameterIndex; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong ScopeId + { + get; + set; + } + + public ushort ParameterIndex + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong ScopeId => ctx.ReadDataULong(128UL, 0UL); + public ushort ParameterIndex => ctx.ReadDataUShort(80UL, (ushort)0); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public ulong ScopeId + { + get => this.ReadDataULong(128UL, 0UL); + set => this.WriteData(128UL, value, 0UL); + } + + public ushort ParameterIndex + { + get => this.ReadDataUShort(80UL, (ushort)0); + set => this.WriteData(80UL, value, (ushort)0); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbaefc9120c56e274UL)] + public class implicitMethodParameter : ICapnpSerializable + { + public const UInt64 typeId = 0xbaefc9120c56e274UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + ParameterIndex = reader.ParameterIndex; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.ParameterIndex = ParameterIndex; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ushort ParameterIndex + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ushort ParameterIndex => ctx.ReadDataUShort(80UL, (ushort)0); + } + + public class WRITER : SerializerState + { + public WRITER() + { + } + + public ushort ParameterIndex + { + get => this.ReadDataUShort(80UL, (ushort)0); + set => this.WriteData(80UL, value, (ushort)0); + } + } + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0x903455f06065422bUL)] + public class Brand : ICapnpSerializable + { + public const UInt64 typeId = 0x903455f06065422bUL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Scopes = reader.Scopes?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Scopes.Init(Scopes, (_s1, _v1) => _v1?.serialize(_s1)); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public IReadOnlyList Scopes + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public IReadOnlyList Scopes => ctx.ReadList(0).Cast(CapnpC.CSharp.Generator.Schema.Brand.Scope.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(0, 1); + } + + public ListOfStructsSerializer Scopes + { + get => BuildPointer>(0); + set => Link(0, value); + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xabd73485a9636bc9UL)] + public class Scope : ICapnpSerializable + { + public const UInt64 typeId = 0xabd73485a9636bc9UL; + public enum WHICH : ushort + { + Bind = 0, + Inherit = 1, + undefined = 65535 + } + + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + switch (reader.which) + { + case WHICH.Bind: + Bind = reader.Bind?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + break; + case WHICH.Inherit: + which = reader.which; + break; + } + + ScopeId = reader.ScopeId; + applyDefaults(); + } + + private WHICH _which = WHICH.undefined; + private object _content; + public WHICH which + { + get => _which; + set + { + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.Bind: + _content = null; + break; + case WHICH.Inherit: + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.Bind: + writer.Bind.Init(Bind, (_s1, _v1) => _v1?.serialize(_s1)); + break; + case WHICH.Inherit: + break; + } + + writer.ScopeId = ScopeId; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong ScopeId + { + get; + set; + } + + public IReadOnlyList Bind + { + get => _which == WHICH.Bind ? (IReadOnlyList)_content : null; + set + { + _which = WHICH.Bind; + _content = value; + } + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(64U, (ushort)0); + public ulong ScopeId => ctx.ReadDataULong(0UL, 0UL); + public IReadOnlyList Bind => which == WHICH.Bind ? ctx.ReadList(0).Cast(CapnpC.CSharp.Generator.Schema.Brand.Binding.READER.create) : default; + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(2, 1); + } + + public WHICH which + { + get => (WHICH)this.ReadDataUShort(64U, (ushort)0); + set => this.WriteData(64U, (ushort)value, (ushort)0); + } + + public ulong ScopeId + { + get => this.ReadDataULong(0UL, 0UL); + set => this.WriteData(0UL, value, 0UL); + } + + public ListOfStructsSerializer Bind + { + get => which == WHICH.Bind ? BuildPointer>(0) : default; + set => Link(0, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xc863cd16969ee7fcUL)] + public class Binding : ICapnpSerializable + { + public const UInt64 typeId = 0xc863cd16969ee7fcUL; + public enum WHICH : ushort + { + Unbound = 0, + Type = 1, + undefined = 65535 + } + + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + switch (reader.which) + { + case WHICH.Unbound: + which = reader.which; + break; + case WHICH.Type: + Type = CapnpSerializable.Create(reader.Type); + break; + } + + applyDefaults(); + } + + private WHICH _which = WHICH.undefined; + private object _content; + public WHICH which + { + get => _which; + set + { + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.Unbound: + break; + case WHICH.Type: + _content = null; + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.Unbound: + break; + case WHICH.Type: + Type?.serialize(writer.Type); + break; + } + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public CapnpC.CSharp.Generator.Schema.Type Type + { + get => _which == WHICH.Type ? (CapnpC.CSharp.Generator.Schema.Type)_content : null; + set + { + _which = WHICH.Type; + _content = value; + } + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(0U, (ushort)0); + public CapnpC.CSharp.Generator.Schema.Type.READER Type => which == WHICH.Type ? ctx.ReadStruct(0, CapnpC.CSharp.Generator.Schema.Type.READER.create) : default; + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 1); + } + + public WHICH which + { + get => (WHICH)this.ReadDataUShort(0U, (ushort)0); + set => this.WriteData(0U, (ushort)value, (ushort)0); + } + + public CapnpC.CSharp.Generator.Schema.Type.WRITER Type + { + get => which == WHICH.Type ? BuildPointer(0) : default; + set => Link(0, value); + } + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xce23dcd2d7b00c9bUL)] + public class Value : ICapnpSerializable + { + public const UInt64 typeId = 0xce23dcd2d7b00c9bUL; + public enum WHICH : ushort + { + Void = 0, + Bool = 1, + Int8 = 2, + Int16 = 3, + Int32 = 4, + Int64 = 5, + Uint8 = 6, + Uint16 = 7, + Uint32 = 8, + Uint64 = 9, + Float32 = 10, + Float64 = 11, + Text = 12, + Data = 13, + List = 14, + Enum = 15, + Struct = 16, + Interface = 17, + AnyPointer = 18, + undefined = 65535 + } + + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + switch (reader.which) + { + case WHICH.Void: + which = reader.which; + break; + case WHICH.Bool: + Bool = reader.Bool; + break; + case WHICH.Int8: + Int8 = reader.Int8; + break; + case WHICH.Int16: + Int16 = reader.Int16; + break; + case WHICH.Int32: + Int32 = reader.Int32; + break; + case WHICH.Int64: + Int64 = reader.Int64; + break; + case WHICH.Uint8: + Uint8 = reader.Uint8; + break; + case WHICH.Uint16: + Uint16 = reader.Uint16; + break; + case WHICH.Uint32: + Uint32 = reader.Uint32; + break; + case WHICH.Uint64: + Uint64 = reader.Uint64; + break; + case WHICH.Float32: + Float32 = reader.Float32; + break; + case WHICH.Float64: + Float64 = reader.Float64; + break; + case WHICH.Text: + Text = reader.Text; + break; + case WHICH.Data: + Data = reader.Data; + break; + case WHICH.List: + List = CapnpSerializable.Create(reader.List); + break; + case WHICH.Enum: + Enum = reader.Enum; + break; + case WHICH.Struct: + Struct = CapnpSerializable.Create(reader.Struct); + break; + case WHICH.Interface: + which = reader.which; + break; + case WHICH.AnyPointer: + AnyPointer = CapnpSerializable.Create(reader.AnyPointer); + break; + } + + applyDefaults(); + } + + private WHICH _which = WHICH.undefined; + private object _content; + public WHICH which + { + get => _which; + set + { + if (value == _which) + return; + _which = value; + switch (value) + { + case WHICH.Void: + break; + case WHICH.Bool: + _content = false; + break; + case WHICH.Int8: + _content = 0; + break; + case WHICH.Int16: + _content = 0; + break; + case WHICH.Int32: + _content = 0; + break; + case WHICH.Int64: + _content = 0; + break; + case WHICH.Uint8: + _content = 0; + break; + case WHICH.Uint16: + _content = 0; + break; + case WHICH.Uint32: + _content = 0; + break; + case WHICH.Uint64: + _content = 0; + break; + case WHICH.Float32: + _content = 0F; + break; + case WHICH.Float64: + _content = 0; + break; + case WHICH.Text: + _content = null; + break; + case WHICH.Data: + _content = null; + break; + case WHICH.List: + _content = null; + break; + case WHICH.Enum: + _content = 0; + break; + case WHICH.Struct: + _content = null; + break; + case WHICH.Interface: + break; + case WHICH.AnyPointer: + _content = null; + break; + } + } + } + + public void serialize(WRITER writer) + { + writer.which = which; + switch (which) + { + case WHICH.Void: + break; + case WHICH.Bool: + writer.Bool = Bool.Value; + break; + case WHICH.Int8: + writer.Int8 = Int8.Value; + break; + case WHICH.Int16: + writer.Int16 = Int16.Value; + break; + case WHICH.Int32: + writer.Int32 = Int32.Value; + break; + case WHICH.Int64: + writer.Int64 = Int64.Value; + break; + case WHICH.Uint8: + writer.Uint8 = Uint8.Value; + break; + case WHICH.Uint16: + writer.Uint16 = Uint16.Value; + break; + case WHICH.Uint32: + writer.Uint32 = Uint32.Value; + break; + case WHICH.Uint64: + writer.Uint64 = Uint64.Value; + break; + case WHICH.Float32: + writer.Float32 = Float32.Value; + break; + case WHICH.Float64: + writer.Float64 = Float64.Value; + break; + case WHICH.Text: + writer.Text = Text; + break; + case WHICH.Data: + writer.Data.Init(Data); + break; + case WHICH.List: + writer.List.SetObject(List); + break; + case WHICH.Enum: + writer.Enum = Enum.Value; + break; + case WHICH.Struct: + writer.Struct.SetObject(Struct); + break; + case WHICH.Interface: + break; + case WHICH.AnyPointer: + writer.AnyPointer.SetObject(AnyPointer); + break; + } + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public bool? Bool + { + get => _which == WHICH.Bool ? (bool?)_content : null; + set + { + _which = WHICH.Bool; + _content = value; + } + } + + public sbyte? Int8 + { + get => _which == WHICH.Int8 ? (sbyte?)_content : null; + set + { + _which = WHICH.Int8; + _content = value; + } + } + + public short? Int16 + { + get => _which == WHICH.Int16 ? (short?)_content : null; + set + { + _which = WHICH.Int16; + _content = value; + } + } + + public int? Int32 + { + get => _which == WHICH.Int32 ? (int?)_content : null; + set + { + _which = WHICH.Int32; + _content = value; + } + } + + public long? Int64 + { + get => _which == WHICH.Int64 ? (long?)_content : null; + set + { + _which = WHICH.Int64; + _content = value; + } + } + + public byte? Uint8 + { + get => _which == WHICH.Uint8 ? (byte?)_content : null; + set + { + _which = WHICH.Uint8; + _content = value; + } + } + + public ushort? Uint16 + { + get => _which == WHICH.Uint16 ? (ushort?)_content : null; + set + { + _which = WHICH.Uint16; + _content = value; + } + } + + public uint? Uint32 + { + get => _which == WHICH.Uint32 ? (uint?)_content : null; + set + { + _which = WHICH.Uint32; + _content = value; + } + } + + public ulong? Uint64 + { + get => _which == WHICH.Uint64 ? (ulong?)_content : null; + set + { + _which = WHICH.Uint64; + _content = value; + } + } + + public float? Float32 + { + get => _which == WHICH.Float32 ? (float?)_content : null; + set + { + _which = WHICH.Float32; + _content = value; + } + } + + public double? Float64 + { + get => _which == WHICH.Float64 ? (double?)_content : null; + set + { + _which = WHICH.Float64; + _content = value; + } + } + + public string Text + { + get => _which == WHICH.Text ? (string)_content : null; + set + { + _which = WHICH.Text; + _content = value; + } + } + + public IReadOnlyList Data + { + get => _which == WHICH.Data ? (IReadOnlyList)_content : null; + set + { + _which = WHICH.Data; + _content = value; + } + } + + public object List + { + get => _which == WHICH.List ? (object)_content : null; + set + { + _which = WHICH.List; + _content = value; + } + } + + public ushort? Enum + { + get => _which == WHICH.Enum ? (ushort?)_content : null; + set + { + _which = WHICH.Enum; + _content = value; + } + } + + public object Struct + { + get => _which == WHICH.Struct ? (object)_content : null; + set + { + _which = WHICH.Struct; + _content = value; + } + } + + public object AnyPointer + { + get => _which == WHICH.AnyPointer ? (object)_content : null; + set + { + _which = WHICH.AnyPointer; + _content = value; + } + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public WHICH which => (WHICH)ctx.ReadDataUShort(0U, (ushort)0); + public bool Bool => which == WHICH.Bool ? ctx.ReadDataBool(16UL, false) : default; + public sbyte Int8 => which == WHICH.Int8 ? ctx.ReadDataSByte(16UL, (sbyte)0) : default; + public short Int16 => which == WHICH.Int16 ? ctx.ReadDataShort(16UL, (short)0) : default; + public int Int32 => which == WHICH.Int32 ? ctx.ReadDataInt(32UL, 0) : default; + public long Int64 => which == WHICH.Int64 ? ctx.ReadDataLong(64UL, 0L) : default; + public byte Uint8 => which == WHICH.Uint8 ? ctx.ReadDataByte(16UL, (byte)0) : default; + public ushort Uint16 => which == WHICH.Uint16 ? ctx.ReadDataUShort(16UL, (ushort)0) : default; + public uint Uint32 => which == WHICH.Uint32 ? ctx.ReadDataUInt(32UL, 0U) : default; + public ulong Uint64 => which == WHICH.Uint64 ? ctx.ReadDataULong(64UL, 0UL) : default; + public float Float32 => which == WHICH.Float32 ? ctx.ReadDataFloat(32UL, 0F) : default; + public double Float64 => which == WHICH.Float64 ? ctx.ReadDataDouble(64UL, 0) : default; + public string Text => which == WHICH.Text ? ctx.ReadText(0, null) : default; + public IReadOnlyList Data => which == WHICH.Data ? ctx.ReadList(0).CastByte() : default; + public DeserializerState List => which == WHICH.List ? ctx.StructReadPointer(0) : default; + public ushort Enum => which == WHICH.Enum ? ctx.ReadDataUShort(16UL, (ushort)0) : default; + public DeserializerState Struct => which == WHICH.Struct ? ctx.StructReadPointer(0) : default; + public DeserializerState AnyPointer => which == WHICH.AnyPointer ? ctx.StructReadPointer(0) : default; + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(2, 1); + } + + public WHICH which + { + get => (WHICH)this.ReadDataUShort(0U, (ushort)0); + set => this.WriteData(0U, (ushort)value, (ushort)0); + } + + public bool Bool + { + get => which == WHICH.Bool ? this.ReadDataBool(16UL, false) : default; + set => this.WriteData(16UL, value, false); + } + + public sbyte Int8 + { + get => which == WHICH.Int8 ? this.ReadDataSByte(16UL, (sbyte)0) : default; + set => this.WriteData(16UL, value, (sbyte)0); + } + + public short Int16 + { + get => which == WHICH.Int16 ? this.ReadDataShort(16UL, (short)0) : default; + set => this.WriteData(16UL, value, (short)0); + } + + public int Int32 + { + get => which == WHICH.Int32 ? this.ReadDataInt(32UL, 0) : default; + set => this.WriteData(32UL, value, 0); + } + + public long Int64 + { + get => which == WHICH.Int64 ? this.ReadDataLong(64UL, 0L) : default; + set => this.WriteData(64UL, value, 0L); + } + + public byte Uint8 + { + get => which == WHICH.Uint8 ? this.ReadDataByte(16UL, (byte)0) : default; + set => this.WriteData(16UL, value, (byte)0); + } + + public ushort Uint16 + { + get => which == WHICH.Uint16 ? this.ReadDataUShort(16UL, (ushort)0) : default; + set => this.WriteData(16UL, value, (ushort)0); + } + + public uint Uint32 + { + get => which == WHICH.Uint32 ? this.ReadDataUInt(32UL, 0U) : default; + set => this.WriteData(32UL, value, 0U); + } + + public ulong Uint64 + { + get => which == WHICH.Uint64 ? this.ReadDataULong(64UL, 0UL) : default; + set => this.WriteData(64UL, value, 0UL); + } + + public float Float32 + { + get => which == WHICH.Float32 ? this.ReadDataFloat(32UL, 0F) : default; + set => this.WriteData(32UL, value, 0F); + } + + public double Float64 + { + get => which == WHICH.Float64 ? this.ReadDataDouble(64UL, 0) : default; + set => this.WriteData(64UL, value, 0); + } + + public string Text + { + get => which == WHICH.Text ? this.ReadText(0, null) : default; + set => this.WriteText(0, value, null); + } + + public ListOfPrimitivesSerializer Data + { + get => which == WHICH.Data ? BuildPointer>(0) : default; + set => Link(0, value); + } + + public DynamicSerializerState List + { + get => which == WHICH.List ? BuildPointer(0) : default; + set => Link(0, value); + } + + public ushort Enum + { + get => which == WHICH.Enum ? this.ReadDataUShort(16UL, (ushort)0) : default; + set => this.WriteData(16UL, value, (ushort)0); + } + + public DynamicSerializerState Struct + { + get => which == WHICH.Struct ? BuildPointer(0) : default; + set => Link(0, value); + } + + public DynamicSerializerState AnyPointer + { + get => which == WHICH.AnyPointer ? BuildPointer(0) : default; + set => Link(0, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xf1c8950dab257542UL)] + public class Annotation : ICapnpSerializable + { + public const UInt64 typeId = 0xf1c8950dab257542UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Id = reader.Id; + Value = CapnpSerializable.Create(reader.Value); + Brand = CapnpSerializable.Create(reader.Brand); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Id = Id; + Value?.serialize(writer.Value); + Brand?.serialize(writer.Brand); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong Id + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Value Value + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.Brand Brand + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong Id => ctx.ReadDataULong(0UL, 0UL); + public CapnpC.CSharp.Generator.Schema.Value.READER Value => ctx.ReadStruct(0, CapnpC.CSharp.Generator.Schema.Value.READER.create); + public CapnpC.CSharp.Generator.Schema.Brand.READER Brand => ctx.ReadStruct(1, CapnpC.CSharp.Generator.Schema.Brand.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 2); + } + + public ulong Id + { + get => this.ReadDataULong(0UL, 0UL); + set => this.WriteData(0UL, value, 0UL); + } + + public CapnpC.CSharp.Generator.Schema.Value.WRITER Value + { + get => BuildPointer(0); + set => Link(0, value); + } + + public CapnpC.CSharp.Generator.Schema.Brand.WRITER Brand + { + get => BuildPointer(1); + set => Link(1, value); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd1958f7dba521926UL)] + public enum ElementSize : ushort + { + empty, + bit, + @byte, + twoBytes, + fourBytes, + eightBytes, + pointer, + inlineComposite + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xd85d305b7d839963UL)] + public class CapnpVersion : ICapnpSerializable + { + public const UInt64 typeId = 0xd85d305b7d839963UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Major = reader.Major; + Minor = reader.Minor; + Micro = reader.Micro; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Major = Major; + writer.Minor = Minor; + writer.Micro = Micro; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ushort Major + { + get; + set; + } + + public byte Minor + { + get; + set; + } + + public byte Micro + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ushort Major => ctx.ReadDataUShort(0UL, (ushort)0); + public byte Minor => ctx.ReadDataByte(16UL, (byte)0); + public byte Micro => ctx.ReadDataByte(24UL, (byte)0); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 0); + } + + public ushort Major + { + get => this.ReadDataUShort(0UL, (ushort)0); + set => this.WriteData(0UL, value, (ushort)0); + } + + public byte Minor + { + get => this.ReadDataByte(16UL, (byte)0); + set => this.WriteData(16UL, value, (byte)0); + } + + public byte Micro + { + get => this.ReadDataByte(24UL, (byte)0); + set => this.WriteData(24UL, value, (byte)0); + } + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xbfc546f6210ad7ceUL)] + public class CodeGeneratorRequest : ICapnpSerializable + { + public const UInt64 typeId = 0xbfc546f6210ad7ceUL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Nodes = reader.Nodes?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + RequestedFiles = reader.RequestedFiles?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + CapnpVersion = CapnpSerializable.Create(reader.CapnpVersion); + SourceInfo = reader.SourceInfo?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Nodes.Init(Nodes, (_s1, _v1) => _v1?.serialize(_s1)); + writer.RequestedFiles.Init(RequestedFiles, (_s1, _v1) => _v1?.serialize(_s1)); + CapnpVersion?.serialize(writer.CapnpVersion); + writer.SourceInfo.Init(SourceInfo, (_s1, _v1) => _v1?.serialize(_s1)); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public IReadOnlyList Nodes + { + get; + set; + } + + public IReadOnlyList RequestedFiles + { + get; + set; + } + + public CapnpC.CSharp.Generator.Schema.CapnpVersion CapnpVersion + { + get; + set; + } + + public IReadOnlyList SourceInfo + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public IReadOnlyList Nodes => ctx.ReadList(0).Cast(CapnpC.CSharp.Generator.Schema.Node.READER.create); + public IReadOnlyList RequestedFiles => ctx.ReadList(1).Cast(CapnpC.CSharp.Generator.Schema.CodeGeneratorRequest.RequestedFile.READER.create); + public CapnpC.CSharp.Generator.Schema.CapnpVersion.READER CapnpVersion => ctx.ReadStruct(2, CapnpC.CSharp.Generator.Schema.CapnpVersion.READER.create); + public IReadOnlyList SourceInfo => ctx.ReadList(3).Cast(CapnpC.CSharp.Generator.Schema.Node.SourceInfo.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(0, 4); + } + + public ListOfStructsSerializer Nodes + { + get => BuildPointer>(0); + set => Link(0, value); + } + + public ListOfStructsSerializer RequestedFiles + { + get => BuildPointer>(1); + set => Link(1, value); + } + + public CapnpC.CSharp.Generator.Schema.CapnpVersion.WRITER CapnpVersion + { + get => BuildPointer(2); + set => Link(2, value); + } + + public ListOfStructsSerializer SourceInfo + { + get => BuildPointer>(3); + set => Link(3, value); + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xcfea0eb02e810062UL)] + public class RequestedFile : ICapnpSerializable + { + public const UInt64 typeId = 0xcfea0eb02e810062UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Id = reader.Id; + Filename = reader.Filename; + Imports = reader.Imports?.ToReadOnlyList(_ => CapnpSerializable.Create(_)); + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Id = Id; + writer.Filename = Filename; + writer.Imports.Init(Imports, (_s1, _v1) => _v1?.serialize(_s1)); + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong Id + { + get; + set; + } + + public string Filename + { + get; + set; + } + + public IReadOnlyList Imports + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong Id => ctx.ReadDataULong(0UL, 0UL); + public string Filename => ctx.ReadText(0, null); + public IReadOnlyList Imports => ctx.ReadList(1).Cast(CapnpC.CSharp.Generator.Schema.CodeGeneratorRequest.RequestedFile.Import.READER.create); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 2); + } + + public ulong Id + { + get => this.ReadDataULong(0UL, 0UL); + set => this.WriteData(0UL, value, 0UL); + } + + public string Filename + { + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + + public ListOfStructsSerializer Imports + { + get => BuildPointer>(1); + set => Link(1, value); + } + } + + [System.CodeDom.Compiler.GeneratedCode("capnpc-csharp", "1.3.0.0"), TypeId(0xae504193122357e5UL)] + public class Import : ICapnpSerializable + { + public const UInt64 typeId = 0xae504193122357e5UL; + void ICapnpSerializable.Deserialize(DeserializerState arg_) + { + var reader = READER.create(arg_); + Id = reader.Id; + Name = reader.Name; + applyDefaults(); + } + + public void serialize(WRITER writer) + { + writer.Id = Id; + writer.Name = Name; + } + + void ICapnpSerializable.Serialize(SerializerState arg_) + { + serialize(arg_.Rewrap()); + } + + public void applyDefaults() + { + } + + public ulong Id + { + get; + set; + } + + public string Name + { + get; + set; + } + + public struct READER + { + readonly DeserializerState ctx; + public READER(DeserializerState ctx) + { + this.ctx = ctx; + } + + public static READER create(DeserializerState ctx) => new READER(ctx); + public static implicit operator DeserializerState(READER reader) => reader.ctx; + public static implicit operator READER(DeserializerState ctx) => new READER(ctx); + public ulong Id => ctx.ReadDataULong(0UL, 0UL); + public string Name => ctx.ReadText(0, null); + } + + public class WRITER : SerializerState + { + public WRITER() + { + this.SetStruct(1, 1); + } + + public ulong Id + { + get => this.ReadDataULong(0UL, 0UL); + set => this.WriteData(0UL, value, 0UL); + } + + public string Name + { + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); + } + } + } + } + } +} \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index b8c4883..2033be4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,17 +11,21 @@ install: - vcpkg install capnproto - cd %APPVEYOR_BUILD_FOLDER% - dotnet tool install -g nbgv + - choco install opencover --version=4.7.922 --force -y + - choco install reportgenerator.portable --version=2.5.0.0 --force -y + - dotnet tool install -g coveralls.net --version 1.0.0 init: # Good practise, because Windows line endings are different from Unix/Linux ones - cmd: git config --global core.autocrlf true +environment: + COVERALLS_REPO_TOKEN: + secure: mwxwOymoS7vB56iQN5Obbt8+oMqbRpK8Ei2GZUI7Mm46C8asDR/Wu0RAXYlhp85Q before_build: - cmd: nbgv cloud - cmd: dotnet --version - cmd: msbuild -ver - cmd: dotnet restore ./Capnp.Net.Runtime/Capnp.Net.Runtime.csproj --verbosity m - - cmd: dotnet restore ./Capnp.Net.Runtime.Core21/Capnp.Net.Runtime.Core21.csproj --verbosity m - - cmd: dotnet restore ./Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.Std20.csproj --verbosity m - - cmd: dotnet restore ./Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj --verbosity m + - cmd: dotnet restore ./Capnp.Net.Runtime.Tests/Capnp.Net.Runtime.Tests.csproj --verbosity m - cmd: dotnet restore ./CapnpC.CSharp.Generator/CapnpC.CSharp.Generator.csproj --verbosity m - cmd: dotnet restore ./CapnpC.CSharp.Generator.Tests/CapnpC.CSharp.Generator.Tests.csproj --verbosity m - cmd: dotnet restore ./CapnpC.CSharp.MsBuild.Generation/CapnpC.CSharp.MsBuild.Generation.csproj --verbosity m @@ -51,6 +55,9 @@ artifacts: - path: capnpc-csharp\nupkg\*.nupkg name: capnpc-csharp type: NuGetPackage + - path: coverage\report + name: Coverage report + type: zip test_script: - cmd: | nbgv get-version -v NuGetPackageVersion >> version.txt @@ -76,10 +83,12 @@ test_script: vstest.console /logger:Appveyor /inIsolation CapnpC.CSharp.MsBuild.Generation.Tests\bin\Release\netcoreapp3.0\CapnpC.CSharp.MsBuild.Generation.Tests.dll msbuild -t:restore ./MsBuildGenerationTest/MsBuildGenerationTest.csproj /p:Configuration="Debug" /p:PackageReferenceVersion="%VERSION%" msbuild ./MsBuildGenerationTest/MsBuildGenerationTest.sln /p:Configuration="Debug" /p:PackageReferenceVersion="%VERSION%" - vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests\bin\Debug\net471\Capnp.Net.Runtime.Tests.Std20.dll - vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests\bin\Release\net471\Capnp.Net.Runtime.Tests.Std20.dll - vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests.Core21\bin\Debug\netcoreapp2.1\Capnp.Net.Runtime.Tests.Core21.dll - vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests.Core21\bin\Release\netcoreapp2.1\Capnp.Net.Runtime.Tests.Core21.dll + vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests\bin\Debug\net471\Capnp.Net.Runtime.Tests.dll + vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests\bin\Release\net471\Capnp.Net.Runtime.Tests.dll + vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests\bin\Debug\netcoreapp2.1\Capnp.Net.Runtime.Tests.dll + vstest.console /logger:Appveyor /inIsolation Capnp.Net.Runtime.Tests\bin\Release\netcoreapp2.1\Capnp.Net.Runtime.Tests.dll + powershell -File .\scripts\measure-coverage.ps1 + csmacnz.Coveralls --opencover -i "coverage\coverage.xml" --repoToken %COVERALLS_REPO_TOKEN% on_finish : # any cleanup in here deploy: diff --git a/include/capnp/c++.capnp b/include/capnp/c++.capnp new file mode 100644 index 0000000..2bda547 --- /dev/null +++ b/include/capnp/c++.capnp @@ -0,0 +1,26 @@ +# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +# Licensed under the MIT License: +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +@0xbdf87d7bb8304e81; +$namespace("capnp::annotations"); + +annotation namespace(file): Text; +annotation name(field, enumerant, struct, enum, interface, method, param, group, union): Text; diff --git a/include/csharp.capnp b/include/csharp.capnp index 19aabd2..879d533 100644 --- a/include/csharp.capnp +++ b/include/csharp.capnp @@ -1,6 +1,11 @@ @0xeb0d831668c6edab; $namespace("Capnp.Annotations"); +enum TypeVisibility @0xeb0d831668c6eda5 { + public @0; + internal @1; +} + annotation namespace @0xeb0d831668c6eda0 (file) : Text; # C# namespace for code generation @@ -8,7 +13,13 @@ annotation nullableEnable @0xeb0d831668c6eda1 (file) : Bool; # Whether to generate C# nullable reference types annotation emitNullableDirective @0xeb0d831668c6eda3 (file) : Bool; -# Whether to surround the generated with with #nullable enable/disable ... #nullable restore +# Whether to surround the generated code with #nullable enable/disable ... #nullable restore + +annotation emitDomainClassesAndInterfaces @0xeb0d831668c6eda4 (file) : Bool; +# Whether generate domain classes and interfaces (default is 'true' if annotation is missing) + +annotation typeVisibility @0xeb0d831668c6eda6 (file) : TypeVisibility; +# Visibility of generated types annotation name @0xeb0d831668c6eda2 (field, enumerant, struct, enum, interface, method, param, group, union) : Text; # C# member name for code generation diff --git a/scripts/choco-install-coverage-tools.ps1 b/scripts/choco-install-coverage-tools.ps1 new file mode 100644 index 0000000..82e6e98 --- /dev/null +++ b/scripts/choco-install-coverage-tools.ps1 @@ -0,0 +1,4 @@ +if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit } + +choco install opencover --version=4.7.922 +choco install reportgenerator.portable --version=2.5.0.0 diff --git a/scripts/measure-coverage.ps1 b/scripts/measure-coverage.ps1 new file mode 100644 index 0000000..d06dfdb --- /dev/null +++ b/scripts/measure-coverage.ps1 @@ -0,0 +1,37 @@ +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$rootDir = "$scriptDir\.." +$coverageDir = "$rootDir\coverage" +$coverageReportDir = "$rootDir\coverage\report" +$openCover = "$env:LOCALAPPDATA\Apps\OpenCover\OpenCover.Console.exe" +$vsTestConsole = where.exe vstest.console +$coverageOutput = "$coverageDir\coverage.xml" + +$runtimeTests = "$rootDir\Capnp.Net.Runtime.Tests\bin\Release\netcoreapp2.1\Capnp.Net.Runtime.Tests.dll" +$generatorTests = "$rootDir\CapnpC.CSharp.Generator.Tests\bin\Release\netcoreapp3.0\CapnpC.CSharp.Generator.Tests.dll" + +If(!(test-path $coverageDir)) +{ + New-Item -ItemType Directory -Force -Path $coverageDir +} + +If(!(test-path $coverageReportDir)) +{ + New-Item -ItemType Directory -Force -Path $coverageReportDir +} + +& $openCover -target:"$vsTestConsole" ` + -targetArgs:"/inIsolation $runtimeTests /TestCaseFilter:`"TestCategory=Coverage`" /Framework:.NETCoreApp,Version=v2.1 /logger:trx;LogFileName=runtime.trx" ` + -filter:"+[Capnp.Net.Runtime]Capnp.*" ` + -excludebyattribute:"System.CodeDom.Compiler.GeneratedCodeAttribute" ` + -output:"$coverageOutput" ` + -mergebyhash -register:user -oldStyle + +& $openCover -target:"$vsTestConsole" ` + -targetArgs:"/inIsolation $generatorTests /logger:trx;LogFileName=generator.trx" ` + -filter:"+[CapnpC.CSharp.Generator]CapnpC.CSharp.Generator.* -[CapnpC.CSharp.Generator]CapnpC.CSharp.Generator.Schema.*" ` + -excludebyattribute:"System.CodeDom.Compiler.GeneratedCodeAttribute" ` + -output:"$coverageOutput" ` + -mergeoutput ` + -mergebyhash -register:user -oldStyle + +ReportGenerator.exe -reports:"$coverageOutput" -targetdir:"$coverageReportDir" -reportTypes:"Html" diff --git a/scripts/regen-capnpbin.bat b/scripts/regen-capnpbin.bat new file mode 100644 index 0000000..aa4d9bb --- /dev/null +++ b/scripts/regen-capnpbin.bat @@ -0,0 +1,3 @@ +@echo off +cd "%~dp0\..\CapnpC.CSharp.Generator.Tests\No Resources" +for /f %%f in ('dir /b "*.capnp"') do capnp compile -o- %%f -I"..\..\include" > "..\Embedded Resources\%%f.bin" \ No newline at end of file diff --git a/scripts/vsdevcmdprompt-measure-coverage.bat b/scripts/vsdevcmdprompt-measure-coverage.bat new file mode 100644 index 0000000..be2bf74 --- /dev/null +++ b/scripts/vsdevcmdprompt-measure-coverage.bat @@ -0,0 +1,4 @@ +rem This batch file assumes to be run from a Visual Studio developer command prompt +rem This is necessary because we need to locate vstest.console.exe + +powershell -File measure-coverage.ps1