@@ -17,6 +17,7 @@ package protovalidate
1717import (
1818 "fmt"
1919 "maps"
20+ "slices"
2021 "sync"
2122 "sync/atomic"
2223
@@ -231,15 +232,15 @@ func (bldr *builder) processOneofRules(
231232
232233func (bldr * builder ) processFields (
233234 desc protoreflect.MessageDescriptor ,
234- _ * validate.MessageRules ,
235+ msgRules * validate.MessageRules ,
235236 msgEval * message ,
236237 cache messageCache ,
237238) {
238239 fields := desc .Fields ()
239240 for i := range fields .Len () {
240241 fdesc := fields .Get (i )
241242 fieldRules , _ := ResolveFieldRules (fdesc )
242- fldEval , err := bldr .buildField (fdesc , fieldRules , cache )
243+ fldEval , err := bldr .buildField (fdesc , fieldRules , msgRules , cache )
243244 if err != nil {
244245 fldEval .Err = err
245246 }
@@ -250,8 +251,16 @@ func (bldr *builder) processFields(
250251func (bldr * builder ) buildField (
251252 fieldDescriptor protoreflect.FieldDescriptor ,
252253 fieldRules * validate.FieldRules ,
254+ msgRules * validate.MessageRules ,
253255 cache messageCache ,
254256) (field , error ) {
257+ if ! fieldRules .HasIgnore () && isPartOfMessageOneof (msgRules , fieldDescriptor ) {
258+ fieldRules = proto .CloneOf (fieldRules )
259+ if fieldRules == nil {
260+ fieldRules = & validate.FieldRules {}
261+ }
262+ fieldRules .SetIgnore (validate .Ignore_IGNORE_IF_UNPOPULATED )
263+ }
255264 fld := field {
256265 Value : value {
257266 Descriptor : fieldDescriptor ,
@@ -610,3 +619,9 @@ func isMessageField(fdesc protoreflect.FieldDescriptor) bool {
610619 return fdesc .Kind () == protoreflect .MessageKind ||
611620 fdesc .Kind () == protoreflect .GroupKind
612621}
622+
623+ func isPartOfMessageOneof (msgRules * validate.MessageRules , field protoreflect.FieldDescriptor ) bool {
624+ return slices .ContainsFunc (msgRules .GetOneof (), func (oneof * validate.MessageOneofRule ) bool {
625+ return slices .Contains (oneof .GetFields (), string (field .Name ()))
626+ })
627+ }
0 commit comments