v1.15.0
This is a significant and admittedly long overdue release. This release finally provides a bridge for interoperability between packages and functionality in this repo and the new reflection packages and APIs added in the "v2 API" of the Protobuf runtime for Go (google.golang.org/protobuf
), particularly the protoreflect, protodesc, protoregistry, and dynamicpb packages.
This repo began because the Protobuf runtime (at the time, the "v1 API" in github.com/golang/protobuf
) had no support for Protobuf reflection and dynamic messages. The functionality slowly grew to include dynamic gRPC, interesting meta features like parsing Protobuf sources or printing Protobuf source from a descriptor, etc.
But the v2 API was released nearly three years ago. And it does provide some functionality that this repo provided, but now in the core runtime library. And yet this repo still refers to the now-deprecated v1 API.
Under the hood, this is a very big change, mainly due to the big changes (described below) in the github.com/jhump/protoreflect/desc
and github.com/jhump/protoreflect/desc/protoparse
packages.
This release is planned to be the final v1 release. Any other changes significant enough to warrant a new minor version will instead be added in an upcoming v2 version. A new v2 version will have zero references to the v1 API of the Protobuf runtime, and it will not duplicate any of the functionality that now exists in the v2 API.
The changes are all detailed below and include all of the changes described in the past two release candidates (v1.15.0-rc1 and v1.15.0-rc2).
NOTE: Zero defects were reported in the nearly six weeks since the first release candidate was created. It is entirely possible that very few users tried it, so there still could be some material bugs and compatibility issues lurking in this release. If you encounter any marked changes in behavior between the previous release (v1.14.1) and this one, please file an issue as soon as possible! However, if the issue is a performance degradation, it may not be addressed until a v2. So If your use case is very sensitive to performance, you may need to stay on v1.14.1. The under-the-hood changes in this repo for this release are expected to have some performance impact, though it will hopefully be minor or even negligible for most users.
"github.com/jhump/protoreflect/desc"
Changes/fixes:
- This package, the core of this whole repo, with its descriptor interfaces and related functions, has been substantially overhauled. The descriptor values provided by this package are now backed by the descriptor implementations in the
google.golang.org/protobuf/reflect/protoreflect
package.- The primary advantage of this change is that it is now easy to convert a
protoreflect.Descriptor
to adesc.Descriptor
(via the variousWrap*
functions in this package). It is similarly easy to unwrap adesc.Descriptor
value, to recover the underlyingprotoreflectDescriptor
. - This allows this package to be easily used in conjunction with
protoreflect
and accompanying packages. You can take aprotoreflect.Descriptor
and then easily use it with thedesc/builder
anddesc/protoprint
packages in this repo. Similarly, you can create adesc.Descriptor
using thedesc/protoparse
package and easily turn that into aprotoreflect.Descriptor
, for use with thegoogle.golang.org/protobuf/...
packages.
- The primary advantage of this change is that it is now easy to convert a
Additions:
- This adds a new
DescriptorWrapper
interface, which is implemented by all descriptor implementations in this package. It contains anUnwrap() protoreflect.Descriptor
function, to recover the underlyingprotoreflect.Descriptor
. - Also, all descriptor implementations in this package also have additional methods that are more strongly typed. For example,
*desc.FileDescriptor
has a methodUnwrapFile() protoreflect.FileDescriptor
. - Finally, this package now has numerous
Wrap*
functions, which accept aprotoreflect.Descriptor
and wrap it, returning adesc.Descriptor
. There is one function for each concrete type, for example for messages there isWrapMessage(d protoreflect.MessageDescriptor) (*MessageDescriptor, error)
"github.com/jhump/protoreflect/desc/builder"
Changes/fixes:
- Previously, not all rules of the Protobuf language were enforced when building a new descriptor with this package. Since the
desc.Descriptor
values returned by this package are now backed byprotoreflect.Descriptor
values, more rules are enforced. This is because the implementation of descriptors in theprotoreflect
package does perform all of those validation checks. The new checks that are now enforced that previously were not:- Files with a syntax of proto3 are not allowed to have required fields.
- Files with a syntax of proto3 are not allowed to have messages that define extension ranges.
- Files with a syntax of proto3 are not allowed to use groups.
- Files with a syntax of proto3 are not allowed to declare default values for fields.
- Extension fields must use tag numbers that are in an extension range defined on the extended message.
- Non-extension fields are not allowed to use tags that lie in a message's extension ranges or reserved ranges.
- Non-extension fields are not allowed to use names that the message has marked as reserved.
- Extension ranges and reserved ranges must not overlap.
"github.com/jhump/protoreflect/desc/protoparse"
Changes/fixes:
- This package has been overhauled perhaps even more than the
desc
package. The implementation in this package has been completely replaced with the functionality of thegithub.com/bufbuild/protocompile
package. So the exported APIs in this package are now just adapters. The actual parser/compiler is implemented in this other dependency. Most of this adaptation logic is trivial with the exception being for theParser.ParseToAST
method, which must convert fromprotocompile
's AST model to the model defined indesc/protoparse/ast
.
"github.com/jhump/protoreflect/desc/protoprint"
Changes/fixes:
- Formatting of message literals in custom option values has been improved.
- It now encloses nested messages in curly braces (
{
and}
) instead of angle brackets (<
and>
), which is better aligned with the commonly-used and preferred syntax style. - Also, nested messages now respect the
Printer.MessageLiteralExpansionThresholdLength
, instead of this threshold only being applied for a top-level message. So small nested messages can be emitted in compact form, even if enclosed within a message literal that has been expanded.
- It now encloses nested messages in curly braces (
- If printing descriptors that had no source code info and no other sort configuration was used on the
Printer
, then elements with multiple option declarations would have those options printed in seemingly random order. The actual order was based on a map iteration, and was thus non-deterministic. This has been fixed. In such a case, options will now be ordered by name.
"github.com/jhump/protoreflect/desc/sourceinfo"
Additions:
- A new
TypeResolver
interface has been added, as well as aGlobalTypes
package variable that implements that interface. This is analogous toprotoregistry.GlobalTypes
, just as the existingsourceinfo.GlobalFiles
corresponds toprotoregistry.GlobalFiles
. - This adds new
Wrap*
functions, that accept variousprotoreflect
types and return values that are identical to the input values except that they include source code info that was registered with this package.
"github.com/jhump/protoreflect/dynamic"
Changes/fixes:
- Previously, if
protoreflect
APIs were used to store a value in an extension field, using aprotoreflect.FieldDescriptor
that was not a generated extension (i.e. not known at compile-time), trying to convert the resulting message to a*dynamic.Message
would overlook that field; it would be absent from the result, not even appearing in the unrecognized fields. This has been fixed. Such extension values will be in the resulting*dynamic.Message
and appear as recognized/known fields.