Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hard code dependency resolution bindings for @go_googleapis and WKTs #251

Merged
merged 1 commit into from
Jul 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions internal/config/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,6 @@ const (
// "compilers" attribute of go_proto_library rules.
GrpcCompilerLabel = "@io_bazel_rules_go//proto:go_grpc"

// WellKnownTypesProtoRepo is the repository containing proto_library rules
// for the Well Known Types.
WellKnownTypesProtoRepo = "com_google_protobuf"
// WellKnownTypeProtoPrefix is the proto import path prefix for the
// Well Known Types.
WellKnownTypesProtoPrefix = "google/protobuf"
// WellKnownTypesGoPrefix is the import path for the Go repository containing
// pre-generated code for the Well Known Types.
WellKnownTypesGoPrefix = "github.com/golang/protobuf"
// WellKnownTypesPkg is the package name for the predefined WKTs in rules_go.
WellKnownTypesPkg = "proto/wkt"

// GazelleImportsKey is an internal attribute that lists imported packages
// on generated rules. It is replaced with "deps" during import resolution.
GazelleImportsKey = "_gazelle_imports"
Expand Down
18 changes: 18 additions & 0 deletions internal/language/go/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ genrule(
tools = ["//internal/language/go/gen_std_package_list"],
)

genrule(
name = "known_proto_imports",
srcs = ["//internal/language/proto:proto.csv"],
outs = ["known_proto_imports.go"],
cmd = "$(location //internal/language/proto/gen:gen_known_imports) -proto_csv $< -known_imports $@ -package golang -var knownProtoImports -key 0 -value 3",
tools = ["//internal/language/proto/gen:gen_known_imports"],
)

genrule(
name = "known_go_imports",
srcs = ["//internal/language/proto:proto.csv"],
outs = ["known_go_imports.go"],
cmd = "$(location //internal/language/proto/gen:gen_known_imports) -proto_csv $< -known_imports $@ -package golang -var knownGoProtoImports -key 2 -value 3",
tools = ["//internal/language/proto/gen:gen_known_imports"],
)

go_library(
name = "go_default_library",
srcs = [
Expand All @@ -24,6 +40,8 @@ go_library(
"fix.go",
"generate.go",
"kinds.go",
"known_go_imports.go",
"known_proto_imports.go",
"lang.go",
"package.go",
"resolve.go",
Expand Down
136 changes: 136 additions & 0 deletions internal/language/go/known_go_imports.go

Large diffs are not rendered by default.

300 changes: 300 additions & 0 deletions internal/language/go/known_proto_imports.go

Large diffs are not rendered by default.

87 changes: 25 additions & 62 deletions internal/language/go/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func resolveGo(gc *goConfig, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *ru
return label.NoLabel, skipImportError
}

if l := resolveWellKnownGo(imp); !l.Equal(label.NoLabel) {
if l, ok := knownGoProtoImports[imp]; ok {
return l, nil
}

Expand All @@ -140,42 +140,6 @@ func isStandard(imp string) bool {
return stdPackages[imp]
}

func resolveWellKnownGo(imp string) label.Label {
// keep in sync with @io_bazel_rules_go//proto/wkt:well_known_types.bzl
// TODO(jayconrod): in well_known_types.bzl, write the import paths and
// targets in a public dict. Import it here, and use it to generate this code.
switch imp {
case "github.com/golang/protobuf/ptypes/any",
"github.com/golang/protobuf/ptypes/api",
"github.com/golang/protobuf/protoc-gen-go/descriptor",
"github.com/golang/protobuf/ptypes/duration",
"github.com/golang/protobuf/ptypes/empty",
"google.golang.org/genproto/protobuf/field_mask",
"google.golang.org/genproto/protobuf/source_context",
"github.com/golang/protobuf/ptypes/struct",
"github.com/golang/protobuf/ptypes/timestamp",
"github.com/golang/protobuf/ptypes/wrappers":
return label.Label{
Repo: config.RulesGoRepoName,
Pkg: config.WellKnownTypesPkg,
Name: path.Base(imp) + "_go_proto",
}
case "github.com/golang/protobuf/protoc-gen-go/plugin":
return label.Label{
Repo: config.RulesGoRepoName,
Pkg: config.WellKnownTypesPkg,
Name: "compiler_plugin_go_proto",
}
case "google.golang.org/genproto/protobuf/ptype":
return label.Label{
Repo: config.RulesGoRepoName,
Pkg: config.WellKnownTypesPkg,
Name: "type_go_proto",
}
}
return label.NoLabel
}

func resolveWithIndexGo(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
matches := ix.FindRulesByImport(resolve.ImportSpec{Lang: "go", Imp: imp}, "go")
var bestMatch resolve.FindResult
Expand Down Expand Up @@ -248,13 +212,16 @@ func resolveVendored(rc *repos.RemoteCache, imp string) (label.Label, error) {
}

func resolveProto(gc *goConfig, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
if !strings.HasSuffix(imp, ".proto") {
return label.NoLabel, fmt.Errorf("can't import non-proto: %q", imp)
if wellKnownProtos[imp] {
return label.NoLabel, skipImportError
}
stem := imp[:len(imp)-len(".proto")]

if isWellKnownProto(stem) {
return label.NoLabel, skipImportError
if l, ok := knownProtoImports[imp]; ok {
if l.Equal(from) {
return label.NoLabel, skipImportError
} else {
return l, nil
}
}

if l, err := resolveWithIndexProto(ix, imp, from); err == nil || err == skipImportError {
Expand Down Expand Up @@ -282,22 +249,18 @@ func resolveProto(gc *goConfig, ix *resolve.RuleIndex, rc *repos.RemoteCache, r
// TODO(jayconrod): generate from
// @io_bazel_rules_go//proto/wkt:WELL_KNOWN_TYPE_PACKAGES
var wellKnownProtos = map[string]bool{
"google/protobuf/any": true,
"google/protobuf/api": true,
"google/protobuf/compiler_plugin": true,
"google/protobuf/descriptor": true,
"google/protobuf/duration": true,
"google/protobuf/empty": true,
"google/protobuf/field_mask": true,
"google/protobuf/source_context": true,
"google/protobuf/struct": true,
"google/protobuf/timestamp": true,
"google/protobuf/type": true,
"google/protobuf/wrappers": true,
}

func isWellKnownProto(stem string) bool {
return wellKnownProtos[stem]
"google/protobuf/any.proto": true,
"google/protobuf/api.proto": true,
"google/protobuf/compiler_plugin.proto": true,
"google/protobuf/descriptor.proto": true,
"google/protobuf/duration.proto": true,
"google/protobuf/empty.proto": true,
"google/protobuf/field_mask.proto": true,
"google/protobuf/source_context.proto": true,
"google/protobuf/struct.proto": true,
"google/protobuf/timestamp.proto": true,
"google/protobuf/type.proto": true,
"google/protobuf/wrappers.proto": true,
}

func resolveWithIndexProto(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
Expand All @@ -308,10 +271,10 @@ func resolveWithIndexProto(ix *resolve.RuleIndex, imp string, from label.Label)
if len(matches) > 1 {
return label.NoLabel, fmt.Errorf("multiple rules (%s and %s) may be imported with %q from %s", matches[0].Label, matches[1].Label, imp, from)
}
// If some go_library embeds the go_proto_library we found, use that instead.
importpath := matches[0].Rule.AttrString("importpath")
if l, err := resolveWithIndexGo(ix, importpath, from); err == nil {
return l, nil
// TODO(#247): this check is not sufficient. We should check whether the
// match embeds this library (possibly transitively).
if from.Equal(matches[0].Label) {
return label.NoLabel, skipImportError
}
return matches[0].Label, nil
}
Expand Down
53 changes: 51 additions & 2 deletions internal/language/go/resolve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,14 +568,17 @@ go_proto_library(
"google/protobuf/timestamp.proto",
"google/protobuf/type.proto",
"google/protobuf/wrappers.proto",
"google/api/http.proto",
"google/rpc/status.proto",
"google/type/latlng.proto",
],
)

go_library(
name = "wkts_go_lib",
_imports = [
"github.com/golang/protobuf/ptypes/any",
"github.com/golang/protobuf/ptypes/api",
"google.golang.org/genproto/protobuf/api",
"github.com/golang/protobuf/protoc-gen-go/descriptor",
"github.com/golang/protobuf/ptypes/duration",
"github.com/golang/protobuf/ptypes/empty",
Expand All @@ -586,15 +589,28 @@ go_library(
"github.com/golang/protobuf/ptypes/wrappers",
"github.com/golang/protobuf/protoc-gen-go/plugin",
"google.golang.org/genproto/protobuf/ptype",
"google.golang.org/genproto/googleapis/api/annotations",
"google.golang.org/genproto/googleapis/rpc/status",
"google.golang.org/genproto/googleapis/type/latlng",
],
)
`},
want: `
go_proto_library(name = "wkts_go_proto")
go_proto_library(
name = "wkts_go_proto",
deps = [
"@go_googleapis//google/api:annotations_go_proto",
"@go_googleapis//google/rpc:status_go_proto",
"@go_googleapis//google/type:latlng_go_proto",
],
)

go_library(
name = "wkts_go_lib",
deps = [
"@go_googleapis//google/api:annotations_go_proto",
"@go_googleapis//google/rpc:status_go_proto",
"@go_googleapis//google/type:latlng_go_proto",
"@io_bazel_rules_go//proto/wkt:any_go_proto",
"@io_bazel_rules_go//proto/wkt:api_go_proto",
"@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
Expand All @@ -609,6 +625,39 @@ go_library(
"@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
],
)
`,
}, {
desc: "proto_self_import",
old: buildFile{content: `
proto_library(
name = "foo_proto",
srcs = [
"a.proto",
"b.proto",
],
)

go_proto_library(
name = "foo_go_proto",
importpath = "foo",
proto = ":foo_proto",
_imports = ["a.proto"],
)
`},
want: `
proto_library(
name = "foo_proto",
srcs = [
"a.proto",
"b.proto",
],
)

go_proto_library(
name = "foo_go_proto",
importpath = "foo",
proto = ":foo_proto",
)
`,
},
} {
Expand Down
12 changes: 11 additions & 1 deletion internal/language/proto/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

# gazelle:exclude testdata

genrule(
name = "known_imports",
srcs = ["proto.csv"],
outs = ["known_imports.go"],
cmd = "$(location //internal/language/proto/gen:gen_known_imports) -proto_csv $< -known_imports $@ -package proto -var knownImports -key 0 -value 1",
tools = ["//internal/language/proto/gen:gen_known_imports"],
)

go_library(
name = "go_default_library",
srcs = [
Expand All @@ -11,6 +19,7 @@ go_library(
"fix.go",
"generate.go",
"kinds.go",
"known_imports.go",
"lang.go",
"package.go",
"resolve.go",
Expand All @@ -21,7 +30,6 @@ go_library(
"//internal/config:go_default_library",
"//internal/label:go_default_library",
"//internal/language:go_default_library",
"//internal/pathtools:go_default_library",
"//internal/repos:go_default_library",
"//internal/resolve:go_default_library",
"//internal/rule:go_default_library",
Expand All @@ -48,3 +56,5 @@ go_test(
"//vendor/github.com/bazelbuild/buildtools/build:go_default_library",
],
)

exports_files(["proto.csv"])
15 changes: 15 additions & 0 deletions internal/language/proto/gen/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")

go_library(
name = "go_default_library",
srcs = ["gen_known_imports.go"],
importpath = "github.com/bazelbuild/bazel-gazelle/internal/language/proto/gen",
visibility = ["//visibility:private"],
deps = ["//internal/label:go_default_library"],
)

go_binary(
name = "gen_known_imports",
embed = [":go_default_library"],
visibility = ["//:__subpackages__"],
)
Loading