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

RFC-0231:FIDL 版本控制替换语法
状态已接受
区域
  • 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 的元素。

  • 此验证仅适用于直接标记为 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 版本控制的设计,因此据我所知,没有针对此确切问题的在先技术。