FIDL 編譯器錯誤目錄

本文件列出 FIDL 編譯器產生的所有錯誤。 fidlc。這個網域中的錯誤 ID 一律會以前置字串顯示 fi- 後接 4 位數字的代碼,例如 fi-0123

fi-0001:無效字元

勒克斯無法將字元轉換為位於 指定位置。

library test.bad.fi0001;

type ßar = struct {
    value uint64;
};

請改用替代或移除字元來修正無效字元。

library test.good.fi0001;

type Foo = struct {
    value uint64;
};

無效字元取決於位置。詳情請參閱 FIDL 語言規格: FIDL 語法每個部分允許的字元。

fi-0002:非預期的換行符號

字串常值不允許分割在多行之間:

library test.bad.fi0002;

const BAD_STRING string:1 = "Hello
World";

請改用逸出順序 \n 來代表換行符號:

library test.good.fi0002;

const GOOD_STRING string:11 = "Hello\nWorld";

fi-0003:逸出序列無效

Lexer 在 逸出序列。

library test.bad.fi0003;

const UNESCAPED_BACKSLASH string:2 = "\ ";
const BACKSLASH_TYPO string:1 = "\i";
const CODE_POINT_TYPO string:1 = "\Y1F604";

請改用有效字元來開始逸出序列,或是移除 非預期中的反斜線字元

library test.good.fi0003;

const ESCAPED_BACKSLASH string:2 = "\\ ";
const REMOVED_BACKSLASH string:1 = "i";
const SMALL_CODE_POINT string:3 = "\u{2604}";
const BIG_CODE_POINT string:4 = "\u{01F604}";

請參閱 FIDL 文法規格 以取得有效的逸出序列。

fi-0004:無效的十六進位數字

字串常值中的萬國碼 (Unicode) 逸出不得含有無效的十六進位數字:

library test.bad.fi0004;

const SMILE string = "\u{1G600}";

您必須以十六進位指定有效的 Unicode 碼點,範圍從 0 到 10FFFF。 每個十六進位數字必須是介於 0 到 9 之間的數字,並使用小寫英文字母,從 af, 或從 AF 的大寫字母。在本例中,GF 的錯字:

library test.good.fi0004;

const SMILE string = "\u{1F600}";

fi-0005

fi-0006:預計宣告

如果 FIDL 預期收到宣告並找到其他內容,就會發生這個錯誤。 這通常是拼寫錯誤所致。有效的宣告如下:typealiasconstusingprotocolservice

library test.bad.fi0006;

cosnt SPELLED_CONST_WRONG string:2 = ":("; // Expected a declaraction (such as const).

如要修正這項錯誤,請檢查頂層宣告是否有誤,並確保 您只使用 FIDL 支援的功能。

library test.good.fi0006;

const SPELLED_CONST_RIGHT string:2 = ":)";

fi-0007:未預期的符記

剖析期間發生未預期的權杖時,就會發生這項錯誤。 一般而言,這是錯字:

library test.bad.fi0007;

alias MyType = vector<uint8>:<,256,optional>; // Extra leading comma

如要修正這個問題,一般會移除非預期的權杖 ,請提供其餘缺少的語法:

library test.good.fi0007;

alias MyType = vector<uint8>:<256, optional>;

fi-0008:未預期的符記

當 FIDL 剖析器遇到文法無效錯誤時,就會發生這個錯誤 產生下一個符記這種情況有很多種,例如列舉成員缺少 =, 額外的權杖,例如 library = what.is.that.equals.doing.there 等。

library test.bad.unexpectedtokenofkind;

type Numbers = flexible enum {
    ONE; // FIDL enums don't have a default value.
};

一般來說,如要解決這個問題,系統會新增缺少的權杖或移除 再多一個

library test.good.fi0008;

type Numbers = flexible enum {
    ONE = 1;
};

如要避免發生這個錯誤,請仔細檢查 *.fidl 檔案,確保這些檔案 通常文法正確

fi-0009:未預期的 ID

這個錯誤通常是因為識別碼使用的位置不正確:

using test.bad.fi0009;

請改用正確的 ID:

library test.good.fi0009;

fi-0010:ID 無效

系統發現某個 ID 不符合有效條件 識別碼FIDL ID 可包含英數字元和底線 (特別是 A-Za-z0-9_),以及每個 ID 開頭必須是英文字母,結尾則須為英文字母或數字。

library test.bad.fi0010a;

// Foo_ is not a valid identifier because it ends with '_'.
type Foo_ = struct {
    value uint64;
};

如要解決這個問題,請變更 ID,確保僅包含有效 ID 開頭必須是英文字母,結尾則須為英文字母或數字。

library test.good.fi0010a;

type Foo = struct {
    value uint64;
};

如果將多部分 (虛線) 的 ID 傳遞至 屬性。

library test.bad.fi0010b;

@foo(bar.baz="Bar", zork="Zoom")
type Empty = struct{};

如要修正這個問題,請變更屬性,讓屬性中僅使用單部分 ID。

library test.good.fi0010b;

@foo(bar="Bar", zork="Zoom")
type Empty = struct {};

fi-0011:無效的程式庫名稱元件

程式庫名稱只能使用英文字母和數字 (A-Za-z0-9)。 且開頭必須是英文字母

library test.bad.fi0011.name_with_underscores;

如要修正這個問題,請確認所有程式庫名稱元件均符合相關規定。

library test.good.fi0011.namewithoutunderscores;

fi-0012:類型的版面配置類別無效

類型宣告必須指定 FIDL 已知的版面配置:

library test.bad.fi00012;

type Foo = invalid {};

有效的版面配置為 bitsenumstructtableunion

library test.good.fi0012;

type Empty = struct {};

版面配置是 FIDL 的可參數說明 類型。這是指一系列可能進一步接收的 指定形狀例如,struct 是一種版面配置 定義特定成員時會成為具體類型;而 array 是指定類型要重複時,會變得具體的版面配置 並按照指定次數來請求

版面配置全都以 FIDL 語言建構而成,使用者無法以各種方式 您可以指定自己的版面配置,也可以自行建立通用類型的範本。

fi-0013:包裝類型無效

如果傳遞給列舉或位元宣告的值並非 類別 ID 或 ID 或 ID 等。舉例來說,如果您改為提供字串值做為 "支援類型:

library test.bad.fi0013;

type TypeDecl = enum : "int32" {
    FOO = 1;
    BAR = 2;
};

如要修正這項錯誤,請確認列舉或位元的支援類型為類型 或 ID。

library test.good.fi0013;

type TypeDecl = enum : int32 {
    FOO = 1;
    BAR = 2;
};

fi-0014:屬性含空白括號的屬性

如果屬性含有括號但沒有引數,就會發生這個錯誤。

library test.bad.fi0014;

@discoverable()
protocol MyProtocol {};

如要修正這個問題,請從不含引數的屬性中移除括號,或者提交屬性 引數

library test.good.fi0014;

@discoverable
protocol MyProtocol {};

FIDL 一般不允許做為樣式選擇的屬性使用空白引數清單。

fi-0015:屬性引數必須全部命名為

為求明確,如果屬性有多個引數, 屬性的引數必須明確命名。

當屬性含有多個引數,但卻沒有引數時,就會發生這個錯誤 明確提供引數的名稱

library test.bad.fi0015;

@foo("abc", "def")
type MyStruct = struct {};

如要修正這個問題,請使用 name=value 語法提供所有引數的名稱。

library test.good.fi0015;

@foo(bar="abc", baz="def")
type MyStruct = struct {};

fi-0016:成員之前遺漏序數

聯集或資料表中的欄位缺少序數時,就會發生這項錯誤。

library test.bad.fi0016a;

type Foo = table {
    x int64;
};
敬上
library test.bad.fi0016b;

type Bar = union {
    foo int64;
    bar vector<uint32>:10;
};

如要修正這個錯誤,請明確指定資料表或聯集的序數:

library test.good.fi0016;

type Foo = table {
    1: x int64;
};

type Bar = union {
    1: foo int64;
    2: bar vector<uint32>:10;
};

不同於結構體,資料表和聯集的設計目的是讓回溯相容 調整內容為了實現這個目標 值,就必須是序數,才能識別資料表欄位或聯集變體。目的地: 避免混淆,並在變更過程中 或聯集,您必須明確指定序數。

fi-0017:序數超出

資料表和聯集的序數必須是有效的無正負號 32 位元整數。負面評價 當序或中度大於 4,294,967,295 時,就會導致這類錯誤。

library test.bad.fi0017a;

type Foo = table {
  -1: foo string;
};
敬上
library test.bad.fi0017b;

type Bar = union {
  -1: foo string;
};

如要修正這個錯誤,請確認所有序數都在允許範圍內。

library test.good.fi0017;

type Foo = table {
    1: foo string;
};

type Bar = union {
    1: foo string;
};

fi-0018:中等開頭必須是 1

tableunion 成員序數值都不得為 0:

library test.bad.fi0018;

type Foo = strict union {
    0: foo uint32;
    1: bar uint64;
};

而是應從 1 開始編號:

library test.good.fi0018;

type Foo = strict union {
    1: foo uint32;
    2: bar uint64;
};

fi-0019:嚴格位元、列舉或聯集不得為空

嚴格位元、列舉或聯集不得含有零個成員:

library test.bad.fi0019;

type Numbers = strict enum {};

相反地,必須至少有一名成員:

library test.good.fi0019a;

type Numbers = flexible enum {};

或者,您也可以標示宣告 flexible,而不是 strict

library test.good.fi0019b;

type Numbers = strict enum {
    ONE = 1;
};

空白位元、列舉或聯集不會顯示任何資訊,因此通常不應 在 API 中使用然而,彈性資料類型是專為演變而設計, 而定義開頭是空白的彈性位元或列舉,加上 預期稍後會新增成員請務必仔細思考 定義新資料類型時使用 strictflexible

fi-0020:無效的通訊協定成員

當通訊協定中的項目無法辨識有效時,就會發生這個錯誤 通訊協定成員,例如通訊協定中的某個項目不是通訊協定時 組合、單向方法、雙向方法或事件。

library test.bad.fi0020;

protocol Example {
    NotAMethodOrCompose;
};

如要修正這項錯誤,請移除無效商品或將其轉換為正確商品 預期採用的通訊協定項目類型語法

library test.good.fi0020;

protocol Example {
    AMethod();
};

fi-0021

fi-0022:無法將屬性附加至 ID

如果在宣告類型中加入屬性,就會發生這項錯誤 屬於 ID 類型的話舉例來說,將屬性放在 欄位名稱,但 struct 宣告中欄位類型之前,會將 與 屬性的類型,而不是欄位本身。如果 欄位類型是指名稱所參照的既有類型 無法套用任何屬性

library test.bad.fi0022;

type Foo = struct {
    // uint32 is an existing type, extra attributes cannot be added to it just
    // for this field.
    data @foo uint32;
};

如果意圖是將屬性套用至欄位,則屬性應 。

屬性可以套用至宣告的類型。也就是說 struct 欄位或其他類似宣告的型別是匿名型別 而非 ID 類型,則可將屬性套用至類型。

library test.good.fi0022;

type Foo = struct {
    // The foo attribute is associated with the data1 field, not the uint32
    // type.
    @foo
    data1 uint32;
    // The type of data2 is a newly declared anonymous structure, so that new
    // type can have an attribute applied to it.
    data2 @foo struct {};
};

fi-0023:類型宣告中的屬性

使用內嵌版面配置時 可以直接將屬性放置在版面配置之前不過,當您宣告 在頂層輸入,您無法進行以下操作:

library test.bad.fi0023;

type Foo = @foo struct {};

相反地,您必須在 type 關鍵字前面加入屬性:

library test.good.fi0023;

@foo
type Foo = struct {};

之所以採取這種做法,是因為如果允許在兩個位置使用屬性,可能會令人混淆。

fi-0024:方法參數清單的文件註解

方法參數清單不得包含文件註解:

library test.bad.fi0024;

protocol Example {
    Method(/// This is a one-way method.
            struct {
        b bool;
    });
};

請針對「目前」,將文件註解加入方法本身:

library test.good.fi0024;

protocol Example {
    /// This is a one-way method.
    Method(struct {
        b bool;
    });
};

修正這個錯誤後,這個錯誤就不會再存在。 為了描述方法酬載,遷移發生保留的錯誤 而非參數清單

fi-0025:匯入群組必須位於檔案頂端

除了檔案頂端的 library 宣告以外,沒有任何 至於檔案的 using 匯入前的其他宣告,它們必須存在:

library test.bad.fi0025;

alias i16 = int16;
using dependent;

type UsesDependent = struct {
    field dependent.Something;
};

如要解決這個錯誤,請將所有的 using 匯入項目直接放在區塊中 library 宣告後:

library test.good.fi0025;

using dependent;

alias i16 = int16;
type UsesDependent = struct {
    field dependent.Something;
};

這項規則反映了 FIDL 團隊做出的美妙決定 如果依附元件群組經過妥善分組,且能輕鬆找出,就能更輕鬆地閱讀。

fi-0026:在文件註解區塊中加註

註解不應置於文件註解區塊中:

library test.bad.fi0026;

/// start
// middle
/// end
type Empty = struct {};

請改為將註解放在文件註解區塊的前後:

library test.good.fi0026;

// some comments above,
// maybe about the doc comment
/// A
/// multiline
/// comment!
// another comment, maybe about the struct
type Empty = struct {};

一般來說,文件註解區塊前方的註解為最佳效果 以供文件註解本身的註解

fi-0027:文件註解區塊中的空白行

文件註解區塊中不得空白行:

library test.bad.fi0027;

/// start

/// end
type Empty = struct {};

空白行應該只在文件註解的前面或後面 區塊:

library test.good.fi0027a;

/// A doc comment
type Empty = struct {};

您也可以考慮完全省略空白行:

library test.good.fi0027b;

/// A doc comment
type Empty = struct {};

fi-0028:文件註解後面必須加上宣告

文件註解不可任意浮動,如同一般註解:

library test.bad.fi0028;

type Empty = struct {};
/// bad

無論何種情況,文件註解都必須列在 FIDL 宣告之前:

library test.good.fi0028a;

/// A doc comment
type Empty = struct {};

FIDL「lowers」文件在編譯期間對 @doc 屬性的註解。事實上 您可以視需要直接以這種方式撰寫註解:

library test.good.fi0028b;

@doc("An attribute doc comment")
type Empty = struct {};

從技術面來看,獨立的文件註解無法完整呈現, 「文件」的意思也可能在語意上造成混淆什麼東西?取消喜歡 一般註解、文件註解會處理成結構化文件,以及 因此,請務必清楚說明這些 FIDL 結構所連結的是哪個 FIDL 結構。

fi-0029:資源定義必須至少有一項屬性

不允許沒有指定屬性的資源定義:

library test.bad.resourcedefinitionnoproperties;

resource_definition SomeResource : uint32 {
  properties {};
};

請指定至少一個屬性:

library test.good.fi0029;

resource_definition SomeResource : uint32 {
    properties {
        subtype strict enum : uint32 {
            NONE = 0;
        };
    };
};

這是與 FIDL 內部實作相關的錯誤,因此應該僅 。使用者 絕不顯示這個錯誤

其所參照的 resource_definition 宣告是 FIDL 的內部方式 定義諸如帳號代碼等資源,而且日後可能會 處理一般化工作。

fi-0030:修飾符無效

每個 FIDL 修飾符都有一組特定可用的宣告。 禁止在禁止的宣告中使用修飾符:

library test.bad.fi0030;

type MyStruct = strict struct {
    i int32;
};

最佳做法是移除違規的修飾符:

library test.good.fi0030;

type MyStruct = struct {
    i int32;
};

fi-0031:只有位元和列舉可以有子類型

並非所有 FIDL 版面配置都可以包含子類型:

library test.bad.fi0031;

type Foo = flexible union : uint32 {};

只有 bitsenum 版面配置是在基礎類型上定義。

library test.good.fi0031;

type Foo = flexible enum : uint32 {};

bitsenum 的版面配置不太獨特,因為他們只是 完整性 FIDL 基元的子類型受限因此 因此可以指定做為這個子類型的基礎類型。 相反地,structtableunion 版面配置可以任意大型 可能包含許多成員,因此全版面配置的子類型無法使 感覺。

fi-0032:不允許使用重複的修飾符

禁止在單一宣告中指定同一個修飾符:

library test.bad.fi0032;

type MyUnion = strict resource strict union {
    1: foo bool;
};

移除重複的修飾符:

library test.good.fi0032;

type MyUnion = resource strict union {
    1: foo bool;
};

fi-0033:衝突的修飾符

某些修飾符彼此互斥,且無法同時修改 相同的宣告:

library test.bad.conflictingmodifiers;

type StrictFlexibleFoo = strict flexible union {
    1: b bool;
};

type FlexibleStrictBar = flexible strict union {
    1: b bool;
};

您只能在一張 strictflexible 修飾符中擇一使用 逐一宣告

library test.good.fi0033;

type FlexibleFoo = flexible union {
    1: i int32;
};

type StrictBar = strict union {
    1: i int32;
};

目前,只有 strictflexible 修飾符彼此互斥 resource 修飾符沒有對等修飾符,因此具有 未套用這類限制

fi-0034:名稱衝突

兩個宣告的名稱不得重複:

library test.bad.fi0034;

const COLOR string = "red";
const COLOR string = "blue";

而是為每個宣告提供專屬的名稱:

library test.good.fi0034b;

const COLOR string = "red";
const OTHER_COLOR string = "blue";

或者,如果您不小心新增了一個宣告,請移除以下任一宣告:

library test.good.fi0034a;

const COLOR string = "red";

如要進一步瞭解如何選擇名稱,請參閱 FIDL 樣式指南

fi-0035:正式名稱衝突

兩個宣告不得使用相同的正規名稱:

library test.bad.fi0035;

const COLOR string = "red";

protocol Color {};

雖然 COLORColor 的外觀不同,但兩者都會以 正規名稱 color。如要取得正規名稱,只需將 將名稱原始為 snake_case

如要修正錯誤,請為每項宣告命名,且名稱後方應不得重複 標準化:

library test.good.fi0035;

const COLOR string = "red";

protocol ColorMixer {};

遵循 FIDL 樣式指南的命名規範,即可 降低發生錯誤的機率正規名稱衝突 在使用相同大小寫樣式的宣告之間不會發生,且 與其他樣式不同的廣告之間很少會發生 要求 (例如通訊協定名稱通常應為以「-er」結尾的名詞片語)。

FIDL 會強制執行這項規則,因為繫結產生器會將名稱轉換為 目標語言的慣用命名樣式。確保專屬標準 命名,我們保證繫結作業不會產生名稱衝突。 詳情請參閱 RFC-0040:識別碼不重複性

fi-0036:名稱重疊

具有相同名稱的宣告不能有重疊的播映資訊:

@available(added=1)
library test.bad.fi0036;

type Color = strict enum {
    RED = 1;
};

@available(added=2)
type Color = flexible enum {
    RED = 1;
};

請改用 @available 屬性,確定只有 宣告的任何版本:

@available(added=1)
library test.good.fi0036;

@available(replaced=2)
type Color = strict enum {
    RED = 1;
};

@available(added=2)
type Color = flexible enum {
    RED = 1;
};

您也可以重新命名或移除其中一項宣告,如下所示: fi-0034

請參閱 FIDL 版本管理,進一步瞭解版本管理。

fi-0037:正式名稱重疊

具有相同標準名稱的宣告不得重疊 播映時間:

@available(added=1)
library test.bad.fi0037;

const COLOR string = "red";

@available(added=2)
protocol Color {};

雖然 COLORColor 的外觀不同,但兩者都會以 正規名稱 color。如要取得正規名稱,只需將 將名稱原始為 snake_case

如要修正錯誤,請為每項宣告命名,且名稱後方應不得重複 以及標準化

@available(added=1)
library test.good.fi0037;

const COLOR string = "red";

@available(added=2)
protocol ColorMixer {};

或者,您也可以變更下列任一聲明的播映資訊: fi-0036 或移除宣告。

如要進一步瞭解 FIDL 要求宣告權限的原因,請參閱 fi-0035 且沒有不重複的正規名稱

fi-0038:名稱與匯入衝突

宣告的名稱不得與使用 using 匯入的程式庫名稱相同:

library dependency;

const VALUE uint32 = 1;
library test.bad.fi0038b;

using dependency;

type dependency = struct {};

// Without this, we'd get fi-0178 instead.
const USE_VALUE uint32 = dependency.VALUE;

請改為使用 using 以不同名稱匯入程式庫 ... as 語法:

library test.good.fi0038b;

using dependency as dep;

type dependency = struct {};

const USE_VALUE uint32 = dep.VALUE;

或者,您也可以重新命名宣告以避免衝突:

library test.good.fi0038c;

using dependency;

type OtherName = struct {};

const USE_VALUE uint32 = dependency.VALUE;

如要避免這個問題,您可以在程式庫名稱中使用多個元件。適用對象 例如 Fuchsia SDK 中的 FIDL 程式庫以 fuchsia. 開頭,因此 至少兩個元件,而且不得與宣告名稱衝突。

這項錯誤是為了防止混淆。舉例來說,如果 dependency 是 加入名為 VALUE 的成員列舉,系統會不明確 dependency.VALUE 會參照該列舉成員,或參照 匯入的程式庫

fi-0039:正規名稱與匯入衝突

宣告的標準名稱不得與匯入的程式庫時相同 using:

library dependency;

const VALUE uint32 = 1;
library test.bad.fi0039b;

using dependency;

type Dependency = struct {};

// Without this, we'd get fi-0178 instead.
const USE_VALUE uint32 = dependency.VALUE;

雖然 dependencyDependency 的外觀不同,但兩者 由「標準」名稱 dependency 表示。這樣您就能取得正規名稱 做法是將原始名稱轉換為 snake_case

如要修正錯誤,請使用 using 以不同名稱匯入程式庫 ... as 語法:

library test.good.fi0039b;

using dependency as dep;

type Dependency = struct {};

const USE_VALUE uint32 = dep.VALUE;

或者,您也可以重新命名宣告以避免衝突:

library test.good.fi0039c;

using dependency;

type OtherName = struct {};

const USE_VALUE uint32 = dependency.VALUE;

請參閱 fi-0038,瞭解出現這個錯誤的原因,以及如何避免。

如要進一步瞭解 FIDL 要求宣告權限的原因,請參閱 fi-0035 且沒有不重複的正規名稱

fi-0040:檔案對資料庫名稱有異議

程式庫可由多個檔案組成,但每個檔案都必須相同 名稱:

library test.bad.fi0040a;
library test.bad.fi0040b;

確認程式庫使用的所有檔案都使用相同的名稱:

library test.good.fi0040;
library test.good.fi0040;

多檔案程式庫的建議慣例是另外建立 空白的 overview.fidl 檔案,以做為主要的「項目」 點」到程式庫中overview.fidl 檔案也是合適的位置 加入以程式庫限定範圍的 @available 平台 規格

fi-0041:多個名稱相同的程式庫

傳遞至 fidlc 的每個程式庫都必須具有不重複的名稱:

library test.bad.fi0041;
library test.bad.fi0041;

確認所有程式庫的名稱皆不重複:

library test.good.fi0041a;
library test.good.fi0041b;

這項錯誤通常是因為在fidlc 不正確。構成每個必要程式庫所需的程式庫的組成檔案 編譯 (即編譯的程式庫以及其所有轉換程序) 依附元件) 必須以單一空格分隔的檔案清單的形式提供 透過 --files 引數指定這類旗標。常見錯誤是 嘗試傳遞單一 --files 清單中所有程式庫的檔案。

fi-0042:重複的程式庫匯入作業

無法多次匯入依附元件:

library test.bad.fi0042a;

type Bar = struct {};
library test.bad.fi0042b;

using test.bad.fi0042a;
using test.bad.fi0042a; // duplicated
type Foo = struct {
    bar test.bad.fi0042a.Bar;
};

確認每個依附元件僅匯入一次:

library test.good.fi0042a;

type Bar = struct {};
library test.good.fi0042b;

using test.good.fi0042a;
type Foo = struct {
    bar test.good.fi0042a.Bar;
};

值得注意的是,FIDL 不支援匯入不同版本的 同一個程式庫系統會為整個 fidlc 解析 @available 版本 透過 --available 旗標進行編譯,這表示兩個程式庫 所有已編譯的依附元件及其所有依附元件都必須使用相同的版本 程式碼編譯作業

fi-0043:衝突的程式庫匯入

匯入的程式庫不得建立別名 與其他匯入程式庫的非別名名稱衝突:

library test.bad.fi0043a;

type Bar = struct {};

// This library has a one component name to demonstrate the error.
library fi0043b;

type Baz = struct {};
library test.bad.fi0043c;

using test.bad.fi0043a as fi0043b; // conflict
using fi0043b;

type Foo = struct {
    a fi0043b.Bar;
    b fi0043b.Baz;
};

選擇其他別名,即可解決名稱衝突問題:

library test.good.fi0043a;

type Bar = struct {};
library fi0043b;

type Baz = struct {};
library test.good.fi0043c;

using test.good.fi0043a as dep;
using fi0043b;

type Foo = struct {
    a dep.Bar;
    b fi0043b.Baz;
};

fi-0044:衝突的程式庫匯入別名

匯入的程式庫不得建立別名 與指派給其他匯入程式庫的別名相衝突:

library test.bad.fi0044a;

type Bar = struct {};
library test.bad.fi0044b;

type Baz = struct {};
library test.bad.fi0044c;

using test.bad.fi0044a as dep;
using test.bad.fi0044b as dep; // conflict
type Foo = struct {
    a dep.Bar;
    b dep.Baz;
};

選擇不含衝突的別名,解決名稱衝突問題:

library test.good.fi0044a;

type Bar = struct {};
library test.good.fi0044b;

type Baz = struct {};
library test.good.fi0044c;

using test.good.fi0044a as dep1;
using test.good.fi0044b as dep2;
type Foo = struct {
    a dep1.Bar;
    b dep2.Baz;
};

fi-0045:使用宣告的屬性遭到禁止

屬性無法附加至 using 宣告:

library test.bad.fi0045a;

type Bar = struct {};
library test.bad.fi0045b;

/// not allowed
@also_not_allowed
using test.bad.fi0045a;

type Foo = struct {
    bar test.bad.fi0045a.Bar;
};

請移除這項屬性來修正錯誤:

library test.good.fi0045a;

type Bar = struct {};
library test.good.fi0045b;

using test.good.fi0045a;

type Foo = struct {
    bar test.good.fi0045a.Bar;
};

這項限制也適用於 /// ... 份文件註解,而且這些內容僅限於 @doc("...") 屬性的語法糖。

fi-0046:不明的程式庫

在大多數情況下,這是因為依附元件有錯字,或建構系統沒有提供。 如果相關依附元件是刻意未使用,則必須移除相關的使用行:

library test.bad.fi0046;

using dependent; // unknown using.

type Foo = struct {
    dep dependent.Bar;
};

請確認所有匯入內容都會透過建構系統新增為程式庫的依附元件。

library test.good.fi0046;

type Foo = struct {
    dep int64;
};

fi-0047

fi-0048:選擇性的資料表成員

資料表成員類型不得為 optional

library test.bad.fi0048;

type Foo = table {
    // Strings can be optional in general, but not in table member position.
    1: t string:optional;
};

從所有成員中移除 optional 限制:

library test.good.fi0048;

type Foo = table {
    1: t string;
};

資料表成員一律為選用項目,因此針對成員的基礎類型指定此資訊是多餘的。

表格成員一律可以選用,因為線路上,每個資料表成員都以一個向量項目表示。 這個向量一定代表表格中所有已知的欄位,因此每個省略的資料表成員都會 視為空值信封 - 與省略的選擇性類型表示法完全相同。

fi-0049:非必要的工會成員

無法選擇是否加入聯合成員:

library test.bad.fi0049;

type Foo = strict union {
    // Strings can be optional in general, but not in unions.
    1: bar string:optional;
};

移除 optional 限制:

library test.good.fi0049;

type Foo = strict union {
    1: bar string;
};

FIDL 不允許將聯集成員設為選用,因為這可能會導致透過許多方式表示相同值。 例如,包含三個選用成員的聯集會有 6 個狀態 (每個成員 2 個)。而應該使用 第四個成員類型為 struct {},或將整體聯集設為選用 Foo:optional

fi-0050:禁止使用已淘汰的結構體預設語法

先前允許為 struct 成員設定預設值 FIDL:

library test.bad.fi0050;

type MyStruct = struct {
    field int64 = 20;
};

RFC-0160:移除 FIDL 結構體預設值的支援,這個行為將 不允許:

library test.good.fi0050;

type MyStruct = struct {
    field int64;
};

無法使用 struct 成員的預設值。使用者應進行設定 應用程式邏輯的預設值

少數舊版使用者已可使用這個語法 列在編譯器內建的許可清單中,但沒有任何新的例外狀況 您想加入這份清單中遷移這些使用者後,這項功能 將從 FIDL 中永久移除。

fi-0051:不明的相依程式庫

使用不明資料庫的符號時,就會發生這個錯誤。

library test.bad.fi0051;

type Company = table {
    1: employees vector<unknown.dependent.library.Person>;
    2: name string;
};

如要修正這個問題,請使用宣告來匯入缺少的相依程式庫。

library known.dependent.library;

type Person = table {
    1: age uint8;
    2: name string;
};
library test.good.fi0051;
using known.dependent.library;

type Company = table {
    1: employees vector<known.dependent.library.Person>;
    2: name string;
};

這個錯誤通常發生於 fidlc 指令列叫用 格式錯誤。如果您確定存在未知資料庫,且 必須能解決;請務必傳送相依程式庫的檔案 會透過傳遞至 --files 旗標的空格分隔清單,正確定義這些元素。

fi-0052:找不到名稱

如果您使用 FIDL 編譯器找不到的名稱,就會發生這個錯誤。

library test.bad.fi0052;

protocol Parser {
    Tokenize() -> (struct {
        tokens vector<string>;
    }) error ParsingError; // ParsingError doesn't exist.
};

如要修正這個問題,請移除找不到的名稱:

library test.good.fi0052a;

protocol Parser {
    Tokenize() -> (struct {
        tokens vector<string>;
    });
};

或定義找不到的名稱:

library test.good.fi0052b;

type ParsingError = flexible enum {
    UNEXPECTED_EOF = 0;
};

protocol Parser {
    Tokenize() -> (struct {
        tokens vector<string>;
    }) error ParsingError;
};

fi-0053:無法參照成員

當您參照的成員不是 bitsenum 項目時,就會發生這個錯誤。

library test.bad.fi0053a;

type Person = struct {
    name string;
    birthday struct {
        year uint16;
        month uint8;
        day uint8;
    };
};

const JOHNS_NAME Person.name = "John Johnson"; // Cannot refer to member of struct 'Person'.
library test.bad.fi0053b;

type Person = struct {
    name string;
    birthday struct {
        year uint16;
        month uint8;
        day uint8;
    };
};

type Cat = struct {
    name string;
    age Person.birthday; // Cannot refer to member of struct 'Person'.
};

如要修正這項錯誤,請變更為已命名的類型:

library test.good.fi0053a;

type Person = struct {
    name string;
    birthday struct {
        year uint16;
        month uint8;
        day uint8;
    };
};

const JOHNS_NAME string = "John Johnson";

或擷取成員的類型:

library test.good.fi0053b;

type Date = struct {
    year uint16;
    month uint8;
    day uint8;
};

type Person = struct {
    name string;
    birthday Date;
};

type Cat = struct {
    name string;
    age Date;
};

fi-0054:位元/列舉成員無效

如果在未事先定義的情況下參照 enumbits 成員,就會發生這項錯誤。

library test.bad.fi0054;

type Enum = enum {
    foo_bar = 1;
};

const EXAMPLE Enum = Enum.FOO_BAR;

為避免發生這個錯誤,請確認您先前已宣告參照 成員的值。這些值有大小寫之分。

library test.good.fi0054;

type Enum = enum {
    foo_bar = 1;
};

const EXAMPLE Enum = Enum.foo_bar;

fi-0055:已淘汰的參考檔案無效

當使用帶有 typeconst 的參照 @available 屬性不相容。這通常是因為您在 淘汰了較新版本的 typesconsts

@available(added=1)
library test.bad.fi0055;

@available(added=1, deprecated=2, note="use Color instead")
alias RGB = array<uint8, 3>;

@available(added=2)
type Color = struct {
    r uint8;
    g uint8;
    b uint8;
    a uint8;
};

@available(added=3)
type Config = table {
    // RGB is deprecated in version 2.
    1: color RGB;
};

如要修正這個錯誤,請使用未淘汰的 typeconst

@available(added=1)
library test.good.fi0055;

@available(added=1, deprecated=2, note="use Color instead")
alias RGB = array<uint8, 3>;

@available(added=2)
type Color = struct {
    r uint8;
    g uint8;
    b uint8;
    a uint8;
};

@available(added=3)
type Config = table {
    // Using a non-deprecated type.
    1: color Color;
};

fi-0056:參照給已淘汰的其他平台無效

當您使用其他 typeconst 的參照時,就會發生這個錯誤 @available 屬性不相容的平台。這種情況通常發生在 使用已淘汰的 typesconsts

@available(platform="foo", added=1)
library test.bad.fi0056a;

@available(added=1, deprecated=2, note="use Color instead")
alias RGB = array<uint8, 3>;

@available(added=2)
type Color = struct {
    r uint8;
    g uint8;
    b uint8;
    a uint8;
};
@available(platform="bar", added=2)
library test.bad.fi0056b;

using test.bad.fi0056a;

@available(added=3)
type Config = table {
    // RGB is deprecated in version 2.
    1: color test.bad.fi0056a.RGB;
};

如要修正這個錯誤,請使用未淘汰的 typeconst

@available(platform="foo", added=1)
library test.good.fi0056a;

@available(added=1, deprecated=2, note="use Color instead")
alias RGB = array<uint8, 3>;

@available(added=2)
type Color = struct {
    r uint8;
    g uint8;
    b uint8;
    a uint8;
};
@available(platform="bar", added=2)
library test.good.fi0056b;

using test.good.fi0056a;

@available(added=2)
type Config = table {
    // Change to use a non-deprecated type.
    1: color test.good.fi0056a.Color;
};

fi-0057:包含月經週期

有許多情況可能導致這個問題發生,但所有內容 基本上,這些變數基本上會對應到 無法解決這項錯誤最簡單的形式,就是當型別或通訊協定 在自己的定義中直接提及本身:

library test.bad.fi0057c;

type MySelf = struct {
    me MySelf;
};

發生更複雜的故障情況時,可能會轉換類型或通訊協定 至少透過一種間接層級提及自己:

library test.bad.fi0057a;

type Yin = struct {
    yang Yang;
};

type Yang = struct {
    yin Yin;
};
library test.bad.fi0057b;

protocol Yin {
    compose Yang;
};

protocol Yang {
    compose Yin;
};

只要在 循環,因為這樣可讓循環「中斷」編碼/解碼 時間:

library test.good.fi0057;

type MySelf = struct {
    me box<MySelf>;
};
敬上
library test.bad.fi0057d;

type MySelf = table {
    1: me MySelf;
};

系統不得使用信封無法解鎖的遞迴類型,因為 就無法編碼在上方第一個範例中,編碼 MySelf 會 需要對 MySelf 的執行個體進行初次編碼,而這反過來又需要 編碼是 MySelf 的例項、廣告啟動。這個問題的解決方法是 新增「休息時間」在這個鏈中,使用者可選擇自己 為另一個 MySelf 的巢狀例項編碼,或對空值信封進行編碼 若是沒有進一步資料

fi-0058:參照編譯器產生的酬載名稱

匿名方法酬載具有由 FIDL 自動產生的名稱 ,讓產生的後端程式碼使用者能夠參照他們所建構的類型 物件圖示請在 *.fidl 檔案本身參照這些類型 不過,我們也禁止:

library test.bad.fi0058;

protocol MyProtocol {
    strict MyInfallible(struct {
        in uint8;
    }) -> (struct {
        out int8;
    });
    strict MyFallible(struct {
        in uint8;
    }) -> (struct {
        out int8;
    }) error flexible enum {};
    strict -> MyEvent(struct {
        out int8;
    });
};

type MyAnonymousReferences = struct {
    a MyProtocolMyInfallibleRequest;
    b MyProtocolMyInfallibleResponse;
    c MyProtocolMyFallibleRequest;
    d MyProtocol_MyFallible_Result;
    e MyProtocol_MyFallible_Response;
    f MyProtocol_MyFallible_Error;
    g MyProtocolMyEventRequest;
};

如要直接參照酬載類型,則應擷取 酬載轉換為自身的具名類型宣告:

library test.good.fi0058;

type MyRequest = struct {
    in uint8;
};
type MyResponse = struct {
    out int8;
};
type MyError = flexible enum {};

protocol MyProtocol {
    strict MyInfallible(MyRequest) -> (MyResponse);
    strict MyFallible(MyRequest) -> (MyResponse) error MyError;
    strict -> MyEvent(MyResponse);
};

type MyAnonymousReferences = struct {
    a MyRequest;
    b MyResponse;
    c MyRequest;
    // There is no way to explicitly name the error result union.
    // d MyProtocol_MyFallible_Result;
    e MyResponse;
    f MyError;
    g MyResponse;
};

所有 FIDL 方法和事件都會保留 [PROTOCOL_NAME][METHOD_NAME]Request 匿名要求酬載的名稱成效卓越、難以理解的雙向方法 此外,請額外預訂 [PROTOCOL_NAME][METHOD_NAME]Response。雙向方法 可彈性或可捨棄預訂的廣告:

  • [PROTOCOL_NAME]_[METHOD_NAME]_Result
  • [PROTOCOL_NAME]_[METHOD_NAME]_Response
  • [PROTOCOL_NAME]_[METHOD_NAME]_Error

基於歷史原因,這些名稱使用底線與其他名稱不同。

fi-0059:常數類型無效

並非所有類型都可用於 const 宣告:

library test.bad.fi0059;

const MY_CONST string:optional = "foo";

請盡可能轉換為允許的類型:

library test.good.fi0059;

const MY_CONST string = "foo";

只有 FIDL 原始物件 (boolint8int16int32int64uint8uint16uint32uint64float32float64,以及非選用 string 類型可用於 const 宣告的左側。

fi-0060:無法解析常數值

常數值必須可解析為已知值:

library test.bad.fi0060;

const MY_CONST bool = optional;

請確認使用的常數是有效值:

library test.good.fi0060;

const MY_CONST bool = true;

這個錯誤通常發生了其他錯誤, 無法解析預期常數的特性

fi-0061:或者在非原始值的運算子

二元或運算子只能用於基本:

library test.bad.fi0061;

const HI string = "hi";
const THERE string = "there";
const OR_OP string = HI | THERE;

建議將目前操作的資料顯示為 bits 列舉:

library test.good.fi0061;

type MyBits = flexible bits {
    HI = 0x1;
    THERE = 0x10;
};
const OR_OP MyBits = MyBits.HI | MyBits.THERE;

fi-0062:不允許使用新類型

來自 RFC-0052:類型別名和新類型的新類型 已完全實作,目前無法使用:

library test.bad.fi0062;

type Matrix = array<float64, 9>;

同時,您可以透過使用 單一元素:

library test.good.fi0062a;

type Matrix = struct {
    elements array<float64, 9>;
};

或者,您也可以定義別名,但請注意,此類型與新類型 且沒有任何型別安全,也就是說,可與叢集的 基礎類型):

library test.good.fi0062b;

alias Matrix = array<float64, 9>;

fi-0063:預期值但已取得類型

const 宣告的右側必須解析為常數值。 非類型:

library test.bad.fi0063;

type MyType = struct {};
const MY_CONST uint32 = MyType;

確認右側為值:

library test.good.fi0063;

const MY_VALUE uint32 = 8;
const MY_CONST uint32 = MY_VALUE;

fi-0064:位元或列舉值類型不正確

使用 bitsenum 變數做為 const 宣告中的值時, bits/enum 值的類型必須與 const 宣告:

library test.bad.fi0064;

type MyEnum = enum : int32 {
    VALUE = 1;
};
type OtherEnum = enum : int32 {
    VALUE = 5;
};
const MY_CONST MyEnum = OtherEnum.VALUE;

其中一種解決方法是變更 const 宣告的類型,以符合 儲存的值:

library test.good.fi0064;

type MyEnum = enum : int32 {
    VALUE = 1;
};
type OtherEnum = enum : int32 {
    VALUE = 5;
};
const MY_CONST OtherEnum = OtherEnum.VALUE;

或者,您也可以選取其他與 const 相符的值 宣告的類型:

library test.good.fi0064;

type MyEnum = enum : int32 {
    VALUE = 1;
};
type OtherEnum = enum : int32 {
    VALUE = 5;
};
const MY_CONST MyEnum = MyEnum.VALUE;

fi-0065:無法將值轉換為預期的類型

常數值必須是適用於該位置的類型

發生這項錯誤最常見的原因是 const 宣告的值 不符合敘述類型:

library test.bad.fi0065a;

const MY_CONST bool = "foo";

如果使用正確定義的 const 值,仍會發生問題 基礎類型的無效位置:

library test.bad.fi0065b;

const ONE uint8 = 0x0001;
const TWO_FIFTY_SIX uint16 = 0x0100;
const TWO_FIFTY_SEVEN uint8 = ONE | TWO_FIFTY_SIX;

此外,FIDL 的「官方」會檢查其引數 比對結構定義這些引數本身都是常數值,因此 可能會出現類似類型不符的情況

library test.bad.fi0065c;

protocol MyProtocol {
    @selector(3840912312901827381273)
    MyMethod();
};

在這些情況下,解決辦法是只使用預期的值 輸入可接受 const 值的位置。上述案例變為 分別為:

library test.good.fi0065a;

const MY_CONST string = "foo";
敬上
library test.good.fi0065b;

const ONE uint8 = 0x0001;
const TWO_FIFTY_SIX uint16 = 0x0100;
const TWO_FIFTY_SEVEN uint16 = ONE | TWO_FIFTY_SIX;
敬上
library test.good.fi0065c;

protocol MyProtocol {
    @selector("MyOldMethod")
    MyMethod();
};

fi-0066:常數溢位類型

常數值不能落在其基礎範圍外 類型:

library test.bad.fi0066;

const NUM uint64 = -42;

變更值以符合類型 範圍:

library test.good.fi0066a;

const NUM uint64 = 42;

或者,變更為 以配合目前溢位的 值:

library test.good.fi0066b;

const NUM int64 = -42;

這個錯誤只與 FIDL 的數字類型有關,且所有 範圍來自 C++ std::numeric_limits 介面,而且如下:

類型 最小值 上限
int8 -128 127
int16 32768 32767
int32 2147483648 2147483647
int64 9223372036854775808 9223372036854775807
uint8 0 255
uint16 0 65536
uint32 0 4294967295
uint64 0 18446744073709551615
float32 -3.40282e+38 3.40282e+38
float64 -1.79769e+308 1.79769e+308

fi-0067:位元成員必須是兩個方的權力

bits 宣告中所有成員的值,不得為 不等於兩個的次方:

library test.bad.fi0067;

type NonPowerOfTwo = bits : uint64 {
    THREE = 3;
};

成員值應一律為兩個次方:

library test.good.fi0067a;

type Fruit = bits : uint64 {
    ORANGE = 1;
    APPLE = 2;
    BANANA = 4;
};

要避免因這項限製而耗費過多心力,最簡單的方法就是只使用位元 使用遮罩,而非十進位數字:

library test.good.fi0067b;

type Life = bits {
    A = 0b000010;
    B = 0b001000;
    C = 0b100000;
};

bits 結構代表「位元陣列」。這份 節省記憶體,表示一系列布林標記序列。由於每個 bits 宣告的成員會對應至其基礎部分 該對應的值就必須清楚識別 指派的無正負號整數。

fi-0068:彈性列舉有保留的未知值

當您定義列舉成員,且其值與 保留的未知值。

彈性列舉可能會保留 FIDL 結構定義無法辨識的值。此外, 彈性列舉一律會保留一個視為不明的值。 根據預設,此值是 該列舉的基本整數類型 (例如 uint8255)。

library test.bad.fi0068;

type Foo = flexible enum : uint8 {
    ZERO = 0;
    ONE = 1;
    MAX = 255;
};

如要修正錯誤,你可以移除成員或變更其值:

library test.good.fi0068a;

type Foo = flexible enum : uint8 {
    ZERO = 0;
    ONE = 1;
};
library test.good.fi0068b;

type Foo = flexible enum : uint8 {
    ZERO = 0;
    ONE = 1;
    MAX = 254;
};

最後,如果您在將 strict 列舉轉換為 flexible 列舉,您可以使用 @unknown 屬性來指定數值 值做為未知的值。請見 @unknown

fi-0069:位元必須使用無正負號的積分子類型

使用帶正負號的數值做為 bits 宣告的基礎類型為 禁止:

library test.bad.fi0069;

type Fruit = bits : int64 {
    ORANGE = 1;
    APPLE = 2;
    BANANA = 4;
};

請改用下列任一種:uint8uint16uint32uint64

library test.good.fi0069;

type Fruit = bits : uint64 {
    ORANGE = 1;
    APPLE = 2;
    BANANA = 4;
};

enum 宣告不同,後者同時允許帶正負號與無正負號整數 (請參閱: fi-0070),bits 宣告則僅允許後者。這是 因為每位 bits 成員都代表 位元陣列 (這就是 fi-0067 的原因 存在)。最明確表示這是一個無正負號整數。 無正負號整數的二進位表示法會直接對應至單一位元 (2 到 索引的次方),而正負號整數中的負數則幾乎 必須根據雙重補給的機制,選擇多個位元 表示法

fi-0070:列舉必須使用積分子類型

使用非積分數字 float32float64 做為基礎類型 禁止使用 enum 宣告:

library test.bad.fi0070;

type MyEnum = enum : float64 {
    ONE_POINT_FIVE = 1.5;
};

請改用下列任一種格式:int8int16int32int64uint8uint16uint32uint64

library test.good.fi0070;

type MyEnum = enum : uint64 {
    ONE = 1;
};

fi-0071:嚴格列舉成員不允許使用未知屬性

strict enum 不得包含使用 @unknown 加註的任何成員 屬性:

library test.bad.fi0071;

type MyEnum = strict enum : int8 {
    @unknown
    UNKNOWN = 0;
    FOO = 1;
    MAX = 127;
};

如要繼續使用 @unknown 屬性,請變更為 flexible enum

library test.good.fi0071a;

type MyEnum = flexible enum : int8 {
    @unknown
    UNKNOWN = 0;
    FOO = 1;
    MAX = 127;
};

否則,請直接移除該屬性,以維持 strict enum

library test.good.fi0071;

type MyEnum = strict enum : int8 {
    UNKNOWN = 0;
    FOO = 1;
    MAX = 127;
};

@unknown 屬性的用途是 順利轉換 strict enum 時,有使用者定義的未知值。 轉換為 flexible enum,且其中已知及處理的值不明 FIDL。在上述範例中,我應該使用另一個 正確用法

fi-0072:只有列舉成員可以攜帶未知的屬性

禁止利用 @unknown 屬性容納多位 enum 成員:

library test.bad.fi0072;

type MyEnum = flexible enum : uint8 {
    @unknown
    UNKNOWN = 0;
    @unknown
    OTHER = 1;
};

只選擇特定網域為「未知」的成員,並加上註解 值:

library test.good.fi0071a;

type MyEnum = flexible enum : int8 {
    @unknown
    UNKNOWN = 0;
    OTHER = 1;
};

@unknown 屬性的用途是 順利轉換 strict enum 時,有使用者定義的未知值。 轉換為 flexible enum,且其中已知及處理的值不明 FIDL:

library test.good.fi0072;

type MyEnum = strict enum : int8 {
    UNKNOWN = 0;
    OTHER = 1;
};
敬上
library test.good.fi0071a;

type MyEnum = flexible enum : int8 {
    @unknown
    UNKNOWN = 0;
    OTHER = 1;
};

fi-0073:撰寫非通訊協定

只有通訊協定可用於 compose 陳述式:

library test.bad.fi0073;

type MyStruct = struct {};

protocol MyProtocol {
    compose MyStruct;
};

請確定您所參照的名稱指向通訊協定:

library test.good.fi0073;

protocol MyOtherProtocol {};

protocol MyProtocol {
    compose MyOtherProtocol;
};

fi-0074:方法酬載所使用的版面配置無效

您只能使用 structtableunion 版面配置來描述方法 酬載:

library test.bad.fi0074;

protocol MyProtocol {
    MyMethod(enum {
        FOO = 1;
    });
};

請改用下列其中一種版面配置:

library test.good.fi0074;

protocol MyProtocol {
    MyMethod(struct {
        foo bool;
    });
};

fi-0075:用於方法酬載的原始無效

基元無法用作方法酬載:

library test.bad.fi0075;

protocol MyProtocol {
    MyMethod(uint32);
};

請改用 structtableunion 版面配置類型:

library test.good.fi0075;

protocol MyProtocol {
    MyMethod(struct {
        wrapped_in_struct uint32;
    });
};

所需的酬載真的只是基本值的情況, 演變時不是問題,只要將值納入 struct 版面配置中, 所產生的酬載,大小會與預期值相同。

fi-0076

fi-0077:互動酬載不得為空白結構體

方法或事件中的酬載不得為空白的結構體:

library test.bad.fi0077a;

protocol Test {
    MyMethod(struct {}) -> (struct {});
};
library test.bad.fi0077b;

protocol Test {
    -> MyEvent(struct {});
};

可表示特定的要求/回應並未 刪除任何資訊,刪除空白的結構,將 () 留在該位置:

library test.good.fi0077a;

protocol Test {
    MyMethod() -> ();
};
library test.good.fi0077b;

protocol Test {
    -> MyEvent();
};

空白結構體無法擴充,且線上線需要 1 位元組。自 FIDL 支援不含有效負載的互動,以這種方式使用空白結構, 大幅提高效率因此不接受。

fi-0078

fi-0079

fi-0080:產生的零序數

這個錯誤不應發生。如果你能做到這點 恭喜,您可能已經破損 SHA-256!

但開玩笑,如果 fidlc 編譯器產生序數值,就會發生這個錯誤 值。由於這個錯誤一定不會發生,因此如果確實顯示,您可能已在 FIDL 編譯器。如果發生這種情況,請向 Issue Tracker 回報問題。

fi-0081:重複的方法序數

這個錯誤通常會在使用 @selector 屬性時發生 使兩個方法名稱產生相同序數

library test.bad.fi0081;

protocol Parser {
    ParseLine();

    // Multiple methods with the same ordinal...
    @selector("ParseLine")
    ParseOneLine();
};

如要修正這個問題,請更新方法名稱或選取器,確保不會衝突。

library test.good.fi0081;

protocol Parser {
    ParseLine();

    @selector("Parse1Line")
    ParseOneLine();
};

如果出現 SHA-256 衝突,也可能會發生這個錯誤,但 基本上為零如果你確信選取器沒有錯, 仍然遇到這個錯誤,您可能在 FIDL 編譯器中發現了錯誤。 如果發生這種情況,請向 Issue Tracker 回報問題。

fi-0082:選取器值無效

如果 @selector 使用的值無效,就會發生這個錯誤。 最常見的原因是錯字。選取器必須是獨立項目 方法名稱或完整方法名稱

library test.bad.fi0082;

protocol Parser {
    @selector("test.old.fi0082.Parser.Parse")
    Parse();
};

如要修正這個問題,請將選取器改成有效的獨立或完全 合格方法名稱:

library test.good.fi0082;

protocol Parser {
    @selector("test.old.fi0082/Parser.Parse")
    Parse();
};

fi-0083:fuchsia.io 必須使用明確的序數

用於自動將 fuchsia.io 序重新命名的 FIDL 編譯器 fuchsia.io1。這項魔法設計是為了讓您更輕鬆地 fuchsia.io2,方法是讓方法的 io2 版本具有「normal」 序數然而,這個系統的反應有點太神奇了,因此現在 即可手動提供 fuchsia.io 的序數。

library fuchsia.io;

protocol SomeProtocol {
    SomeMethod();
};

如要修正這個問題,請使用 fuchsia.io1 手動提供選取器, 程式庫名稱,讓 fuchsia.io 名稱用於 io2。

library fuchsia.io;

protocol SomeProtocol {
    @selector("fuchsia.io1/SomeProtocol.SomeMethod")
    SomeMethod();
};

fi-0084:方法酬載結構中不允許有預設成員

做為付款方式付款的結構體無法指定預設成員:

library test.bad.fi0084;

type MyStruct = struct {
    @allow_deprecated_struct_defaults
    a bool = false;
};

protocol MyProtocol {
    MyMethod(MyStruct) -> (MyStruct);
};

從相關的 struct 宣告中移除預設成員:

library test.good.fi0084;

type MyStruct = struct {
    a bool;
};

protocol MyProtocol {
    MyMethod(MyStruct) -> (MyStruct);
};

fi-0085

fi-0086

fi-0087

fi-0088:服務成員不可為選用

如果您將服務成員標示為 optional,就會發生這個錯誤。標示 服務成員一律是「optional」,因此無法允許服務成員 選用。

library test.bad.fi0088;

protocol Sorter {
    Sort(struct {
        input vector<int32>;
    }) -> (struct {
        output vector<int32>;
    });
};

service SortService {
    quicksort client_end:<Sorter, optional>;
    mergesort client_end:<Sorter, optional>;
};

如要修正這個問題,請移除選用子句:

library test.good.fi0088;

protocol Sorter {
    Sort(struct {
        input vector<int32>;
    }) -> (struct {
        output vector<int32>;
    });
};

service SortService {
    quicksort client_end:Sorter;
    mergesort client_end:Sorter;
};

fi-0089

fi-0090

fi-0091:結構體成員類型無效

當您嘗試為不支援的設定方式設定預設結構值時,就會發生這個錯誤 類型。僅允許數字和布林值類型設定預設結構值。

library test.bad.fi0091;

type Person = struct {
    @allow_deprecated_struct_defaults
    name string:optional = "";
};

如要修正這個問題,請移除預設值:

library test.good.fi0091;

type Person = struct {
    @allow_deprecated_struct_defaults
    name string:optional;
};

fi-0092:表格序數過大

FIDL 資料表序數不得大於 64:

library test.bad.fi0092;

type Table64thField = table {
    1: x int64;
};

type Example = table {
    1: v1 int64;
    2: v2 int64;
    3: v3 int64;
    4: v4 int64;
    5: v5 int64;
    6: v6 int64;
    7: v7 int64;
    8: v8 int64;
    9: v9 int64;
    10: v10 int64;
    11: v11 int64;
    12: v12 int64;
    13: v13 int64;
    14: v14 int64;
    15: v15 int64;
    16: v16 int64;
    17: v17 int64;
    18: v18 int64;
    19: v19 int64;
    20: v20 int64;
    21: v21 int64;
    22: v22 int64;
    23: v23 int64;
    24: v24 int64;
    25: v25 int64;
    26: v26 int64;
    27: v27 int64;
    28: v28 int64;
    29: v29 int64;
    30: v30 int64;
    31: v31 int64;
    32: v32 int64;
    33: v33 int64;
    34: v34 int64;
    35: v35 int64;
    36: v36 int64;
    37: v37 int64;
    38: v38 int64;
    39: v39 int64;
    40: v40 int64;
    41: v41 int64;
    42: v42 int64;
    43: v43 int64;
    44: v44 int64;
    45: v45 int64;
    46: v46 int64;
    47: v47 int64;
    48: v48 int64;
    49: v49 int64;
    50: v50 int64;
    51: v51 int64;
    52: v52 int64;
    53: v53 int64;
    54: v54 int64;
    55: v55 int64;
    56: v56 int64;
    57: v57 int64;
    58: v58 int64;
    59: v59 int64;
    60: v60 int64;
    61: v61 int64;
    62: v62 int64;
    63: v63 int64;
    // The 64th field of a table must be another table, otherwise it will cause
    // fi-0093: Max Ordinal In Table Must Be Table.
    64: v64 Table64thField;
    65: v65 int64;
};

為了支援超過 64 種一般的成長,FIDL 需要 做為另一個資料表凡是超過 64 個表格欄位,都必須放在巢狀結構中 表格。

library test.good.fi0092;

type Table64thField = table {
    1: x int64;
    // Any fields beyond 64 of table Example must be move to the nested table in
    // ordinal 64 of Example.
    2: v65 int64;
};

type Example = table {
    1: v1 int64;
    2: v2 int64;
    3: v3 int64;
    4: v4 int64;
    5: v5 int64;
    6: v6 int64;
    7: v7 int64;
    8: v8 int64;
    9: v9 int64;
    10: v10 int64;
    11: v11 int64;
    12: v12 int64;
    13: v13 int64;
    14: v14 int64;
    15: v15 int64;
    16: v16 int64;
    17: v17 int64;
    18: v18 int64;
    19: v19 int64;
    20: v20 int64;
    21: v21 int64;
    22: v22 int64;
    23: v23 int64;
    24: v24 int64;
    25: v25 int64;
    26: v26 int64;
    27: v27 int64;
    28: v28 int64;
    29: v29 int64;
    30: v30 int64;
    31: v31 int64;
    32: v32 int64;
    33: v33 int64;
    34: v34 int64;
    35: v35 int64;
    36: v36 int64;
    37: v37 int64;
    38: v38 int64;
    39: v39 int64;
    40: v40 int64;
    41: v41 int64;
    42: v42 int64;
    43: v43 int64;
    44: v44 int64;
    45: v45 int64;
    46: v46 int64;
    47: v47 int64;
    48: v48 int64;
    49: v49 int64;
    50: v50 int64;
    51: v51 int64;
    52: v52 int64;
    53: v53 int64;
    54: v54 int64;
    55: v55 int64;
    56: v56 int64;
    57: v57 int64;
    58: v58 int64;
    59: v59 int64;
    60: v60 int64;
    61: v61 int64;
    62: v62 int64;
    63: v63 int64;
    64: v64 Table64thField;
};

資料表中的每個欄位都會產生 FIDL 信封的負擔,以便 選填欄位如此一來,資料表的每個欄位都會顯示 並支援增減資料表來改良資料表,但 比結構體耗用更多記憶體負擔

一般來說,您可以藉由避免 精細的小型欄位您可以改將一些元素分組 您預期需要同時在結構體中新增或移除 這些欄位可做為資料表欄位使用這麼做可以減輕負擔,並避免 因此往往難以追求變革。

這成為 RFC-0132: FIDL 資料表大小的錯誤 上限, 目的是避免使用者不小心將 大型資料表。在結構定義中,這所需的額外費用並不明顯,尤其是有 只有幾個欄位 (和通常較大),或有許多欄位 一次只能使用幾個範本

fi-0093:表格的序數上限必須為表格

FIDL 資料表中的第 64 個成員類型必須是資料表:

library test.bad.fi0093;

type Example = table {
    1: v1 int64;
    2: v2 int64;
    3: v3 int64;
    4: v4 int64;
    5: v5 int64;
    6: v6 int64;
    7: v7 int64;
    8: v8 int64;
    9: v9 int64;
    10: v10 int64;
    11: v11 int64;
    12: v12 int64;
    13: v13 int64;
    14: v14 int64;
    15: v15 int64;
    16: v16 int64;
    17: v17 int64;
    18: v18 int64;
    19: v19 int64;
    20: v20 int64;
    21: v21 int64;
    22: v22 int64;
    23: v23 int64;
    24: v24 int64;
    25: v25 int64;
    26: v26 int64;
    27: v27 int64;
    28: v28 int64;
    29: v29 int64;
    30: v30 int64;
    31: v31 int64;
    32: v32 int64;
    33: v33 int64;
    34: v34 int64;
    35: v35 int64;
    36: v36 int64;
    37: v37 int64;
    38: v38 int64;
    39: v39 int64;
    40: v40 int64;
    41: v41 int64;
    42: v42 int64;
    43: v43 int64;
    44: v44 int64;
    45: v45 int64;
    46: v46 int64;
    47: v47 int64;
    48: v48 int64;
    49: v49 int64;
    50: v50 int64;
    51: v51 int64;
    52: v52 int64;
    53: v53 int64;
    54: v54 int64;
    55: v55 int64;
    56: v56 int64;
    57: v57 int64;
    58: v58 int64;
    59: v59 int64;
    60: v60 int64;
    61: v61 int64;
    62: v62 int64;
    63: v63 int64;
    64: v64 int64;
};

如果發現自己需要新增第 64 位成員,應建立個別 表格來保留 64 以上成員,並改為將該成員加入表格中:

library test.good.fi0093;

type Table64thField = table {
    1: x int64;
};

type Example = table {
    1: v1 int64;
    2: v2 int64;
    3: v3 int64;
    4: v4 int64;
    5: v5 int64;
    6: v6 int64;
    7: v7 int64;
    8: v8 int64;
    9: v9 int64;
    10: v10 int64;
    11: v11 int64;
    12: v12 int64;
    13: v13 int64;
    14: v14 int64;
    15: v15 int64;
    16: v16 int64;
    17: v17 int64;
    18: v18 int64;
    19: v19 int64;
    20: v20 int64;
    21: v21 int64;
    22: v22 int64;
    23: v23 int64;
    24: v24 int64;
    25: v25 int64;
    26: v26 int64;
    27: v27 int64;
    28: v28 int64;
    29: v29 int64;
    30: v30 int64;
    31: v31 int64;
    32: v32 int64;
    33: v33 int64;
    34: v34 int64;
    35: v35 int64;
    36: v36 int64;
    37: v37 int64;
    38: v38 int64;
    39: v39 int64;
    40: v40 int64;
    41: v41 int64;
    42: v42 int64;
    43: v43 int64;
    44: v44 int64;
    45: v45 int64;
    46: v46 int64;
    47: v47 int64;
    48: v48 int64;
    49: v49 int64;
    50: v50 int64;
    51: v51 int64;
    52: v52 int64;
    53: v53 int64;
    54: v54 int64;
    55: v55 int64;
    56: v56 int64;
    57: v57 int64;
    58: v58 int64;
    59: v59 int64;
    60: v60 int64;
    61: v61 int64;
    62: v62 int64;
    63: v63 int64;
    64: v64 Table64thField;
};

我們完整詳述這個要求背後的推理和動機 RFC-0132:FIDL 資料表大小限制。簡單來說,FIDL 資料表必須 允許的欄位數量較為有限,否則 若是一次只使用幾個欄位的資料表,編碼形式就會有 空間非常大 (每省略成員 16 個位元組)。

如要為使用者提供表格中超過 64 個欄位的解決方法,FIDL 強制為「接續表」保留最後一個序數包含 就能輸入這些欄位在這個位置使用任何其他類型會導致表格 無法實現目標

fi-0094:重複的資料表成員一般

table 宣告中,成員使用的常態無法重複:

library test.bad.fi0094;

type MyTable = table {
    1: my_field string;
    1: my_other_field uint32;
};

視需要遞增序數,以確保宣告的獨特性 所有成員的序數:

library test.good.fi0094a;

type MyTable = table {
    1: my_field string;
    2: my_other_field uint32;
};

或者,您也可以移除其中一位名稱重複的成員:

library test.good.fi0094b;

type MyTable = table {
    1: my_field string;
};

序數是用來識別電線欄位。如果兩名成員共用一個 單數式,就無法有可靠的方式 判斷該參照哪個欄位 解碼器會解碼 FIDL 訊息

fi-0095

fi-0096

fi-0097:重複的聯集成員一般

union 宣告中,成員使用的常態無法重複:

library test.bad.fi0097;

type MyUnion = strict union {
    1: my_variant string;
    1: my_other_variant int32;
};

視需要遞增序數,以確保宣告的獨特性 所有成員的序數:

library test.good.fi0097a;

type MyUnion = strict union {
    1: my_variant string;
    2: my_other_variant int32;
};

或者,您也可以移除其中一位名稱重複的成員:

library test.good.fi0097b;

type MyUnion = strict union {
    1: my_variant string;
};

序數是用於識別電線的變體。如果兩名成員共用一個 單數,沒有可靠的方式可以判斷系統參照哪個變化版本 標示出 FIDL 訊息的情況

fi-0098

fi-0099

fi-0100

fi-0101:無法解析的大小限制

套用至 vectorstring 類型定義的大小限制必須是 uint32 類型的有效值:

library test.bad.fi0101a;

alias MyBoundedOptionalVector = vector<uint32>:<"255", optional>;
library test.bad.fi0101b;

alias MyBoundedOptionalVector = vector<uint32>:<uint8, optional>;

確認情況如下:

library test.good.fi0101;

alias MyBoundedOptionalVector = vector<uint32>:<255, optional>;

fi-0102:會員價值無法解析

bitsenum 宣告的成員必須是 指定的子類型:

library test.bad.fi0102;

type Fruit = bits : uint64 {
    ORANGE = 1;
    APPLE = 2;
    BANANA = -4;
};

確保所有值都與宣告的基礎類型相符:

library test.good.fi0102;

type Fruit = bits : uint64 {
    ORANGE = 1;
    APPLE = 2;
    BANANA = 4;
};

fi-0103:無法解析結構體預設值

struct 宣告成員的預設值必須與 個別成員的指定類型:

library test.bad.fi0103;

type MyEnum = enum : int32 {
    A = 1;
};

type MyStruct = struct {
    @allow_deprecated_struct_defaults
    field MyEnum = 1;
};

確認該值與宣告的類型相符:

library test.good.fi0103;

type MyEnum = enum : int32 {
    A = 1;
};

type MyStruct = struct {
    @allow_deprecated_struct_defaults
    field MyEnum = MyEnum.A;
};

fi-0104:無法解析的屬性引數

官方的引數值 根據預期屬性結構定義,FIDL 屬性無效 引數:

library test.bad.fi0104;

type MyStruct = struct {
    my_field @generated_name(true) struct {};
};

確認做為屬性引數使用的值類型正確無誤:

library test.good.fi0104;

type MyStruct = struct {
    my_field @generated_name("my_inner_type") struct {};
};

fi-0105

fi-0106

fi-0107:成員值重複

bitsenum 宣告中都不得包含相同值的成員:

library test.bad.fi0107;

type Fruit = flexible enum {
    ORANGE = 1;
    APPLE = 1;
};

將成員值變更為不得重複:

library test.good.fi0107a;

type Fruit = flexible enum {
    ORANGE = 1;
    APPLE = 2;
};

或者,您也可以移除其中一名重複的成員:

library test.good.fi0107b;

type Fruit = flexible enum {
    ORANGE = 1;
};

fi-0108

fi-0109

fi-0110:包含類型的資源必須標示為資源

包含帳號代碼的類型 (直接或透過遞移性) 加入另一個包含的處理常式類型,如果沒有該類型,則無法宣告 指定類型為 resource

library test.bad.fi0110;

using zx;

type Foo = struct {
    handle zx.Handle;
};

有兩種可能的解決方案。其一是針對 使用資源修飾符進行宣告:

library test.good.fi0110a;

using zx;

type Foo = resource struct {
    handle zx.Handle;
};

或者,您也可以選擇徹底移除包含 resource 的類型, 因此,無需在自有宣告中使用修飾符:

library test.good.fi0110b;

type Foo = struct {
    value uint32;
};

新增 resource 修飾符和其動機的推理和動機 「傳染性」如要瞭解這項錯誤強制執行的使用模式的性質,請查看 。RFC-0057:預設 no 帳號

fi-0111:內嵌大小超過上限

不允許內嵌大小為 64 KiB 以上的 FIDL 類型:

library test.bad.fi0111;

type MyStruct = struct {
    numbers array<uint8, 65536>;
};

而是確定該類型的內嵌大小小於 64 KiB。在本例中 就可以調整陣列繫結:

library test.good.fi0111;

type MyStruct = struct {
    numbers array<uint8, 65535>;
};

這項限制是基於效能考量的考量。也就是編碼器和解碼器 可以假設大小和偏移量符合無正負號的 16 位元整數。

除非您使用大型陣列或 具備深度巢狀結構的結構體大多數的 FIDL 結構 (例如字串、向量、資料表、 和聯集) 會使用離線儲存空間,不會計入 個別內嵌大小

fi-0112:服務成員並非 client_end

服務成員只能做為用戶端結束,不得加入任何其他類型:

library test.bad.fi0112;

protocol Calculator {};

service Service {
    calculator server_end:Calculator;
};

如要修正錯誤,請確認成員的格式是某些通訊協定 Pclient_end:P 格式:

library test.good.fi0112;

protocol Calculator {};

service Service {
    calculator client_end:Calculator;
};

服務是通訊協定執行個體的集合,而非一般用途資料 所以對於允許任意型別並不合理。

fi-0113:服務中的傳輸方式不符

FIDL 服務禁止包含使用不同傳輸的通訊協定:

library test.bad.fi0113;

protocol ChannelProtocol {};

@transport("Driver")
protocol DriverProtocol {};

service SomeService {
    a client_end:ChannelProtocol;
    b client_end:DriverProtocol;
};

請改為針對各種交通運輸使用不同服務:

library test.good.fi0113;

protocol ChannelProtocol {};

@transport("Driver")
protocol DriverProtocol {};

service ChannelService {
    protocol client_end:ChannelProtocol;
};

service DriverService {
    protocol client_end:DriverProtocol;
};

請注意,服務是 FIDL 中尚未完成的功能。其原本是 於 RFC-0041 中設計:支援統合 Serviceas,以及 裝置。 詳情請參閱 https://fxbug.dev/42160684

fi-0114:Composed 通訊協定太開放

通訊協定無法組合更開放的其他通訊協定:

library test.bad.fi0114;

open protocol Composed {};

ajar protocol Composing {
    compose Composed;
};

如要修正此問題,請提高撰寫通訊協定的開放程度,即 從 closed 改為 ajar 或從 ajar 變更為 open

library test.good.fi0114a;

open protocol Composed {};

open protocol Composing {
    compose Composed;
};

或者,您也可以降低組成通訊協定的開放程度,即 從 openajar 或從 ajarclosed

library test.good.fi0114b;

ajar protocol Composed {};

ajar protocol Composing {
    compose Composed;
};

之所以有這項規則,是因為通訊協定的開放性會限制 可以包含的方法。例如,ajar 通訊協定不得含有 彈性的雙向方法,但開放式通訊協定可以執行,因此對 Ajar 而言並不安全 都屬於開放式通訊協定

請參閱 RFC-0138:處理不明問題 互動 ,進一步瞭解通訊協定修飾符。

fi-0115:彈性的雙向方法須使用開放通訊協定

封閉式和 ajar 通訊協定不得包含彈性的雙向方法:

library test.bad.fi0115;

ajar protocol Protocol {
    flexible Method() -> ();
};

請改為標示雙向方法 strict,而非 flexible

library test.good.fi0115a;

ajar protocol Protocol {
    strict Method() -> ();
};

或者,您也可以標記通訊協定 open,而不是 closedajar

library test.good.fi0115b;

open protocol Protocol {
    flexible Method() -> ();
};

之所以發生這個錯誤,是因為 closed (或 ajar) 修飾符的用途: 確定方法不含任何彈性 (雙向) 方法。第一次 建立通訊協定後,請審慎考慮 關閉、關閉、Ajar 或開放式,按照需要的可進性屬性進行設計。

請參閱 RFC-0138:處理不明問題 互動 ,進一步瞭解通訊協定修飾符。

fi-0116:彈性的單向方法,需要 ajar 或開放式通訊協定

封閉式通訊協定不允許包含彈性的單向方法:

library test.bad.fi0116;

closed protocol Protocol {
    flexible Method();
};

請改為標記單向方法 strict,而非 flexible

library test.good.fi0116;

closed protocol Protocol {
    strict Method();
};

您也可以標示通訊協定 ajaropen,而不是 closed

library test.good.fi0116;

ajar protocol Protocol {
    flexible Method();
};

之所以發生這個錯誤,是因為 closed 修飾符的用途是確保 方法不含任何彈性方法,首次建立通訊協定時 請務必仔細考慮該產品是關閉、罐子或打開 視需求彈性調整資源配置

請參閱 RFC-0138:處理不明問題 互動 ,進一步瞭解通訊協定修飾符。

fi-0117:使用不相容的傳輸帳號

通訊協定只能指與其傳輸相容的帳號代碼。 例如,Zircon 管道傳輸上的通訊協定不得參照 Fuchsia 驅動程式架構可處理:

library test.bad.fi0117;

using fdf;

protocol Protocol {
    Method(resource struct {
        h fdf.handle;
    });
};

請改用與通訊協定傳輸相容的帳號代碼:

library test.good.fi0117a;

using zx;

protocol Protocol {
    Method(resource struct {
        h zx.Handle;
    });
};

或者,變更通訊協定的傳輸方式,使其符合控制代碼:

library test.good.fi0117b;

using fdf;

@transport("Driver")
protocol Protocol {
    Method(resource struct {
        h fdf.handle;
    });
};

fi-0118:使用不相容的傳輸端點

通訊協定只能指涉傳輸的結尾 (client_endserver_end) 支援相同的通訊協定例如使用 Syscall 的通訊協定 傳輸功能不能使用驅動程式傳輸參照通訊協定的用戶端端:

library test.bad.fi0118;

@transport("Driver")
protocol DriverProtocol {};

@transport("Syscall")
protocol P {
    M(resource struct {
        s client_end:DriverProtocol;
    });
};

如要修正錯誤,請移除傳輸端成員:

library test.good.fi0118;

@transport("Driver")
protocol DriverProtocol {};

@transport("Syscall")
protocol Protocol {
    M();
};

fi-0119

fi-0120:屬性位置無效

部分官方屬性僅 是否允許特定位置例如,@selector 屬性 用於:

library test.bad.fi0120a;

@selector("Nonsense")
type MyUnion = union {
    1: hello uint8;
};

如要修正錯誤,請移除這項屬性:

library test.good.fi0120a;

type MyUnion = union {
    1: hello uint8;
};

您打算以特定方式使用屬性時,也可能會發生這個錯誤 但放在錯誤的位置舉例來說, @generated_name 屬性無法直接位於成員上:

library test.bad.fi0120a;

@selector("Nonsense")
type MyUnion = union {
    1: hello uint8;
};

而是放在成員的匿名版面配置之前:

library test.good.fi0120a;

type MyUnion = union {
    1: hello uint8;
};

fi-0121:屬性已淘汰

部分官方屬性為 已淘汰,且應不再使用:

library test.bad.fi0121;

@example_deprecated_attribute
type MyStruct = struct {};

修正方式取決於該屬性遭到淘汰的原因。舉例來說,錯誤訊息可能指出需改用其他屬性。在此情況下,我們可以移除屬性:

library test.good.fi0121;

type MyStruct = struct {};

fi-0122:屬性名稱重複

元素中不能有多個名稱相同的屬性:

library test.bad.fi0122;

@custom_attribute("first")
@custom_attribute("second")
type Foo = struct {};

每項屬性只需指定一次即可:

library test.good.fi0122;

@custom_attribute("first")
type Foo = struct {};

fi-0123:標準屬性名稱重複

元素中不得含有多個有相同標準名稱的屬性:

library test.bad.fi0123;

@custom_attribute("first")
@CustomAttribute("second")
type Foo = struct {};

雖然 custom_attributeCustomAttribute 的外觀不同 兩者皆以「標準」名稱 custom_attribute 表示。您就能取得 正規名稱,方法是將原始名稱轉換為 snake_case

如要修正錯誤,請為每項屬性命名,且名稱之間不得重複 以及標準化

library test.good.fi0123;

@custom_attribute("first")
@AnotherCustomAttribute("first")
type Foo = struct {};

如要進一步瞭解 FIDL 要求宣告權限的原因,請參閱 fi-0035 且沒有不重複的正規名稱

fi-0124:自訂屬性引數必須為字串或布林值

使用者定義 FIDL 屬性上的引數僅能使用字串或 布林值類型:

library test.bad.fi0124;

@my_custom_attr(foo=1, bar=2.3)
type MyStruct = struct {};
敬上
library test.good.fi0124;

@my_custom_attr(foo=true, bar="baz")
type MyStruct = struct {};

不同於官方屬性,使用者定義的結構定義 編譯器不知道這些屬性。因此不可能 導致任何指定數字引數的型別。為 2int8」、「uint64」或「float32」?編譯器無法知道。

如要解決這個問題,可能的做法是實作第一級 numeric 類型 (適用於這類模稜兩可的情況)。但由於 自訂屬性引數是目前已知的用途 還沒有優先處理的功能

fi-0125:屬性引數不得命名

使用官方屬性時 需要使用單一引數,您就無法為該引數命名:

library test.bad.fi0125;

@transport(value="Driver")
protocol Foo {};

請改為傳送引數,而不為其命名:

library test.good.fi0125;

@discoverable(name="example.Bar")
protocol Foo {};

FIDL 會強制執行此要求,讓屬性更簡潔一致。在 系統推論引數名稱是 value (顯示在 JSON IR),因為這是屬性接收的唯一引數。

fi-0126:屬性引數必須命名

使用官方屬性時 需要多個引數,則無法傳遞未命名的引數:

@available(1)
library test.bad.fi0126;

請改為指定引數的名稱:

@available(added=1)
library test.good.fi0126;

發生這個錯誤,因為無法得知您想要的引數 在屬性接受多個引數時設定。

fi-0127:缺少必要屬性引數

使用官方屬性時 您不可省略該引數:

library test.bad.fi0127;

@has_required_arg
type Foo = struct {};

請改為提供必要引數:

library test.good.fi0127;

@has_required_arg(required="something")
type Foo = struct {};

fi-0128:缺少單一屬性引數

使用官方屬性時 需要一個引數,您就無法省略該引數:

library test.bad.fi0128;

@transport
protocol Protocol {};

而是改為提供引數:

library test.good.fi0128;

@transport("Driver")
protocol Protocol {};

fi-0129:不明的屬性引數

使用官方屬性時 您無法提供結構定義中沒有的引數:

@available(added=1, discontinued=2)
library test.bad.fi0129;

如果您要傳遞不同的引數但名稱有誤,請將其變更為正確的名稱:

@available(added=1, deprecated=2)
library test.good.fi0129a;

您也可以移除引數:

@available(added=1)
library test.good.fi0129b;

發生這個錯誤,是因為系統依據結構定義驗證官方屬性。如果 FIDL 允許使用任意引數,因此不會有任何作用,而且可能會造成 並遮蓋錯字

fi-0130:屬性引數重複

一個屬性不能有兩個名稱相同的引數:

library test.bad.fi0130;

@custom_attribute(custom_arg=true, custom_arg=true)
type Foo = struct {};

請改為只提供一個具有該名稱的引數:

library test.good.fi0130;

@custom_attribute(custom_arg=true)
type Foo = struct {};

fi-0131:重複的標準屬性引數

一個屬性不能有兩個使用相同正規名稱的引數:

library test.bad.fi0131;

@custom_attribute(custom_arg=true, CustomArg=true)
type Foo = struct {};

雖然 custom_argCustomArg 的外觀不同,但兩者 由「標準」名稱 custom_arg 表示。這樣您就能取得正規名稱 做法是將原始名稱轉換為 snake_case

如要修正錯誤,請為每個引數提供一個不重複的名稱 標準化:

library test.good.fi0131a;

@custom_attribute(custom_arg=true, AnotherCustomArg=true)
type Foo = struct {};

您也可以移除其中一個引數:

library test.good.fi0131b;

@custom_attribute(custom_arg=true)
type Foo = struct {};

如要進一步瞭解 FIDL 要求宣告權限的原因,請參閱 fi-0035 且沒有不重複的正規名稱

fi-0132:非預期的屬性引數

使用官方屬性時 沒有引數,您就無法提供引數:

library test.bad.fi0132;

type Foo = flexible enum : uint8 {
    @unknown("hello")
    BAR = 1;
};

而是應該移除引數:

library test.good.fi0132;

type Foo = flexible enum : uint8 {
    @unknown
    BAR = 1;
};

fi-0133:屬性引數須為常值

特定的官方屬性 不允許參照常數的引數:

library test.bad.fi0133;

const NAME string = "MyTable";

type Foo = struct {
    bar @generated_name(NAME) table {};
};

請改為傳送常值做為引數:

library test.good.fi0133;

type Foo = struct {
    bar @generated_name("MyTable") table {};
};

這些屬性需要常值引數,因為其值會影響 編譯。支援非常值的論述並不容易 有時則會造成牴觸

fi-0134

fi-0135:可搜尋名稱無效

如果 @discoverable 屬性使用的名稱無效,就會發生這個錯誤。 @discoverable 屬性應為程式庫名稱,後面接有 . 和 通訊協定名稱

library test.bad.fi0135;

@discoverable(name="test.bad.fi0135/Parser")
protocol Parser {
    Tokenize() -> (struct {
        tokens vector<string>;
    });
};

如要修正這項錯誤,請使用有效的可搜尋名稱:

library test.good.fi0135;

@discoverable(name="test.good.fi0135.Parser")
protocol Parser {
    Tokenize() -> (struct {
        tokens vector<string>;
    });
};

fi-0136

fi-0137

fi-0138

fi-0139

fi-0140

fi-0141:無效的錯誤類型

方法回應酬載上的 error 類型必須是 int32uint32enum 數量:

library test.bad.fi0141;

protocol MyProtocol {
    MyMethod() -> () error float32;
};

如要修正這項錯誤,請將 error 類型變更為其中一個有效選項:

library test.good.fi0141;

protocol MyProtocol {
    MyMethod() -> () error int32;
};

詳情請參閱 RFC-0060:錯誤處理

fi-0142:通訊協定傳輸類型無效

protocol 宣告中的 @transport(...) 屬性不得指定 無效的傳輸方式:

library test.bad.fi0142;

@transport("Invalid")
protocol MyProtocol {
    MyMethod();
};

請改用系統支援的其中一種傳輸方式:

library test.good.fi0142;

@transport("Syscall")
protocol MyProtocol {
    MyMethod();
};

支援的傳輸元件仍在開發階段,請參閱 FIDL 屬性」一文,掌握最新資訊。

fi-0143

fi-0144

fi-0145:屬性錯字

屬性名稱的拼寫與 FIDL 官方機構其中一個官方名稱過於相似 屬性會導致編譯器警告:

library test.bad.fi0145;

@duc("should be doc")
protocol Example {
    Method();
};

在上述範例中,@duc 屬性的拼寫方式與 官方 FIDL 屬性 @doc。在這類情況中,屬性的命名方式 而不是不小心打錯官方 FIDL 屬性 應加以修改,使其更加獨特:

library test.good.fi0145;

@duck("quack")
protocol Example {
    Method();
};

除了拼字檢查以外,這項警告的目的在於不建議 與官方 FIDL 屬性太過相似的名稱。

錯字偵測演算法的運作方式是計算 屬性名稱與每個官方 FIDL 的距離 屬性。名稱太過相似,定義為編輯內容太小 並觸發錯字偵測器

fi-0146:無效的生成名稱

如果使用 @generated_name 屬性指定無效的屬性,就會發生這個錯誤 名稱。產生的名稱必須符合所有 FIDL ID 的規則。

library test.bad.fi0146;

type Device = table {
    1: kind flexible enum {
        DESKTOP = 1;
        PHONE = 2;
    };
};

type Input = table {
    1: kind @generated_name("_kind") flexible enum {
        KEYBOARD = 1;
        MOUSE = 2;
    };
};

如要修正這個問題,請將 @generated_name 值變更為有效的 ID。

library test.good.fi0146;

type Device = table {
    1: kind flexible enum {
        DESKTOP = 1;
        PHONE = 2;
    };
};

type Input = table {
    1: kind @generated_name("input_kind") flexible enum {
        KEYBOARD = 1;
        MOUSE = 2;
    };
};

fi-0147:@available 個缺少引數

這個錯誤會在您使用 @available 屬性且未提供 必要的引數@available 需要至少一個addeddeprecatedremoved

@available(added=1)
library test.bad.fi0147;

@available
type Foo = struct {};

如要修正這個問題,請新增下列其中一個必要引數:

@available(added=1)
library test.good.fi0147;

@available(added=2)
type Foo = struct {};

詳情請參閱 FIDL 版本管理

fi-0148:淘汰通知

@available 使用 note 引數時,就會發生這個錯誤 ,而且未加入 deprecated 引數。note 僅支援 以及淘汰的那一環

@available(added=1, note="My note")
library test.bad.fi0148;

如要修正這個錯誤,請移除附註:

@available(added=1)
library test.good.fi0148a;

或是新增必要的 deprecated 通知:

@available(added=1, deprecated=2, note="Removed in 2; use X instead.")
library test.good.fi0148b;

詳情請參閱 FIDL 版本管理

fi-0149:平台不在程式庫中

嘗試使用 @available 屬性的 platform 時,就會發生這個錯誤 引數。platform 引數僅在 library 層級有效。

@available(added=1)
library test.bad.fi0149;

@available(platform="foo")
type Person = struct {
    name string;
};

如要修正這個問題,請將 platform 引數移至程式庫 @available 屬性:

@available(added=1, platform="foo")
library test.good.fi0149a;

type Person = struct {
    name string;
};

或是完全移除 platform 引數:

@available(added=1)
library test.good.fi0149b;

type Person = struct {
    name string;
};

fi-0150:新增缺少的程式庫供應情形

在沒有在程式庫中新增 @available 屬性至程式庫時,就會發生這個錯誤 並傳回 added 引數必須為 library 指定 added 引數 @available 屬性。

@available(removed=2)
library test.bad.fi0150a;
@available(platform="foo")
library test.bad.fi0150b;

如要修正這個問題,請將 added 引數新增至程式庫的 @available 屬性:

@available(added=1, removed=2)
library test.good.fi0150a;
@available(added=1, platform="foo")
library test.good.fi0150b;

fi-0151:缺少程式庫可用性

如果在非 library 中新增 @available 屬性,就會發生這個錯誤 宣告,但 library 宣告中沒有 @available 屬性。

library test.bad.fi0151;

@available(added=1)
type Person = struct {
    name string;
};

如要修正這個錯誤,請在 library 宣告中加入 @available 屬性:

@available(added=1)
library test.good.fi0151a;

@available(added=1)
type Person = struct {
    name string;
};

或是從非 library 宣告中移除 @available 屬性:

library test.good.fi0151b;

type Person = struct {
    name string;
};

fi-0152:平台無效

如果 platform 引數的 platform 引數使用無效字元,就會發生這個錯誤。 @available 屬性。platform 引數必須是有效的 FIDL 程式庫 ID

@available(added=1, platform="Spaces are not allowed")
library test.bad.fi0152;

如要修正這個錯誤,請移除不允許的字元:

@available(added=1, platform="foo")
library test.good.fi0152;

fi-0153:版本無效

如果 addedremoved 使用的版本無效,就會發生這個錯誤 @available 屬性的引數。addedremoved 引數必須 介於 1 和 2^63-1 之間的正整數,或特殊常數 HEAD

@available(added=0)
library test.bad.fi0153;

如要解決這個問題,請將版本變更為有效值:

@available(added=1)
library test.good.fi0153;

fi-0154:供應順序無效

如果 addeddeprecated@available 屬性的 remove 引數。您必須使用下列限制 尊重:

  • added必須小於或等於 deprecated
  • deprecated必須小於 removed
  • added必須小於 removed
,瞭解如何調查及移除這項存取權。
@available(added=2, removed=2)
library test.bad.fi0154a;
@available(added=2, deprecated=3, removed=3)
library test.bad.fi0154b;

如要解決這個問題,請將 addeddeprecatedremoved 引數更新為 所需排序:

@available(added=1, removed=2)
library test.good.fi0154a;
@available(added=2, deprecated=2, removed=3)
library test.good.fi0154b;

fi-0155:供應情形與父項衝突

當你將 @availability 屬性新增至非 library 時,就會發生這個錯誤 宣告與 library 的宣告發生衝突。

@available(added=2, deprecated=3, removed=4)
library test.bad.fi0155a;

@available(added=1)
type Person = struct {
    name string;
};
@available(added=2, deprecated=3, removed=4)
library test.bad.fi0155b;

@available(added=4)
type Person = struct {
    name string;
};

如要修正這個錯誤,請將 @availability 屬性更新為必填屬性 限制:

@available(added=2, deprecated=3, removed=4)
library test.good.fi0155;

@available(added=2)
type Person = struct {
    name string;
};

fi-0156:不能為選用

當您嘗試將類型標示為「選用」無法選取時,就會發生這個錯誤 選用。

library test.bad.fi0156;

type Person = struct {
    name string;
    age int16:optional;
};

如要修正這個錯誤,請移除選用限制:

library test.good.fi0156;

type Person = struct {
    name string;
    age int16;
};

只有能選用且不會變更電線形狀的 FIDL 類型才是 可以使用 optional 限制。詳情請參閱 非必要指南或下方的可展開內容。

FIDL 方案:選填性

某些 FIDL 類型可設為選用,不要變更 但該訊息包含訊息,且加上 :optional 限制。 此外,table 版面配置一律為選用性質,struct 版面配置則一律不會 不過,無論內部 IP 位址為何 DNS 名稱始終會指向特定的執行個體如要將 struct 設為選用,其必須納入 box<T> 中,因此 而不是包含訊息的線形

基礎類型 選用版本 選用性是否會改變電線配置?
struct {...} box<struct {...}>
table {...} table {...}
union {...} union {...}:optional 不可以
vector<T> vector<T>:optional 不可以
string string:optional 不可以
zx.Handle zx.Handle:optional 不可以
client_end:P client_end:<P, optional> 不可以
server_end:P server_end:<P, optional>

所有其他類型 (bitsenumarray<T, N> 和原始類型) 都無法 並可視需要設為

在這個變化版本中,我們允許鍵/值儲存庫將其他鍵/值儲存庫視為 成員。簡單來說,我們將這層變成樹做法是替換掉原始的 value 的定義,以及使用雙成員 union 的定義:一種變體 使用與之前相同的 vector<byte> 類型儲存分葉節點,而另一個 會以其他巢狀儲存庫的形式儲存分支版本節點。

原因

這裡說明瞭「選用」的幾個用法,因此我們可以宣告 不一定存在。FIDL 有三種選用方式:

  • 一律儲存的類型 中斷狀態 還可直接在線路上說明「缺口」透過 空值 。啟用中 這些類型的選擇性設定不會影響郵件的傳播形狀 ,只會變更特定項目中有效的值 類型。unionvector<T>client_endserver_endzx.Handle 透過新增 :optional 限制,即可選擇所有型別。 將 value union 設為選用值,我們就能 「null」項目,格式為缺少 value。這表示 bytes 沒有任何內容 和缺少/空白的 store 屬性都是無效值。
  • 與前述類型不同,struct 版面配置沒有額外空間, 可以儲存空值的標題因此,這必須包裝在 信封,變更郵件包含的郵件的傳輸形狀 。為確保此線路修改效果清晰易讀,Item struct 類型必須納入 box<T> 類型範本中。
  • 最後,table 版面配置一律為選用項目。缺失的 table 只是單一個 而不設定任何成員

樹狀結構是自然的自我參照資料結構:樹狀結構中的任何節點 包含純資料 (在本範例中為字串) 或含有更多資料的子樹狀結構 節點。這需要遞迴:Item 的定義現在轉為遞移性 只靠它!在 FIDL 中表示遞迴類型可能有點難度, 尤其是因為支援服務目前稍微 受限。我們可以支援這些類型 由自我參照建立的循環中至少一種選用類型。適用對象 例如,這裡會將 items struct 成員定義為 box<Item> 進而破壞納入循環。

這些變更也大量使用匿名類型或 宣告只會內嵌在其使用點上,而不是命名。 自己的頂層 type 宣告。系統預設會以匿名方式 所產生語言繫結中的型別擷取自其本機環境。適用對象 執行個體,新導入的 flexible union 會使用其本身的成員 名稱為 Value,新引入的 struct 會變成 Store,依此類推。 這種經驗法則有時會導致衝突,因此 FIDL 會提供逸出字元 方法是允許作者手動覆寫系統產生的匿名類型 name。這項操作是透過 @generated_name 屬性來完成 並變更後端產生的名稱我們可以使用這個方法 Store 類型已重新命名為 NestedStore,以免與 使用相同的名稱的 protocol 宣告。

實作

FIDL、CML 和領域介面定義的修改如下:

FIDL

// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library examples.keyvaluestore.supporttrees;

/// An item in the store. The key must match the regex `^[A-z][A-z0-9_\.\/]{2,62}[A-z0-9]$`. That
/// is, it must start with a letter, end with a letter or number, contain only letters, numbers,
/// periods, and slashes, and be between 4 and 64 characters long.
type Item = struct {
    key string:128;
    value strict union {
        // Keep the original `bytes` as one of the options in the new union. All leaf nodes in the
        // tree must be `bytes`, or absent unions (representing empty). Empty byte arrays are
        // disallowed.
        1: bytes vector<byte>:64000;

        // Allows a store within a store, thereby turning our flat key-value store into a tree
        // thereof. Note the use of `@generated_name` to prevent a type-name collision with the
        // `Store` protocol below, and the use of `box<T>` to ensure that there is a break in the
        // chain of recursion, thereby allowing `Item` to include itself in its own definition.
        //
        // This is a table so that added fields, like for example a `hash`, can be easily added in
        // the future.
        2: store @generated_name("nested_store") table {
            1: items vector<box<Item>>;
        };
    }:optional;
};

/// An enumeration of things that may go wrong when trying to write a value to our store.
type WriteError = flexible enum {
    UNKNOWN = 0;
    INVALID_KEY = 1;
    INVALID_VALUE = 2;
    ALREADY_EXISTS = 3;
};

/// A very basic key-value store.
@discoverable
open protocol Store {
    /// Writes an item to the store.
    flexible WriteItem(struct {
        attempt Item;
    }) -> () error WriteError;
};

CML

用戶端

// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
{
    include: [ "syslog/client.shard.cml" ],
    program: {
        runner: "elf",
        binary: "bin<