github.com/yoheimuta/protolint@v0.49.8-0.20240515023657-4ecaebb7575d/internal/addon/rules/enumFieldNamesUpperSnakeCaseRule.go (about) 1 package rules 2 3 import ( 4 "github.com/yoheimuta/go-protoparser/v4/lexer" 5 "github.com/yoheimuta/go-protoparser/v4/parser" 6 "github.com/yoheimuta/protolint/linter/autodisable" 7 "github.com/yoheimuta/protolint/linter/fixer" 8 "github.com/yoheimuta/protolint/linter/report" 9 "github.com/yoheimuta/protolint/linter/rule" 10 "github.com/yoheimuta/protolint/linter/strs" 11 "github.com/yoheimuta/protolint/linter/visitor" 12 ) 13 14 // EnumFieldNamesUpperSnakeCaseRule verifies that all enum field names are CAPITALS_WITH_UNDERSCORES. 15 // See https://developers.google.com/protocol-buffers/docs/style#enums. 16 type EnumFieldNamesUpperSnakeCaseRule struct { 17 RuleWithSeverity 18 fixMode bool 19 autoDisableType autodisable.PlacementType 20 } 21 22 // NewEnumFieldNamesUpperSnakeCaseRule creates a new EnumFieldNamesUpperSnakeCaseRule. 23 func NewEnumFieldNamesUpperSnakeCaseRule( 24 severity rule.Severity, 25 fixMode bool, 26 autoDisableType autodisable.PlacementType, 27 ) EnumFieldNamesUpperSnakeCaseRule { 28 if autoDisableType != autodisable.Noop { 29 fixMode = false 30 } 31 return EnumFieldNamesUpperSnakeCaseRule{ 32 RuleWithSeverity: RuleWithSeverity{severity: severity}, 33 fixMode: fixMode, 34 autoDisableType: autoDisableType, 35 } 36 } 37 38 // ID returns the ID of this rule. 39 func (r EnumFieldNamesUpperSnakeCaseRule) ID() string { 40 return "ENUM_FIELD_NAMES_UPPER_SNAKE_CASE" 41 } 42 43 // Purpose returns the purpose of this rule. 44 func (r EnumFieldNamesUpperSnakeCaseRule) Purpose() string { 45 return "Verifies that all enum field names are CAPITALS_WITH_UNDERSCORES." 46 } 47 48 // IsOfficial decides whether or not this rule belongs to the official guide. 49 func (r EnumFieldNamesUpperSnakeCaseRule) IsOfficial() bool { 50 return true 51 } 52 53 // Apply applies the rule to the proto. 54 func (r EnumFieldNamesUpperSnakeCaseRule) Apply(proto *parser.Proto) ([]report.Failure, error) { 55 base, err := visitor.NewBaseFixableVisitor(r.ID(), r.fixMode, proto, string(r.Severity())) 56 if err != nil { 57 return nil, err 58 } 59 60 v := &enumFieldNamesUpperSnakeCaseVisitor{ 61 BaseFixableVisitor: base, 62 } 63 return visitor.RunVisitorAutoDisable(v, proto, r.ID(), r.autoDisableType) 64 } 65 66 type enumFieldNamesUpperSnakeCaseVisitor struct { 67 *visitor.BaseFixableVisitor 68 } 69 70 // VisitEnumField checks the enum field. 71 func (v *enumFieldNamesUpperSnakeCaseVisitor) VisitEnumField(field *parser.EnumField) bool { 72 name := field.Ident 73 if !strs.IsUpperSnakeCase(name) { 74 expected := strs.ToUpperSnakeCase(name) 75 v.AddFailuref(field.Meta.Pos, "EnumField name %q must be CAPITALS_WITH_UNDERSCORES like %q", name, expected) 76 77 err := v.Fixer.SearchAndReplace(field.Meta.Pos, func(lex *lexer.Lexer) fixer.TextEdit { 78 lex.Next() 79 return fixer.TextEdit{ 80 Pos: lex.Pos.Offset, 81 End: lex.Pos.Offset + len(lex.Text) - 1, 82 NewText: []byte(expected), 83 } 84 }) 85 if err != nil { 86 panic(err) 87 } 88 } 89 return false 90 }