add protogetter linter (#4069)

This commit is contained in:
Vladislav Fursov 2023-10-09 19:30:50 +04:00 committed by GitHub
parent 2d5d29f505
commit 8c178d388c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 732 additions and 0 deletions

View File

@ -2263,6 +2263,7 @@ linters:
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- revive
- rowserrcheck
@ -2378,6 +2379,7 @@ linters:
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- revive
- rowserrcheck

1
go.mod
View File

@ -34,6 +34,7 @@ require (
github.com/fatih/color v1.15.0
github.com/firefart/nonamedreturns v1.0.4
github.com/fzipp/gocyclo v0.6.0
github.com/ghostiam/protogetter v0.2.2
github.com/go-critic/go-critic v0.9.0
github.com/go-xmlfmt/xmlfmt v1.1.2
github.com/gofrs/flock v0.8.1

2
go.sum generated
View File

@ -146,6 +146,8 @@ github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwV
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/ghostiam/protogetter v0.2.2 h1:eWwreOprO2z+4x8eiIFGvA54n2XHoPg01A/XG1rMMKQ=
github.com/ghostiam/protogetter v0.2.2/go.mod h1:KmNLOsy1v04hKbvZs8EfGI1fk39AgTdRDxWNYPfXVc4=
github.com/go-critic/go-critic v0.9.0 h1:Pmys9qvU3pSML/3GEQ2Xd9RZ/ip+aXHKILuxczKGV/U=
github.com/go-critic/go-critic v0.9.0/go.mod h1:5P8tdXL7m/6qnyG6oRAlYLORvoXH0WDypYgAEmagT40=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=

View File

@ -0,0 +1,59 @@
package golinters
import (
"sync"
"github.com/ghostiam/protogetter"
"golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/result"
)
func NewProtoGetter() *goanalysis.Linter {
var mu sync.Mutex
var resIssues []goanalysis.Issue
a := protogetter.NewAnalyzer()
a.Run = func(pass *analysis.Pass) (any, error) {
pgIssues := protogetter.Run(pass, protogetter.GolangciLintMode)
issues := make([]goanalysis.Issue, len(pgIssues))
for i, issue := range pgIssues {
report := &result.Issue{
FromLinter: a.Name,
Pos: issue.Pos,
Text: issue.Message,
Replacement: &result.Replacement{
Inline: &result.InlineFix{
StartCol: issue.InlineFix.StartCol,
Length: issue.InlineFix.Length,
NewString: issue.InlineFix.NewString,
},
},
}
issues[i] = goanalysis.NewIssue(report, pass)
}
if len(issues) == 0 {
return nil, nil
}
mu.Lock()
resIssues = append(resIssues, issues...)
mu.Unlock()
return nil, nil
}
return goanalysis.NewLinter(
a.Name,
a.Doc,
[]*analysis.Analyzer{a},
nil,
).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
return resIssues
}).WithLoadMode(goanalysis.LoadModeTypesInfo)
}

View File

@ -717,6 +717,13 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetStyle).
WithURL("https://github.com/yeya24/promlinter"),
linter.NewConfig(golinters.NewProtoGetter()).
WithSince("v1.55.0").
WithPresets(linter.PresetBugs).
WithLoadForGoAnalysis().
WithAutoFix().
WithURL("https://github.com/ghostiam/protogetter"),
linter.NewConfig(golinters.NewReassign(reassignCfg)).
WithSince("1.49.0").
WithPresets(linter.PresetBugs).

View File

@ -32,6 +32,7 @@ func TestSourcesFromTestdataSubDir(t *testing.T) {
"loggercheck",
"ginkgolinter",
"zerologlint",
"protogetter",
}
for _, dir := range subDirs {

16
test/testdata/protogetter/go.mod vendored Normal file
View File

@ -0,0 +1,16 @@
module protogetter
go 1.19
require (
google.golang.org/grpc v1.57.0
google.golang.org/protobuf v1.31.0
)
require (
github.com/golang/protobuf v1.5.3 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
)

20
test/testdata/protogetter/go.sum generated vendored Normal file
View File

@ -0,0 +1,20 @@
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=

23
test/testdata/protogetter/proto/test.go vendored Normal file
View File

@ -0,0 +1,23 @@
package proto
func (x *Embedded) CustomMethod() interface{} {
return nil
}
type Other struct {
}
func (x *Other) MyMethod(certs *Test) *Embedded {
return nil
}
func (x *Test) Equal(v *Test) bool {
return false
}
func (x *Embedded) SetS(s string) {
x.S = s
}
func (x *Embedded) SetMap(_ map[string]string) {
}

View File

@ -0,0 +1,315 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v4.23.4
// source: test.proto
package proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Test struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
D float64 `protobuf:"fixed64,1,opt,name=d,proto3" json:"d,omitempty"`
F float32 `protobuf:"fixed32,2,opt,name=f,proto3" json:"f,omitempty"`
I32 int32 `protobuf:"varint,3,opt,name=i32,proto3" json:"i32,omitempty"`
I64 int64 `protobuf:"varint,4,opt,name=i64,proto3" json:"i64,omitempty"`
U32 uint32 `protobuf:"varint,5,opt,name=u32,proto3" json:"u32,omitempty"`
U64 uint64 `protobuf:"varint,6,opt,name=u64,proto3" json:"u64,omitempty"`
T bool `protobuf:"varint,7,opt,name=t,proto3" json:"t,omitempty"`
B []byte `protobuf:"bytes,8,opt,name=b,proto3" json:"b,omitempty"`
S string `protobuf:"bytes,9,opt,name=s,proto3" json:"s,omitempty"`
Embedded *Embedded `protobuf:"bytes,10,opt,name=embedded,proto3" json:"embedded,omitempty"`
RepeatedEmbeddeds []*Embedded `protobuf:"bytes,11,rep,name=repeated_embeddeds,json=repeatedEmbeddeds,proto3" json:"repeated_embeddeds,omitempty"`
}
func (x *Test) Reset() {
*x = Test{}
if protoimpl.UnsafeEnabled {
mi := &file_test_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Test) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Test) ProtoMessage() {}
func (x *Test) ProtoReflect() protoreflect.Message {
mi := &file_test_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Test.ProtoReflect.Descriptor instead.
func (*Test) Descriptor() ([]byte, []int) {
return file_test_proto_rawDescGZIP(), []int{0}
}
func (x *Test) GetD() float64 {
if x != nil {
return x.D
}
return 0
}
func (x *Test) GetF() float32 {
if x != nil {
return x.F
}
return 0
}
func (x *Test) GetI32() int32 {
if x != nil {
return x.I32
}
return 0
}
func (x *Test) GetI64() int64 {
if x != nil {
return x.I64
}
return 0
}
func (x *Test) GetU32() uint32 {
if x != nil {
return x.U32
}
return 0
}
func (x *Test) GetU64() uint64 {
if x != nil {
return x.U64
}
return 0
}
func (x *Test) GetT() bool {
if x != nil {
return x.T
}
return false
}
func (x *Test) GetB() []byte {
if x != nil {
return x.B
}
return nil
}
func (x *Test) GetS() string {
if x != nil {
return x.S
}
return ""
}
func (x *Test) GetEmbedded() *Embedded {
if x != nil {
return x.Embedded
}
return nil
}
func (x *Test) GetRepeatedEmbeddeds() []*Embedded {
if x != nil {
return x.RepeatedEmbeddeds
}
return nil
}
type Embedded struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
S string `protobuf:"bytes,1,opt,name=s,proto3" json:"s,omitempty"`
Embedded *Embedded `protobuf:"bytes,2,opt,name=embedded,proto3" json:"embedded,omitempty"`
}
func (x *Embedded) Reset() {
*x = Embedded{}
if protoimpl.UnsafeEnabled {
mi := &file_test_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Embedded) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Embedded) ProtoMessage() {}
func (x *Embedded) ProtoReflect() protoreflect.Message {
mi := &file_test_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Embedded.ProtoReflect.Descriptor instead.
func (*Embedded) Descriptor() ([]byte, []int) {
return file_test_proto_rawDescGZIP(), []int{1}
}
func (x *Embedded) GetS() string {
if x != nil {
return x.S
}
return ""
}
func (x *Embedded) GetEmbedded() *Embedded {
if x != nil {
return x.Embedded
}
return nil
}
var File_test_proto protoreflect.FileDescriptor
var file_test_proto_rawDesc = []byte{
0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf5, 0x01, 0x0a,
0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x0c, 0x0a, 0x01, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01,
0x52, 0x01, 0x64, 0x12, 0x0c, 0x0a, 0x01, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x01,
0x66, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x33, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03,
0x69, 0x33, 0x32, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x36, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
0x52, 0x03, 0x69, 0x36, 0x34, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x33, 0x32, 0x18, 0x05, 0x20, 0x01,
0x28, 0x0d, 0x52, 0x03, 0x75, 0x33, 0x32, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x36, 0x34, 0x18, 0x06,
0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x75, 0x36, 0x34, 0x12, 0x0c, 0x0a, 0x01, 0x74, 0x18, 0x07,
0x20, 0x01, 0x28, 0x08, 0x52, 0x01, 0x74, 0x12, 0x0c, 0x0a, 0x01, 0x62, 0x18, 0x08, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x01, 0x62, 0x12, 0x0c, 0x0a, 0x01, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09,
0x52, 0x01, 0x73, 0x12, 0x25, 0x0a, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x18,
0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64,
0x52, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x12, 0x72, 0x65,
0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x73,
0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65,
0x64, 0x52, 0x11, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6d, 0x62, 0x65, 0x64,
0x64, 0x65, 0x64, 0x73, 0x22, 0x3f, 0x0a, 0x08, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64,
0x12, 0x0c, 0x0a, 0x01, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x73, 0x12, 0x25,
0x0a, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x09, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x52, 0x08, 0x65, 0x6d, 0x62,
0x65, 0x64, 0x64, 0x65, 0x64, 0x32, 0x1f, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67,
0x12, 0x14, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, 0x05, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x1a,
0x05, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x68, 0x6f, 0x73, 0x74, 0x69, 0x61, 0x6d, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x67, 0x65, 0x74, 0x74, 0x65, 0x72, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61,
0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_test_proto_rawDescOnce sync.Once
file_test_proto_rawDescData = file_test_proto_rawDesc
)
func file_test_proto_rawDescGZIP() []byte {
file_test_proto_rawDescOnce.Do(func() {
file_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_proto_rawDescData)
})
return file_test_proto_rawDescData
}
var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_test_proto_goTypes = []interface{}{
(*Test)(nil), // 0: Test
(*Embedded)(nil), // 1: Embedded
}
var file_test_proto_depIdxs = []int32{
1, // 0: Test.embedded:type_name -> Embedded
1, // 1: Test.repeated_embeddeds:type_name -> Embedded
1, // 2: Embedded.embedded:type_name -> Embedded
0, // 3: Testing.call:input_type -> Test
0, // 4: Testing.call:output_type -> Test
4, // [4:5] is the sub-list for method output_type
3, // [3:4] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_test_proto_init() }
func file_test_proto_init() {
if File_test_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Test); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Embedded); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_test_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_test_proto_goTypes,
DependencyIndexes: file_test_proto_depIdxs,
MessageInfos: file_test_proto_msgTypes,
}.Build()
File_test_proto = out.File
file_test_proto_rawDesc = nil
file_test_proto_goTypes = nil
file_test_proto_depIdxs = nil
}

View File

@ -0,0 +1,26 @@
syntax = "proto3";
option go_package = "github.com/ghostiam/protogetter/testdata/proto";
message Test {
double d = 1;
float f = 2;
int32 i32 = 3;
int64 i64 = 4;
uint32 u32 = 5;
uint64 u64 = 6;
bool t = 7;
bytes b = 8;
string s = 9;
Embedded embedded = 10;
repeated Embedded repeated_embeddeds = 11;
}
message Embedded {
string s = 1;
Embedded embedded = 2;
}
service Testing {
rpc call(Test) returns (Test);
}

View File

@ -0,0 +1,109 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v4.23.4
// source: test.proto
package proto
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
Testing_Call_FullMethodName = "/Testing/call"
)
// TestingClient is the client API for Testing service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type TestingClient interface {
Call(ctx context.Context, in *Test, opts ...grpc.CallOption) (*Test, error)
}
type testingClient struct {
cc grpc.ClientConnInterface
}
func NewTestingClient(cc grpc.ClientConnInterface) TestingClient {
return &testingClient{cc}
}
func (c *testingClient) Call(ctx context.Context, in *Test, opts ...grpc.CallOption) (*Test, error) {
out := new(Test)
err := c.cc.Invoke(ctx, Testing_Call_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// TestingServer is the server API for Testing service.
// All implementations must embed UnimplementedTestingServer
// for forward compatibility
type TestingServer interface {
Call(context.Context, *Test) (*Test, error)
mustEmbedUnimplementedTestingServer()
}
// UnimplementedTestingServer must be embedded to have forward compatible implementations.
type UnimplementedTestingServer struct {
}
func (UnimplementedTestingServer) Call(context.Context, *Test) (*Test, error) {
return nil, status.Errorf(codes.Unimplemented, "method Call not implemented")
}
func (UnimplementedTestingServer) mustEmbedUnimplementedTestingServer() {}
// UnsafeTestingServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to TestingServer will
// result in compilation errors.
type UnsafeTestingServer interface {
mustEmbedUnimplementedTestingServer()
}
func RegisterTestingServer(s grpc.ServiceRegistrar, srv TestingServer) {
s.RegisterService(&Testing_ServiceDesc, srv)
}
func _Testing_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Test)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TestingServer).Call(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Testing_Call_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TestingServer).Call(ctx, req.(*Test))
}
return interceptor(ctx, in, info, handler)
}
// Testing_ServiceDesc is the grpc.ServiceDesc for Testing service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Testing_ServiceDesc = grpc.ServiceDesc{
ServiceName: "Testing",
HandlerType: (*TestingServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "call",
Handler: _Testing_Call_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "test.proto",
}

151
test/testdata/protogetter/protogetter.go vendored Normal file
View File

@ -0,0 +1,151 @@
//golangcitest:args -Eprotogetter
package protogetter
import (
"fmt"
"protogetter/proto"
)
type Test struct {
Embedded *proto.Embedded
}
func testInvalid(t *proto.Test) {
func(...interface{}) {}(t.B, t.D) // want `avoid direct access to proto field t\.B, use t\.GetB\(\) instead`
func(...interface{}) {}(t.GetB(), t.D) // want `avoid direct access to proto field t\.D, use t\.GetD\(\) instead`
func(...interface{}) {}(t.B, t.GetD()) // want `avoid direct access to proto field t\.B, use t\.GetB\(\) instead`
_ = t.D // want `avoid direct access to proto field t\.D, use t\.GetD\(\) instead`
_ = t.F // want `avoid direct access to proto field t\.F, use t\.GetF\(\) instead`
_ = t.I32 // want `avoid direct access to proto field t\.I32, use t\.GetI32\(\) instead`
_ = t.I64 // want `avoid direct access to proto field t\.I64, use t\.GetI64\(\) instead`
_ = t.U32 // want `avoid direct access to proto field t\.U32, use t\.GetU32\(\) instead`
_ = t.U64 // want `avoid direct access to proto field t\.U64, use t\.GetU64\(\) instead`
_ = t.T // want `avoid direct access to proto field t\.T, use t\.GetT\(\) instead`
_ = t.B // want `avoid direct access to proto field t\.B, use t\.GetB\(\) instead`
_ = t.S // want `avoid direct access to proto field t\.S, use t\.GetS\(\) instead`
_ = t.Embedded // want `avoid direct access to proto field t\.Embedded, use t\.GetEmbedded\(\) instead`
_ = t.Embedded.S // want `avoid direct access to proto field t\.Embedded\.S, use t\.GetEmbedded\(\)\.GetS\(\) instead`
_ = t.GetEmbedded().S // want `avoid direct access to proto field t\.GetEmbedded\(\)\.S, use t\.GetEmbedded\(\)\.GetS\(\) instead`
_ = t.Embedded.Embedded // want `avoid direct access to proto field t\.Embedded\.Embedded, use t\.GetEmbedded\(\)\.GetEmbedded\(\) instead`
_ = t.GetEmbedded().Embedded // want `avoid direct access to proto field t\.GetEmbedded\(\)\.Embedded, use t\.GetEmbedded\(\)\.GetEmbedded\(\) instead`
_ = t.Embedded.Embedded.S // want `avoid direct access to proto field t\.Embedded\.Embedded\.S, use t\.GetEmbedded\(\)\.GetEmbedded\(\).GetS\(\) instead`
_ = t.GetEmbedded().GetEmbedded().S // want `avoid direct access to proto field t\.GetEmbedded\(\)\.GetEmbedded\(\)\.S, use t\.GetEmbedded\(\)\.GetEmbedded\(\)\.GetS\(\) instead`
_ = t.RepeatedEmbeddeds // want `avoid direct access to proto field t\.RepeatedEmbeddeds, use t\.GetRepeatedEmbeddeds\(\) instead`
_ = t.RepeatedEmbeddeds[0] // want `avoid direct access to proto field t\.RepeatedEmbeddeds, use t\.GetRepeatedEmbeddeds\(\) instead`
_ = t.RepeatedEmbeddeds[0].S // want `avoid direct access to proto field t\.RepeatedEmbeddeds\[0\]\.S, use t\.GetRepeatedEmbeddeds\(\)\[0\]\.GetS\(\) instead`
_ = t.GetRepeatedEmbeddeds()[0].S // want `avoid direct access to proto field t\.GetRepeatedEmbeddeds\(\)\[0\]\.S, use t\.GetRepeatedEmbeddeds\(\)\[0\]\.GetS\(\) instead`
_ = t.RepeatedEmbeddeds[0].Embedded // want `avoid direct access to proto field t\.RepeatedEmbeddeds\[0\]\.Embedded, use t\.GetRepeatedEmbeddeds\(\)\[0\]\.GetEmbedded\(\) instead`
_ = t.GetRepeatedEmbeddeds()[0].Embedded // want `avoid direct access to proto field t\.GetRepeatedEmbeddeds\(\)\[0\]\.Embedded, use t\.GetRepeatedEmbeddeds\(\)\[0\]\.GetEmbedded\(\) instead`
_ = t.RepeatedEmbeddeds[0].Embedded.S // want `avoid direct access to proto field t\.RepeatedEmbeddeds\[0\]\.Embedded\.S, use t\.GetRepeatedEmbeddeds\(\)\[0\].GetEmbedded\(\).GetS\(\) instead`
_ = t.GetRepeatedEmbeddeds()[0].GetEmbedded().S // want `avoid direct access to proto field t\.GetRepeatedEmbeddeds\(\)\[0\].GetEmbedded\(\).S, use t\.GetRepeatedEmbeddeds\(\)\[0\].GetEmbedded\(\).GetS\(\) instead`
_ = t.RepeatedEmbeddeds[t.I64].Embedded.S // want `avoid direct access to proto field t\.RepeatedEmbeddeds\[t.I64\]\.Embedded\.S, use t\.GetRepeatedEmbeddeds\(\)\[t\.GetI64\(\)\].GetEmbedded\(\).GetS\(\) instead`
_ = t.GetRepeatedEmbeddeds()[t.I64].GetEmbedded().S // want `avoid direct access to proto field t\.GetRepeatedEmbeddeds\(\)\[t\.I64\]\.GetEmbedded\(\)\.S, use t\.GetRepeatedEmbeddeds\(\)\[t\.GetI64\(\)\]\.GetEmbedded\(\).GetS\(\) instead`
var many []*proto.Test
manyIndex := 42
_ = many[0].T // want `avoid direct access to proto field many\[0\]\.T, use many\[0\]\.GetT\(\) instead`
_ = many[1].Embedded.S // want `avoid direct access to proto field many\[1\]\.Embedded\.S, use many\[1\]\.GetEmbedded\(\)\.GetS\(\) instead`
_ = many[2].GetEmbedded().S // want `avoid direct access to proto field many\[2\]\.GetEmbedded\(\)\.S, use many\[2\].GetEmbedded\(\)\.GetS\(\) instead`
_ = many[3].Embedded.Embedded.S // want `avoid direct access to proto field many\[3\]\.Embedded\.Embedded\.S, use many\[3\].GetEmbedded\(\)\.GetEmbedded\(\)\.GetS\(\) instead`
_ = many[manyIndex].S // want `avoid direct access to proto field many\[manyIndex\]\.S, use many\[manyIndex\]\.GetS\(\) instead`
test := many[0].Embedded.S == "" || t.Embedded.CustomMethod() == nil || t.S == "" || t.Embedded == nil // want `avoid direct access to proto field many\[0\]\.Embedded\.S, use many\[0\]\.GetEmbedded\(\).GetS\(\) instead`
_ = test
other := proto.Other{}
_ = other.MyMethod(nil).S // want `avoid direct access to proto field other\.MyMethod\(nil\)\.S, use other\.MyMethod\(nil\)\.GetS\(\) instead`
ems := t.RepeatedEmbeddeds // want `avoid direct access to proto field t\.RepeatedEmbeddeds, use t\.GetRepeatedEmbeddeds\(\) instead`
_ = ems[len(ems)-1].S // want `avoid direct access to proto field ems\[len\(ems\)-1\]\.S, use ems\[len\(ems\)-1\]\.GetS\(\) instead`
ch := make(chan string)
ch <- t.S // want `avoid direct access to proto field t\.S, use t\.GetS\(\) instead`
for _, v := range t.RepeatedEmbeddeds { // want `avoid direct access to proto field t\.RepeatedEmbeddeds, use t\.GetRepeatedEmbeddeds\(\) instead`
_ = v
}
fn := func(...interface{}) bool { return false }
fn((*proto.Test)(nil).S) // want `avoid direct access to proto field \(\*proto\.Test\)\(nil\)\.S, use \(\*proto\.Test\)\(nil\)\.GetS\(\) instead`
var ptrs *[]proto.Test
_ = (*ptrs)[42].RepeatedEmbeddeds // want `avoid direct access to proto field \(\*ptrs\)\[42\]\.RepeatedEmbeddeds, use \(\*ptrs\)\[42\].GetRepeatedEmbeddeds\(\) instead`
_ = (*ptrs)[t.I64].RepeatedEmbeddeds // want `avoid direct access to proto field \(\*ptrs\)\[t\.I64\]\.RepeatedEmbeddeds, use \(\*ptrs\)\[t\.GetI64\(\)\].GetRepeatedEmbeddeds\(\) instead`
var anyType interface{}
_ = anyType.(*proto.Test).S // want `avoid direct access to proto field anyType\.\(\*proto\.Test\)\.S, use anyType\.\(\*proto\.Test\)\.GetS\(\) instead`
t.Embedded.SetS("test") // want `avoid direct access to proto field t\.Embedded\.SetS\("test"\), use t\.GetEmbedded\(\)\.SetS\("test"\) instead`
t.Embedded.SetMap(map[string]string{"test": "test"}) // want `avoid direct access to proto field t\.Embedded\.SetMap\(map\[string\]string{"test": "test"}\), use t\.GetEmbedded\(\)\.SetMap\(map\[string\]string{"test": "test"}\) instead`
}
func testValid(t *proto.Test) {
func(...interface{}) {}(t.GetB(), t.GetD())
func(...interface{}) {}(&t.B, &t.D)
_, t.T = true, true
_, t.T, _ = true, true, false
_, _, t.T = true, true, false
t.T, _ = true, true
t.D = 2
t.I32++
t.I32 += 2
fmt.Scanf("Test", &t.S, &t.B, &t.T)
t.D = 1.0
t.F = 1.0
t.I32 = 1
t.I64 = 1
t.U32 = 1
t.U64 = 1
t.T = true
t.B = []byte{1}
t.S = "1"
t.Embedded = &proto.Embedded{}
t.Embedded.S = "1"
t.GetEmbedded().S = "1"
t.Embedded.Embedded = &proto.Embedded{}
t.GetEmbedded().Embedded = &proto.Embedded{}
t.Embedded.Embedded.S = "1"
t.GetEmbedded().GetEmbedded().S = "1"
t.RepeatedEmbeddeds = []*proto.Embedded{{S: "1"}}
_ = t.GetD()
_ = t.GetF()
_ = t.GetI32()
_ = t.GetI64()
_ = t.GetU32()
_ = t.GetU64()
_ = t.GetT()
_ = t.GetB()
_ = t.GetS()
_ = t.GetEmbedded()
_ = t.GetEmbedded().GetS()
_ = t.GetEmbedded().GetEmbedded()
_ = t.GetEmbedded().GetEmbedded().GetS()
_ = t.GetRepeatedEmbeddeds()
_ = t.GetRepeatedEmbeddeds()[0]
_ = t.GetRepeatedEmbeddeds()[0].GetS()
_ = t.GetRepeatedEmbeddeds()[0].GetEmbedded()
_ = t.GetRepeatedEmbeddeds()[0].GetEmbedded().GetS()
other := proto.Other{}
other.MyMethod(nil).CustomMethod()
other.MyMethod(nil).GetS()
var tt Test
_ = tt.Embedded.GetS()
_ = tt.Embedded.GetEmbedded().GetS()
ems := t.GetRepeatedEmbeddeds()
_ = ems[len(ems)-1].GetS()
ch := make(chan string)
ch <- t.GetS()
t.Equal(&proto.Test{S: "test", I64: 42})
}