Skip to content

v1.15.0

Compare
Choose a tag to compare
@jhump jhump released this 26 Feb 22:39
bc601ae

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 a desc.Descriptor (via the various Wrap* functions in this package). It is similarly easy to unwrap a desc.Descriptor value, to recover the underlying protoreflectDescriptor.
    • This allows this package to be easily used in conjunction with protoreflect and accompanying packages. You can take a protoreflect.Descriptor and then easily use it with the desc/builder and desc/protoprint packages in this repo. Similarly, you can create a desc.Descriptor using the desc/protoparse package and easily turn that into a protoreflect.Descriptor, for use with the google.golang.org/protobuf/... packages.

Additions:

  • This adds a new DescriptorWrapper interface, which is implemented by all descriptor implementations in this package. It contains an Unwrap() protoreflect.Descriptor function, to recover the underlying protoreflect.Descriptor.
  • Also, all descriptor implementations in this package also have additional methods that are more strongly typed. For example, *desc.FileDescriptor has a method UnwrapFile() protoreflect.FileDescriptor.
  • Finally, this package now has numerous Wrap* functions, which accept a protoreflect.Descriptor and wrap it, returning a desc.Descriptor. There is one function for each concrete type, for example for messages there is WrapMessage(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 by protoreflect.Descriptor values, more rules are enforced. This is because the implementation of descriptors in the protoreflect package does perform all of those validation checks. The new checks that are now enforced that previously were not:
    1. Files with a syntax of proto3 are not allowed to have required fields.
    2. Files with a syntax of proto3 are not allowed to have messages that define extension ranges.
    3. Files with a syntax of proto3 are not allowed to use groups.
    4. Files with a syntax of proto3 are not allowed to declare default values for fields.
    5. Extension fields must use tag numbers that are in an extension range defined on the extended message.
    6. Non-extension fields are not allowed to use tags that lie in a message's extension ranges or reserved ranges.
    7. Non-extension fields are not allowed to use names that the message has marked as reserved.
    8. 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 the github.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 the Parser.ParseToAST method, which must convert from protocompile's AST model to the model defined in desc/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.
  • 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 a GlobalTypes package variable that implements that interface. This is analogous to protoregistry.GlobalTypes, just as the existing sourceinfo.GlobalFiles corresponds to protoregistry.GlobalFiles.
  • This adds new Wrap* functions, that accept various protoreflect 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 a protoreflect.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.