Files
zeekay 2aa8261f86 rebrand: complete capnp → ZAP across all C# source/build files
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.
2026-06-19 23:46:57 -07:00

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;
}
}
}