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
|
package server
import (
"strings"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
field_mask "google.golang.org/protobuf/types/known/fieldmaskpb"
)
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
}
|