可逆计算要求所有业务结构以 DSL 形式存在1)。但问题来了:谁来定义 DSL 本身的结构?这就是 XDef 的角色。
XDef(XML Definition)是 Nop 平台中用来定义 DSL 语法的元模型语言。它描述了一个 DSL 文件可以有哪些节点、属性、子元素、数据类型等。基于 XDef,平台可以自动推导出解析器、验证器、IDE 插件、差量合并规则。
传统的 DSL 实现方式是为每个语言手写解析器:
每个 DSL 都要重复“写解析器 → 写验证器 → 写编辑器插件”这个流程,成本很高。
Nop 的解决思路:所有 DSL 共享同一种元模型描述。只要写好 XDef,配套工具自动生成。
下面是一个 .xdef 文件片段,它定义了 ORM 实体模型(orm.xml)的语法:
<entity name="string" table="string">
<columns>
<column name="string" code="string"
primary="boolean" mandatory="boolean">
<comment text="string" />
</column>
</columns>
</entity>
这个 XDef 描述的意思是:
基于这几十行定义,平台自动获得:
XDef 内置了一套完整的数据类型:
| 类型 | 说明 |
|---|---|
| string | 字符串 |
| boolean | 布尔值 |
| integer | 整数 |
| double | 浮点数 |
| decimal | 高精度小数(BigDecimal) |
| date | 日期 |
| datetime | 日期时间 |
| enum | 枚举值(配合 option 使用) |
| xml | 内嵌 XML 片段 |
| csv | 逗号分隔列表 |
还可以通过 xdef:check 扩展自定义验证逻辑。
XDef 支持元模型级别的复用机制:
这意味着可以定义基础 XDef,然后在具体 DSL 中扩展。例如,所有业务模型的 XDef 都继承自一个公共的基础 XDef,统一了 id、name、label 等公共属性的定义。
定义一个 Nop 平台 DSL 的完整流程:
.xdef(元模型)→ 解析器 + 验证器 + IDE 插件(自动生成)
↓
.xdsl(具体模型文件)→ 经过 x-extends 合并
↓
Generator → Java / SQL / GraphQL / 前端
整个过程,手写部分只有 .xdef 和 .xdsl 文件。
| 对比维度 | XSD | JSON Schema | XDef |
|---|---|---|---|
| 语法复杂度 | 繁琐 | 中等 | 简洁 |
| 差量合并 | 不支持 | 不支持 | 内置 |
| IDE 生成 | 需要额外工具 | 需要额外工具 | 自动 |
| 已定义 DSL 数量 | 少数 | 少数 | 数百个 |
| 与生成器集成 | 无 | 无 | 原生 |
XDef 的设计目标并非替代 XSD/JSON Schema,而是为可逆计算中的 DSL 体系提供统一的元模型基础。差量合并和代码生成才是它的核心价值。