diff --git a/Makefile b/Makefile index 9e07e48..d05ba97 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,9 @@ clean: ## Delete intermediate build artifacts .PHONY: test test: build ## Run unit tests go test -vet=off -race -cover ./... + @# Also run against the Go Opaque API, which the protoopaque build tag selects + @# for the hybrid-generated Protobuf packages we depend on. + go test -vet=off -race -cover -tags protoopaque ./... .PHONY: build build: generate ## Build all packages diff --git a/check/annotation.go b/check/annotation.go index 26104b0..1a6ac7a 100644 --- a/check/annotation.go +++ b/check/annotation.go @@ -104,12 +104,12 @@ func (a *annotation) toProto() *checkv1.Annotation { if a.againstFileLocation != nil { protoAgainstFileLocation = a.againstFileLocation.ToProto() } - return &checkv1.Annotation{ + return checkv1.Annotation_builder{ RuleId: a.RuleID(), Message: a.Message(), FileLocation: protoFileLocation, AgainstFileLocation: protoAgainstFileLocation, - } + }.Build() } func (*annotation) isAnnotation() {} diff --git a/check/category.go b/check/category.go index 63bc11d..89b1c95 100644 --- a/check/category.go +++ b/check/category.go @@ -111,12 +111,12 @@ func (r *category) toProto() *checkv1.Category { if r == nil { return nil } - return &checkv1.Category{ + return checkv1.Category_builder{ Id: r.id, Purpose: r.purpose, Deprecated: r.deprecated, ReplacementIds: r.replacementIDs, - } + }.Build() } func (*category) isCategory() {} diff --git a/check/check_service_handler.go b/check/check_service_handler.go index ad78e43..e8ccef2 100644 --- a/check/check_service_handler.go +++ b/check/check_service_handler.go @@ -221,10 +221,10 @@ func (c *checkServiceHandler) ListRules(_ context.Context, listRulesRequest *che if err != nil { return nil, err } - listRulesResponse := &checkv1.ListRulesResponse{ + listRulesResponse := checkv1.ListRulesResponse_builder{ NextPageToken: nextPageToken, Rules: xslices.Map(rules, Rule.toProto), - } + }.Build() if err := c.validator.Validate(listRulesResponse); err != nil { return nil, err } @@ -242,10 +242,10 @@ func (c *checkServiceHandler) ListCategories(_ context.Context, listCategoriesRe if err != nil { return nil, err } - listCategoriesResponse := &checkv1.ListCategoriesResponse{ + listCategoriesResponse := checkv1.ListCategoriesResponse_builder{ NextPageToken: nextPageToken, Categories: xslices.Map(categories, Category.toProto), - } + }.Build() if err := c.validator.Validate(listCategoriesResponse); err != nil { return nil, err } diff --git a/check/check_service_handler_test.go b/check/check_service_handler_test.go index 67fc7b4..fa68c10 100644 --- a/check/check_service_handler_test.go +++ b/check/check_service_handler_test.go @@ -39,45 +39,45 @@ func TestCheckServiceHandlerUniqueFiles(t *testing.T) { _, err = checkServiceHandler.Check( t.Context(), - &checkv1.CheckRequest{ + checkv1.CheckRequest_builder{ FileDescriptors: []*descriptorv1.FileDescriptor{ - { + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("foo.proto"), SourceCodeInfo: &descriptorpb.SourceCodeInfo{}, }, - }, + }.Build(), }, AgainstFileDescriptors: []*descriptorv1.FileDescriptor{ - { + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("foo.proto"), SourceCodeInfo: &descriptorpb.SourceCodeInfo{}, }, - }, + }.Build(), }, - }, + }.Build(), ) require.NoError(t, err) _, err = checkServiceHandler.Check( t.Context(), - &checkv1.CheckRequest{ + checkv1.CheckRequest_builder{ FileDescriptors: []*descriptorv1.FileDescriptor{ - { + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("foo.proto"), SourceCodeInfo: &descriptorpb.SourceCodeInfo{}, }, - }, - { + }.Build(), + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("foo.proto"), SourceCodeInfo: &descriptorpb.SourceCodeInfo{}, }, - }, + }.Build(), }, - }, + }.Build(), ) pluginrpcError := &pluginrpc.Error{} require.ErrorAs(t, err, &pluginrpcError) @@ -85,30 +85,30 @@ func TestCheckServiceHandlerUniqueFiles(t *testing.T) { _, err = checkServiceHandler.Check( t.Context(), - &checkv1.CheckRequest{ + checkv1.CheckRequest_builder{ FileDescriptors: []*descriptorv1.FileDescriptor{ - { + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("foo.proto"), SourceCodeInfo: &descriptorpb.SourceCodeInfo{}, }, - }, + }.Build(), }, AgainstFileDescriptors: []*descriptorv1.FileDescriptor{ - { + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("bar.proto"), SourceCodeInfo: &descriptorpb.SourceCodeInfo{}, }, - }, - { + }.Build(), + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("bar.proto"), SourceCodeInfo: &descriptorpb.SourceCodeInfo{}, }, - }, + }.Build(), }, - }, + }.Build(), ) pluginrpcError = &pluginrpc.Error{} require.ErrorAs(t, err, &pluginrpcError) @@ -129,22 +129,22 @@ func TestCheckServiceHandlerNoSourceCodeInfo(t *testing.T) { _, err = checkServiceHandler.Check( t.Context(), - &checkv1.CheckRequest{ + checkv1.CheckRequest_builder{ FileDescriptors: []*descriptorv1.FileDescriptor{ - { + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("foo.proto"), }, - }, + }.Build(), }, AgainstFileDescriptors: []*descriptorv1.FileDescriptor{ - { + descriptorv1.FileDescriptor_builder{ FileDescriptorProto: &descriptorpb.FileDescriptorProto{ Name: proto.String("foo.proto"), }, - }, + }.Build(), }, - }, + }.Build(), ) require.NoError(t, err) } diff --git a/check/checktest/checktest.go b/check/checktest/checktest.go index 6bc1b48..82e0038 100644 --- a/check/checktest/checktest.go +++ b/check/checktest/checktest.go @@ -361,12 +361,12 @@ func compile(ctx context.Context, dirPaths []string, filePaths []string) ([]desc fileDescriptorProto, filePathToUnusedDependencyFilePaths[fileDescriptorProto.GetName()], ) - protoFileDescriptors[i] = &descriptorv1.FileDescriptor{ + protoFileDescriptors[i] = descriptorv1.FileDescriptor_builder{ FileDescriptorProto: fileDescriptorProto, IsImport: !isNotImport, IsSyntaxUnspecified: isSyntaxUnspecified, UnusedDependency: unusedDependencyIndexes, - } + }.Build() } return descriptor.FileDescriptorsForProtoFileDescriptors(protoFileDescriptors) } diff --git a/check/client.go b/check/client.go index 9a83874..704dacc 100644 --- a/check/client.go +++ b/check/client.go @@ -208,10 +208,10 @@ func (c *client) listRulesUncached(ctx context.Context) ([]Rule, error) { for { response, err := checkServiceClient.ListRules( ctx, - &checkv1.ListRulesRequest{ + checkv1.ListRulesRequest_builder{ PageSize: listRulesPageSize, PageToken: pageToken, - }, + }.Build(), ) if err != nil { return nil, err @@ -259,10 +259,10 @@ func (c *client) listCategoriesUncached(ctx context.Context) ([]Category, error) for { response, err := checkServiceClient.ListCategories( ctx, - &checkv1.ListCategoriesRequest{ + checkv1.ListCategoriesRequest_builder{ PageSize: listCategoriesPageSize, PageToken: pageToken, - }, + }.Build(), ) if err != nil { return nil, err diff --git a/check/request.go b/check/request.go index 92ee1f0..afb4727 100644 --- a/check/request.go +++ b/check/request.go @@ -194,11 +194,11 @@ func (r *request) toProtos() ([]*checkv1.CheckRequest, error) { } if len(r.ruleIDs) == 0 { return []*checkv1.CheckRequest{ - { + checkv1.CheckRequest_builder{ FileDescriptors: protoFileDescriptors, AgainstFileDescriptors: protoAgainstFileDescriptors, Options: protoOptions, - }, + }.Build(), }, nil } var checkRequests []*checkv1.CheckRequest @@ -207,12 +207,12 @@ func (r *request) toProtos() ([]*checkv1.CheckRequest, error) { end := min(start+checkRuleIDPageSize, len(r.ruleIDs)) checkRequests = append( checkRequests, - &checkv1.CheckRequest{ + checkv1.CheckRequest_builder{ FileDescriptors: protoFileDescriptors, AgainstFileDescriptors: protoAgainstFileDescriptors, Options: protoOptions, RuleIds: r.ruleIDs[start:end], - }, + }.Build(), ) } return checkRequests, nil diff --git a/check/response.go b/check/response.go index 51b4910..6bbc084 100644 --- a/check/response.go +++ b/check/response.go @@ -51,9 +51,9 @@ func (r *response) Annotations() []Annotation { } func (r *response) toProto() *checkv1.CheckResponse { - return &checkv1.CheckResponse{ + return checkv1.CheckResponse_builder{ Annotations: xslices.Map(r.annotations, Annotation.toProto), - } + }.Build() } func (*response) isResponse() {} diff --git a/check/rule.go b/check/rule.go index 71097f5..8cec3a9 100644 --- a/check/rule.go +++ b/check/rule.go @@ -152,7 +152,7 @@ func (r *rule) toProto() *checkv1.Rule { return nil } protoRuleType := ruleTypeToProtoRuleType[r.ruleType] - return &checkv1.Rule{ + return checkv1.Rule_builder{ Id: r.id, CategoryIds: xslices.Map(r.categories, Category.ID), Default: r.isDefault, @@ -160,7 +160,7 @@ func (r *rule) toProto() *checkv1.Rule { Type: protoRuleType, Deprecated: r.deprecated, ReplacementIds: r.replacementIDs, - } + }.Build() } func (*rule) isRule() {} diff --git a/descriptor/file_descriptor.go b/descriptor/file_descriptor.go index c8e8274..78a3986 100644 --- a/descriptor/file_descriptor.go +++ b/descriptor/file_descriptor.go @@ -179,12 +179,12 @@ func (f *fileDescriptor) ToProto() *descriptorv1.FileDescriptor { if f == nil { return nil } - return &descriptorv1.FileDescriptor{ + return descriptorv1.FileDescriptor_builder{ FileDescriptorProto: f.fileDescriptorProto, IsImport: f.isImport, IsSyntaxUnspecified: f.isSyntaxUnspecified, UnusedDependency: f.unusedDependencyIndexes, - } + }.Build() } func (*fileDescriptor) isFileDescriptor() {} diff --git a/descriptor/file_location.go b/descriptor/file_location.go index 84189eb..39aa1d3 100644 --- a/descriptor/file_location.go +++ b/descriptor/file_location.go @@ -113,10 +113,10 @@ func (l *fileLocation) ToProto() *descriptorv1.FileLocation { if l == nil { return nil } - return &descriptorv1.FileLocation{ + return descriptorv1.FileLocation_builder{ FileName: l.fileDescriptor.ProtoreflectFileDescriptor().Path(), SourcePath: l.sourceLocation.Path, - } + }.Build() } func (l *fileLocation) unclonedSourcePath() protoreflect.SourcePath { diff --git a/info/license.go b/info/license.go index 7c96fb6..f427583 100644 --- a/info/license.go +++ b/info/license.go @@ -101,17 +101,13 @@ func (l *license) toProto() *infov1.License { if l == nil { return nil } - protoLicense := &infov1.License{ + protoLicense := infov1.License_builder{ SpdxLicenseId: l.SPDXLicenseID(), - } + }.Build() if l.text != "" { - protoLicense.Source = &infov1.License_Text{ - Text: l.text, - } + protoLicense.SetText(l.text) } else if l.url != nil { - protoLicense.Source = &infov1.License_Url{ - Url: l.url.String(), - } + protoLicense.SetUrl(l.url.String()) } return protoLicense } diff --git a/info/plugin_info.go b/info/plugin_info.go index bbf8319..840cb20 100644 --- a/info/plugin_info.go +++ b/info/plugin_info.go @@ -95,10 +95,10 @@ func (p *pluginInfo) License() License { } func (p *pluginInfo) toProto() *infov1.PluginInfo { - return &infov1.PluginInfo{ + return infov1.PluginInfo_builder{ Documentation: p.documentation, License: p.license.toProto(), - } + }.Build() } func (*pluginInfo) isPluginInfo() {} diff --git a/info/plugin_info_service_handler.go b/info/plugin_info_service_handler.go index 8e4d53d..ccd0d6f 100644 --- a/info/plugin_info_service_handler.go +++ b/info/plugin_info_service_handler.go @@ -57,9 +57,9 @@ func newPluginInfoServiceHandler(spec *Spec, options ...PluginInfoServiceHandler return nil, err } protoPluginInfo := pluginInfo.toProto() - getPluginInfoResponse := &infov1.GetPluginInfoResponse{ + getPluginInfoResponse := infov1.GetPluginInfoResponse_builder{ PluginInfo: protoPluginInfo, - } + }.Build() validator := opts.validator if validator == nil { validator = protovalidate.GlobalValidator diff --git a/option/options.go b/option/options.go index e1595e9..7e89f2a 100644 --- a/option/options.go +++ b/option/options.go @@ -29,6 +29,7 @@ import ( "reflect" optionv1 "buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go/buf/plugin/option/v1" + "google.golang.org/protobuf/proto" ) // EmptyOptions is an instance of Options with no keys. @@ -254,10 +255,10 @@ func (o *options) ToProto() ([]*optionv1.Option, error) { // Assuming that we've validated that no values are empty. protoOptions = append( protoOptions, - &optionv1.Option{ + optionv1.Option_builder{ Key: key, Value: protoValue, - }, + }.Build(), ) } return protoOptions, nil @@ -269,36 +270,26 @@ func (*options) isOption() {} func valueToProtoValue(value any) (*optionv1.Value, error) { switch reflectValue := reflect.ValueOf(value); reflectValue.Kind() { case reflect.Bool: - return &optionv1.Value{ - Type: &optionv1.Value_BoolValue{ - BoolValue: reflectValue.Bool(), - }, - }, nil + return optionv1.Value_builder{ + BoolValue: proto.Bool(reflectValue.Bool()), + }.Build(), nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return &optionv1.Value{ - Type: &optionv1.Value_Int64Value{ - Int64Value: reflectValue.Int(), - }, - }, nil + return optionv1.Value_builder{ + Int64Value: proto.Int64(reflectValue.Int()), + }.Build(), nil case reflect.Float32, reflect.Float64: - return &optionv1.Value{ - Type: &optionv1.Value_DoubleValue{ - DoubleValue: reflectValue.Float(), - }, - }, nil + return optionv1.Value_builder{ + DoubleValue: proto.Float64(reflectValue.Float()), + }.Build(), nil case reflect.String: - return &optionv1.Value{ - Type: &optionv1.Value_StringValue{ - StringValue: reflectValue.String(), - }, - }, nil + return optionv1.Value_builder{ + StringValue: proto.String(reflectValue.String()), + }.Build(), nil case reflect.Slice: if t, ok := value.([]byte); ok { - return &optionv1.Value{ - Type: &optionv1.Value_BytesValue{ - BytesValue: t, - }, - }, nil + return optionv1.Value_builder{ + BytesValue: t, + }.Build(), nil } values := make([]*optionv1.Value, reflectValue.Len()) for i := range reflectValue.Len() { @@ -308,13 +299,11 @@ func valueToProtoValue(value any) (*optionv1.Value, error) { } values[i] = subValue } - return &optionv1.Value{ - Type: &optionv1.Value_ListValue{ - ListValue: &optionv1.ListValue{ - Values: values, - }, - }, - }, nil + return optionv1.Value_builder{ + ListValue: optionv1.ListValue_builder{ + Values: values, + }.Build(), + }.Build(), nil case reflect.Invalid, reflect.Uintptr, reflect.Complex64, reflect.Complex128, reflect.Array, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer | reflect.Ptr, reflect.Struct, reflect.UnsafePointer: return nil, fmt.Errorf("invalid type for Options value %T", value) default: