Skip to content

Instantly share code, notes, and snippets.

@Olex1313
Created October 9, 2023 06:23
Show Gist options
  • Save Olex1313/88ff52b1f4cad1af15c6733b4553b4cb to your computer and use it in GitHub Desktop.
Save Olex1313/88ff52b1f4cad1af15c6733b4553b4cb 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