diff --git a/go.mod b/go.mod index 335a778f..9af6f1d9 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.22 require ( github.com/bavix/gripmock/protogen v0.0.0 - github.com/goccy/go-yaml v1.11.3 + github.com/goccy/go-yaml v1.12.0 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 github.com/hashicorp/go-memdb v1.3.4 @@ -32,7 +32,7 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -46,9 +46,9 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240708141625-4ad9e859172b // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect + golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index a8af2e6b..d16ecf4e 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= -github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= +github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= +github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -34,8 +34,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 h1:CWyXh/jylQWp2dtiV33mY4iSSp6yf4lmn+c7/tN+ObI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0/go.mod h1:nCLIt0w3Ept2NwF8ThLmrppXsfT07oC8k0XNDxd8sVU= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -146,12 +146,12 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/genproto/googleapis/api v0.0.0-20240708141625-4ad9e859172b h1:y/kpOWeX2pWERnbsvh/hF+Zmo69wVmjyZhstreXQQeA= -google.golang.org/genproto/googleapis/api v0.0.0-20240708141625-4ad9e859172b/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf h1:GillM0Ef0pkZPIB+5iO6SDK+4T9pf6TpaYR6ICD5rVE= +google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:OFMYQFHJ4TM3JRlWDZhJbZfra2uqc3WLBZiaaqP4DtU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/internal/app/rest_server.go b/internal/app/rest_server.go index 16926176..2605e38c 100644 --- a/internal/app/rest_server.go +++ b/internal/app/rest_server.go @@ -34,7 +34,7 @@ type StubsServer struct { ok atomic.Bool } -func NewRestServer(path string) (*StubsServer, error) { +func NewRestServer(path string, strictMode bool) (*StubsServer, error) { stubsStorage, err := storage.New() if err != nil { return nil, err @@ -48,7 +48,7 @@ func NewRestServer(path string) (*StubsServer, error) { } if path != "" { - server.readStubs(path) // TODO: someday you will need to rewrite this code + server.readStubs(path, strictMode) // TODO: someday you will need to rewrite this code } return server, nil @@ -233,7 +233,7 @@ func (h *StubsServer) writeResponseError(err error, w http.ResponseWriter) { } //nolint:cyclop -func (h *StubsServer) readStubs(path string) { +func (h *StubsServer) readStubs(path string, strictMode bool) { files, err := os.ReadDir(path) if err != nil { log.Printf("Can't read stub from %s. %v\n", path, err) @@ -243,7 +243,7 @@ func (h *StubsServer) readStubs(path string) { for _, file := range files { if file.IsDir() { - h.readStubs(path + "/" + file.Name()) + h.readStubs(path+"/"+file.Name(), strictMode) continue } @@ -280,7 +280,7 @@ func (h *StubsServer) readStubs(path string) { continue } - h.stubs.Add(storageStubs...) + h.stubs.AddFromFiles(strictMode, storageStubs...) } } diff --git a/main.go b/main.go index edf00c2f..7a62e5a7 100644 --- a/main.go +++ b/main.go @@ -62,6 +62,9 @@ func main() { outputPointer := flag.String("output", "", "directory to output server.go. Default is $GOPATH/src/grpc/") flag.StringVar(outputPointer, "o", *outputPointer, "alias for -output") + strictMode := false + flag.BoolVar(&strictMode, "strict", false, "enable strict mode") + stubPath := flag.String("stub", "", "Path where the stub files are (Optional)") imports := flag.String("imports", "/protobuf,/googleapis", "comma separated imports path. default path /protobuf,/googleapis is where gripmock Dockerfile install WKT protos") //nolint:lll @@ -114,9 +117,10 @@ func main() { // run admin stub server stub.RunRestServer(ctx, chReady, stub.Options{ - StubPath: *stubPath, - Port: *adminPort, - BindAddr: *adminBindAddr, + StubPath: *stubPath, + Port: *adminPort, + BindAddr: *adminBindAddr, + StrictMode: strictMode, }) importDirs := strings.Split(*imports, ",") diff --git a/pkg/storage/stubs.go b/pkg/storage/stubs.go index db3e539c..50e86ad7 100644 --- a/pkg/storage/stubs.go +++ b/pkg/storage/stubs.go @@ -2,6 +2,8 @@ package storage import ( "errors" + "fmt" + "log" "slices" "sync" "sync/atomic" @@ -14,6 +16,7 @@ import ( var ( ErrServiceNotFound = errors.New("service not found") ErrMethodNotFound = errors.New("method not found") + ErrAlreadyExists = errors.New("already exists") ) type Stub struct { @@ -100,10 +103,11 @@ func (s *storage) CheckHeaders() bool { } type StubStorage struct { - mu sync.Mutex - used map[uuid.UUID]struct{} - db *memdb.MemDB - total int64 + mu sync.Mutex + used map[uuid.UUID]struct{} + loadedFromFiles map[uuid.UUID]struct{} + db *memdb.MemDB + total int64 } func New() (*StubStorage, error) { @@ -112,7 +116,32 @@ func New() (*StubStorage, error) { return nil, err } - return &StubStorage{db: db, used: map[uuid.UUID]struct{}{}}, nil + return &StubStorage{ + db: db, + used: make(map[uuid.UUID]struct{}, 128), + loadedFromFiles: make(map[uuid.UUID]struct{}, 128), + }, nil +} + +func (r *StubStorage) AddFromFiles( + strict bool, + stubs ...*Stub, +) []uuid.UUID { + for _, stub := range stubs { + if _, ok := r.loadedFromFiles[stub.GetID()]; ok { + msg := fmt.Sprintf("[WARN] stub %s already loaded from file", stub.GetID()) + + if strict { + log.Fatalln(msg) + } + + log.Println(msg) + } + + r.loadedFromFiles[stub.GetID()] = struct{}{} + } + + return r.Add(stubs...) } func (r *StubStorage) Add(stubs ...*Stub) []uuid.UUID { diff --git a/protoc-gen-gripmock/go.mod b/protoc-gen-gripmock/go.mod index a313b743..7b05f2c1 100644 --- a/protoc-gen-gripmock/go.mod +++ b/protoc-gen-gripmock/go.mod @@ -21,6 +21,6 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.22.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect google.golang.org/grpc v1.65.0 // indirect ) diff --git a/protoc-gen-gripmock/go.sum b/protoc-gen-gripmock/go.sum index ee7783b7..a3f0bede 100644 --- a/protoc-gen-gripmock/go.sum +++ b/protoc-gen-gripmock/go.sum @@ -35,8 +35,8 @@ golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/protogen/example/ms/ms_grpc.pb.go b/protogen/example/ms/ms_grpc.pb.go index e2775b3b..990b7db0 100644 --- a/protogen/example/ms/ms_grpc.pb.go +++ b/protogen/example/ms/ms_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: ms.proto @@ -15,8 +15,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( MicroService_SayHello_FullMethodName = "/ms.MicroService/SayHello" @@ -49,20 +49,24 @@ func (c *microServiceClient) SayHello(ctx context.Context, in *Request, opts ... // MicroServiceServer is the server API for MicroService service. // All implementations must embed UnimplementedMicroServiceServer -// for forward compatibility +// for forward compatibility. type MicroServiceServer interface { SayHello(context.Context, *Request) (*Reply, error) mustEmbedUnimplementedMicroServiceServer() } -// UnimplementedMicroServiceServer must be embedded to have forward compatible implementations. -type UnimplementedMicroServiceServer struct { -} +// UnimplementedMicroServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedMicroServiceServer struct{} func (UnimplementedMicroServiceServer) SayHello(context.Context, *Request) (*Reply, error) { return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") } func (UnimplementedMicroServiceServer) mustEmbedUnimplementedMicroServiceServer() {} +func (UnimplementedMicroServiceServer) testEmbeddedByValue() {} // UnsafeMicroServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to MicroServiceServer will @@ -72,6 +76,13 @@ type UnsafeMicroServiceServer interface { } func RegisterMicroServiceServer(s grpc.ServiceRegistrar, srv MicroServiceServer) { + // If the following call pancis, it indicates UnimplementedMicroServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&MicroService_ServiceDesc, srv) } diff --git a/protogen/example/multi-files/file1_grpc.pb.go b/protogen/example/multi-files/file1_grpc.pb.go index 709b9ef8..03ace4a7 100644 --- a/protogen/example/multi-files/file1_grpc.pb.go +++ b/protogen/example/multi-files/file1_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: file1.proto @@ -15,8 +15,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Gripmock1_SayHello_FullMethodName = "/multifiles.Gripmock1/SayHello" @@ -52,7 +52,7 @@ func (c *gripmock1Client) SayHello(ctx context.Context, in *Request1, opts ...gr // Gripmock1Server is the server API for Gripmock1 service. // All implementations must embed UnimplementedGripmock1Server -// for forward compatibility +// for forward compatibility. // // The Gripmock service definition. type Gripmock1Server interface { @@ -61,14 +61,18 @@ type Gripmock1Server interface { mustEmbedUnimplementedGripmock1Server() } -// UnimplementedGripmock1Server must be embedded to have forward compatible implementations. -type UnimplementedGripmock1Server struct { -} +// UnimplementedGripmock1Server must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedGripmock1Server struct{} func (UnimplementedGripmock1Server) SayHello(context.Context, *Request1) (*Reply1, error) { return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") } func (UnimplementedGripmock1Server) mustEmbedUnimplementedGripmock1Server() {} +func (UnimplementedGripmock1Server) testEmbeddedByValue() {} // UnsafeGripmock1Server may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to Gripmock1Server will @@ -78,6 +82,13 @@ type UnsafeGripmock1Server interface { } func RegisterGripmock1Server(s grpc.ServiceRegistrar, srv Gripmock1Server) { + // If the following call pancis, it indicates UnimplementedGripmock1Server was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Gripmock1_ServiceDesc, srv) } diff --git a/protogen/example/multi-files/file2_grpc.pb.go b/protogen/example/multi-files/file2_grpc.pb.go index 6eb0f9fa..c221109f 100644 --- a/protogen/example/multi-files/file2_grpc.pb.go +++ b/protogen/example/multi-files/file2_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: file2.proto @@ -15,8 +15,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Gripmock2_SayHello_FullMethodName = "/multifiles.Gripmock2/SayHello" @@ -50,21 +50,25 @@ func (c *gripmock2Client) SayHello(ctx context.Context, in *Request2, opts ...gr // Gripmock2Server is the server API for Gripmock2 service. // All implementations must embed UnimplementedGripmock2Server -// for forward compatibility +// for forward compatibility. type Gripmock2Server interface { // simple unary method SayHello(context.Context, *Request2) (*Reply2, error) mustEmbedUnimplementedGripmock2Server() } -// UnimplementedGripmock2Server must be embedded to have forward compatible implementations. -type UnimplementedGripmock2Server struct { -} +// UnimplementedGripmock2Server must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedGripmock2Server struct{} func (UnimplementedGripmock2Server) SayHello(context.Context, *Request2) (*Reply2, error) { return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") } func (UnimplementedGripmock2Server) mustEmbedUnimplementedGripmock2Server() {} +func (UnimplementedGripmock2Server) testEmbeddedByValue() {} // UnsafeGripmock2Server may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to Gripmock2Server will @@ -74,6 +78,13 @@ type UnsafeGripmock2Server interface { } func RegisterGripmock2Server(s grpc.ServiceRegistrar, srv Gripmock2Server) { + // If the following call pancis, it indicates UnimplementedGripmock2Server was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Gripmock2_ServiceDesc, srv) } diff --git a/protogen/example/multi-package/hello_grpc.pb.go b/protogen/example/multi-package/hello_grpc.pb.go index 55cb1e58..69231763 100644 --- a/protogen/example/multi-package/hello_grpc.pb.go +++ b/protogen/example/multi-package/hello_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: hello.proto @@ -16,8 +16,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Gripmock_Greet_FullMethodName = "/multi_package.Gripmock/Greet" @@ -50,20 +50,24 @@ func (c *gripmockClient) Greet(ctx context.Context, in *bar.Bar, opts ...grpc.Ca // GripmockServer is the server API for Gripmock service. // All implementations must embed UnimplementedGripmockServer -// for forward compatibility +// for forward compatibility. type GripmockServer interface { Greet(context.Context, *bar.Bar) (*Response, error) mustEmbedUnimplementedGripmockServer() } -// UnimplementedGripmockServer must be embedded to have forward compatible implementations. -type UnimplementedGripmockServer struct { -} +// UnimplementedGripmockServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedGripmockServer struct{} func (UnimplementedGripmockServer) Greet(context.Context, *bar.Bar) (*Response, error) { return nil, status.Errorf(codes.Unimplemented, "method Greet not implemented") } func (UnimplementedGripmockServer) mustEmbedUnimplementedGripmockServer() {} +func (UnimplementedGripmockServer) testEmbeddedByValue() {} // UnsafeGripmockServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to GripmockServer will @@ -73,6 +77,13 @@ type UnsafeGripmockServer interface { } func RegisterGripmockServer(s grpc.ServiceRegistrar, srv GripmockServer) { + // If the following call pancis, it indicates UnimplementedGripmockServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Gripmock_ServiceDesc, srv) } diff --git a/protogen/example/one-of/oneof_grpc.pb.go b/protogen/example/one-of/oneof_grpc.pb.go index d419c9a5..6a3fe239 100644 --- a/protogen/example/one-of/oneof_grpc.pb.go +++ b/protogen/example/one-of/oneof_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: oneof.proto @@ -15,8 +15,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Gripmock_SayHello_FullMethodName = "/oneof.Gripmock/SayHello" @@ -52,7 +52,7 @@ func (c *gripmockClient) SayHello(ctx context.Context, in *Request, opts ...grpc // GripmockServer is the server API for Gripmock service. // All implementations must embed UnimplementedGripmockServer -// for forward compatibility +// for forward compatibility. // // The Gripmock service definition. type GripmockServer interface { @@ -61,14 +61,18 @@ type GripmockServer interface { mustEmbedUnimplementedGripmockServer() } -// UnimplementedGripmockServer must be embedded to have forward compatible implementations. -type UnimplementedGripmockServer struct { -} +// UnimplementedGripmockServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedGripmockServer struct{} func (UnimplementedGripmockServer) SayHello(context.Context, *Request) (*Reply, error) { return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") } func (UnimplementedGripmockServer) mustEmbedUnimplementedGripmockServer() {} +func (UnimplementedGripmockServer) testEmbeddedByValue() {} // UnsafeGripmockServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to GripmockServer will @@ -78,6 +82,13 @@ type UnsafeGripmockServer interface { } func RegisterGripmockServer(s grpc.ServiceRegistrar, srv GripmockServer) { + // If the following call pancis, it indicates UnimplementedGripmockServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Gripmock_ServiceDesc, srv) } diff --git a/protogen/example/simple/simple_grpc.pb.go b/protogen/example/simple/simple_grpc.pb.go index 80b33c57..26d2040f 100644 --- a/protogen/example/simple/simple_grpc.pb.go +++ b/protogen/example/simple/simple_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: simple.proto @@ -15,8 +15,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Gripmock_SayHello_FullMethodName = "/simple.Gripmock/SayHello" @@ -52,7 +52,7 @@ func (c *gripmockClient) SayHello(ctx context.Context, in *Request, opts ...grpc // GripmockServer is the server API for Gripmock service. // All implementations must embed UnimplementedGripmockServer -// for forward compatibility +// for forward compatibility. // // The Gripmock service definition. type GripmockServer interface { @@ -61,14 +61,18 @@ type GripmockServer interface { mustEmbedUnimplementedGripmockServer() } -// UnimplementedGripmockServer must be embedded to have forward compatible implementations. -type UnimplementedGripmockServer struct { -} +// UnimplementedGripmockServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedGripmockServer struct{} func (UnimplementedGripmockServer) SayHello(context.Context, *Request) (*Reply, error) { return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") } func (UnimplementedGripmockServer) mustEmbedUnimplementedGripmockServer() {} +func (UnimplementedGripmockServer) testEmbeddedByValue() {} // UnsafeGripmockServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to GripmockServer will @@ -78,6 +82,13 @@ type UnsafeGripmockServer interface { } func RegisterGripmockServer(s grpc.ServiceRegistrar, srv GripmockServer) { + // If the following call pancis, it indicates UnimplementedGripmockServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Gripmock_ServiceDesc, srv) } diff --git a/protogen/example/stream/stream_grpc.pb.go b/protogen/example/stream/stream_grpc.pb.go index 58d65bff..367e9500 100644 --- a/protogen/example/stream/stream_grpc.pb.go +++ b/protogen/example/stream/stream_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: stream.proto @@ -15,8 +15,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Gripmock_ServerStream_FullMethodName = "/stream.Gripmock/serverStream" @@ -31,11 +31,11 @@ const ( // The Gripmock service definition. type GripmockClient interface { // server to client sreaming - ServerStream(ctx context.Context, in *Request, opts ...grpc.CallOption) (Gripmock_ServerStreamClient, error) + ServerStream(ctx context.Context, in *Request, opts ...grpc.CallOption) (grpc.ServerStreamingClient[Reply], error) // client to server streaming - ClientStream(ctx context.Context, opts ...grpc.CallOption) (Gripmock_ClientStreamClient, error) + ClientStream(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[Request, Reply], error) // bidirectional streaming - Bidirectional(ctx context.Context, opts ...grpc.CallOption) (Gripmock_BidirectionalClient, error) + Bidirectional(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[Request, Reply], error) } type gripmockClient struct { @@ -46,13 +46,13 @@ func NewGripmockClient(cc grpc.ClientConnInterface) GripmockClient { return &gripmockClient{cc} } -func (c *gripmockClient) ServerStream(ctx context.Context, in *Request, opts ...grpc.CallOption) (Gripmock_ServerStreamClient, error) { +func (c *gripmockClient) ServerStream(ctx context.Context, in *Request, opts ...grpc.CallOption) (grpc.ServerStreamingClient[Reply], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &Gripmock_ServiceDesc.Streams[0], Gripmock_ServerStream_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &gripmockServerStreamClient{ClientStream: stream} + x := &grpc.GenericClientStream[Request, Reply]{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -62,119 +62,68 @@ func (c *gripmockClient) ServerStream(ctx context.Context, in *Request, opts ... return x, nil } -type Gripmock_ServerStreamClient interface { - Recv() (*Reply, error) - grpc.ClientStream -} - -type gripmockServerStreamClient struct { - grpc.ClientStream -} - -func (x *gripmockServerStreamClient) Recv() (*Reply, error) { - m := new(Reply) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Gripmock_ServerStreamClient = grpc.ServerStreamingClient[Reply] -func (c *gripmockClient) ClientStream(ctx context.Context, opts ...grpc.CallOption) (Gripmock_ClientStreamClient, error) { +func (c *gripmockClient) ClientStream(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[Request, Reply], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &Gripmock_ServiceDesc.Streams[1], Gripmock_ClientStream_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &gripmockClientStreamClient{ClientStream: stream} + x := &grpc.GenericClientStream[Request, Reply]{ClientStream: stream} return x, nil } -type Gripmock_ClientStreamClient interface { - Send(*Request) error - CloseAndRecv() (*Reply, error) - grpc.ClientStream -} - -type gripmockClientStreamClient struct { - grpc.ClientStream -} - -func (x *gripmockClientStreamClient) Send(m *Request) error { - return x.ClientStream.SendMsg(m) -} - -func (x *gripmockClientStreamClient) CloseAndRecv() (*Reply, error) { - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - m := new(Reply) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Gripmock_ClientStreamClient = grpc.ClientStreamingClient[Request, Reply] -func (c *gripmockClient) Bidirectional(ctx context.Context, opts ...grpc.CallOption) (Gripmock_BidirectionalClient, error) { +func (c *gripmockClient) Bidirectional(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[Request, Reply], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &Gripmock_ServiceDesc.Streams[2], Gripmock_Bidirectional_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &gripmockBidirectionalClient{ClientStream: stream} + x := &grpc.GenericClientStream[Request, Reply]{ClientStream: stream} return x, nil } -type Gripmock_BidirectionalClient interface { - Send(*Request) error - Recv() (*Reply, error) - grpc.ClientStream -} - -type gripmockBidirectionalClient struct { - grpc.ClientStream -} - -func (x *gripmockBidirectionalClient) Send(m *Request) error { - return x.ClientStream.SendMsg(m) -} - -func (x *gripmockBidirectionalClient) Recv() (*Reply, error) { - m := new(Reply) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Gripmock_BidirectionalClient = grpc.BidiStreamingClient[Request, Reply] // GripmockServer is the server API for Gripmock service. // All implementations must embed UnimplementedGripmockServer -// for forward compatibility +// for forward compatibility. // // The Gripmock service definition. type GripmockServer interface { // server to client sreaming - ServerStream(*Request, Gripmock_ServerStreamServer) error + ServerStream(*Request, grpc.ServerStreamingServer[Reply]) error // client to server streaming - ClientStream(Gripmock_ClientStreamServer) error + ClientStream(grpc.ClientStreamingServer[Request, Reply]) error // bidirectional streaming - Bidirectional(Gripmock_BidirectionalServer) error + Bidirectional(grpc.BidiStreamingServer[Request, Reply]) error mustEmbedUnimplementedGripmockServer() } -// UnimplementedGripmockServer must be embedded to have forward compatible implementations. -type UnimplementedGripmockServer struct { -} +// UnimplementedGripmockServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedGripmockServer struct{} -func (UnimplementedGripmockServer) ServerStream(*Request, Gripmock_ServerStreamServer) error { +func (UnimplementedGripmockServer) ServerStream(*Request, grpc.ServerStreamingServer[Reply]) error { return status.Errorf(codes.Unimplemented, "method ServerStream not implemented") } -func (UnimplementedGripmockServer) ClientStream(Gripmock_ClientStreamServer) error { +func (UnimplementedGripmockServer) ClientStream(grpc.ClientStreamingServer[Request, Reply]) error { return status.Errorf(codes.Unimplemented, "method ClientStream not implemented") } -func (UnimplementedGripmockServer) Bidirectional(Gripmock_BidirectionalServer) error { +func (UnimplementedGripmockServer) Bidirectional(grpc.BidiStreamingServer[Request, Reply]) error { return status.Errorf(codes.Unimplemented, "method Bidirectional not implemented") } func (UnimplementedGripmockServer) mustEmbedUnimplementedGripmockServer() {} +func (UnimplementedGripmockServer) testEmbeddedByValue() {} // UnsafeGripmockServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to GripmockServer will @@ -184,6 +133,13 @@ type UnsafeGripmockServer interface { } func RegisterGripmockServer(s grpc.ServiceRegistrar, srv GripmockServer) { + // If the following call pancis, it indicates UnimplementedGripmockServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Gripmock_ServiceDesc, srv) } @@ -192,73 +148,25 @@ func _Gripmock_ServerStream_Handler(srv interface{}, stream grpc.ServerStream) e if err := stream.RecvMsg(m); err != nil { return err } - return srv.(GripmockServer).ServerStream(m, &gripmockServerStreamServer{ServerStream: stream}) -} - -type Gripmock_ServerStreamServer interface { - Send(*Reply) error - grpc.ServerStream -} - -type gripmockServerStreamServer struct { - grpc.ServerStream + return srv.(GripmockServer).ServerStream(m, &grpc.GenericServerStream[Request, Reply]{ServerStream: stream}) } -func (x *gripmockServerStreamServer) Send(m *Reply) error { - return x.ServerStream.SendMsg(m) -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Gripmock_ServerStreamServer = grpc.ServerStreamingServer[Reply] func _Gripmock_ClientStream_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(GripmockServer).ClientStream(&gripmockClientStreamServer{ServerStream: stream}) -} - -type Gripmock_ClientStreamServer interface { - SendAndClose(*Reply) error - Recv() (*Request, error) - grpc.ServerStream -} - -type gripmockClientStreamServer struct { - grpc.ServerStream -} - -func (x *gripmockClientStreamServer) SendAndClose(m *Reply) error { - return x.ServerStream.SendMsg(m) + return srv.(GripmockServer).ClientStream(&grpc.GenericServerStream[Request, Reply]{ServerStream: stream}) } -func (x *gripmockClientStreamServer) Recv() (*Request, error) { - m := new(Request) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Gripmock_ClientStreamServer = grpc.ClientStreamingServer[Request, Reply] func _Gripmock_Bidirectional_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(GripmockServer).Bidirectional(&gripmockBidirectionalServer{ServerStream: stream}) -} - -type Gripmock_BidirectionalServer interface { - Send(*Reply) error - Recv() (*Request, error) - grpc.ServerStream -} - -type gripmockBidirectionalServer struct { - grpc.ServerStream -} - -func (x *gripmockBidirectionalServer) Send(m *Reply) error { - return x.ServerStream.SendMsg(m) + return srv.(GripmockServer).Bidirectional(&grpc.GenericServerStream[Request, Reply]{ServerStream: stream}) } -func (x *gripmockBidirectionalServer) Recv() (*Request, error) { - m := new(Request) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Gripmock_BidirectionalServer = grpc.BidiStreamingServer[Request, Reply] // Gripmock_ServiceDesc is the grpc.ServiceDesc for Gripmock service. // It's only intended for direct use with grpc.RegisterService, diff --git a/protogen/example/stub-subfolders/stub-subfolders_grpc.pb.go b/protogen/example/stub-subfolders/stub-subfolders_grpc.pb.go index 04c6d613..224a2c72 100644 --- a/protogen/example/stub-subfolders/stub-subfolders_grpc.pb.go +++ b/protogen/example/stub-subfolders/stub-subfolders_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: stub-subfolders.proto @@ -15,8 +15,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Gripmock_SayHello_FullMethodName = "/stub_subfolders.Gripmock/SayHello" @@ -52,7 +52,7 @@ func (c *gripmockClient) SayHello(ctx context.Context, in *Request, opts ...grpc // GripmockServer is the server API for Gripmock service. // All implementations must embed UnimplementedGripmockServer -// for forward compatibility +// for forward compatibility. // // The Gripmock service definition. type GripmockServer interface { @@ -61,14 +61,18 @@ type GripmockServer interface { mustEmbedUnimplementedGripmockServer() } -// UnimplementedGripmockServer must be embedded to have forward compatible implementations. -type UnimplementedGripmockServer struct { -} +// UnimplementedGripmockServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedGripmockServer struct{} func (UnimplementedGripmockServer) SayHello(context.Context, *Request) (*Reply, error) { return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") } func (UnimplementedGripmockServer) mustEmbedUnimplementedGripmockServer() {} +func (UnimplementedGripmockServer) testEmbeddedByValue() {} // UnsafeGripmockServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to GripmockServer will @@ -78,6 +82,13 @@ type UnsafeGripmockServer interface { } func RegisterGripmockServer(s grpc.ServiceRegistrar, srv GripmockServer) { + // If the following call pancis, it indicates UnimplementedGripmockServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Gripmock_ServiceDesc, srv) } diff --git a/protogen/example/well_known_types/wkt_grpc.pb.go b/protogen/example/well_known_types/wkt_grpc.pb.go index ffe0ccca..70fdec35 100644 --- a/protogen/example/well_known_types/wkt_grpc.pb.go +++ b/protogen/example/well_known_types/wkt_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.5.1 // - protoc v4.24.4 // source: wkt.proto @@ -17,8 +17,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Gripmock_ApiInfo_FullMethodName = "/well_known_types.Gripmock/ApiInfo" @@ -54,7 +54,7 @@ func (c *gripmockClient) ApiInfo(ctx context.Context, in *emptypb.Empty, opts .. // GripmockServer is the server API for Gripmock service. // All implementations must embed UnimplementedGripmockServer -// for forward compatibility +// for forward compatibility. type GripmockServer interface { // this shows us example on using WKT as dependency // api.proto in particular has go_package alias with semicolon @@ -63,14 +63,18 @@ type GripmockServer interface { mustEmbedUnimplementedGripmockServer() } -// UnimplementedGripmockServer must be embedded to have forward compatible implementations. -type UnimplementedGripmockServer struct { -} +// UnimplementedGripmockServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedGripmockServer struct{} func (UnimplementedGripmockServer) ApiInfo(context.Context, *emptypb.Empty) (*apipb.Api, error) { return nil, status.Errorf(codes.Unimplemented, "method ApiInfo not implemented") } func (UnimplementedGripmockServer) mustEmbedUnimplementedGripmockServer() {} +func (UnimplementedGripmockServer) testEmbeddedByValue() {} // UnsafeGripmockServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to GripmockServer will @@ -80,6 +84,13 @@ type UnsafeGripmockServer interface { } func RegisterGripmockServer(s grpc.ServiceRegistrar, srv GripmockServer) { + // If the following call pancis, it indicates UnimplementedGripmockServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Gripmock_ServiceDesc, srv) } diff --git a/protogen/go.mod b/protogen/go.mod index 2c8b5da0..569ec81d 100644 --- a/protogen/go.mod +++ b/protogen/go.mod @@ -5,7 +5,7 @@ go 1.22 require ( go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 - google.golang.org/genproto/googleapis/api v0.0.0-20240708141625-4ad9e859172b + google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 ) @@ -20,5 +20,5 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect ) diff --git a/protogen/go.sum b/protogen/go.sum index 9baeae59..9bce1f8c 100644 --- a/protogen/go.sum +++ b/protogen/go.sum @@ -29,10 +29,10 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240708141625-4ad9e859172b h1:y/kpOWeX2pWERnbsvh/hF+Zmo69wVmjyZhstreXQQeA= -google.golang.org/genproto/googleapis/api v0.0.0-20240708141625-4ad9e859172b/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf h1:GillM0Ef0pkZPIB+5iO6SDK+4T9pf6TpaYR6ICD5rVE= +google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:OFMYQFHJ4TM3JRlWDZhJbZfra2uqc3WLBZiaaqP4DtU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/stub/api_test.go b/stub/api_test.go index b7ac4e02..f3f3c11c 100644 --- a/stub/api_test.go +++ b/stub/api_test.go @@ -20,7 +20,7 @@ func TestStub(t *testing.T) { expect string } - api, _ := app.NewRestServer("") + api, _ := app.NewRestServer("", false) //nolint:lll cases := []test{ diff --git a/stub/stub.go b/stub/stub.go index 8b17f8a9..f20dbb04 100644 --- a/stub/stub.go +++ b/stub/stub.go @@ -17,9 +17,10 @@ import ( ) type Options struct { - Port string - BindAddr string - StubPath string + Port string + BindAddr string + StubPath string + StrictMode bool } func RunRestServer(ctx context.Context, ch chan struct{}, opt Options) { @@ -27,7 +28,7 @@ func RunRestServer(ctx context.Context, ch chan struct{}, opt Options) { addr := net.JoinHostPort(opt.BindAddr, opt.Port) - apiServer, _ := app.NewRestServer(opt.StubPath) + apiServer, _ := app.NewRestServer(opt.StubPath, opt.StrictMode) router := mux.NewRouter() router.Use(muxmiddleware.RequestLogger)