RFC-0231:FIDL 版本控制替换语法 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 向 @available 属性添加 replace=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
相同,只不过它具有不同的验证,如下所述。可以代替removed
用于任何元素(library
声明除外)。将某个元素标记为
removed=N
后,请验证是否不存在标记为added=N
的同名其他元素。将某个元素标记为
replaced=N
后,请验证是否存在另一个标记为added=N
的同名元素。IS此验证仅适用于直接标记为
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 版本控制的设计,因此据我所知,目前还没有关于这一确切问题的先进技术。