RFC-0076:FIDL API 摘要 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 為人類可讀的 FIDL API 介面提供格式。 |
問題 | |
更小鳥 | |
作者 | |
審查人員 | |
提交日期 (年月分) | 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),用於偵測在 API 變更後需要執行的測試。
CTS 尤其需要減少對平台變更執行的測試耗用的電量。瞭解 API 介面的變更項目,可能可讓軟體僅執行受變更影響的測試,進而節省執行時間和運算資源。
入門範例
請考慮以下從 fuchsia.accessibility.gesture
取得的 FIDL 程式庫定義。註解已縮減,但程式庫尚未完整完成。
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 摘要產生的 API 摘要「必須」列出影響 API 介面的 FIDL 程式庫的所有元素。
設計
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);
};
ID OnGesture
一律稱為 fuchsia.accessibility.gesture/Listener.OnGesture
。
檔案格式刻意保持扁平,以便讀取和處理。也就是說,FIDL 成員 (出現在 struct
或 protocol
等範圍中) 會分別以不同的文字行列出。日後我們就能視需要
擴展格式舉例來說,日後有版本管理屬性可供使用時,就可能加入該屬性。
單一 API 摘要檔案會列出整個 FIDL 程式庫中的所有宣告,無論宣告指定多少檔案都一樣。
API 摘要中顯示的宣告順序與宣告順序獨立且穩定。相關宣告會刻意保持接近,以利後續處理,但這並非正確性要求:任何聲明順序獨立且穩定的排序就已足夠。
API 摘要排序
宣告的順序衍生自 FIDL AST:宣告順序與 AST 的後順序週遊一致,在選取同層級時,會先挑選包含英數字元完整名稱更小的 ID。
以下為排序 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
檔案中的實際排序方式為何 (包括分割至多個檔案),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 介面摘要。