| RFC-0231:FIDL 版本控制替换语法 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 向 @available 属性添加了 replaced=N 实参 |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2023-09-26 |
| 审核日期(年-月-日) | 2023-10-24 |
摘要
更改 FIDL 的 @available 属性以支持 replaced 实参。它与 removed 类似,但会验证替换项是否为 added 且版本相同。
背景
RFC-0083:FIDL 版本控制引入了用于对 FIDL API 进行版本控制的 @available 属性。该设计中的一项要求是允许对所有可能的更改进行版本控制。换句话说,应该可以在单个 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 绑定。
利益相关方
Facilitator: abarth@google.com
Reviewers: 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的元素,而不适用于继承实参的子元素。
示例
在新的设计中,背景部分中将 @discoverable 添加到版本 5 的协议的示例如下所示:
@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,因为该 API 显示 removed=5,而我们的目标是 6”这种情况。
同样,我们可以引入一个 re_added 实参,以明确元素是作为替换项添加的,还是首次添加的。这样可以避免“我以为自己还不能使用此 API,因为它显示 added=6,而我们的目标是 5”这种情况。
我拒绝此替代方案的原因有以下几个:
我认为第一种情况比第二种情况更重要。
名称
re_added不尽如人意,但我找不到更好的名称。即使没有此功能,我们仍然可以使 fidldoc 推断元素是否是首次为
added。
在先技术和参考资料
我在 2021 年开发 FIDL 版本控制功能时,在一份名为“FIDL 版本控制:交换元素”的内部文档中讨论过类似的想法。
此提案专门针对 FIDL 版本控制的设计,据我所知,目前还没有针对此确切问题的现有技术。