mirror of
https://github.com/zap-proto/cs.git
synced 2026-10-30 15:05:32 +00:00
Finishes the in-flight capnp→ZAP rebrand on this branch. The prior commits
renamed identifiers/namespaces/files/projects (Capnp.Net.Runtime→Zap.Net.Runtime,
CapnpC→ZapC, .capnp→.zap) but left the human-readable brand name "Cap'n Proto"
throughout doc-comments, .csproj/.nuspec descriptions, README, MSBuild .xaml
rule display names, and the generated XML doc. This completes brand neutrality:
- Replace 154 "Cap'n Proto" / 4 "Cap'n-Proto" / 1 "Cap'n'p" prose occurrences
with "ZAP" across 32 first-party files (runtime, generator, zapc-csharp,
MSBuild integration, chocolatey nuspecs, README, docs, XML doc).
- Revert the LICENSE provenance URL to the real upstream fork
(c80k/capnproto-dotnetcore) — upstream-fork license headers must stay.
- Canonicalize project/repo URLs to github.com/zap-proto/cs (were fabricated
c80k/zap-dotnetcore) in csproj/nuspec/VERIFICATION/README badges.
- Canonicalize docs URLs zap-protocol(.github.io|/zap-cs|/zap-cpp-core)
→ zap-proto.dev / github.com/zap-proto/{cs,cpp-core}.
- Collapse redundant "zap \"ZAP\"" PackageTags to "zap".
Verified consistent (no toolchain on host): every .sln/.csproj ProjectReference
resolves; all namespaces are Zap*/ZapC*; MSBuild task chain
(GenerateZapFileCodeBehindTask, ZapFiles ItemGroup, _ZapcCsharp_TaskAssembly)
is uniformly renamed; props/targets/xaml/coverage/chocolatey carry no capnp.
Deliberately preserved as upstream-derived test data (not first-party source):
upstream Cap'n Proto schema fixtures (rpc.zap, rpc-twoparty.zap, json.zap,
rpc-csharp.zap), golden compiler-error outputs (errors.txt), and the
machine-generated DO-NOT-EDIT test.zap.{c++,h}. Their "Cap'n Proto" strings are
the literal output of the external schema compiler the compat test matches.
450 lines
17 KiB
C#
450 lines
17 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ZapC.CSharp.Generator.Model;
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
|
using static ZapC.CSharp.Generator.CodeGen.SyntaxHelpers;
|
|
|
|
namespace ZapC.CSharp.Generator.CodeGen
|
|
{
|
|
class WriterSnippetGen
|
|
{
|
|
readonly GenNames _names;
|
|
|
|
public WriterSnippetGen(GenNames names)
|
|
{
|
|
_names = names;
|
|
}
|
|
|
|
IEnumerable<MemberDeclarationSyntax> MakeWriterStructMembers(TypeDefinition structType)
|
|
{
|
|
yield return ConstructorDeclaration(_names.WriterStruct.Identifier)
|
|
.AddModifiers(Public)
|
|
.WithBody(
|
|
Block(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MemberAccessExpression(
|
|
SyntaxKind.SimpleMemberAccessExpression,
|
|
ThisExpression(),
|
|
IdentifierName(SerializerStateWorder.SetStructName)))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
LiteralExpression(
|
|
SyntaxKind.NumericLiteralExpression,
|
|
Literal(structType.StructDataWordCount))),
|
|
Argument(
|
|
LiteralExpression(
|
|
SyntaxKind.NumericLiteralExpression,
|
|
Literal(structType.StructPointerCount)))))));
|
|
}
|
|
|
|
IEnumerable<MemberDeclarationSyntax> MakeGroupWriterStructMembers()
|
|
{
|
|
yield return ConstructorDeclaration(_names.WriterStruct.Identifier)
|
|
.AddModifiers(Public)
|
|
.WithBody(Block());
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeWriterProperty(
|
|
TypeSyntax type,
|
|
string name,
|
|
ExpressionSyntax getter,
|
|
ExpressionSyntax setter,
|
|
bool cast,
|
|
bool cond)
|
|
{
|
|
if (cast)
|
|
{
|
|
getter = CastExpression(type, getter);
|
|
}
|
|
|
|
if (cond)
|
|
{
|
|
getter = ConditionalExpression(
|
|
BinaryExpression(
|
|
SyntaxKind.EqualsExpression,
|
|
_names.UnionDiscriminatorProp.IdentifierName,
|
|
MemberAccessExpression(
|
|
SyntaxKind.SimpleMemberAccessExpression,
|
|
_names.UnionDiscriminatorEnum.IdentifierName,
|
|
IdentifierName(name))),
|
|
getter,
|
|
LiteralExpression(
|
|
SyntaxKind.DefaultLiteralExpression,
|
|
Token(SyntaxKind.DefaultKeyword)));
|
|
}
|
|
|
|
var accessors = new AccessorDeclarationSyntax[setter != null ? 2 : 1];
|
|
|
|
accessors[0] = AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
|
|
.WithExpressionBody(ArrowExpressionClause(getter))
|
|
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
|
|
|
|
if (setter != null)
|
|
{
|
|
accessors[1] = AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
|
|
.WithExpressionBody(ArrowExpressionClause(setter))
|
|
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
|
|
}
|
|
|
|
return PropertyDeclaration(type, name)
|
|
.AddModifiers(Public)
|
|
.AddAccessorListAccessors(accessors);
|
|
}
|
|
|
|
ExpressionSyntax MakePointerSyntax(TypeSyntax type, object index) =>
|
|
InvocationExpression(
|
|
GenericName(nameof(Zap.SerializerState.BuildPointer))
|
|
.AddTypeArgumentListArguments(type))
|
|
.AddArgumentListArguments(
|
|
Argument(ValueOf(index)));
|
|
|
|
ExpressionSyntax MakeReadCapSyntax(TypeSyntax type, object index) =>
|
|
InvocationExpression(
|
|
GenericName(nameof(Zap.SerializerState.ReadCap))
|
|
.AddTypeArgumentListArguments(type))
|
|
.AddArgumentListArguments(
|
|
Argument(ValueOf(index)));
|
|
|
|
ExpressionSyntax MakeTypedPointerSyntax(object index, TypeSyntax type) =>
|
|
InvocationExpression(
|
|
GenericName(nameof(Zap.SerializerState.BuildPointer))
|
|
.AddTypeArgumentListArguments(type))
|
|
.AddArgumentListArguments(
|
|
Argument(ValueOf(index)));
|
|
|
|
ExpressionSyntax MakeLinkSyntax(object index, bool suppressNullableWarning)
|
|
{
|
|
ExpressionSyntax value = IdentifierName("value");
|
|
|
|
if (suppressNullableWarning)
|
|
{
|
|
value = _names.SuppressNullableWarning(value);
|
|
}
|
|
|
|
return InvocationExpression(
|
|
IdentifierName(SerializerStateWorder.LinkName))
|
|
.AddArgumentListArguments(
|
|
Argument(ValueOf(index)),
|
|
Argument(value));
|
|
}
|
|
|
|
ExpressionSyntax MakeLinkObjectSyntax(object index) =>
|
|
InvocationExpression(
|
|
IdentifierName(nameof(Zap.SerializerState.LinkObject)))
|
|
.AddArgumentListArguments(
|
|
Argument(ValueOf(index)),
|
|
Argument(IdentifierName("value")));
|
|
|
|
PropertyDeclarationSyntax MakeWriterRefTypeProperty(
|
|
TypeSyntax type,
|
|
string name,
|
|
ExpressionSyntax getter,
|
|
ExpressionSyntax setter,
|
|
bool cast,
|
|
bool cond)
|
|
{
|
|
if (cond)
|
|
{
|
|
type = _names.MakeNullableRefType(type);
|
|
}
|
|
|
|
var prop = MakeWriterProperty(type, name, getter, setter, cast, cond);
|
|
|
|
if (cond && _names.NullableEnable)
|
|
{
|
|
prop = prop.AddAttributeLists(
|
|
AttributeList(
|
|
SingletonSeparatedList(
|
|
Attribute(
|
|
IdentifierName("DisallowNull")))));
|
|
}
|
|
return prop;
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakePointerProperty(TypeSyntax type, string name, object index, bool cast, bool cond)
|
|
{
|
|
ExpressionSyntax getter = MakePointerSyntax(type, index);
|
|
ExpressionSyntax setter = MakeLinkSyntax(index, cond);
|
|
|
|
return MakeWriterRefTypeProperty(type, name, getter, setter, cast, cond);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakePointerAsStructProperty(TypeSyntax type, string name, object index, bool cast, bool cond)
|
|
{
|
|
ExpressionSyntax getter = MakeTypedPointerSyntax(index, type);
|
|
ExpressionSyntax setter = MakeLinkSyntax(index, cond);
|
|
|
|
return MakeWriterRefTypeProperty(type, name, getter, setter, cast, cond);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeProperty(
|
|
TypeSyntax outerType,
|
|
TypeSyntax innerType,
|
|
string name,
|
|
string readName,
|
|
string writeName,
|
|
object indexOrBitOffset,
|
|
ExpressionSyntax secondArg,
|
|
bool cast,
|
|
bool cond,
|
|
bool pasd)
|
|
{
|
|
var getter = InvocationExpression(
|
|
MemberAccessExpression(
|
|
SyntaxKind.SimpleMemberAccessExpression,
|
|
ThisExpression(),
|
|
IdentifierName(readName)))
|
|
.AddArgumentListArguments(
|
|
Argument(ValueOf(indexOrBitOffset)),
|
|
Argument(secondArg));
|
|
|
|
ExpressionSyntax value = IdentifierName("value");
|
|
|
|
if (cast)
|
|
{
|
|
value = CastExpression(innerType, value);
|
|
}
|
|
|
|
var setter = InvocationExpression(
|
|
MemberAccessExpression(
|
|
SyntaxKind.SimpleMemberAccessExpression,
|
|
ThisExpression(),
|
|
IdentifierName(writeName)))
|
|
.AddArgumentListArguments(
|
|
Argument(ValueOf(indexOrBitOffset)),
|
|
Argument(value),
|
|
Argument(secondArg));
|
|
|
|
if (pasd)
|
|
{
|
|
setter.AddArgumentListArguments(Argument(secondArg));
|
|
}
|
|
|
|
return MakeWriterProperty(outerType, name, getter, setter, cast, cond);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakePrimitiveProperty<T>(Field field, string readName)
|
|
{
|
|
return MakeProperty(
|
|
_names.Type<T>(Nullability.NonNullable),
|
|
null,
|
|
_names.GetCodeIdentifier(field).ToString(),
|
|
readName,
|
|
nameof(Zap.SerializerExtensions.WriteData),
|
|
field.BitOffset.Value,
|
|
ValueOf(field.DefaultValue.ScalarValue),
|
|
false,
|
|
field.DiscValue.HasValue,
|
|
true);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeEnumProperty(Field field, string readName)
|
|
{
|
|
return MakeProperty(
|
|
_names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.NotRelevant, Nullability.NonNullable),
|
|
_names.Type<ushort>(Nullability.NonNullable),
|
|
_names.GetCodeIdentifier(field).ToString(),
|
|
readName,
|
|
nameof(Zap.SerializerExtensions.WriteData),
|
|
field.BitOffset.Value,
|
|
ValueOf(field.DefaultValue.ScalarValue),
|
|
true,
|
|
field.DiscValue.HasValue,
|
|
true);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeTextProperty(Field field)
|
|
{
|
|
return MakeProperty(
|
|
_names.Type<string>(Nullability.NullableRef),
|
|
null,
|
|
_names.GetCodeIdentifier(field).ToString(),
|
|
nameof(Zap.SerializerState.ReadText),
|
|
nameof(Zap.SerializerState.WriteText),
|
|
(int)field.Offset,
|
|
ValueOf(field.DefaultValue.ScalarValue),
|
|
false,
|
|
field.DiscValue.HasValue,
|
|
false);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeStructProperty(Field field)
|
|
{
|
|
var qtype = _names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.Writer, Nullability.NonNullable);
|
|
|
|
return MakePointerAsStructProperty(qtype, _names.GetCodeIdentifier(field).ToString(),
|
|
(int)field.Offset, false, field.DiscValue.HasValue);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeGroupProperty(Field field)
|
|
{
|
|
TypeSyntax type = QualifiedName(
|
|
_names.MakeTypeName(field.Type.Definition).IdentifierName,
|
|
_names.WriterStruct.IdentifierName);
|
|
|
|
var getter = InvocationExpression(
|
|
GenericName(nameof(Zap.SerializerState.Rewrap))
|
|
.AddTypeArgumentListArguments(type));
|
|
|
|
if (field.DiscValue.HasValue)
|
|
{
|
|
type = _names.MakeNullableRefType(type);
|
|
}
|
|
|
|
return MakeWriterProperty(type, _names.GetCodeIdentifier(field).ToString(), getter, null, false, field.DiscValue.HasValue);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeListProperty(Field field)
|
|
{
|
|
var qtype = _names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.Writer, Nullability.NonNullable);
|
|
|
|
return MakePointerProperty(qtype, _names.GetCodeIdentifier(field).ToString(),
|
|
(int)field.Offset, false, field.DiscValue.HasValue);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakePointerProperty(Field field)
|
|
{
|
|
var type = IdentifierName(nameof(Zap.DynamicSerializerState));
|
|
|
|
return MakePointerProperty(type, _names.GetCodeIdentifier(field).ToString(), (int)field.Offset, false, field.DiscValue.HasValue);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeCapProperty(Field field)
|
|
{
|
|
var nonNullableType = _names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.Writer, Nullability.NonNullable);
|
|
var nullableType = _names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.Writer, Nullability.NullableRef);
|
|
int index = (int)field.Offset;
|
|
string name = _names.GetCodeIdentifier(field).ToString();
|
|
ExpressionSyntax getter = MakeReadCapSyntax(nonNullableType, index);
|
|
ExpressionSyntax setter = MakeLinkObjectSyntax(index);
|
|
|
|
return MakeWriterProperty(nullableType, name, getter, setter, false, field.DiscValue.HasValue);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeWriterUnionSelector(TypeDefinition def)
|
|
{
|
|
return MakeProperty(
|
|
_names.UnionDiscriminatorEnum.IdentifierName,
|
|
_names.Type<ushort>(Nullability.NonNullable),
|
|
_names.UnionDiscriminatorProp.ToString(),
|
|
nameof(Zap.SerializerExtensions.ReadDataUShort),
|
|
nameof(Zap.SerializerExtensions.WriteData),
|
|
def.UnionInfo.TagOffset,
|
|
ValueOf(default(ushort)),
|
|
true, false, true);
|
|
}
|
|
|
|
PropertyDeclarationSyntax MakeWriterFieldProperty(Field field)
|
|
{
|
|
switch (field.Type.Tag)
|
|
{
|
|
case TypeTag.Bool:
|
|
return MakePrimitiveProperty<bool>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataBool));
|
|
|
|
case TypeTag.S8:
|
|
return MakePrimitiveProperty<sbyte>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataSByte));
|
|
|
|
case TypeTag.U8:
|
|
return MakePrimitiveProperty<byte>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataByte));
|
|
|
|
case TypeTag.S16:
|
|
return MakePrimitiveProperty<short>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataShort));
|
|
|
|
case TypeTag.U16:
|
|
return MakePrimitiveProperty<ushort>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataUShort));
|
|
|
|
case TypeTag.S32:
|
|
return MakePrimitiveProperty<int>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataInt));
|
|
|
|
case TypeTag.U32:
|
|
return MakePrimitiveProperty<uint>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataUInt));
|
|
|
|
case TypeTag.S64:
|
|
return MakePrimitiveProperty<long>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataLong));
|
|
|
|
case TypeTag.U64:
|
|
return MakePrimitiveProperty<ulong>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataULong));
|
|
|
|
case TypeTag.F32:
|
|
return MakePrimitiveProperty<float>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataFloat));
|
|
|
|
case TypeTag.F64:
|
|
return MakePrimitiveProperty<double>(field,
|
|
nameof(Zap.SerializerExtensions.ReadDataDouble));
|
|
|
|
case TypeTag.Enum:
|
|
return MakeEnumProperty(field, nameof(Zap.SerializerExtensions.ReadDataUShort));
|
|
|
|
case TypeTag.Text:
|
|
return MakeTextProperty(field);
|
|
|
|
case TypeTag.Struct:
|
|
return MakeStructProperty(field);
|
|
|
|
case TypeTag.Group:
|
|
return MakeGroupProperty(field);
|
|
|
|
case TypeTag.List:
|
|
case TypeTag.Data:
|
|
return MakeListProperty(field);
|
|
|
|
case TypeTag.AnyPointer:
|
|
case TypeTag.StructPointer:
|
|
case TypeTag.ListPointer:
|
|
return MakePointerProperty(field);
|
|
|
|
case TypeTag.CapabilityPointer:
|
|
case TypeTag.Interface:
|
|
return MakeCapProperty(field);
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public ClassDeclarationSyntax MakeWriterStruct(TypeDefinition def)
|
|
{
|
|
var WriterDecl = ClassDeclaration(_names.WriterStruct.ToString())
|
|
.AddModifiers(Public)
|
|
.AddBaseListTypes(
|
|
SimpleBaseType(IdentifierName(nameof(Zap.SerializerState))));
|
|
|
|
var members = def.Tag == TypeTag.Group ?
|
|
MakeGroupWriterStructMembers() :
|
|
MakeWriterStructMembers(def);
|
|
|
|
WriterDecl = WriterDecl.AddMembers(members.ToArray());
|
|
|
|
if (def.UnionInfo != null)
|
|
{
|
|
WriterDecl = WriterDecl.AddMembers(MakeWriterUnionSelector(def));
|
|
}
|
|
|
|
foreach (var field in def.Fields)
|
|
{
|
|
var propDecl = MakeWriterFieldProperty(field);
|
|
|
|
if (propDecl != null)
|
|
{
|
|
WriterDecl = WriterDecl.AddMembers(propDecl);
|
|
}
|
|
}
|
|
|
|
return WriterDecl;
|
|
}
|
|
}
|
|
}
|