Skip to content

v1.15.0-rc1

Pre-release
Pre-release
Compare
Choose a tag to compare
@jhump jhump released this 17 Jan 14:29
d2a36df

This is a very big change under-the-hood, which is why this is a release candidate. Unfortunately, go get -u ... and tools like Depend-a-bot will not take release candidates/pre-release versions. So this candidate is a sort of shot in the dark, hoping that some brave souls might try it out and provide feedback before I stamp it as an official release.

All of CI is green, I've run apidiff to make sure there are no backwards-incompatible changes in the exported API, and I've done some other exploratory testing to make sure this is all good. My hope is that no one will notice a thing. If they do notice something, it might be a slight performance degradation, but hopefully not consequential enough to be a problem.

I expect v1.15 to be the last v1 version. Any other changes significant enough to warrant a new minor version will instead be added in an upcoming v2 version. This version is intended to be a stop-gap between v1 and v2 as it provides a long-needed bridge between the functionality in this repo and the newer google.golang.org/protobuf/reflect/protoreflect package (and its accompanying packages, protodesc, protoregistry, and dynamicpb).

"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.

"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.