podman

Форк
0
176 строк · 4.5 Кб
1
// Copyright 2020 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
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
// merge is protoreflect.Methods.Merge.
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.