protocol buffer

protocol buffer

protocol buffer是Google的一種獨立的數據交換格式,可運用於多種領域。

基本介紹

  • 外文名:protocol buffer
  • 簡稱:PB
  • 類別:google的一種數據交換的格式
  • 特點:獨立於語言,獨立於平台
簡介,編譯環境,

簡介

protocolbuffer(以下簡稱PB)是google 的一種數據交換的格式,它獨立於語言,獨立於平台。google 提供了多種語言的實現:java、c#c++、go 和 python,每一種實現都包含了相應語言的編譯器以及庫檔案。由於它是一種二進制的格式,比使用 xml 進行數據交換快許多。可以把它用於分散式套用之間的數據通信或者異構環境下的數據交換。作為一種效率和兼容性都很優秀的二進制數據傳輸格式,可以用於諸如網路傳輸、配置檔案、數據存儲等諸多領域。

編譯環境

本文的分析基於google發布的源碼2.0.1版本。
PB的源碼結構大致如下:
PB源碼
{
PB基礎庫
{
Message抽象層
Descriptor抽象層
IO子系統
}
PB編譯器----源碼生成器
}
IO子系統最為簡單,不依賴於系統其他部分,實現統一的輸入輸出接口
Message抽象層主要由一個抽象的Message類和從Message類裡面單獨分離出來的Reflection類構成.
GeneratedMessageReflection是Reflection的派生類,實現了抽象的Message方法。這裡的關鍵在於
一個靜態的offsets數組,裡面存儲了任何Message派生類對象裡面各個欄位相對於對象本身的偏移量
利用這個偏移量,GeneratedMessageReflection可以在不知道確切欄位名字和類型的情況下實現
Reflection裡面定義的Message方法。
Descriptor抽象層是系統的核心。由平行的兩組解釋器構成。一組是一系列遞歸下降的Descriptor類
群,另一組是一系列遞歸下降的DescriptorProto類群。Descriptor類群描述的是抽象的任意的訊息。
DescriptorProto類型是對訊息格式本身進行描述的訊息。其中FileDescriptorProto類群描述了.proto
檔案的結構,任何.proto檔案都可以映射到一個FileDescriptorProto對象上。FileDescriptorProto對象
和FileDescriptor之間可以相互轉換。
PB編譯器實際上是一組遞歸下降的CodeGenerator類群。Generator的輸入是Descriptor類群,輸出是
具體的派生訊息類。
整個編譯器的運作過程如下:
1 從.proto檔案生成FileDescriptorProto對象
2 從FileDescriptorProto對象生成FileDescriptor對象
3 CodeGenerator從FileDescriptor對象生成代碼
這裡的關鍵是第一步,相當於常規編譯的詞法和語法分析,構造解釋器的過程。但是看代碼我們並沒有
發現詞法和語法分析過程。google是怎么做到的呢。原來,在Generator裡面通過把FileDescriptor轉化為
FileDescritorProto,然後SerializeToString序列化後把二進制直接輸出到代碼中。於是
FileDescriptorProto對象就可以直接從這個二進制通過ParseFromArray構造出來。這裡有一個問題,
FileDescriptorProto類本身就是Generator生成的,依賴於Generator,Generator依賴於FileDescriptor,
FileDescriptor依賴於FileDescriptorProto對象,FileDescriptorProto對象又依賴於
FileDescriptorProto類。這就構成了一個循環依賴。這是一個雞生蛋還是蛋生雞的問題。其實我們可以
想像,最初的FileDescriptorProto類可以手工構造,然後用這個手工構造的類生成其他派生訊息類包括
現在的FileDescriptorProto類。這樣,google就把詞法和語法分析納入到了已有的序列化和反序列化
過程中,而不需要單獨的其他邏輯。

相關詞條

熱門詞條

聯絡我們