diff --git a/.bazelrc b/.bazelrc index a2f90a52d0..ee109f887c 100644 --- a/.bazelrc +++ b/.bazelrc @@ -10,3 +10,6 @@ build:ci --spawn_strategy=standalone build:ci --genrule_strategy=standalone test:ci --test_strategy=standalone test:ci --test_output=errors + +# Required for proto related tests. +build --protocopt=--experimental_allow_proto3_optional \ No newline at end of file diff --git a/WORKSPACE b/WORKSPACE index 54dd87275a..3551b623d4 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -10,12 +10,12 @@ go_register_toolchains(version = "1.16rc1") http_archive( name = "com_google_protobuf", - sha256 = "a79d19dcdf9139fa4b81206e318e33d245c4c9da1ffed21c87288ed4380426f9", - strip_prefix = "protobuf-3.11.4", - # latest, as of 2020-02-21 + sha256 = "d0f5f605d0d656007ce6c8b5a82df3037e1d8fe8b121ed42e536f569dec16113", + strip_prefix = "protobuf-3.14.0", + # latest, as of 2020-11-13 urls = [ - "https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v3.11.4.tar.gz", - "https://github.com/protocolbuffers/protobuf/archive/v3.11.4.tar.gz", + "https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v3.14.0.tar.gz", + "https://github.com/protocolbuffers/protobuf/archive/v3.14.0.tar.gz", ], ) diff --git a/go/tools/builders/protoc.go b/go/tools/builders/protoc.go index 44e6f848a1..a86e94d123 100644 --- a/go/tools/builders/protoc.go +++ b/go/tools/builders/protoc.go @@ -49,6 +49,7 @@ func run(args []string) error { descriptors := multiFlag{} expected := multiFlag{} imports := multiFlag{} + protocopts := multiFlag{} flags := flag.NewFlagSet("protoc", flag.ExitOnError) protoc := flags.String("protoc", "", "The path to the real protoc.") outPath := flags.String("out_path", "", "The base output path to write to.") @@ -58,6 +59,7 @@ func run(args []string) error { flags.Var(&descriptors, "descriptor_set", "The descriptor set to read.") flags.Var(&expected, "expected", "The expected output files.") flags.Var(&imports, "import", "Map a proto file to an import path.") + flags.Var(&protocopts, "protocopt", "Extra options to pass to protoc.") if err := flags.Parse(args); err != nil { return err } @@ -88,7 +90,9 @@ func run(args []string) error { "--plugin", fmt.Sprintf("%v=%v", strings.TrimSuffix(pluginBase, ".exe"), *plugin), "--descriptor_set_in", strings.Join(descriptors, string(os.PathListSeparator)), } + protoc_args = append(protoc_args, protocopts...) protoc_args = append(protoc_args, flags.Args()...) + cmd := exec.Command(*protoc, protoc_args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr diff --git a/proto/compiler.bzl b/proto/compiler.bzl index c85b161815..1cef1b89ea 100644 --- a/proto/compiler.bzl +++ b/proto/compiler.bzl @@ -99,6 +99,7 @@ def go_proto_compile(go, compiler, protos, imports, importpath): args.add("-importpath", importpath) args.add("-out_path", outpath) args.add("-plugin", compiler.internal.plugin) + args.add_all("-protocopt", compiler.internal.protocopts) # TODO(jayconrod): can we just use go.env instead? args.add_all(compiler.internal.options, before_each = "-option") @@ -190,6 +191,7 @@ def _go_proto_compiler_impl(ctx): go_protoc = ctx.file._go_protoc, plugin = ctx.file.plugin, import_path_option = ctx.attr.import_path_option, + protocopts = ctx.attr.protocopts, ), ), library, @@ -209,6 +211,7 @@ _go_proto_compiler = rule( cfg = "exec", mandatory = True, ), + "protocopts": attr.string_list(), "_go_protoc": attr.label( allow_single_file = True, cfg = "exec", diff --git a/tests/core/go_proto_library/BUILD.bazel b/tests/core/go_proto_library/BUILD.bazel index 2e29db96a9..534d6a09b8 100644 --- a/tests/core/go_proto_library/BUILD.bazel +++ b/tests/core/go_proto_library/BUILD.bazel @@ -1,6 +1,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") load("@rules_proto//proto:defs.bzl", "proto_library") +load("@io_bazel_rules_go//proto:compiler.bzl", "go_proto_compiler") +load( + "//proto/wkt:well_known_types.bzl", + "PROTO_RUNTIME_DEPS", + "WELL_KNOWN_TYPES_APIV2", + "WELL_KNOWN_TYPE_RULES", +) # Common rules proto_library( @@ -312,3 +319,27 @@ go_test( "@org_golang_google_protobuf//types/pluginpb:go_default_library", ], ) + +go_proto_compiler( + name = "proto_optionals_compiler", + protocopts = ["--experimental_allow_proto3_optional"], + deps = PROTO_RUNTIME_DEPS + WELL_KNOWN_TYPE_RULES.values() + WELL_KNOWN_TYPES_APIV2, +) + +proto_library( + name = "proto_optionals", + srcs = ["proto_optionals.proto"], +) + +go_proto_library( + name = "go_proto_optionals", + compilers = [":proto_optionals_compiler"], + protos = [":proto_optionals"], + importpath = "github.com/bazelbuild/rules_go/tests/core/go_proto_library/protos", +) + +go_test( + name = "proto_optionals_test", + srcs = ["proto_optionals_test.go"], + deps = [":go_proto_optionals"], +) \ No newline at end of file diff --git a/tests/core/go_proto_library/README.rst b/tests/core/go_proto_library/README.rst index 1a5b039d3b..3834eb5d4e 100644 --- a/tests/core/go_proto_library/README.rst +++ b/tests/core/go_proto_library/README.rst @@ -59,3 +59,8 @@ protos_alias_test Checks that packages generated by `go_proto_library` can be imported using one of the strings listed in ``importpath_aliases``. + +proto_optionals_test +-------------------- + +Checks that protocopts can be provided via go_proto_compiler. \ No newline at end of file diff --git a/tests/core/go_proto_library/proto_optionals.proto b/tests/core/go_proto_library/proto_optionals.proto new file mode 100644 index 0000000000..6ffe6c9f69 --- /dev/null +++ b/tests/core/go_proto_library/proto_optionals.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +option go_package = "github.com/bazelbuild/rules_go/tests/core/go_proto_library/protos"; + +message Foo { + // Experimental protoc feature + // See: https://github.com/protocolbuffers/protobuf/blob/master/docs/implementing_proto3_presence.md + optional int64 x = 1; +} diff --git a/tests/core/go_proto_library/proto_optionals_test.go b/tests/core/go_proto_library/proto_optionals_test.go new file mode 100644 index 0000000000..4bae42bebc --- /dev/null +++ b/tests/core/go_proto_library/proto_optionals_test.go @@ -0,0 +1,27 @@ +/* Copyright 2019 The Bazel Authors. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package proto_optionals_test + +import ( + "testing" + + "github.com/bazelbuild/rules_go/tests/core/go_proto_library/protos" +) + +func TestProtoOptional(t *testing.T) { + x := int64(1) + _ = protos.Foo{X: &x} // X is a pointer to int64 since it is proto3 optional. +}