[VOL-4442] grpc streaming connection monitoring
Change-Id: I6b26a29c74be8833e7262eb59d266e6cce66f0c3
diff --git a/vendor/github.com/jhump/protoreflect/dynamic/merge.go b/vendor/github.com/jhump/protoreflect/dynamic/merge.go
new file mode 100644
index 0000000..ce727fd
--- /dev/null
+++ b/vendor/github.com/jhump/protoreflect/dynamic/merge.go
@@ -0,0 +1,100 @@
+package dynamic
+
+import (
+ "errors"
+ "reflect"
+
+ "github.com/golang/protobuf/proto"
+
+ "github.com/jhump/protoreflect/desc"
+)
+
+// Merge merges the given source message into the given destination message. Use
+// use this instead of proto.Merge when one or both of the messages might be a
+// a dynamic message. If there is a problem merging the messages, such as the
+// two messages having different types, then this method will panic (just as
+// proto.Merges does).
+func Merge(dst, src proto.Message) {
+ if dm, ok := dst.(*Message); ok {
+ if err := dm.MergeFrom(src); err != nil {
+ panic(err.Error())
+ }
+ } else if dm, ok := src.(*Message); ok {
+ if err := dm.MergeInto(dst); err != nil {
+ panic(err.Error())
+ }
+ } else {
+ proto.Merge(dst, src)
+ }
+}
+
+// TryMerge merges the given source message into the given destination message.
+// You can use this instead of proto.Merge when one or both of the messages
+// might be a dynamic message. Unlike proto.Merge, this method will return an
+// error on failure instead of panic'ing.
+func TryMerge(dst, src proto.Message) error {
+ if dm, ok := dst.(*Message); ok {
+ if err := dm.MergeFrom(src); err != nil {
+ return err
+ }
+ } else if dm, ok := src.(*Message); ok {
+ if err := dm.MergeInto(dst); err != nil {
+ return err
+ }
+ } else {
+ // proto.Merge panics on bad input, so we first verify
+ // inputs and return error instead of panic
+ out := reflect.ValueOf(dst)
+ if out.IsNil() {
+ return errors.New("proto: nil destination")
+ }
+ in := reflect.ValueOf(src)
+ if in.Type() != out.Type() {
+ return errors.New("proto: type mismatch")
+ }
+ proto.Merge(dst, src)
+ }
+ return nil
+}
+
+func mergeField(m *Message, fd *desc.FieldDescriptor, val interface{}) error {
+ rv := reflect.ValueOf(val)
+
+ if fd.IsMap() && rv.Kind() == reflect.Map {
+ return mergeMapField(m, fd, rv)
+ }
+
+ if fd.IsRepeated() && rv.Kind() == reflect.Slice && rv.Type() != typeOfBytes {
+ for i := 0; i < rv.Len(); i++ {
+ e := rv.Index(i)
+ if e.Kind() == reflect.Interface && !e.IsNil() {
+ e = e.Elem()
+ }
+ if err := m.addRepeatedField(fd, e.Interface()); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ if fd.IsRepeated() {
+ return m.addRepeatedField(fd, val)
+ } else if fd.GetMessageType() == nil {
+ return m.setField(fd, val)
+ }
+
+ // it's a message type, so we want to merge contents
+ var err error
+ if val, err = validFieldValue(fd, val); err != nil {
+ return err
+ }
+
+ existing, _ := m.doGetField(fd, true)
+ if existing != nil && !reflect.ValueOf(existing).IsNil() {
+ return TryMerge(existing.(proto.Message), val.(proto.Message))
+ }
+
+ // no existing message, so just set field
+ m.internalSetField(fd, val)
+ return nil
+}