原始碼閱讀 protobuf 中的 any 包

2021-10-05 12:26:09 字數 3953 閱讀 7817

path: google/protobuf/any.proto

在 anypb 中 any 包含兩個字段

type_url 充當訊息全域性唯一識別符號並解析為該訊息的型別

value 任意序列化的訊息(位元組)

// anymessagename 方法,返回 anypb.any 訊息中包含的訊息名稱

func

anymessagename

(any *anypb.any)

(string

,error

)// anymessagename 方法,返回 anypb.any 訊息中包含的訊息名稱

// 如果獲取的訊息名稱是無效在,則返回錯誤

func

anymessagename

(any *anypb.any)

(protoreflect.fullname,

error

) name := protoreflect.

fullname

(any.typeurl)

if i := strings.

lastindex

(any.typeurl,

"/")

; i >=0if

!name.

isvalid()

return name,

nil}

// marshalany 方法,將訊息 m 序列化到 any 中,用於訊息傳遞。

// 即泛型的轉換,與 unmarshalany 為一組序列化方法

func

marshalany

(m proto.message)

(*anypb.any,

error

) m = dm.message

} b, err := proto.

marshal

(m)if err !=

nilreturn

&anypb.any

,nil

}// empty 方法,用於判斷 any 訊息中的訊息是否存在於全域性登錄檔中

// 如果在全域性登錄檔中找到相應的訊息型別,則返回對應的訊息型別

// 如果無法在全域性登錄檔中找到相應的訊息型別,則返回 `protoregistry.notfound`

func

empty

(any *anypb.any)

(proto.message,

error

) mt, err := protoregistry.globaltypes.

findmessagebyname

(name)

if err !=

nilreturn proto.

messagev1

(mt.

new().

inte***ce()

),nil}

// unmarshalany 方法,將訊息 any 進行反序列化並判斷是否匹配 m 訊息。

// 即泛型的轉換,與 marshalany 為一組序列化方法

// 如果 m 訊息並不與 any 訊息匹配,或者在反序列化時出現錯誤,將返回乙個錯誤

// // 當訊息 m 是乙個無法解析的動態訊息(*dynamicany),同樣也會返回乙個錯誤 `protoregistry.notfound`

func

unmarshalany

(any *anypb.any, m proto.message)

error

} m = dm.message

} anyname, err :=

anymessagename

(any)

if err !=

nil msgname := proto.

messagename

(m)if anyname != msgname

return proto.

unmarshal

(any.value, m)

}// is 方法,判斷 any 訊息是否包含指定型別 m 的訊息(斷言)

func

is(any *anypb.any, m proto.message)

bool

name := proto.

messagename

(m)if

!strings.

hassuffix

(any.typeurl, name)

return

len(any.typeurl)

==len

(name)

|| any.typeurl[

len(any.typeurl)

-len

(name)-1

]=='/'}

// dynamicany 方法,傳遞給 unmarshalany 乙個 anypb.any 中自動分配的任意指定型別訊息的值

// 待分配的訊息儲存在嵌入的 proto.message 中

//// example:

// var x ptypes.dynamicany

// if err := ptypes.unmarshalany(a, &x); err != nil

// fmt.printf("unmarshaled message: %v", x.message)

type dynamicany struct

func

(m dynamicany)

string()

string

return m.message.

string()

}func

(m dynamicany)

reset()

m.message.

reset()

}func

(m dynamicany)

protomessage()

func

(m dynamicany)

protoreflect

() protoreflect.message

return dynamicany

}type dynamicany struct

func

(m dynamicany)

type

() protoreflect.messagetype

}func

(m dynamicany)

new(

) protoreflect.message

.new()

}func

(m dynamicany)

inte***ce

() protoreflect.protomessage

}type dynamicanytype struct

func

(t dynamicanytype)

new(

) protoreflect.message

}func

(t dynamicanytype)

zero

() protoreflect.message

}

《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具

檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...

原始碼閱讀 Glide原始碼閱讀之with方法(一)

前言 本篇基於4.8.0版本 原始碼閱讀 glide原始碼閱讀之with方法 一 原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 大多數情況下,我們使用glide 就一句 但是這一句 裡面蘊含著成噸的 with方法有以下幾個過載方法 publi...

原始碼閱讀 Glide原始碼閱讀之load方法(二)

原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 首先,load方法有以下幾個過載方法 public requestbuilder load nullable bitmap bitmap public requestbuilder load nu...