| 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时,请验证是否IS另一个标记为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 版本控制的设计,因此据我所知,没有关于这个确切问题的先前技术。