| RFC-0231:FIDL 版本控制替换语法 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 向 @available 属性添加 replaced=N 参数 |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2023-09-26 |
| 审核日期(年-月-日) | 2023-10-24 |
摘要
更改 FIDL 的 @available 属性以支持 replaced 参数。它与 removed 类似,但会验证是否在同一版本中 added 了替换项。
背景
RFC-0083:FIDL 版本控制引入了 @available 属性,用于
对 FIDL API 进行版本控制。该设计中的一项要求是允许对所有可能的更改进行版本控制。换句话说,应该可以在单个 versioned.fidl 文件中表达 v1.fidl 向任意不同的 v2.fidl 的转换。该设计通过允许多个元素具有相同的名称(只要其版本范围不重叠)来满足该要求。
例如,假设在版本 5 中向协议 P 添加 @discoverable 属性。我们无法使用 @available 直接表达这一点,因为属性不能放在其他属性上。不过,我们可以改为执行以下操作:
@available(added=1, removed=5)
protocol P {};
@available(added=5)
@discoverable
protocol P {};
这种移除元素并在同一版本中重新添加元素的技术称为 交换。
设计初衷
添加、废弃和移除 API 的常规生命周期的语法非常直观。另一方面,交换模式则不然。如果加以解释,它会很有意义,但它是一项需要解释的隐藏功能。在上面的示例中,如果您认为 removed=5 实际上意味着协议在版本 5 中已消失,尤其是当相应的 added=5 在源代码中不相邻时,您可能会这么想。
将替换与移除区分开来,还可以摆脱 旧版功能并将其替换为更通用的解决方案。这是一个单独的 提案:RFC-0232:适用于多个 API 级别的 FIDL 绑定。
利益相关方
教员: abarth@google.com
审核人: hjfreyer@google.com、ianloic@google.com、ddorwin@google.com
咨询对象: wez@google.com、sethladd@google.com、wilkinsonclay@google.com
社交化: 在编写 RFC 之前,我与 FIDL 团队和平台版本控制工作组讨论了这一想法。
设计
引入名为
replaced的新@available参数。它的行为与removed相同,但具有不同的验证,如下所述。除了library声明之外,它可用于替换任何元素上的removed。当元素标记为
removed=N时,验证是否没有 另一个具有相同名称且标记为added=N的元素。当元素标记为
replaced=N时,验证是否有 另一个具有相同名称且标记为added=N的元素。此验证仅适用于直接标记为
removed或replaced的元素,而不适用于继承参数的子元素。
示例
在 背景部分 中,向版本 5 中的协议添加 @discoverable
的示例在新设计中如下所示:
@available(added=1, replaced=5)
protocol P {};
@available(added=5)
@discoverable
protocol P {};
再举一例,假设要替换包含具有匿名类型的成员的结构体:
@available(added=1, replaced=2)
struct Foo {
bar @generated_name("Bar") table {};
};
@available(added=2)
struct Foo {
baz string;
};
由于第一个 Foo 标记为 replaced=2,因此 fidlc 会验证是否存在另一个标记为 added=2 的 Foo。不过,它不会对子元素 bar 或其匿名类型 Bar 执行类似的验证。
实现
实现
replaced参数,包括其验证。在适用情况下,将所有 FIDL 文件更改为使用
replaced而不是removed。实现新的
removed验证。如果 (2) 遗漏了任何内容,CQ 将失败。
性能
此提案对性能没有影响。
工效学设计
此提案通过在语言中直接支持 它,使交换模式更符合工效学设计。
向后兼容性
此提案对向后兼容性没有影响。
安全注意事项
此提案对安全性没有影响。
隐私注意事项
此提案对隐私没有影响。
测试
必须更新以下文件才能测试新行为:
- tools/fidl/fidlc/tests/availability_interleaving_tests.cc
- tools/fidl/fidlc/tests/decomposition_tests.cc
- tools/fidl/fidlc/tests/versioning_tests.cc
- tools/fidl/fidlc/tests/versioning_types_tests.cc
文档
必须更新以下页面才能记录 replaced:
还应移除“交换”一词,改为使用“替换”。
fidldoc 工具目前针对单个 API 级别的 JSON IR 运行,因此
它永远不会看到 removed 参数,也不会看到 replaced 参数
(https://fxbug.dev/42084086)。修复此问题后,应更新 fidldoc,以清楚地指明何时替换了内容,而不是移除了内容。
缺点、替代方案和未知因素
替代方案:重新添加的参数
此提案引入了 replaced 参数,以便清楚地表明元素是被替换而不是被移除。它避免了“我以为我无法使用此 API,因为它显示 removed=5,而我们的目标是 6”这种情况。
我们可以类似地引入 re_added 参数,以明确元素是作为替换项添加的,而不是首次添加的。它避免了“我以为我无法使用此 API,因为它显示 added=6,而我们的目标是 5”这种情况。
我拒绝此替代方案的原因如下:
我认为第一种情况比第二种情况更重要。
re_added这个名称不令人满意,而且我想不出更好的名称。即使没有此参数,我们仍然可以使 fidldoc 推断元素是否是
added首次添加。
在先技术和参考文档
我在 2021 年开发 FIDL 版本控制时讨论过类似的想法,该想法记录在一份名为“FIDL 版本控制:交换元素”的内部文档中。
此提案非常具体地针对 FIDL 版本控制的设计,因此据我所知,没有针对此确切问题的在先技术。