[VOL-5051] - Build and deploy voltctl
[VOL-5152]
[VOL-4961]
[VOL-5063]
[VOL-4966]
[VOL-4893]
[VOL-4906]
go.mod
go.sum
vendor/modules.txt
------------------
o Update voltha-lib-go dep to 7.5.3
o Update voltha-protos dep to 5.4.11
o make mod-update
Makefile
makefiles/
o Add more repo:onf-make makefile logic
o make LOCAL_FIX_PERMS=1 mod-update need to work around docker perm problems.
internal/
pkg/
vendor/
---------
o Update copyright ending date to span 2024.
o make mod-update to regenerate vendor/
Change-Id: Ib89fd6a9cc15c7e08b1274b110dd8141832557e9
diff --git a/vendor/github.com/jhump/protoreflect/codec/codec.go b/vendor/github.com/jhump/protoreflect/codec/codec.go
new file mode 100644
index 0000000..b6f4ed0
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/codec/codec.go
@@ -0,0 +1,217 @@
+package codec
+
+import (
+ "io"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/jhump/protoreflect/internal/codec"
+)
+
+// ErrOverflow is returned when an integer is too large to be represented.
+var ErrOverflow = codec.ErrOverflow
+
+// ErrBadWireType is returned when decoding a wire-type from a buffer that
+// is not valid.
+var ErrBadWireType = codec.ErrBadWireType
+
+// NB: much of the implementation is in an internal package, to avoid an import
+// cycle between this codec package and the desc package. We export it from
+// this package, but we can't use a type alias because we also need to add
+// methods to it, to broaden the exposed API.
+
+// Buffer is a reader and a writer that wraps a slice of bytes and also
+// provides API for decoding and encoding the protobuf binary format.
+//
+// Its operation is similar to that of a bytes.Buffer: writing pushes
+// data to the end of the buffer while reading pops data from the head
+// of the buffer. So the same buffer can be used to both read and write.
+type Buffer codec.Buffer
+
+// NewBuffer creates a new buffer with the given slice of bytes as the
+// buffer's initial contents.
+func NewBuffer(buf []byte) *Buffer {
+ return (*Buffer)(codec.NewBuffer(buf))
+}
+
+// SetDeterministic sets this buffer to encode messages deterministically. This
+// is useful for tests. But the overhead is non-zero, so it should not likely be
+// used outside of tests. When true, map fields in a message must have their
+// keys sorted before serialization to ensure deterministic output. Otherwise,
+// values in a map field will be serialized in map iteration order.
+func (cb *Buffer) SetDeterministic(deterministic bool) {
+ (*codec.Buffer)(cb).SetDeterministic(deterministic)
+}
+
+// IsDeterministic returns whether or not this buffer is configured to encode
+// messages deterministically.
+func (cb *Buffer) IsDeterministic() bool {
+ return (*codec.Buffer)(cb).IsDeterministic()
+}
+
+// Reset resets this buffer back to empty. Any subsequent writes/encodes
+// to the buffer will allocate a new backing slice of bytes.
+func (cb *Buffer) Reset() {
+ (*codec.Buffer)(cb).Reset()
+}
+
+// Bytes returns the slice of bytes remaining in the buffer. Note that
+// this does not perform a copy: if the contents of the returned slice
+// are modified, the modifications will be visible to subsequent reads
+// via the buffer.
+func (cb *Buffer) Bytes() []byte {
+ return (*codec.Buffer)(cb).Bytes()
+}
+
+// String returns the remaining bytes in the buffer as a string.
+func (cb *Buffer) String() string {
+ return (*codec.Buffer)(cb).String()
+}
+
+// EOF returns true if there are no more bytes remaining to read.
+func (cb *Buffer) EOF() bool {
+ return (*codec.Buffer)(cb).EOF()
+}
+
+// Skip attempts to skip the given number of bytes in the input. If
+// the input has fewer bytes than the given count, io.ErrUnexpectedEOF
+// is returned and the buffer is unchanged. Otherwise, the given number
+// of bytes are skipped and nil is returned.
+func (cb *Buffer) Skip(count int) error {
+ return (*codec.Buffer)(cb).Skip(count)
+
+}
+
+// Len returns the remaining number of bytes in the buffer.
+func (cb *Buffer) Len() int {
+ return (*codec.Buffer)(cb).Len()
+}
+
+// Read implements the io.Reader interface. If there are no bytes
+// remaining in the buffer, it will return 0, io.EOF. Otherwise,
+// it reads max(len(dest), cb.Len()) bytes from input and copies
+// them into dest. It returns the number of bytes copied and a nil
+// error in this case.
+func (cb *Buffer) Read(dest []byte) (int, error) {
+ return (*codec.Buffer)(cb).Read(dest)
+}
+
+var _ io.Reader = (*Buffer)(nil)
+
+// Write implements the io.Writer interface. It always returns
+// len(data), nil.
+func (cb *Buffer) Write(data []byte) (int, error) {
+ return (*codec.Buffer)(cb).Write(data)
+}
+
+var _ io.Writer = (*Buffer)(nil)
+
+// DecodeVarint reads a varint-encoded integer from the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (cb *Buffer) DecodeVarint() (uint64, error) {
+ return (*codec.Buffer)(cb).DecodeVarint()
+}
+
+// DecodeTagAndWireType decodes a field tag and wire type from input.
+// This reads a varint and then extracts the two fields from the varint
+// value read.
+func (cb *Buffer) DecodeTagAndWireType() (tag int32, wireType int8, err error) {
+ return (*codec.Buffer)(cb).DecodeTagAndWireType()
+}
+
+// DecodeFixed64 reads a 64-bit integer from the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (cb *Buffer) DecodeFixed64() (x uint64, err error) {
+ return (*codec.Buffer)(cb).DecodeFixed64()
+}
+
+// DecodeFixed32 reads a 32-bit integer from the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (cb *Buffer) DecodeFixed32() (x uint64, err error) {
+ return (*codec.Buffer)(cb).DecodeFixed32()
+}
+
+// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (cb *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
+ return (*codec.Buffer)(cb).DecodeRawBytes(alloc)
+}
+
+// ReadGroup reads the input until a "group end" tag is found
+// and returns the data up to that point. Subsequent reads from
+// the buffer will read data after the group end tag. If alloc
+// is true, the data is copied to a new slice before being returned.
+// Otherwise, the returned slice is a view into the buffer's
+// underlying byte slice.
+//
+// This function correctly handles nested groups: if a "group start"
+// tag is found, then that group's end tag will be included in the
+// returned data.
+func (cb *Buffer) ReadGroup(alloc bool) ([]byte, error) {
+ return (*codec.Buffer)(cb).ReadGroup(alloc)
+}
+
+// SkipGroup is like ReadGroup, except that it discards the
+// data and just advances the buffer to point to the input
+// right *after* the "group end" tag.
+func (cb *Buffer) SkipGroup() error {
+ return (*codec.Buffer)(cb).SkipGroup()
+}
+
+// SkipField attempts to skip the value of a field with the given wire
+// type. When consuming a protobuf-encoded stream, it can be called immediately
+// after DecodeTagAndWireType to discard the subsequent data for the field.
+func (cb *Buffer) SkipField(wireType int8) error {
+ return (*codec.Buffer)(cb).SkipField(wireType)
+}
+
+// EncodeVarint writes a varint-encoded integer to the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (cb *Buffer) EncodeVarint(x uint64) error {
+ return (*codec.Buffer)(cb).EncodeVarint(x)
+}
+
+// EncodeTagAndWireType encodes the given field tag and wire type to the
+// buffer. This combines the two values and then writes them as a varint.
+func (cb *Buffer) EncodeTagAndWireType(tag int32, wireType int8) error {
+ return (*codec.Buffer)(cb).EncodeTagAndWireType(tag, wireType)
+}
+
+// EncodeFixed64 writes a 64-bit integer to the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (cb *Buffer) EncodeFixed64(x uint64) error {
+ return (*codec.Buffer)(cb).EncodeFixed64(x)
+
+}
+
+// EncodeFixed32 writes a 32-bit integer to the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (cb *Buffer) EncodeFixed32(x uint64) error {
+ return (*codec.Buffer)(cb).EncodeFixed32(x)
+}
+
+// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (cb *Buffer) EncodeRawBytes(b []byte) error {
+ return (*codec.Buffer)(cb).EncodeRawBytes(b)
+}
+
+// EncodeMessage writes the given message to the buffer.
+func (cb *Buffer) EncodeMessage(pm proto.Message) error {
+ return (*codec.Buffer)(cb).EncodeMessage(pm)
+}
+
+// EncodeDelimitedMessage writes the given message to the buffer with a
+// varint-encoded length prefix (the delimiter).
+func (cb *Buffer) EncodeDelimitedMessage(pm proto.Message) error {
+ return (*codec.Buffer)(cb).EncodeDelimitedMessage(pm)
+}
diff --git a/vendor/github.com/jhump/protoreflect/codec/decode_fields.go b/vendor/github.com/jhump/protoreflect/codec/decode_fields.go
index 938b4d9..02f8a32 100644
--- a/vendor/github.com/jhump/protoreflect/codec/decode_fields.go
+++ b/vendor/github.com/jhump/protoreflect/codec/decode_fields.go
@@ -12,6 +12,29 @@
"github.com/jhump/protoreflect/desc"
)
+var varintTypes = map[descriptor.FieldDescriptorProto_Type]bool{}
+var fixed32Types = map[descriptor.FieldDescriptorProto_Type]bool{}
+var fixed64Types = map[descriptor.FieldDescriptorProto_Type]bool{}
+
+func init() {
+ varintTypes[descriptor.FieldDescriptorProto_TYPE_BOOL] = true
+ varintTypes[descriptor.FieldDescriptorProto_TYPE_INT32] = true
+ varintTypes[descriptor.FieldDescriptorProto_TYPE_INT64] = true
+ varintTypes[descriptor.FieldDescriptorProto_TYPE_UINT32] = true
+ varintTypes[descriptor.FieldDescriptorProto_TYPE_UINT64] = true
+ varintTypes[descriptor.FieldDescriptorProto_TYPE_SINT32] = true
+ varintTypes[descriptor.FieldDescriptorProto_TYPE_SINT64] = true
+ varintTypes[descriptor.FieldDescriptorProto_TYPE_ENUM] = true
+
+ fixed32Types[descriptor.FieldDescriptorProto_TYPE_FIXED32] = true
+ fixed32Types[descriptor.FieldDescriptorProto_TYPE_SFIXED32] = true
+ fixed32Types[descriptor.FieldDescriptorProto_TYPE_FLOAT] = true
+
+ fixed64Types[descriptor.FieldDescriptorProto_TYPE_FIXED64] = true
+ fixed64Types[descriptor.FieldDescriptorProto_TYPE_SFIXED64] = true
+ fixed64Types[descriptor.FieldDescriptorProto_TYPE_DOUBLE] = true
+}
+
// ErrWireTypeEndGroup is returned from DecodeFieldValue if the tag and wire-type
// it reads indicates an end-group marker.
var ErrWireTypeEndGroup = errors.New("unexpected wire type: end group")
@@ -43,6 +66,18 @@
Value uint64
}
+// DecodeZigZag32 decodes a signed 32-bit integer from the given
+// zig-zag encoded value.
+func DecodeZigZag32(v uint64) int32 {
+ return int32((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31))
+}
+
+// DecodeZigZag64 decodes a signed 64-bit integer from the given
+// zig-zag encoded value.
+func DecodeZigZag64(v uint64) int64 {
+ return int64((v >> 1) ^ uint64((int64(v&1)<<63)>>63))
+}
+
// DecodeFieldValue will read a field value from the buffer and return its
// value and the corresponding field descriptor. The given function is used
// to lookup a field descriptor by tag number. The given factory is used to
diff --git a/vendor/github.com/jhump/protoreflect/codec/encode_fields.go b/vendor/github.com/jhump/protoreflect/codec/encode_fields.go
index cda7299..499aa95 100644
--- a/vendor/github.com/jhump/protoreflect/codec/encode_fields.go
+++ b/vendor/github.com/jhump/protoreflect/codec/encode_fields.go
@@ -12,6 +12,20 @@
"github.com/jhump/protoreflect/desc"
)
+// EncodeZigZag64 does zig-zag encoding to convert the given
+// signed 64-bit integer into a form that can be expressed
+// efficiently as a varint, even for negative values.
+func EncodeZigZag64(v int64) uint64 {
+ return (uint64(v) << 1) ^ uint64(v>>63)
+}
+
+// EncodeZigZag32 does zig-zag encoding to convert the given
+// signed 32-bit integer into a form that can be expressed
+// efficiently as a varint, even for negative values.
+func EncodeZigZag32(v int32) uint64 {
+ return uint64((uint32(v) << 1) ^ uint32((v >> 31)))
+}
+
func (cb *Buffer) EncodeFieldValue(fd *desc.FieldDescriptor, val interface{}) error {
if fd.IsMap() {
mp := val.(map[interface{}]interface{})
@@ -19,7 +33,8 @@
keyType := entryType.FindFieldByNumber(1)
valType := entryType.FindFieldByNumber(2)
var entryBuffer Buffer
- if cb.deterministic {
+ if cb.IsDeterministic() {
+ entryBuffer.SetDeterministic(true)
keys := make([]interface{}, 0, len(mp))
for k := range mp {
keys = append(keys, k)
@@ -31,8 +46,11 @@
if err := entryBuffer.encodeFieldElement(keyType, k); err != nil {
return err
}
- if err := entryBuffer.encodeFieldElement(valType, v); err != nil {
- return err
+ rv := reflect.ValueOf(v)
+ if rv.Kind() != reflect.Ptr || !rv.IsNil() {
+ if err := entryBuffer.encodeFieldElement(valType, v); err != nil {
+ return err
+ }
}
if err := cb.EncodeTagAndWireType(fd.GetNumber(), proto.WireBytes); err != nil {
return err
@@ -47,8 +65,11 @@
if err := entryBuffer.encodeFieldElement(keyType, k); err != nil {
return err
}
- if err := entryBuffer.encodeFieldElement(valType, v); err != nil {
- return err
+ rv := reflect.ValueOf(v)
+ if rv.Kind() != reflect.Ptr || !rv.IsNil() {
+ if err := entryBuffer.encodeFieldElement(valType, v); err != nil {
+ return err
+ }
}
if err := cb.EncodeTagAndWireType(fd.GetNumber(), proto.WireBytes); err != nil {
return err
@@ -65,7 +86,7 @@
if err != nil {
return err
}
- if isPacked(fd) && len(sl) > 1 &&
+ if isPacked(fd) && len(sl) > 0 &&
(wt == proto.WireVarint || wt == proto.WireFixed32 || wt == proto.WireFixed64) {
// packed repeated field
var packedBuffer Buffer
diff --git a/vendor/github.com/jhump/protoreflect/desc/descriptor.go b/vendor/github.com/jhump/protoreflect/desc/descriptor.go
index ab235a3..42f0f8e 100644
--- a/vendor/github.com/jhump/protoreflect/desc/descriptor.go
+++ b/vendor/github.com/jhump/protoreflect/desc/descriptor.go
@@ -6,6 +6,7 @@
"sort"
"strconv"
"strings"
+ "unicode"
"unicode/utf8"
"github.com/golang/protobuf/proto"
@@ -191,7 +192,19 @@
if symbol[0] == '.' {
symbol = symbol[1:]
}
- return fd.symbols[symbol]
+ if ret := fd.symbols[symbol]; ret != nil {
+ return ret
+ }
+
+ // allow accessing symbols through public imports, too
+ for _, dep := range fd.GetPublicDependencies() {
+ if ret := dep.FindSymbol(symbol); ret != nil {
+ return ret
+ }
+ }
+
+ // not found
+ return nil
}
// FindMessage finds the message with the given fully-qualified name. If no
@@ -891,10 +904,32 @@
// GetJSONName returns the name of the field as referenced in the message's JSON
// format.
func (fd *FieldDescriptor) GetJSONName() string {
- if jsonName := fd.proto.GetJsonName(); jsonName != "" {
- return jsonName
+ if jsonName := fd.proto.JsonName; jsonName != nil {
+ // if json name is present, use its value
+ return *jsonName
}
- return fd.proto.GetName()
+ // otherwise, compute the proper JSON name from the field name
+ return jsonCamelCase(fd.proto.GetName())
+}
+
+func jsonCamelCase(s string) string {
+ // This mirrors the implementation in protoc/C++ runtime and in the Java runtime:
+ // https://github.com/protocolbuffers/protobuf/blob/a104dffcb6b1958a424f5fa6f9e6bdc0ab9b6f9e/src/google/protobuf/descriptor.cc#L276
+ // https://github.com/protocolbuffers/protobuf/blob/a1c886834425abb64a966231dd2c9dd84fb289b3/java/core/src/main/java/com/google/protobuf/Descriptors.java#L1286
+ var buf bytes.Buffer
+ prevWasUnderscore := false
+ for _, r := range s {
+ if r == '_' {
+ prevWasUnderscore = true
+ continue
+ }
+ if prevWasUnderscore {
+ r = unicode.ToUpper(r)
+ prevWasUnderscore = false
+ }
+ buf.WriteRune(r)
+ }
+ return buf.String()
}
// GetFullyQualifiedJSONName returns the JSON format name (same as GetJSONName),
@@ -959,6 +994,24 @@
return fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED
}
+// IsProto3Optional returns true if this field has an explicit "optional" label
+// and is in a "proto3" syntax file. Such fields, if they are normal fields (not
+// extensions), will be nested in synthetic oneofs that contain only the single
+// field.
+func (fd *FieldDescriptor) IsProto3Optional() bool {
+ return internal.GetProto3Optional(fd.proto)
+}
+
+// HasPresence returns true if this field can distinguish when a value is
+// present or not. Scalar fields in "proto3" syntax files, for example, return
+// false since absent values are indistinguishable from zero values.
+func (fd *FieldDescriptor) HasPresence() bool {
+ if !fd.file.isProto3 {
+ return true
+ }
+ return fd.msgType != nil || fd.oneOf != nil
+}
+
// IsMap returns true if this is a map field. If so, it will have the "repeated"
// label its type will be a message that represents a map entry. The map entry
// message will have exactly two fields: tag #1 is the key and tag #2 is the value.
@@ -1582,6 +1635,10 @@
return od.choices
}
+func (od *OneOfDescriptor) IsSynthetic() bool {
+ return len(od.choices) == 1 && od.choices[0].IsProto3Optional()
+}
+
// scope represents a lexical scope in a proto file in which messages and enums
// can be declared.
type scope func(string) Descriptor
diff --git a/vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go b/vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go
index cd7348e..25d619a 100644
--- a/vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go
+++ b/vendor/github.com/jhump/protoreflect/desc/descriptor_no_unsafe.go
@@ -1,4 +1,6 @@
-//+build appengine gopherjs purego
+//go:build appengine || gopherjs || purego
+// +build appengine gopherjs purego
+
// NB: other environments where unsafe is unappropriate should use "purego" build tag
// https://github.com/golang/go/issues/23172
@@ -13,12 +15,9 @@
func (md *MessageDescriptor) FindFieldByJSONName(jsonName string) *FieldDescriptor {
// NB: With allowed use of unsafe, we use it to atomically define an index
// via atomic.LoadPointer/atomic.StorePointer. Without it, we skip the index
- // and do an linear scan of fields each time.
+ // and must do a linear scan of fields each time.
for _, f := range md.fields {
- jn := f.proto.GetJsonName()
- if jn == "" {
- jn = f.proto.GetName()
- }
+ jn := f.GetJSONName()
if jn == jsonName {
return f
}
diff --git a/vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go b/vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go
index 19b808d..691f0d8 100644
--- a/vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go
+++ b/vendor/github.com/jhump/protoreflect/desc/descriptor_unsafe.go
@@ -1,4 +1,6 @@
-//+build !appengine,!gopherjs,!purego
+//go:build !appengine && !gopherjs && !purego
+// +build !appengine,!gopherjs,!purego
+
// NB: other environments where unsafe is unappropriate should use "purego" build tag
// https://github.com/golang/go/issues/23172
@@ -34,10 +36,7 @@
// slow path: compute the index
index = map[string]*FieldDescriptor{}
for _, f := range md.fields {
- jn := f.proto.GetJsonName()
- if jn == "" {
- jn = f.proto.GetName()
- }
+ jn := f.GetJSONName()
index[jn] = f
}
atomic.StorePointer(addrOfJsonNames, *(*unsafe.Pointer)(unsafe.Pointer(&index)))
diff --git a/vendor/github.com/jhump/protoreflect/desc/internal/proto3_optional.go b/vendor/github.com/jhump/protoreflect/desc/internal/proto3_optional.go
new file mode 100644
index 0000000..9aa4a3e
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/desc/internal/proto3_optional.go
@@ -0,0 +1,120 @@
+package internal
+
+import (
+ "github.com/golang/protobuf/proto"
+ dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ "github.com/jhump/protoreflect/internal/codec"
+ "reflect"
+ "strings"
+
+ "github.com/jhump/protoreflect/internal"
+)
+
+// NB: We use reflection or unknown fields in case we are linked against an older
+// version of the proto runtime which does not know about the proto3_optional field.
+// We don't require linking with newer version (which would greatly simplify this)
+// because that means pulling in v1.4+ of the protobuf runtime, which has some
+// compatibility issues. (We'll be nice to users and not require they upgrade to
+// that latest runtime to upgrade to newer protoreflect.)
+
+func GetProto3Optional(fd *dpb.FieldDescriptorProto) bool {
+ type newerFieldDesc interface {
+ GetProto3Optional() bool
+ }
+ var pm proto.Message = fd
+ if fd, ok := pm.(newerFieldDesc); ok {
+ return fd.GetProto3Optional()
+ }
+
+ // Field does not exist, so we have to examine unknown fields
+ // (we just silently bail if we have problems parsing them)
+ unk := internal.GetUnrecognized(pm)
+ buf := codec.NewBuffer(unk)
+ for {
+ tag, wt, err := buf.DecodeTagAndWireType()
+ if err != nil {
+ return false
+ }
+ if tag == Field_proto3OptionalTag && wt == proto.WireVarint {
+ v, _ := buf.DecodeVarint()
+ return v != 0
+ }
+ if err := buf.SkipField(wt); err != nil {
+ return false
+ }
+ }
+}
+
+func SetProto3Optional(fd *dpb.FieldDescriptorProto) {
+ rv := reflect.ValueOf(fd).Elem()
+ fld := rv.FieldByName("Proto3Optional")
+ if fld.IsValid() {
+ fld.Set(reflect.ValueOf(proto.Bool(true)))
+ return
+ }
+
+ // Field does not exist, so we have to store as unknown field.
+ var buf codec.Buffer
+ if err := buf.EncodeTagAndWireType(Field_proto3OptionalTag, proto.WireVarint); err != nil {
+ // TODO: panic? log?
+ return
+ }
+ if err := buf.EncodeVarint(1); err != nil {
+ // TODO: panic? log?
+ return
+ }
+ internal.SetUnrecognized(fd, buf.Bytes())
+}
+
+// ProcessProto3OptionalFields adds synthetic oneofs to the given message descriptor
+// for each proto3 optional field. It also updates the fields to have the correct
+// oneof index reference.
+func ProcessProto3OptionalFields(msgd *dpb.DescriptorProto) {
+ var allNames map[string]struct{}
+ for _, fd := range msgd.Field {
+ if GetProto3Optional(fd) {
+ // lazy init the set of all names
+ if allNames == nil {
+ allNames = map[string]struct{}{}
+ for _, fd := range msgd.Field {
+ allNames[fd.GetName()] = struct{}{}
+ }
+ for _, fd := range msgd.Extension {
+ allNames[fd.GetName()] = struct{}{}
+ }
+ for _, ed := range msgd.EnumType {
+ allNames[ed.GetName()] = struct{}{}
+ for _, evd := range ed.Value {
+ allNames[evd.GetName()] = struct{}{}
+ }
+ }
+ for _, fd := range msgd.NestedType {
+ allNames[fd.GetName()] = struct{}{}
+ }
+ for _, n := range msgd.ReservedName {
+ allNames[n] = struct{}{}
+ }
+ }
+
+ // Compute a name for the synthetic oneof. This uses the same
+ // algorithm as used in protoc:
+ // https://github.com/protocolbuffers/protobuf/blob/74ad62759e0a9b5a21094f3fb9bb4ebfaa0d1ab8/src/google/protobuf/compiler/parser.cc#L785-L803
+ ooName := fd.GetName()
+ if !strings.HasPrefix(ooName, "_") {
+ ooName = "_" + ooName
+ }
+ for {
+ _, ok := allNames[ooName]
+ if !ok {
+ // found a unique name
+ allNames[ooName] = struct{}{}
+ break
+ }
+ ooName = "X" + ooName
+ }
+
+ fd.OneofIndex = proto.Int32(int32(len(msgd.OneofDecl)))
+ msgd.OneofDecl = append(msgd.OneofDecl, &dpb.OneofDescriptorProto{Name: proto.String(ooName)})
+ }
+ }
+}
diff --git a/vendor/github.com/jhump/protoreflect/desc/internal/util.go b/vendor/github.com/jhump/protoreflect/desc/internal/util.go
index 139c9cd..71855bf 100644
--- a/vendor/github.com/jhump/protoreflect/desc/internal/util.go
+++ b/vendor/github.com/jhump/protoreflect/desc/internal/util.go
@@ -1,13 +1,22 @@
package internal
import (
+ "math"
"unicode"
"unicode/utf8"
)
const (
- // MaxTag is the maximum allowed tag number for a field.
- MaxTag = 536870911 // 2^29 - 1
+ // MaxNormalTag is the maximum allowed tag number for a field in a normal message.
+ MaxNormalTag = 536870911 // 2^29 - 1
+
+ // MaxMessageSetTag is the maximum allowed tag number of a field in a message that
+ // uses the message set wire format.
+ MaxMessageSetTag = math.MaxInt32 - 1
+
+ // MaxTag is the maximum allowed tag number. (It is the same as MaxMessageSetTag
+ // since that is the absolute highest allowed.)
+ MaxTag = MaxMessageSetTag
// SpecialReservedStart is the first tag in a range that is reserved and not
// allowed for use in message definitions.
@@ -117,6 +126,9 @@
// Field_jsonNameTag is the tag number of the JSON name element in a field
// descriptor proto.
Field_jsonNameTag = 10
+ // Field_proto3OptionalTag is the tag number of the proto3_optional element
+ // in a descriptor proto.
+ Field_proto3OptionalTag = 17
// OneOf_nameTag is the tag number of the name element in a one-of
// descriptor proto.
OneOf_nameTag = 1
@@ -268,3 +280,12 @@
return prefixes
}
+
+// GetMaxTag returns the max tag number allowed, based on whether a message uses
+// message set wire format or not.
+func GetMaxTag(isMessageSet bool) int32 {
+ if isMessageSet {
+ return MaxMessageSetTag
+ }
+ return MaxNormalTag
+}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go b/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go
index 3f19d6b..de13b92 100644
--- a/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go
+++ b/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go
@@ -14,6 +14,7 @@
"github.com/jhump/protoreflect/codec"
"github.com/jhump/protoreflect/desc"
+ "github.com/jhump/protoreflect/internal"
)
// ErrUnknownTagNumber is an error that is returned when an operation refers
@@ -527,14 +528,8 @@
}
// GetDefaultValue only returns nil for message types
md := fd.GetMessageType()
- if md.IsProto3() {
- // try to return a proper nil pointer
- msgType := proto.MessageType(md.GetFullyQualifiedName())
- if msgType != nil && msgType.Implements(typeOfProtoMessage) {
- return reflect.Zero(msgType).Interface().(proto.Message), nil
- }
- // fallback to nil dynamic message pointer
- return (*Message)(nil), nil
+ if m.md.IsProto3() {
+ return nilMessage(md), nil
} else {
// for proto2, return default instance of message
return m.mf.NewMessage(md), nil
@@ -561,6 +556,16 @@
return res, nil
}
+func nilMessage(md *desc.MessageDescriptor) interface{} {
+ // try to return a proper nil pointer
+ msgType := proto.MessageType(md.GetFullyQualifiedName())
+ if msgType != nil && msgType.Implements(typeOfProtoMessage) {
+ return reflect.Zero(msgType).Interface().(proto.Message)
+ }
+ // fallback to nil dynamic message pointer
+ return (*Message)(nil)
+}
+
// HasField returns true if this message has a value for the given field. If the
// given field is not valid (e.g. belongs to a different message type), false is
// returned. If this message is defined in a file with "proto3" syntax, this
@@ -980,7 +985,7 @@
return nil, FieldIsNotMapError
}
kfd := fd.GetMessageType().GetFields()[0]
- ki, err := validElementFieldValue(kfd, key)
+ ki, err := validElementFieldValue(kfd, key, false)
if err != nil {
return nil, err
}
@@ -1185,12 +1190,12 @@
return FieldIsNotMapError
}
kfd := fd.GetMessageType().GetFields()[0]
- ki, err := validElementFieldValue(kfd, key)
+ ki, err := validElementFieldValue(kfd, key, false)
if err != nil {
return err
}
vfd := fd.GetMessageType().GetFields()[1]
- vi, err := validElementFieldValue(vfd, val)
+ vi, err := validElementFieldValue(vfd, val, true)
if err != nil {
return err
}
@@ -1279,7 +1284,7 @@
return FieldIsNotMapError
}
kfd := fd.GetMessageType().GetFields()[0]
- ki, err := validElementFieldValue(kfd, key)
+ ki, err := validElementFieldValue(kfd, key, false)
if err != nil {
return err
}
@@ -1580,7 +1585,7 @@
if !fd.IsRepeated() {
return FieldIsNotRepeatedError
}
- val, err := validElementFieldValue(fd, val)
+ val, err := validElementFieldValue(fd, val, false)
if err != nil {
return err
}
@@ -1709,7 +1714,7 @@
if fd.IsMap() || !fd.IsRepeated() {
return FieldIsNotRepeatedError
}
- val, err := validElementFieldValue(fd, val)
+ val, err := validElementFieldValue(fd, val, false)
if err != nil {
return err
}
@@ -1813,7 +1818,7 @@
// value should be a slice of entry messages that we need convert into a map[interface{}]interface{}
m := map[interface{}]interface{}{}
for i := 0; i < val.Len(); i++ {
- e, err := validElementFieldValue(fd, val.Index(i).Interface())
+ e, err := validElementFieldValue(fd, val.Index(i).Interface(), false)
if err != nil {
return nil, err
}
@@ -1843,7 +1848,7 @@
// unwrap it
ev = reflect.ValueOf(ev.Interface())
}
- e, err := validElementFieldValueForRv(fd, ev)
+ e, err := validElementFieldValueForRv(fd, ev, false)
if err != nil {
return nil, err
}
@@ -1853,7 +1858,7 @@
return s, nil
}
- return validElementFieldValueForRv(fd, val)
+ return validElementFieldValueForRv(fd, val, false)
}
func asDynamicMessage(m proto.Message, md *desc.MessageDescriptor, mf *MessageFactory) (*Message, error) {
@@ -1867,11 +1872,11 @@
return dm, nil
}
-func validElementFieldValue(fd *desc.FieldDescriptor, val interface{}) (interface{}, error) {
- return validElementFieldValueForRv(fd, reflect.ValueOf(val))
+func validElementFieldValue(fd *desc.FieldDescriptor, val interface{}, allowNilMessage bool) (interface{}, error) {
+ return validElementFieldValueForRv(fd, reflect.ValueOf(val), allowNilMessage)
}
-func validElementFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) {
+func validElementFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value, allowNilMessage bool) (interface{}, error) {
t := fd.GetType()
if !val.IsValid() {
return nil, typeError(fd, nil)
@@ -1921,6 +1926,11 @@
}
var msgType string
if dm, ok := m.(*Message); ok {
+ if allowNilMessage && dm == nil {
+ // if dm == nil, we'll panic below, so early out if that is allowed
+ // (only allowed for map values, to indicate an entry w/ no value)
+ return m, nil
+ }
msgType = dm.GetMessageDescriptor().GetFullyQualifiedName()
} else {
msgType = proto.MessageName(m)
@@ -2051,7 +2061,22 @@
}
target.Reset()
- return m.mergeInto(target)
+ return m.mergeInto(target, defaultDeterminism)
+}
+
+// ConvertToDeterministic converts this dynamic message into the given message.
+// It is just like ConvertTo, but it attempts to produce deterministic results.
+// That means that if the target is a generated message (not another dynamic
+// message) and the current runtime is unaware of any fields or extensions that
+// are present in m, they will be serialized into the target's unrecognized
+// fields deterministically.
+func (m *Message) ConvertToDeterministic(target proto.Message) error {
+ if err := m.checkType(target); err != nil {
+ return err
+ }
+
+ target.Reset()
+ return m.mergeInto(target, true)
}
// ConvertFrom converts the given message into this dynamic message. This is
@@ -2080,7 +2105,20 @@
if err := m.checkType(target); err != nil {
return err
}
- return m.mergeInto(target)
+ return m.mergeInto(target, defaultDeterminism)
+}
+
+// MergeIntoDeterministic merges this dynamic message into the given message.
+// It is just like MergeInto, but it attempts to produce deterministic results.
+// That means that if the target is a generated message (not another dynamic
+// message) and the current runtime is unaware of any fields or extensions that
+// are present in m, they will be serialized into the target's unrecognized
+// fields deterministically.
+func (m *Message) MergeIntoDeterministic(target proto.Message) error {
+ if err := m.checkType(target); err != nil {
+ return err
+ }
+ return m.mergeInto(target, true)
}
// MergeFrom merges the given message into this dynamic message. All field
@@ -2145,7 +2183,7 @@
return nil
}
-func (m *Message) mergeInto(pm proto.Message) error {
+func (m *Message) mergeInto(pm proto.Message, deterministic bool) error {
if dm, ok := pm.(*Message); ok {
return dm.mergeFrom(m)
}
@@ -2157,13 +2195,9 @@
// track tags for which the dynamic message has data but the given
// message doesn't know about it
- u := target.FieldByName("XXX_unrecognized")
- var unknownTags map[int32]struct{}
- if u.IsValid() && u.Type() == typeOfBytes {
- unknownTags = map[int32]struct{}{}
- for tag := range m.values {
- unknownTags[tag] = struct{}{}
- }
+ unknownTags := map[int32]struct{}{}
+ for tag := range m.values {
+ unknownTags[tag] = struct{}{}
}
// check that we can successfully do the merge
@@ -2231,7 +2265,7 @@
continue
}
f := target.FieldByName(prop.Name)
- if err := mergeVal(reflect.ValueOf(v), f); err != nil {
+ if err := mergeVal(reflect.ValueOf(v), f, deterministic); err != nil {
return err
}
}
@@ -2245,7 +2279,7 @@
}
oov := reflect.New(oop.Type.Elem())
f := oov.Elem().FieldByName(prop.Name)
- if err := mergeVal(reflect.ValueOf(v), f); err != nil {
+ if err := mergeVal(reflect.ValueOf(v), f, deterministic); err != nil {
return err
}
target.Field(oop.Field).Set(oov)
@@ -2257,7 +2291,7 @@
continue
}
e := reflect.New(reflect.TypeOf(ext.ExtensionType)).Elem()
- if err := mergeVal(reflect.ValueOf(v), e); err != nil {
+ if err := mergeVal(reflect.ValueOf(v), e, deterministic); err != nil {
return err
}
if err := proto.SetExtension(pm, ext, e.Interface()); err != nil {
@@ -2268,17 +2302,34 @@
// if we have fields that the given message doesn't know about, add to its unknown fields
if len(unknownTags) > 0 {
- ub := u.Interface().([]byte)
var b codec.Buffer
- b.SetDeterministic(defaultDeterminism)
- for tag := range unknownTags {
- fd := m.FindFieldDescriptor(tag)
- if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil {
- return err
+ b.SetDeterministic(deterministic)
+ if deterministic {
+ // if we need to emit things deterministically, sort the
+ // extensions by their tag number
+ sortedUnknownTags := make([]int32, 0, len(unknownTags))
+ for tag := range unknownTags {
+ sortedUnknownTags = append(sortedUnknownTags, tag)
+ }
+ sort.Slice(sortedUnknownTags, func(i, j int) bool {
+ return sortedUnknownTags[i] < sortedUnknownTags[j]
+ })
+ for _, tag := range sortedUnknownTags {
+ fd := m.FindFieldDescriptor(tag)
+ if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil {
+ return err
+ }
+ }
+ } else {
+ for tag := range unknownTags {
+ fd := m.FindFieldDescriptor(tag)
+ if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil {
+ return err
+ }
}
}
- ub = append(ub, b.Bytes()...)
- u.Set(reflect.ValueOf(ub))
+
+ internal.SetUnrecognized(pm, b.Bytes())
}
// finally, convey unknown fields into the given message by letting it unmarshal them
@@ -2331,7 +2382,7 @@
}
}
-func mergeVal(src, target reflect.Value) error {
+func mergeVal(src, target reflect.Value, deterministic bool) error {
if src.Kind() == reflect.Interface && !src.IsNil() {
src = src.Elem()
}
@@ -2368,19 +2419,19 @@
if dest.Kind() == reflect.Ptr {
dest.Set(reflect.New(dest.Type().Elem()))
}
- if err := mergeVal(src.Index(i), dest); err != nil {
+ if err := mergeVal(src.Index(i), dest, deterministic); err != nil {
return err
}
}
} else if targetType.Kind() == reflect.Map {
- return mergeMapVal(src, target, targetType)
+ return mergeMapVal(src, target, targetType, deterministic)
} else if srcType == typeOfDynamicMessage && targetType.Implements(typeOfProtoMessage) {
dm := src.Interface().(*Message)
if target.IsNil() {
target.Set(reflect.New(targetType.Elem()))
}
m := target.Interface().(proto.Message)
- if err := dm.mergeInto(m); err != nil {
+ if err := dm.mergeInto(m, deterministic); err != nil {
return err
}
} else {
@@ -2478,17 +2529,14 @@
// extension fields
rexts, _ := proto.ExtensionDescs(pm)
- var unknownExtensions []byte
for _, ed := range rexts {
v, _ := proto.GetExtension(pm, ed)
if v == nil {
continue
}
if ed.ExtensionType == nil {
- extBytes, _ := v.([]byte)
- if len(extBytes) > 0 {
- unknownExtensions = append(unknownExtensions, extBytes...)
- }
+ // unrecognized extension: we'll handle that below when we
+ // handle other unrecognized fields
continue
}
fd := m.er.FindExtension(m.md.GetFullyQualifiedName(), ed.Field)
@@ -2507,22 +2555,17 @@
// now actually perform the merge
for fd, v := range values {
- mergeField(m, fd, v)
+ if err := mergeField(m, fd, v); err != nil {
+ return err
+ }
}
- u := src.FieldByName("XXX_unrecognized")
- if u.IsValid() && u.Type() == typeOfBytes {
+ data := internal.GetUnrecognized(pm)
+ if len(data) > 0 {
// ignore any error returned: pulling in unknown fields is best-effort
- _ = m.UnmarshalMerge(u.Interface().([]byte))
+ _ = m.UnmarshalMerge(data)
}
- // lastly, also extract any unknown extensions the message may have (unknown extensions
- // are stored with other extensions, not in the XXX_unrecognized field, so we have to do
- // more than just the step above...)
- if len(unknownExtensions) > 0 {
- // pulling in unknown fields is best-effort, so we just ignore errors
- _ = m.UnmarshalMerge(unknownExtensions)
- }
return nil
}
@@ -2574,12 +2617,15 @@
var dm *Message
if d, ok := pm.(*Message); ok {
dm = d
- } else {
+ } else if pm != nil {
dm = m.mf.NewDynamicMessage(md)
if err := dm.ConvertFrom(pm); err != nil {
return nil
}
}
+ if dm == nil {
+ return nil
+ }
if err := dm.validateRecursive(chprefix); err != nil {
return err
}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/equal.go b/vendor/github.com/jhump/protoreflect/dynamic/equal.go
index 5fbcc24..e44c6c5 100644
--- a/vendor/github.com/jhump/protoreflect/dynamic/equal.go
+++ b/vendor/github.com/jhump/protoreflect/dynamic/equal.go
@@ -13,6 +13,12 @@
// have the same message type and same fields set to equal values. For proto3 messages, fields set
// to their zero value are considered unset.
func Equal(a, b *Message) bool {
+ if a == b {
+ return true
+ }
+ if (a == nil) != (b == nil) {
+ return false
+ }
if a.md.GetFullyQualifiedName() != b.md.GetFullyQualifiedName() {
return false
}
@@ -128,25 +134,24 @@
return proto.Equal(a, b)
}
// Mixed
- if aok {
- md, err := desc.LoadMessageDescriptorForMessage(b)
- if err != nil {
- return false
- }
- db = NewMessageWithMessageFactory(md, da.mf)
- if db.ConvertFrom(b) != nil {
- return false
- }
- return Equal(da, db)
- } else {
- md, err := desc.LoadMessageDescriptorForMessage(a)
- if err != nil {
- return false
- }
- da = NewMessageWithMessageFactory(md, db.mf)
- if da.ConvertFrom(a) != nil {
- return false
- }
- return Equal(da, db)
+ if bok {
+ // we want a to be the dynamic one
+ b, da = a, db
}
+
+ // Instead of panic'ing below if we have a nil dynamic message, check
+ // now and return false if the input message is not also nil.
+ if da == nil {
+ return isNil(b)
+ }
+
+ md, err := desc.LoadMessageDescriptorForMessage(b)
+ if err != nil {
+ return false
+ }
+ db = NewMessageWithMessageFactory(md, da.mf)
+ if db.ConvertFrom(b) != nil {
+ return false
+ }
+ return Equal(da, db)
}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/json.go b/vendor/github.com/jhump/protoreflect/dynamic/json.go
index 7dfae09..02c8298 100644
--- a/vendor/github.com/jhump/protoreflect/dynamic/json.go
+++ b/vendor/github.com/jhump/protoreflect/dynamic/json.go
@@ -114,6 +114,10 @@
}
func (m *Message) marshalJSON(b *indentBuffer, opts *jsonpb.Marshaler) error {
+ if m == nil {
+ _, err := b.WriteString("null")
+ return err
+ }
if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed {
newOpts := *opts
newOpts.AnyResolver = r
@@ -364,7 +368,7 @@
default:
return fmt.Errorf("invalid map key value: %v (%v)", mk, rk.Type())
}
- err := writeString(b, strkey)
+ err := writeJsonString(b, strkey)
if err != nil {
return err
}
@@ -430,44 +434,49 @@
return writeJsonString(b, rv.String())
default:
// must be a message
+ if isNil(v) {
+ _, err := b.WriteString("null")
+ return err
+ }
+
if dm, ok := v.(*Message); ok {
return dm.marshalJSON(b, opts)
+ }
+
+ var err error
+ if b.indentCount <= 0 || len(b.indent) == 0 {
+ err = opts.Marshal(b, v.(proto.Message))
} else {
- var err error
- if b.indentCount <= 0 || len(b.indent) == 0 {
- err = opts.Marshal(b, v.(proto.Message))
- } else {
- str, err := opts.MarshalToString(v.(proto.Message))
- if err != nil {
- return err
+ str, err := opts.MarshalToString(v.(proto.Message))
+ if err != nil {
+ return err
+ }
+ indent := strings.Repeat(b.indent, b.indentCount)
+ pos := 0
+ // add indention prefix to each line
+ for pos < len(str) {
+ start := pos
+ nextPos := strings.Index(str[pos:], "\n")
+ if nextPos == -1 {
+ nextPos = len(str)
+ } else {
+ nextPos = pos + nextPos + 1 // include newline
}
- indent := strings.Repeat(b.indent, b.indentCount)
- pos := 0
- // add indention prefix to each line
- for pos < len(str) {
- start := pos
- nextPos := strings.Index(str[pos:], "\n")
- if nextPos == -1 {
- nextPos = len(str)
- } else {
- nextPos = pos + nextPos + 1 // include newline
- }
- line := str[start:nextPos]
- if pos > 0 {
- _, err = b.WriteString(indent)
- if err != nil {
- return err
- }
- }
- _, err = b.WriteString(line)
+ line := str[start:nextPos]
+ if pos > 0 {
+ _, err = b.WriteString(indent)
if err != nil {
return err
}
- pos = nextPos
}
+ _, err = b.WriteString(line)
+ if err != nil {
+ return err
+ }
+ pos = nextPos
}
- return err
}
+ return err
}
}
@@ -665,8 +674,10 @@
}
func isWellKnownListValue(fd *desc.FieldDescriptor) bool {
+ // we look for ListValue; but we also look for Value, which can be assigned a ListValue
return !fd.IsRepeated() && fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
- fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.ListValue"
+ (fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.ListValue" ||
+ fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.Value")
}
func unmarshalJsField(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler) (interface{}, error) {
@@ -698,11 +709,11 @@
return nil, err
}
for r.hasNext() {
- kk, err := unmarshalJsFieldElement(keyType, r, mf, opts)
+ kk, err := unmarshalJsFieldElement(keyType, r, mf, opts, false)
if err != nil {
return nil, err
}
- vv, err := unmarshalJsFieldElement(valueType, r, mf, opts)
+ vv, err := unmarshalJsFieldElement(valueType, r, mf, opts, true)
if err != nil {
return nil, err
}
@@ -725,7 +736,7 @@
var v interface{}
for r.hasNext() {
var err error
- v, err = unmarshalJsFieldElement(fd, r, mf, opts)
+ v, err = unmarshalJsFieldElement(fd, r, mf, opts, false)
if err != nil {
return nil, err
}
@@ -761,7 +772,7 @@
// binary wire format that supports changing an optional field to repeated and vice versa.
// If the field is repeated, we store value as singleton slice of that one value.
- v, err := unmarshalJsFieldElement(fd, r, mf, opts)
+ v, err := unmarshalJsFieldElement(fd, r, mf, opts, false)
if err != nil {
return nil, err
}
@@ -776,7 +787,7 @@
}
}
-func unmarshalJsFieldElement(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler) (interface{}, error) {
+func unmarshalJsFieldElement(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler, allowNilMessage bool) (interface{}, error) {
t, err := r.peek()
if err != nil {
return nil, err
@@ -785,6 +796,13 @@
switch fd.GetType() {
case descriptor.FieldDescriptorProto_TYPE_MESSAGE,
descriptor.FieldDescriptorProto_TYPE_GROUP:
+
+ if t == nil && allowNilMessage {
+ // if json is simply "null" return a nil pointer
+ r.poll()
+ return nilMessage(fd.GetMessageType()), nil
+ }
+
m := mf.NewMessage(fd.GetMessageType())
if dm, ok := m.(*Message); ok {
if err := dm.unmarshalJson(r, opts); err != nil {
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go
index bb68d7b..03162a4 100644
--- a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go
+++ b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go
@@ -1,4 +1,5 @@
-//+build !go1.12
+//go:build !go1.12
+// +build !go1.12
package dynamic
@@ -44,7 +45,7 @@
// unwrap it
k = reflect.ValueOf(k.Interface())
}
- kk, err := validFieldValueForRv(keyField, k)
+ kk, err := validElementFieldValueForRv(keyField, k, false)
if err != nil {
return nil, err
}
@@ -53,7 +54,7 @@
// unwrap it
v = reflect.ValueOf(v.Interface())
}
- vv, err := validFieldValueForRv(valField, v)
+ vv, err := validElementFieldValueForRv(valField, v, true)
if err != nil {
return nil, err
}
@@ -76,7 +77,7 @@
return true
}
-func mergeMapVal(src, target reflect.Value, targetType reflect.Type) error {
+func mergeMapVal(src, target reflect.Value, targetType reflect.Type, deterministic bool) error {
tkt := targetType.Key()
tvt := targetType.Elem()
for _, k := range src.MapKeys() {
@@ -90,7 +91,7 @@
nk = k.Addr()
} else {
nk = reflect.New(tkt).Elem()
- if err := mergeVal(k, nk); err != nil {
+ if err := mergeVal(k, nk, deterministic); err != nil {
return err
}
}
@@ -100,7 +101,7 @@
nv = v.Addr()
} else {
nv = reflect.New(tvt).Elem()
- if err := mergeVal(v, nv); err != nil {
+ if err := mergeVal(v, nv, deterministic); err != nil {
return err
}
}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go
index f5ffd67..ef1b370 100644
--- a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go
+++ b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go
@@ -1,4 +1,5 @@
-//+build go1.12
+//go:build go1.12
+// +build go1.12
package dynamic
@@ -47,7 +48,7 @@
// unwrap it
k = reflect.ValueOf(k.Interface())
}
- kk, err := validFieldValueForRv(keyField, k)
+ kk, err := validElementFieldValueForRv(keyField, k, false)
if err != nil {
return nil, err
}
@@ -56,7 +57,7 @@
// unwrap it
v = reflect.ValueOf(v.Interface())
}
- vv, err := validFieldValueForRv(valField, v)
+ vv, err := validElementFieldValueForRv(valField, v, true)
if err != nil {
return nil, err
}
@@ -80,7 +81,7 @@
return true
}
-func mergeMapVal(src, target reflect.Value, targetType reflect.Type) error {
+func mergeMapVal(src, target reflect.Value, targetType reflect.Type, deterministic bool) error {
tkt := targetType.Key()
tvt := targetType.Elem()
iter := src.MapRange()
@@ -96,7 +97,7 @@
nk = k.Addr()
} else {
nk = reflect.New(tkt).Elem()
- if err := mergeVal(k, nk); err != nil {
+ if err := mergeVal(k, nk, deterministic); err != nil {
return err
}
}
@@ -106,7 +107,7 @@
nv = v.Addr()
} else {
nv = reflect.New(tvt).Elem()
- if err := mergeVal(v, nv); err != nil {
+ if err := mergeVal(v, nv, deterministic); err != nil {
return err
}
}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go b/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go
index 6c54de8..9ab8e61 100644
--- a/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go
+++ b/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go
@@ -159,6 +159,18 @@
}
}
+func isWellKnownType(t reflect.Type) bool {
+ if t.Implements(typeOfWkt) {
+ return true
+ }
+ if msg, ok := reflect.Zero(t).Interface().(proto.Message); ok {
+ name := proto.MessageName(msg)
+ _, ok := wellKnownTypeNames[name]
+ return ok
+ }
+ return false
+}
+
// GetKnownType will return the reflect.Type for the given message name if it is
// known. If it is not known, nil is returned.
func (r *KnownTypeRegistry) GetKnownType(messageName string) reflect.Type {
@@ -166,7 +178,7 @@
if r == nil {
// a nil registry behaves the same as zero value instance: only know of well-known types
t := proto.MessageType(messageName)
- if t != nil && t.Implements(typeOfWkt) {
+ if t != nil && isWellKnownType(t) {
msgType = t
}
} else {
@@ -174,7 +186,7 @@
msgType = proto.MessageType(messageName)
} else if !r.excludeWkt {
t := proto.MessageType(messageName)
- if t != nil && t.Implements(typeOfWkt) {
+ if t != nil && isWellKnownType(t) {
msgType = t
}
}
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/text.go b/vendor/github.com/jhump/protoreflect/dynamic/text.go
index 72636f2..5784d3e 100644
--- a/vendor/github.com/jhump/protoreflect/dynamic/text.go
+++ b/vendor/github.com/jhump/protoreflect/dynamic/text.go
@@ -193,9 +193,11 @@
if err != nil {
return err
}
- err = marshalKnownFieldText(b, vfd, mv)
- if err != nil {
- return err
+ if !isNil(mv) {
+ err = marshalKnownFieldText(b, vfd, mv)
+ if err != nil {
+ return err
+ }
}
err = b.end()
@@ -344,7 +346,7 @@
case '\t':
_, err = b.WriteString("\\t")
case '"':
- _, err = b.WriteString("\\")
+ _, err = b.WriteString("\\\"")
case '\\':
_, err = b.WriteString("\\\\")
default:
diff --git a/vendor/github.com/jhump/protoreflect/codec/buffer.go b/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go
similarity index 89%
rename from vendor/github.com/jhump/protoreflect/codec/buffer.go
rename to vendor/github.com/jhump/protoreflect/internal/codec/buffer.go
index b9de99c..09f8849 100644
--- a/vendor/github.com/jhump/protoreflect/codec/buffer.go
+++ b/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go
@@ -40,6 +40,12 @@
cb.deterministic = deterministic
}
+// IsDeterministic returns whether or not this buffer is configured to encode
+// messages deterministically.
+func (cb *Buffer) IsDeterministic() bool {
+ return cb.deterministic
+}
+
// Reset resets this buffer back to empty. Any subsequent writes/encodes
// to the buffer will allocate a new backing slice of bytes.
func (cb *Buffer) Reset() {
@@ -66,9 +72,9 @@
}
// Skip attempts to skip the given number of bytes in the input. If
-// the input has fewer bytes than the given count, false is returned
-// and the buffer is unchanged. Otherwise, the given number of bytes
-// are skipped and true is returned.
+// the input has fewer bytes than the given count, io.ErrUnexpectedEOF
+// is returned and the buffer is unchanged. Otherwise, the given number
+// of bytes are skipped and nil is returned.
func (cb *Buffer) Skip(count int) error {
if count < 0 {
return fmt.Errorf("proto: bad byte length %d", count)
diff --git a/vendor/github.com/jhump/protoreflect/codec/decode.go b/vendor/github.com/jhump/protoreflect/internal/codec/decode.go
similarity index 68%
rename from vendor/github.com/jhump/protoreflect/codec/decode.go
rename to vendor/github.com/jhump/protoreflect/internal/codec/decode.go
index 2a7e59f..a25f680 100644
--- a/vendor/github.com/jhump/protoreflect/codec/decode.go
+++ b/vendor/github.com/jhump/protoreflect/internal/codec/decode.go
@@ -7,7 +7,6 @@
"math"
"github.com/golang/protobuf/proto"
- "github.com/golang/protobuf/protoc-gen-go/descriptor"
)
// ErrOverflow is returned when an integer is too large to be represented.
@@ -17,29 +16,6 @@
// is not valid.
var ErrBadWireType = errors.New("proto: bad wiretype")
-var varintTypes = map[descriptor.FieldDescriptorProto_Type]bool{}
-var fixed32Types = map[descriptor.FieldDescriptorProto_Type]bool{}
-var fixed64Types = map[descriptor.FieldDescriptorProto_Type]bool{}
-
-func init() {
- varintTypes[descriptor.FieldDescriptorProto_TYPE_BOOL] = true
- varintTypes[descriptor.FieldDescriptorProto_TYPE_INT32] = true
- varintTypes[descriptor.FieldDescriptorProto_TYPE_INT64] = true
- varintTypes[descriptor.FieldDescriptorProto_TYPE_UINT32] = true
- varintTypes[descriptor.FieldDescriptorProto_TYPE_UINT64] = true
- varintTypes[descriptor.FieldDescriptorProto_TYPE_SINT32] = true
- varintTypes[descriptor.FieldDescriptorProto_TYPE_SINT64] = true
- varintTypes[descriptor.FieldDescriptorProto_TYPE_ENUM] = true
-
- fixed32Types[descriptor.FieldDescriptorProto_TYPE_FIXED32] = true
- fixed32Types[descriptor.FieldDescriptorProto_TYPE_SFIXED32] = true
- fixed32Types[descriptor.FieldDescriptorProto_TYPE_FLOAT] = true
-
- fixed64Types[descriptor.FieldDescriptorProto_TYPE_FIXED64] = true
- fixed64Types[descriptor.FieldDescriptorProto_TYPE_SFIXED64] = true
- fixed64Types[descriptor.FieldDescriptorProto_TYPE_DOUBLE] = true
-}
-
func (cb *Buffer) decodeVarintSlow() (x uint64, err error) {
i := cb.index
l := len(cb.buf)
@@ -227,18 +203,6 @@
return
}
-// DecodeZigZag32 decodes a signed 32-bit integer from the given
-// zig-zag encoded value.
-func DecodeZigZag32(v uint64) int32 {
- return int32((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31))
-}
-
-// DecodeZigZag64 decodes a signed 64-bit integer from the given
-// zig-zag encoded value.
-func DecodeZigZag64(v uint64) int64 {
- return int64((v >> 1) ^ uint64((int64(v&1)<<63)>>63))
-}
-
// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
// This is the format used for the bytes protocol buffer
// type and for embedded messages.
@@ -308,8 +272,58 @@
return nil
}
+// SkipField attempts to skip the value of a field with the given wire
+// type. When consuming a protobuf-encoded stream, it can be called immediately
+// after DecodeTagAndWireType to discard the subsequent data for the field.
+func (cb *Buffer) SkipField(wireType int8) error {
+ switch wireType {
+ case proto.WireFixed32:
+ if err := cb.Skip(4); err != nil {
+ return err
+ }
+ case proto.WireFixed64:
+ if err := cb.Skip(8); err != nil {
+ return err
+ }
+ case proto.WireVarint:
+ // skip varint by finding last byte (has high bit unset)
+ i := cb.index
+ limit := i + 10 // varint cannot be >10 bytes
+ for {
+ if i >= limit {
+ return ErrOverflow
+ }
+ if i >= len(cb.buf) {
+ return io.ErrUnexpectedEOF
+ }
+ if cb.buf[i]&0x80 == 0 {
+ break
+ }
+ i++
+ }
+ // TODO: This would only overflow if buffer length was MaxInt and we
+ // read the last byte. This is not a real/feasible concern on 64-bit
+ // systems. Something to worry about for 32-bit systems? Do we care?
+ cb.index = i + 1
+ case proto.WireBytes:
+ l, err := cb.DecodeVarint()
+ if err != nil {
+ return err
+ }
+ if err := cb.Skip(int(l)); err != nil {
+ return err
+ }
+ case proto.WireStartGroup:
+ if err := cb.SkipGroup(); err != nil {
+ return err
+ }
+ default:
+ return ErrBadWireType
+ }
+ return nil
+}
+
func (cb *Buffer) findGroupEnd() (groupEnd int, dataEnd int, err error) {
- bs := cb.buf
start := cb.index
defer func() {
cb.index = start
@@ -321,52 +335,12 @@
if err != nil {
return 0, 0, err
}
- // skip past the field's data
- switch wireType {
- case proto.WireFixed32:
- if err := cb.Skip(4); err != nil {
- return 0, 0, err
- }
- case proto.WireFixed64:
- if err := cb.Skip(8); err != nil {
- return 0, 0, err
- }
- case proto.WireVarint:
- // skip varint by finding last byte (has high bit unset)
- i := cb.index
- limit := i + 10 // varint cannot be >10 bytes
- for {
- if i >= limit {
- return 0, 0, ErrOverflow
- }
- if i >= len(bs) {
- return 0, 0, io.ErrUnexpectedEOF
- }
- if bs[i]&0x80 == 0 {
- break
- }
- i++
- }
- // TODO: This would only overflow if buffer length was MaxInt and we
- // read the last byte. This is not a real/feasible concern on 64-bit
- // systems. Something to worry about for 32-bit systems? Do we care?
- cb.index = i + 1
- case proto.WireBytes:
- l, err := cb.DecodeVarint()
- if err != nil {
- return 0, 0, err
- }
- if err := cb.Skip(int(l)); err != nil {
- return 0, 0, err
- }
- case proto.WireStartGroup:
- if err := cb.SkipGroup(); err != nil {
- return 0, 0, err
- }
- case proto.WireEndGroup:
+ if wireType == proto.WireEndGroup {
return cb.index, fieldStart, nil
- default:
- return 0, 0, ErrBadWireType
+ }
+ // skip past the field's data
+ if err := cb.SkipField(wireType); err != nil {
+ return 0, 0, err
}
}
}
diff --git a/vendor/github.com/jhump/protoreflect/codec/encode.go b/vendor/github.com/jhump/protoreflect/internal/codec/encode.go
similarity index 76%
rename from vendor/github.com/jhump/protoreflect/codec/encode.go
rename to vendor/github.com/jhump/protoreflect/internal/codec/encode.go
index c84523f..524f1bc 100644
--- a/vendor/github.com/jhump/protoreflect/codec/encode.go
+++ b/vendor/github.com/jhump/protoreflect/internal/codec/encode.go
@@ -1,6 +1,8 @@
package codec
-import "github.com/golang/protobuf/proto"
+import (
+ "github.com/golang/protobuf/proto"
+)
// EncodeVarint writes a varint-encoded integer to the Buffer.
// This is the format for the
@@ -50,20 +52,6 @@
return nil
}
-// EncodeZigZag64 does zig-zag encoding to convert the given
-// signed 64-bit integer into a form that can be expressed
-// efficiently as a varint, even for negative values.
-func EncodeZigZag64(v int64) uint64 {
- return (uint64(v) << 1) ^ uint64(v>>63)
-}
-
-// EncodeZigZag32 does zig-zag encoding to convert the given
-// signed 32-bit integer into a form that can be expressed
-// efficiently as a varint, even for negative values.
-func EncodeZigZag32(v int32) uint64 {
- return uint64((uint32(v) << 1) ^ uint32((v >> 31)))
-}
-
// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
// This is the format used for the bytes protocol buffer
// type and for embedded messages.
@@ -101,22 +89,7 @@
}
func marshalMessage(b []byte, pm proto.Message, deterministic bool) ([]byte, error) {
- // we try to use the most efficient way to marshal to existing slice
- nm, ok := pm.(interface {
- // this interface is implemented by generated messages
- XXX_Size() int
- XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
- })
- if ok {
- sz := nm.XXX_Size()
- if cap(b) < len(b)+sz {
- // re-allocate to fit
- bytes := make([]byte, len(b), len(b)+sz)
- copy(bytes, b)
- b = bytes
- }
- return nm.XXX_Marshal(b, deterministic)
- }
+ // We try to use the most efficient way to marshal to existing slice.
if deterministic {
// see if the message has custom deterministic methods, preferring an
@@ -141,6 +114,17 @@
}
return append(b, bytes...), nil
}
+
+ var buf proto.Buffer
+ buf.SetDeterministic(true)
+ if err := buf.Marshal(pm); err != nil {
+ return nil, err
+ }
+ bytes := buf.Bytes()
+ if len(b) == 0 {
+ return bytes, nil
+ }
+ return append(b, bytes...), nil
}
mam, ok := pm.(interface {
diff --git a/vendor/github.com/jhump/protoreflect/internal/unrecognized.go b/vendor/github.com/jhump/protoreflect/internal/unrecognized.go
new file mode 100644
index 0000000..c903d4b
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/internal/unrecognized.go
@@ -0,0 +1,86 @@
+package internal
+
+import (
+ "reflect"
+
+ "github.com/golang/protobuf/proto"
+)
+
+var typeOfBytes = reflect.TypeOf([]byte(nil))
+
+// GetUnrecognized fetches the bytes of unrecognized fields for the given message.
+func GetUnrecognized(msg proto.Message) []byte {
+ val := reflect.Indirect(reflect.ValueOf(msg))
+ u := val.FieldByName("XXX_unrecognized")
+ if u.IsValid() && u.Type() == typeOfBytes {
+ return u.Interface().([]byte)
+ }
+
+ // Fallback to reflection for API v2 messages
+ get, _, _, ok := unrecognizedGetSetMethods(val)
+ if !ok {
+ return nil
+ }
+
+ return get.Call([]reflect.Value(nil))[0].Convert(typeOfBytes).Interface().([]byte)
+}
+
+// SetUnrecognized adds the given bytes to the unrecognized fields for the given message.
+func SetUnrecognized(msg proto.Message, data []byte) {
+ val := reflect.Indirect(reflect.ValueOf(msg))
+ u := val.FieldByName("XXX_unrecognized")
+ if u.IsValid() && u.Type() == typeOfBytes {
+ // Just store the bytes in the unrecognized field
+ ub := u.Interface().([]byte)
+ ub = append(ub, data...)
+ u.Set(reflect.ValueOf(ub))
+ return
+ }
+
+ // Fallback to reflection for API v2 messages
+ get, set, argType, ok := unrecognizedGetSetMethods(val)
+ if !ok {
+ return
+ }
+
+ existing := get.Call([]reflect.Value(nil))[0].Convert(typeOfBytes).Interface().([]byte)
+ if len(existing) > 0 {
+ data = append(existing, data...)
+ }
+ set.Call([]reflect.Value{reflect.ValueOf(data).Convert(argType)})
+}
+
+func unrecognizedGetSetMethods(val reflect.Value) (get reflect.Value, set reflect.Value, argType reflect.Type, ok bool) {
+ // val could be an APIv2 message. We use reflection to interact with
+ // this message so that we don't have a hard dependency on the new
+ // version of the protobuf package.
+ refMethod := val.MethodByName("ProtoReflect")
+ if !refMethod.IsValid() {
+ if val.CanAddr() {
+ refMethod = val.Addr().MethodByName("ProtoReflect")
+ }
+ if !refMethod.IsValid() {
+ return
+ }
+ }
+ refType := refMethod.Type()
+ if refType.NumIn() != 0 || refType.NumOut() != 1 {
+ return
+ }
+ ref := refMethod.Call([]reflect.Value(nil))
+ getMethod, setMethod := ref[0].MethodByName("GetUnknown"), ref[0].MethodByName("SetUnknown")
+ if !getMethod.IsValid() || !setMethod.IsValid() {
+ return
+ }
+ getType := getMethod.Type()
+ setType := setMethod.Type()
+ if getType.NumIn() != 0 || getType.NumOut() != 1 || setType.NumIn() != 1 || setType.NumOut() != 0 {
+ return
+ }
+ arg := setType.In(0)
+ if !arg.ConvertibleTo(typeOfBytes) || getType.Out(0) != arg {
+ return
+ }
+
+ return getMethod, setMethod, arg, true
+}