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