| RFC-0076:FIDL API 摘要 | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 以人類可讀的形式呈現 FIDL API 介面。 |
| 問題 | |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2021-03-16 |
| 審查日期 (年-月-日) | 2021-03-16 |
摘要
介紹摘要方法,以人類可解讀的格式做為第一個輸出內容,說明 FIDL API 介面,並建議利用這項摘要,在 Fuchsia 來源樹狀結構中找出 FIDL 程式庫的 API 變更。
修訂 (2022 年 8 月)。本 RFC 說明使用者可解讀的文字格式,每個 API 元素各占一行。實作期間,系統會新增包含相同資訊的 JSON 格式 (https://fxrev.dev/480357)。與文字格式不同,JSON 格式可以剖析回 Go 資料結構,這對 fidl_api_diff 特別有用。由於目前只使用 JSON 格式,我們已移除文字格式,以利維護。
提振精神
撰寫本文時,Fuchsia 專案已啟動多項工作,共同目標是追蹤平台 API 介面的變更。完成後,我們就能使用版本控管,將平台開發作業與 SDK 消費者使用的程式庫版本分離。
具體來說,在 FIDL 領域中,需要以人類可解讀的形式呈現 FIDL 程式庫的 API 介面。這項表示法 (以下稱為「摘要」) 有多種用途:
以方便使用者閱讀的格式列出 FIDL 程式庫提供的 API。
其他產生 API 介面的軟體 (例如 go) 也會保留類似的目錄。這樣一來,在版本控管很重要的情況下,就能將版本歸因於特定 API 摘要。
做為偵測 FIDL API 中不相容變更的基礎。
API 摘要可用於計算兩個 API 介面之間的差異,自動檢查一個 API 介面是否可演化為另一個介面。目前使用的方法是將所有來源檔案以可預測的方式串連,並移除註解和無關的間距,藉此產生程式庫來源的穩定 (稱為「正規化」) 形式,而這項改善措施可提升精確度。
做為其他工作的建構區塊,例如用於偵測 API 變更後需要執行的測試的 Compatibility Testing Suite (CTS,請參閱 RFC-0015)。
特別是 CTS,必須在平台變更時縮減執行的測試項目。瞭解 API 介面中的變更,可讓軟體只執行受變更影響的測試,節省執行時間和運算資源。
入門範例
請參考下列 FIDL 程式庫定義,取自 fuchsia.accessibility.gesture。註解已刪除,但其他內容完整無缺。
library fuchsia.accessibility.gesture;
/// Maximum size of a returned utterance.
const uint64 MAX_UTTERANCE_SIZE = 16384;
/// Gesture types that accessibility offers to a UI component for listening.
enum Type {
THREE_FINGER_SWIPE_UP = 1;
THREE_FINGER_SWIPE_DOWN = 2;
THREE_FINGER_SWIPE_RIGHT = 3;
THREE_FINGER_SWIPE_LEFT = 4;
};
/// An interface to listen for accessibility gestures.
protocol Listener {
/// When accessibility services detect a gesture, the listener is informed
/// of which gesture was performed.
OnGesture(Type gesture_type) -> (bool handled, string:MAX_UTTERANCE_SIZE? utterance);
};
/// An interface for registering a listener of accessibility gestures.
[Discoverable]
protocol ListenerRegistry {
/// A UI registers itself to start listening for accessibility gestures
/// through `listener`.
Register(Listener listener) -> ();
};
上述程式庫的 API 摘要如下所示:
protocol/member fuchsia.accessibility.gesture/Listener.OnGesture(fuchsia.accessibility.gesture/Type gesture_type) -> (bool handled,string:16384? utterance)
protocol fuchsia.accessibility.gesture/Listener
protocol/member fuchsia.accessibility.gesture/ListenerRegistry.Register(fuchsia.accessibility.gesture/Listener listener) -> ()
protocol fuchsia.accessibility.gesture/ListenerRegistry
const fuchsia.accessibility.gesture/MAX_UTTERANCE_SIZE uint64 16384
enum/member fuchsia.accessibility.gesture/Type.THREE_FINGER_SWIPE_DOWN 2
enum/member fuchsia.accessibility.gesture/Type.THREE_FINGER_SWIPE_LEFT 4
enum/member fuchsia.accessibility.gesture/Type.THREE_FINGER_SWIPE_RIGHT 3
enum/member fuchsia.accessibility.gesture/Type.THREE_FINGER_SWIPE_UP 1
strict enum fuchsia.accessibility.gesture/Type uint32
library fuchsia.accessibility.gesture
請注意以下幾點:
- 每個 API 元素都是一行文字。
- 每個 API 元素都以完整名稱表示。
- 摘要中的 API 元素順序是固定的。如果 FIDL 檔案中的宣告順序有所變更,API 摘要的形狀不會受到影響。
您可以使用
grep等文字工具輕鬆擷取摘要內容。舉例來說,假設 API 摘要位於名為fidl.api_summary的檔案中,下列指令列只會擷取通訊協定的 API 介面:cat fidl.api_summary | grep "fuchsia.accessibility.gesture/ListenerRegistry"同樣地,只擷取方法也很簡單:
cat fidl.api_summary \ | grep "fuchsia.accessibility.gesture/ListenerRegistry" \ | grep "protocol/member"您可以透過下列方式產生基本的 API 介面差異:
diff -u fidl.old.api_summary fidl.new.api_summary(假設
fidl.{old,new}.api_summary分別包含原始和修改後的 API 介面)
需求條件
API 摘要應可供人閱讀,並能以
grep和diff等簡單工具處理。產生的 API 摘要必須列出 FIDL 程式庫中所有會影響 API 介面的元素,且僅限這些元素。
設計
API 摘要格式包含對 API 有影響的程式庫相關資訊。這項資訊定義於「定義:RFC-0024 的來源相容性和轉換性」一節,並擷取自 FIDL 繫結規格。這實際上只是 FIDL IR 中已有的資訊子集,但呈現方式更易於人類閱讀和文字公用程式處理。如需完整清單,請參閱規則摘要。
摘要規則涵蓋所有 FIDL 語言建構。
每個 FIDL 宣告都會使用完整名稱命名。舉例來說,在上述範例的縮短程式碼片段中:
library fuchsia.accessibility.gesture;
enum Type { THREE_FINGER_SWIPE_UP = 1; };
protocol Listener {
OnGesture(Type gesture_type);
};
識別碼 OnGesture 一律稱為 fuchsia.accessibility.gesture/Listener.OnGesture。
為方便讀取和處理,檔案格式刻意保持扁平。
也就是說,FIDL 成員 (顯示在 struct 或 protocol 等範圍中) 會列在不同的文字行中。這樣一來,我們就能在日後視需要擴充格式。舉例來說,日後推出版本控管屬性時,您就能納入這些屬性。
單一 API 摘要檔案會列出整個 FIDL 程式庫中出現的所有宣告,無論宣告是在多少個檔案中指定。
API 摘要中聲明的顯示順序與聲明順序無關,且不會變動。相關宣告會刻意保留在附近,方便後續處理,但這並非正確性要求:任何與宣告順序無關的穩定排序都已足夠。
API 摘要排序
宣告的排序方式衍生自 FIDL AST:宣告的寫入方式與 AST 的後序遍歷一致,在選取同層級的識別項時,會優先選取完整名稱在字母數字上較小的識別項。
我們將此稱為 API 摘要排序。
這個方法建議在 API 摘要檔案中,依下列順序宣告:
fuchsia.accessibility.gesture/Listener.OnGesture
fuchsia.accessibility.gesture/Listener
fuchsia.accessibility.gesture/ListenerRegistry.Register
fuchsia.accessibility.gesture/ListenerRegistry
fuchsia.accessibility.gesture/MAX_UTTERANCE_SIZE
fuchsia.accessibility.gesture/Type.THREE_FINGER_SWIPE_DOWN
fuchsia.accessibility.gesture/Type.THREE_FINGER_SWIPE_LEFT
fuchsia.accessibility.gesture/Type.THREE_FINGER_SWIPE_RIGHT
fuchsia.accessibility.gesture/Type.THREE_FINGER_SWIPE_UP
fuchsia.accessibility.gesture/Type
fuchsia.accessibility.gesture
適用於上述範例 FIDL 程式庫。
無論聲明在 .fidl 檔案中的實際順序為何 (包括是否分散在多個檔案中),API 摘要中的聲明順序都會相同。
API 摘要宣告結構定義
下方提供 API 摘要檔案的簡化 BNF,以供參考。
summary ::= declaration_list
declaration_list ::= declaration
| declaration "\n" declaration_list
declaration ::= library
| const
| bits
| bits_member
| enum
| enum_member
| struct
| struct_member
| union
| union_member
| protocol
| protocol_member
| alias
alias ::= "alias" fqn
bits ::= strictness "bits" fqn fp
bits_member ::= "bits/member" fqn
const ::= "const" fqn d fv
enum ::= strictness "enum" ft
enum_member ::= "enum/member" fqn fv
library ::= "library" fqn
protocol ::= "protocol" fqn
protocol_member ::= "protocol/member" fqn d
struct ::= resourceness "struct" fqn
struct_member ::= "struct/member" fqn ft [ fv ]
union ::= strictness "union" fqn
union_member ::= "union/member" fqn
resourceness ::= "" | "resource"
strictness ::= "flexible" | "strict"
d ::= <FIDL protocol member type signature>
fp ::= <FIDL primitive type>
fqn ::= <FIDL identifier>
ft ::= <FIDL type>
fv ::= <FIDL value>
實作
API 摘要是由程式 fidl_api_summarize 實作。這個程式會將 FIDL IR 做為輸入內容,並輸出 FIDL API 摘要,且兩個檔案名稱都會指定為標記。按照慣例,呼叫端「應」使用擴充項 .api_summary 做為這項程式的輸出內容,但這並非硬性規定。
效能
fidl_api_summarize 是 FIDL IR 檔案的簡單轉換。
抽樣檢查結果顯示,在合理大小的程式庫上執行時,程式會在約 0.1 秒內完成執行。也就是說,這個程式很可能適用於在每個 FIDL 程式庫上執行,做為一般建構程序的一部分。
安全性考量
目前 fidl_api_summarize 的實作方式不會嘗試驗證 FIDL IR,並假設輸入內容一律是 fidlc 產生的有效輸出內容。這可能會導致程式容易受到格式錯誤的輸入內容混淆,但很難判斷這是否可用於 Fuchsia 建構程序的攻擊向量。
隱私權注意事項
fidl_api_summarize目前處理的資訊屬於可公開檢視的程式碼存放區。因此,輸入內容適用的隱私權規則,也應適用於輸出內容。
也就是說,如果用來總結非公開的 FIDL 程式庫程式碼,其輸出內容應與所用程式庫程式碼的隱私權標準相同。
測試
我們會使用大量的範例輸入內容測試程式,並處理這些內容,然後與本機輸出內容進行比較。這可確保在 Fuchsia 程式碼集生命週期內,結果保持一致。
說明文件
fidl_api_summarize 的使用方式應記錄在 https://fuchsia.dev 的 FIDL 說明頁面中。
既有技術和參考資料
Go 語言 API 會定期產生 API 介面摘要。