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 版本控制引入了用于对 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

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

示例

在新的设计中,背景部分中将 @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=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,因为该 API 显示 removed=5,而我们的目标是 6”这种情况。

同样,我们可以引入一个 re_added 实参,以明确元素是作为替换项添加的,还是首次添加的。这样可以避免“我以为自己还不能使用此 API,因为它显示 added=6,而我们的目标是 5”这种情况。

我拒绝此替代方案的原因有以下几个:

  • 我认为第一种情况比第二种情况更重要。

  • 名称 re_added 不尽如人意,但我找不到更好的名称。

  • 即使没有此功能,我们仍然可以使 fidldoc 推断元素是否是首次为 added

在先技术和参考资料

我在 2021 年开发 FIDL 版本控制功能时,在一份名为“FIDL 版本控制:交换元素”的内部文档中讨论过类似的想法。

此提案专门针对 FIDL 版本控制的设计,据我所知,目前还没有针对此确切问题的现有技术。