This change add parsing editions specific descriptor parts to
internal/filedesc which makes it possible to load file descriptors of
protos using editions at runtime.
Change-Id: I7a0c23303acddd2cff115859d4cf82bf0102b14c
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/563615
Reviewed-by: Michael Stapelberg <stapelberg@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
I'll add the runtime implementations and tests in a followup change to
make it easier to review.
Change-Id: I2917e0d40a99e81799d89a66584a680ed7e8dbf7
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/561939
Auto-Submit: Lasse Folger <lassefolger@google.com>
Reviewed-by: Michael Stapelberg <stapelberg@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This change adds the first Go specific editions feature and the
associated proto. The feature is used to control if the legacy
UnmarshalJSON method should be generated for enums. This change only
affects protos using editions.
More tests will be added in a followup change.
Change-Id: Ifb62454d7568bd6d90d0b93f8953adcfe46c45fd
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/561938
Reviewed-by: Michael Stapelberg <stapelberg@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Lasse Folger <lassefolger@google.com>
Provide an API to add the GeneratedCodeInfo.Annotation.Semantic enum to
annotations.
Change-Id: I92ab30619a94a117679a0eb16d8cb5b3a1352586
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/489795
Reviewed-by: Lasse Folger <lassefolger@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
This change strips out all descriptor option fields marked with [retention = RETENTION_SOURCE] before writing the FileDescriptor to the generated go code bindings.
Change-Id: Ie624d9d4b4f211a256661d80a04199ae8401662b
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/472696
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Lasse Folger <lassefolger@google.com>
This updates all generated code to match the contents of the latest
v22.0 release of Protobuf.
This involved a couple of changes to the script that does the sync'ing:
1. The new Protobuf version no longer includes autoconf configuration
and instead requires using bazel to build things.
2. The new Protobuf release does not have an artifact named
"protobuf-all-${VERSION}.tar.gz", but the one named
"protobuf-${VERSION}.tar.gz" has all of the sources and was
sufficient for the regenerate.bash script to complete.
This change does NOT regenerate the protos related to benchmarks.
The Protobuf repo no longer includes benchmarks. The CL removing them
says they are superceded by google/fleetbench:
83c499de86
But that project's proto benchmark files are very different:
https://github.com/google/fleetbench/tree/main/fleetbench/proto
So I commented out those steps in the generation code since the benchmarks
will need some work to reconcile with fleetbench.
This code adds known failing tests for conformance. New test cases were
added in https://github.com/protocolbuffers/protobuf/pull/9534, but the
Go protojson package does not behave according to the new tests. There
is an existing issue in GitHub about this:
https://github.com/golang/protobuf/issues/1208
Change-Id: Iad796ec7889bc2a74b58db5224facf850cd1a1cd
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/469255
Reviewed-by: Michael Stapelberg <stapelberg@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Also respect the file-wide deprecation option by treating every
identifier within the file as deprecated.
Change-Id: Ic3a5e84c2d90bbcbefc0a1b3272cc50554b94218
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/462315
Reviewed-by: Lasse Folger <lassefolger@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Apply go1.19 gofmt to non-generated files.
Generated .pb.go files are created by generate.bash using Go 1.18,
so leave them unchanged for now.
Change-Id: Ied36c83cf99704988d059bf0412e677f0fbc71b0
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/418676
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Lasse Folger <lassefolger@google.com>
Previously, this call strconv.FormatInt with base 32,
when the intention is to call it with base 10.
Change-Id: I31cdd2415b3a80936cdcdeb5612a486204404ecb
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/331149
Trust: Joe Tsai <joetsai@digital-static.net>
Reviewed-by: Damien Neil <dneil@google.com>
The Go generator has historically always prefixed an enum value
with the name of the enum type, when it was unnecessary to do so.
For example:
enum Status {
STATUS_FAILED = 0;
STATUS_PASSED = 1;
}
would be generated as:
type Status int32
const (
Status_STATUS_FAILED Status = 0
Status_STATUS_PASSED Status = 1
)
It is common for the enum values to be manually prefixed by the
enum type since protobuf enums use C++ namespace rules where
enum types and enum values are in the same namespace scope.
Thus, having the Go generator add a prefix is redundant.
See https://github.com/golang/protobuf/issues/513.
Some custom Go generators like protoc-gen-gogo allow removing
the prefix with the gogoproto.goproto_enum_prefix feature.
However, this leads to interoperability issues between
protoc-gen-go and protoc-gen-gogo, where the enum value names
cannot be accurately inferred.
Avoid this problem by just hard-coding the enum value number
for values declared in other packages. This provides benefits
in interoperability at the small cost of enum values possibly
being stale if their value were ever changed in a remote package.
However, this would only occur with use of proto2 enums and
default values, which seems to be an exceptionally rare situation.
Before:
Default_MyMessage_MyField = remotepb.FooEnum_FOO_ENUM
After:
Default_MyMessage_MyField = remotepb.FooEnum(4) // remotepb.FooEnum_FOO_ENUM
Before:
func (x *MyMessage) GetField() remotepb.FooEnum {
...
return remotepb.FooEnum_FOO_ZERO
}
After:
func (x *MyMessage) GetField() remotepb.FooEnum {
...
return remotepb.FooEnum(0) // always 0 for proto3 and often 0 for proto2
}
Change-Id: I3a06cd553f2eaf6124666f6c36c196d500d35718
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/319649
Trust: Joe Tsai <joetsai@digital-static.net>
Reviewed-by: Damien Neil <dneil@google.com>
Change-Id: Ib09bd3cbd15088d534de34b08d01a4d7a4880c0a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/306209
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Damien Neil <dneil@google.com>
Trust: Joe Tsai <thebrokentoaster@gmail.com>
Trust: Damien Neil <dneil@google.com>
The ExtensionRangeArray was a pseudo-internal API that was used by
the protobuf runtime implementation to know what the extension ranges are.
For some time now, the runtime implementation does not make use of this.
According to all the latest modules known by the module proxy,
no code depends directly on this method being present.
In the extremely rare case where some user code is depending on this method,
the user can place a .go file next to the generated .pb.go file that
injects this method.
Change-Id: Iae40a9a33b8c9b5a243d48db14f25b05ca24e3dc
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/305574
Trust: Joe Tsai <joetsai@digital-static.net>
Reviewed-by: Damien Neil <dneil@google.com>
When someone has no idea what a binary does, it is convention to
pass the "--help" flag. When done, we should point the user
to the devsite documentation on protoc with protoc-gen-go.
Change-Id: I36289a1ae025b9e12521b34362370aba5235a44b
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/302330
Trust: Joe Tsai <joetsai@digital-static.net>
Reviewed-by: Damien Neil <dneil@google.com>
Since the release of v1.20, we have warned that it be required
that the import path for every generated package be specified.
This CL simplifies the mechanism for specifying such information
to just the "M" command-line flags and the "go_package" options
in the .proto source files, where the former takes precedence
over the latter.
Changes made:
* Remove "import_prefix" and "import_path" flags.
* Make the Go import path and package name derivation logic simpler
where both "M" flags and "go_package" options are parsed the same way
by calling the common splitImportPathAndPackageName function, and
where "M" flags take precedence over "go_package" options.
The exception to this occurs when neither "M" nor "go_package" specify
an explicit Go package name, where the derivation may be non-intuitive.
See the "NOTE" comment for the rationale for this behavior,
which actually matches what was already the case.
* Remove the pathTypeLegacy output mode and make pathTypeImport
the default. The pathTypeLegacy mode becomes even more non-sensible
now that we require that the import path always be provided.
* Remove the baseName function. After deleting unsupported functionality,
this seems to only be used by GeneratedFile.QualifiedGoIdent.
However, that method does not need to create stable package names
since they are only used locally within the generated file.
They only need to guarantee the property of validity and uniqueness.
* Remove the warn function since there are no more warnings.
Change-Id: Ic95fb3cde5ffcb71bbcc829fcff34369758cebef
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/301953
Trust: Joe Tsai <joetsai@digital-static.net>
Reviewed-by: Damien Neil <dneil@google.com>
A reference to this constant was originally generated to ensure that users
were using a sufficiently new version of the github.com/golnag/protobuf
module to avoid subtle runtime incompatibility issues.
Such a technique is not needed if users were using modules,
which would enforce this constraint based on our go.mod requirements.
When we first released the google.golang.org/protobuf module,
we suggested that we would consider removing it after 6 months.
It has now been 7 months since the release.
Fixesgolang/protobuf#1077
Change-Id: I9f2010da27b27fe6b12541a15833721441df8409
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/259901
Reviewed-by: Damien Neil <dneil@google.com>
Trust: Joe Tsai <thebrokentoaster@gmail.com>
Added API:
SourceLocations.ByPath
SourceLocations.ByDescriptor
SourceLocation.Next
SourcePath.String
SourcePath.Equal
We modify compiler/protogen to use SourceLocations.ByDescriptor.
In retrospect, if this had existed during the development of protogen,
we would not have exposed protogen.Location and related fields.
Change-Id: I58f17e59f90b9ba16f0982c4b71c2542e4ff6e75
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/238000
Reviewed-by: Damien Neil <dneil@google.com>
MessageSet are a proto1 feature only used by Google.
We no longer rely on the name mangling logic performed here,
so remove it.
Change-Id: I5d66ebd86875894632f0d0c1e9816ae47ee0d5f4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/242657
Reviewed-by: Herbie Ong <herbie@google.com>
Trivial adjustments to error handling to reduce differences between
the generated helpers and the legacy ptypes package.
Change-Id: Ib3022eb50d9a9c0906b7809fe7e8011ee9399b0a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/238009
Reviewed-by: Damien Neil <dneil@google.com>
Many usages of the legacy ptypes.Timestamp and ptypes.Duration rely
on the functions implicitly returning an error for a nil message.
In order to migrate previous usages of the ptypes constructors to
the new API, we modify CheckValid to preserve similar semantics.
There is some consistency with this change in that:
(*M)(nil).IsValid() == (*M)(nil).ProtoReflect().IsValid()
where M is Duration, Timestamp, and FieldMask.
Change-Id: I05ae152511f9875ea034e78aefb7aab18d17a318
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/238007
Reviewed-by: Damien Neil <dneil@google.com>
While the MarshalFrom method and function are more flexible since
it permits the reuse of an existing Any, the most common use case
by far is to construct a new Any. Optimize for that use case
by providing a constructor that directly returns a new Any instance.
We do not provide a variant that accepts a MarshalOptions since
the more flexible MarshalFrom function can be used for that.
Change-Id: Iab0219229c7d3aaa7390a2340a4f248002995293
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/237997
Reviewed-by: Damien Neil <dneil@google.com>
Add checks so that MarshalFrom and UnmarshalTo consistently matches
the behavior of the proto package with regard to nil messages.
In particular, using a nil message as the destination results in
a panic (which is already the current behavior), while using a
nil message as the source does not panic (it is usually treated as
an untyped empty message). Since an untyped message has no
sensible meaning in the context of Any, return an error.
Change-Id: I99e86c2cdfbd8be57cc039efd550458dc56aadbc
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/237920
Reviewed-by: Damien Neil <dneil@google.com>
This CL introduces generation of specialized APIs directly into the
generated packages for certain well-known types. This follows the pattern
set forth by the other language implementations that have specialized
generated support for certain well-known types.
Overview of new API:
package anypb
func MarshalFrom(*Any, proto.Message, proto.MarshalOptions) error
func UnmarshalTo(*Any, proto.Message, proto.UnmarshalOptions) error
func UnmarshalNew(*Any, proto.UnmarshalOptions) (proto.Message, error)
func (*Any) MessageIs(proto.Message) bool
func (*Any) MessageName() protoreflect.FullName
func (*Any) MarshalFrom(proto.Message) error
func (*Any) UnmarshalTo(proto.Message) error
func (*Any) UnmarshalNew() (proto.Message, error)
package timestamppb
func Now() *Timestamp
func New(time.Time) *Timestamp
func (*Timestamp) AsTime() time.Time
func (*Timestamp) IsValid() bool
func (*Timestamp) CheckValid() error
package durationpb
func New(time.Duration) *Duration
func (*Duration) AsDuration() time.Duration
func (*Duration) IsValid() bool
func (*Duration) CheckValid() error
package structpb
func NewStruct(map[string]interface{}) (*Struct, error)
func (*Struct) AsMap() map[string]interface{}
func (*Struct) MarshalJSON() ([]byte, error)
func (*Struct) UnmarshalJSON(b []byte) error
func NewList([]interface{}) (*ListValue, error)
func (*ListValue) AsSlice() []interface{}
func (*ListValue) MarshalJSON() ([]byte, error)
func (*ListValue) UnmarshalJSON(b []byte) error
func NewValue(interface{}) (*Value, error)
func NewNullValue() *Value
func NewBoolValue(bool) *Value
func NewNumberValue(float64) *Value
func NewStringValue(string) *Value
func NewStructValue(*Struct) *Value
func NewListValue(*ListValue) *Value
func (*Value) AsInterface() interface{}
func (*Value) MarshalJSON() ([]byte, error)
func (*Value) UnmarshalJSON(b []byte) error
package fieldmaskpb
func New(proto.Message, ...string) (*FieldMask, error)
func Union(*FieldMask, *FieldMask, ...*FieldMask) *FieldMask
func Intersect(*FieldMask, *FieldMask, ...*FieldMask) *FieldMask
func (*FieldMask) IsValid(proto.Message) bool
func (*FieldMask) Append(proto.Message, ...string) error
func (*FieldMask) Normalize()
package wrapperspb
func Bool(bool) *BoolValue
func Int32(int32) *Int32Value
func Int64(int64) *Int64Value
func UInt32(uint32) *UInt32Value
func UInt64(uint64) *UInt64Value
func Float(float32) *FloatValue
func Double(float64) *DoubleValue
func String(string) *StringValue
func Bytes([]byte) *BytesValue
This functionality expands upon and supersedes the
older github.com/golang/protobuf/ptypes package,
which provided helpers for Any, Timestamp, and Duration.
Comparison with older ptypes package:
* ptypes.AnyMessageName is replaced by anypb.Any.MessageName.
The former returned an error for malformed type URLs,
while the latter simply returns an empty string.
* ptypes.Is is replaced by anypb.Any.MessageIs.
* ptypes.Empty has no direct replacement as it is equivalent to:
mt, err := protoregistry.GlobalTypes.FindMessageByURL(any.GetTypeUrl())
if err != nil {
return nil, err
}
return mt.New().Interface(), nil
Analysis of user code revealed that this function is seldom used.
* ptypes.MarshalAny is replaced by anypb.Any.MarshalFrom.
The former creates a new Any message and returns it,
while the latter is a method that modifies the receiver.
* ptypes.UnmarshalAny is replaced by anypb.Any.UnmarshalTo.
* ptypes.DynamicAny is loosely replaced by anypb.Any.UnmarshalNew.
The DynamicAny type is a custom proto.Message that is special
to ptypes.UnmarshalAny where it would allocate a new message
and store it into the DynamicAny instance. The UnmarshalNew method
accomplishes the equivalent functionality in a more direct fashion.
* ptypes.TimestampNow is replaced by timestamppb.Now.
* ptypes.TimestampProto is replaced by timestamppb.New.
The former returned an error if the timestamp was outside the
10000-year range recommended by timestamp.proto,
while the latter always succeeded. To preserve the behavior of
the former validation check, the replacement can additionally
call the timestamppb.Timestamp.CheckValid method.
* ptypes.Timestamp is replaced by timestamppb.Timestamp.AsTime.
The former returned an error if the timestamp was outside the
10000-year range recommended by timestamp.proto,
while the latter always succeeded. To preserve the behavior of
the former validation check, the replacement can additionally
call the timestamppb.Timestamp.CheckValid method.
* ptypes.TimestampString has no direct replacement as it is equivalent to:
ts.AsTime().Format(time.RFC3339Nano)
* ptypes.DurationProto is replaced by durationpb.New.
* ptypes.Duration is replaced by durationpb.Duration.AsDuration.
The former returned an error if the duration would overflow
when converting to a time.Duration, while the latter uses
saturation arithmetic (similiar to the time package itself).
Underflow resulted in time.Duration(math.MinInt64), while
overflow resulted in time.Duration(math.MaxInt64).
To preserve the behavior of former validation checks,
the replacement can call the durationpb.Duration.CheckValid method
and check whether the duration is fixed to one of the overflow values.
Change-Id: Ia996b1037a1fcafced7c7e10e9408ef7fa22863a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/225298
Reviewed-by: Damien Neil <dneil@google.com>
The genid package unifies the genname, fieldnum, and detectknown
packages into a single package.
Whenever possible use the generated constants rather than
hard-coded literals. This makes it easier to search the entire
module for special logic that deal with well-known types.
Change-Id: I13beff1f4149444a0c0b9e607ebf759657f000f4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/235301
Reviewed-by: Herbie Ong <herbie@google.com>
Cleanup the generated logic by having the implementation be backed
by protoimpl rather that directly generated.
Weak fields are a deprecated feature of protobufs and
have entirely be superceded by extensions.
Unfortunately, there are still some usages of it.
Change-Id: Ie1a4b7da253e2ccf5e56627775d9b2fb4090d59a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/229717
Reviewed-by: Damien Neil <dneil@google.com>
In the upcoming 3.12.x release of protoc, the proto3 language will be
amended to support true presence for scalars. This CL adds support
to both the generator and runtime to support these semantics.
Newly added public API:
protogen.Plugin.SupportedFeatures
protoreflect.FieldDescriptor.HasPresence
protoreflect.FieldDescriptor.HasOptionalKeyword
protoreflect.OneofDescriptor.IsSynthetic
Change-Id: I7c86bf66d0ae56642109beb5f2132184593747ad
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/230698
Reviewed-by: Damien Neil <dneil@google.com>
Now we'll get a generator error if a file is missing a go_package
option.
Change-Id: I89eec716f86956e6c164a61f5531c140b74bc099
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/222378
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Throughout the module options usually expressed as a struct where the
acting function is a method hanging off the options type.
Use this pattern for protogen as well.
Change-Id: I533a61387cb74971e4efc9313d400b66b8aac451
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/221424
Reviewed-by: Damien Neil <dneil@google.com>
In the distant past this was necessary because:
1) the generated code depended on github.com/golang/protobuf,
but now it doesn't.
2) protoc-gen-go-grpc had a dependency on google.golang.org/grpc,
and the seperate go.mod file allowed us to isolate the dependency,
but that binary doesn't exist here anymore.
Drop the go.mod file for cmd/protoc-gen-go/testdata.
Change-Id: I7341d78dc346bd82e5c68ed48cee3275b6296249
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/220502
Reviewed-by: Damien Neil <dneil@google.com>
Fix a few files with no or unusual copyright headers.
Manually add copyright headers to the legacy testprotos, which will
(probably) never be regenerated.
Change-Id: Ifb52fa0eb59bf9d2de40b8df7e581a3c9731c883
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/220498
Reviewed-by: Joe Tsai <joetsai@google.com>
Remove a stray bit of punctuation that crept into one of the license
headers and got copied around everywhere.
Change-Id: Iebe4e882650ab6dab28f132b5e324e2ab0b99a73
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/220339
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Change the protoc flags such that when one of our test .proto files
imports another, the filename is consistently specified relative to the
module root.
Change-Id: I690282795cef23347c8794c1c6357e4fe9560d8a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/217762
Reviewed-by: Joe Tsai <joetsai@google.com>
Refactor the internal logic of protoc-gen-go to better plumb local
settings and parameters down the call tree.
Change-Id: I09fec188d7359f2b66be584aa8f10e682a7b6796
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/214357
Reviewed-by: Patrik Nyblom <pnyb@google.com>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
We resisted adding Clone for a while since:
* It is a function that is perfectly suited for generics.
However, generics probably still won't be available in Go for some time
and it is impractical to block addition of this function when it is very
widely used and will be necessary for the v1 to v2 migration.
* In the past, there was no protoreflect.Message.IsValid, so there was
no proper API to detect invalid top-level messages and return them as such.
Since Clone relies on certain properties about proper round-tripping
of ProtoMessage.ProtoReflect <-> Message.Interface, we add a test
in testing/prototest to check for this.
Change-Id: Ic492b68f27b8b88322a6a3fa3a5e492228db79d9
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/213297
Reviewed-by: Damien Neil <dneil@google.com>
These are not necessary now that weak fields are unexported.
Change-Id: Ida18b984abedfdf52fd3d5f3cb2f4ca580659a5c
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/210745
Reviewed-by: Damien Neil <dneil@google.com>
Both the generator and the runtime need to agree upon the names of
specialized Go struct fields. Centralize that information in an
internal genname package.
In the mean time, also change the XXX_weak field name to match
the name used internally at Google.
Change-Id: I026bf354418c363482e5902f21aa5e0cacae24b0
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/207080
Reviewed-by: Damien Neil <dneil@google.com>
Remove previously deprecated types, functions, and methods.
Update github.com/golang/protobuf module version to one which does not
depend on any deprecated APIs.
Fixexs golang/protobuf#963
Change-Id: Ida451ef5ef3f34830808f737cc0d1c98f32ce76a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/206017
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Remove compiler flags that originally existed to assist the internal
divergences of protoc-gen-go. However, these ended up not being used
since the internal "patch" ended up being an entirely different fork.
Change-Id: I936d1db96bc7d737a2f2e5b90d2bd09fcc8c7b88
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/201738
Reviewed-by: Herbie Ong <herbie@google.com>