...
1 package server
2
3 import (
4 "strings"
5
6 "google.golang.org/protobuf/proto"
7 "google.golang.org/protobuf/reflect/protoreflect"
8 field_mask "google.golang.org/protobuf/types/known/fieldmaskpb"
9 )
10
11 func applyFieldMask(patchee, patcher proto.Message, mask *field_mask.FieldMask) {
12 if mask == nil {
13 return
14 }
15 if patchee.ProtoReflect().Descriptor().FullName() != patcher.ProtoReflect().Descriptor().FullName() {
16 panic("patchee and patcher must be same type")
17 }
18
19 for _, path := range mask.GetPaths() {
20 patcherField, patcherParent := getField(patcher.ProtoReflect(), path)
21 patcheeField, patcheeParent := getField(patchee.ProtoReflect(), path)
22 patcheeParent.Set(patcheeField, patcherParent.Get(patcherField))
23 }
24 }
25
26 func getField(msg protoreflect.Message, path string) (field protoreflect.FieldDescriptor, parent protoreflect.Message) {
27 fields := msg.Descriptor().Fields()
28 parent = msg
29 names := strings.Split(path, ".")
30 for i, name := range names {
31 field = fields.ByName(protoreflect.Name(name))
32
33 if i < len(names)-1 {
34 parent = parent.Get(field).Message()
35 fields = field.Message().Fields()
36 }
37 }
38
39 return field, parent
40 }
41
View as plain text