forked from forgejo/forgejo
Vendor Update: go-gitlab v0.22.1 -> v0.31.0 (#11136)
* vendor update: go-gitlab to v0.31.0 * migrate client init to v0.31.0 * refactor
This commit is contained in:
parent
5c092eb0ef
commit
82dbb34c9c
256 changed files with 36039 additions and 12965 deletions
170
vendor/google.golang.org/protobuf/internal/impl/api_export.go
generated
vendored
Normal file
170
vendor/google.golang.org/protobuf/internal/impl/api_export.go
generated
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"google.golang.org/protobuf/encoding/prototext"
|
||||
"google.golang.org/protobuf/proto"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
// Export is a zero-length named type that exists only to export a set of
|
||||
// functions that we do not want to appear in godoc.
|
||||
type Export struct{}
|
||||
|
||||
// enum is any enum type generated by protoc-gen-go
|
||||
// and must be a named int32 type.
|
||||
type enum = interface{}
|
||||
|
||||
// EnumOf returns the protoreflect.Enum interface over e.
|
||||
// It returns nil if e is nil.
|
||||
func (Export) EnumOf(e enum) pref.Enum {
|
||||
switch e := e.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case pref.Enum:
|
||||
return e
|
||||
default:
|
||||
return legacyWrapEnum(reflect.ValueOf(e))
|
||||
}
|
||||
}
|
||||
|
||||
// EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
|
||||
// It returns nil if e is nil.
|
||||
func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor {
|
||||
switch e := e.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case pref.Enum:
|
||||
return e.Descriptor()
|
||||
default:
|
||||
return LegacyLoadEnumDesc(reflect.TypeOf(e))
|
||||
}
|
||||
}
|
||||
|
||||
// EnumTypeOf returns the protoreflect.EnumType for e.
|
||||
// It returns nil if e is nil.
|
||||
func (Export) EnumTypeOf(e enum) pref.EnumType {
|
||||
switch e := e.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case pref.Enum:
|
||||
return e.Type()
|
||||
default:
|
||||
return legacyLoadEnumType(reflect.TypeOf(e))
|
||||
}
|
||||
}
|
||||
|
||||
// EnumStringOf returns the enum value as a string, either as the name if
|
||||
// the number is resolvable, or the number formatted as a string.
|
||||
func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string {
|
||||
ev := ed.Values().ByNumber(n)
|
||||
if ev != nil {
|
||||
return string(ev.Name())
|
||||
}
|
||||
return strconv.Itoa(int(n))
|
||||
}
|
||||
|
||||
// message is any message type generated by protoc-gen-go
|
||||
// and must be a pointer to a named struct type.
|
||||
type message = interface{}
|
||||
|
||||
// legacyMessageWrapper wraps a v2 message as a v1 message.
|
||||
type legacyMessageWrapper struct{ m pref.ProtoMessage }
|
||||
|
||||
func (m legacyMessageWrapper) Reset() { proto.Reset(m.m) }
|
||||
func (m legacyMessageWrapper) String() string { return Export{}.MessageStringOf(m.m) }
|
||||
func (m legacyMessageWrapper) ProtoMessage() {}
|
||||
|
||||
// ProtoMessageV1Of converts either a v1 or v2 message to a v1 message.
|
||||
// It returns nil if m is nil.
|
||||
func (Export) ProtoMessageV1Of(m message) piface.MessageV1 {
|
||||
switch mv := m.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case piface.MessageV1:
|
||||
return mv
|
||||
case unwrapper:
|
||||
return Export{}.ProtoMessageV1Of(mv.protoUnwrap())
|
||||
case pref.ProtoMessage:
|
||||
return legacyMessageWrapper{mv}
|
||||
default:
|
||||
panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
|
||||
}
|
||||
}
|
||||
|
||||
func (Export) protoMessageV2Of(m message) pref.ProtoMessage {
|
||||
switch mv := m.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case pref.ProtoMessage:
|
||||
return mv
|
||||
case legacyMessageWrapper:
|
||||
return mv.m
|
||||
case piface.MessageV1:
|
||||
return nil
|
||||
default:
|
||||
panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
|
||||
}
|
||||
}
|
||||
|
||||
// ProtoMessageV2Of converts either a v1 or v2 message to a v2 message.
|
||||
// It returns nil if m is nil.
|
||||
func (Export) ProtoMessageV2Of(m message) pref.ProtoMessage {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
if mv := (Export{}).protoMessageV2Of(m); mv != nil {
|
||||
return mv
|
||||
}
|
||||
return legacyWrapMessage(reflect.ValueOf(m)).Interface()
|
||||
}
|
||||
|
||||
// MessageOf returns the protoreflect.Message interface over m.
|
||||
// It returns nil if m is nil.
|
||||
func (Export) MessageOf(m message) pref.Message {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
if mv := (Export{}).protoMessageV2Of(m); mv != nil {
|
||||
return mv.ProtoReflect()
|
||||
}
|
||||
return legacyWrapMessage(reflect.ValueOf(m))
|
||||
}
|
||||
|
||||
// MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
|
||||
// It returns nil if m is nil.
|
||||
func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
if mv := (Export{}).protoMessageV2Of(m); mv != nil {
|
||||
return mv.ProtoReflect().Descriptor()
|
||||
}
|
||||
return LegacyLoadMessageDesc(reflect.TypeOf(m))
|
||||
}
|
||||
|
||||
// MessageTypeOf returns the protoreflect.MessageType for m.
|
||||
// It returns nil if m is nil.
|
||||
func (Export) MessageTypeOf(m message) pref.MessageType {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
if mv := (Export{}).protoMessageV2Of(m); mv != nil {
|
||||
return mv.ProtoReflect().Type()
|
||||
}
|
||||
return legacyLoadMessageInfo(reflect.TypeOf(m), "")
|
||||
}
|
||||
|
||||
// MessageStringOf returns the message value as a string,
|
||||
// which is the message serialized in the protobuf text format.
|
||||
func (Export) MessageStringOf(m pref.ProtoMessage) string {
|
||||
return prototext.MarshalOptions{Multiline: false}.Format(m)
|
||||
}
|
141
vendor/google.golang.org/protobuf/internal/impl/checkinit.go
generated
vendored
Normal file
141
vendor/google.golang.org/protobuf/internal/impl/checkinit.go
generated
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
func (mi *MessageInfo) checkInitialized(in piface.CheckInitializedInput) (piface.CheckInitializedOutput, error) {
|
||||
var p pointer
|
||||
if ms, ok := in.Message.(*messageState); ok {
|
||||
p = ms.pointer()
|
||||
} else {
|
||||
p = in.Message.(*messageReflectWrapper).pointer()
|
||||
}
|
||||
return piface.CheckInitializedOutput{}, mi.checkInitializedPointer(p)
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) checkInitializedPointer(p pointer) error {
|
||||
mi.init()
|
||||
if !mi.needsInitCheck {
|
||||
return nil
|
||||
}
|
||||
if p.IsNil() {
|
||||
for _, f := range mi.orderedCoderFields {
|
||||
if f.isRequired {
|
||||
return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if mi.extensionOffset.IsValid() {
|
||||
e := p.Apply(mi.extensionOffset).Extensions()
|
||||
if err := mi.isInitExtensions(e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, f := range mi.orderedCoderFields {
|
||||
if !f.isRequired && f.funcs.isInit == nil {
|
||||
continue
|
||||
}
|
||||
fptr := p.Apply(f.offset)
|
||||
if f.isPointer && fptr.Elem().IsNil() {
|
||||
if f.isRequired {
|
||||
return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
|
||||
}
|
||||
continue
|
||||
}
|
||||
if f.funcs.isInit == nil {
|
||||
continue
|
||||
}
|
||||
if err := f.funcs.isInit(fptr, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) isInitExtensions(ext *map[int32]ExtensionField) error {
|
||||
if ext == nil {
|
||||
return nil
|
||||
}
|
||||
for _, x := range *ext {
|
||||
ei := getExtensionFieldInfo(x.Type())
|
||||
if ei.funcs.isInit == nil {
|
||||
continue
|
||||
}
|
||||
v := x.Value()
|
||||
if !v.IsValid() {
|
||||
continue
|
||||
}
|
||||
if err := ei.funcs.isInit(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
needsInitCheckMu sync.Mutex
|
||||
needsInitCheckMap sync.Map
|
||||
)
|
||||
|
||||
// needsInitCheck reports whether a message needs to be checked for partial initialization.
|
||||
//
|
||||
// It returns true if the message transitively includes any required or extension fields.
|
||||
func needsInitCheck(md pref.MessageDescriptor) bool {
|
||||
if v, ok := needsInitCheckMap.Load(md); ok {
|
||||
if has, ok := v.(bool); ok {
|
||||
return has
|
||||
}
|
||||
}
|
||||
needsInitCheckMu.Lock()
|
||||
defer needsInitCheckMu.Unlock()
|
||||
return needsInitCheckLocked(md)
|
||||
}
|
||||
|
||||
func needsInitCheckLocked(md pref.MessageDescriptor) (has bool) {
|
||||
if v, ok := needsInitCheckMap.Load(md); ok {
|
||||
// If has is true, we've previously determined that this message
|
||||
// needs init checks.
|
||||
//
|
||||
// If has is false, we've previously determined that it can never
|
||||
// be uninitialized.
|
||||
//
|
||||
// If has is not a bool, we've just encountered a cycle in the
|
||||
// message graph. In this case, it is safe to return false: If
|
||||
// the message does have required fields, we'll detect them later
|
||||
// in the graph traversal.
|
||||
has, ok := v.(bool)
|
||||
return ok && has
|
||||
}
|
||||
needsInitCheckMap.Store(md, struct{}{}) // avoid cycles while descending into this message
|
||||
defer func() {
|
||||
needsInitCheckMap.Store(md, has)
|
||||
}()
|
||||
if md.RequiredNumbers().Len() > 0 {
|
||||
return true
|
||||
}
|
||||
if md.ExtensionRanges().Len() > 0 {
|
||||
return true
|
||||
}
|
||||
for i := 0; i < md.Fields().Len(); i++ {
|
||||
fd := md.Fields().Get(i)
|
||||
// Map keys are never messages, so just consider the map value.
|
||||
if fd.IsMap() {
|
||||
fd = fd.MapValue()
|
||||
}
|
||||
fmd := fd.Message()
|
||||
if fmd != nil && needsInitCheckLocked(fmd) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
223
vendor/google.golang.org/protobuf/internal/impl/codec_extension.go
generated
vendored
Normal file
223
vendor/google.golang.org/protobuf/internal/impl/codec_extension.go
generated
vendored
Normal file
|
@ -0,0 +1,223 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
type extensionFieldInfo struct {
|
||||
wiretag uint64
|
||||
tagsize int
|
||||
unmarshalNeedsValue bool
|
||||
funcs valueCoderFuncs
|
||||
validation validationInfo
|
||||
}
|
||||
|
||||
var legacyExtensionFieldInfoCache sync.Map // map[protoreflect.ExtensionType]*extensionFieldInfo
|
||||
|
||||
func getExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo {
|
||||
if xi, ok := xt.(*ExtensionInfo); ok {
|
||||
xi.lazyInit()
|
||||
return xi.info
|
||||
}
|
||||
return legacyLoadExtensionFieldInfo(xt)
|
||||
}
|
||||
|
||||
// legacyLoadExtensionFieldInfo dynamically loads a *ExtensionInfo for xt.
|
||||
func legacyLoadExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo {
|
||||
if xi, ok := legacyExtensionFieldInfoCache.Load(xt); ok {
|
||||
return xi.(*extensionFieldInfo)
|
||||
}
|
||||
e := makeExtensionFieldInfo(xt.TypeDescriptor())
|
||||
if e, ok := legacyMessageTypeCache.LoadOrStore(xt, e); ok {
|
||||
return e.(*extensionFieldInfo)
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func makeExtensionFieldInfo(xd pref.ExtensionDescriptor) *extensionFieldInfo {
|
||||
var wiretag uint64
|
||||
if !xd.IsPacked() {
|
||||
wiretag = protowire.EncodeTag(xd.Number(), wireTypes[xd.Kind()])
|
||||
} else {
|
||||
wiretag = protowire.EncodeTag(xd.Number(), protowire.BytesType)
|
||||
}
|
||||
e := &extensionFieldInfo{
|
||||
wiretag: wiretag,
|
||||
tagsize: protowire.SizeVarint(wiretag),
|
||||
funcs: encoderFuncsForValue(xd),
|
||||
}
|
||||
// Does the unmarshal function need a value passed to it?
|
||||
// This is true for composite types, where we pass in a message, list, or map to fill in,
|
||||
// and for enums, where we pass in a prototype value to specify the concrete enum type.
|
||||
switch xd.Kind() {
|
||||
case pref.MessageKind, pref.GroupKind, pref.EnumKind:
|
||||
e.unmarshalNeedsValue = true
|
||||
default:
|
||||
if xd.Cardinality() == pref.Repeated {
|
||||
e.unmarshalNeedsValue = true
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
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 is either the value of GetValue,
|
||||
// or a *lazyExtensionValue that then returns the value of GetValue.
|
||||
value pref.Value
|
||||
lazy *lazyExtensionValue
|
||||
}
|
||||
|
||||
func (f *ExtensionField) appendLazyBytes(xt pref.ExtensionType, xi *extensionFieldInfo, num protowire.Number, wtyp protowire.Type, b []byte) {
|
||||
if f.lazy == nil {
|
||||
f.lazy = &lazyExtensionValue{xi: xi}
|
||||
}
|
||||
f.typ = xt
|
||||
f.lazy.xi = xi
|
||||
f.lazy.b = protowire.AppendTag(f.lazy.b, num, wtyp)
|
||||
f.lazy.b = append(f.lazy.b, b...)
|
||||
}
|
||||
|
||||
func (f *ExtensionField) canLazy(xt pref.ExtensionType) bool {
|
||||
if f.typ == nil {
|
||||
return true
|
||||
}
|
||||
if f.typ == xt && f.lazy != nil && atomic.LoadUint32(&f.lazy.atomicOnce) == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *ExtensionField) lazyInit() {
|
||||
f.lazy.mu.Lock()
|
||||
defer f.lazy.mu.Unlock()
|
||||
if atomic.LoadUint32(&f.lazy.atomicOnce) == 1 {
|
||||
return
|
||||
}
|
||||
if f.lazy.xi != nil {
|
||||
b := f.lazy.b
|
||||
val := f.typ.New()
|
||||
for len(b) > 0 {
|
||||
var tag uint64
|
||||
if b[0] < 0x80 {
|
||||
tag = uint64(b[0])
|
||||
b = b[1:]
|
||||
} else if len(b) >= 2 && b[1] < 128 {
|
||||
tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
|
||||
b = b[2:]
|
||||
} else {
|
||||
var n int
|
||||
tag, n = protowire.ConsumeVarint(b)
|
||||
if n < 0 {
|
||||
panic(errors.New("bad tag in lazy extension decoding"))
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
num := protowire.Number(tag >> 3)
|
||||
wtyp := protowire.Type(tag & 7)
|
||||
var out unmarshalOutput
|
||||
var err error
|
||||
val, out, err = f.lazy.xi.funcs.unmarshal(b, val, num, wtyp, lazyUnmarshalOptions)
|
||||
if err != nil {
|
||||
panic(errors.New("decode failure in lazy extension decoding: %v", err))
|
||||
}
|
||||
b = b[out.n:]
|
||||
}
|
||||
f.lazy.value = val
|
||||
} else {
|
||||
f.lazy.value = f.lazy.fn()
|
||||
}
|
||||
f.lazy.xi = nil
|
||||
f.lazy.fn = nil
|
||||
f.lazy.b = nil
|
||||
atomic.StoreUint32(&f.lazy.atomicOnce, 1)
|
||||
}
|
||||
|
||||
// Set sets the type and value of the extension field.
|
||||
// This must not be called concurrently.
|
||||
func (f *ExtensionField) Set(t pref.ExtensionType, v pref.Value) {
|
||||
f.typ = t
|
||||
f.value = v
|
||||
f.lazy = nil
|
||||
}
|
||||
|
||||
// SetLazy sets the type and a value that is to be lazily evaluated upon first use.
|
||||
// This must not be called concurrently.
|
||||
func (f *ExtensionField) SetLazy(t pref.ExtensionType, fn func() pref.Value) {
|
||||
f.typ = t
|
||||
f.lazy = &lazyExtensionValue{fn: fn}
|
||||
}
|
||||
|
||||
// Value returns the value of the extension field.
|
||||
// This may be called concurrently.
|
||||
func (f *ExtensionField) Value() pref.Value {
|
||||
if f.lazy != nil {
|
||||
if atomic.LoadUint32(&f.lazy.atomicOnce) == 0 {
|
||||
f.lazyInit()
|
||||
}
|
||||
return f.lazy.value
|
||||
}
|
||||
return f.value
|
||||
}
|
||||
|
||||
// Type returns the type of the extension field.
|
||||
// This may be called concurrently.
|
||||
func (f ExtensionField) Type() pref.ExtensionType {
|
||||
return f.typ
|
||||
}
|
||||
|
||||
// IsSet returns whether the extension field is set.
|
||||
// This may be called concurrently.
|
||||
func (f ExtensionField) IsSet() bool {
|
||||
return f.typ != nil
|
||||
}
|
||||
|
||||
// IsLazy reports whether a field is lazily encoded.
|
||||
// It is exported for testing.
|
||||
func IsLazy(m pref.Message, fd pref.FieldDescriptor) bool {
|
||||
var mi *MessageInfo
|
||||
var p pointer
|
||||
switch m := m.(type) {
|
||||
case *messageState:
|
||||
mi = m.messageInfo()
|
||||
p = m.pointer()
|
||||
case *messageReflectWrapper:
|
||||
mi = m.messageInfo()
|
||||
p = m.pointer()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
xd, ok := fd.(pref.ExtensionTypeDescriptor)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
xt := xd.Type()
|
||||
ext := mi.extensionMap(p)
|
||||
if ext == nil {
|
||||
return false
|
||||
}
|
||||
f, ok := (*ext)[int32(fd.Number())]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return f.typ == xt && f.lazy != nil && atomic.LoadUint32(&f.lazy.atomicOnce) == 0
|
||||
}
|
828
vendor/google.golang.org/protobuf/internal/impl/codec_field.go
generated
vendored
Normal file
828
vendor/google.golang.org/protobuf/internal/impl/codec_field.go
generated
vendored
Normal file
|
@ -0,0 +1,828 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/proto"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
preg "google.golang.org/protobuf/reflect/protoregistry"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
type errInvalidUTF8 struct{}
|
||||
|
||||
func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
|
||||
func (errInvalidUTF8) InvalidUTF8() bool { return true }
|
||||
|
||||
// initOneofFieldCoders initializes the fast-path functions for the fields in a oneof.
|
||||
//
|
||||
// For size, marshal, and isInit operations, functions are set only on the first field
|
||||
// in the oneof. The functions are called when the oneof is non-nil, and will dispatch
|
||||
// to the appropriate field-specific function as necessary.
|
||||
//
|
||||
// The unmarshal function is set on each field individually as usual.
|
||||
func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) {
|
||||
fs := si.oneofsByName[od.Name()]
|
||||
ft := fs.Type
|
||||
oneofFields := make(map[reflect.Type]*coderFieldInfo)
|
||||
needIsInit := false
|
||||
fields := od.Fields()
|
||||
for i, lim := 0, fields.Len(); i < lim; i++ {
|
||||
fd := od.Fields().Get(i)
|
||||
num := fd.Number()
|
||||
// Make a copy of the original coderFieldInfo for use in unmarshaling.
|
||||
//
|
||||
// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
|
||||
//
|
||||
// mi.coderFields[num].marshal is set on only the first field in the oneof,
|
||||
// and dispatches to the field-specific marshaler in oneofFields.
|
||||
cf := *mi.coderFields[num]
|
||||
ot := si.oneofWrappersByNumber[num]
|
||||
cf.ft = ot.Field(0).Type
|
||||
cf.mi, cf.funcs = fieldCoder(fd, cf.ft)
|
||||
oneofFields[ot] = &cf
|
||||
if cf.funcs.isInit != nil {
|
||||
needIsInit = true
|
||||
}
|
||||
mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
var vw reflect.Value // pointer to wrapper type
|
||||
vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
|
||||
if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
|
||||
vw = vi.Elem()
|
||||
} else {
|
||||
vw = reflect.New(ot)
|
||||
}
|
||||
out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
vi.Set(vw)
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
getInfo := func(p pointer) (pointer, *coderFieldInfo) {
|
||||
v := p.AsValueOf(ft).Elem()
|
||||
if v.IsNil() {
|
||||
return pointer{}, nil
|
||||
}
|
||||
v = v.Elem() // interface -> *struct
|
||||
if v.IsNil() {
|
||||
return pointer{}, nil
|
||||
}
|
||||
return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
|
||||
}
|
||||
first := mi.coderFields[od.Fields().Get(0).Number()]
|
||||
first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
|
||||
p, info := getInfo(p)
|
||||
if info == nil || info.funcs.size == nil {
|
||||
return 0
|
||||
}
|
||||
return info.funcs.size(p, info, opts)
|
||||
}
|
||||
first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
p, info := getInfo(p)
|
||||
if info == nil || info.funcs.marshal == nil {
|
||||
return b, nil
|
||||
}
|
||||
return info.funcs.marshal(b, p, info, opts)
|
||||
}
|
||||
first.funcs.merge = func(dst, src pointer, _ *coderFieldInfo, opts mergeOptions) {
|
||||
srcp, srcinfo := getInfo(src)
|
||||
if srcinfo == nil || srcinfo.funcs.merge == nil {
|
||||
return
|
||||
}
|
||||
dstp, dstinfo := getInfo(dst)
|
||||
if dstinfo != srcinfo {
|
||||
dst.AsValueOf(ft).Elem().Set(reflect.New(src.AsValueOf(ft).Elem().Elem().Elem().Type()))
|
||||
dstp = pointerOfValue(dst.AsValueOf(ft).Elem().Elem()).Apply(zeroOffset)
|
||||
}
|
||||
srcinfo.funcs.merge(dstp, srcp, srcinfo, opts)
|
||||
}
|
||||
if needIsInit {
|
||||
first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
|
||||
p, info := getInfo(p)
|
||||
if info == nil || info.funcs.isInit == nil {
|
||||
return nil
|
||||
}
|
||||
return info.funcs.isInit(p, info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs {
|
||||
var once sync.Once
|
||||
var messageType pref.MessageType
|
||||
lazyInit := func() {
|
||||
once.Do(func() {
|
||||
messageName := fd.Message().FullName()
|
||||
messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
|
||||
})
|
||||
}
|
||||
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
m, ok := p.WeakFields().get(f.num)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
lazyInit()
|
||||
if messageType == nil {
|
||||
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
|
||||
}
|
||||
return sizeMessage(m, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
m, ok := p.WeakFields().get(f.num)
|
||||
if !ok {
|
||||
return b, nil
|
||||
}
|
||||
lazyInit()
|
||||
if messageType == nil {
|
||||
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
|
||||
}
|
||||
return appendMessage(b, m, f.wiretag, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
fs := p.WeakFields()
|
||||
m, ok := fs.get(f.num)
|
||||
if !ok {
|
||||
lazyInit()
|
||||
if messageType == nil {
|
||||
return unmarshalOutput{}, errUnknown
|
||||
}
|
||||
m = messageType.New().Interface()
|
||||
fs.set(f.num, m)
|
||||
}
|
||||
return consumeMessage(b, m, wtyp, opts)
|
||||
},
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
m, ok := p.WeakFields().get(f.num)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return proto.CheckInitialized(m)
|
||||
},
|
||||
merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
|
||||
sm, ok := src.WeakFields().get(f.num)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
dm, ok := dst.WeakFields().get(f.num)
|
||||
if !ok {
|
||||
lazyInit()
|
||||
if messageType == nil {
|
||||
panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
|
||||
}
|
||||
dm = messageType.New().Interface()
|
||||
dst.WeakFields().set(f.num, dm)
|
||||
}
|
||||
opts.Merge(dm, sm)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
if mi := getMessageInfo(ft); mi != nil {
|
||||
funcs := pointerCoderFuncs{
|
||||
size: sizeMessageInfo,
|
||||
marshal: appendMessageInfo,
|
||||
unmarshal: consumeMessageInfo,
|
||||
merge: mergeMessage,
|
||||
}
|
||||
if needsInitCheck(mi.Desc) {
|
||||
funcs.isInit = isInitMessageInfo
|
||||
}
|
||||
return funcs
|
||||
} else {
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return sizeMessage(m, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return appendMessage(b, m, f.wiretag, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
mp := p.AsValueOf(ft).Elem()
|
||||
if mp.IsNil() {
|
||||
mp.Set(reflect.New(ft.Elem()))
|
||||
}
|
||||
return consumeMessage(b, asMessage(mp), wtyp, opts)
|
||||
},
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return proto.CheckInitialized(m)
|
||||
},
|
||||
merge: mergeMessage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return protowire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
|
||||
}
|
||||
|
||||
func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
b = protowire.AppendVarint(b, f.wiretag)
|
||||
b = protowire.AppendVarint(b, uint64(f.mi.sizePointer(p.Elem(), opts)))
|
||||
return f.mi.marshalAppendPointer(b, p.Elem(), opts)
|
||||
}
|
||||
|
||||
func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
v, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
if p.Elem().IsNil() {
|
||||
p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
|
||||
}
|
||||
o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.n = n
|
||||
out.initialized = o.initialized
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
|
||||
return f.mi.checkInitializedPointer(p.Elem())
|
||||
}
|
||||
|
||||
func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
|
||||
return protowire.SizeBytes(proto.Size(m)) + tagsize
|
||||
}
|
||||
|
||||
func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
b = protowire.AppendVarint(b, wiretag)
|
||||
b = protowire.AppendVarint(b, uint64(proto.Size(m)))
|
||||
return opts.Options().MarshalAppend(b, m)
|
||||
}
|
||||
|
||||
func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
v, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
|
||||
Buf: v,
|
||||
Message: m.ProtoReflect(),
|
||||
})
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.n = n
|
||||
out.initialized = o.Flags&piface.UnmarshalInitialized != 0
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int {
|
||||
m := v.Message().Interface()
|
||||
return sizeMessage(m, tagsize, opts)
|
||||
}
|
||||
|
||||
func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
m := v.Message().Interface()
|
||||
return appendMessage(b, m, wiretag, opts)
|
||||
}
|
||||
|
||||
func consumeMessageValue(b []byte, v pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
|
||||
m := v.Message().Interface()
|
||||
out, err := consumeMessage(b, m, wtyp, opts)
|
||||
return v, out, err
|
||||
}
|
||||
|
||||
func isInitMessageValue(v pref.Value) error {
|
||||
m := v.Message().Interface()
|
||||
return proto.CheckInitialized(m)
|
||||
}
|
||||
|
||||
var coderMessageValue = valueCoderFuncs{
|
||||
size: sizeMessageValue,
|
||||
marshal: appendMessageValue,
|
||||
unmarshal: consumeMessageValue,
|
||||
isInit: isInitMessageValue,
|
||||
merge: mergeMessageValue,
|
||||
}
|
||||
|
||||
func sizeGroupValue(v pref.Value, tagsize int, opts marshalOptions) int {
|
||||
m := v.Message().Interface()
|
||||
return sizeGroup(m, tagsize, opts)
|
||||
}
|
||||
|
||||
func appendGroupValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
m := v.Message().Interface()
|
||||
return appendGroup(b, m, wiretag, opts)
|
||||
}
|
||||
|
||||
func consumeGroupValue(b []byte, v pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) {
|
||||
m := v.Message().Interface()
|
||||
out, err := consumeGroup(b, m, num, wtyp, opts)
|
||||
return v, out, err
|
||||
}
|
||||
|
||||
var coderGroupValue = valueCoderFuncs{
|
||||
size: sizeGroupValue,
|
||||
marshal: appendGroupValue,
|
||||
unmarshal: consumeGroupValue,
|
||||
isInit: isInitMessageValue,
|
||||
merge: mergeMessageValue,
|
||||
}
|
||||
|
||||
func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
num := fd.Number()
|
||||
if mi := getMessageInfo(ft); mi != nil {
|
||||
funcs := pointerCoderFuncs{
|
||||
size: sizeGroupType,
|
||||
marshal: appendGroupType,
|
||||
unmarshal: consumeGroupType,
|
||||
merge: mergeMessage,
|
||||
}
|
||||
if needsInitCheck(mi.Desc) {
|
||||
funcs.isInit = isInitMessageInfo
|
||||
}
|
||||
return funcs
|
||||
} else {
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return sizeGroup(m, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return appendGroup(b, m, f.wiretag, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
mp := p.AsValueOf(ft).Elem()
|
||||
if mp.IsNil() {
|
||||
mp.Set(reflect.New(ft.Elem()))
|
||||
}
|
||||
return consumeGroup(b, asMessage(mp), num, wtyp, opts)
|
||||
},
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
m := asMessage(p.AsValueOf(ft).Elem())
|
||||
return proto.CheckInitialized(m)
|
||||
},
|
||||
merge: mergeMessage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
|
||||
}
|
||||
|
||||
func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
b = protowire.AppendVarint(b, f.wiretag) // start group
|
||||
b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
|
||||
b = protowire.AppendVarint(b, f.wiretag+1) // end group
|
||||
return b, err
|
||||
}
|
||||
|
||||
func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.StartGroupType {
|
||||
return out, errUnknown
|
||||
}
|
||||
if p.Elem().IsNil() {
|
||||
p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
|
||||
}
|
||||
return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
|
||||
}
|
||||
|
||||
func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
|
||||
return 2*tagsize + proto.Size(m)
|
||||
}
|
||||
|
||||
func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
b = protowire.AppendVarint(b, wiretag) // start group
|
||||
b, err := opts.Options().MarshalAppend(b, m)
|
||||
b = protowire.AppendVarint(b, wiretag+1) // end group
|
||||
return b, err
|
||||
}
|
||||
|
||||
func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.StartGroupType {
|
||||
return out, errUnknown
|
||||
}
|
||||
b, n := protowire.ConsumeGroup(num, b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
|
||||
Buf: b,
|
||||
Message: m.ProtoReflect(),
|
||||
})
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.n = n
|
||||
out.initialized = o.Flags&piface.UnmarshalInitialized != 0
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
if mi := getMessageInfo(ft); mi != nil {
|
||||
funcs := pointerCoderFuncs{
|
||||
size: sizeMessageSliceInfo,
|
||||
marshal: appendMessageSliceInfo,
|
||||
unmarshal: consumeMessageSliceInfo,
|
||||
merge: mergeMessageSlice,
|
||||
}
|
||||
if needsInitCheck(mi.Desc) {
|
||||
funcs.isInit = isInitMessageSliceInfo
|
||||
}
|
||||
return funcs
|
||||
}
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return sizeMessageSlice(p, ft, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
return appendMessageSlice(b, p, f.wiretag, ft, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
return consumeMessageSlice(b, p, ft, wtyp, opts)
|
||||
},
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
return isInitMessageSlice(p, ft)
|
||||
},
|
||||
merge: mergeMessageSlice,
|
||||
}
|
||||
}
|
||||
|
||||
func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
s := p.PointerSlice()
|
||||
n := 0
|
||||
for _, v := range s {
|
||||
n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
s := p.PointerSlice()
|
||||
var err error
|
||||
for _, v := range s {
|
||||
b = protowire.AppendVarint(b, f.wiretag)
|
||||
siz := f.mi.sizePointer(v, opts)
|
||||
b = protowire.AppendVarint(b, uint64(siz))
|
||||
b, err = f.mi.marshalAppendPointer(b, v, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeMessageSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
v, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
|
||||
mp := pointerOfIface(m)
|
||||
o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
p.AppendPointerSlice(mp)
|
||||
out.n = n
|
||||
out.initialized = o.initialized
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
|
||||
s := p.PointerSlice()
|
||||
for _, v := range s {
|
||||
if err := f.mi.checkInitializedPointer(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
|
||||
s := p.PointerSlice()
|
||||
n := 0
|
||||
for _, v := range s {
|
||||
m := asMessage(v.AsValueOf(goType.Elem()))
|
||||
n += protowire.SizeBytes(proto.Size(m)) + tagsize
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
|
||||
s := p.PointerSlice()
|
||||
var err error
|
||||
for _, v := range s {
|
||||
m := asMessage(v.AsValueOf(goType.Elem()))
|
||||
b = protowire.AppendVarint(b, wiretag)
|
||||
siz := proto.Size(m)
|
||||
b = protowire.AppendVarint(b, uint64(siz))
|
||||
b, err = opts.Options().MarshalAppend(b, m)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
v, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
mp := reflect.New(goType.Elem())
|
||||
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
|
||||
Buf: v,
|
||||
Message: asMessage(mp).ProtoReflect(),
|
||||
})
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
p.AppendPointerSlice(pointerOfValue(mp))
|
||||
out.n = n
|
||||
out.initialized = o.Flags&piface.UnmarshalInitialized != 0
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func isInitMessageSlice(p pointer, goType reflect.Type) error {
|
||||
s := p.PointerSlice()
|
||||
for _, v := range s {
|
||||
m := asMessage(v.AsValueOf(goType.Elem()))
|
||||
if err := proto.CheckInitialized(m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Slices of messages
|
||||
|
||||
func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
|
||||
list := listv.List()
|
||||
n := 0
|
||||
for i, llen := 0, list.Len(); i < llen; i++ {
|
||||
m := list.Get(i).Message().Interface()
|
||||
n += protowire.SizeBytes(proto.Size(m)) + tagsize
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
list := listv.List()
|
||||
mopts := opts.Options()
|
||||
for i, llen := 0, list.Len(); i < llen; i++ {
|
||||
m := list.Get(i).Message().Interface()
|
||||
b = protowire.AppendVarint(b, wiretag)
|
||||
siz := proto.Size(m)
|
||||
b = protowire.AppendVarint(b, uint64(siz))
|
||||
var err error
|
||||
b, err = mopts.MarshalAppend(b, m)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeMessageSliceValue(b []byte, listv pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
|
||||
list := listv.List()
|
||||
if wtyp != protowire.BytesType {
|
||||
return pref.Value{}, out, errUnknown
|
||||
}
|
||||
v, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return pref.Value{}, out, protowire.ParseError(n)
|
||||
}
|
||||
m := list.NewElement()
|
||||
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
|
||||
Buf: v,
|
||||
Message: m.Message(),
|
||||
})
|
||||
if err != nil {
|
||||
return pref.Value{}, out, err
|
||||
}
|
||||
list.Append(m)
|
||||
out.n = n
|
||||
out.initialized = o.Flags&piface.UnmarshalInitialized != 0
|
||||
return listv, out, nil
|
||||
}
|
||||
|
||||
func isInitMessageSliceValue(listv pref.Value) error {
|
||||
list := listv.List()
|
||||
for i, llen := 0, list.Len(); i < llen; i++ {
|
||||
m := list.Get(i).Message().Interface()
|
||||
if err := proto.CheckInitialized(m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var coderMessageSliceValue = valueCoderFuncs{
|
||||
size: sizeMessageSliceValue,
|
||||
marshal: appendMessageSliceValue,
|
||||
unmarshal: consumeMessageSliceValue,
|
||||
isInit: isInitMessageSliceValue,
|
||||
merge: mergeMessageListValue,
|
||||
}
|
||||
|
||||
func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
|
||||
list := listv.List()
|
||||
n := 0
|
||||
for i, llen := 0, list.Len(); i < llen; i++ {
|
||||
m := list.Get(i).Message().Interface()
|
||||
n += 2*tagsize + proto.Size(m)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
|
||||
list := listv.List()
|
||||
mopts := opts.Options()
|
||||
for i, llen := 0, list.Len(); i < llen; i++ {
|
||||
m := list.Get(i).Message().Interface()
|
||||
b = protowire.AppendVarint(b, wiretag) // start group
|
||||
var err error
|
||||
b, err = mopts.MarshalAppend(b, m)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
b = protowire.AppendVarint(b, wiretag+1) // end group
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeGroupSliceValue(b []byte, listv pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) {
|
||||
list := listv.List()
|
||||
if wtyp != protowire.StartGroupType {
|
||||
return pref.Value{}, out, errUnknown
|
||||
}
|
||||
b, n := protowire.ConsumeGroup(num, b)
|
||||
if n < 0 {
|
||||
return pref.Value{}, out, protowire.ParseError(n)
|
||||
}
|
||||
m := list.NewElement()
|
||||
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
|
||||
Buf: b,
|
||||
Message: m.Message(),
|
||||
})
|
||||
if err != nil {
|
||||
return pref.Value{}, out, err
|
||||
}
|
||||
list.Append(m)
|
||||
out.n = n
|
||||
out.initialized = o.Flags&piface.UnmarshalInitialized != 0
|
||||
return listv, out, nil
|
||||
}
|
||||
|
||||
var coderGroupSliceValue = valueCoderFuncs{
|
||||
size: sizeGroupSliceValue,
|
||||
marshal: appendGroupSliceValue,
|
||||
unmarshal: consumeGroupSliceValue,
|
||||
isInit: isInitMessageSliceValue,
|
||||
merge: mergeMessageListValue,
|
||||
}
|
||||
|
||||
func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
|
||||
num := fd.Number()
|
||||
if mi := getMessageInfo(ft); mi != nil {
|
||||
funcs := pointerCoderFuncs{
|
||||
size: sizeGroupSliceInfo,
|
||||
marshal: appendGroupSliceInfo,
|
||||
unmarshal: consumeGroupSliceInfo,
|
||||
merge: mergeMessageSlice,
|
||||
}
|
||||
if needsInitCheck(mi.Desc) {
|
||||
funcs.isInit = isInitMessageSliceInfo
|
||||
}
|
||||
return funcs
|
||||
}
|
||||
return pointerCoderFuncs{
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return sizeGroupSlice(p, ft, f.tagsize, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
return appendGroupSlice(b, p, f.wiretag, ft, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
return consumeGroupSlice(b, p, num, wtyp, ft, opts)
|
||||
},
|
||||
isInit: func(p pointer, f *coderFieldInfo) error {
|
||||
return isInitMessageSlice(p, ft)
|
||||
},
|
||||
merge: mergeMessageSlice,
|
||||
}
|
||||
}
|
||||
|
||||
func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
|
||||
s := p.PointerSlice()
|
||||
n := 0
|
||||
for _, v := range s {
|
||||
m := asMessage(v.AsValueOf(messageType.Elem()))
|
||||
n += 2*tagsize + proto.Size(m)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
|
||||
s := p.PointerSlice()
|
||||
var err error
|
||||
for _, v := range s {
|
||||
m := asMessage(v.AsValueOf(messageType.Elem()))
|
||||
b = protowire.AppendVarint(b, wiretag) // start group
|
||||
b, err = opts.Options().MarshalAppend(b, m)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
b = protowire.AppendVarint(b, wiretag+1) // end group
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.StartGroupType {
|
||||
return out, errUnknown
|
||||
}
|
||||
b, n := protowire.ConsumeGroup(num, b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
mp := reflect.New(goType.Elem())
|
||||
o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{
|
||||
Buf: b,
|
||||
Message: asMessage(mp).ProtoReflect(),
|
||||
})
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
p.AppendPointerSlice(pointerOfValue(mp))
|
||||
out.n = n
|
||||
out.initialized = o.Flags&piface.UnmarshalInitialized != 0
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
s := p.PointerSlice()
|
||||
n := 0
|
||||
for _, v := range s {
|
||||
n += 2*f.tagsize + f.mi.sizePointer(v, opts)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
s := p.PointerSlice()
|
||||
var err error
|
||||
for _, v := range s {
|
||||
b = protowire.AppendVarint(b, f.wiretag) // start group
|
||||
b, err = f.mi.marshalAppendPointer(b, v, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
b = protowire.AppendVarint(b, f.wiretag+1) // end group
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
if wtyp != protowire.StartGroupType {
|
||||
return unmarshalOutput{}, errUnknown
|
||||
}
|
||||
m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
|
||||
mp := pointerOfIface(m)
|
||||
out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
p.AppendPointerSlice(mp)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func asMessage(v reflect.Value) pref.ProtoMessage {
|
||||
if m, ok := v.Interface().(pref.ProtoMessage); ok {
|
||||
return m
|
||||
}
|
||||
return legacyWrapMessage(v).Interface()
|
||||
}
|
5597
vendor/google.golang.org/protobuf/internal/impl/codec_gen.go
generated
vendored
Normal file
5597
vendor/google.golang.org/protobuf/internal/impl/codec_gen.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
388
vendor/google.golang.org/protobuf/internal/impl/codec_map.go
generated
vendored
Normal file
388
vendor/google.golang.org/protobuf/internal/impl/codec_map.go
generated
vendored
Normal file
|
@ -0,0 +1,388 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
type mapInfo struct {
|
||||
goType reflect.Type
|
||||
keyWiretag uint64
|
||||
valWiretag uint64
|
||||
keyFuncs valueCoderFuncs
|
||||
valFuncs valueCoderFuncs
|
||||
keyZero pref.Value
|
||||
keyKind pref.Kind
|
||||
conv *mapConverter
|
||||
}
|
||||
|
||||
func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage *MessageInfo, funcs pointerCoderFuncs) {
|
||||
// TODO: Consider generating specialized map coders.
|
||||
keyField := fd.MapKey()
|
||||
valField := fd.MapValue()
|
||||
keyWiretag := protowire.EncodeTag(1, wireTypes[keyField.Kind()])
|
||||
valWiretag := protowire.EncodeTag(2, wireTypes[valField.Kind()])
|
||||
keyFuncs := encoderFuncsForValue(keyField)
|
||||
valFuncs := encoderFuncsForValue(valField)
|
||||
conv := newMapConverter(ft, fd)
|
||||
|
||||
mapi := &mapInfo{
|
||||
goType: ft,
|
||||
keyWiretag: keyWiretag,
|
||||
valWiretag: valWiretag,
|
||||
keyFuncs: keyFuncs,
|
||||
valFuncs: valFuncs,
|
||||
keyZero: keyField.Default(),
|
||||
keyKind: keyField.Kind(),
|
||||
conv: conv,
|
||||
}
|
||||
if valField.Kind() == pref.MessageKind {
|
||||
valueMessage = getMessageInfo(ft.Elem())
|
||||
}
|
||||
|
||||
funcs = pointerCoderFuncs{
|
||||
size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
|
||||
return sizeMap(p.AsValueOf(ft).Elem(), mapi, f, opts)
|
||||
},
|
||||
marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
return appendMap(b, p.AsValueOf(ft).Elem(), mapi, f, opts)
|
||||
},
|
||||
unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
|
||||
mp := p.AsValueOf(ft)
|
||||
if mp.Elem().IsNil() {
|
||||
mp.Elem().Set(reflect.MakeMap(mapi.goType))
|
||||
}
|
||||
if f.mi == nil {
|
||||
return consumeMap(b, mp.Elem(), wtyp, mapi, f, opts)
|
||||
} else {
|
||||
return consumeMapOfMessage(b, mp.Elem(), wtyp, mapi, f, opts)
|
||||
}
|
||||
},
|
||||
}
|
||||
switch valField.Kind() {
|
||||
case pref.MessageKind:
|
||||
funcs.merge = mergeMapOfMessage
|
||||
case pref.BytesKind:
|
||||
funcs.merge = mergeMapOfBytes
|
||||
default:
|
||||
funcs.merge = mergeMap
|
||||
}
|
||||
if valFuncs.isInit != nil {
|
||||
funcs.isInit = func(p pointer, f *coderFieldInfo) error {
|
||||
return isInitMap(p.AsValueOf(ft).Elem(), mapi, f)
|
||||
}
|
||||
}
|
||||
return valueMessage, funcs
|
||||
}
|
||||
|
||||
const (
|
||||
mapKeyTagSize = 1 // field 1, tag size 1.
|
||||
mapValTagSize = 1 // field 2, tag size 2.
|
||||
)
|
||||
|
||||
func sizeMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) int {
|
||||
if mapv.Len() == 0 {
|
||||
return 0
|
||||
}
|
||||
n := 0
|
||||
iter := mapRange(mapv)
|
||||
for iter.Next() {
|
||||
key := mapi.conv.keyConv.PBValueOf(iter.Key()).MapKey()
|
||||
keySize := mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
|
||||
var valSize int
|
||||
value := mapi.conv.valConv.PBValueOf(iter.Value())
|
||||
if f.mi == nil {
|
||||
valSize = mapi.valFuncs.size(value, mapValTagSize, opts)
|
||||
} else {
|
||||
p := pointerOfValue(iter.Value())
|
||||
valSize += mapValTagSize
|
||||
valSize += protowire.SizeBytes(f.mi.sizePointer(p, opts))
|
||||
}
|
||||
n += f.tagsize + protowire.SizeBytes(keySize+valSize)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
b, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
var (
|
||||
key = mapi.keyZero
|
||||
val = mapi.conv.valConv.New()
|
||||
)
|
||||
for len(b) > 0 {
|
||||
num, wtyp, n := protowire.ConsumeTag(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
if num > protowire.MaxValidNumber {
|
||||
return out, errors.New("invalid field number")
|
||||
}
|
||||
b = b[n:]
|
||||
err := errUnknown
|
||||
switch num {
|
||||
case 1:
|
||||
var v pref.Value
|
||||
var o unmarshalOutput
|
||||
v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
key = v
|
||||
n = o.n
|
||||
case 2:
|
||||
var v pref.Value
|
||||
var o unmarshalOutput
|
||||
v, o, err = mapi.valFuncs.unmarshal(b, val, num, wtyp, opts)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
val = v
|
||||
n = o.n
|
||||
}
|
||||
if err == errUnknown {
|
||||
n = protowire.ConsumeFieldValue(num, wtyp, b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
} else if err != nil {
|
||||
return out, err
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
mapv.SetMapIndex(mapi.conv.keyConv.GoValueOf(key), mapi.conv.valConv.GoValueOf(val))
|
||||
out.n = n
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.BytesType {
|
||||
return out, errUnknown
|
||||
}
|
||||
b, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
var (
|
||||
key = mapi.keyZero
|
||||
val = reflect.New(f.mi.GoReflectType.Elem())
|
||||
)
|
||||
for len(b) > 0 {
|
||||
num, wtyp, n := protowire.ConsumeTag(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
if num > protowire.MaxValidNumber {
|
||||
return out, errors.New("invalid field number")
|
||||
}
|
||||
b = b[n:]
|
||||
err := errUnknown
|
||||
switch num {
|
||||
case 1:
|
||||
var v pref.Value
|
||||
var o unmarshalOutput
|
||||
v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
key = v
|
||||
n = o.n
|
||||
case 2:
|
||||
if wtyp != protowire.BytesType {
|
||||
break
|
||||
}
|
||||
var v []byte
|
||||
v, n = protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
var o unmarshalOutput
|
||||
o, err = f.mi.unmarshalPointer(v, pointerOfValue(val), 0, opts)
|
||||
if o.initialized {
|
||||
// Consider this map item initialized so long as we see
|
||||
// an initialized value.
|
||||
out.initialized = true
|
||||
}
|
||||
}
|
||||
if err == errUnknown {
|
||||
n = protowire.ConsumeFieldValue(num, wtyp, b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
} else if err != nil {
|
||||
return out, err
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
mapv.SetMapIndex(mapi.conv.keyConv.GoValueOf(key), val)
|
||||
out.n = n
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func appendMapItem(b []byte, keyrv, valrv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
if f.mi == nil {
|
||||
key := mapi.conv.keyConv.PBValueOf(keyrv).MapKey()
|
||||
val := mapi.conv.valConv.PBValueOf(valrv)
|
||||
size := 0
|
||||
size += mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
|
||||
size += mapi.valFuncs.size(val, mapValTagSize, opts)
|
||||
b = protowire.AppendVarint(b, uint64(size))
|
||||
b, err := mapi.keyFuncs.marshal(b, key.Value(), mapi.keyWiretag, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mapi.valFuncs.marshal(b, val, mapi.valWiretag, opts)
|
||||
} else {
|
||||
key := mapi.conv.keyConv.PBValueOf(keyrv).MapKey()
|
||||
val := pointerOfValue(valrv)
|
||||
valSize := f.mi.sizePointer(val, opts)
|
||||
size := 0
|
||||
size += mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts)
|
||||
size += mapValTagSize + protowire.SizeBytes(valSize)
|
||||
b = protowire.AppendVarint(b, uint64(size))
|
||||
b, err := mapi.keyFuncs.marshal(b, key.Value(), mapi.keyWiretag, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = protowire.AppendVarint(b, mapi.valWiretag)
|
||||
b = protowire.AppendVarint(b, uint64(valSize))
|
||||
return f.mi.marshalAppendPointer(b, val, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func appendMap(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
if mapv.Len() == 0 {
|
||||
return b, nil
|
||||
}
|
||||
if opts.Deterministic() {
|
||||
return appendMapDeterministic(b, mapv, mapi, f, opts)
|
||||
}
|
||||
iter := mapRange(mapv)
|
||||
for iter.Next() {
|
||||
var err error
|
||||
b = protowire.AppendVarint(b, f.wiretag)
|
||||
b, err = appendMapItem(b, iter.Key(), iter.Value(), mapi, f, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func appendMapDeterministic(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
keys := mapv.MapKeys()
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
switch keys[i].Kind() {
|
||||
case reflect.Bool:
|
||||
return !keys[i].Bool() && keys[j].Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return keys[i].Int() < keys[j].Int()
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return keys[i].Uint() < keys[j].Uint()
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return keys[i].Float() < keys[j].Float()
|
||||
case reflect.String:
|
||||
return keys[i].String() < keys[j].String()
|
||||
default:
|
||||
panic("invalid kind: " + keys[i].Kind().String())
|
||||
}
|
||||
})
|
||||
for _, key := range keys {
|
||||
var err error
|
||||
b = protowire.AppendVarint(b, f.wiretag)
|
||||
b, err = appendMapItem(b, key, mapv.MapIndex(key), mapi, f, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error {
|
||||
if mi := f.mi; mi != nil {
|
||||
mi.init()
|
||||
if !mi.needsInitCheck {
|
||||
return nil
|
||||
}
|
||||
iter := mapRange(mapv)
|
||||
for iter.Next() {
|
||||
val := pointerOfValue(iter.Value())
|
||||
if err := mi.checkInitializedPointer(val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iter := mapRange(mapv)
|
||||
for iter.Next() {
|
||||
val := mapi.conv.valConv.PBValueOf(iter.Value())
|
||||
if err := mapi.valFuncs.isInit(val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func mergeMap(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
|
||||
dstm := dst.AsValueOf(f.ft).Elem()
|
||||
srcm := src.AsValueOf(f.ft).Elem()
|
||||
if srcm.Len() == 0 {
|
||||
return
|
||||
}
|
||||
if dstm.IsNil() {
|
||||
dstm.Set(reflect.MakeMap(f.ft))
|
||||
}
|
||||
iter := mapRange(srcm)
|
||||
for iter.Next() {
|
||||
dstm.SetMapIndex(iter.Key(), iter.Value())
|
||||
}
|
||||
}
|
||||
|
||||
func mergeMapOfBytes(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
|
||||
dstm := dst.AsValueOf(f.ft).Elem()
|
||||
srcm := src.AsValueOf(f.ft).Elem()
|
||||
if srcm.Len() == 0 {
|
||||
return
|
||||
}
|
||||
if dstm.IsNil() {
|
||||
dstm.Set(reflect.MakeMap(f.ft))
|
||||
}
|
||||
iter := mapRange(srcm)
|
||||
for iter.Next() {
|
||||
dstm.SetMapIndex(iter.Key(), reflect.ValueOf(append(emptyBuf[:], iter.Value().Bytes()...)))
|
||||
}
|
||||
}
|
||||
|
||||
func mergeMapOfMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
|
||||
dstm := dst.AsValueOf(f.ft).Elem()
|
||||
srcm := src.AsValueOf(f.ft).Elem()
|
||||
if srcm.Len() == 0 {
|
||||
return
|
||||
}
|
||||
if dstm.IsNil() {
|
||||
dstm.Set(reflect.MakeMap(f.ft))
|
||||
}
|
||||
iter := mapRange(srcm)
|
||||
for iter.Next() {
|
||||
val := reflect.New(f.ft.Elem().Elem())
|
||||
if f.mi != nil {
|
||||
f.mi.mergePointer(pointerOfValue(val), pointerOfValue(iter.Value()), opts)
|
||||
} else {
|
||||
opts.Merge(asMessage(val), asMessage(iter.Value()))
|
||||
}
|
||||
dstm.SetMapIndex(iter.Key(), val)
|
||||
}
|
||||
}
|
37
vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go
generated
vendored
Normal file
37
vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.12
|
||||
|
||||
package impl
|
||||
|
||||
import "reflect"
|
||||
|
||||
type mapIter struct {
|
||||
v reflect.Value
|
||||
keys []reflect.Value
|
||||
}
|
||||
|
||||
// mapRange provides a less-efficient equivalent to
|
||||
// the Go 1.12 reflect.Value.MapRange method.
|
||||
func mapRange(v reflect.Value) *mapIter {
|
||||
return &mapIter{v: v}
|
||||
}
|
||||
|
||||
func (i *mapIter) Next() bool {
|
||||
if i.keys == nil {
|
||||
i.keys = i.v.MapKeys()
|
||||
} else {
|
||||
i.keys = i.keys[1:]
|
||||
}
|
||||
return len(i.keys) > 0
|
||||
}
|
||||
|
||||
func (i *mapIter) Key() reflect.Value {
|
||||
return i.keys[0]
|
||||
}
|
||||
|
||||
func (i *mapIter) Value() reflect.Value {
|
||||
return i.v.MapIndex(i.keys[0])
|
||||
}
|
11
vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go
generated
vendored
Normal file
11
vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.12
|
||||
|
||||
package impl
|
||||
|
||||
import "reflect"
|
||||
|
||||
func mapRange(v reflect.Value) *reflect.MapIter { return v.MapRange() }
|
157
vendor/google.golang.org/protobuf/internal/impl/codec_message.go
generated
vendored
Normal file
157
vendor/google.golang.org/protobuf/internal/impl/codec_message.go
generated
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/internal/encoding/messageset"
|
||||
"google.golang.org/protobuf/internal/fieldsort"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
// coderMessageInfo contains per-message information used by the fast-path functions.
|
||||
// This is a different type from MessageInfo to keep MessageInfo as general-purpose as
|
||||
// possible.
|
||||
type coderMessageInfo struct {
|
||||
methods piface.Methods
|
||||
|
||||
orderedCoderFields []*coderFieldInfo
|
||||
denseCoderFields []*coderFieldInfo
|
||||
coderFields map[protowire.Number]*coderFieldInfo
|
||||
sizecacheOffset offset
|
||||
unknownOffset offset
|
||||
extensionOffset offset
|
||||
needsInitCheck bool
|
||||
isMessageSet bool
|
||||
numRequiredFields uint8
|
||||
}
|
||||
|
||||
type coderFieldInfo struct {
|
||||
funcs pointerCoderFuncs // fast-path per-field functions
|
||||
mi *MessageInfo // field's message
|
||||
ft reflect.Type
|
||||
validation validationInfo // information used by message validation
|
||||
num pref.FieldNumber // field number
|
||||
offset offset // struct field offset
|
||||
wiretag uint64 // field tag (number + wire type)
|
||||
tagsize int // size of the varint-encoded tag
|
||||
isPointer bool // true if IsNil may be called on the struct field
|
||||
isRequired bool // true if field is required
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
|
||||
mi.sizecacheOffset = si.sizecacheOffset
|
||||
mi.unknownOffset = si.unknownOffset
|
||||
mi.extensionOffset = si.extensionOffset
|
||||
|
||||
mi.coderFields = make(map[protowire.Number]*coderFieldInfo)
|
||||
fields := mi.Desc.Fields()
|
||||
for i := 0; i < fields.Len(); i++ {
|
||||
fd := fields.Get(i)
|
||||
|
||||
fs := si.fieldsByNumber[fd.Number()]
|
||||
if fd.ContainingOneof() != nil {
|
||||
fs = si.oneofsByName[fd.ContainingOneof().Name()]
|
||||
}
|
||||
ft := fs.Type
|
||||
var wiretag uint64
|
||||
if !fd.IsPacked() {
|
||||
wiretag = protowire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
|
||||
} else {
|
||||
wiretag = protowire.EncodeTag(fd.Number(), protowire.BytesType)
|
||||
}
|
||||
var fieldOffset offset
|
||||
var funcs pointerCoderFuncs
|
||||
var childMessage *MessageInfo
|
||||
switch {
|
||||
case fd.ContainingOneof() != nil:
|
||||
fieldOffset = offsetOf(fs, mi.Exporter)
|
||||
case fd.IsWeak():
|
||||
fieldOffset = si.weakOffset
|
||||
funcs = makeWeakMessageFieldCoder(fd)
|
||||
default:
|
||||
fieldOffset = offsetOf(fs, mi.Exporter)
|
||||
childMessage, funcs = fieldCoder(fd, ft)
|
||||
}
|
||||
cf := &coderFieldInfo{
|
||||
num: fd.Number(),
|
||||
offset: fieldOffset,
|
||||
wiretag: wiretag,
|
||||
ft: ft,
|
||||
tagsize: protowire.SizeVarint(wiretag),
|
||||
funcs: funcs,
|
||||
mi: childMessage,
|
||||
validation: newFieldValidationInfo(mi, si, fd, ft),
|
||||
isPointer: (fd.Cardinality() == pref.Repeated ||
|
||||
fd.Kind() == pref.MessageKind ||
|
||||
fd.Kind() == pref.GroupKind ||
|
||||
fd.Syntax() != pref.Proto3),
|
||||
isRequired: fd.Cardinality() == pref.Required,
|
||||
}
|
||||
mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
|
||||
mi.coderFields[cf.num] = cf
|
||||
}
|
||||
for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ {
|
||||
mi.initOneofFieldCoders(oneofs.Get(i), si)
|
||||
}
|
||||
if messageset.IsMessageSet(mi.Desc) {
|
||||
if !mi.extensionOffset.IsValid() {
|
||||
panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName()))
|
||||
}
|
||||
if !mi.unknownOffset.IsValid() {
|
||||
panic(fmt.Sprintf("%v: MessageSet with no unknown field", mi.Desc.FullName()))
|
||||
}
|
||||
mi.isMessageSet = true
|
||||
}
|
||||
sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
|
||||
return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num
|
||||
})
|
||||
|
||||
var maxDense pref.FieldNumber
|
||||
for _, cf := range mi.orderedCoderFields {
|
||||
if cf.num >= 16 && cf.num >= 2*maxDense {
|
||||
break
|
||||
}
|
||||
maxDense = cf.num
|
||||
}
|
||||
mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
|
||||
for _, cf := range mi.orderedCoderFields {
|
||||
if int(cf.num) > len(mi.denseCoderFields) {
|
||||
break
|
||||
}
|
||||
mi.denseCoderFields[cf.num] = cf
|
||||
}
|
||||
|
||||
// To preserve compatibility with historic wire output, marshal oneofs last.
|
||||
if mi.Desc.Oneofs().Len() > 0 {
|
||||
sort.Slice(mi.orderedCoderFields, func(i, j int) bool {
|
||||
fi := fields.ByNumber(mi.orderedCoderFields[i].num)
|
||||
fj := fields.ByNumber(mi.orderedCoderFields[j].num)
|
||||
return fieldsort.Less(fi, fj)
|
||||
})
|
||||
}
|
||||
|
||||
mi.needsInitCheck = needsInitCheck(mi.Desc)
|
||||
if mi.methods.Marshal == nil && mi.methods.Size == nil {
|
||||
mi.methods.Flags |= piface.SupportMarshalDeterministic
|
||||
mi.methods.Marshal = mi.marshal
|
||||
mi.methods.Size = mi.size
|
||||
}
|
||||
if mi.methods.Unmarshal == nil {
|
||||
mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown
|
||||
mi.methods.Unmarshal = mi.unmarshal
|
||||
}
|
||||
if mi.methods.CheckInitialized == nil {
|
||||
mi.methods.CheckInitialized = mi.checkInitialized
|
||||
}
|
||||
if mi.methods.Merge == nil {
|
||||
mi.methods.Merge = mi.merge
|
||||
}
|
||||
}
|
120
vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go
generated
vendored
Normal file
120
vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/internal/encoding/messageset"
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
"google.golang.org/protobuf/internal/flags"
|
||||
)
|
||||
|
||||
func sizeMessageSet(mi *MessageInfo, p pointer, opts marshalOptions) (size int) {
|
||||
if !flags.ProtoLegacy {
|
||||
return 0
|
||||
}
|
||||
|
||||
ext := *p.Apply(mi.extensionOffset).Extensions()
|
||||
for _, x := range ext {
|
||||
xi := getExtensionFieldInfo(x.Type())
|
||||
if xi.funcs.size == nil {
|
||||
continue
|
||||
}
|
||||
num, _ := protowire.DecodeTag(xi.wiretag)
|
||||
size += messageset.SizeField(num)
|
||||
size += xi.funcs.size(x.Value(), protowire.SizeTag(messageset.FieldMessage), opts)
|
||||
}
|
||||
|
||||
unknown := *p.Apply(mi.unknownOffset).Bytes()
|
||||
size += messageset.SizeUnknown(unknown)
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
func marshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts marshalOptions) ([]byte, error) {
|
||||
if !flags.ProtoLegacy {
|
||||
return b, errors.New("no support for message_set_wire_format")
|
||||
}
|
||||
|
||||
ext := *p.Apply(mi.extensionOffset).Extensions()
|
||||
switch len(ext) {
|
||||
case 0:
|
||||
case 1:
|
||||
// Fast-path for one extension: Don't bother sorting the keys.
|
||||
for _, x := range ext {
|
||||
var err error
|
||||
b, err = marshalMessageSetField(mi, b, x, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Sort the keys to provide a deterministic encoding.
|
||||
// Not sure this is required, but the old code does it.
|
||||
keys := make([]int, 0, len(ext))
|
||||
for k := range ext {
|
||||
keys = append(keys, int(k))
|
||||
}
|
||||
sort.Ints(keys)
|
||||
for _, k := range keys {
|
||||
var err error
|
||||
b, err = marshalMessageSetField(mi, b, ext[int32(k)], opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unknown := *p.Apply(mi.unknownOffset).Bytes()
|
||||
b, err := messageset.AppendUnknown(b, unknown)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func marshalMessageSetField(mi *MessageInfo, b []byte, x ExtensionField, opts marshalOptions) ([]byte, error) {
|
||||
xi := getExtensionFieldInfo(x.Type())
|
||||
num, _ := protowire.DecodeTag(xi.wiretag)
|
||||
b = messageset.AppendFieldStart(b, num)
|
||||
b, err := xi.funcs.marshal(b, x.Value(), protowire.EncodeTag(messageset.FieldMessage, protowire.BytesType), opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
b = messageset.AppendFieldEnd(b)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func unmarshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if !flags.ProtoLegacy {
|
||||
return out, errors.New("no support for message_set_wire_format")
|
||||
}
|
||||
|
||||
ep := p.Apply(mi.extensionOffset).Extensions()
|
||||
if *ep == nil {
|
||||
*ep = make(map[int32]ExtensionField)
|
||||
}
|
||||
ext := *ep
|
||||
unknown := p.Apply(mi.unknownOffset).Bytes()
|
||||
initialized := true
|
||||
err = messageset.Unmarshal(b, true, func(num protowire.Number, v []byte) error {
|
||||
o, err := mi.unmarshalExtension(v, num, protowire.BytesType, ext, opts)
|
||||
if err == errUnknown {
|
||||
*unknown = protowire.AppendTag(*unknown, num, protowire.BytesType)
|
||||
*unknown = append(*unknown, v...)
|
||||
return nil
|
||||
}
|
||||
if !o.initialized {
|
||||
initialized = false
|
||||
}
|
||||
return err
|
||||
})
|
||||
out.n = len(b)
|
||||
out.initialized = initialized
|
||||
return out, err
|
||||
}
|
209
vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go
generated
vendored
Normal file
209
vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go
generated
vendored
Normal file
|
@ -0,0 +1,209 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build purego appengine
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
)
|
||||
|
||||
func sizeEnum(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
|
||||
v := p.v.Elem().Int()
|
||||
return f.tagsize + protowire.SizeVarint(uint64(v))
|
||||
}
|
||||
|
||||
func appendEnum(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
v := p.v.Elem().Int()
|
||||
b = protowire.AppendVarint(b, f.wiretag)
|
||||
b = protowire.AppendVarint(b, uint64(v))
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeEnum(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.VarintType {
|
||||
return out, errUnknown
|
||||
}
|
||||
v, n := protowire.ConsumeVarint(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
p.v.Elem().SetInt(int64(v))
|
||||
out.n = n
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func mergeEnum(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
dst.v.Elem().Set(src.v.Elem())
|
||||
}
|
||||
|
||||
var coderEnum = pointerCoderFuncs{
|
||||
size: sizeEnum,
|
||||
marshal: appendEnum,
|
||||
unmarshal: consumeEnum,
|
||||
merge: mergeEnum,
|
||||
}
|
||||
|
||||
func sizeEnumNoZero(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
|
||||
if p.v.Elem().Int() == 0 {
|
||||
return 0
|
||||
}
|
||||
return sizeEnum(p, f, opts)
|
||||
}
|
||||
|
||||
func appendEnumNoZero(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
if p.v.Elem().Int() == 0 {
|
||||
return b, nil
|
||||
}
|
||||
return appendEnum(b, p, f, opts)
|
||||
}
|
||||
|
||||
func mergeEnumNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
if src.v.Elem().Int() != 0 {
|
||||
dst.v.Elem().Set(src.v.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
var coderEnumNoZero = pointerCoderFuncs{
|
||||
size: sizeEnumNoZero,
|
||||
marshal: appendEnumNoZero,
|
||||
unmarshal: consumeEnum,
|
||||
merge: mergeEnumNoZero,
|
||||
}
|
||||
|
||||
func sizeEnumPtr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
|
||||
return sizeEnum(pointer{p.v.Elem()}, f, opts)
|
||||
}
|
||||
|
||||
func appendEnumPtr(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
return appendEnum(b, pointer{p.v.Elem()}, f, opts)
|
||||
}
|
||||
|
||||
func consumeEnumPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
if wtyp != protowire.VarintType {
|
||||
return out, errUnknown
|
||||
}
|
||||
if p.v.Elem().IsNil() {
|
||||
p.v.Elem().Set(reflect.New(p.v.Elem().Type().Elem()))
|
||||
}
|
||||
return consumeEnum(b, pointer{p.v.Elem()}, wtyp, f, opts)
|
||||
}
|
||||
|
||||
func mergeEnumPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
if !src.v.Elem().IsNil() {
|
||||
v := reflect.New(dst.v.Type().Elem().Elem())
|
||||
v.Elem().Set(src.v.Elem().Elem())
|
||||
dst.v.Elem().Set(v)
|
||||
}
|
||||
}
|
||||
|
||||
var coderEnumPtr = pointerCoderFuncs{
|
||||
size: sizeEnumPtr,
|
||||
marshal: appendEnumPtr,
|
||||
unmarshal: consumeEnumPtr,
|
||||
merge: mergeEnumPtr,
|
||||
}
|
||||
|
||||
func sizeEnumSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
|
||||
s := p.v.Elem()
|
||||
for i, llen := 0, s.Len(); i < llen; i++ {
|
||||
size += protowire.SizeVarint(uint64(s.Index(i).Int())) + f.tagsize
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
func appendEnumSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
s := p.v.Elem()
|
||||
for i, llen := 0, s.Len(); i < llen; i++ {
|
||||
b = protowire.AppendVarint(b, f.wiretag)
|
||||
b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func consumeEnumSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
s := p.v.Elem()
|
||||
if wtyp == protowire.BytesType {
|
||||
b, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
for len(b) > 0 {
|
||||
v, n := protowire.ConsumeVarint(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
rv := reflect.New(s.Type().Elem()).Elem()
|
||||
rv.SetInt(int64(v))
|
||||
s.Set(reflect.Append(s, rv))
|
||||
b = b[n:]
|
||||
}
|
||||
out.n = n
|
||||
return out, nil
|
||||
}
|
||||
if wtyp != protowire.VarintType {
|
||||
return out, errUnknown
|
||||
}
|
||||
v, n := protowire.ConsumeVarint(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
rv := reflect.New(s.Type().Elem()).Elem()
|
||||
rv.SetInt(int64(v))
|
||||
s.Set(reflect.Append(s, rv))
|
||||
out.n = n
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func mergeEnumSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
dst.v.Elem().Set(reflect.AppendSlice(dst.v.Elem(), src.v.Elem()))
|
||||
}
|
||||
|
||||
var coderEnumSlice = pointerCoderFuncs{
|
||||
size: sizeEnumSlice,
|
||||
marshal: appendEnumSlice,
|
||||
unmarshal: consumeEnumSlice,
|
||||
merge: mergeEnumSlice,
|
||||
}
|
||||
|
||||
func sizeEnumPackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
|
||||
s := p.v.Elem()
|
||||
llen := s.Len()
|
||||
if llen == 0 {
|
||||
return 0
|
||||
}
|
||||
n := 0
|
||||
for i := 0; i < llen; i++ {
|
||||
n += protowire.SizeVarint(uint64(s.Index(i).Int()))
|
||||
}
|
||||
return f.tagsize + protowire.SizeBytes(n)
|
||||
}
|
||||
|
||||
func appendEnumPackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
|
||||
s := p.v.Elem()
|
||||
llen := s.Len()
|
||||
if llen == 0 {
|
||||
return b, nil
|
||||
}
|
||||
b = protowire.AppendVarint(b, f.wiretag)
|
||||
n := 0
|
||||
for i := 0; i < llen; i++ {
|
||||
n += protowire.SizeVarint(uint64(s.Index(i).Int()))
|
||||
}
|
||||
b = protowire.AppendVarint(b, uint64(n))
|
||||
for i := 0; i < llen; i++ {
|
||||
b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
var coderEnumPackedSlice = pointerCoderFuncs{
|
||||
size: sizeEnumPackedSlice,
|
||||
marshal: appendEnumPackedSlice,
|
||||
unmarshal: consumeEnumSlice,
|
||||
merge: mergeEnumSlice,
|
||||
}
|
554
vendor/google.golang.org/protobuf/internal/impl/codec_tables.go
generated
vendored
Normal file
554
vendor/google.golang.org/protobuf/internal/impl/codec_tables.go
generated
vendored
Normal file
|
@ -0,0 +1,554 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/internal/strs"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
// pointerCoderFuncs is a set of pointer encoding functions.
|
||||
type pointerCoderFuncs struct {
|
||||
mi *MessageInfo
|
||||
size func(p pointer, f *coderFieldInfo, opts marshalOptions) int
|
||||
marshal func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error)
|
||||
unmarshal func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error)
|
||||
isInit func(p pointer, f *coderFieldInfo) error
|
||||
merge func(dst, src pointer, f *coderFieldInfo, opts mergeOptions)
|
||||
}
|
||||
|
||||
// valueCoderFuncs is a set of protoreflect.Value encoding functions.
|
||||
type valueCoderFuncs struct {
|
||||
size func(v pref.Value, tagsize int, opts marshalOptions) int
|
||||
marshal func(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error)
|
||||
unmarshal func(b []byte, v pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error)
|
||||
isInit func(v pref.Value) error
|
||||
merge func(dst, src pref.Value, opts mergeOptions) pref.Value
|
||||
}
|
||||
|
||||
// fieldCoder returns pointer functions for a field, used for operating on
|
||||
// struct fields.
|
||||
func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) {
|
||||
switch {
|
||||
case fd.IsMap():
|
||||
return encoderFuncsForMap(fd, ft)
|
||||
case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
|
||||
// Repeated fields (not packed).
|
||||
if ft.Kind() != reflect.Slice {
|
||||
break
|
||||
}
|
||||
ft := ft.Elem()
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return nil, coderBoolSlice
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderEnumSlice
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderInt32Slice
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSint32Slice
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderUint32Slice
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderInt64Slice
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSint64Slice
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderUint64Slice
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSfixed32Slice
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderFixed32Slice
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return nil, coderFloatSlice
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSfixed64Slice
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderFixed64Slice
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return nil, coderDoubleSlice
|
||||
}
|
||||
case pref.StringKind:
|
||||
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
|
||||
return nil, coderStringSliceValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.String {
|
||||
return nil, coderStringSlice
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
|
||||
return nil, coderBytesSliceValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return nil, coderBytesSlice
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return nil, coderStringSlice
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return nil, coderBytesSlice
|
||||
}
|
||||
case pref.MessageKind:
|
||||
return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft)
|
||||
case pref.GroupKind:
|
||||
return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft)
|
||||
}
|
||||
case fd.Cardinality() == pref.Repeated && fd.IsPacked():
|
||||
// Packed repeated fields.
|
||||
//
|
||||
// Only repeated fields of primitive numeric types
|
||||
// (Varint, Fixed32, or Fixed64 wire type) can be packed.
|
||||
if ft.Kind() != reflect.Slice {
|
||||
break
|
||||
}
|
||||
ft := ft.Elem()
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return nil, coderBoolPackedSlice
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderEnumPackedSlice
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderInt32PackedSlice
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSint32PackedSlice
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderUint32PackedSlice
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderInt64PackedSlice
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSint64PackedSlice
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderUint64PackedSlice
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSfixed32PackedSlice
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderFixed32PackedSlice
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return nil, coderFloatPackedSlice
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSfixed64PackedSlice
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderFixed64PackedSlice
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return nil, coderDoublePackedSlice
|
||||
}
|
||||
}
|
||||
case fd.Kind() == pref.MessageKind:
|
||||
return getMessageInfo(ft), makeMessageFieldCoder(fd, ft)
|
||||
case fd.Kind() == pref.GroupKind:
|
||||
return getMessageInfo(ft), makeGroupFieldCoder(fd, ft)
|
||||
case fd.Syntax() == pref.Proto3 && fd.ContainingOneof() == nil:
|
||||
// Populated oneof fields always encode even if set to the zero value,
|
||||
// which normally are not encoded in proto3.
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return nil, coderBoolNoZero
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderEnumNoZero
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderInt32NoZero
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSint32NoZero
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderUint32NoZero
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderInt64NoZero
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSint64NoZero
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderUint64NoZero
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSfixed32NoZero
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderFixed32NoZero
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return nil, coderFloatNoZero
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSfixed64NoZero
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderFixed64NoZero
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return nil, coderDoubleNoZero
|
||||
}
|
||||
case pref.StringKind:
|
||||
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
|
||||
return nil, coderStringNoZeroValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.String {
|
||||
return nil, coderStringNoZero
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
|
||||
return nil, coderBytesNoZeroValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return nil, coderBytesNoZero
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return nil, coderStringNoZero
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return nil, coderBytesNoZero
|
||||
}
|
||||
}
|
||||
case ft.Kind() == reflect.Ptr:
|
||||
ft := ft.Elem()
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return nil, coderBoolPtr
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderEnumPtr
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderInt32Ptr
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSint32Ptr
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderUint32Ptr
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderInt64Ptr
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSint64Ptr
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderUint64Ptr
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSfixed32Ptr
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderFixed32Ptr
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return nil, coderFloatPtr
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSfixed64Ptr
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderFixed64Ptr
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return nil, coderDoublePtr
|
||||
}
|
||||
case pref.StringKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return nil, coderStringPtr
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return nil, coderStringPtr
|
||||
}
|
||||
}
|
||||
default:
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if ft.Kind() == reflect.Bool {
|
||||
return nil, coderBool
|
||||
}
|
||||
case pref.EnumKind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderEnum
|
||||
}
|
||||
case pref.Int32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderInt32
|
||||
}
|
||||
case pref.Sint32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSint32
|
||||
}
|
||||
case pref.Uint32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderUint32
|
||||
}
|
||||
case pref.Int64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderInt64
|
||||
}
|
||||
case pref.Sint64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSint64
|
||||
}
|
||||
case pref.Uint64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderUint64
|
||||
}
|
||||
case pref.Sfixed32Kind:
|
||||
if ft.Kind() == reflect.Int32 {
|
||||
return nil, coderSfixed32
|
||||
}
|
||||
case pref.Fixed32Kind:
|
||||
if ft.Kind() == reflect.Uint32 {
|
||||
return nil, coderFixed32
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if ft.Kind() == reflect.Float32 {
|
||||
return nil, coderFloat
|
||||
}
|
||||
case pref.Sfixed64Kind:
|
||||
if ft.Kind() == reflect.Int64 {
|
||||
return nil, coderSfixed64
|
||||
}
|
||||
case pref.Fixed64Kind:
|
||||
if ft.Kind() == reflect.Uint64 {
|
||||
return nil, coderFixed64
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if ft.Kind() == reflect.Float64 {
|
||||
return nil, coderDouble
|
||||
}
|
||||
case pref.StringKind:
|
||||
if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
|
||||
return nil, coderStringValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.String {
|
||||
return nil, coderString
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) {
|
||||
return nil, coderBytesValidateUTF8
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return nil, coderBytes
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if ft.Kind() == reflect.String {
|
||||
return nil, coderString
|
||||
}
|
||||
if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
|
||||
return nil, coderBytes
|
||||
}
|
||||
}
|
||||
}
|
||||
panic(fmt.Sprintf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
|
||||
}
|
||||
|
||||
// encoderFuncsForValue returns value functions for a field, used for
|
||||
// extension values and map encoding.
|
||||
func encoderFuncsForValue(fd pref.FieldDescriptor) valueCoderFuncs {
|
||||
switch {
|
||||
case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
return coderBoolSliceValue
|
||||
case pref.EnumKind:
|
||||
return coderEnumSliceValue
|
||||
case pref.Int32Kind:
|
||||
return coderInt32SliceValue
|
||||
case pref.Sint32Kind:
|
||||
return coderSint32SliceValue
|
||||
case pref.Uint32Kind:
|
||||
return coderUint32SliceValue
|
||||
case pref.Int64Kind:
|
||||
return coderInt64SliceValue
|
||||
case pref.Sint64Kind:
|
||||
return coderSint64SliceValue
|
||||
case pref.Uint64Kind:
|
||||
return coderUint64SliceValue
|
||||
case pref.Sfixed32Kind:
|
||||
return coderSfixed32SliceValue
|
||||
case pref.Fixed32Kind:
|
||||
return coderFixed32SliceValue
|
||||
case pref.FloatKind:
|
||||
return coderFloatSliceValue
|
||||
case pref.Sfixed64Kind:
|
||||
return coderSfixed64SliceValue
|
||||
case pref.Fixed64Kind:
|
||||
return coderFixed64SliceValue
|
||||
case pref.DoubleKind:
|
||||
return coderDoubleSliceValue
|
||||
case pref.StringKind:
|
||||
// We don't have a UTF-8 validating coder for repeated string fields.
|
||||
// Value coders are used for extensions and maps.
|
||||
// Extensions are never proto3, and maps never contain lists.
|
||||
return coderStringSliceValue
|
||||
case pref.BytesKind:
|
||||
return coderBytesSliceValue
|
||||
case pref.MessageKind:
|
||||
return coderMessageSliceValue
|
||||
case pref.GroupKind:
|
||||
return coderGroupSliceValue
|
||||
}
|
||||
case fd.Cardinality() == pref.Repeated && fd.IsPacked():
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
return coderBoolPackedSliceValue
|
||||
case pref.EnumKind:
|
||||
return coderEnumPackedSliceValue
|
||||
case pref.Int32Kind:
|
||||
return coderInt32PackedSliceValue
|
||||
case pref.Sint32Kind:
|
||||
return coderSint32PackedSliceValue
|
||||
case pref.Uint32Kind:
|
||||
return coderUint32PackedSliceValue
|
||||
case pref.Int64Kind:
|
||||
return coderInt64PackedSliceValue
|
||||
case pref.Sint64Kind:
|
||||
return coderSint64PackedSliceValue
|
||||
case pref.Uint64Kind:
|
||||
return coderUint64PackedSliceValue
|
||||
case pref.Sfixed32Kind:
|
||||
return coderSfixed32PackedSliceValue
|
||||
case pref.Fixed32Kind:
|
||||
return coderFixed32PackedSliceValue
|
||||
case pref.FloatKind:
|
||||
return coderFloatPackedSliceValue
|
||||
case pref.Sfixed64Kind:
|
||||
return coderSfixed64PackedSliceValue
|
||||
case pref.Fixed64Kind:
|
||||
return coderFixed64PackedSliceValue
|
||||
case pref.DoubleKind:
|
||||
return coderDoublePackedSliceValue
|
||||
}
|
||||
default:
|
||||
switch fd.Kind() {
|
||||
default:
|
||||
case pref.BoolKind:
|
||||
return coderBoolValue
|
||||
case pref.EnumKind:
|
||||
return coderEnumValue
|
||||
case pref.Int32Kind:
|
||||
return coderInt32Value
|
||||
case pref.Sint32Kind:
|
||||
return coderSint32Value
|
||||
case pref.Uint32Kind:
|
||||
return coderUint32Value
|
||||
case pref.Int64Kind:
|
||||
return coderInt64Value
|
||||
case pref.Sint64Kind:
|
||||
return coderSint64Value
|
||||
case pref.Uint64Kind:
|
||||
return coderUint64Value
|
||||
case pref.Sfixed32Kind:
|
||||
return coderSfixed32Value
|
||||
case pref.Fixed32Kind:
|
||||
return coderFixed32Value
|
||||
case pref.FloatKind:
|
||||
return coderFloatValue
|
||||
case pref.Sfixed64Kind:
|
||||
return coderSfixed64Value
|
||||
case pref.Fixed64Kind:
|
||||
return coderFixed64Value
|
||||
case pref.DoubleKind:
|
||||
return coderDoubleValue
|
||||
case pref.StringKind:
|
||||
if strs.EnforceUTF8(fd) {
|
||||
return coderStringValueValidateUTF8
|
||||
}
|
||||
return coderStringValue
|
||||
case pref.BytesKind:
|
||||
return coderBytesValue
|
||||
case pref.MessageKind:
|
||||
return coderMessageValue
|
||||
case pref.GroupKind:
|
||||
return coderGroupValue
|
||||
}
|
||||
}
|
||||
panic(fmt.Sprintf("invalid field: no encoder for %v %v %v", fd.FullName(), fd.Cardinality(), fd.Kind()))
|
||||
}
|
17
vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go
generated
vendored
Normal file
17
vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !purego,!appengine
|
||||
|
||||
package impl
|
||||
|
||||
// When using unsafe pointers, we can just treat enum values as int32s.
|
||||
|
||||
var (
|
||||
coderEnumNoZero = coderInt32NoZero
|
||||
coderEnum = coderInt32
|
||||
coderEnumPtr = coderInt32Ptr
|
||||
coderEnumSlice = coderInt32Slice
|
||||
coderEnumPackedSlice = coderInt32PackedSlice
|
||||
)
|
467
vendor/google.golang.org/protobuf/internal/impl/convert.go
generated
vendored
Normal file
467
vendor/google.golang.org/protobuf/internal/impl/convert.go
generated
vendored
Normal file
|
@ -0,0 +1,467 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
// unwrapper unwraps the value to the underlying value.
|
||||
// This is implemented by List and Map.
|
||||
type unwrapper interface {
|
||||
protoUnwrap() interface{}
|
||||
}
|
||||
|
||||
// A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types.
|
||||
type Converter interface {
|
||||
// PBValueOf converts a reflect.Value to a protoreflect.Value.
|
||||
PBValueOf(reflect.Value) pref.Value
|
||||
|
||||
// GoValueOf converts a protoreflect.Value to a reflect.Value.
|
||||
GoValueOf(pref.Value) reflect.Value
|
||||
|
||||
// IsValidPB returns whether a protoreflect.Value is compatible with this type.
|
||||
IsValidPB(pref.Value) bool
|
||||
|
||||
// IsValidGo returns whether a reflect.Value is compatible with this type.
|
||||
IsValidGo(reflect.Value) bool
|
||||
|
||||
// New returns a new field value.
|
||||
// For scalars, it returns the default value of the field.
|
||||
// For composite types, it returns a new mutable value.
|
||||
New() pref.Value
|
||||
|
||||
// Zero returns a new field value.
|
||||
// For scalars, it returns the default value of the field.
|
||||
// For composite types, it returns an immutable, empty value.
|
||||
Zero() pref.Value
|
||||
}
|
||||
|
||||
// NewConverter matches a Go type with a protobuf field and returns a Converter
|
||||
// that converts between the two. Enums must be a named int32 kind that
|
||||
// implements protoreflect.Enum, and messages must be pointer to a named
|
||||
// struct type that implements protoreflect.ProtoMessage.
|
||||
//
|
||||
// This matcher deliberately supports a wider range of Go types than what
|
||||
// protoc-gen-go historically generated to be able to automatically wrap some
|
||||
// v1 messages generated by other forks of protoc-gen-go.
|
||||
func NewConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
|
||||
switch {
|
||||
case fd.IsList():
|
||||
return newListConverter(t, fd)
|
||||
case fd.IsMap():
|
||||
return newMapConverter(t, fd)
|
||||
default:
|
||||
return newSingularConverter(t, fd)
|
||||
}
|
||||
panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
|
||||
}
|
||||
|
||||
var (
|
||||
boolType = reflect.TypeOf(bool(false))
|
||||
int32Type = reflect.TypeOf(int32(0))
|
||||
int64Type = reflect.TypeOf(int64(0))
|
||||
uint32Type = reflect.TypeOf(uint32(0))
|
||||
uint64Type = reflect.TypeOf(uint64(0))
|
||||
float32Type = reflect.TypeOf(float32(0))
|
||||
float64Type = reflect.TypeOf(float64(0))
|
||||
stringType = reflect.TypeOf(string(""))
|
||||
bytesType = reflect.TypeOf([]byte(nil))
|
||||
byteType = reflect.TypeOf(byte(0))
|
||||
)
|
||||
|
||||
var (
|
||||
boolZero = pref.ValueOfBool(false)
|
||||
int32Zero = pref.ValueOfInt32(0)
|
||||
int64Zero = pref.ValueOfInt64(0)
|
||||
uint32Zero = pref.ValueOfUint32(0)
|
||||
uint64Zero = pref.ValueOfUint64(0)
|
||||
float32Zero = pref.ValueOfFloat32(0)
|
||||
float64Zero = pref.ValueOfFloat64(0)
|
||||
stringZero = pref.ValueOfString("")
|
||||
bytesZero = pref.ValueOfBytes(nil)
|
||||
)
|
||||
|
||||
func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
|
||||
defVal := func(fd pref.FieldDescriptor, zero pref.Value) pref.Value {
|
||||
if fd.Cardinality() == pref.Repeated {
|
||||
// Default isn't defined for repeated fields.
|
||||
return zero
|
||||
}
|
||||
return fd.Default()
|
||||
}
|
||||
switch fd.Kind() {
|
||||
case pref.BoolKind:
|
||||
if t.Kind() == reflect.Bool {
|
||||
return &boolConverter{t, defVal(fd, boolZero)}
|
||||
}
|
||||
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
|
||||
if t.Kind() == reflect.Int32 {
|
||||
return &int32Converter{t, defVal(fd, int32Zero)}
|
||||
}
|
||||
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
|
||||
if t.Kind() == reflect.Int64 {
|
||||
return &int64Converter{t, defVal(fd, int64Zero)}
|
||||
}
|
||||
case pref.Uint32Kind, pref.Fixed32Kind:
|
||||
if t.Kind() == reflect.Uint32 {
|
||||
return &uint32Converter{t, defVal(fd, uint32Zero)}
|
||||
}
|
||||
case pref.Uint64Kind, pref.Fixed64Kind:
|
||||
if t.Kind() == reflect.Uint64 {
|
||||
return &uint64Converter{t, defVal(fd, uint64Zero)}
|
||||
}
|
||||
case pref.FloatKind:
|
||||
if t.Kind() == reflect.Float32 {
|
||||
return &float32Converter{t, defVal(fd, float32Zero)}
|
||||
}
|
||||
case pref.DoubleKind:
|
||||
if t.Kind() == reflect.Float64 {
|
||||
return &float64Converter{t, defVal(fd, float64Zero)}
|
||||
}
|
||||
case pref.StringKind:
|
||||
if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
|
||||
return &stringConverter{t, defVal(fd, stringZero)}
|
||||
}
|
||||
case pref.BytesKind:
|
||||
if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
|
||||
return &bytesConverter{t, defVal(fd, bytesZero)}
|
||||
}
|
||||
case pref.EnumKind:
|
||||
// Handle enums, which must be a named int32 type.
|
||||
if t.Kind() == reflect.Int32 {
|
||||
return newEnumConverter(t, fd)
|
||||
}
|
||||
case pref.MessageKind, pref.GroupKind:
|
||||
return newMessageConverter(t)
|
||||
}
|
||||
panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
|
||||
}
|
||||
|
||||
type boolConverter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *boolConverter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfBool(v.Bool())
|
||||
}
|
||||
func (c *boolConverter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(v.Bool()).Convert(c.goType)
|
||||
}
|
||||
func (c *boolConverter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(bool)
|
||||
return ok
|
||||
}
|
||||
func (c *boolConverter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *boolConverter) New() pref.Value { return c.def }
|
||||
func (c *boolConverter) Zero() pref.Value { return c.def }
|
||||
|
||||
type int32Converter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *int32Converter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfInt32(int32(v.Int()))
|
||||
}
|
||||
func (c *int32Converter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(int32(v.Int())).Convert(c.goType)
|
||||
}
|
||||
func (c *int32Converter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(int32)
|
||||
return ok
|
||||
}
|
||||
func (c *int32Converter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *int32Converter) New() pref.Value { return c.def }
|
||||
func (c *int32Converter) Zero() pref.Value { return c.def }
|
||||
|
||||
type int64Converter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *int64Converter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfInt64(int64(v.Int()))
|
||||
}
|
||||
func (c *int64Converter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(int64(v.Int())).Convert(c.goType)
|
||||
}
|
||||
func (c *int64Converter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(int64)
|
||||
return ok
|
||||
}
|
||||
func (c *int64Converter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *int64Converter) New() pref.Value { return c.def }
|
||||
func (c *int64Converter) Zero() pref.Value { return c.def }
|
||||
|
||||
type uint32Converter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *uint32Converter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfUint32(uint32(v.Uint()))
|
||||
}
|
||||
func (c *uint32Converter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(uint32(v.Uint())).Convert(c.goType)
|
||||
}
|
||||
func (c *uint32Converter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(uint32)
|
||||
return ok
|
||||
}
|
||||
func (c *uint32Converter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *uint32Converter) New() pref.Value { return c.def }
|
||||
func (c *uint32Converter) Zero() pref.Value { return c.def }
|
||||
|
||||
type uint64Converter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *uint64Converter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfUint64(uint64(v.Uint()))
|
||||
}
|
||||
func (c *uint64Converter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(uint64(v.Uint())).Convert(c.goType)
|
||||
}
|
||||
func (c *uint64Converter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(uint64)
|
||||
return ok
|
||||
}
|
||||
func (c *uint64Converter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *uint64Converter) New() pref.Value { return c.def }
|
||||
func (c *uint64Converter) Zero() pref.Value { return c.def }
|
||||
|
||||
type float32Converter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *float32Converter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfFloat32(float32(v.Float()))
|
||||
}
|
||||
func (c *float32Converter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(float32(v.Float())).Convert(c.goType)
|
||||
}
|
||||
func (c *float32Converter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(float32)
|
||||
return ok
|
||||
}
|
||||
func (c *float32Converter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *float32Converter) New() pref.Value { return c.def }
|
||||
func (c *float32Converter) Zero() pref.Value { return c.def }
|
||||
|
||||
type float64Converter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *float64Converter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfFloat64(float64(v.Float()))
|
||||
}
|
||||
func (c *float64Converter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(float64(v.Float())).Convert(c.goType)
|
||||
}
|
||||
func (c *float64Converter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(float64)
|
||||
return ok
|
||||
}
|
||||
func (c *float64Converter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *float64Converter) New() pref.Value { return c.def }
|
||||
func (c *float64Converter) Zero() pref.Value { return c.def }
|
||||
|
||||
type stringConverter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *stringConverter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfString(v.Convert(stringType).String())
|
||||
}
|
||||
func (c *stringConverter) GoValueOf(v pref.Value) reflect.Value {
|
||||
// pref.Value.String never panics, so we go through an interface
|
||||
// conversion here to check the type.
|
||||
s := v.Interface().(string)
|
||||
if c.goType.Kind() == reflect.Slice && s == "" {
|
||||
return reflect.Zero(c.goType) // ensure empty string is []byte(nil)
|
||||
}
|
||||
return reflect.ValueOf(s).Convert(c.goType)
|
||||
}
|
||||
func (c *stringConverter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(string)
|
||||
return ok
|
||||
}
|
||||
func (c *stringConverter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *stringConverter) New() pref.Value { return c.def }
|
||||
func (c *stringConverter) Zero() pref.Value { return c.def }
|
||||
|
||||
type bytesConverter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func (c *bytesConverter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
if c.goType.Kind() == reflect.String && v.Len() == 0 {
|
||||
return pref.ValueOfBytes(nil) // ensure empty string is []byte(nil)
|
||||
}
|
||||
return pref.ValueOfBytes(v.Convert(bytesType).Bytes())
|
||||
}
|
||||
func (c *bytesConverter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(v.Bytes()).Convert(c.goType)
|
||||
}
|
||||
func (c *bytesConverter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().([]byte)
|
||||
return ok
|
||||
}
|
||||
func (c *bytesConverter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
func (c *bytesConverter) New() pref.Value { return c.def }
|
||||
func (c *bytesConverter) Zero() pref.Value { return c.def }
|
||||
|
||||
type enumConverter struct {
|
||||
goType reflect.Type
|
||||
def pref.Value
|
||||
}
|
||||
|
||||
func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter {
|
||||
var def pref.Value
|
||||
if fd.Cardinality() == pref.Repeated {
|
||||
def = pref.ValueOfEnum(fd.Enum().Values().Get(0).Number())
|
||||
} else {
|
||||
def = fd.Default()
|
||||
}
|
||||
return &enumConverter{goType, def}
|
||||
}
|
||||
|
||||
func (c *enumConverter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfEnum(pref.EnumNumber(v.Int()))
|
||||
}
|
||||
|
||||
func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return reflect.ValueOf(v.Enum()).Convert(c.goType)
|
||||
}
|
||||
|
||||
func (c *enumConverter) IsValidPB(v pref.Value) bool {
|
||||
_, ok := v.Interface().(pref.EnumNumber)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (c *enumConverter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
|
||||
func (c *enumConverter) New() pref.Value {
|
||||
return c.def
|
||||
}
|
||||
|
||||
func (c *enumConverter) Zero() pref.Value {
|
||||
return c.def
|
||||
}
|
||||
|
||||
type messageConverter struct {
|
||||
goType reflect.Type
|
||||
}
|
||||
|
||||
func newMessageConverter(goType reflect.Type) Converter {
|
||||
return &messageConverter{goType}
|
||||
}
|
||||
|
||||
func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
if m, ok := v.Interface().(pref.ProtoMessage); ok {
|
||||
return pref.ValueOfMessage(m.ProtoReflect())
|
||||
}
|
||||
return pref.ValueOfMessage(legacyWrapMessage(v))
|
||||
}
|
||||
|
||||
func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value {
|
||||
m := v.Message()
|
||||
var rv reflect.Value
|
||||
if u, ok := m.(unwrapper); ok {
|
||||
rv = reflect.ValueOf(u.protoUnwrap())
|
||||
} else {
|
||||
rv = reflect.ValueOf(m.Interface())
|
||||
}
|
||||
if rv.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType))
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
func (c *messageConverter) IsValidPB(v pref.Value) bool {
|
||||
m := v.Message()
|
||||
var rv reflect.Value
|
||||
if u, ok := m.(unwrapper); ok {
|
||||
rv = reflect.ValueOf(u.protoUnwrap())
|
||||
} else {
|
||||
rv = reflect.ValueOf(m.Interface())
|
||||
}
|
||||
return rv.Type() == c.goType
|
||||
}
|
||||
|
||||
func (c *messageConverter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
|
||||
func (c *messageConverter) New() pref.Value {
|
||||
return c.PBValueOf(reflect.New(c.goType.Elem()))
|
||||
}
|
||||
|
||||
func (c *messageConverter) Zero() pref.Value {
|
||||
return c.PBValueOf(reflect.Zero(c.goType))
|
||||
}
|
141
vendor/google.golang.org/protobuf/internal/impl/convert_list.go
generated
vendored
Normal file
141
vendor/google.golang.org/protobuf/internal/impl/convert_list.go
generated
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
func newListConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
|
||||
switch {
|
||||
case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Slice:
|
||||
return &listPtrConverter{t, newSingularConverter(t.Elem().Elem(), fd)}
|
||||
case t.Kind() == reflect.Slice:
|
||||
return &listConverter{t, newSingularConverter(t.Elem(), fd)}
|
||||
}
|
||||
panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
|
||||
}
|
||||
|
||||
type listConverter struct {
|
||||
goType reflect.Type
|
||||
c Converter
|
||||
}
|
||||
|
||||
func (c *listConverter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
pv := reflect.New(c.goType)
|
||||
pv.Elem().Set(v)
|
||||
return pref.ValueOfList(&listReflect{pv, c.c})
|
||||
}
|
||||
|
||||
func (c *listConverter) GoValueOf(v pref.Value) reflect.Value {
|
||||
rv := v.List().(*listReflect).v
|
||||
if rv.IsNil() {
|
||||
return reflect.Zero(c.goType)
|
||||
}
|
||||
return rv.Elem()
|
||||
}
|
||||
|
||||
func (c *listConverter) IsValidPB(v pref.Value) bool {
|
||||
list, ok := v.Interface().(*listReflect)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return list.v.Type().Elem() == c.goType && list.IsValid()
|
||||
}
|
||||
|
||||
func (c *listConverter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
|
||||
func (c *listConverter) New() pref.Value {
|
||||
return pref.ValueOfList(&listReflect{reflect.New(c.goType), c.c})
|
||||
}
|
||||
|
||||
func (c *listConverter) Zero() pref.Value {
|
||||
return pref.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c})
|
||||
}
|
||||
|
||||
type listPtrConverter struct {
|
||||
goType reflect.Type
|
||||
c Converter
|
||||
}
|
||||
|
||||
func (c *listPtrConverter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfList(&listReflect{v, c.c})
|
||||
}
|
||||
|
||||
func (c *listPtrConverter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return v.List().(*listReflect).v
|
||||
}
|
||||
|
||||
func (c *listPtrConverter) IsValidPB(v pref.Value) bool {
|
||||
list, ok := v.Interface().(*listReflect)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return list.v.Type() == c.goType
|
||||
}
|
||||
|
||||
func (c *listPtrConverter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
|
||||
func (c *listPtrConverter) New() pref.Value {
|
||||
return c.PBValueOf(reflect.New(c.goType.Elem()))
|
||||
}
|
||||
|
||||
func (c *listPtrConverter) Zero() pref.Value {
|
||||
return c.PBValueOf(reflect.Zero(c.goType))
|
||||
}
|
||||
|
||||
type listReflect struct {
|
||||
v reflect.Value // *[]T
|
||||
conv Converter
|
||||
}
|
||||
|
||||
func (ls *listReflect) Len() int {
|
||||
if ls.v.IsNil() {
|
||||
return 0
|
||||
}
|
||||
return ls.v.Elem().Len()
|
||||
}
|
||||
func (ls *listReflect) Get(i int) pref.Value {
|
||||
return ls.conv.PBValueOf(ls.v.Elem().Index(i))
|
||||
}
|
||||
func (ls *listReflect) Set(i int, v pref.Value) {
|
||||
ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v))
|
||||
}
|
||||
func (ls *listReflect) Append(v pref.Value) {
|
||||
ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v)))
|
||||
}
|
||||
func (ls *listReflect) AppendMutable() pref.Value {
|
||||
if _, ok := ls.conv.(*messageConverter); !ok {
|
||||
panic("invalid AppendMutable on list with non-message type")
|
||||
}
|
||||
v := ls.NewElement()
|
||||
ls.Append(v)
|
||||
return v
|
||||
}
|
||||
func (ls *listReflect) Truncate(i int) {
|
||||
ls.v.Elem().Set(ls.v.Elem().Slice(0, i))
|
||||
}
|
||||
func (ls *listReflect) NewElement() pref.Value {
|
||||
return ls.conv.New()
|
||||
}
|
||||
func (ls *listReflect) IsValid() bool {
|
||||
return !ls.v.IsNil()
|
||||
}
|
||||
func (ls *listReflect) protoUnwrap() interface{} {
|
||||
return ls.v.Interface()
|
||||
}
|
121
vendor/google.golang.org/protobuf/internal/impl/convert_map.go
generated
vendored
Normal file
121
vendor/google.golang.org/protobuf/internal/impl/convert_map.go
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
type mapConverter struct {
|
||||
goType reflect.Type
|
||||
keyConv, valConv Converter
|
||||
}
|
||||
|
||||
func newMapConverter(t reflect.Type, fd pref.FieldDescriptor) *mapConverter {
|
||||
if t.Kind() != reflect.Map {
|
||||
panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
|
||||
}
|
||||
return &mapConverter{
|
||||
goType: t,
|
||||
keyConv: newSingularConverter(t.Key(), fd.MapKey()),
|
||||
valConv: newSingularConverter(t.Elem(), fd.MapValue()),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *mapConverter) PBValueOf(v reflect.Value) pref.Value {
|
||||
if v.Type() != c.goType {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
|
||||
}
|
||||
return pref.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv})
|
||||
}
|
||||
|
||||
func (c *mapConverter) GoValueOf(v pref.Value) reflect.Value {
|
||||
return v.Map().(*mapReflect).v
|
||||
}
|
||||
|
||||
func (c *mapConverter) IsValidPB(v pref.Value) bool {
|
||||
mapv, ok := v.Interface().(*mapReflect)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return mapv.v.Type() == c.goType && mapv.IsValid()
|
||||
}
|
||||
|
||||
func (c *mapConverter) IsValidGo(v reflect.Value) bool {
|
||||
return v.Type() == c.goType
|
||||
}
|
||||
|
||||
func (c *mapConverter) New() pref.Value {
|
||||
return c.PBValueOf(reflect.MakeMap(c.goType))
|
||||
}
|
||||
|
||||
func (c *mapConverter) Zero() pref.Value {
|
||||
return c.PBValueOf(reflect.Zero(c.goType))
|
||||
}
|
||||
|
||||
type mapReflect struct {
|
||||
v reflect.Value // map[K]V
|
||||
keyConv Converter
|
||||
valConv Converter
|
||||
}
|
||||
|
||||
func (ms *mapReflect) Len() int {
|
||||
return ms.v.Len()
|
||||
}
|
||||
func (ms *mapReflect) Has(k pref.MapKey) bool {
|
||||
rk := ms.keyConv.GoValueOf(k.Value())
|
||||
rv := ms.v.MapIndex(rk)
|
||||
return rv.IsValid()
|
||||
}
|
||||
func (ms *mapReflect) Get(k pref.MapKey) pref.Value {
|
||||
rk := ms.keyConv.GoValueOf(k.Value())
|
||||
rv := ms.v.MapIndex(rk)
|
||||
if !rv.IsValid() {
|
||||
return pref.Value{}
|
||||
}
|
||||
return ms.valConv.PBValueOf(rv)
|
||||
}
|
||||
func (ms *mapReflect) Set(k pref.MapKey, v pref.Value) {
|
||||
rk := ms.keyConv.GoValueOf(k.Value())
|
||||
rv := ms.valConv.GoValueOf(v)
|
||||
ms.v.SetMapIndex(rk, rv)
|
||||
}
|
||||
func (ms *mapReflect) Clear(k pref.MapKey) {
|
||||
rk := ms.keyConv.GoValueOf(k.Value())
|
||||
ms.v.SetMapIndex(rk, reflect.Value{})
|
||||
}
|
||||
func (ms *mapReflect) Mutable(k pref.MapKey) pref.Value {
|
||||
if _, ok := ms.valConv.(*messageConverter); !ok {
|
||||
panic("invalid Mutable on map with non-message value type")
|
||||
}
|
||||
v := ms.Get(k)
|
||||
if !v.IsValid() {
|
||||
v = ms.NewValue()
|
||||
ms.Set(k, v)
|
||||
}
|
||||
return v
|
||||
}
|
||||
func (ms *mapReflect) Range(f func(pref.MapKey, pref.Value) bool) {
|
||||
iter := mapRange(ms.v)
|
||||
for iter.Next() {
|
||||
k := ms.keyConv.PBValueOf(iter.Key()).MapKey()
|
||||
v := ms.valConv.PBValueOf(iter.Value())
|
||||
if !f(k, v) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
func (ms *mapReflect) NewValue() pref.Value {
|
||||
return ms.valConv.New()
|
||||
}
|
||||
func (ms *mapReflect) IsValid() bool {
|
||||
return !ms.v.IsNil()
|
||||
}
|
||||
func (ms *mapReflect) protoUnwrap() interface{} {
|
||||
return ms.v.Interface()
|
||||
}
|
274
vendor/google.golang.org/protobuf/internal/impl/decode.go
generated
vendored
Normal file
274
vendor/google.golang.org/protobuf/internal/impl/decode.go
generated
vendored
Normal file
|
@ -0,0 +1,274 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"math/bits"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
"google.golang.org/protobuf/internal/flags"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
preg "google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/runtime/protoiface"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
type unmarshalOptions struct {
|
||||
flags protoiface.UnmarshalInputFlags
|
||||
resolver interface {
|
||||
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
|
||||
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (o unmarshalOptions) Options() proto.UnmarshalOptions {
|
||||
return proto.UnmarshalOptions{
|
||||
Merge: true,
|
||||
AllowPartial: true,
|
||||
DiscardUnknown: o.DiscardUnknown(),
|
||||
Resolver: o.resolver,
|
||||
}
|
||||
}
|
||||
|
||||
func (o unmarshalOptions) DiscardUnknown() bool { return o.flags&piface.UnmarshalDiscardUnknown != 0 }
|
||||
|
||||
func (o unmarshalOptions) IsDefault() bool {
|
||||
return o.flags == 0 && o.resolver == preg.GlobalTypes
|
||||
}
|
||||
|
||||
var lazyUnmarshalOptions = unmarshalOptions{
|
||||
resolver: preg.GlobalTypes,
|
||||
}
|
||||
|
||||
type unmarshalOutput struct {
|
||||
n int // number of bytes consumed
|
||||
initialized bool
|
||||
}
|
||||
|
||||
// unmarshal is protoreflect.Methods.Unmarshal.
|
||||
func (mi *MessageInfo) unmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) {
|
||||
var p pointer
|
||||
if ms, ok := in.Message.(*messageState); ok {
|
||||
p = ms.pointer()
|
||||
} else {
|
||||
p = in.Message.(*messageReflectWrapper).pointer()
|
||||
}
|
||||
out, err := mi.unmarshalPointer(in.Buf, p, 0, unmarshalOptions{
|
||||
flags: in.Flags,
|
||||
resolver: in.Resolver,
|
||||
})
|
||||
var flags piface.UnmarshalOutputFlags
|
||||
if out.initialized {
|
||||
flags |= piface.UnmarshalInitialized
|
||||
}
|
||||
return piface.UnmarshalOutput{
|
||||
Flags: flags,
|
||||
}, err
|
||||
}
|
||||
|
||||
// errUnknown is returned during unmarshaling to indicate a parse error that
|
||||
// should result in a field being placed in the unknown fields section (for example,
|
||||
// when the wire type doesn't match) as opposed to the entire unmarshal operation
|
||||
// failing (for example, when a field extends past the available input).
|
||||
//
|
||||
// This is a sentinel error which should never be visible to the user.
|
||||
var errUnknown = errors.New("unknown")
|
||||
|
||||
func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
mi.init()
|
||||
if flags.ProtoLegacy && mi.isMessageSet {
|
||||
return unmarshalMessageSet(mi, b, p, opts)
|
||||
}
|
||||
initialized := true
|
||||
var requiredMask uint64
|
||||
var exts *map[int32]ExtensionField
|
||||
start := len(b)
|
||||
for len(b) > 0 {
|
||||
// Parse the tag (field number and wire type).
|
||||
var tag uint64
|
||||
if b[0] < 0x80 {
|
||||
tag = uint64(b[0])
|
||||
b = b[1:]
|
||||
} else if len(b) >= 2 && b[1] < 128 {
|
||||
tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
|
||||
b = b[2:]
|
||||
} else {
|
||||
var n int
|
||||
tag, n = protowire.ConsumeVarint(b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
var num protowire.Number
|
||||
if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) {
|
||||
return out, errors.New("invalid field number")
|
||||
} else {
|
||||
num = protowire.Number(n)
|
||||
}
|
||||
wtyp := protowire.Type(tag & 7)
|
||||
|
||||
if wtyp == protowire.EndGroupType {
|
||||
if num != groupTag {
|
||||
return out, errors.New("mismatching end group marker")
|
||||
}
|
||||
groupTag = 0
|
||||
break
|
||||
}
|
||||
|
||||
var f *coderFieldInfo
|
||||
if int(num) < len(mi.denseCoderFields) {
|
||||
f = mi.denseCoderFields[num]
|
||||
} else {
|
||||
f = mi.coderFields[num]
|
||||
}
|
||||
var n int
|
||||
err := errUnknown
|
||||
switch {
|
||||
case f != nil:
|
||||
if f.funcs.unmarshal == nil {
|
||||
break
|
||||
}
|
||||
var o unmarshalOutput
|
||||
o, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, f, opts)
|
||||
n = o.n
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
requiredMask |= f.validation.requiredBit
|
||||
if f.funcs.isInit != nil && !o.initialized {
|
||||
initialized = false
|
||||
}
|
||||
default:
|
||||
// Possible extension.
|
||||
if exts == nil && mi.extensionOffset.IsValid() {
|
||||
exts = p.Apply(mi.extensionOffset).Extensions()
|
||||
if *exts == nil {
|
||||
*exts = make(map[int32]ExtensionField)
|
||||
}
|
||||
}
|
||||
if exts == nil {
|
||||
break
|
||||
}
|
||||
var o unmarshalOutput
|
||||
o, err = mi.unmarshalExtension(b, num, wtyp, *exts, opts)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
n = o.n
|
||||
if !o.initialized {
|
||||
initialized = false
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if err != errUnknown {
|
||||
return out, err
|
||||
}
|
||||
n = protowire.ConsumeFieldValue(num, wtyp, b)
|
||||
if n < 0 {
|
||||
return out, protowire.ParseError(n)
|
||||
}
|
||||
if !opts.DiscardUnknown() && mi.unknownOffset.IsValid() {
|
||||
u := p.Apply(mi.unknownOffset).Bytes()
|
||||
*u = protowire.AppendTag(*u, num, wtyp)
|
||||
*u = append(*u, b[:n]...)
|
||||
}
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
if groupTag != 0 {
|
||||
return out, errors.New("missing end group marker")
|
||||
}
|
||||
if mi.numRequiredFields > 0 && bits.OnesCount64(requiredMask) != int(mi.numRequiredFields) {
|
||||
initialized = false
|
||||
}
|
||||
if initialized {
|
||||
out.initialized = true
|
||||
}
|
||||
out.n = start - len(b)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) unmarshalExtension(b []byte, num protowire.Number, wtyp protowire.Type, exts map[int32]ExtensionField, opts unmarshalOptions) (out unmarshalOutput, err error) {
|
||||
x := exts[int32(num)]
|
||||
xt := x.Type()
|
||||
if xt == nil {
|
||||
var err error
|
||||
xt, err = opts.resolver.FindExtensionByNumber(mi.Desc.FullName(), num)
|
||||
if err != nil {
|
||||
if err == preg.NotFound {
|
||||
return out, errUnknown
|
||||
}
|
||||
return out, errors.New("%v: unable to resolve extension %v: %v", mi.Desc.FullName(), num, err)
|
||||
}
|
||||
}
|
||||
xi := getExtensionFieldInfo(xt)
|
||||
if xi.funcs.unmarshal == nil {
|
||||
return out, errUnknown
|
||||
}
|
||||
if flags.LazyUnmarshalExtensions {
|
||||
if opts.IsDefault() && x.canLazy(xt) {
|
||||
out, valid := skipExtension(b, xi, num, wtyp, opts)
|
||||
switch valid {
|
||||
case ValidationValid:
|
||||
if out.initialized {
|
||||
x.appendLazyBytes(xt, xi, num, wtyp, b[:out.n])
|
||||
exts[int32(num)] = x
|
||||
return out, nil
|
||||
}
|
||||
case ValidationInvalid:
|
||||
return out, errors.New("invalid wire format")
|
||||
case ValidationUnknown:
|
||||
}
|
||||
}
|
||||
}
|
||||
ival := x.Value()
|
||||
if !ival.IsValid() && xi.unmarshalNeedsValue {
|
||||
// Create a new message, list, or map value to fill in.
|
||||
// For enums, create a prototype value to let the unmarshal func know the
|
||||
// concrete type.
|
||||
ival = xt.New()
|
||||
}
|
||||
v, out, err := xi.funcs.unmarshal(b, ival, num, wtyp, opts)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
if xi.funcs.isInit == nil {
|
||||
out.initialized = true
|
||||
}
|
||||
x.Set(xt, v)
|
||||
exts[int32(num)] = x
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func skipExtension(b []byte, xi *extensionFieldInfo, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, _ ValidationStatus) {
|
||||
if xi.validation.mi == nil {
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
xi.validation.mi.init()
|
||||
switch xi.validation.typ {
|
||||
case validationTypeMessage:
|
||||
if wtyp != protowire.BytesType {
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
v, n := protowire.ConsumeBytes(b)
|
||||
if n < 0 {
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
out, st := xi.validation.mi.validate(v, 0, opts)
|
||||
out.n = n
|
||||
return out, st
|
||||
case validationTypeGroup:
|
||||
if wtyp != protowire.StartGroupType {
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
out, st := xi.validation.mi.validate(b, num, opts)
|
||||
return out, st
|
||||
default:
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
}
|
199
vendor/google.golang.org/protobuf/internal/impl/encode.go
generated
vendored
Normal file
199
vendor/google.golang.org/protobuf/internal/impl/encode.go
generated
vendored
Normal file
|
@ -0,0 +1,199 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
|
||||
"google.golang.org/protobuf/internal/flags"
|
||||
proto "google.golang.org/protobuf/proto"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
type marshalOptions struct {
|
||||
flags piface.MarshalInputFlags
|
||||
}
|
||||
|
||||
func (o marshalOptions) Options() proto.MarshalOptions {
|
||||
return proto.MarshalOptions{
|
||||
AllowPartial: true,
|
||||
Deterministic: o.Deterministic(),
|
||||
UseCachedSize: o.UseCachedSize(),
|
||||
}
|
||||
}
|
||||
|
||||
func (o marshalOptions) Deterministic() bool { return o.flags&piface.MarshalDeterministic != 0 }
|
||||
func (o marshalOptions) UseCachedSize() bool { return o.flags&piface.MarshalUseCachedSize != 0 }
|
||||
|
||||
// size is protoreflect.Methods.Size.
|
||||
func (mi *MessageInfo) size(in piface.SizeInput) piface.SizeOutput {
|
||||
var p pointer
|
||||
if ms, ok := in.Message.(*messageState); ok {
|
||||
p = ms.pointer()
|
||||
} else {
|
||||
p = in.Message.(*messageReflectWrapper).pointer()
|
||||
}
|
||||
size := mi.sizePointer(p, marshalOptions{
|
||||
flags: in.Flags,
|
||||
})
|
||||
return piface.SizeOutput{Size: size}
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) sizePointer(p pointer, opts marshalOptions) (size int) {
|
||||
mi.init()
|
||||
if p.IsNil() {
|
||||
return 0
|
||||
}
|
||||
if opts.UseCachedSize() && mi.sizecacheOffset.IsValid() {
|
||||
if size := atomic.LoadInt32(p.Apply(mi.sizecacheOffset).Int32()); size >= 0 {
|
||||
return int(size)
|
||||
}
|
||||
}
|
||||
return mi.sizePointerSlow(p, opts)
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int) {
|
||||
if flags.ProtoLegacy && mi.isMessageSet {
|
||||
size = sizeMessageSet(mi, p, opts)
|
||||
if mi.sizecacheOffset.IsValid() {
|
||||
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size))
|
||||
}
|
||||
return size
|
||||
}
|
||||
if mi.extensionOffset.IsValid() {
|
||||
e := p.Apply(mi.extensionOffset).Extensions()
|
||||
size += mi.sizeExtensions(e, opts)
|
||||
}
|
||||
for _, f := range mi.orderedCoderFields {
|
||||
if f.funcs.size == nil {
|
||||
continue
|
||||
}
|
||||
fptr := p.Apply(f.offset)
|
||||
if f.isPointer && fptr.Elem().IsNil() {
|
||||
continue
|
||||
}
|
||||
size += f.funcs.size(fptr, f, opts)
|
||||
}
|
||||
if mi.unknownOffset.IsValid() {
|
||||
u := *p.Apply(mi.unknownOffset).Bytes()
|
||||
size += len(u)
|
||||
}
|
||||
if mi.sizecacheOffset.IsValid() {
|
||||
if size > math.MaxInt32 {
|
||||
// The size is too large for the int32 sizecache field.
|
||||
// We will need to recompute the size when encoding;
|
||||
// unfortunately expensive, but better than invalid output.
|
||||
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), -1)
|
||||
} else {
|
||||
atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size))
|
||||
}
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
// marshal is protoreflect.Methods.Marshal.
|
||||
func (mi *MessageInfo) marshal(in piface.MarshalInput) (out piface.MarshalOutput, err error) {
|
||||
var p pointer
|
||||
if ms, ok := in.Message.(*messageState); ok {
|
||||
p = ms.pointer()
|
||||
} else {
|
||||
p = in.Message.(*messageReflectWrapper).pointer()
|
||||
}
|
||||
b, err := mi.marshalAppendPointer(in.Buf, p, marshalOptions{
|
||||
flags: in.Flags,
|
||||
})
|
||||
return piface.MarshalOutput{Buf: b}, err
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOptions) ([]byte, error) {
|
||||
mi.init()
|
||||
if p.IsNil() {
|
||||
return b, nil
|
||||
}
|
||||
if flags.ProtoLegacy && mi.isMessageSet {
|
||||
return marshalMessageSet(mi, b, p, opts)
|
||||
}
|
||||
var err error
|
||||
// The old marshaler encodes extensions at beginning.
|
||||
if mi.extensionOffset.IsValid() {
|
||||
e := p.Apply(mi.extensionOffset).Extensions()
|
||||
// TODO: Special handling for MessageSet?
|
||||
b, err = mi.appendExtensions(b, e, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
for _, f := range mi.orderedCoderFields {
|
||||
if f.funcs.marshal == nil {
|
||||
continue
|
||||
}
|
||||
fptr := p.Apply(f.offset)
|
||||
if f.isPointer && fptr.Elem().IsNil() {
|
||||
continue
|
||||
}
|
||||
b, err = f.funcs.marshal(b, fptr, f, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
if mi.unknownOffset.IsValid() && !mi.isMessageSet {
|
||||
u := *p.Apply(mi.unknownOffset).Bytes()
|
||||
b = append(b, u...)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marshalOptions) (n int) {
|
||||
if ext == nil {
|
||||
return 0
|
||||
}
|
||||
for _, x := range *ext {
|
||||
xi := getExtensionFieldInfo(x.Type())
|
||||
if xi.funcs.size == nil {
|
||||
continue
|
||||
}
|
||||
n += xi.funcs.size(x.Value(), xi.tagsize, opts)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) appendExtensions(b []byte, ext *map[int32]ExtensionField, opts marshalOptions) ([]byte, error) {
|
||||
if ext == nil {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
switch len(*ext) {
|
||||
case 0:
|
||||
return b, nil
|
||||
case 1:
|
||||
// Fast-path for one extension: Don't bother sorting the keys.
|
||||
var err error
|
||||
for _, x := range *ext {
|
||||
xi := getExtensionFieldInfo(x.Type())
|
||||
b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
|
||||
}
|
||||
return b, err
|
||||
default:
|
||||
// Sort the keys to provide a deterministic encoding.
|
||||
// Not sure this is required, but the old code does it.
|
||||
keys := make([]int, 0, len(*ext))
|
||||
for k := range *ext {
|
||||
keys = append(keys, int(k))
|
||||
}
|
||||
sort.Ints(keys)
|
||||
var err error
|
||||
for _, k := range keys {
|
||||
x := (*ext)[int32(k)]
|
||||
xi := getExtensionFieldInfo(x.Type())
|
||||
b, err = xi.funcs.marshal(b, x.Value(), xi.wiretag, opts)
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
}
|
21
vendor/google.golang.org/protobuf/internal/impl/enum.go
generated
vendored
Normal file
21
vendor/google.golang.org/protobuf/internal/impl/enum.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
type EnumInfo struct {
|
||||
GoReflectType reflect.Type // int32 kind
|
||||
Desc pref.EnumDescriptor
|
||||
}
|
||||
|
||||
func (t *EnumInfo) New(n pref.EnumNumber) pref.Enum {
|
||||
return reflect.ValueOf(n).Convert(t.GoReflectType).Interface().(pref.Enum)
|
||||
}
|
||||
func (t *EnumInfo) Descriptor() pref.EnumDescriptor { return t.Desc }
|
156
vendor/google.golang.org/protobuf/internal/impl/extension.go
generated
vendored
Normal file
156
vendor/google.golang.org/protobuf/internal/impl/extension.go
generated
vendored
Normal file
|
@ -0,0 +1,156 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
// ExtensionInfo implements ExtensionType.
|
||||
//
|
||||
// This type contains a number of exported fields for legacy compatibility.
|
||||
// The only non-deprecated use of this type is through the methods of the
|
||||
// ExtensionType interface.
|
||||
type ExtensionInfo struct {
|
||||
// An ExtensionInfo may exist in several stages of initialization.
|
||||
//
|
||||
// extensionInfoUninitialized: Some or all of the legacy exported
|
||||
// fields may be set, but none of the unexported fields have been
|
||||
// initialized. This is the starting state for an ExtensionInfo
|
||||
// in legacy generated code.
|
||||
//
|
||||
// extensionInfoDescInit: The desc field is set, but other unexported fields
|
||||
// may not be initialized. Legacy exported fields may or may not be set.
|
||||
// This is the starting state for an ExtensionInfo in newly generated code.
|
||||
//
|
||||
// extensionInfoFullInit: The ExtensionInfo is fully initialized.
|
||||
// This state is only entered after lazy initialization is complete.
|
||||
init uint32
|
||||
mu sync.Mutex
|
||||
|
||||
goType reflect.Type
|
||||
desc extensionTypeDescriptor
|
||||
conv Converter
|
||||
info *extensionFieldInfo // for fast-path method implementations
|
||||
|
||||
// ExtendedType is a typed nil-pointer to the parent message type that
|
||||
// is being extended. It is possible for this to be unpopulated in v2
|
||||
// since the message may no longer implement the MessageV1 interface.
|
||||
//
|
||||
// Deprecated: Use the ExtendedType method instead.
|
||||
ExtendedType piface.MessageV1
|
||||
|
||||
// ExtensionType is the zero value of the extension type.
|
||||
//
|
||||
// For historical reasons, reflect.TypeOf(ExtensionType) and the
|
||||
// type returned by InterfaceOf may not be identical.
|
||||
//
|
||||
// Deprecated: Use InterfaceOf(xt.Zero()) instead.
|
||||
ExtensionType interface{}
|
||||
|
||||
// Field is the field number of the extension.
|
||||
//
|
||||
// Deprecated: Use the Descriptor().Number method instead.
|
||||
Field int32
|
||||
|
||||
// Name is the fully qualified name of extension.
|
||||
//
|
||||
// Deprecated: Use the Descriptor().FullName method instead.
|
||||
Name string
|
||||
|
||||
// Tag is the protobuf struct tag used in the v1 API.
|
||||
//
|
||||
// Deprecated: Do not use.
|
||||
Tag string
|
||||
|
||||
// Filename is the proto filename in which the extension is defined.
|
||||
//
|
||||
// Deprecated: Use Descriptor().ParentFile().Path() instead.
|
||||
Filename string
|
||||
}
|
||||
|
||||
// Stages of initialization: See the ExtensionInfo.init field.
|
||||
const (
|
||||
extensionInfoUninitialized = 0
|
||||
extensionInfoDescInit = 1
|
||||
extensionInfoFullInit = 2
|
||||
)
|
||||
|
||||
func InitExtensionInfo(xi *ExtensionInfo, xd pref.ExtensionDescriptor, goType reflect.Type) {
|
||||
xi.goType = goType
|
||||
xi.desc = extensionTypeDescriptor{xd, xi}
|
||||
xi.init = extensionInfoDescInit
|
||||
}
|
||||
|
||||
func (xi *ExtensionInfo) New() pref.Value {
|
||||
return xi.lazyInit().New()
|
||||
}
|
||||
func (xi *ExtensionInfo) Zero() pref.Value {
|
||||
return xi.lazyInit().Zero()
|
||||
}
|
||||
func (xi *ExtensionInfo) ValueOf(v interface{}) pref.Value {
|
||||
return xi.lazyInit().PBValueOf(reflect.ValueOf(v))
|
||||
}
|
||||
func (xi *ExtensionInfo) InterfaceOf(v pref.Value) interface{} {
|
||||
return xi.lazyInit().GoValueOf(v).Interface()
|
||||
}
|
||||
func (xi *ExtensionInfo) IsValidValue(v pref.Value) bool {
|
||||
return xi.lazyInit().IsValidPB(v)
|
||||
}
|
||||
func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool {
|
||||
return xi.lazyInit().IsValidGo(reflect.ValueOf(v))
|
||||
}
|
||||
func (xi *ExtensionInfo) TypeDescriptor() pref.ExtensionTypeDescriptor {
|
||||
if atomic.LoadUint32(&xi.init) < extensionInfoDescInit {
|
||||
xi.lazyInitSlow()
|
||||
}
|
||||
return &xi.desc
|
||||
}
|
||||
|
||||
func (xi *ExtensionInfo) lazyInit() Converter {
|
||||
if atomic.LoadUint32(&xi.init) < extensionInfoFullInit {
|
||||
xi.lazyInitSlow()
|
||||
}
|
||||
return xi.conv
|
||||
}
|
||||
|
||||
func (xi *ExtensionInfo) lazyInitSlow() {
|
||||
xi.mu.Lock()
|
||||
defer xi.mu.Unlock()
|
||||
|
||||
if xi.init == extensionInfoFullInit {
|
||||
return
|
||||
}
|
||||
defer atomic.StoreUint32(&xi.init, extensionInfoFullInit)
|
||||
|
||||
if xi.desc.ExtensionDescriptor == nil {
|
||||
xi.initFromLegacy()
|
||||
}
|
||||
if !xi.desc.ExtensionDescriptor.IsPlaceholder() {
|
||||
if xi.ExtensionType == nil {
|
||||
xi.initToLegacy()
|
||||
}
|
||||
xi.conv = NewConverter(xi.goType, xi.desc.ExtensionDescriptor)
|
||||
xi.info = makeExtensionFieldInfo(xi.desc.ExtensionDescriptor)
|
||||
xi.info.validation = newValidationInfo(xi.desc.ExtensionDescriptor, xi.goType)
|
||||
}
|
||||
}
|
||||
|
||||
type extensionTypeDescriptor struct {
|
||||
pref.ExtensionDescriptor
|
||||
xi *ExtensionInfo
|
||||
}
|
||||
|
||||
func (xtd *extensionTypeDescriptor) Type() pref.ExtensionType {
|
||||
return xtd.xi
|
||||
}
|
||||
func (xtd *extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor {
|
||||
return xtd.ExtensionDescriptor
|
||||
}
|
219
vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go
generated
vendored
Normal file
219
vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go
generated
vendored
Normal file
|
@ -0,0 +1,219 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/protobuf/internal/filedesc"
|
||||
"google.golang.org/protobuf/internal/strs"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
// legacyEnumName returns the name of enums used in legacy code.
|
||||
// It is neither the protobuf full name nor the qualified Go name,
|
||||
// but rather an odd hybrid of both.
|
||||
func legacyEnumName(ed pref.EnumDescriptor) string {
|
||||
var protoPkg string
|
||||
enumName := string(ed.FullName())
|
||||
if fd := ed.ParentFile(); fd != nil {
|
||||
protoPkg = string(fd.Package())
|
||||
enumName = strings.TrimPrefix(enumName, protoPkg+".")
|
||||
}
|
||||
if protoPkg == "" {
|
||||
return strs.GoCamelCase(enumName)
|
||||
}
|
||||
return protoPkg + "." + strs.GoCamelCase(enumName)
|
||||
}
|
||||
|
||||
// legacyWrapEnum wraps v as a protoreflect.Enum,
|
||||
// where v must be a int32 kind and not implement the v2 API already.
|
||||
func legacyWrapEnum(v reflect.Value) pref.Enum {
|
||||
et := legacyLoadEnumType(v.Type())
|
||||
return et.New(pref.EnumNumber(v.Int()))
|
||||
}
|
||||
|
||||
var legacyEnumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType
|
||||
|
||||
// legacyLoadEnumType dynamically loads a protoreflect.EnumType for t,
|
||||
// where t must be an int32 kind and not implement the v2 API already.
|
||||
func legacyLoadEnumType(t reflect.Type) pref.EnumType {
|
||||
// Fast-path: check if a EnumType is cached for this concrete type.
|
||||
if et, ok := legacyEnumTypeCache.Load(t); ok {
|
||||
return et.(pref.EnumType)
|
||||
}
|
||||
|
||||
// Slow-path: derive enum descriptor and initialize EnumType.
|
||||
var et pref.EnumType
|
||||
ed := LegacyLoadEnumDesc(t)
|
||||
et = &legacyEnumType{
|
||||
desc: ed,
|
||||
goType: t,
|
||||
}
|
||||
if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok {
|
||||
return et.(pref.EnumType)
|
||||
}
|
||||
return et
|
||||
}
|
||||
|
||||
type legacyEnumType struct {
|
||||
desc pref.EnumDescriptor
|
||||
goType reflect.Type
|
||||
m sync.Map // map[protoreflect.EnumNumber]proto.Enum
|
||||
}
|
||||
|
||||
func (t *legacyEnumType) New(n pref.EnumNumber) pref.Enum {
|
||||
if e, ok := t.m.Load(n); ok {
|
||||
return e.(pref.Enum)
|
||||
}
|
||||
e := &legacyEnumWrapper{num: n, pbTyp: t, goTyp: t.goType}
|
||||
t.m.Store(n, e)
|
||||
return e
|
||||
}
|
||||
func (t *legacyEnumType) Descriptor() pref.EnumDescriptor {
|
||||
return t.desc
|
||||
}
|
||||
|
||||
type legacyEnumWrapper struct {
|
||||
num pref.EnumNumber
|
||||
pbTyp pref.EnumType
|
||||
goTyp reflect.Type
|
||||
}
|
||||
|
||||
func (e *legacyEnumWrapper) Descriptor() pref.EnumDescriptor {
|
||||
return e.pbTyp.Descriptor()
|
||||
}
|
||||
func (e *legacyEnumWrapper) Type() pref.EnumType {
|
||||
return e.pbTyp
|
||||
}
|
||||
func (e *legacyEnumWrapper) Number() pref.EnumNumber {
|
||||
return e.num
|
||||
}
|
||||
func (e *legacyEnumWrapper) ProtoReflect() pref.Enum {
|
||||
return e
|
||||
}
|
||||
func (e *legacyEnumWrapper) protoUnwrap() interface{} {
|
||||
v := reflect.New(e.goTyp).Elem()
|
||||
v.SetInt(int64(e.num))
|
||||
return v.Interface()
|
||||
}
|
||||
|
||||
var (
|
||||
_ pref.Enum = (*legacyEnumWrapper)(nil)
|
||||
_ unwrapper = (*legacyEnumWrapper)(nil)
|
||||
)
|
||||
|
||||
var legacyEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor
|
||||
|
||||
// LegacyLoadEnumDesc returns an EnumDescriptor derived from the Go type,
|
||||
// which must be an int32 kind and not implement the v2 API already.
|
||||
//
|
||||
// This is exported for testing purposes.
|
||||
func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
|
||||
// Fast-path: check if an EnumDescriptor is cached for this concrete type.
|
||||
if ed, ok := legacyEnumDescCache.Load(t); ok {
|
||||
return ed.(pref.EnumDescriptor)
|
||||
}
|
||||
|
||||
// Slow-path: initialize EnumDescriptor from the raw descriptor.
|
||||
ev := reflect.Zero(t).Interface()
|
||||
if _, ok := ev.(pref.Enum); ok {
|
||||
panic(fmt.Sprintf("%v already implements proto.Enum", t))
|
||||
}
|
||||
edV1, ok := ev.(enumV1)
|
||||
if !ok {
|
||||
return aberrantLoadEnumDesc(t)
|
||||
}
|
||||
b, idxs := edV1.EnumDescriptor()
|
||||
|
||||
var ed pref.EnumDescriptor
|
||||
if len(idxs) == 1 {
|
||||
ed = legacyLoadFileDesc(b).Enums().Get(idxs[0])
|
||||
} else {
|
||||
md := legacyLoadFileDesc(b).Messages().Get(idxs[0])
|
||||
for _, i := range idxs[1 : len(idxs)-1] {
|
||||
md = md.Messages().Get(i)
|
||||
}
|
||||
ed = md.Enums().Get(idxs[len(idxs)-1])
|
||||
}
|
||||
if ed, ok := legacyEnumDescCache.LoadOrStore(t, ed); ok {
|
||||
return ed.(protoreflect.EnumDescriptor)
|
||||
}
|
||||
return ed
|
||||
}
|
||||
|
||||
var aberrantEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor
|
||||
|
||||
// aberrantLoadEnumDesc returns an EnumDescriptor derived from the Go type,
|
||||
// which must not implement protoreflect.Enum or enumV1.
|
||||
//
|
||||
// If the type does not implement enumV1, then there is no reliable
|
||||
// way to derive the original protobuf type information.
|
||||
// We are unable to use the global enum registry since it is
|
||||
// unfortunately keyed by the protobuf full name, which we also do not know.
|
||||
// Thus, this produces some bogus enum descriptor based on the Go type name.
|
||||
func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
|
||||
// Fast-path: check if an EnumDescriptor is cached for this concrete type.
|
||||
if ed, ok := aberrantEnumDescCache.Load(t); ok {
|
||||
return ed.(pref.EnumDescriptor)
|
||||
}
|
||||
|
||||
// Slow-path: construct a bogus, but unique EnumDescriptor.
|
||||
ed := &filedesc.Enum{L2: new(filedesc.EnumL2)}
|
||||
ed.L0.FullName = AberrantDeriveFullName(t) // e.g., github_com.user.repo.MyEnum
|
||||
ed.L0.ParentFile = filedesc.SurrogateProto3
|
||||
ed.L2.Values.List = append(ed.L2.Values.List, filedesc.EnumValue{})
|
||||
|
||||
// TODO: Use the presence of a UnmarshalJSON method to determine proto2?
|
||||
|
||||
vd := &ed.L2.Values.List[0]
|
||||
vd.L0.FullName = ed.L0.FullName + "_UNKNOWN" // e.g., github_com.user.repo.MyEnum_UNKNOWN
|
||||
vd.L0.ParentFile = ed.L0.ParentFile
|
||||
vd.L0.Parent = ed
|
||||
|
||||
// TODO: We could use the String method to obtain some enum value names by
|
||||
// starting at 0 and print the enum until it produces invalid identifiers.
|
||||
// An exhaustive query is clearly impractical, but can be best-effort.
|
||||
|
||||
if ed, ok := aberrantEnumDescCache.LoadOrStore(t, ed); ok {
|
||||
return ed.(pref.EnumDescriptor)
|
||||
}
|
||||
return ed
|
||||
}
|
||||
|
||||
// AberrantDeriveFullName derives a fully qualified protobuf name for the given Go type
|
||||
// The provided name is not guaranteed to be stable nor universally unique.
|
||||
// It should be sufficiently unique within a program.
|
||||
//
|
||||
// This is exported for testing purposes.
|
||||
func AberrantDeriveFullName(t reflect.Type) pref.FullName {
|
||||
sanitize := func(r rune) rune {
|
||||
switch {
|
||||
case r == '/':
|
||||
return '.'
|
||||
case 'a' <= r && r <= 'z', 'A' <= r && r <= 'Z', '0' <= r && r <= '9':
|
||||
return r
|
||||
default:
|
||||
return '_'
|
||||
}
|
||||
}
|
||||
prefix := strings.Map(sanitize, t.PkgPath())
|
||||
suffix := strings.Map(sanitize, t.Name())
|
||||
if suffix == "" {
|
||||
suffix = fmt.Sprintf("UnknownX%X", reflect.ValueOf(t).Pointer())
|
||||
}
|
||||
|
||||
ss := append(strings.Split(prefix, "."), suffix)
|
||||
for i, s := range ss {
|
||||
if s == "" || ('0' <= s[0] && s[0] <= '9') {
|
||||
ss[i] = "x" + s
|
||||
}
|
||||
}
|
||||
return pref.FullName(strings.Join(ss, "."))
|
||||
}
|
104
vendor/google.golang.org/protobuf/internal/impl/legacy_export.go
generated
vendored
Normal file
104
vendor/google.golang.org/protobuf/internal/impl/legacy_export.go
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
// These functions exist to support exported APIs in generated protobufs.
|
||||
// While these are deprecated, they cannot be removed for compatibility reasons.
|
||||
|
||||
// LegacyEnumName returns the name of enums used in legacy code.
|
||||
func (Export) LegacyEnumName(ed pref.EnumDescriptor) string {
|
||||
return legacyEnumName(ed)
|
||||
}
|
||||
|
||||
// LegacyMessageTypeOf returns the protoreflect.MessageType for m,
|
||||
// with name used as the message name if necessary.
|
||||
func (Export) LegacyMessageTypeOf(m piface.MessageV1, name pref.FullName) pref.MessageType {
|
||||
if mv := (Export{}).protoMessageV2Of(m); mv != nil {
|
||||
return mv.ProtoReflect().Type()
|
||||
}
|
||||
return legacyLoadMessageInfo(reflect.TypeOf(m), name)
|
||||
}
|
||||
|
||||
// UnmarshalJSONEnum unmarshals an enum from a JSON-encoded input.
|
||||
// The input can either be a string representing the enum value by name,
|
||||
// or a number representing the enum number itself.
|
||||
func (Export) UnmarshalJSONEnum(ed pref.EnumDescriptor, b []byte) (pref.EnumNumber, error) {
|
||||
if b[0] == '"' {
|
||||
var name pref.Name
|
||||
if err := json.Unmarshal(b, &name); err != nil {
|
||||
return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b)
|
||||
}
|
||||
ev := ed.Values().ByName(name)
|
||||
if ev == nil {
|
||||
return 0, errors.New("invalid value for enum %v: %s", ed.FullName(), name)
|
||||
}
|
||||
return ev.Number(), nil
|
||||
} else {
|
||||
var num pref.EnumNumber
|
||||
if err := json.Unmarshal(b, &num); err != nil {
|
||||
return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b)
|
||||
}
|
||||
return num, nil
|
||||
}
|
||||
}
|
||||
|
||||
// CompressGZIP compresses the input as a GZIP-encoded file.
|
||||
// The current implementation does no compression.
|
||||
func (Export) CompressGZIP(in []byte) (out []byte) {
|
||||
// RFC 1952, section 2.3.1.
|
||||
var gzipHeader = [10]byte{0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}
|
||||
|
||||
// RFC 1951, section 3.2.4.
|
||||
var blockHeader [5]byte
|
||||
const maxBlockSize = math.MaxUint16
|
||||
numBlocks := 1 + len(in)/maxBlockSize
|
||||
|
||||
// RFC 1952, section 2.3.1.
|
||||
var gzipFooter [8]byte
|
||||
binary.LittleEndian.PutUint32(gzipFooter[0:4], crc32.ChecksumIEEE(in))
|
||||
binary.LittleEndian.PutUint32(gzipFooter[4:8], uint32(len(in)))
|
||||
|
||||
// Encode the input without compression using raw DEFLATE blocks.
|
||||
out = make([]byte, 0, len(gzipHeader)+len(blockHeader)*numBlocks+len(in)+len(gzipFooter))
|
||||
out = append(out, gzipHeader[:]...)
|
||||
for blockHeader[0] == 0 {
|
||||
blockSize := maxBlockSize
|
||||
if blockSize > len(in) {
|
||||
blockHeader[0] = 0x01 // final bit per RFC 1951, section 3.2.3.
|
||||
blockSize = len(in)
|
||||
}
|
||||
binary.LittleEndian.PutUint16(blockHeader[1:3], uint16(blockSize)^0x0000)
|
||||
binary.LittleEndian.PutUint16(blockHeader[3:5], uint16(blockSize)^0xffff)
|
||||
out = append(out, blockHeader[:]...)
|
||||
out = append(out, in[:blockSize]...)
|
||||
in = in[blockSize:]
|
||||
}
|
||||
out = append(out, gzipFooter[:]...)
|
||||
return out
|
||||
}
|
||||
|
||||
// WeakNil returns a typed nil pointer to a concrete message.
|
||||
// It panics if the message is not linked into the binary.
|
||||
func (Export) WeakNil(s pref.FullName) piface.MessageV1 {
|
||||
mt, err := protoregistry.GlobalTypes.FindMessageByName(s)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("weak message %v is not linked in", s))
|
||||
}
|
||||
return mt.Zero().Interface().(piface.MessageV1)
|
||||
}
|
173
vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go
generated
vendored
Normal file
173
vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go
generated
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"google.golang.org/protobuf/internal/descopts"
|
||||
"google.golang.org/protobuf/internal/encoding/messageset"
|
||||
ptag "google.golang.org/protobuf/internal/encoding/tag"
|
||||
"google.golang.org/protobuf/internal/filedesc"
|
||||
"google.golang.org/protobuf/internal/pragma"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
preg "google.golang.org/protobuf/reflect/protoregistry"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
func (xi *ExtensionInfo) initToLegacy() {
|
||||
xd := xi.desc
|
||||
var parent piface.MessageV1
|
||||
messageName := xd.ContainingMessage().FullName()
|
||||
if mt, _ := preg.GlobalTypes.FindMessageByName(messageName); mt != nil {
|
||||
// Create a new parent message and unwrap it if possible.
|
||||
mv := mt.New().Interface()
|
||||
t := reflect.TypeOf(mv)
|
||||
if mv, ok := mv.(unwrapper); ok {
|
||||
t = reflect.TypeOf(mv.protoUnwrap())
|
||||
}
|
||||
|
||||
// Check whether the message implements the legacy v1 Message interface.
|
||||
mz := reflect.Zero(t).Interface()
|
||||
if mz, ok := mz.(piface.MessageV1); ok {
|
||||
parent = mz
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the v1 extension type, which is unfortunately not the same as
|
||||
// the v2 ExtensionType.GoType.
|
||||
extType := xi.goType
|
||||
switch extType.Kind() {
|
||||
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
|
||||
extType = reflect.PtrTo(extType) // T -> *T for singular scalar fields
|
||||
}
|
||||
|
||||
// Reconstruct the legacy enum full name.
|
||||
var enumName string
|
||||
if xd.Kind() == pref.EnumKind {
|
||||
enumName = legacyEnumName(xd.Enum())
|
||||
}
|
||||
|
||||
// Derive the proto file that the extension was declared within.
|
||||
var filename string
|
||||
if fd := xd.ParentFile(); fd != nil {
|
||||
filename = fd.Path()
|
||||
}
|
||||
|
||||
// For MessageSet extensions, the name used is the parent message.
|
||||
name := xd.FullName()
|
||||
if messageset.IsMessageSetExtension(xd) {
|
||||
name = name.Parent()
|
||||
}
|
||||
|
||||
xi.ExtendedType = parent
|
||||
xi.ExtensionType = reflect.Zero(extType).Interface()
|
||||
xi.Field = int32(xd.Number())
|
||||
xi.Name = string(name)
|
||||
xi.Tag = ptag.Marshal(xd, enumName)
|
||||
xi.Filename = filename
|
||||
}
|
||||
|
||||
// initFromLegacy initializes an ExtensionInfo from
|
||||
// the contents of the deprecated exported fields of the type.
|
||||
func (xi *ExtensionInfo) initFromLegacy() {
|
||||
// The v1 API returns "type incomplete" descriptors where only the
|
||||
// field number is specified. In such a case, use a placeholder.
|
||||
if xi.ExtendedType == nil || xi.ExtensionType == nil {
|
||||
xd := placeholderExtension{
|
||||
name: pref.FullName(xi.Name),
|
||||
number: pref.FieldNumber(xi.Field),
|
||||
}
|
||||
xi.desc = extensionTypeDescriptor{xd, xi}
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve enum or message dependencies.
|
||||
var ed pref.EnumDescriptor
|
||||
var md pref.MessageDescriptor
|
||||
t := reflect.TypeOf(xi.ExtensionType)
|
||||
isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
|
||||
isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
|
||||
if isOptional || isRepeated {
|
||||
t = t.Elem()
|
||||
}
|
||||
switch v := reflect.Zero(t).Interface().(type) {
|
||||
case pref.Enum:
|
||||
ed = v.Descriptor()
|
||||
case enumV1:
|
||||
ed = LegacyLoadEnumDesc(t)
|
||||
case pref.ProtoMessage:
|
||||
md = v.ProtoReflect().Descriptor()
|
||||
case messageV1:
|
||||
md = LegacyLoadMessageDesc(t)
|
||||
}
|
||||
|
||||
// Derive basic field information from the struct tag.
|
||||
var evs pref.EnumValueDescriptors
|
||||
if ed != nil {
|
||||
evs = ed.Values()
|
||||
}
|
||||
fd := ptag.Unmarshal(xi.Tag, t, evs).(*filedesc.Field)
|
||||
|
||||
// Construct a v2 ExtensionType.
|
||||
xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)}
|
||||
xd.L0.ParentFile = filedesc.SurrogateProto2
|
||||
xd.L0.FullName = pref.FullName(xi.Name)
|
||||
xd.L1.Number = pref.FieldNumber(xi.Field)
|
||||
xd.L1.Cardinality = fd.L1.Cardinality
|
||||
xd.L1.Kind = fd.L1.Kind
|
||||
xd.L2.IsPacked = fd.L1.IsPacked
|
||||
xd.L2.Default = fd.L1.Default
|
||||
xd.L1.Extendee = Export{}.MessageDescriptorOf(xi.ExtendedType)
|
||||
xd.L2.Enum = ed
|
||||
xd.L2.Message = md
|
||||
|
||||
// Derive real extension field name for MessageSets.
|
||||
if messageset.IsMessageSet(xd.L1.Extendee) && md.FullName() == xd.L0.FullName {
|
||||
xd.L0.FullName = xd.L0.FullName.Append(messageset.ExtensionName)
|
||||
}
|
||||
|
||||
tt := reflect.TypeOf(xi.ExtensionType)
|
||||
if isOptional {
|
||||
tt = tt.Elem()
|
||||
}
|
||||
xi.goType = tt
|
||||
xi.desc = extensionTypeDescriptor{xd, xi}
|
||||
}
|
||||
|
||||
type placeholderExtension struct {
|
||||
name pref.FullName
|
||||
number pref.FieldNumber
|
||||
}
|
||||
|
||||
func (x placeholderExtension) ParentFile() pref.FileDescriptor { return nil }
|
||||
func (x placeholderExtension) Parent() pref.Descriptor { return nil }
|
||||
func (x placeholderExtension) Index() int { return 0 }
|
||||
func (x placeholderExtension) Syntax() pref.Syntax { return 0 }
|
||||
func (x placeholderExtension) Name() pref.Name { return x.name.Name() }
|
||||
func (x placeholderExtension) FullName() pref.FullName { return x.name }
|
||||
func (x placeholderExtension) IsPlaceholder() bool { return true }
|
||||
func (x placeholderExtension) Options() pref.ProtoMessage { return descopts.Field }
|
||||
func (x placeholderExtension) Number() pref.FieldNumber { return x.number }
|
||||
func (x placeholderExtension) Cardinality() pref.Cardinality { return 0 }
|
||||
func (x placeholderExtension) Kind() pref.Kind { return 0 }
|
||||
func (x placeholderExtension) HasJSONName() bool { return false }
|
||||
func (x placeholderExtension) JSONName() string { return "" }
|
||||
func (x placeholderExtension) IsExtension() bool { return true }
|
||||
func (x placeholderExtension) IsWeak() bool { return false }
|
||||
func (x placeholderExtension) IsPacked() bool { return false }
|
||||
func (x placeholderExtension) IsList() bool { return false }
|
||||
func (x placeholderExtension) IsMap() bool { return false }
|
||||
func (x placeholderExtension) MapKey() pref.FieldDescriptor { return nil }
|
||||
func (x placeholderExtension) MapValue() pref.FieldDescriptor { return nil }
|
||||
func (x placeholderExtension) HasDefault() bool { return false }
|
||||
func (x placeholderExtension) Default() pref.Value { return pref.Value{} }
|
||||
func (x placeholderExtension) DefaultEnumValue() pref.EnumValueDescriptor { return nil }
|
||||
func (x placeholderExtension) ContainingOneof() pref.OneofDescriptor { return nil }
|
||||
func (x placeholderExtension) ContainingMessage() pref.MessageDescriptor { return nil }
|
||||
func (x placeholderExtension) Enum() pref.EnumDescriptor { return nil }
|
||||
func (x placeholderExtension) Message() pref.MessageDescriptor { return nil }
|
||||
func (x placeholderExtension) ProtoType(pref.FieldDescriptor) { return }
|
||||
func (x placeholderExtension) ProtoInternal(pragma.DoNotImplement) { return }
|
81
vendor/google.golang.org/protobuf/internal/impl/legacy_file.go
generated
vendored
Normal file
81
vendor/google.golang.org/protobuf/internal/impl/legacy_file.go
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/protobuf/internal/filedesc"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
)
|
||||
|
||||
// Every enum and message type generated by protoc-gen-go since commit 2fc053c5
|
||||
// on February 25th, 2016 has had a method to get the raw descriptor.
|
||||
// Types that were not generated by protoc-gen-go or were generated prior
|
||||
// to that version are not supported.
|
||||
//
|
||||
// The []byte returned is the encoded form of a FileDescriptorProto message
|
||||
// compressed using GZIP. The []int is the path from the top-level file
|
||||
// to the specific message or enum declaration.
|
||||
type (
|
||||
enumV1 interface {
|
||||
EnumDescriptor() ([]byte, []int)
|
||||
}
|
||||
messageV1 interface {
|
||||
Descriptor() ([]byte, []int)
|
||||
}
|
||||
)
|
||||
|
||||
var legacyFileDescCache sync.Map // map[*byte]protoreflect.FileDescriptor
|
||||
|
||||
// legacyLoadFileDesc unmarshals b as a compressed FileDescriptorProto message.
|
||||
//
|
||||
// This assumes that b is immutable and that b does not refer to part of a
|
||||
// concatenated series of GZIP files (which would require shenanigans that
|
||||
// rely on the concatenation properties of both protobufs and GZIP).
|
||||
// File descriptors generated by protoc-gen-go do not rely on that property.
|
||||
func legacyLoadFileDesc(b []byte) protoreflect.FileDescriptor {
|
||||
// Fast-path: check whether we already have a cached file descriptor.
|
||||
if fd, ok := legacyFileDescCache.Load(&b[0]); ok {
|
||||
return fd.(protoreflect.FileDescriptor)
|
||||
}
|
||||
|
||||
// Slow-path: decompress and unmarshal the file descriptor proto.
|
||||
zr, err := gzip.NewReader(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b2, err := ioutil.ReadAll(zr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fd := filedesc.Builder{
|
||||
RawDescriptor: b2,
|
||||
FileRegistry: resolverOnly{protoregistry.GlobalFiles}, // do not register back to global registry
|
||||
}.Build().File
|
||||
if fd, ok := legacyFileDescCache.LoadOrStore(&b[0], fd); ok {
|
||||
return fd.(protoreflect.FileDescriptor)
|
||||
}
|
||||
return fd
|
||||
}
|
||||
|
||||
type resolverOnly struct {
|
||||
reg *protoregistry.Files
|
||||
}
|
||||
|
||||
func (r resolverOnly) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
|
||||
return r.reg.FindFileByPath(path)
|
||||
}
|
||||
func (r resolverOnly) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error) {
|
||||
return r.reg.FindDescriptorByName(name)
|
||||
}
|
||||
func (resolverOnly) RegisterFile(protoreflect.FileDescriptor) error {
|
||||
return nil
|
||||
}
|
502
vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
generated
vendored
Normal file
502
vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
generated
vendored
Normal file
|
@ -0,0 +1,502 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/protobuf/internal/descopts"
|
||||
ptag "google.golang.org/protobuf/internal/encoding/tag"
|
||||
"google.golang.org/protobuf/internal/errors"
|
||||
"google.golang.org/protobuf/internal/filedesc"
|
||||
"google.golang.org/protobuf/internal/strs"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/runtime/protoiface"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
// legacyWrapMessage wraps v as a protoreflect.Message,
|
||||
// where v must be a *struct kind and not implement the v2 API already.
|
||||
func legacyWrapMessage(v reflect.Value) pref.Message {
|
||||
typ := v.Type()
|
||||
if typ.Kind() != reflect.Ptr || typ.Elem().Kind() != reflect.Struct {
|
||||
return aberrantMessage{v: v}
|
||||
}
|
||||
mt := legacyLoadMessageInfo(typ, "")
|
||||
return mt.MessageOf(v.Interface())
|
||||
}
|
||||
|
||||
var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo
|
||||
|
||||
// legacyLoadMessageInfo dynamically loads a *MessageInfo for t,
|
||||
// where t must be a *struct kind and not implement the v2 API already.
|
||||
// The provided name is used if it cannot be determined from the message.
|
||||
func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo {
|
||||
// Fast-path: check if a MessageInfo is cached for this concrete type.
|
||||
if mt, ok := legacyMessageTypeCache.Load(t); ok {
|
||||
return mt.(*MessageInfo)
|
||||
}
|
||||
|
||||
// Slow-path: derive message descriptor and initialize MessageInfo.
|
||||
mi := &MessageInfo{
|
||||
Desc: legacyLoadMessageDesc(t, name),
|
||||
GoReflectType: t,
|
||||
}
|
||||
|
||||
v := reflect.Zero(t).Interface()
|
||||
if _, ok := v.(legacyMarshaler); ok {
|
||||
mi.methods.Marshal = legacyMarshal
|
||||
|
||||
// We have no way to tell whether the type's Marshal method
|
||||
// supports deterministic serialization or not, but this
|
||||
// preserves the v1 implementation's behavior of always
|
||||
// calling Marshal methods when present.
|
||||
mi.methods.Flags |= piface.SupportMarshalDeterministic
|
||||
}
|
||||
if _, ok := v.(legacyUnmarshaler); ok {
|
||||
mi.methods.Unmarshal = legacyUnmarshal
|
||||
}
|
||||
if _, ok := v.(legacyMerger); ok {
|
||||
mi.methods.Merge = legacyMerge
|
||||
}
|
||||
|
||||
if mi, ok := legacyMessageTypeCache.LoadOrStore(t, mi); ok {
|
||||
return mi.(*MessageInfo)
|
||||
}
|
||||
return mi
|
||||
}
|
||||
|
||||
var legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor
|
||||
|
||||
// LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type,
|
||||
// which must be a *struct kind and not implement the v2 API already.
|
||||
//
|
||||
// This is exported for testing purposes.
|
||||
func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor {
|
||||
return legacyLoadMessageDesc(t, "")
|
||||
}
|
||||
func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
|
||||
// Fast-path: check if a MessageDescriptor is cached for this concrete type.
|
||||
if mi, ok := legacyMessageDescCache.Load(t); ok {
|
||||
return mi.(pref.MessageDescriptor)
|
||||
}
|
||||
|
||||
// Slow-path: initialize MessageDescriptor from the raw descriptor.
|
||||
mv := reflect.Zero(t).Interface()
|
||||
if _, ok := mv.(pref.ProtoMessage); ok {
|
||||
panic(fmt.Sprintf("%v already implements proto.Message", t))
|
||||
}
|
||||
mdV1, ok := mv.(messageV1)
|
||||
if !ok {
|
||||
return aberrantLoadMessageDesc(t, name)
|
||||
}
|
||||
|
||||
// If this is a dynamic message type where there isn't a 1-1 mapping between
|
||||
// Go and protobuf types, calling the Descriptor method on the zero value of
|
||||
// the message type isn't likely to work. If it panics, swallow the panic and
|
||||
// continue as if the Descriptor method wasn't present.
|
||||
b, idxs := func() ([]byte, []int) {
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
return mdV1.Descriptor()
|
||||
}()
|
||||
if b == nil {
|
||||
return aberrantLoadMessageDesc(t, name)
|
||||
}
|
||||
|
||||
// If the Go type has no fields, then this might be a proto3 empty message
|
||||
// from before the size cache was added. If there are any fields, check to
|
||||
// see that at least one of them looks like something we generated.
|
||||
if nfield := t.Elem().NumField(); nfield > 0 {
|
||||
hasProtoField := false
|
||||
for i := 0; i < nfield; i++ {
|
||||
f := t.Elem().Field(i)
|
||||
if f.Tag.Get("protobuf") != "" || f.Tag.Get("protobuf_oneof") != "" || strings.HasPrefix(f.Name, "XXX_") {
|
||||
hasProtoField = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasProtoField {
|
||||
return aberrantLoadMessageDesc(t, name)
|
||||
}
|
||||
}
|
||||
|
||||
md := legacyLoadFileDesc(b).Messages().Get(idxs[0])
|
||||
for _, i := range idxs[1:] {
|
||||
md = md.Messages().Get(i)
|
||||
}
|
||||
if name != "" && md.FullName() != name {
|
||||
panic(fmt.Sprintf("mismatching message name: got %v, want %v", md.FullName(), name))
|
||||
}
|
||||
if md, ok := legacyMessageDescCache.LoadOrStore(t, md); ok {
|
||||
return md.(protoreflect.MessageDescriptor)
|
||||
}
|
||||
return md
|
||||
}
|
||||
|
||||
var (
|
||||
aberrantMessageDescLock sync.Mutex
|
||||
aberrantMessageDescCache map[reflect.Type]protoreflect.MessageDescriptor
|
||||
)
|
||||
|
||||
// aberrantLoadMessageDesc returns an MessageDescriptor derived from the Go type,
|
||||
// which must not implement protoreflect.ProtoMessage or messageV1.
|
||||
//
|
||||
// This is a best-effort derivation of the message descriptor using the protobuf
|
||||
// tags on the struct fields.
|
||||
func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
|
||||
aberrantMessageDescLock.Lock()
|
||||
defer aberrantMessageDescLock.Unlock()
|
||||
if aberrantMessageDescCache == nil {
|
||||
aberrantMessageDescCache = make(map[reflect.Type]protoreflect.MessageDescriptor)
|
||||
}
|
||||
return aberrantLoadMessageDescReentrant(t, name)
|
||||
}
|
||||
func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
|
||||
// Fast-path: check if an MessageDescriptor is cached for this concrete type.
|
||||
if md, ok := aberrantMessageDescCache[t]; ok {
|
||||
return md
|
||||
}
|
||||
|
||||
// Slow-path: construct a descriptor from the Go struct type (best-effort).
|
||||
// Cache the MessageDescriptor early on so that we can resolve internal
|
||||
// cyclic references.
|
||||
md := &filedesc.Message{L2: new(filedesc.MessageL2)}
|
||||
md.L0.FullName = aberrantDeriveMessageName(t, name)
|
||||
md.L0.ParentFile = filedesc.SurrogateProto2
|
||||
aberrantMessageDescCache[t] = md
|
||||
|
||||
if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
|
||||
return md
|
||||
}
|
||||
|
||||
// Try to determine if the message is using proto3 by checking scalars.
|
||||
for i := 0; i < t.Elem().NumField(); i++ {
|
||||
f := t.Elem().Field(i)
|
||||
if tag := f.Tag.Get("protobuf"); tag != "" {
|
||||
switch f.Type.Kind() {
|
||||
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
|
||||
md.L0.ParentFile = filedesc.SurrogateProto3
|
||||
}
|
||||
for _, s := range strings.Split(tag, ",") {
|
||||
if s == "proto3" {
|
||||
md.L0.ParentFile = filedesc.SurrogateProto3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain a list of oneof wrapper types.
|
||||
var oneofWrappers []reflect.Type
|
||||
for _, method := range []string{"XXX_OneofFuncs", "XXX_OneofWrappers"} {
|
||||
if fn, ok := t.MethodByName(method); ok {
|
||||
for _, v := range fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))}) {
|
||||
if vs, ok := v.Interface().([]interface{}); ok {
|
||||
for _, v := range vs {
|
||||
oneofWrappers = append(oneofWrappers, reflect.TypeOf(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain a list of the extension ranges.
|
||||
if fn, ok := t.MethodByName("ExtensionRangeArray"); ok {
|
||||
vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0]
|
||||
for i := 0; i < vs.Len(); i++ {
|
||||
v := vs.Index(i)
|
||||
md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]pref.FieldNumber{
|
||||
pref.FieldNumber(v.FieldByName("Start").Int()),
|
||||
pref.FieldNumber(v.FieldByName("End").Int() + 1),
|
||||
})
|
||||
md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// Derive the message fields by inspecting the struct fields.
|
||||
for i := 0; i < t.Elem().NumField(); i++ {
|
||||
f := t.Elem().Field(i)
|
||||
if tag := f.Tag.Get("protobuf"); tag != "" {
|
||||
tagKey := f.Tag.Get("protobuf_key")
|
||||
tagVal := f.Tag.Get("protobuf_val")
|
||||
aberrantAppendField(md, f.Type, tag, tagKey, tagVal)
|
||||
}
|
||||
if tag := f.Tag.Get("protobuf_oneof"); tag != "" {
|
||||
n := len(md.L2.Oneofs.List)
|
||||
md.L2.Oneofs.List = append(md.L2.Oneofs.List, filedesc.Oneof{})
|
||||
od := &md.L2.Oneofs.List[n]
|
||||
od.L0.FullName = md.FullName().Append(pref.Name(tag))
|
||||
od.L0.ParentFile = md.L0.ParentFile
|
||||
od.L0.Parent = md
|
||||
od.L0.Index = n
|
||||
|
||||
for _, t := range oneofWrappers {
|
||||
if t.Implements(f.Type) {
|
||||
f := t.Elem().Field(0)
|
||||
if tag := f.Tag.Get("protobuf"); tag != "" {
|
||||
aberrantAppendField(md, f.Type, tag, "", "")
|
||||
fd := &md.L2.Fields.List[len(md.L2.Fields.List)-1]
|
||||
fd.L1.ContainingOneof = od
|
||||
od.L1.Fields.List = append(od.L1.Fields.List, fd)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return md
|
||||
}
|
||||
|
||||
func aberrantDeriveMessageName(t reflect.Type, name pref.FullName) pref.FullName {
|
||||
if name.IsValid() {
|
||||
return name
|
||||
}
|
||||
func() {
|
||||
defer func() { recover() }() // swallow possible nil panics
|
||||
if m, ok := reflect.Zero(t).Interface().(interface{ XXX_MessageName() string }); ok {
|
||||
name = pref.FullName(m.XXX_MessageName())
|
||||
}
|
||||
}()
|
||||
if name.IsValid() {
|
||||
return name
|
||||
}
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
return AberrantDeriveFullName(t)
|
||||
}
|
||||
|
||||
func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, tagVal string) {
|
||||
t := goType
|
||||
isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
|
||||
isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
|
||||
if isOptional || isRepeated {
|
||||
t = t.Elem()
|
||||
}
|
||||
fd := ptag.Unmarshal(tag, t, placeholderEnumValues{}).(*filedesc.Field)
|
||||
|
||||
// Append field descriptor to the message.
|
||||
n := len(md.L2.Fields.List)
|
||||
md.L2.Fields.List = append(md.L2.Fields.List, *fd)
|
||||
fd = &md.L2.Fields.List[n]
|
||||
fd.L0.FullName = md.FullName().Append(fd.Name())
|
||||
fd.L0.ParentFile = md.L0.ParentFile
|
||||
fd.L0.Parent = md
|
||||
fd.L0.Index = n
|
||||
|
||||
if fd.L1.IsWeak || fd.L1.HasPacked {
|
||||
fd.L1.Options = func() pref.ProtoMessage {
|
||||
opts := descopts.Field.ProtoReflect().New()
|
||||
if fd.L1.IsWeak {
|
||||
opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
|
||||
}
|
||||
if fd.L1.HasPacked {
|
||||
opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.IsPacked))
|
||||
}
|
||||
return opts.Interface()
|
||||
}
|
||||
}
|
||||
|
||||
// Populate Enum and Message.
|
||||
if fd.Enum() == nil && fd.Kind() == pref.EnumKind {
|
||||
switch v := reflect.Zero(t).Interface().(type) {
|
||||
case pref.Enum:
|
||||
fd.L1.Enum = v.Descriptor()
|
||||
default:
|
||||
fd.L1.Enum = LegacyLoadEnumDesc(t)
|
||||
}
|
||||
}
|
||||
if fd.Message() == nil && (fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind) {
|
||||
switch v := reflect.Zero(t).Interface().(type) {
|
||||
case pref.ProtoMessage:
|
||||
fd.L1.Message = v.ProtoReflect().Descriptor()
|
||||
case messageV1:
|
||||
fd.L1.Message = LegacyLoadMessageDesc(t)
|
||||
default:
|
||||
if t.Kind() == reflect.Map {
|
||||
n := len(md.L1.Messages.List)
|
||||
md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)})
|
||||
md2 := &md.L1.Messages.List[n]
|
||||
md2.L0.FullName = md.FullName().Append(pref.Name(strs.MapEntryName(string(fd.Name()))))
|
||||
md2.L0.ParentFile = md.L0.ParentFile
|
||||
md2.L0.Parent = md
|
||||
md2.L0.Index = n
|
||||
|
||||
md2.L1.IsMapEntry = true
|
||||
md2.L2.Options = func() pref.ProtoMessage {
|
||||
opts := descopts.Message.ProtoReflect().New()
|
||||
opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true))
|
||||
return opts.Interface()
|
||||
}
|
||||
|
||||
aberrantAppendField(md2, t.Key(), tagKey, "", "")
|
||||
aberrantAppendField(md2, t.Elem(), tagVal, "", "")
|
||||
|
||||
fd.L1.Message = md2
|
||||
break
|
||||
}
|
||||
fd.L1.Message = aberrantLoadMessageDescReentrant(t, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type placeholderEnumValues struct {
|
||||
protoreflect.EnumValueDescriptors
|
||||
}
|
||||
|
||||
func (placeholderEnumValues) ByNumber(n pref.EnumNumber) pref.EnumValueDescriptor {
|
||||
return filedesc.PlaceholderEnumValue(pref.FullName(fmt.Sprintf("UNKNOWN_%d", n)))
|
||||
}
|
||||
|
||||
// legacyMarshaler is the proto.Marshaler interface superseded by protoiface.Methoder.
|
||||
type legacyMarshaler interface {
|
||||
Marshal() ([]byte, error)
|
||||
}
|
||||
|
||||
// legacyUnmarshaler is the proto.Unmarshaler interface superseded by protoiface.Methoder.
|
||||
type legacyUnmarshaler interface {
|
||||
Unmarshal([]byte) error
|
||||
}
|
||||
|
||||
// legacyMerger is the proto.Merger interface superseded by protoiface.Methoder.
|
||||
type legacyMerger interface {
|
||||
Merge(protoiface.MessageV1)
|
||||
}
|
||||
|
||||
var legacyProtoMethods = &piface.Methods{
|
||||
Marshal: legacyMarshal,
|
||||
Unmarshal: legacyUnmarshal,
|
||||
Merge: legacyMerge,
|
||||
|
||||
// We have no way to tell whether the type's Marshal method
|
||||
// supports deterministic serialization or not, but this
|
||||
// preserves the v1 implementation's behavior of always
|
||||
// calling Marshal methods when present.
|
||||
Flags: piface.SupportMarshalDeterministic,
|
||||
}
|
||||
|
||||
func legacyMarshal(in piface.MarshalInput) (piface.MarshalOutput, error) {
|
||||
v := in.Message.(unwrapper).protoUnwrap()
|
||||
marshaler, ok := v.(legacyMarshaler)
|
||||
if !ok {
|
||||
return piface.MarshalOutput{}, errors.New("%T does not implement Marshal", v)
|
||||
}
|
||||
out, err := marshaler.Marshal()
|
||||
if in.Buf != nil {
|
||||
out = append(in.Buf, out...)
|
||||
}
|
||||
return piface.MarshalOutput{
|
||||
Buf: out,
|
||||
}, err
|
||||
}
|
||||
|
||||
func legacyUnmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) {
|
||||
v := in.Message.(unwrapper).protoUnwrap()
|
||||
unmarshaler, ok := v.(legacyUnmarshaler)
|
||||
if !ok {
|
||||
return piface.UnmarshalOutput{}, errors.New("%T does not implement Marshal", v)
|
||||
}
|
||||
return piface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf)
|
||||
}
|
||||
|
||||
func legacyMerge(in piface.MergeInput) piface.MergeOutput {
|
||||
dstv := in.Destination.(unwrapper).protoUnwrap()
|
||||
merger, ok := dstv.(legacyMerger)
|
||||
if !ok {
|
||||
return piface.MergeOutput{}
|
||||
}
|
||||
merger.Merge(Export{}.ProtoMessageV1Of(in.Source))
|
||||
return piface.MergeOutput{Flags: piface.MergeComplete}
|
||||
}
|
||||
|
||||
// aberrantMessageType implements MessageType for all types other than pointer-to-struct.
|
||||
type aberrantMessageType struct {
|
||||
t reflect.Type
|
||||
}
|
||||
|
||||
func (mt aberrantMessageType) New() pref.Message {
|
||||
return aberrantMessage{reflect.Zero(mt.t)}
|
||||
}
|
||||
func (mt aberrantMessageType) Zero() pref.Message {
|
||||
return aberrantMessage{reflect.Zero(mt.t)}
|
||||
}
|
||||
func (mt aberrantMessageType) GoType() reflect.Type {
|
||||
return mt.t
|
||||
}
|
||||
func (mt aberrantMessageType) Descriptor() pref.MessageDescriptor {
|
||||
return LegacyLoadMessageDesc(mt.t)
|
||||
}
|
||||
|
||||
// aberrantMessage implements Message for all types other than pointer-to-struct.
|
||||
//
|
||||
// When the underlying type implements legacyMarshaler or legacyUnmarshaler,
|
||||
// the aberrant Message can be marshaled or unmarshaled. Otherwise, there is
|
||||
// not much that can be done with values of this type.
|
||||
type aberrantMessage struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
func (m aberrantMessage) ProtoReflect() pref.Message {
|
||||
return m
|
||||
}
|
||||
|
||||
func (m aberrantMessage) Descriptor() pref.MessageDescriptor {
|
||||
return LegacyLoadMessageDesc(m.v.Type())
|
||||
}
|
||||
func (m aberrantMessage) Type() pref.MessageType {
|
||||
return aberrantMessageType{m.v.Type()}
|
||||
}
|
||||
func (m aberrantMessage) New() pref.Message {
|
||||
return aberrantMessage{reflect.Zero(m.v.Type())}
|
||||
}
|
||||
func (m aberrantMessage) Interface() pref.ProtoMessage {
|
||||
return m
|
||||
}
|
||||
func (m aberrantMessage) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
|
||||
}
|
||||
func (m aberrantMessage) Has(pref.FieldDescriptor) bool {
|
||||
panic("invalid field descriptor")
|
||||
}
|
||||
func (m aberrantMessage) Clear(pref.FieldDescriptor) {
|
||||
panic("invalid field descriptor")
|
||||
}
|
||||
func (m aberrantMessage) Get(pref.FieldDescriptor) pref.Value {
|
||||
panic("invalid field descriptor")
|
||||
}
|
||||
func (m aberrantMessage) Set(pref.FieldDescriptor, pref.Value) {
|
||||
panic("invalid field descriptor")
|
||||
}
|
||||
func (m aberrantMessage) Mutable(pref.FieldDescriptor) pref.Value {
|
||||
panic("invalid field descriptor")
|
||||
}
|
||||
func (m aberrantMessage) NewField(pref.FieldDescriptor) pref.Value {
|
||||
panic("invalid field descriptor")
|
||||
}
|
||||
func (m aberrantMessage) WhichOneof(pref.OneofDescriptor) pref.FieldDescriptor {
|
||||
panic("invalid oneof descriptor")
|
||||
}
|
||||
func (m aberrantMessage) GetUnknown() pref.RawFields {
|
||||
return nil
|
||||
}
|
||||
func (m aberrantMessage) SetUnknown(pref.RawFields) {
|
||||
// SetUnknown discards its input on messages which don't support unknown field storage.
|
||||
}
|
||||
func (m aberrantMessage) IsValid() bool {
|
||||
// An invalid message is a read-only, empty message. Since we don't know anything
|
||||
// about the alleged contents of this message, we can't say with confidence that
|
||||
// it is invalid in this sense. Therefore, report it as valid.
|
||||
return true
|
||||
}
|
||||
func (m aberrantMessage) ProtoMethods() *piface.Methods {
|
||||
return legacyProtoMethods
|
||||
}
|
||||
func (m aberrantMessage) protoUnwrap() interface{} {
|
||||
return m.v.Interface()
|
||||
}
|
176
vendor/google.golang.org/protobuf/internal/impl/merge.go
generated
vendored
Normal file
176
vendor/google.golang.org/protobuf/internal/impl/merge.go
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
type mergeOptions struct{}
|
||||
|
||||
func (o mergeOptions) Merge(dst, src proto.Message) {
|
||||
proto.Merge(dst, src)
|
||||
}
|
||||
|
||||
// merge is protoreflect.Methods.Merge.
|
||||
func (mi *MessageInfo) merge(in piface.MergeInput) piface.MergeOutput {
|
||||
dp, ok := mi.getPointer(in.Destination)
|
||||
if !ok {
|
||||
return piface.MergeOutput{}
|
||||
}
|
||||
sp, ok := mi.getPointer(in.Source)
|
||||
if !ok {
|
||||
return piface.MergeOutput{}
|
||||
}
|
||||
mi.mergePointer(dp, sp, mergeOptions{})
|
||||
return piface.MergeOutput{Flags: piface.MergeComplete}
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) {
|
||||
mi.init()
|
||||
if dst.IsNil() {
|
||||
panic(fmt.Sprintf("invalid value: merging into nil message"))
|
||||
}
|
||||
if src.IsNil() {
|
||||
return
|
||||
}
|
||||
for _, f := range mi.orderedCoderFields {
|
||||
if f.funcs.merge == nil {
|
||||
continue
|
||||
}
|
||||
sfptr := src.Apply(f.offset)
|
||||
if f.isPointer && sfptr.Elem().IsNil() {
|
||||
continue
|
||||
}
|
||||
f.funcs.merge(dst.Apply(f.offset), sfptr, f, opts)
|
||||
}
|
||||
if mi.extensionOffset.IsValid() {
|
||||
sext := src.Apply(mi.extensionOffset).Extensions()
|
||||
dext := dst.Apply(mi.extensionOffset).Extensions()
|
||||
if *dext == nil {
|
||||
*dext = make(map[int32]ExtensionField)
|
||||
}
|
||||
for num, sx := range *sext {
|
||||
xt := sx.Type()
|
||||
xi := getExtensionFieldInfo(xt)
|
||||
if xi.funcs.merge == nil {
|
||||
continue
|
||||
}
|
||||
dx := (*dext)[num]
|
||||
var dv pref.Value
|
||||
if dx.Type() == sx.Type() {
|
||||
dv = dx.Value()
|
||||
}
|
||||
if !dv.IsValid() && xi.unmarshalNeedsValue {
|
||||
dv = xt.New()
|
||||
}
|
||||
dv = xi.funcs.merge(dv, sx.Value(), opts)
|
||||
dx.Set(sx.Type(), dv)
|
||||
(*dext)[num] = dx
|
||||
}
|
||||
}
|
||||
if mi.unknownOffset.IsValid() {
|
||||
du := dst.Apply(mi.unknownOffset).Bytes()
|
||||
su := src.Apply(mi.unknownOffset).Bytes()
|
||||
if len(*su) > 0 {
|
||||
*du = append(*du, *su...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mergeScalarValue(dst, src pref.Value, opts mergeOptions) pref.Value {
|
||||
return src
|
||||
}
|
||||
|
||||
func mergeBytesValue(dst, src pref.Value, opts mergeOptions) pref.Value {
|
||||
return pref.ValueOfBytes(append(emptyBuf[:], src.Bytes()...))
|
||||
}
|
||||
|
||||
func mergeListValue(dst, src pref.Value, opts mergeOptions) pref.Value {
|
||||
dstl := dst.List()
|
||||
srcl := src.List()
|
||||
for i, llen := 0, srcl.Len(); i < llen; i++ {
|
||||
dstl.Append(srcl.Get(i))
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func mergeBytesListValue(dst, src pref.Value, opts mergeOptions) pref.Value {
|
||||
dstl := dst.List()
|
||||
srcl := src.List()
|
||||
for i, llen := 0, srcl.Len(); i < llen; i++ {
|
||||
sb := srcl.Get(i).Bytes()
|
||||
db := append(emptyBuf[:], sb...)
|
||||
dstl.Append(pref.ValueOfBytes(db))
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func mergeMessageListValue(dst, src pref.Value, opts mergeOptions) pref.Value {
|
||||
dstl := dst.List()
|
||||
srcl := src.List()
|
||||
for i, llen := 0, srcl.Len(); i < llen; i++ {
|
||||
sm := srcl.Get(i).Message()
|
||||
dm := proto.Clone(sm.Interface()).ProtoReflect()
|
||||
dstl.Append(pref.ValueOfMessage(dm))
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func mergeMessageValue(dst, src pref.Value, opts mergeOptions) pref.Value {
|
||||
opts.Merge(dst.Message().Interface(), src.Message().Interface())
|
||||
return dst
|
||||
}
|
||||
|
||||
func mergeMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
|
||||
if f.mi != nil {
|
||||
if dst.Elem().IsNil() {
|
||||
dst.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
|
||||
}
|
||||
f.mi.mergePointer(dst.Elem(), src.Elem(), opts)
|
||||
} else {
|
||||
dm := dst.AsValueOf(f.ft).Elem()
|
||||
sm := src.AsValueOf(f.ft).Elem()
|
||||
if dm.IsNil() {
|
||||
dm.Set(reflect.New(f.ft.Elem()))
|
||||
}
|
||||
opts.Merge(asMessage(dm), asMessage(sm))
|
||||
}
|
||||
}
|
||||
|
||||
func mergeMessageSlice(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
|
||||
for _, sp := range src.PointerSlice() {
|
||||
dm := reflect.New(f.ft.Elem().Elem())
|
||||
if f.mi != nil {
|
||||
f.mi.mergePointer(pointerOfValue(dm), sp, opts)
|
||||
} else {
|
||||
opts.Merge(asMessage(dm), asMessage(sp.AsValueOf(f.ft.Elem().Elem())))
|
||||
}
|
||||
dst.AppendPointerSlice(pointerOfValue(dm))
|
||||
}
|
||||
}
|
||||
|
||||
func mergeBytes(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.Bytes() = append(emptyBuf[:], *src.Bytes()...)
|
||||
}
|
||||
|
||||
func mergeBytesNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.Bytes()
|
||||
if len(v) > 0 {
|
||||
*dst.Bytes() = append(emptyBuf[:], v...)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeBytesSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.BytesSlice()
|
||||
for _, v := range *src.BytesSlice() {
|
||||
*ds = append(*ds, append(emptyBuf[:], v...))
|
||||
}
|
||||
}
|
209
vendor/google.golang.org/protobuf/internal/impl/merge_gen.go
generated
vendored
Normal file
209
vendor/google.golang.org/protobuf/internal/impl/merge_gen.go
generated
vendored
Normal file
|
@ -0,0 +1,209 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by generate-types. DO NOT EDIT.
|
||||
|
||||
package impl
|
||||
|
||||
import ()
|
||||
|
||||
func mergeBool(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.Bool() = *src.Bool()
|
||||
}
|
||||
|
||||
func mergeBoolNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.Bool()
|
||||
if v != false {
|
||||
*dst.Bool() = v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeBoolPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
p := *src.BoolPtr()
|
||||
if p != nil {
|
||||
v := *p
|
||||
*dst.BoolPtr() = &v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeBoolSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.BoolSlice()
|
||||
ss := src.BoolSlice()
|
||||
*ds = append(*ds, *ss...)
|
||||
}
|
||||
|
||||
func mergeInt32(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.Int32() = *src.Int32()
|
||||
}
|
||||
|
||||
func mergeInt32NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.Int32()
|
||||
if v != 0 {
|
||||
*dst.Int32() = v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeInt32Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
p := *src.Int32Ptr()
|
||||
if p != nil {
|
||||
v := *p
|
||||
*dst.Int32Ptr() = &v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeInt32Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.Int32Slice()
|
||||
ss := src.Int32Slice()
|
||||
*ds = append(*ds, *ss...)
|
||||
}
|
||||
|
||||
func mergeUint32(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.Uint32() = *src.Uint32()
|
||||
}
|
||||
|
||||
func mergeUint32NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.Uint32()
|
||||
if v != 0 {
|
||||
*dst.Uint32() = v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeUint32Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
p := *src.Uint32Ptr()
|
||||
if p != nil {
|
||||
v := *p
|
||||
*dst.Uint32Ptr() = &v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeUint32Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.Uint32Slice()
|
||||
ss := src.Uint32Slice()
|
||||
*ds = append(*ds, *ss...)
|
||||
}
|
||||
|
||||
func mergeInt64(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.Int64() = *src.Int64()
|
||||
}
|
||||
|
||||
func mergeInt64NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.Int64()
|
||||
if v != 0 {
|
||||
*dst.Int64() = v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeInt64Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
p := *src.Int64Ptr()
|
||||
if p != nil {
|
||||
v := *p
|
||||
*dst.Int64Ptr() = &v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeInt64Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.Int64Slice()
|
||||
ss := src.Int64Slice()
|
||||
*ds = append(*ds, *ss...)
|
||||
}
|
||||
|
||||
func mergeUint64(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.Uint64() = *src.Uint64()
|
||||
}
|
||||
|
||||
func mergeUint64NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.Uint64()
|
||||
if v != 0 {
|
||||
*dst.Uint64() = v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeUint64Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
p := *src.Uint64Ptr()
|
||||
if p != nil {
|
||||
v := *p
|
||||
*dst.Uint64Ptr() = &v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeUint64Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.Uint64Slice()
|
||||
ss := src.Uint64Slice()
|
||||
*ds = append(*ds, *ss...)
|
||||
}
|
||||
|
||||
func mergeFloat32(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.Float32() = *src.Float32()
|
||||
}
|
||||
|
||||
func mergeFloat32NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.Float32()
|
||||
if v != 0 {
|
||||
*dst.Float32() = v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeFloat32Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
p := *src.Float32Ptr()
|
||||
if p != nil {
|
||||
v := *p
|
||||
*dst.Float32Ptr() = &v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeFloat32Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.Float32Slice()
|
||||
ss := src.Float32Slice()
|
||||
*ds = append(*ds, *ss...)
|
||||
}
|
||||
|
||||
func mergeFloat64(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.Float64() = *src.Float64()
|
||||
}
|
||||
|
||||
func mergeFloat64NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.Float64()
|
||||
if v != 0 {
|
||||
*dst.Float64() = v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeFloat64Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
p := *src.Float64Ptr()
|
||||
if p != nil {
|
||||
v := *p
|
||||
*dst.Float64Ptr() = &v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeFloat64Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.Float64Slice()
|
||||
ss := src.Float64Slice()
|
||||
*ds = append(*ds, *ss...)
|
||||
}
|
||||
|
||||
func mergeString(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
*dst.String() = *src.String()
|
||||
}
|
||||
|
||||
func mergeStringNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
v := *src.String()
|
||||
if v != "" {
|
||||
*dst.String() = v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeStringPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
p := *src.StringPtr()
|
||||
if p != nil {
|
||||
v := *p
|
||||
*dst.StringPtr() = &v
|
||||
}
|
||||
}
|
||||
|
||||
func mergeStringSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
|
||||
ds := dst.StringSlice()
|
||||
ss := src.StringSlice()
|
||||
*ds = append(*ds, *ss...)
|
||||
}
|
216
vendor/google.golang.org/protobuf/internal/impl/message.go
generated
vendored
Normal file
216
vendor/google.golang.org/protobuf/internal/impl/message.go
generated
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"google.golang.org/protobuf/internal/genname"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
// MessageInfo provides protobuf related functionality for a given Go type
|
||||
// that represents a message. A given instance of MessageInfo is tied to
|
||||
// exactly one Go type, which must be a pointer to a struct type.
|
||||
//
|
||||
// The exported fields must be populated before any methods are called
|
||||
// and cannot be mutated after set.
|
||||
type MessageInfo struct {
|
||||
// GoReflectType is the underlying message Go type and must be populated.
|
||||
GoReflectType reflect.Type // pointer to struct
|
||||
|
||||
// Desc is the underlying message descriptor type and must be populated.
|
||||
Desc pref.MessageDescriptor
|
||||
|
||||
// Exporter must be provided in a purego environment in order to provide
|
||||
// access to unexported fields.
|
||||
Exporter exporter
|
||||
|
||||
// OneofWrappers is list of pointers to oneof wrapper struct types.
|
||||
OneofWrappers []interface{}
|
||||
|
||||
initMu sync.Mutex // protects all unexported fields
|
||||
initDone uint32
|
||||
|
||||
reflectMessageInfo // for reflection implementation
|
||||
coderMessageInfo // for fast-path method implementations
|
||||
}
|
||||
|
||||
// exporter is a function that returns a reference to the ith field of v,
|
||||
// where v is a pointer to a struct. It returns nil if it does not support
|
||||
// exporting the requested field (e.g., already exported).
|
||||
type exporter func(v interface{}, i int) interface{}
|
||||
|
||||
// getMessageInfo returns the MessageInfo for any message type that
|
||||
// is generated by our implementation of protoc-gen-go (for v2 and on).
|
||||
// If it is unable to obtain a MessageInfo, it returns nil.
|
||||
func getMessageInfo(mt reflect.Type) *MessageInfo {
|
||||
m, ok := reflect.Zero(mt).Interface().(pref.ProtoMessage)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
mr, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *MessageInfo })
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return mr.ProtoMessageInfo()
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) init() {
|
||||
// This function is called in the hot path. Inline the sync.Once logic,
|
||||
// since allocating a closure for Once.Do is expensive.
|
||||
// Keep init small to ensure that it can be inlined.
|
||||
if atomic.LoadUint32(&mi.initDone) == 0 {
|
||||
mi.initOnce()
|
||||
}
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) initOnce() {
|
||||
mi.initMu.Lock()
|
||||
defer mi.initMu.Unlock()
|
||||
if mi.initDone == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
t := mi.GoReflectType
|
||||
if t.Kind() != reflect.Ptr && t.Elem().Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("got %v, want *struct kind", t))
|
||||
}
|
||||
t = t.Elem()
|
||||
|
||||
si := mi.makeStructInfo(t)
|
||||
mi.makeReflectFuncs(t, si)
|
||||
mi.makeCoderMethods(t, si)
|
||||
|
||||
atomic.StoreUint32(&mi.initDone, 1)
|
||||
}
|
||||
|
||||
// getPointer returns the pointer for a message, which should be of
|
||||
// the type of the MessageInfo. If the message is of a different type,
|
||||
// it returns ok==false.
|
||||
func (mi *MessageInfo) getPointer(m pref.Message) (p pointer, ok bool) {
|
||||
switch m := m.(type) {
|
||||
case *messageState:
|
||||
return m.pointer(), m.messageInfo() == mi
|
||||
case *messageReflectWrapper:
|
||||
return m.pointer(), m.messageInfo() == mi
|
||||
}
|
||||
return pointer{}, false
|
||||
}
|
||||
|
||||
type (
|
||||
SizeCache = int32
|
||||
WeakFields = map[int32]piface.MessageV1
|
||||
UnknownFields = []byte
|
||||
ExtensionFields = map[int32]ExtensionField
|
||||
)
|
||||
|
||||
var (
|
||||
sizecacheType = reflect.TypeOf(SizeCache(0))
|
||||
weakFieldsType = reflect.TypeOf(WeakFields(nil))
|
||||
unknownFieldsType = reflect.TypeOf(UnknownFields(nil))
|
||||
extensionFieldsType = reflect.TypeOf(ExtensionFields(nil))
|
||||
)
|
||||
|
||||
type structInfo struct {
|
||||
sizecacheOffset offset
|
||||
weakOffset offset
|
||||
unknownOffset offset
|
||||
extensionOffset offset
|
||||
|
||||
fieldsByNumber map[pref.FieldNumber]reflect.StructField
|
||||
oneofsByName map[pref.Name]reflect.StructField
|
||||
oneofWrappersByType map[reflect.Type]pref.FieldNumber
|
||||
oneofWrappersByNumber map[pref.FieldNumber]reflect.Type
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo {
|
||||
si := structInfo{
|
||||
sizecacheOffset: invalidOffset,
|
||||
weakOffset: invalidOffset,
|
||||
unknownOffset: invalidOffset,
|
||||
extensionOffset: invalidOffset,
|
||||
|
||||
fieldsByNumber: map[pref.FieldNumber]reflect.StructField{},
|
||||
oneofsByName: map[pref.Name]reflect.StructField{},
|
||||
oneofWrappersByType: map[reflect.Type]pref.FieldNumber{},
|
||||
oneofWrappersByNumber: map[pref.FieldNumber]reflect.Type{},
|
||||
}
|
||||
|
||||
fieldLoop:
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
switch f := t.Field(i); f.Name {
|
||||
case genname.SizeCache, genname.SizeCacheA:
|
||||
if f.Type == sizecacheType {
|
||||
si.sizecacheOffset = offsetOf(f, mi.Exporter)
|
||||
}
|
||||
case genname.WeakFields, genname.WeakFieldsA:
|
||||
if f.Type == weakFieldsType {
|
||||
si.weakOffset = offsetOf(f, mi.Exporter)
|
||||
}
|
||||
case genname.UnknownFields, genname.UnknownFieldsA:
|
||||
if f.Type == unknownFieldsType {
|
||||
si.unknownOffset = offsetOf(f, mi.Exporter)
|
||||
}
|
||||
case genname.ExtensionFields, genname.ExtensionFieldsA, genname.ExtensionFieldsB:
|
||||
if f.Type == extensionFieldsType {
|
||||
si.extensionOffset = offsetOf(f, mi.Exporter)
|
||||
}
|
||||
default:
|
||||
for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
|
||||
if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
|
||||
n, _ := strconv.ParseUint(s, 10, 64)
|
||||
si.fieldsByNumber[pref.FieldNumber(n)] = f
|
||||
continue fieldLoop
|
||||
}
|
||||
}
|
||||
if s := f.Tag.Get("protobuf_oneof"); len(s) > 0 {
|
||||
si.oneofsByName[pref.Name(s)] = f
|
||||
continue fieldLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Derive a mapping of oneof wrappers to fields.
|
||||
oneofWrappers := mi.OneofWrappers
|
||||
for _, method := range []string{"XXX_OneofFuncs", "XXX_OneofWrappers"} {
|
||||
if fn, ok := reflect.PtrTo(t).MethodByName(method); ok {
|
||||
for _, v := range fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))}) {
|
||||
if vs, ok := v.Interface().([]interface{}); ok {
|
||||
oneofWrappers = vs
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, v := range oneofWrappers {
|
||||
tf := reflect.TypeOf(v).Elem()
|
||||
f := tf.Field(0)
|
||||
for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") {
|
||||
if len(s) > 0 && strings.Trim(s, "0123456789") == "" {
|
||||
n, _ := strconv.ParseUint(s, 10, 64)
|
||||
si.oneofWrappersByType[tf] = pref.FieldNumber(n)
|
||||
si.oneofWrappersByNumber[pref.FieldNumber(n)] = tf
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return si
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) New() protoreflect.Message {
|
||||
return mi.MessageOf(reflect.New(mi.GoReflectType.Elem()).Interface())
|
||||
}
|
||||
func (mi *MessageInfo) Zero() protoreflect.Message {
|
||||
return mi.MessageOf(reflect.Zero(mi.GoReflectType).Interface())
|
||||
}
|
||||
func (mi *MessageInfo) Descriptor() protoreflect.MessageDescriptor { return mi.Desc }
|
346
vendor/google.golang.org/protobuf/internal/impl/message_reflect.go
generated
vendored
Normal file
346
vendor/google.golang.org/protobuf/internal/impl/message_reflect.go
generated
vendored
Normal file
|
@ -0,0 +1,346 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"google.golang.org/protobuf/internal/pragma"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
type reflectMessageInfo struct {
|
||||
fields map[pref.FieldNumber]*fieldInfo
|
||||
oneofs map[pref.Name]*oneofInfo
|
||||
|
||||
// denseFields is a subset of fields where:
|
||||
// 0 < fieldDesc.Number() < len(denseFields)
|
||||
// It provides faster access to the fieldInfo, but may be incomplete.
|
||||
denseFields []*fieldInfo
|
||||
|
||||
// rangeInfos is a list of all fields (not belonging to a oneof) and oneofs.
|
||||
rangeInfos []interface{} // either *fieldInfo or *oneofInfo
|
||||
|
||||
getUnknown func(pointer) pref.RawFields
|
||||
setUnknown func(pointer, pref.RawFields)
|
||||
extensionMap func(pointer) *extensionMap
|
||||
|
||||
nilMessage atomicNilMessage
|
||||
}
|
||||
|
||||
// makeReflectFuncs generates the set of functions to support reflection.
|
||||
func (mi *MessageInfo) makeReflectFuncs(t reflect.Type, si structInfo) {
|
||||
mi.makeKnownFieldsFunc(si)
|
||||
mi.makeUnknownFieldsFunc(t, si)
|
||||
mi.makeExtensionFieldsFunc(t, si)
|
||||
}
|
||||
|
||||
// makeKnownFieldsFunc generates functions for operations that can be performed
|
||||
// on each protobuf message field. It takes in a reflect.Type representing the
|
||||
// Go struct and matches message fields with struct fields.
|
||||
//
|
||||
// This code assumes that the struct is well-formed and panics if there are
|
||||
// any discrepancies.
|
||||
func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
|
||||
mi.fields = map[pref.FieldNumber]*fieldInfo{}
|
||||
md := mi.Desc
|
||||
fds := md.Fields()
|
||||
for i := 0; i < fds.Len(); i++ {
|
||||
fd := fds.Get(i)
|
||||
fs := si.fieldsByNumber[fd.Number()]
|
||||
var fi fieldInfo
|
||||
switch {
|
||||
case fd.ContainingOneof() != nil:
|
||||
fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], mi.Exporter, si.oneofWrappersByNumber[fd.Number()])
|
||||
case fd.IsMap():
|
||||
fi = fieldInfoForMap(fd, fs, mi.Exporter)
|
||||
case fd.IsList():
|
||||
fi = fieldInfoForList(fd, fs, mi.Exporter)
|
||||
case fd.IsWeak():
|
||||
fi = fieldInfoForWeakMessage(fd, si.weakOffset)
|
||||
case fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind:
|
||||
fi = fieldInfoForMessage(fd, fs, mi.Exporter)
|
||||
default:
|
||||
fi = fieldInfoForScalar(fd, fs, mi.Exporter)
|
||||
}
|
||||
mi.fields[fd.Number()] = &fi
|
||||
}
|
||||
|
||||
mi.oneofs = map[pref.Name]*oneofInfo{}
|
||||
for i := 0; i < md.Oneofs().Len(); i++ {
|
||||
od := md.Oneofs().Get(i)
|
||||
mi.oneofs[od.Name()] = makeOneofInfo(od, si.oneofsByName[od.Name()], mi.Exporter, si.oneofWrappersByType)
|
||||
}
|
||||
|
||||
mi.denseFields = make([]*fieldInfo, fds.Len()*2)
|
||||
for i := 0; i < fds.Len(); i++ {
|
||||
if fd := fds.Get(i); int(fd.Number()) < len(mi.denseFields) {
|
||||
mi.denseFields[fd.Number()] = mi.fields[fd.Number()]
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < fds.Len(); {
|
||||
fd := fds.Get(i)
|
||||
if od := fd.ContainingOneof(); od != nil {
|
||||
mi.rangeInfos = append(mi.rangeInfos, mi.oneofs[od.Name()])
|
||||
i += od.Fields().Len()
|
||||
} else {
|
||||
mi.rangeInfos = append(mi.rangeInfos, mi.fields[fd.Number()])
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) {
|
||||
mi.getUnknown = func(pointer) pref.RawFields { return nil }
|
||||
mi.setUnknown = func(pointer, pref.RawFields) { return }
|
||||
if si.unknownOffset.IsValid() {
|
||||
mi.getUnknown = func(p pointer) pref.RawFields {
|
||||
if p.IsNil() {
|
||||
return nil
|
||||
}
|
||||
rv := p.Apply(si.unknownOffset).AsValueOf(unknownFieldsType)
|
||||
return pref.RawFields(*rv.Interface().(*[]byte))
|
||||
}
|
||||
mi.setUnknown = func(p pointer, b pref.RawFields) {
|
||||
if p.IsNil() {
|
||||
panic("invalid SetUnknown on nil Message")
|
||||
}
|
||||
rv := p.Apply(si.unknownOffset).AsValueOf(unknownFieldsType)
|
||||
*rv.Interface().(*[]byte) = []byte(b)
|
||||
}
|
||||
} else {
|
||||
mi.getUnknown = func(pointer) pref.RawFields {
|
||||
return nil
|
||||
}
|
||||
mi.setUnknown = func(p pointer, _ pref.RawFields) {
|
||||
if p.IsNil() {
|
||||
panic("invalid SetUnknown on nil Message")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) makeExtensionFieldsFunc(t reflect.Type, si structInfo) {
|
||||
if si.extensionOffset.IsValid() {
|
||||
mi.extensionMap = func(p pointer) *extensionMap {
|
||||
if p.IsNil() {
|
||||
return (*extensionMap)(nil)
|
||||
}
|
||||
v := p.Apply(si.extensionOffset).AsValueOf(extensionFieldsType)
|
||||
return (*extensionMap)(v.Interface().(*map[int32]ExtensionField))
|
||||
}
|
||||
} else {
|
||||
mi.extensionMap = func(pointer) *extensionMap {
|
||||
return (*extensionMap)(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type extensionMap map[int32]ExtensionField
|
||||
|
||||
func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
|
||||
if m != nil {
|
||||
for _, x := range *m {
|
||||
xd := x.Type().TypeDescriptor()
|
||||
v := x.Value()
|
||||
if xd.IsList() && v.List().Len() == 0 {
|
||||
continue
|
||||
}
|
||||
if !f(xd, v) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) {
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
xd := xt.TypeDescriptor()
|
||||
x, ok := (*m)[int32(xd.Number())]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
switch {
|
||||
case xd.IsList():
|
||||
return x.Value().List().Len() > 0
|
||||
case xd.IsMap():
|
||||
return x.Value().Map().Len() > 0
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (m *extensionMap) Clear(xt pref.ExtensionType) {
|
||||
delete(*m, int32(xt.TypeDescriptor().Number()))
|
||||
}
|
||||
func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value {
|
||||
xd := xt.TypeDescriptor()
|
||||
if m != nil {
|
||||
if x, ok := (*m)[int32(xd.Number())]; ok {
|
||||
return x.Value()
|
||||
}
|
||||
}
|
||||
return xt.Zero()
|
||||
}
|
||||
func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) {
|
||||
if !xt.IsValidValue(v) {
|
||||
panic(fmt.Sprintf("%v: assigning invalid value", xt.TypeDescriptor().FullName()))
|
||||
}
|
||||
if *m == nil {
|
||||
*m = make(map[int32]ExtensionField)
|
||||
}
|
||||
var x ExtensionField
|
||||
x.Set(xt, v)
|
||||
(*m)[int32(xt.TypeDescriptor().Number())] = x
|
||||
}
|
||||
func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
|
||||
xd := xt.TypeDescriptor()
|
||||
if xd.Kind() != pref.MessageKind && xd.Kind() != pref.GroupKind && !xd.IsList() && !xd.IsMap() {
|
||||
panic("invalid Mutable on field with non-composite type")
|
||||
}
|
||||
if x, ok := (*m)[int32(xd.Number())]; ok {
|
||||
return x.Value()
|
||||
}
|
||||
v := xt.New()
|
||||
m.Set(xt, v)
|
||||
return v
|
||||
}
|
||||
|
||||
// MessageState is a data structure that is nested as the first field in a
|
||||
// concrete message. It provides a way to implement the ProtoReflect method
|
||||
// in an allocation-free way without needing to have a shadow Go type generated
|
||||
// for every message type. This technique only works using unsafe.
|
||||
//
|
||||
//
|
||||
// Example generated code:
|
||||
//
|
||||
// type M struct {
|
||||
// state protoimpl.MessageState
|
||||
//
|
||||
// Field1 int32
|
||||
// Field2 string
|
||||
// Field3 *BarMessage
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// func (m *M) ProtoReflect() protoreflect.Message {
|
||||
// mi := &file_fizz_buzz_proto_msgInfos[5]
|
||||
// if protoimpl.UnsafeEnabled && m != nil {
|
||||
// ms := protoimpl.X.MessageStateOf(Pointer(m))
|
||||
// if ms.LoadMessageInfo() == nil {
|
||||
// ms.StoreMessageInfo(mi)
|
||||
// }
|
||||
// return ms
|
||||
// }
|
||||
// return mi.MessageOf(m)
|
||||
// }
|
||||
//
|
||||
// The MessageState type holds a *MessageInfo, which must be atomically set to
|
||||
// the message info associated with a given message instance.
|
||||
// By unsafely converting a *M into a *MessageState, the MessageState object
|
||||
// has access to all the information needed to implement protobuf reflection.
|
||||
// It has access to the message info as its first field, and a pointer to the
|
||||
// MessageState is identical to a pointer to the concrete message value.
|
||||
//
|
||||
//
|
||||
// Requirements:
|
||||
// • The type M must implement protoreflect.ProtoMessage.
|
||||
// • The address of m must not be nil.
|
||||
// • The address of m and the address of m.state must be equal,
|
||||
// even though they are different Go types.
|
||||
type MessageState struct {
|
||||
pragma.NoUnkeyedLiterals
|
||||
pragma.DoNotCompare
|
||||
pragma.DoNotCopy
|
||||
|
||||
atomicMessageInfo *MessageInfo
|
||||
}
|
||||
|
||||
type messageState MessageState
|
||||
|
||||
var (
|
||||
_ pref.Message = (*messageState)(nil)
|
||||
_ unwrapper = (*messageState)(nil)
|
||||
)
|
||||
|
||||
// messageDataType is a tuple of a pointer to the message data and
|
||||
// a pointer to the message type. It is a generalized way of providing a
|
||||
// reflective view over a message instance. The disadvantage of this approach
|
||||
// is the need to allocate this tuple of 16B.
|
||||
type messageDataType struct {
|
||||
p pointer
|
||||
mi *MessageInfo
|
||||
}
|
||||
|
||||
type (
|
||||
messageReflectWrapper messageDataType
|
||||
messageIfaceWrapper messageDataType
|
||||
)
|
||||
|
||||
var (
|
||||
_ pref.Message = (*messageReflectWrapper)(nil)
|
||||
_ unwrapper = (*messageReflectWrapper)(nil)
|
||||
_ pref.ProtoMessage = (*messageIfaceWrapper)(nil)
|
||||
_ unwrapper = (*messageIfaceWrapper)(nil)
|
||||
)
|
||||
|
||||
// MessageOf returns a reflective view over a message. The input must be a
|
||||
// pointer to a named Go struct. If the provided type has a ProtoReflect method,
|
||||
// it must be implemented by calling this method.
|
||||
func (mi *MessageInfo) MessageOf(m interface{}) pref.Message {
|
||||
// TODO: Switch the input to be an opaque Pointer.
|
||||
if reflect.TypeOf(m) != mi.GoReflectType {
|
||||
panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
|
||||
}
|
||||
p := pointerOfIface(m)
|
||||
if p.IsNil() {
|
||||
return mi.nilMessage.Init(mi)
|
||||
}
|
||||
return &messageReflectWrapper{p, mi}
|
||||
}
|
||||
|
||||
func (m *messageReflectWrapper) pointer() pointer { return m.p }
|
||||
func (m *messageReflectWrapper) messageInfo() *MessageInfo { return m.mi }
|
||||
|
||||
func (m *messageIfaceWrapper) ProtoReflect() pref.Message {
|
||||
return (*messageReflectWrapper)(m)
|
||||
}
|
||||
func (m *messageIfaceWrapper) protoUnwrap() interface{} {
|
||||
return m.p.AsIfaceOf(m.mi.GoReflectType.Elem())
|
||||
}
|
||||
|
||||
// checkField verifies that the provided field descriptor is valid.
|
||||
// Exactly one of the returned values is populated.
|
||||
func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) {
|
||||
var fi *fieldInfo
|
||||
if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) {
|
||||
fi = mi.denseFields[n]
|
||||
} else {
|
||||
fi = mi.fields[n]
|
||||
}
|
||||
if fi != nil {
|
||||
if fi.fieldDesc != fd {
|
||||
panic("mismatching field descriptor")
|
||||
}
|
||||
return fi, nil
|
||||
}
|
||||
|
||||
if fd.IsExtension() {
|
||||
if fd.ContainingMessage().FullName() != mi.Desc.FullName() {
|
||||
// TODO: Should this be exact containing message descriptor match?
|
||||
panic("mismatching containing message")
|
||||
}
|
||||
if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
|
||||
panic("invalid extension field")
|
||||
}
|
||||
xtd, ok := fd.(pref.ExtensionTypeDescriptor)
|
||||
if !ok {
|
||||
panic("extension descriptor does not implement ExtensionTypeDescriptor")
|
||||
}
|
||||
return nil, xtd.Type()
|
||||
}
|
||||
panic("invalid field descriptor")
|
||||
}
|
448
vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go
generated
vendored
Normal file
448
vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go
generated
vendored
Normal file
|
@ -0,0 +1,448 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/protobuf/internal/flags"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
preg "google.golang.org/protobuf/reflect/protoregistry"
|
||||
)
|
||||
|
||||
type fieldInfo struct {
|
||||
fieldDesc pref.FieldDescriptor
|
||||
|
||||
// These fields are used for protobuf reflection support.
|
||||
has func(pointer) bool
|
||||
clear func(pointer)
|
||||
get func(pointer) pref.Value
|
||||
set func(pointer, pref.Value)
|
||||
mutable func(pointer) pref.Value
|
||||
newMessage func() pref.Message
|
||||
newField func() pref.Value
|
||||
}
|
||||
|
||||
func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo {
|
||||
ft := fs.Type
|
||||
if ft.Kind() != reflect.Interface {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want interface kind", ft))
|
||||
}
|
||||
if ot.Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want struct kind", ot))
|
||||
}
|
||||
if !reflect.PtrTo(ot).Implements(ft) {
|
||||
panic(fmt.Sprintf("invalid type: %v does not implement %v", ot, ft))
|
||||
}
|
||||
conv := NewConverter(ot.Field(0).Type, fd)
|
||||
isMessage := fd.Message() != nil
|
||||
|
||||
// TODO: Implement unsafe fast path?
|
||||
fieldOffset := offsetOf(fs, x)
|
||||
return fieldInfo{
|
||||
// NOTE: The logic below intentionally assumes that oneof fields are
|
||||
// well-formatted. That is, the oneof interface never contains a
|
||||
// typed nil pointer to one of the wrapper structs.
|
||||
|
||||
fieldDesc: fd,
|
||||
has: func(p pointer) bool {
|
||||
if p.IsNil() {
|
||||
return false
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
clear: func(p pointer) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if rv.IsNil() || rv.Elem().Type().Elem() != ot {
|
||||
// NOTE: We intentionally don't check for rv.Elem().IsNil()
|
||||
// so that (*OneofWrapperType)(nil) gets cleared to nil.
|
||||
return
|
||||
}
|
||||
rv.Set(reflect.Zero(rv.Type()))
|
||||
},
|
||||
get: func(p pointer) pref.Value {
|
||||
if p.IsNil() {
|
||||
return conv.Zero()
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
|
||||
return conv.Zero()
|
||||
}
|
||||
rv = rv.Elem().Elem().Field(0)
|
||||
return conv.PBValueOf(rv)
|
||||
},
|
||||
set: func(p pointer, v pref.Value) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
|
||||
rv.Set(reflect.New(ot))
|
||||
}
|
||||
rv = rv.Elem().Elem().Field(0)
|
||||
rv.Set(conv.GoValueOf(v))
|
||||
},
|
||||
mutable: func(p pointer) pref.Value {
|
||||
if !isMessage {
|
||||
panic("invalid Mutable on field with non-composite type")
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
|
||||
rv.Set(reflect.New(ot))
|
||||
}
|
||||
rv = rv.Elem().Elem().Field(0)
|
||||
if rv.IsNil() {
|
||||
rv.Set(conv.GoValueOf(pref.ValueOfMessage(conv.New().Message())))
|
||||
}
|
||||
return conv.PBValueOf(rv)
|
||||
},
|
||||
newMessage: func() pref.Message {
|
||||
return conv.New().Message()
|
||||
},
|
||||
newField: func() pref.Value {
|
||||
return conv.New()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
|
||||
ft := fs.Type
|
||||
if ft.Kind() != reflect.Map {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
|
||||
}
|
||||
conv := NewConverter(ft, fd)
|
||||
|
||||
// TODO: Implement unsafe fast path?
|
||||
fieldOffset := offsetOf(fs, x)
|
||||
return fieldInfo{
|
||||
fieldDesc: fd,
|
||||
has: func(p pointer) bool {
|
||||
if p.IsNil() {
|
||||
return false
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
return rv.Len() > 0
|
||||
},
|
||||
clear: func(p pointer) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
rv.Set(reflect.Zero(rv.Type()))
|
||||
},
|
||||
get: func(p pointer) pref.Value {
|
||||
if p.IsNil() {
|
||||
return conv.Zero()
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if rv.Len() == 0 {
|
||||
return conv.Zero()
|
||||
}
|
||||
return conv.PBValueOf(rv)
|
||||
},
|
||||
set: func(p pointer, v pref.Value) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
pv := conv.GoValueOf(v)
|
||||
if pv.IsNil() {
|
||||
panic(fmt.Sprintf("invalid value: setting map field to read-only value"))
|
||||
}
|
||||
rv.Set(pv)
|
||||
},
|
||||
mutable: func(p pointer) pref.Value {
|
||||
v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if v.IsNil() {
|
||||
v.Set(reflect.MakeMap(fs.Type))
|
||||
}
|
||||
return conv.PBValueOf(v)
|
||||
},
|
||||
newField: func() pref.Value {
|
||||
return conv.New()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
|
||||
ft := fs.Type
|
||||
if ft.Kind() != reflect.Slice {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
|
||||
}
|
||||
conv := NewConverter(reflect.PtrTo(ft), fd)
|
||||
|
||||
// TODO: Implement unsafe fast path?
|
||||
fieldOffset := offsetOf(fs, x)
|
||||
return fieldInfo{
|
||||
fieldDesc: fd,
|
||||
has: func(p pointer) bool {
|
||||
if p.IsNil() {
|
||||
return false
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
return rv.Len() > 0
|
||||
},
|
||||
clear: func(p pointer) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
rv.Set(reflect.Zero(rv.Type()))
|
||||
},
|
||||
get: func(p pointer) pref.Value {
|
||||
if p.IsNil() {
|
||||
return conv.Zero()
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type)
|
||||
if rv.Elem().Len() == 0 {
|
||||
return conv.Zero()
|
||||
}
|
||||
return conv.PBValueOf(rv)
|
||||
},
|
||||
set: func(p pointer, v pref.Value) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
pv := conv.GoValueOf(v)
|
||||
if pv.IsNil() {
|
||||
panic(fmt.Sprintf("invalid value: setting repeated field to read-only value"))
|
||||
}
|
||||
rv.Set(pv.Elem())
|
||||
},
|
||||
mutable: func(p pointer) pref.Value {
|
||||
v := p.Apply(fieldOffset).AsValueOf(fs.Type)
|
||||
return conv.PBValueOf(v)
|
||||
},
|
||||
newField: func() pref.Value {
|
||||
return conv.New()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
nilBytes = reflect.ValueOf([]byte(nil))
|
||||
emptyBytes = reflect.ValueOf([]byte{})
|
||||
)
|
||||
|
||||
func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
|
||||
ft := fs.Type
|
||||
nullable := fd.Syntax() == pref.Proto2
|
||||
isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
|
||||
if nullable {
|
||||
if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want pointer", ft))
|
||||
}
|
||||
if ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
}
|
||||
conv := NewConverter(ft, fd)
|
||||
|
||||
// TODO: Implement unsafe fast path?
|
||||
fieldOffset := offsetOf(fs, x)
|
||||
return fieldInfo{
|
||||
fieldDesc: fd,
|
||||
has: func(p pointer) bool {
|
||||
if p.IsNil() {
|
||||
return false
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if nullable {
|
||||
return !rv.IsNil()
|
||||
}
|
||||
switch rv.Kind() {
|
||||
case reflect.Bool:
|
||||
return rv.Bool()
|
||||
case reflect.Int32, reflect.Int64:
|
||||
return rv.Int() != 0
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
return rv.Uint() != 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return rv.Float() != 0 || math.Signbit(rv.Float())
|
||||
case reflect.String, reflect.Slice:
|
||||
return rv.Len() > 0
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid type: %v", rv.Type())) // should never happen
|
||||
}
|
||||
},
|
||||
clear: func(p pointer) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
rv.Set(reflect.Zero(rv.Type()))
|
||||
},
|
||||
get: func(p pointer) pref.Value {
|
||||
if p.IsNil() {
|
||||
return conv.Zero()
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if nullable {
|
||||
if rv.IsNil() {
|
||||
return conv.Zero()
|
||||
}
|
||||
if rv.Kind() == reflect.Ptr {
|
||||
rv = rv.Elem()
|
||||
}
|
||||
}
|
||||
return conv.PBValueOf(rv)
|
||||
},
|
||||
set: func(p pointer, v pref.Value) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if nullable && rv.Kind() == reflect.Ptr {
|
||||
if rv.IsNil() {
|
||||
rv.Set(reflect.New(ft))
|
||||
}
|
||||
rv = rv.Elem()
|
||||
}
|
||||
rv.Set(conv.GoValueOf(v))
|
||||
if isBytes && rv.Len() == 0 {
|
||||
if nullable {
|
||||
rv.Set(emptyBytes) // preserve presence in proto2
|
||||
} else {
|
||||
rv.Set(nilBytes) // do not preserve presence in proto3
|
||||
}
|
||||
}
|
||||
},
|
||||
newField: func() pref.Value {
|
||||
return conv.New()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldInfo {
|
||||
if !flags.ProtoLegacy {
|
||||
panic("no support for proto1 weak fields")
|
||||
}
|
||||
|
||||
var once sync.Once
|
||||
var messageType pref.MessageType
|
||||
lazyInit := func() {
|
||||
once.Do(func() {
|
||||
messageName := fd.Message().FullName()
|
||||
messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
|
||||
if messageType == nil {
|
||||
panic(fmt.Sprintf("weak message %v is not linked in", messageName))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
num := fd.Number()
|
||||
return fieldInfo{
|
||||
fieldDesc: fd,
|
||||
has: func(p pointer) bool {
|
||||
if p.IsNil() {
|
||||
return false
|
||||
}
|
||||
_, ok := p.Apply(weakOffset).WeakFields().get(num)
|
||||
return ok
|
||||
},
|
||||
clear: func(p pointer) {
|
||||
p.Apply(weakOffset).WeakFields().clear(num)
|
||||
},
|
||||
get: func(p pointer) pref.Value {
|
||||
lazyInit()
|
||||
if p.IsNil() {
|
||||
return pref.ValueOfMessage(messageType.Zero())
|
||||
}
|
||||
m, ok := p.Apply(weakOffset).WeakFields().get(num)
|
||||
if !ok {
|
||||
return pref.ValueOfMessage(messageType.Zero())
|
||||
}
|
||||
return pref.ValueOfMessage(m.ProtoReflect())
|
||||
},
|
||||
set: func(p pointer, v pref.Value) {
|
||||
lazyInit()
|
||||
m := v.Message()
|
||||
if m.Descriptor() != messageType.Descriptor() {
|
||||
panic("mismatching message descriptor")
|
||||
}
|
||||
p.Apply(weakOffset).WeakFields().set(num, m.Interface())
|
||||
},
|
||||
mutable: func(p pointer) pref.Value {
|
||||
lazyInit()
|
||||
fs := p.Apply(weakOffset).WeakFields()
|
||||
m, ok := fs.get(num)
|
||||
if !ok {
|
||||
m = messageType.New().Interface()
|
||||
fs.set(num, m)
|
||||
}
|
||||
return pref.ValueOfMessage(m.ProtoReflect())
|
||||
},
|
||||
newMessage: func() pref.Message {
|
||||
lazyInit()
|
||||
return messageType.New()
|
||||
},
|
||||
newField: func() pref.Value {
|
||||
lazyInit()
|
||||
return pref.ValueOfMessage(messageType.New())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
|
||||
ft := fs.Type
|
||||
conv := NewConverter(ft, fd)
|
||||
|
||||
// TODO: Implement unsafe fast path?
|
||||
fieldOffset := offsetOf(fs, x)
|
||||
return fieldInfo{
|
||||
fieldDesc: fd,
|
||||
has: func(p pointer) bool {
|
||||
if p.IsNil() {
|
||||
return false
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
return !rv.IsNil()
|
||||
},
|
||||
clear: func(p pointer) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
rv.Set(reflect.Zero(rv.Type()))
|
||||
},
|
||||
get: func(p pointer) pref.Value {
|
||||
if p.IsNil() {
|
||||
return conv.Zero()
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
return conv.PBValueOf(rv)
|
||||
},
|
||||
set: func(p pointer, v pref.Value) {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
rv.Set(conv.GoValueOf(v))
|
||||
if rv.IsNil() {
|
||||
panic("invalid nil pointer")
|
||||
}
|
||||
},
|
||||
mutable: func(p pointer) pref.Value {
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if rv.IsNil() {
|
||||
rv.Set(conv.GoValueOf(conv.New()))
|
||||
}
|
||||
return conv.PBValueOf(rv)
|
||||
},
|
||||
newMessage: func() pref.Message {
|
||||
return conv.New().Message()
|
||||
},
|
||||
newField: func() pref.Value {
|
||||
return conv.New()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type oneofInfo struct {
|
||||
oneofDesc pref.OneofDescriptor
|
||||
which func(pointer) pref.FieldNumber
|
||||
}
|
||||
|
||||
func makeOneofInfo(od pref.OneofDescriptor, fs reflect.StructField, x exporter, wrappersByType map[reflect.Type]pref.FieldNumber) *oneofInfo {
|
||||
fieldOffset := offsetOf(fs, x)
|
||||
return &oneofInfo{
|
||||
oneofDesc: od,
|
||||
which: func(p pointer) pref.FieldNumber {
|
||||
if p.IsNil() {
|
||||
return 0
|
||||
}
|
||||
rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
|
||||
if rv.IsNil() {
|
||||
return 0
|
||||
}
|
||||
rv = rv.Elem()
|
||||
if rv.IsNil() {
|
||||
return 0
|
||||
}
|
||||
return wrappersByType[rv.Type().Elem()]
|
||||
},
|
||||
}
|
||||
}
|
249
vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go
generated
vendored
Normal file
249
vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go
generated
vendored
Normal file
|
@ -0,0 +1,249 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by generate-types. DO NOT EDIT.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
func (m *messageState) Descriptor() protoreflect.MessageDescriptor {
|
||||
return m.messageInfo().Desc
|
||||
}
|
||||
func (m *messageState) Type() protoreflect.MessageType {
|
||||
return m.messageInfo()
|
||||
}
|
||||
func (m *messageState) New() protoreflect.Message {
|
||||
return m.messageInfo().New()
|
||||
}
|
||||
func (m *messageState) Interface() protoreflect.ProtoMessage {
|
||||
return m.protoUnwrap().(protoreflect.ProtoMessage)
|
||||
}
|
||||
func (m *messageState) protoUnwrap() interface{} {
|
||||
return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
|
||||
}
|
||||
func (m *messageState) ProtoMethods() *protoiface.Methods {
|
||||
m.messageInfo().init()
|
||||
return &m.messageInfo().methods
|
||||
}
|
||||
|
||||
// ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
|
||||
// to be able to retrieve a v2 MessageInfo struct.
|
||||
//
|
||||
// WARNING: This method is exempt from the compatibility promise and
|
||||
// may be removed in the future without warning.
|
||||
func (m *messageState) ProtoMessageInfo() *MessageInfo {
|
||||
return m.messageInfo()
|
||||
}
|
||||
|
||||
func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
|
||||
m.messageInfo().init()
|
||||
for _, ri := range m.messageInfo().rangeInfos {
|
||||
switch ri := ri.(type) {
|
||||
case *fieldInfo:
|
||||
if ri.has(m.pointer()) {
|
||||
if !f(ri.fieldDesc, ri.get(m.pointer())) {
|
||||
return
|
||||
}
|
||||
}
|
||||
case *oneofInfo:
|
||||
if n := ri.which(m.pointer()); n > 0 {
|
||||
fi := m.messageInfo().fields[n]
|
||||
if !f(fi.fieldDesc, fi.get(m.pointer())) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m.messageInfo().extensionMap(m.pointer()).Range(f)
|
||||
}
|
||||
func (m *messageState) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
return fi.has(m.pointer())
|
||||
} else {
|
||||
return m.messageInfo().extensionMap(m.pointer()).Has(xt)
|
||||
}
|
||||
}
|
||||
func (m *messageState) Clear(fd protoreflect.FieldDescriptor) {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
fi.clear(m.pointer())
|
||||
} else {
|
||||
m.messageInfo().extensionMap(m.pointer()).Clear(xt)
|
||||
}
|
||||
}
|
||||
func (m *messageState) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
return fi.get(m.pointer())
|
||||
} else {
|
||||
return m.messageInfo().extensionMap(m.pointer()).Get(xt)
|
||||
}
|
||||
}
|
||||
func (m *messageState) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
fi.set(m.pointer(), v)
|
||||
} else {
|
||||
m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
|
||||
}
|
||||
}
|
||||
func (m *messageState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
return fi.mutable(m.pointer())
|
||||
} else {
|
||||
return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
|
||||
}
|
||||
}
|
||||
func (m *messageState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
return fi.newField()
|
||||
} else {
|
||||
return xt.New()
|
||||
}
|
||||
}
|
||||
func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
|
||||
m.messageInfo().init()
|
||||
if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
|
||||
return od.Fields().ByNumber(oi.which(m.pointer()))
|
||||
}
|
||||
panic("invalid oneof descriptor")
|
||||
}
|
||||
func (m *messageState) GetUnknown() protoreflect.RawFields {
|
||||
m.messageInfo().init()
|
||||
return m.messageInfo().getUnknown(m.pointer())
|
||||
}
|
||||
func (m *messageState) SetUnknown(b protoreflect.RawFields) {
|
||||
m.messageInfo().init()
|
||||
m.messageInfo().setUnknown(m.pointer(), b)
|
||||
}
|
||||
func (m *messageState) IsValid() bool {
|
||||
return !m.pointer().IsNil()
|
||||
}
|
||||
|
||||
func (m *messageReflectWrapper) Descriptor() protoreflect.MessageDescriptor {
|
||||
return m.messageInfo().Desc
|
||||
}
|
||||
func (m *messageReflectWrapper) Type() protoreflect.MessageType {
|
||||
return m.messageInfo()
|
||||
}
|
||||
func (m *messageReflectWrapper) New() protoreflect.Message {
|
||||
return m.messageInfo().New()
|
||||
}
|
||||
func (m *messageReflectWrapper) Interface() protoreflect.ProtoMessage {
|
||||
if m, ok := m.protoUnwrap().(protoreflect.ProtoMessage); ok {
|
||||
return m
|
||||
}
|
||||
return (*messageIfaceWrapper)(m)
|
||||
}
|
||||
func (m *messageReflectWrapper) protoUnwrap() interface{} {
|
||||
return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
|
||||
}
|
||||
func (m *messageReflectWrapper) ProtoMethods() *protoiface.Methods {
|
||||
m.messageInfo().init()
|
||||
return &m.messageInfo().methods
|
||||
}
|
||||
|
||||
// ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
|
||||
// to be able to retrieve a v2 MessageInfo struct.
|
||||
//
|
||||
// WARNING: This method is exempt from the compatibility promise and
|
||||
// may be removed in the future without warning.
|
||||
func (m *messageReflectWrapper) ProtoMessageInfo() *MessageInfo {
|
||||
return m.messageInfo()
|
||||
}
|
||||
|
||||
func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
|
||||
m.messageInfo().init()
|
||||
for _, ri := range m.messageInfo().rangeInfos {
|
||||
switch ri := ri.(type) {
|
||||
case *fieldInfo:
|
||||
if ri.has(m.pointer()) {
|
||||
if !f(ri.fieldDesc, ri.get(m.pointer())) {
|
||||
return
|
||||
}
|
||||
}
|
||||
case *oneofInfo:
|
||||
if n := ri.which(m.pointer()); n > 0 {
|
||||
fi := m.messageInfo().fields[n]
|
||||
if !f(fi.fieldDesc, fi.get(m.pointer())) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m.messageInfo().extensionMap(m.pointer()).Range(f)
|
||||
}
|
||||
func (m *messageReflectWrapper) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
return fi.has(m.pointer())
|
||||
} else {
|
||||
return m.messageInfo().extensionMap(m.pointer()).Has(xt)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) Clear(fd protoreflect.FieldDescriptor) {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
fi.clear(m.pointer())
|
||||
} else {
|
||||
m.messageInfo().extensionMap(m.pointer()).Clear(xt)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
return fi.get(m.pointer())
|
||||
} else {
|
||||
return m.messageInfo().extensionMap(m.pointer()).Get(xt)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
fi.set(m.pointer(), v)
|
||||
} else {
|
||||
m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
return fi.mutable(m.pointer())
|
||||
} else {
|
||||
return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
m.messageInfo().init()
|
||||
if fi, xt := m.messageInfo().checkField(fd); fi != nil {
|
||||
return fi.newField()
|
||||
} else {
|
||||
return xt.New()
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
|
||||
m.messageInfo().init()
|
||||
if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
|
||||
return od.Fields().ByNumber(oi.which(m.pointer()))
|
||||
}
|
||||
panic("invalid oneof descriptor")
|
||||
}
|
||||
func (m *messageReflectWrapper) GetUnknown() protoreflect.RawFields {
|
||||
m.messageInfo().init()
|
||||
return m.messageInfo().getUnknown(m.pointer())
|
||||
}
|
||||
func (m *messageReflectWrapper) SetUnknown(b protoreflect.RawFields) {
|
||||
m.messageInfo().init()
|
||||
m.messageInfo().setUnknown(m.pointer(), b)
|
||||
}
|
||||
func (m *messageReflectWrapper) IsValid() bool {
|
||||
return !m.pointer().IsNil()
|
||||
}
|
177
vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go
generated
vendored
Normal file
177
vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go
generated
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build purego appengine
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const UnsafeEnabled = false
|
||||
|
||||
// Pointer is an opaque pointer type.
|
||||
type Pointer interface{}
|
||||
|
||||
// offset represents the offset to a struct field, accessible from a pointer.
|
||||
// The offset is the field index into a struct.
|
||||
type offset struct {
|
||||
index int
|
||||
export exporter
|
||||
}
|
||||
|
||||
// offsetOf returns a field offset for the struct field.
|
||||
func offsetOf(f reflect.StructField, x exporter) offset {
|
||||
if len(f.Index) != 1 {
|
||||
panic("embedded structs are not supported")
|
||||
}
|
||||
if f.PkgPath == "" {
|
||||
return offset{index: f.Index[0]} // field is already exported
|
||||
}
|
||||
if x == nil {
|
||||
panic("exporter must be provided for unexported field")
|
||||
}
|
||||
return offset{index: f.Index[0], export: x}
|
||||
}
|
||||
|
||||
// IsValid reports whether the offset is valid.
|
||||
func (f offset) IsValid() bool { return f.index >= 0 }
|
||||
|
||||
// invalidOffset is an invalid field offset.
|
||||
var invalidOffset = offset{index: -1}
|
||||
|
||||
// zeroOffset is a noop when calling pointer.Apply.
|
||||
var zeroOffset = offset{index: 0}
|
||||
|
||||
// pointer is an abstract representation of a pointer to a struct or field.
|
||||
type pointer struct{ v reflect.Value }
|
||||
|
||||
// pointerOf returns p as a pointer.
|
||||
func pointerOf(p Pointer) pointer {
|
||||
return pointerOfIface(p)
|
||||
}
|
||||
|
||||
// pointerOfValue returns v as a pointer.
|
||||
func pointerOfValue(v reflect.Value) pointer {
|
||||
return pointer{v: v}
|
||||
}
|
||||
|
||||
// pointerOfIface returns the pointer portion of an interface.
|
||||
func pointerOfIface(v interface{}) pointer {
|
||||
return pointer{v: reflect.ValueOf(v)}
|
||||
}
|
||||
|
||||
// IsNil reports whether the pointer is nil.
|
||||
func (p pointer) IsNil() bool {
|
||||
return p.v.IsNil()
|
||||
}
|
||||
|
||||
// Apply adds an offset to the pointer to derive a new pointer
|
||||
// to a specified field. The current pointer must be pointing at a struct.
|
||||
func (p pointer) Apply(f offset) pointer {
|
||||
if f.export != nil {
|
||||
if v := reflect.ValueOf(f.export(p.v.Interface(), f.index)); v.IsValid() {
|
||||
return pointer{v: v}
|
||||
}
|
||||
}
|
||||
return pointer{v: p.v.Elem().Field(f.index).Addr()}
|
||||
}
|
||||
|
||||
// AsValueOf treats p as a pointer to an object of type t and returns the value.
|
||||
// It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
|
||||
func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
|
||||
if got := p.v.Type().Elem(); got != t {
|
||||
panic(fmt.Sprintf("invalid type: got %v, want %v", got, t))
|
||||
}
|
||||
return p.v
|
||||
}
|
||||
|
||||
// AsIfaceOf treats p as a pointer to an object of type t and returns the value.
|
||||
// It is equivalent to p.AsValueOf(t).Interface()
|
||||
func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
|
||||
return p.AsValueOf(t).Interface()
|
||||
}
|
||||
|
||||
func (p pointer) Bool() *bool { return p.v.Interface().(*bool) }
|
||||
func (p pointer) BoolPtr() **bool { return p.v.Interface().(**bool) }
|
||||
func (p pointer) BoolSlice() *[]bool { return p.v.Interface().(*[]bool) }
|
||||
func (p pointer) Int32() *int32 { return p.v.Interface().(*int32) }
|
||||
func (p pointer) Int32Ptr() **int32 { return p.v.Interface().(**int32) }
|
||||
func (p pointer) Int32Slice() *[]int32 { return p.v.Interface().(*[]int32) }
|
||||
func (p pointer) Int64() *int64 { return p.v.Interface().(*int64) }
|
||||
func (p pointer) Int64Ptr() **int64 { return p.v.Interface().(**int64) }
|
||||
func (p pointer) Int64Slice() *[]int64 { return p.v.Interface().(*[]int64) }
|
||||
func (p pointer) Uint32() *uint32 { return p.v.Interface().(*uint32) }
|
||||
func (p pointer) Uint32Ptr() **uint32 { return p.v.Interface().(**uint32) }
|
||||
func (p pointer) Uint32Slice() *[]uint32 { return p.v.Interface().(*[]uint32) }
|
||||
func (p pointer) Uint64() *uint64 { return p.v.Interface().(*uint64) }
|
||||
func (p pointer) Uint64Ptr() **uint64 { return p.v.Interface().(**uint64) }
|
||||
func (p pointer) Uint64Slice() *[]uint64 { return p.v.Interface().(*[]uint64) }
|
||||
func (p pointer) Float32() *float32 { return p.v.Interface().(*float32) }
|
||||
func (p pointer) Float32Ptr() **float32 { return p.v.Interface().(**float32) }
|
||||
func (p pointer) Float32Slice() *[]float32 { return p.v.Interface().(*[]float32) }
|
||||
func (p pointer) Float64() *float64 { return p.v.Interface().(*float64) }
|
||||
func (p pointer) Float64Ptr() **float64 { return p.v.Interface().(**float64) }
|
||||
func (p pointer) Float64Slice() *[]float64 { return p.v.Interface().(*[]float64) }
|
||||
func (p pointer) String() *string { return p.v.Interface().(*string) }
|
||||
func (p pointer) StringPtr() **string { return p.v.Interface().(**string) }
|
||||
func (p pointer) StringSlice() *[]string { return p.v.Interface().(*[]string) }
|
||||
func (p pointer) Bytes() *[]byte { return p.v.Interface().(*[]byte) }
|
||||
func (p pointer) BytesSlice() *[][]byte { return p.v.Interface().(*[][]byte) }
|
||||
func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.v.Interface().(*WeakFields)) }
|
||||
func (p pointer) Extensions() *map[int32]ExtensionField {
|
||||
return p.v.Interface().(*map[int32]ExtensionField)
|
||||
}
|
||||
|
||||
func (p pointer) Elem() pointer {
|
||||
return pointer{v: p.v.Elem()}
|
||||
}
|
||||
|
||||
// PointerSlice copies []*T from p as a new []pointer.
|
||||
// This behavior differs from the implementation in pointer_unsafe.go.
|
||||
func (p pointer) PointerSlice() []pointer {
|
||||
// TODO: reconsider this
|
||||
if p.v.IsNil() {
|
||||
return nil
|
||||
}
|
||||
n := p.v.Elem().Len()
|
||||
s := make([]pointer, n)
|
||||
for i := 0; i < n; i++ {
|
||||
s[i] = pointer{v: p.v.Elem().Index(i)}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// AppendPointerSlice appends v to p, which must be a []*T.
|
||||
func (p pointer) AppendPointerSlice(v pointer) {
|
||||
sp := p.v.Elem()
|
||||
sp.Set(reflect.Append(sp, v.v))
|
||||
}
|
||||
|
||||
// SetPointer sets *p to v.
|
||||
func (p pointer) SetPointer(v pointer) {
|
||||
p.v.Elem().Set(v.v)
|
||||
}
|
||||
|
||||
func (Export) MessageStateOf(p Pointer) *messageState { panic("not supported") }
|
||||
func (ms *messageState) pointer() pointer { panic("not supported") }
|
||||
func (ms *messageState) messageInfo() *MessageInfo { panic("not supported") }
|
||||
func (ms *messageState) LoadMessageInfo() *MessageInfo { panic("not supported") }
|
||||
func (ms *messageState) StoreMessageInfo(mi *MessageInfo) { panic("not supported") }
|
||||
|
||||
type atomicNilMessage struct {
|
||||
once sync.Once
|
||||
m messageReflectWrapper
|
||||
}
|
||||
|
||||
func (m *atomicNilMessage) Init(mi *MessageInfo) *messageReflectWrapper {
|
||||
m.once.Do(func() {
|
||||
m.m.p = pointerOfIface(reflect.Zero(mi.GoReflectType).Interface())
|
||||
m.m.mi = mi
|
||||
})
|
||||
return &m.m
|
||||
}
|
169
vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
generated
vendored
Normal file
169
vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
generated
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !purego,!appengine
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const UnsafeEnabled = true
|
||||
|
||||
// Pointer is an opaque pointer type.
|
||||
type Pointer unsafe.Pointer
|
||||
|
||||
// offset represents the offset to a struct field, accessible from a pointer.
|
||||
// The offset is the byte offset to the field from the start of the struct.
|
||||
type offset uintptr
|
||||
|
||||
// offsetOf returns a field offset for the struct field.
|
||||
func offsetOf(f reflect.StructField, x exporter) offset {
|
||||
return offset(f.Offset)
|
||||
}
|
||||
|
||||
// IsValid reports whether the offset is valid.
|
||||
func (f offset) IsValid() bool { return f != invalidOffset }
|
||||
|
||||
// invalidOffset is an invalid field offset.
|
||||
var invalidOffset = ^offset(0)
|
||||
|
||||
// zeroOffset is a noop when calling pointer.Apply.
|
||||
var zeroOffset = offset(0)
|
||||
|
||||
// pointer is a pointer to a message struct or field.
|
||||
type pointer struct{ p unsafe.Pointer }
|
||||
|
||||
// pointerOf returns p as a pointer.
|
||||
func pointerOf(p Pointer) pointer {
|
||||
return pointer{p: unsafe.Pointer(p)}
|
||||
}
|
||||
|
||||
// pointerOfValue returns v as a pointer.
|
||||
func pointerOfValue(v reflect.Value) pointer {
|
||||
return pointer{p: unsafe.Pointer(v.Pointer())}
|
||||
}
|
||||
|
||||
// pointerOfIface returns the pointer portion of an interface.
|
||||
func pointerOfIface(v interface{}) pointer {
|
||||
type ifaceHeader struct {
|
||||
Type unsafe.Pointer
|
||||
Data unsafe.Pointer
|
||||
}
|
||||
return pointer{p: (*ifaceHeader)(unsafe.Pointer(&v)).Data}
|
||||
}
|
||||
|
||||
// IsNil reports whether the pointer is nil.
|
||||
func (p pointer) IsNil() bool {
|
||||
return p.p == nil
|
||||
}
|
||||
|
||||
// Apply adds an offset to the pointer to derive a new pointer
|
||||
// to a specified field. The pointer must be valid and pointing at a struct.
|
||||
func (p pointer) Apply(f offset) pointer {
|
||||
if p.IsNil() {
|
||||
panic("invalid nil pointer")
|
||||
}
|
||||
return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
|
||||
}
|
||||
|
||||
// AsValueOf treats p as a pointer to an object of type t and returns the value.
|
||||
// It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
|
||||
func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
|
||||
return reflect.NewAt(t, p.p)
|
||||
}
|
||||
|
||||
// AsIfaceOf treats p as a pointer to an object of type t and returns the value.
|
||||
// It is equivalent to p.AsValueOf(t).Interface()
|
||||
func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
|
||||
// TODO: Use tricky unsafe magic to directly create ifaceHeader.
|
||||
return p.AsValueOf(t).Interface()
|
||||
}
|
||||
|
||||
func (p pointer) Bool() *bool { return (*bool)(p.p) }
|
||||
func (p pointer) BoolPtr() **bool { return (**bool)(p.p) }
|
||||
func (p pointer) BoolSlice() *[]bool { return (*[]bool)(p.p) }
|
||||
func (p pointer) Int32() *int32 { return (*int32)(p.p) }
|
||||
func (p pointer) Int32Ptr() **int32 { return (**int32)(p.p) }
|
||||
func (p pointer) Int32Slice() *[]int32 { return (*[]int32)(p.p) }
|
||||
func (p pointer) Int64() *int64 { return (*int64)(p.p) }
|
||||
func (p pointer) Int64Ptr() **int64 { return (**int64)(p.p) }
|
||||
func (p pointer) Int64Slice() *[]int64 { return (*[]int64)(p.p) }
|
||||
func (p pointer) Uint32() *uint32 { return (*uint32)(p.p) }
|
||||
func (p pointer) Uint32Ptr() **uint32 { return (**uint32)(p.p) }
|
||||
func (p pointer) Uint32Slice() *[]uint32 { return (*[]uint32)(p.p) }
|
||||
func (p pointer) Uint64() *uint64 { return (*uint64)(p.p) }
|
||||
func (p pointer) Uint64Ptr() **uint64 { return (**uint64)(p.p) }
|
||||
func (p pointer) Uint64Slice() *[]uint64 { return (*[]uint64)(p.p) }
|
||||
func (p pointer) Float32() *float32 { return (*float32)(p.p) }
|
||||
func (p pointer) Float32Ptr() **float32 { return (**float32)(p.p) }
|
||||
func (p pointer) Float32Slice() *[]float32 { return (*[]float32)(p.p) }
|
||||
func (p pointer) Float64() *float64 { return (*float64)(p.p) }
|
||||
func (p pointer) Float64Ptr() **float64 { return (**float64)(p.p) }
|
||||
func (p pointer) Float64Slice() *[]float64 { return (*[]float64)(p.p) }
|
||||
func (p pointer) String() *string { return (*string)(p.p) }
|
||||
func (p pointer) StringPtr() **string { return (**string)(p.p) }
|
||||
func (p pointer) StringSlice() *[]string { return (*[]string)(p.p) }
|
||||
func (p pointer) Bytes() *[]byte { return (*[]byte)(p.p) }
|
||||
func (p pointer) BytesSlice() *[][]byte { return (*[][]byte)(p.p) }
|
||||
func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.p) }
|
||||
func (p pointer) Extensions() *map[int32]ExtensionField { return (*map[int32]ExtensionField)(p.p) }
|
||||
|
||||
func (p pointer) Elem() pointer {
|
||||
return pointer{p: *(*unsafe.Pointer)(p.p)}
|
||||
}
|
||||
|
||||
// PointerSlice loads []*T from p as a []pointer.
|
||||
// The value returned is aliased with the original slice.
|
||||
// This behavior differs from the implementation in pointer_reflect.go.
|
||||
func (p pointer) PointerSlice() []pointer {
|
||||
// Super-tricky - p should point to a []*T where T is a
|
||||
// message type. We load it as []pointer.
|
||||
return *(*[]pointer)(p.p)
|
||||
}
|
||||
|
||||
// AppendPointerSlice appends v to p, which must be a []*T.
|
||||
func (p pointer) AppendPointerSlice(v pointer) {
|
||||
*(*[]pointer)(p.p) = append(*(*[]pointer)(p.p), v)
|
||||
}
|
||||
|
||||
// SetPointer sets *p to v.
|
||||
func (p pointer) SetPointer(v pointer) {
|
||||
*(*unsafe.Pointer)(p.p) = (unsafe.Pointer)(v.p)
|
||||
}
|
||||
|
||||
// Static check that MessageState does not exceed the size of a pointer.
|
||||
const _ = uint(unsafe.Sizeof(unsafe.Pointer(nil)) - unsafe.Sizeof(MessageState{}))
|
||||
|
||||
func (Export) MessageStateOf(p Pointer) *messageState {
|
||||
// Super-tricky - see documentation on MessageState.
|
||||
return (*messageState)(unsafe.Pointer(p))
|
||||
}
|
||||
func (ms *messageState) pointer() pointer {
|
||||
// Super-tricky - see documentation on MessageState.
|
||||
return pointer{p: unsafe.Pointer(ms)}
|
||||
}
|
||||
func (ms *messageState) messageInfo() *MessageInfo {
|
||||
return ms.LoadMessageInfo()
|
||||
}
|
||||
func (ms *messageState) LoadMessageInfo() *MessageInfo {
|
||||
return (*MessageInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&ms.atomicMessageInfo))))
|
||||
}
|
||||
func (ms *messageState) StoreMessageInfo(mi *MessageInfo) {
|
||||
atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&ms.atomicMessageInfo)), unsafe.Pointer(mi))
|
||||
}
|
||||
|
||||
type atomicNilMessage struct{ p unsafe.Pointer } // p is a *messageReflectWrapper
|
||||
|
||||
func (m *atomicNilMessage) Init(mi *MessageInfo) *messageReflectWrapper {
|
||||
if p := atomic.LoadPointer(&m.p); p != nil {
|
||||
return (*messageReflectWrapper)(p)
|
||||
}
|
||||
w := &messageReflectWrapper{mi: mi}
|
||||
atomic.CompareAndSwapPointer(&m.p, nil, (unsafe.Pointer)(w))
|
||||
return (*messageReflectWrapper)(atomic.LoadPointer(&m.p))
|
||||
}
|
575
vendor/google.golang.org/protobuf/internal/impl/validate.go
generated
vendored
Normal file
575
vendor/google.golang.org/protobuf/internal/impl/validate.go
generated
vendored
Normal file
|
@ -0,0 +1,575 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/bits"
|
||||
"reflect"
|
||||
"unicode/utf8"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
"google.golang.org/protobuf/internal/encoding/messageset"
|
||||
"google.golang.org/protobuf/internal/flags"
|
||||
"google.golang.org/protobuf/internal/strs"
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
preg "google.golang.org/protobuf/reflect/protoregistry"
|
||||
piface "google.golang.org/protobuf/runtime/protoiface"
|
||||
)
|
||||
|
||||
// ValidationStatus is the result of validating the wire-format encoding of a message.
|
||||
type ValidationStatus int
|
||||
|
||||
const (
|
||||
// ValidationUnknown indicates that unmarshaling the message might succeed or fail.
|
||||
// The validator was unable to render a judgement.
|
||||
//
|
||||
// The only causes of this status are an aberrant message type appearing somewhere
|
||||
// in the message or a failure in the extension resolver.
|
||||
ValidationUnknown ValidationStatus = iota + 1
|
||||
|
||||
// ValidationInvalid indicates that unmarshaling the message will fail.
|
||||
ValidationInvalid
|
||||
|
||||
// ValidationValid indicates that unmarshaling the message will succeed.
|
||||
ValidationValid
|
||||
)
|
||||
|
||||
func (v ValidationStatus) String() string {
|
||||
switch v {
|
||||
case ValidationUnknown:
|
||||
return "ValidationUnknown"
|
||||
case ValidationInvalid:
|
||||
return "ValidationInvalid"
|
||||
case ValidationValid:
|
||||
return "ValidationValid"
|
||||
default:
|
||||
return fmt.Sprintf("ValidationStatus(%d)", int(v))
|
||||
}
|
||||
}
|
||||
|
||||
// Validate determines whether the contents of the buffer are a valid wire encoding
|
||||
// of the message type.
|
||||
//
|
||||
// This function is exposed for testing.
|
||||
func Validate(mt pref.MessageType, in piface.UnmarshalInput) (out piface.UnmarshalOutput, _ ValidationStatus) {
|
||||
mi, ok := mt.(*MessageInfo)
|
||||
if !ok {
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
if in.Resolver == nil {
|
||||
in.Resolver = preg.GlobalTypes
|
||||
}
|
||||
o, st := mi.validate(in.Buf, 0, unmarshalOptions{
|
||||
flags: in.Flags,
|
||||
resolver: in.Resolver,
|
||||
})
|
||||
if o.initialized {
|
||||
out.Flags |= piface.UnmarshalInitialized
|
||||
}
|
||||
return out, st
|
||||
}
|
||||
|
||||
type validationInfo struct {
|
||||
mi *MessageInfo
|
||||
typ validationType
|
||||
keyType, valType validationType
|
||||
|
||||
// For non-required fields, requiredBit is 0.
|
||||
//
|
||||
// For required fields, requiredBit's nth bit is set, where n is a
|
||||
// unique index in the range [0, MessageInfo.numRequiredFields).
|
||||
//
|
||||
// If there are more than 64 required fields, requiredBit is 0.
|
||||
requiredBit uint64
|
||||
}
|
||||
|
||||
type validationType uint8
|
||||
|
||||
const (
|
||||
validationTypeOther validationType = iota
|
||||
validationTypeMessage
|
||||
validationTypeGroup
|
||||
validationTypeMap
|
||||
validationTypeRepeatedVarint
|
||||
validationTypeRepeatedFixed32
|
||||
validationTypeRepeatedFixed64
|
||||
validationTypeVarint
|
||||
validationTypeFixed32
|
||||
validationTypeFixed64
|
||||
validationTypeBytes
|
||||
validationTypeUTF8String
|
||||
validationTypeMessageSetItem
|
||||
)
|
||||
|
||||
func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescriptor, ft reflect.Type) validationInfo {
|
||||
var vi validationInfo
|
||||
switch {
|
||||
case fd.ContainingOneof() != nil:
|
||||
switch fd.Kind() {
|
||||
case pref.MessageKind:
|
||||
vi.typ = validationTypeMessage
|
||||
if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok {
|
||||
vi.mi = getMessageInfo(ot.Field(0).Type)
|
||||
}
|
||||
case pref.GroupKind:
|
||||
vi.typ = validationTypeGroup
|
||||
if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok {
|
||||
vi.mi = getMessageInfo(ot.Field(0).Type)
|
||||
}
|
||||
case pref.StringKind:
|
||||
if strs.EnforceUTF8(fd) {
|
||||
vi.typ = validationTypeUTF8String
|
||||
}
|
||||
}
|
||||
default:
|
||||
vi = newValidationInfo(fd, ft)
|
||||
}
|
||||
if fd.Cardinality() == pref.Required {
|
||||
// Avoid overflow. The required field check is done with a 64-bit mask, with
|
||||
// any message containing more than 64 required fields always reported as
|
||||
// potentially uninitialized, so it is not important to get a precise count
|
||||
// of the required fields past 64.
|
||||
if mi.numRequiredFields < math.MaxUint8 {
|
||||
mi.numRequiredFields++
|
||||
vi.requiredBit = 1 << (mi.numRequiredFields - 1)
|
||||
}
|
||||
}
|
||||
return vi
|
||||
}
|
||||
|
||||
func newValidationInfo(fd pref.FieldDescriptor, ft reflect.Type) validationInfo {
|
||||
var vi validationInfo
|
||||
switch {
|
||||
case fd.IsList():
|
||||
switch fd.Kind() {
|
||||
case pref.MessageKind:
|
||||
vi.typ = validationTypeMessage
|
||||
if ft.Kind() == reflect.Slice {
|
||||
vi.mi = getMessageInfo(ft.Elem())
|
||||
}
|
||||
case pref.GroupKind:
|
||||
vi.typ = validationTypeGroup
|
||||
if ft.Kind() == reflect.Slice {
|
||||
vi.mi = getMessageInfo(ft.Elem())
|
||||
}
|
||||
case pref.StringKind:
|
||||
vi.typ = validationTypeBytes
|
||||
if strs.EnforceUTF8(fd) {
|
||||
vi.typ = validationTypeUTF8String
|
||||
}
|
||||
default:
|
||||
switch wireTypes[fd.Kind()] {
|
||||
case protowire.VarintType:
|
||||
vi.typ = validationTypeRepeatedVarint
|
||||
case protowire.Fixed32Type:
|
||||
vi.typ = validationTypeRepeatedFixed32
|
||||
case protowire.Fixed64Type:
|
||||
vi.typ = validationTypeRepeatedFixed64
|
||||
}
|
||||
}
|
||||
case fd.IsMap():
|
||||
vi.typ = validationTypeMap
|
||||
switch fd.MapKey().Kind() {
|
||||
case pref.StringKind:
|
||||
if strs.EnforceUTF8(fd) {
|
||||
vi.keyType = validationTypeUTF8String
|
||||
}
|
||||
}
|
||||
switch fd.MapValue().Kind() {
|
||||
case pref.MessageKind:
|
||||
vi.valType = validationTypeMessage
|
||||
if ft.Kind() == reflect.Map {
|
||||
vi.mi = getMessageInfo(ft.Elem())
|
||||
}
|
||||
case pref.StringKind:
|
||||
if strs.EnforceUTF8(fd) {
|
||||
vi.valType = validationTypeUTF8String
|
||||
}
|
||||
}
|
||||
default:
|
||||
switch fd.Kind() {
|
||||
case pref.MessageKind:
|
||||
vi.typ = validationTypeMessage
|
||||
if !fd.IsWeak() {
|
||||
vi.mi = getMessageInfo(ft)
|
||||
}
|
||||
case pref.GroupKind:
|
||||
vi.typ = validationTypeGroup
|
||||
vi.mi = getMessageInfo(ft)
|
||||
case pref.StringKind:
|
||||
vi.typ = validationTypeBytes
|
||||
if strs.EnforceUTF8(fd) {
|
||||
vi.typ = validationTypeUTF8String
|
||||
}
|
||||
default:
|
||||
switch wireTypes[fd.Kind()] {
|
||||
case protowire.VarintType:
|
||||
vi.typ = validationTypeVarint
|
||||
case protowire.Fixed32Type:
|
||||
vi.typ = validationTypeFixed32
|
||||
case protowire.Fixed64Type:
|
||||
vi.typ = validationTypeFixed64
|
||||
case protowire.BytesType:
|
||||
vi.typ = validationTypeBytes
|
||||
}
|
||||
}
|
||||
}
|
||||
return vi
|
||||
}
|
||||
|
||||
func (mi *MessageInfo) validate(b []byte, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, result ValidationStatus) {
|
||||
mi.init()
|
||||
type validationState struct {
|
||||
typ validationType
|
||||
keyType, valType validationType
|
||||
endGroup protowire.Number
|
||||
mi *MessageInfo
|
||||
tail []byte
|
||||
requiredMask uint64
|
||||
}
|
||||
|
||||
// Pre-allocate some slots to avoid repeated slice reallocation.
|
||||
states := make([]validationState, 0, 16)
|
||||
states = append(states, validationState{
|
||||
typ: validationTypeMessage,
|
||||
mi: mi,
|
||||
})
|
||||
if groupTag > 0 {
|
||||
states[0].typ = validationTypeGroup
|
||||
states[0].endGroup = groupTag
|
||||
}
|
||||
initialized := true
|
||||
start := len(b)
|
||||
State:
|
||||
for len(states) > 0 {
|
||||
st := &states[len(states)-1]
|
||||
for len(b) > 0 {
|
||||
// Parse the tag (field number and wire type).
|
||||
var tag uint64
|
||||
if b[0] < 0x80 {
|
||||
tag = uint64(b[0])
|
||||
b = b[1:]
|
||||
} else if len(b) >= 2 && b[1] < 128 {
|
||||
tag = uint64(b[0]&0x7f) + uint64(b[1])<<7
|
||||
b = b[2:]
|
||||
} else {
|
||||
var n int
|
||||
tag, n = protowire.ConsumeVarint(b)
|
||||
if n < 0 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
var num protowire.Number
|
||||
if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) {
|
||||
return out, ValidationInvalid
|
||||
} else {
|
||||
num = protowire.Number(n)
|
||||
}
|
||||
wtyp := protowire.Type(tag & 7)
|
||||
|
||||
if wtyp == protowire.EndGroupType {
|
||||
if st.endGroup == num {
|
||||
goto PopState
|
||||
}
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
var vi validationInfo
|
||||
switch {
|
||||
case st.typ == validationTypeMap:
|
||||
switch num {
|
||||
case 1:
|
||||
vi.typ = st.keyType
|
||||
case 2:
|
||||
vi.typ = st.valType
|
||||
vi.mi = st.mi
|
||||
vi.requiredBit = 1
|
||||
}
|
||||
case flags.ProtoLegacy && st.mi.isMessageSet:
|
||||
switch num {
|
||||
case messageset.FieldItem:
|
||||
vi.typ = validationTypeMessageSetItem
|
||||
}
|
||||
default:
|
||||
var f *coderFieldInfo
|
||||
if int(num) < len(st.mi.denseCoderFields) {
|
||||
f = st.mi.denseCoderFields[num]
|
||||
} else {
|
||||
f = st.mi.coderFields[num]
|
||||
}
|
||||
if f != nil {
|
||||
vi = f.validation
|
||||
if vi.typ == validationTypeMessage && vi.mi == nil {
|
||||
// Probable weak field.
|
||||
//
|
||||
// TODO: Consider storing the results of this lookup somewhere
|
||||
// rather than recomputing it on every validation.
|
||||
fd := st.mi.Desc.Fields().ByNumber(num)
|
||||
if fd == nil || !fd.IsWeak() {
|
||||
break
|
||||
}
|
||||
messageName := fd.Message().FullName()
|
||||
messageType, err := preg.GlobalTypes.FindMessageByName(messageName)
|
||||
switch err {
|
||||
case nil:
|
||||
vi.mi, _ = messageType.(*MessageInfo)
|
||||
case preg.NotFound:
|
||||
vi.typ = validationTypeBytes
|
||||
default:
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// Possible extension field.
|
||||
//
|
||||
// TODO: We should return ValidationUnknown when:
|
||||
// 1. The resolver is not frozen. (More extensions may be added to it.)
|
||||
// 2. The resolver returns preg.NotFound.
|
||||
// In this case, a type added to the resolver in the future could cause
|
||||
// unmarshaling to begin failing. Supporting this requires some way to
|
||||
// determine if the resolver is frozen.
|
||||
xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), num)
|
||||
if err != nil && err != preg.NotFound {
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
if err == nil {
|
||||
vi = getExtensionFieldInfo(xt).validation
|
||||
}
|
||||
}
|
||||
if vi.requiredBit != 0 {
|
||||
// Check that the field has a compatible wire type.
|
||||
// We only need to consider non-repeated field types,
|
||||
// since repeated fields (and maps) can never be required.
|
||||
ok := false
|
||||
switch vi.typ {
|
||||
case validationTypeVarint:
|
||||
ok = wtyp == protowire.VarintType
|
||||
case validationTypeFixed32:
|
||||
ok = wtyp == protowire.Fixed32Type
|
||||
case validationTypeFixed64:
|
||||
ok = wtyp == protowire.Fixed64Type
|
||||
case validationTypeBytes, validationTypeUTF8String, validationTypeMessage:
|
||||
ok = wtyp == protowire.BytesType
|
||||
case validationTypeGroup:
|
||||
ok = wtyp == protowire.StartGroupType
|
||||
}
|
||||
if ok {
|
||||
st.requiredMask |= vi.requiredBit
|
||||
}
|
||||
}
|
||||
|
||||
switch wtyp {
|
||||
case protowire.VarintType:
|
||||
if len(b) >= 10 {
|
||||
switch {
|
||||
case b[0] < 0x80:
|
||||
b = b[1:]
|
||||
case b[1] < 0x80:
|
||||
b = b[2:]
|
||||
case b[2] < 0x80:
|
||||
b = b[3:]
|
||||
case b[3] < 0x80:
|
||||
b = b[4:]
|
||||
case b[4] < 0x80:
|
||||
b = b[5:]
|
||||
case b[5] < 0x80:
|
||||
b = b[6:]
|
||||
case b[6] < 0x80:
|
||||
b = b[7:]
|
||||
case b[7] < 0x80:
|
||||
b = b[8:]
|
||||
case b[8] < 0x80:
|
||||
b = b[9:]
|
||||
case b[9] < 0x80 && b[9] < 2:
|
||||
b = b[10:]
|
||||
default:
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
} else {
|
||||
switch {
|
||||
case len(b) > 0 && b[0] < 0x80:
|
||||
b = b[1:]
|
||||
case len(b) > 1 && b[1] < 0x80:
|
||||
b = b[2:]
|
||||
case len(b) > 2 && b[2] < 0x80:
|
||||
b = b[3:]
|
||||
case len(b) > 3 && b[3] < 0x80:
|
||||
b = b[4:]
|
||||
case len(b) > 4 && b[4] < 0x80:
|
||||
b = b[5:]
|
||||
case len(b) > 5 && b[5] < 0x80:
|
||||
b = b[6:]
|
||||
case len(b) > 6 && b[6] < 0x80:
|
||||
b = b[7:]
|
||||
case len(b) > 7 && b[7] < 0x80:
|
||||
b = b[8:]
|
||||
case len(b) > 8 && b[8] < 0x80:
|
||||
b = b[9:]
|
||||
case len(b) > 9 && b[9] < 2:
|
||||
b = b[10:]
|
||||
default:
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
}
|
||||
continue State
|
||||
case protowire.BytesType:
|
||||
var size uint64
|
||||
if len(b) >= 1 && b[0] < 0x80 {
|
||||
size = uint64(b[0])
|
||||
b = b[1:]
|
||||
} else if len(b) >= 2 && b[1] < 128 {
|
||||
size = uint64(b[0]&0x7f) + uint64(b[1])<<7
|
||||
b = b[2:]
|
||||
} else {
|
||||
var n int
|
||||
size, n = protowire.ConsumeVarint(b)
|
||||
if n < 0 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
if size > uint64(len(b)) {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
v := b[:size]
|
||||
b = b[size:]
|
||||
switch vi.typ {
|
||||
case validationTypeMessage:
|
||||
if vi.mi == nil {
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
vi.mi.init()
|
||||
fallthrough
|
||||
case validationTypeMap:
|
||||
if vi.mi != nil {
|
||||
vi.mi.init()
|
||||
}
|
||||
states = append(states, validationState{
|
||||
typ: vi.typ,
|
||||
keyType: vi.keyType,
|
||||
valType: vi.valType,
|
||||
mi: vi.mi,
|
||||
tail: b,
|
||||
})
|
||||
b = v
|
||||
continue State
|
||||
case validationTypeRepeatedVarint:
|
||||
// Packed field.
|
||||
for len(v) > 0 {
|
||||
_, n := protowire.ConsumeVarint(v)
|
||||
if n < 0 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
v = v[n:]
|
||||
}
|
||||
case validationTypeRepeatedFixed32:
|
||||
// Packed field.
|
||||
if len(v)%4 != 0 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
case validationTypeRepeatedFixed64:
|
||||
// Packed field.
|
||||
if len(v)%8 != 0 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
case validationTypeUTF8String:
|
||||
if !utf8.Valid(v) {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
}
|
||||
case protowire.Fixed32Type:
|
||||
if len(b) < 4 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
b = b[4:]
|
||||
case protowire.Fixed64Type:
|
||||
if len(b) < 8 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
b = b[8:]
|
||||
case protowire.StartGroupType:
|
||||
switch {
|
||||
case vi.typ == validationTypeGroup:
|
||||
if vi.mi == nil {
|
||||
return out, ValidationUnknown
|
||||
}
|
||||
vi.mi.init()
|
||||
states = append(states, validationState{
|
||||
typ: validationTypeGroup,
|
||||
mi: vi.mi,
|
||||
endGroup: num,
|
||||
})
|
||||
continue State
|
||||
case flags.ProtoLegacy && vi.typ == validationTypeMessageSetItem:
|
||||
typeid, v, n, err := messageset.ConsumeFieldValue(b, false)
|
||||
if err != nil {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), typeid)
|
||||
switch {
|
||||
case err == preg.NotFound:
|
||||
b = b[n:]
|
||||
case err != nil:
|
||||
return out, ValidationUnknown
|
||||
default:
|
||||
xvi := getExtensionFieldInfo(xt).validation
|
||||
if xvi.mi != nil {
|
||||
xvi.mi.init()
|
||||
}
|
||||
states = append(states, validationState{
|
||||
typ: xvi.typ,
|
||||
mi: xvi.mi,
|
||||
tail: b[n:],
|
||||
})
|
||||
b = v
|
||||
continue State
|
||||
}
|
||||
default:
|
||||
n := protowire.ConsumeFieldValue(num, wtyp, b)
|
||||
if n < 0 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
default:
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
}
|
||||
if st.endGroup != 0 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
if len(b) != 0 {
|
||||
return out, ValidationInvalid
|
||||
}
|
||||
b = st.tail
|
||||
PopState:
|
||||
numRequiredFields := 0
|
||||
switch st.typ {
|
||||
case validationTypeMessage, validationTypeGroup:
|
||||
numRequiredFields = int(st.mi.numRequiredFields)
|
||||
case validationTypeMap:
|
||||
// If this is a map field with a message value that contains
|
||||
// required fields, require that the value be present.
|
||||
if st.mi != nil && st.mi.numRequiredFields > 0 {
|
||||
numRequiredFields = 1
|
||||
}
|
||||
}
|
||||
// If there are more than 64 required fields, this check will
|
||||
// always fail and we will report that the message is potentially
|
||||
// uninitialized.
|
||||
if numRequiredFields > 0 && bits.OnesCount64(st.requiredMask) != numRequiredFields {
|
||||
initialized = false
|
||||
}
|
||||
states = states[:len(states)-1]
|
||||
}
|
||||
out.n = start - len(b)
|
||||
if initialized {
|
||||
out.initialized = true
|
||||
}
|
||||
return out, ValidationValid
|
||||
}
|
46
vendor/google.golang.org/protobuf/internal/impl/weak.go
generated
vendored
Normal file
46
vendor/google.golang.org/protobuf/internal/impl/weak.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package impl
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
pref "google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
// weakFields adds methods to the exported WeakFields type for internal use.
|
||||
//
|
||||
// The exported type is an alias to an unnamed type, so methods can't be
|
||||
// defined directly on it.
|
||||
type weakFields WeakFields
|
||||
|
||||
func (w *weakFields) get(num pref.FieldNumber) (_ pref.ProtoMessage, ok bool) {
|
||||
if *w == nil {
|
||||
return nil, false
|
||||
}
|
||||
m, ok := (*w)[int32(num)]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
// As a legacy quirk, consider a typed nil to be unset.
|
||||
//
|
||||
// TODO: Consider fixing the generated set methods to clear the field
|
||||
// when provided with a typed nil.
|
||||
if v := reflect.ValueOf(m); v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
return nil, false
|
||||
}
|
||||
return Export{}.ProtoMessageV2Of(m), true
|
||||
}
|
||||
|
||||
func (w *weakFields) set(num pref.FieldNumber, m pref.ProtoMessage) {
|
||||
if *w == nil {
|
||||
*w = make(weakFields)
|
||||
}
|
||||
(*w)[int32(num)] = Export{}.ProtoMessageV1Of(m)
|
||||
}
|
||||
|
||||
func (w *weakFields) clear(num pref.FieldNumber) {
|
||||
delete(*w, int32(num))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue