Source File
codec_extension.go
Belonging Package
google.golang.org/protobuf/internal/impl
package impl
import (
pref
)
type extensionFieldInfo struct {
wiretag uint64
tagsize int
unmarshalNeedsValue bool
funcs valueCoderFuncs
validation validationInfo
}
var legacyExtensionFieldInfoCache sync.Map // map[protoreflect.ExtensionType]*extensionFieldInfo
func ( pref.ExtensionType) *extensionFieldInfo {
if , := .(*ExtensionInfo); {
.lazyInit()
return .info
}
return legacyLoadExtensionFieldInfo()
}
func ( pref.ExtensionType) *extensionFieldInfo {
if , := legacyExtensionFieldInfoCache.Load(); {
return .(*extensionFieldInfo)
}
:= makeExtensionFieldInfo(.TypeDescriptor())
if , := legacyMessageTypeCache.LoadOrStore(, ); {
return .(*extensionFieldInfo)
}
return
}
func ( pref.ExtensionDescriptor) *extensionFieldInfo {
var uint64
if !.IsPacked() {
= protowire.EncodeTag(.Number(), wireTypes[.Kind()])
} else {
= protowire.EncodeTag(.Number(), protowire.BytesType)
}
:= &extensionFieldInfo{
wiretag: ,
tagsize: protowire.SizeVarint(),
funcs: encoderFuncsForValue(),
switch .Kind() {
case pref.MessageKind, pref.GroupKind, pref.EnumKind:
.unmarshalNeedsValue = true
default:
if .Cardinality() == pref.Repeated {
.unmarshalNeedsValue = true
}
}
return
}
type lazyExtensionValue struct {
atomicOnce uint32 // atomically set if value is valid
mu sync.Mutex
xi *extensionFieldInfo
value pref.Value
b []byte
fn func() pref.Value
}
type ExtensionField struct {
typ pref.ExtensionType
value pref.Value
lazy *lazyExtensionValue
}
func ( *ExtensionField) ( pref.ExtensionType, *extensionFieldInfo, protowire.Number, protowire.Type, []byte) {
if .lazy == nil {
.lazy = &lazyExtensionValue{xi: }
}
.typ =
.lazy.xi =
.lazy.b = protowire.AppendTag(.lazy.b, , )
.lazy.b = append(.lazy.b, ...)
}
func ( *ExtensionField) ( pref.ExtensionType) bool {
if .typ == nil {
return true
}
if .typ == && .lazy != nil && atomic.LoadUint32(&.lazy.atomicOnce) == 0 {
return true
}
return false
}
func ( *ExtensionField) () {
.lazy.mu.Lock()
defer .lazy.mu.Unlock()
if atomic.LoadUint32(&.lazy.atomicOnce) == 1 {
return
}
if .lazy.xi != nil {
:= .lazy.b
:= .typ.New()
for len() > 0 {
var uint64
if [0] < 0x80 {
= uint64([0])
= [1:]
} else if len() >= 2 && [1] < 128 {
= uint64([0]&0x7f) + uint64([1])<<7
= [2:]
} else {
var int
, = protowire.ConsumeVarint()
if < 0 {
panic(errors.New("bad tag in lazy extension decoding"))
}
= [:]
}
:= protowire.Number( >> 3)
:= protowire.Type( & 7)
var unmarshalOutput
var error
, , = .lazy.xi.funcs.unmarshal(, , , , lazyUnmarshalOptions)
if != nil {
panic(errors.New("decode failure in lazy extension decoding: %v", ))
}
= [.n:]
}
.lazy.value =
} else {
.lazy.value = .lazy.fn()
}
.lazy.xi = nil
.lazy.fn = nil
.lazy.b = nil
atomic.StoreUint32(&.lazy.atomicOnce, 1)
}
func ( *ExtensionField) ( pref.ExtensionType, pref.Value) {
.typ =
.value =
.lazy = nil
}
func ( *ExtensionField) ( pref.ExtensionType, func() pref.Value) {
.typ =
.lazy = &lazyExtensionValue{fn: }
}
func ( *ExtensionField) () pref.Value {
if .lazy != nil {
if atomic.LoadUint32(&.lazy.atomicOnce) == 0 {
.lazyInit()
}
return .lazy.value
}
return .value
}
func ( ExtensionField) () pref.ExtensionType {
return .typ
}
func ( ExtensionField) () bool {
return .typ != nil
}
func ( pref.Message, pref.FieldDescriptor) bool {
var *MessageInfo
var pointer
switch m := .(type) {
case *messageState:
= .messageInfo()
= .pointer()
case *messageReflectWrapper:
= .messageInfo()
= .pointer()
default:
return false
}
, := .(pref.ExtensionTypeDescriptor)
if ! {
return false
}
:= .Type()
:= .extensionMap()
if == nil {
return false
}
, := (*)[int32(.Number())]
if ! {
return false
}
return .typ == && .lazy != nil && atomic.LoadUint32(&.lazy.atomicOnce) == 0
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |