package proto
import (
)
func (, Message) {
, := .ProtoReflect(), .ProtoReflect()
if .Descriptor() != .Descriptor() {
if , := .Descriptor().FullName(), .Descriptor().FullName(); != {
panic(fmt.Sprintf("descriptor mismatch: %v != %v", , ))
}
panic("descriptor mismatch")
}
mergeOptions{}.mergeMessage(, )
}
func ( Message) Message {
if == nil {
return nil
}
:= .ProtoReflect()
if !.IsValid() {
return .Type().Zero().Interface()
}
:= .New()
mergeOptions{}.mergeMessage(, )
return .Interface()
}
type mergeOptions struct{}
func ( mergeOptions) (, protoreflect.Message) {
:= protoMethods()
if != nil && .Merge != nil {
:= protoiface.MergeInput{
Destination: ,
Source: ,
}
:= .Merge()
if .Flags&protoiface.MergeComplete != 0 {
return
}
}
if !.IsValid() {
panic(fmt.Sprintf("cannot merge into invalid %v message", .Descriptor().FullName()))
}
.Range(func( protoreflect.FieldDescriptor, protoreflect.Value) bool {
switch {
case .IsList():
.mergeList(.Mutable().List(), .List(), )
case .IsMap():
.mergeMap(.Mutable().Map(), .Map(), .MapValue())
case .Message() != nil:
.(.Mutable().Message(), .Message())
case .Kind() == protoreflect.BytesKind:
.Set(, .cloneBytes())
default:
.Set(, )
}
return true
})
if len(.GetUnknown()) > 0 {
.SetUnknown(append(.GetUnknown(), .GetUnknown()...))
}
}
func ( mergeOptions) (, protoreflect.List, protoreflect.FieldDescriptor) {
for , := 0, .Len(); < ; ++ {
switch := .Get(); {
case .Message() != nil:
:= .NewElement()
.mergeMessage(.Message(), .Message())
.Append()
case .Kind() == protoreflect.BytesKind:
.Append(.cloneBytes())
default:
.Append()
}
}
}
func ( mergeOptions) (, protoreflect.Map, protoreflect.FieldDescriptor) {
.Range(func( protoreflect.MapKey, protoreflect.Value) bool {
switch {
case .Message() != nil:
:= .NewValue()
.mergeMessage(.Message(), .Message())
.Set(, )
case .Kind() == protoreflect.BytesKind:
.Set(, .cloneBytes())
default:
.Set(, )
}
return true
})
}
func ( mergeOptions) ( protoreflect.Value) protoreflect.Value {
return protoreflect.ValueOfBytes(append([]byte{}, .Bytes()...))
}