Skip to content

Commit 088b84a

Browse files
committed
[Proto] Partially implemented deserialization for ProtoPackable<T>
1 parent dc810de commit 088b84a

19 files changed

+212
-132
lines changed

Lagrange.Proto.Generator/ProtoSourceGenerator.Emitter.TypeInfo.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.CodeAnalysis.CSharp;
12
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
23
using SK = Microsoft.CodeAnalysis.CSharp.SyntaxKind;
34

@@ -51,6 +52,11 @@ private MethodDeclarationSyntax EmitTypeInfoCreationMethod()
5152
]
5253
)
5354
))
55+
.WithInitializer(SF.InitializerExpression(SK.ObjectInitializerExpression).AddExpressions(
56+
SF.AssignmentExpression(SK.SimpleAssignmentExpression, SF.IdentifierName("Get"), EmitTypeInfoGetter(kv.Value.Name)),
57+
SF.AssignmentExpression(SK.SimpleAssignmentExpression, SF.IdentifierName("Set"), EmitTypeInfoSetter(kv.Value.Name))
58+
)
59+
)
5460
);
5561
var dictionaryInitialize = SF.ObjectCreationExpression(SF.ParseTypeName("global::System.Collections.Generic.Dictionary<int, global::Lagrange.Proto.Serialization.Metadata.ProtoFieldInfo>"))
5662
.WithArgumentList(SF.ArgumentList())
@@ -76,6 +82,26 @@ private MethodDeclarationSyntax EmitTypeInfoCreationMethod()
7682
.AddModifiers(SF.Token(SK.PrivateKeyword), SF.Token(SK.StaticKeyword))
7783
.WithBody(SF.Block(returnStatement));
7884
}
85+
86+
private ExpressionSyntax EmitTypeInfoGetter(string prop)
87+
{
88+
var cast = SF.CastExpression(SF.ParseTypeName(parser.Identifier), SF.IdentifierName("obj"));
89+
var access = SF.MemberAccessExpression(SK.SimpleMemberAccessExpression, SF.ParenthesizedExpression(cast), SF.IdentifierName(prop));
90+
91+
return SF.SimpleLambdaExpression(SF.Parameter(SF.Identifier("obj")), access);
92+
}
93+
94+
private ExpressionSyntax EmitTypeInfoSetter(string prop)
95+
{
96+
var parameters = SF.ParameterList().AddParameters(SF.Parameter(SF.Identifier("obj")), SF.Parameter(SF.Identifier("value")));
97+
var cast = SF.CastExpression(SF.ParseTypeName(parser.Identifier), SF.IdentifierName("obj"));
98+
var left = SF.MemberAccessExpression(SK.SimpleMemberAccessExpression, SF.ParenthesizedExpression(cast), SF.IdentifierName(prop));
99+
var right = SF.IdentifierName("value");
100+
101+
return SF.ParenthesizedLambdaExpression(parameters,
102+
SF.AssignmentExpression(SK.SimpleAssignmentExpression, left, right)
103+
);
104+
}
79105
}
80106
}
81107
}

Lagrange.Proto/Lagrange.Proto.csproj

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,22 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17-
<Folder Include="Serialization\Metadata\" />
17+
<Folder Include="Serialization\Converter\Collection\" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<None Update="Serialization\Metadata\ProtoTypeResolver.WellKnownTypes.tt">
22+
<Generator>TextTemplatingFileGenerator</Generator>
23+
<LastGenOutput>ProtoTypeResolver.WellKnownTypes.cs</LastGenOutput>
24+
</None>
25+
</ItemGroup>
26+
27+
<ItemGroup>
28+
<Compile Update="Serialization\Metadata\ProtoTypeResolver.WellKnownTypes.cs">
29+
<AutoGen>True</AutoGen>
30+
<DesignTime>True</DesignTime>
31+
<DependentUpon>ProtoTypeResolver.WellKnownTypes.tt</DependentUpon>
32+
</Compile>
1833
</ItemGroup>
1934

2035
</Project>

Lagrange.Proto/Primitives/ProtoReader.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public ref struct ProtoReader
2323
private static readonly Vector128<ulong> Shift4 = Vector128.Create(2ul, 1ul);
2424

2525
private static readonly Vector128<sbyte> Ascend = Vector128.Create(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
26+
27+
public bool IsCompleted => _offset == _length;
2628

2729
public ProtoReader(ReadOnlySpan<byte> src)
2830
{

Lagrange.Proto/Serialization/Converter/Generic/ProtoNullableConverter.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@ internal class ProtoNullableConverter<T> : ProtoConverter<T?> where T : struct
77
{
88
private readonly ProtoConverter<T> _converter = ProtoTypeResolver.GetConverter<T>();
99

10-
public override WireType WireType => _converter.WireType;
11-
12-
public override void Write(int field, ProtoWriter writer, T? value)
10+
public override void Write(int field, WireType wireType, ProtoWriter writer, T? value)
1311
{
14-
if (value.HasValue) _converter.Write(0, writer, value.Value);
12+
if (value.HasValue) _converter.Write(0, wireType, writer, value.Value);
1513
}
1614

17-
public override T? Read(int field, ref ProtoReader reader)
15+
public override T? Read(int field, WireType wireType, ref ProtoReader reader)
1816
{
19-
return _converter.Read(field, ref reader);
17+
return _converter.Read(field, wireType, ref reader);
2018
}
2119
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Lagrange.Proto.Primitives;
2+
3+
namespace Lagrange.Proto.Serialization.Converter.Object;
4+
5+
internal class ProtoSerializableConverter<T> : ProtoConverter<T> where T : IProtoSerializable<T>
6+
{
7+
public override void Write(int field, WireType wireType, ProtoWriter writer, T value)
8+
{
9+
int length = T.MeasureHandler(value);
10+
writer.EncodeVarInt(length);
11+
if (length > 0) T.SerializeHandler(value, writer);
12+
}
13+
14+
public override T Read(int field, WireType wireType, ref ProtoReader reader)
15+
{
16+
int length = reader.DecodeVarInt<int>();
17+
var span = reader.CreateSpan(length);
18+
return ProtoSerializer.DeserializeProtoPackable<T>(span);
19+
}
20+
}

Lagrange.Proto/Serialization/Converter/Value/ProtoBooleanConverter.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ namespace Lagrange.Proto.Serialization.Converter;
55

66
internal class ProtoBooleanConverter : ProtoConverter<bool>
77
{
8-
public override WireType WireType => WireType.VarInt;
9-
10-
public override void Write(int field, ProtoWriter writer, bool value)
8+
public override void Write(int field, WireType wireType, ProtoWriter writer, bool value)
119
{
1210
writer.WriteRawByte(Unsafe.As<bool, byte>(ref value));
1311
}
1412

15-
public override bool Read(int field, ref ProtoReader reader)
13+
public override bool Read(int field, WireType wireType, ref ProtoReader reader)
1614
{
1715
byte b = reader.DecodeVarInt<byte>();
1816
return Unsafe.As<byte, bool>(ref b);

Lagrange.Proto/Serialization/Converter/Value/ProtoBytesConverter.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ namespace Lagrange.Proto.Serialization.Converter;
44

55
public class ProtoBytesConverter : ProtoConverter<byte[]>
66
{
7-
public override WireType WireType => WireType.LengthDelimited;
8-
9-
public override void Write(int field, ProtoWriter writer, byte[] value)
7+
public override void Write(int field, WireType wireType, ProtoWriter writer, byte[] value)
108
{
119
writer.EncodeVarInt(value.Length);
1210
writer.WriteRawBytes(value);
1311
}
1412

15-
public override byte[] Read(int field, ref ProtoReader reader)
13+
public override byte[] Read(int field, WireType wireType, ref ProtoReader reader)
1614
{
1715
int length = reader.DecodeVarInt<int>();
1816
if (length == 0) return [];

Lagrange.Proto/Serialization/Converter/Value/ProtoFixed32Converter.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

Lagrange.Proto/Serialization/Converter/Value/ProtoFixed64Converter.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Numerics;
2+
using Lagrange.Proto.Primitives;
3+
4+
namespace Lagrange.Proto.Serialization.Converter;
5+
6+
internal class ProtoNumberConverter<T> : ProtoConverter<T> where T : unmanaged, INumber<T>
7+
{
8+
public override void Write(int field, WireType wireType, ProtoWriter writer, T value)
9+
{
10+
switch (wireType)
11+
{
12+
case WireType.Fixed32:
13+
writer.EncodeFixed32<T>(value);
14+
break;
15+
case WireType.Fixed64:
16+
writer.EncodeFixed64<T>(value);
17+
break;
18+
case WireType.VarInt:
19+
writer.EncodeVarInt<T>(value);
20+
break;
21+
default:
22+
throw new ArgumentOutOfRangeException(nameof(wireType), wireType, null);
23+
}
24+
}
25+
26+
public override T Read(int field, WireType wireType, ref ProtoReader reader)
27+
{
28+
return wireType switch
29+
{
30+
WireType.Fixed32 => reader.DecodeFixed32<T>(),
31+
WireType.Fixed64 => reader.DecodeFixed64<T>(),
32+
WireType.VarInt => reader.DecodeVarInt<T>(),
33+
_ => throw new ArgumentOutOfRangeException(nameof(wireType), wireType, null)
34+
};
35+
}
36+
}

0 commit comments

Comments
 (0)