RFC-0231:FIDL 版本控制替换语法

RFC-0231:FIDL 版本控制替换语法
状态已接受
领域
  • FIDL
说明

向 @available 属性添加 replace=N 参数

问题
Gerrit 更改
  • 922341
作者
审核人
提交日期(年-月-日)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

  • 此验证仅适用于直接标记为 removedreplaced 的元素,不适用于继承参数的子元素。

示例

在新设计中,“后台”部分中关于向版本 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=2Foo。但不会对子元素 bar 及其匿名类型 Bar 执行类似的验证。

实现

  1. 实现 replaced 参数,包括其验证。

  2. 在适用的情况下,将所有 FIDL 文件更改为使用 replaced,而不是 removed

  3. 实现新的 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 版本控制的设计,因此据我所知,目前还没有关于这一确切问题的先进技术。