Skip to content

Instantly share code, notes, and snippets.

@picatz
Forked from Olex1313/clear_proto.go
Created September 2, 2024 03:10
Show Gist options
  • Save picatz/0c5d88d79029812b36f0ecf025328fc6 to your computer and use it in GitHub Desktop.
Save picatz/0c5d88d79029812b36f0ecf025328fc6 to your computer and use it in GitHub Desktop.
Example cleanup function for protobuf message
func clearProtoFields(msg proto.Message, sensitiveFieldAnnotation *protoimpl.ExtensionInfo) proto.Message {
clonedMsg := proto.Clone(msg)
reflectMsg := proto.MessageReflect(clonedMsg)
var messagesToCheck []protoreflect.Message
messagesToCheck = append(messagesToCheck, reflectMsg)
for len(messagesToCheck) != 0 {
lastIdx := len(messagesToCheck) - 1
visitMessage := messagesToCheck[lastIdx]
messagesToCheck = messagesToCheck[:lastIdx]
visitMessage.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool {
if opts := fd.Options().(*descriptorpb.FieldOptions); opts != nil {
if proto.HasExtension(opts, sensitiveFieldAnnotation) {
visitMessage.Clear(fd)
}
return true
}
switch {
case fd.Kind() != protoreflect.MessageKind:
return true
case fd.IsList():
listVal := val.List()
for i := 0; i < listVal.Len(); i++ {
elem := listVal.Get(i)
messagesToCheck = append(messagesToCheck, elem.Message())
}
case fd.IsMap():
mapVal := val.Map()
mapVal.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
messagesToCheck = append(messagesToCheck, v.Message())
return true
})
default:
messagesToCheck = append(messagesToCheck, val.Message())
}
return true
})
}
return clonedMsg
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment