-
Notifications
You must be signed in to change notification settings - Fork 25
/
grpc_fieldmask.go
41 lines (34 loc) · 1.16 KB
/
grpc_fieldmask.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package utils
import (
"strings"
"google.golang.org/genproto/protobuf/field_mask"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
)
// ApplyFieldMask applies the field mask to the patchee message.
func ApplyFieldMask(patchee, patcher proto.Message, mask *field_mask.FieldMask) {
if mask == nil {
return
}
if patchee.ProtoReflect().Descriptor().FullName() != patcher.ProtoReflect().Descriptor().FullName() {
panic("patchee and patcher must be same type")
}
for _, path := range mask.GetPaths() {
patcherField, patcherParent := getField(patcher.ProtoReflect(), path)
patcheeField, patcheeParent := getField(patchee.ProtoReflect(), path)
patcheeParent.Set(patcheeField, patcherParent.Get(patcherField))
}
}
func getField(msg protoreflect.Message, path string) (field protoreflect.FieldDescriptor, parent protoreflect.Message) {
fields := msg.Descriptor().Fields()
parent = msg
names := strings.Split(path, ".")
for i, name := range names {
field = fields.ByName(protoreflect.Name(name))
if i < len(names)-1 {
parent = parent.Get(field).Message()
fields = field.Message().Fields()
}
}
return field, parent
}