源生成器家族总览(KernLab.Tier.CodeGen)
给谁看:要用 KernLab.Tier 标注驱动编译期代码生成的开发者(结构/产品/协议/线格式/命令壳作者)。 回答什么:每个生成器吃什么标注、吐什么代码、报什么诊断、详细文档在哪。 形态:本包是纯生成器(IIncrementalGenerator——零运行时反射,NativeAOT 安全);标注定义在
KernLab.Tier.CodeGen.Abstractions(零依赖,见标注面总概)。全部生成器经Directory.Build.props以 Analyzer 引用全局注入——引用 KernLab.Tier 包即生效,零手工安装。
0. 生成器一览(按"你想生成什么"找)
| 你想要 | 标注 | 生成器 | 产出 | 详细文档 |
|---|---|---|---|---|
| 结构布局 codec(零手写字节序;大端可选) | [BinaryLayout] + [Valid*] 族 |
BinaryLayoutGenerator |
XxxCodec:StructSize/Offset_*/Read_*/Write_*/Validate/Create();Endianness = BigEndian 面向网络字节序协议(DNS 消费——#498) |
标注面总概 §3 |
| Ring/索引封闭类型 | [assembly: RingKey(typeof(TKey))] |
RingKeyGenerator |
RingOfXxx/HashOfXxx/BTreeOfXxx/SkipListOfXxx 封闭薄类 + CreateAsync |
ring.md §3.1 |
| KV 组合存储 | [assembly: KvStore(...)] |
KvStoreGenerator |
TierKvOfXxx 存储族 + 会话类型 |
tierkv.md |
| RPC 线消息族 | [WireMessage]+[WireMessageTag(n)] |
WireMessageGenerator |
XxxCodec.Encode/TryDecode + Tag* 常量(tag 判别/公共前缀/字段序全生成物) |
本文 §2 |
| 变长集合线编码 | [WireArray] |
WireArrayGenerator |
[Count 4B][item×N] codec(Encode/TryDecode) |
本文 §2 |
| 常量表防冲突 | [ConstantRegistry] |
ConstantRegistryGenerator |
重复值编译期 Error + Zones 区间谓词注入 |
本文 §3 |
| TierFs 类型化重载族 | [MediumOptions("nature")] |
TierFsGenerator |
TierFs.New/Open(spec, TOptions, logger) 重载族 |
本文 §4 |
| TierFs 协议自动注册 | [NetworkProtocol("s3")] + [assembly: TierProtocolExported] |
TierFsGenerator |
ModuleInitializer 注册代码(引用协议程序集即挂载,消费方零代码) | 本文 §4 |
| 命令壳(CLI+HTTP 双执行面) | [CommandGroup] 族 |
CommandGenerator |
XxxCli/XxxHttp 静态类(参数绑定/帮助/补全/退出码) |
command-shell.md |
1. 线格式族(WireMessage / WireArray)
消息族(tag 判别 + 公共前缀 + 变长成员):
[WireMessage] // 族根:声明公共前缀字段(全体子类共享)
public abstract partial class RaftMsg
{
public long Term { get; set; } // 声明序 = 线顺序(零偏移知识)
}
[WireMessageTag(0x01)] // 子类 tag(族内唯一——重复值 TCSG050 Error)
public sealed partial class RequestVote : RaftMsg
{
public long LastLogIndex { get; set; }
[WireMember(8)] // 变长成员防御上限(缺此标注 TCSG052)
public byte[] Data { get; set; } = [];
}
byte[] wire = RaftMsgCodec.Encode(msg); // 生成物(挂在族根)
bool ok = RaftMsgCodec.TryDecode(wire, out RaftMsg? decoded); // 未知 tag/截断/超上限 = false(畸形拦截)
- 生成
XxxCodec.Encode → byte[]/TryDecode(ReadOnlySpan<byte>, out msg) → bool与Tag子类名常量;tag 判别、公共前缀、字段声明序、小端字节序全部生成物。 - 成员支持:bool/基元整型、标注
[BinaryLayout]的 struct(嵌套件)、byte[]/ReadOnlyMemory<byte>([Len 4B][bytes])、数组/列表([Count 4B][item×N])。 - 变长集合 struct(
[WireArray]):非数组字段构成定长前缀 + 恰一个数组字段承载变长区;Count > MaxCount = TryDecode false。嵌套项的项大小经其StructSize获得(须开BinaryLayoutFeatures.StructSize)。
2. 常量注册表(ConstantRegistry)
[ConstantRegistry(Zones = new[] {
"IsCore:0x00-0x4F", "IsUserRegistrable:0x60-0xAF", "IsForbidden:0x50-0x5F,0xB0-0xFF" })]
public static partial class ProtocolId
{
public const byte Raft = 0x10;
public const byte Mirror = 0x20; // 撞值 → TCSG040 Error(编译期锁死)
}
- 类内全部整型
const数值两两相异——重复即TCSG040(FrameKind/ProtocolId/协议域防冲突)。 Zones可选:生成static bool 谓词(value)注入本类(类须partial);混合整型类型报TCSG044。
3. TierFs 生成面(重载族 + 协议注册桥,TierFsGenerator)
类型化重载族——options 子类贴 [MediumOptions],消费方即得类型化工厂重载:
[MediumOptions("local", Verbs = "New,Open,OpenOrCreate")] // nature = 本性四类(local/memory/virtual/network)
public sealed class DiskFileSystemOptions : FileSystemOptions { ... }
// 生成:TierFs.New/Open/OpenOrCreate("local:///...", DiskFileSystemOptions, logger) 类型化重载族
//(virtual 拆两簇:FormatOptions=Verbs"New" / OpenOptions=Verbs"Open"——各发各的动词)
协议自动注册——实现 ITierProtocolBuilder + 两行标注,引用即挂载:
[NetworkProtocol("s3")] // 协议键 = spec path 首段
public sealed class S3ProtocolBuilder : ITierProtocolBuilder { ... }
[assembly: TierProtocolExported] // 程序集级导出声明(消费方桥精确扫描——零误扫)
// 消费方引用本程序集 → TierFsGenerator 发射 ModuleInitializer 注册 → TierFs.Open("network:///s3/...") 即达
- 未知 nature 值编译期报错(拼错即炸,fail-fast);注册走无参构造 + ModuleInitializer——零反射。
4. 诊断 ID 速查
| 段 | 归属 | 例子 |
|---|---|---|
| TCSG001-002 | BinaryLayout | Size 不准 / 嵌套 struct 缺标注 |
| TCSG020 | RingKey | 声明不满足 unmanaged 约束 |
| TCSG022-023 | KvStore | KvStore 声明违规 |
| TCSG040/044 | ConstantRegistry | 常量重复 / Zones 混合整型类型 |
| TCSG050/052 | WireMessage | tag 重复 / 变长成员缺上限 |
| TCSG054-060 | Command | 路径冲突/参数未标注/GET 带 body 等 |
| TCSG120-122 | TierFs 规范分析器(独立包) | scheme 拼错/参数不适用介质——见 TierFs 规范分析器 |
| TCSG130-139 | 通用纪律分析器(独立包) | 分层依赖/禁用模式——见 Tier 分析器 |
5. 反模式
- 手写字节序/偏移常量——布局知识归标注声明 + 生成物;手拼即违规(漂移无编译期守卫)。
- 绕过封闭薄类直接继承开放泛型——
[RingKey]产出的封闭类是唯一消费面(CS0122 防误绑)。 - 在标注上写运行时逻辑——标注是纯声明;生成物之外的行为放partial 方法/扩展。
6. 想深入?指路
| 想懂什么 | 去哪 |
|---|---|
| 标注全集与 BinaryLayout 使用细节 | 标注面总概 |
| 命令壳全参数(CLI/HTTP/绑定规则/补全) | command-shell.md |
| 生成器/分析器诊断 ID 与豁免 | 生成器源码头注释 + Tier 分析器 |
| 结构侧消费形态(RingKey/KvStore 落地示例) | ring.md / tierkv.md |