1
2
3
4
5 package impl
6
7 import (
8 "fmt"
9 "reflect"
10
11 "google.golang.org/protobuf/proto"
12 "google.golang.org/protobuf/reflect/protoreflect"
13 "google.golang.org/protobuf/runtime/protoiface"
14 )
15
16 type mergeOptions struct{}
17
18 func (o mergeOptions) Merge(dst, src proto.Message) {
19 proto.Merge(dst, src)
20 }
21
22
23 func (mi *MessageInfo) merge(in protoiface.MergeInput) protoiface.MergeOutput {
24 dp, ok := mi.getPointer(in.Destination)
25 if !ok {
26 return protoiface.MergeOutput{}
27 }
28 sp, ok := mi.getPointer(in.Source)
29 if !ok {
30 return protoiface.MergeOutput{}
31 }
32 mi.mergePointer(dp, sp, mergeOptions{})
33 return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
34 }
35
36 func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) {
37 mi.init()
38 if dst.IsNil() {
39 panic(fmt.Sprintf("invalid value: merging into nil message"))
40 }
41 if src.IsNil() {
42 return
43 }
44 for _, f := range mi.orderedCoderFields {
45 if f.funcs.merge == nil {
46 continue
47 }
48 sfptr := src.Apply(f.offset)
49 if f.isPointer && sfptr.Elem().IsNil() {
50 continue
51 }
52 f.funcs.merge(dst.Apply(f.offset), sfptr, f, opts)
53 }
54 if mi.extensionOffset.IsValid() {
55 sext := src.Apply(mi.extensionOffset).Extensions()
56 dext := dst.Apply(mi.extensionOffset).Extensions()
57 if *dext == nil {
58 *dext = make(map[int32]ExtensionField)
59 }
60 for num, sx := range *sext {
61 xt := sx.Type()
62 xi := getExtensionFieldInfo(xt)
63 if xi.funcs.merge == nil {
64 continue
65 }
66 dx := (*dext)[num]
67 var dv protoreflect.Value
68 if dx.Type() == sx.Type() {
69 dv = dx.Value()
70 }
71 if !dv.IsValid() && xi.unmarshalNeedsValue {
72 dv = xt.New()
73 }
74 dv = xi.funcs.merge(dv, sx.Value(), opts)
75 dx.Set(sx.Type(), dv)
76 (*dext)[num] = dx
77 }
78 }
79 if mi.unknownOffset.IsValid() {
80 su := mi.getUnknownBytes(src)
81 if su != nil && len(*su) > 0 {
82 du := mi.mutableUnknownBytes(dst)
83 *du = append(*du, *su...)
84 }
85 }
86 }
87
88 func mergeScalarValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
89 return src
90 }
91
92 func mergeBytesValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
93 return protoreflect.ValueOfBytes(append(emptyBuf[:], src.Bytes()...))
94 }
95
96 func mergeListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
97 dstl := dst.List()
98 srcl := src.List()
99 for i, llen := 0, srcl.Len(); i < llen; i++ {
100 dstl.Append(srcl.Get(i))
101 }
102 return dst
103 }
104
105 func mergeBytesListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
106 dstl := dst.List()
107 srcl := src.List()
108 for i, llen := 0, srcl.Len(); i < llen; i++ {
109 sb := srcl.Get(i).Bytes()
110 db := append(emptyBuf[:], sb...)
111 dstl.Append(protoreflect.ValueOfBytes(db))
112 }
113 return dst
114 }
115
116 func mergeMessageListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
117 dstl := dst.List()
118 srcl := src.List()
119 for i, llen := 0, srcl.Len(); i < llen; i++ {
120 sm := srcl.Get(i).Message()
121 dm := proto.Clone(sm.Interface()).ProtoReflect()
122 dstl.Append(protoreflect.ValueOfMessage(dm))
123 }
124 return dst
125 }
126
127 func mergeMessageValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
128 opts.Merge(dst.Message().Interface(), src.Message().Interface())
129 return dst
130 }
131
132 func mergeMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
133 if f.mi != nil {
134 if dst.Elem().IsNil() {
135 dst.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
136 }
137 f.mi.mergePointer(dst.Elem(), src.Elem(), opts)
138 } else {
139 dm := dst.AsValueOf(f.ft).Elem()
140 sm := src.AsValueOf(f.ft).Elem()
141 if dm.IsNil() {
142 dm.Set(reflect.New(f.ft.Elem()))
143 }
144 opts.Merge(asMessage(dm), asMessage(sm))
145 }
146 }
147
148 func mergeMessageSlice(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
149 for _, sp := range src.PointerSlice() {
150 dm := reflect.New(f.ft.Elem().Elem())
151 if f.mi != nil {
152 f.mi.mergePointer(pointerOfValue(dm), sp, opts)
153 } else {
154 opts.Merge(asMessage(dm), asMessage(sp.AsValueOf(f.ft.Elem().Elem())))
155 }
156 dst.AppendPointerSlice(pointerOfValue(dm))
157 }
158 }
159
160 func mergeBytes(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
161 *dst.Bytes() = append(emptyBuf[:], *src.Bytes()...)
162 }
163
164 func mergeBytesNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
165 v := *src.Bytes()
166 if len(v) > 0 {
167 *dst.Bytes() = append(emptyBuf[:], v...)
168 }
169 }
170
171 func mergeBytesSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
172 ds := dst.BytesSlice()
173 for _, v := range *src.BytesSlice() {
174 *ds = append(*ds, append(emptyBuf[:], v...))
175 }
176 }
177
View as plain text