github.com/grpc-ecosystem/grpc-gateway/v2@v2.19.1/examples/internal/server/fieldmask_helper.go (about) 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 }