diff --git a/internal/cloudplugin/cloudproto1/cloudproto1_grpc.pb.go b/internal/cloudplugin/cloudproto1/cloudproto1_grpc.pb.go index b43167c8e9..50f174f21e 100644 --- a/internal/cloudplugin/cloudproto1/cloudproto1_grpc.pb.go +++ b/internal/cloudplugin/cloudproto1/cloudproto1_grpc.pb.go @@ -74,20 +74,22 @@ func (x *commandServiceExecuteClient) Recv() (*CommandResponse, error) { } // CommandServiceServer is the server API for CommandService service. -// All implementations should embed UnimplementedCommandServiceServer +// All implementations must embed UnimplementedCommandServiceServer // for forward compatibility type CommandServiceServer interface { // Execute runs a specific command with the provided flags and returns the result. Execute(*CommandRequest, CommandService_ExecuteServer) error + mustEmbedUnimplementedCommandServiceServer() } -// UnimplementedCommandServiceServer should be embedded to have forward compatible implementations. +// UnimplementedCommandServiceServer must be embedded to have forward compatible implementations. type UnimplementedCommandServiceServer struct { } func (UnimplementedCommandServiceServer) Execute(*CommandRequest, CommandService_ExecuteServer) error { return status.Errorf(codes.Unimplemented, "method Execute not implemented") } +func (UnimplementedCommandServiceServer) mustEmbedUnimplementedCommandServiceServer() {} // UnsafeCommandServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to CommandServiceServer will diff --git a/internal/grpcwrap/provider.go b/internal/grpcwrap/provider.go index 02fc2da146..d616d3974c 100644 --- a/internal/grpcwrap/provider.go +++ b/internal/grpcwrap/provider.go @@ -34,6 +34,8 @@ type provider struct { provider providers.Interface schema providers.GetProviderSchemaResponse identitySchemas providers.GetResourceIdentitySchemasResponse + + tfplugin5.UnimplementedProviderServer } func (p *provider) GetMetadata(_ context.Context, req *tfplugin5.GetMetadata_Request) (*tfplugin5.GetMetadata_Response, error) { diff --git a/internal/grpcwrap/provider6.go b/internal/grpcwrap/provider6.go index 96aed94261..106d8cbacb 100644 --- a/internal/grpcwrap/provider6.go +++ b/internal/grpcwrap/provider6.go @@ -35,6 +35,8 @@ type provider6 struct { provider providers.Interface schema providers.GetProviderSchemaResponse identitySchemas providers.GetResourceIdentitySchemasResponse + + tfplugin6.UnimplementedProviderServer } func (p *provider6) GetMetadata(_ context.Context, req *tfplugin6.GetMetadata_Request) (*tfplugin6.GetMetadata_Response, error) { diff --git a/internal/grpcwrap/provisioner.go b/internal/grpcwrap/provisioner.go index f813f99dd8..b84e72bd80 100644 --- a/internal/grpcwrap/provisioner.go +++ b/internal/grpcwrap/provisioner.go @@ -29,6 +29,8 @@ func Provisioner(p provisioners.Interface) tfplugin5.ProvisionerServer { type provisioner struct { provisioner provisioners.Interface schema *configschema.Block + + tfplugin5.UnimplementedProvisionerServer } func (p *provisioner) GetSchema(_ context.Context, req *tfplugin5.GetProvisionerSchema_Request) (*tfplugin5.GetProvisionerSchema_Response, error) { diff --git a/internal/rpcapi/dynrpcserver/dependencies.go b/internal/rpcapi/dynrpcserver/dependencies.go index 0ccdb5490a..5474381ad6 100644 --- a/internal/rpcapi/dynrpcserver/dependencies.go +++ b/internal/rpcapi/dynrpcserver/dependencies.go @@ -14,6 +14,7 @@ import ( type Dependencies struct { impl dependencies.DependenciesServer mu sync.RWMutex + dependencies.UnimplementedDependenciesServer } var _ dependencies.DependenciesServer = (*Dependencies)(nil) diff --git a/internal/rpcapi/dynrpcserver/generator/main.go b/internal/rpcapi/dynrpcserver/generator/main.go index cd01001629..ff98a5072d 100644 --- a/internal/rpcapi/dynrpcserver/generator/main.go +++ b/internal/rpcapi/dynrpcserver/generator/main.go @@ -125,6 +125,11 @@ func main() { fmt.Fprintf(&buf, "type %s struct {\n", baseName) fmt.Fprintf(&buf, "impl %s.%s\n", shortName, ifaceName) fmt.Fprintln(&buf, "mu sync.RWMutex") + + unimplementedServerInterface := fmt.Sprintf("%s.Unimplemented%s", shortName, ifaceName) // UnimplementedFoobarServer struct name that's generated from the proto file. + unimplementedServerMethod := fmt.Sprintf("mustEmbedUnimplemented%s", ifaceName) // Name of the method implemented on UnimplementedFoobarServer. + fmt.Fprintln(&buf, unimplementedServerInterface) // Embed UnimplementedFoobarServer struct into the struct we're generating. + buf.WriteString("}\n\n") fmt.Fprintf(&buf, "var _ %s.%s = (*%s)(nil)\n\n", shortName, ifaceName, baseName) @@ -135,6 +140,13 @@ func main() { for i := 0; i < iface.NumMethods(); i++ { method := iface.Method(i) + + if method.Name() == unimplementedServerMethod { + // Code for this method doesn't need to be generated. + // The method is present via embedding, see use of `unimplementedServerInterface` above. + continue + } + sig := method.Type().(*types.Signature) fmt.Fprintf(&buf, "func (s *%s) %s(", baseName, method.Name()) diff --git a/internal/rpcapi/dynrpcserver/packages.go b/internal/rpcapi/dynrpcserver/packages.go index da3e72fc17..31f4a4f859 100644 --- a/internal/rpcapi/dynrpcserver/packages.go +++ b/internal/rpcapi/dynrpcserver/packages.go @@ -14,6 +14,7 @@ import ( type Packages struct { impl packages.PackagesServer mu sync.RWMutex + packages.UnimplementedPackagesServer } var _ packages.PackagesServer = (*Packages)(nil) diff --git a/internal/rpcapi/dynrpcserver/stacks.go b/internal/rpcapi/dynrpcserver/stacks.go index 08cca1fd3c..c0fc256a74 100644 --- a/internal/rpcapi/dynrpcserver/stacks.go +++ b/internal/rpcapi/dynrpcserver/stacks.go @@ -14,6 +14,7 @@ import ( type Stacks struct { impl stacks.StacksServer mu sync.RWMutex + stacks.UnimplementedStacksServer } var _ stacks.StacksServer = (*Stacks)(nil) diff --git a/internal/rpcapi/terraform1/dependencies/dependencies_grpc.pb.go b/internal/rpcapi/terraform1/dependencies/dependencies_grpc.pb.go index 66969f9903..086e086ce7 100644 --- a/internal/rpcapi/terraform1/dependencies/dependencies_grpc.pb.go +++ b/internal/rpcapi/terraform1/dependencies/dependencies_grpc.pb.go @@ -241,7 +241,7 @@ func (c *dependenciesClient) GetProviderSchema(ctx context.Context, in *GetProvi } // DependenciesServer is the server API for Dependencies service. -// All implementations should embed UnimplementedDependenciesServer +// All implementations must embed UnimplementedDependenciesServer // for forward compatibility type DependenciesServer interface { // Opens a source bundle that was already extracted into the filesystem @@ -303,9 +303,10 @@ type DependenciesServer interface { // has the potential to run in a context that probably has access to // private source code and other sensitive information. GetProviderSchema(context.Context, *GetProviderSchema_Request) (*GetProviderSchema_Response, error) + mustEmbedUnimplementedDependenciesServer() } -// UnimplementedDependenciesServer should be embedded to have forward compatible implementations. +// UnimplementedDependenciesServer must be embedded to have forward compatible implementations. type UnimplementedDependenciesServer struct { } @@ -345,6 +346,7 @@ func (UnimplementedDependenciesServer) GetBuiltInProviders(context.Context, *Get func (UnimplementedDependenciesServer) GetProviderSchema(context.Context, *GetProviderSchema_Request) (*GetProviderSchema_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method GetProviderSchema not implemented") } +func (UnimplementedDependenciesServer) mustEmbedUnimplementedDependenciesServer() {} // UnsafeDependenciesServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to DependenciesServer will diff --git a/internal/rpcapi/terraform1/packages/packages_grpc.pb.go b/internal/rpcapi/terraform1/packages/packages_grpc.pb.go index 0842a384df..963abe748b 100644 --- a/internal/rpcapi/terraform1/packages/packages_grpc.pb.go +++ b/internal/rpcapi/terraform1/packages/packages_grpc.pb.go @@ -94,7 +94,7 @@ func (c *packagesClient) FetchModulePackage(ctx context.Context, in *FetchModule } // PackagesServer is the server API for Packages service. -// All implementations should embed UnimplementedPackagesServer +// All implementations must embed UnimplementedPackagesServer // for forward compatibility type PackagesServer interface { ProviderPackageVersions(context.Context, *ProviderPackageVersions_Request) (*ProviderPackageVersions_Response, error) @@ -102,9 +102,10 @@ type PackagesServer interface { ModulePackageVersions(context.Context, *ModulePackageVersions_Request) (*ModulePackageVersions_Response, error) ModulePackageSourceAddr(context.Context, *ModulePackageSourceAddr_Request) (*ModulePackageSourceAddr_Response, error) FetchModulePackage(context.Context, *FetchModulePackage_Request) (*FetchModulePackage_Response, error) + mustEmbedUnimplementedPackagesServer() } -// UnimplementedPackagesServer should be embedded to have forward compatible implementations. +// UnimplementedPackagesServer must be embedded to have forward compatible implementations. type UnimplementedPackagesServer struct { } @@ -123,6 +124,7 @@ func (UnimplementedPackagesServer) ModulePackageSourceAddr(context.Context, *Mod func (UnimplementedPackagesServer) FetchModulePackage(context.Context, *FetchModulePackage_Request) (*FetchModulePackage_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method FetchModulePackage not implemented") } +func (UnimplementedPackagesServer) mustEmbedUnimplementedPackagesServer() {} // UnsafePackagesServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to PackagesServer will diff --git a/internal/rpcapi/terraform1/setup/setup_grpc.pb.go b/internal/rpcapi/terraform1/setup/setup_grpc.pb.go index e290d6056d..52370f18b6 100644 --- a/internal/rpcapi/terraform1/setup/setup_grpc.pb.go +++ b/internal/rpcapi/terraform1/setup/setup_grpc.pb.go @@ -68,7 +68,7 @@ func (c *setupClient) Stop(ctx context.Context, in *Stop_Request, opts ...grpc.C } // SetupServer is the server API for Setup service. -// All implementations should embed UnimplementedSetupServer +// All implementations must embed UnimplementedSetupServer // for forward compatibility type SetupServer interface { // Clients must call Handshake before any other function of any other @@ -80,9 +80,10 @@ type SetupServer interface { // At any time after handshaking, clients may call Stop to initiate a // graceful shutdown of the server. Stop(context.Context, *Stop_Request) (*Stop_Response, error) + mustEmbedUnimplementedSetupServer() } -// UnimplementedSetupServer should be embedded to have forward compatible implementations. +// UnimplementedSetupServer must be embedded to have forward compatible implementations. type UnimplementedSetupServer struct { } @@ -92,6 +93,7 @@ func (UnimplementedSetupServer) Handshake(context.Context, *Handshake_Request) ( func (UnimplementedSetupServer) Stop(context.Context, *Stop_Request) (*Stop_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method Stop not implemented") } +func (UnimplementedSetupServer) mustEmbedUnimplementedSetupServer() {} // UnsafeSetupServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to SetupServer will diff --git a/internal/rpcapi/terraform1/stacks/stacks_grpc.pb.go b/internal/rpcapi/terraform1/stacks/stacks_grpc.pb.go index 914efcb615..dd07dd4cfd 100644 --- a/internal/rpcapi/terraform1/stacks/stacks_grpc.pb.go +++ b/internal/rpcapi/terraform1/stacks/stacks_grpc.pb.go @@ -363,7 +363,7 @@ func (c *stacksClient) ListResourceIdentities(ctx context.Context, in *ListResou } // StacksServer is the server API for Stacks service. -// All implementations should embed UnimplementedStacksServer +// All implementations must embed UnimplementedStacksServer // for forward compatibility type StacksServer interface { // Load and perform initial static validation of a stack configuration @@ -411,9 +411,10 @@ type StacksServer interface { MigrateTerraformState(*MigrateTerraformState_Request, Stacks_MigrateTerraformStateServer) error // ListResourceIdentities lists the identities of all resources in a stack. ListResourceIdentities(context.Context, *ListResourceIdentities_Request) (*ListResourceIdentities_Response, error) + mustEmbedUnimplementedStacksServer() } -// UnimplementedStacksServer should be embedded to have forward compatible implementations. +// UnimplementedStacksServer must be embedded to have forward compatible implementations. type UnimplementedStacksServer struct { } @@ -465,6 +466,7 @@ func (UnimplementedStacksServer) MigrateTerraformState(*MigrateTerraformState_Re func (UnimplementedStacksServer) ListResourceIdentities(context.Context, *ListResourceIdentities_Request) (*ListResourceIdentities_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method ListResourceIdentities not implemented") } +func (UnimplementedStacksServer) mustEmbedUnimplementedStacksServer() {} // UnsafeStacksServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to StacksServer will diff --git a/internal/stacksplugin/stacksproto1/stacksproto1_grpc.pb.go b/internal/stacksplugin/stacksproto1/stacksproto1_grpc.pb.go index 9996d19e0e..490b9b954e 100644 --- a/internal/stacksplugin/stacksproto1/stacksproto1_grpc.pb.go +++ b/internal/stacksplugin/stacksproto1/stacksproto1_grpc.pb.go @@ -74,20 +74,22 @@ func (x *commandServiceExecuteClient) Recv() (*CommandResponse, error) { } // CommandServiceServer is the server API for CommandService service. -// All implementations should embed UnimplementedCommandServiceServer +// All implementations must embed UnimplementedCommandServiceServer // for forward compatibility type CommandServiceServer interface { // Execute runs a specific command with the provided flags and returns the result. Execute(*CommandRequest, CommandService_ExecuteServer) error + mustEmbedUnimplementedCommandServiceServer() } -// UnimplementedCommandServiceServer should be embedded to have forward compatible implementations. +// UnimplementedCommandServiceServer must be embedded to have forward compatible implementations. type UnimplementedCommandServiceServer struct { } func (UnimplementedCommandServiceServer) Execute(*CommandRequest, CommandService_ExecuteServer) error { return status.Errorf(codes.Unimplemented, "method Execute not implemented") } +func (UnimplementedCommandServiceServer) mustEmbedUnimplementedCommandServiceServer() {} // UnsafeCommandServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to CommandServiceServer will diff --git a/internal/tfplugin5/tfplugin5_grpc.pb.go b/internal/tfplugin5/tfplugin5_grpc.pb.go index d97317fd09..baa8a46b70 100644 --- a/internal/tfplugin5/tfplugin5_grpc.pb.go +++ b/internal/tfplugin5/tfplugin5_grpc.pb.go @@ -430,7 +430,7 @@ func (c *providerClient) Stop(ctx context.Context, in *Stop_Request, opts ...grp } // ProviderServer is the server API for Provider service. -// All implementations should embed UnimplementedProviderServer +// All implementations must embed UnimplementedProviderServer // for forward compatibility type ProviderServer interface { // GetMetadata returns upfront information about server capabilities and @@ -480,9 +480,10 @@ type ProviderServer interface { ValidateActionConfig(context.Context, *ValidateActionConfig_Request) (*ValidateActionConfig_Response, error) // ////// Graceful Shutdown Stop(context.Context, *Stop_Request) (*Stop_Response, error) + mustEmbedUnimplementedProviderServer() } -// UnimplementedProviderServer should be embedded to have forward compatible implementations. +// UnimplementedProviderServer must be embedded to have forward compatible implementations. type UnimplementedProviderServer struct { } @@ -570,6 +571,7 @@ func (UnimplementedProviderServer) ValidateActionConfig(context.Context, *Valida func (UnimplementedProviderServer) Stop(context.Context, *Stop_Request) (*Stop_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method Stop not implemented") } +func (UnimplementedProviderServer) mustEmbedUnimplementedProviderServer() {} // UnsafeProviderServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ProviderServer will @@ -1304,16 +1306,17 @@ func (c *provisionerClient) Stop(ctx context.Context, in *Stop_Request, opts ... } // ProvisionerServer is the server API for Provisioner service. -// All implementations should embed UnimplementedProvisionerServer +// All implementations must embed UnimplementedProvisionerServer // for forward compatibility type ProvisionerServer interface { GetSchema(context.Context, *GetProvisionerSchema_Request) (*GetProvisionerSchema_Response, error) ValidateProvisionerConfig(context.Context, *ValidateProvisionerConfig_Request) (*ValidateProvisionerConfig_Response, error) ProvisionResource(*ProvisionResource_Request, Provisioner_ProvisionResourceServer) error Stop(context.Context, *Stop_Request) (*Stop_Response, error) + mustEmbedUnimplementedProvisionerServer() } -// UnimplementedProvisionerServer should be embedded to have forward compatible implementations. +// UnimplementedProvisionerServer must be embedded to have forward compatible implementations. type UnimplementedProvisionerServer struct { } @@ -1329,6 +1332,7 @@ func (UnimplementedProvisionerServer) ProvisionResource(*ProvisionResource_Reque func (UnimplementedProvisionerServer) Stop(context.Context, *Stop_Request) (*Stop_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method Stop not implemented") } +func (UnimplementedProvisionerServer) mustEmbedUnimplementedProvisionerServer() {} // UnsafeProvisionerServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ProvisionerServer will diff --git a/internal/tfplugin6/tfplugin6_grpc.pb.go b/internal/tfplugin6/tfplugin6_grpc.pb.go index 941434db93..134bb9cd98 100644 --- a/internal/tfplugin6/tfplugin6_grpc.pb.go +++ b/internal/tfplugin6/tfplugin6_grpc.pb.go @@ -574,7 +574,7 @@ func (c *providerClient) StopProvider(ctx context.Context, in *StopProvider_Requ } // ProviderServer is the server API for Provider service. -// All implementations should embed UnimplementedProviderServer +// All implementations must embed UnimplementedProviderServer // for forward compatibility type ProviderServer interface { // GetMetadata returns upfront information about server capabilities and @@ -640,9 +640,10 @@ type ProviderServer interface { ValidateActionConfig(context.Context, *ValidateActionConfig_Request) (*ValidateActionConfig_Response, error) // ////// Graceful Shutdown StopProvider(context.Context, *StopProvider_Request) (*StopProvider_Response, error) + mustEmbedUnimplementedProviderServer() } -// UnimplementedProviderServer should be embedded to have forward compatible implementations. +// UnimplementedProviderServer must be embedded to have forward compatible implementations. type UnimplementedProviderServer struct { } @@ -754,6 +755,7 @@ func (UnimplementedProviderServer) ValidateActionConfig(context.Context, *Valida func (UnimplementedProviderServer) StopProvider(context.Context, *StopProvider_Request) (*StopProvider_Response, error) { return nil, status.Errorf(codes.Unimplemented, "method StopProvider not implemented") } +func (UnimplementedProviderServer) mustEmbedUnimplementedProviderServer() {} // UnsafeProviderServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ProviderServer will diff --git a/tools/protobuf-compile/protobuf-compile.go b/tools/protobuf-compile/protobuf-compile.go index c3e950f8b1..2d954f4ffd 100644 --- a/tools/protobuf-compile/protobuf-compile.go +++ b/tools/protobuf-compile/protobuf-compile.go @@ -51,7 +51,6 @@ var protocSteps = []protocStep{ "--go_opt=paths=source_relative", "--go-grpc_out=.", "--go-grpc_opt=paths=source_relative", - "--go-grpc_opt=require_unimplemented_servers=false", "./tfplugin5.proto", }, }, @@ -63,7 +62,6 @@ var protocSteps = []protocStep{ "--go_opt=paths=source_relative", "--go-grpc_out=.", "--go-grpc_opt=paths=source_relative", - "--go-grpc_opt=require_unimplemented_servers=false", "./tfplugin6.proto", }, }, @@ -77,7 +75,6 @@ var protocSteps = []protocStep{ "--go-grpc_out=.", "--go-grpc_opt=paths=source_relative", "--go-grpc_opt=Mterraform1.proto=github.com/hashicorp/terraform/internal/rpcapi/terraform1", - "--go-grpc_opt=require_unimplemented_servers=false", "./terraform1.proto", }, }, @@ -91,7 +88,6 @@ var protocSteps = []protocStep{ "--go-grpc_out=.", "--go-grpc_opt=paths=source_relative", "--go-grpc_opt=Msetup.proto=github.com/hashicorp/terraform/internal/rpcapi/terraform1/setup", - "--go-grpc_opt=require_unimplemented_servers=false", "./setup.proto", }, }, @@ -107,7 +103,6 @@ var protocSteps = []protocStep{ "--go-grpc_opt=paths=source_relative", "--go-grpc_opt=Mterraform1.proto=github.com/hashicorp/terraform/internal/rpcapi/terraform1", "--go-grpc_opt=Mdependencies.proto=github.com/hashicorp/terraform/internal/rpcapi/terraform1/dependencies", - "--go-grpc_opt=require_unimplemented_servers=false", "-I.", "-I..", "./dependencies.proto", @@ -125,7 +120,6 @@ var protocSteps = []protocStep{ "--go-grpc_opt=paths=source_relative", "--go-grpc_opt=Mterraform1.proto=github.com/hashicorp/terraform/internal/rpcapi/terraform1", "--go-grpc_opt=Mstacks.proto=github.com/hashicorp/terraform/internal/rpcapi/terraform1/stacks", - "--go-grpc_opt=require_unimplemented_servers=false", "-I.", "-I..", "./stacks.proto", @@ -143,7 +137,6 @@ var protocSteps = []protocStep{ "--go-grpc_opt=paths=source_relative", "--go-grpc_opt=Mpackages.proto=github.com/hashicorp/terraform/internal/rpcapi/terraform1/packages", "--go-grpc_opt=Mterraform1.proto=github.com/hashicorp/terraform/internal/rpcapi/terraform1", - "--go-grpc_opt=require_unimplemented_servers=false", "-I.", "-I..", "./packages.proto", @@ -176,7 +169,6 @@ var protocSteps = []protocStep{ "--go_opt=paths=source_relative", "--go-grpc_out=.", "--go-grpc_opt=paths=source_relative", - "--go-grpc_opt=require_unimplemented_servers=false", "cloudproto1.proto", }, }, @@ -188,7 +180,6 @@ var protocSteps = []protocStep{ "--go_opt=paths=source_relative", "--go-grpc_out=.", "--go-grpc_opt=paths=source_relative", - "--go-grpc_opt=require_unimplemented_servers=false", "stacksproto1.proto", }, },