Skip to content

Commit 92af3c6

Browse files
committed
Check for const and in/not_in conflicts
1 parent 2bb9474 commit 92af3c6

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

private/bufpkg/bufcheck/bufcheckserver/internal/buflintvalidate/field.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"errors"
1919
"fmt"
2020
"regexp"
21+
"slices"
2122
"strings"
2223
"unicode/utf8"
2324

@@ -100,6 +101,8 @@ const (
100101
ltNowFieldNumberInTimestampRules = 7
101102
gtNowFieldNumberInTimestampRules = 8
102103
withInFieldNumberInTimestampRules = 9
104+
// https://buf.build/bufbuild/protovalidate/docs/v1.1.0:buf.validate#buf.validate.FieldMaskRules
105+
inFieldMaskRules = 2
103106

104107
exampleName = "example"
105108
)
@@ -293,6 +296,8 @@ func checkRulesForField(
293296
return checkDurationRules(adder, fieldRules.GetDuration())
294297
case timestampRulesFieldNumber:
295298
return checkTimestampRules(adder, fieldRules.GetTimestamp())
299+
case fieldMaskRulesFieldNumber:
300+
checkFieldMaskRules(adder, fieldRules.GetFieldMask())
296301
}
297302
return nil
298303
}
@@ -741,6 +746,22 @@ func checkTimestampRules(adder *adder, timestampRules *validate.TimestampRules)
741746
return nil
742747
}
743748

749+
func checkFieldMaskRules(adder *adder, fieldMaskRules *validate.FieldMaskRules) {
750+
checkConst(adder, fieldMaskRules, fieldMaskRulesFieldNumber)
751+
if len(fieldMaskRules.In) > 0 && len(fieldMaskRules.NotIn) > 0 {
752+
for _, in := range fieldMaskRules.In {
753+
if slices.Contains(fieldMaskRules.NotIn, in) {
754+
adder.addForPathf(
755+
[]int32{fieldMaskRulesFieldNumber, inFieldMaskRules},
756+
"Field %q has path %q in both in and not_in rules.",
757+
adder.fieldName(),
758+
in,
759+
)
760+
}
761+
}
762+
}
763+
}
764+
744765
func checkExampleValues(
745766
adder *adder,
746767
pathToExampleValues []int32,

private/bufpkg/bufcheck/lint_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,8 @@ func TestRunProtovalidate(t *testing.T) {
660660
bufanalysistesting.NewFileAnnotation(t, "field.proto", 19, 5, 19, 55, "PROTOVALIDATE"),
661661
bufanalysistesting.NewFileAnnotation(t, "field.proto", 23, 52, 23, 102, "PROTOVALIDATE"),
662662
bufanalysistesting.NewFileAnnotation(t, "field_mask.proto", 16, 45, 16, 88, "PROTOVALIDATE"),
663+
bufanalysistesting.NewFileAnnotation(t, "field_mask.proto", 20, 5, 22, 6, "PROTOVALIDATE"),
664+
bufanalysistesting.NewFileAnnotation(t, "field_mask.proto", 31, 5, 31, 45, "PROTOVALIDATE"),
663665
bufanalysistesting.NewFileAnnotation(t, "map.proto", 24, 38, 24, 76, "PROTOVALIDATE"),
664666
bufanalysistesting.NewFileAnnotation(t, "map.proto", 27, 5, 27, 43, "PROTOVALIDATE"),
665667
bufanalysistesting.NewFileAnnotation(t, "map.proto", 29, 5, 29, 43, "PROTOVALIDATE"),

private/bufpkg/bufcheck/testdata/lint/protovalidate/proto/field_mask.proto

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,22 @@ message FieldMaskTest {
1414
google.protobuf.FieldMask not_in_field_mask = 3 [(buf.validate.field).field_mask.not_in = "some_other_field"];
1515
// invalid
1616
google.protobuf.FieldMask not_string = 4 [(buf.validate.field).string.const = "field"];
17+
// const should be the only field if defined
18+
google.protobuf.FieldMask in_and_const = 5 [
19+
(buf.validate.field).field_mask.in = "a",
20+
(buf.validate.field).field_mask.const = {
21+
paths: ["b"]
22+
}];
23+
// valid
24+
google.protobuf.FieldMask no_conflict = 6 [
25+
(buf.validate.field).field_mask.in = "a",
26+
(buf.validate.field).field_mask.not_in = "b",
27+
(buf.validate.field).field_mask.not_in = "c"
28+
];
29+
// conflict between in and not_in
30+
google.protobuf.FieldMask conflict = 7 [
31+
(buf.validate.field).field_mask.in = "a",
32+
(buf.validate.field).field_mask.not_in = "b",
33+
(buf.validate.field).field_mask.not_in = "a"
34+
];
1735
}

0 commit comments

Comments
 (0)