Skip to content

v0.9.2

Choose a tag to compare

@merlimat merlimat released this 13 Oct 20:03
· 2 commits to master since this release

Open proto3 enums, and no Unsafe warning when Netty doesn't use it

Enum fields of proto3 files now keep numbers their enum doesn't define, as protobuf-java does, so a message from a peer with a newer schema no longer turns an unknown value into the zero value. And LightProto no longer triggers the JDK's sun.misc.Unsafe warning in applications where Netty doesn't use Unsafe.

Keep numbers that proto3 enums don't define (#52)

LightProto generated every enum field as a closed enum. A number the enum didn't define was dropped while parsing: the getter returned the enum's zero value, and serializing the message again lost the number. In oxia-java, a client read a new server status INVALID_ARGUMENT = 4 as OK and completed rejected writes as successes.

Enum fields and map values declared in a proto3 file are now open, as in protobuf-java:

  • Enums of proto3 files end with UNRECOGNIZED(-1). The getter returns it for an unknown number, and the new getXValue(), getXValueAt(i) and getXValue(key) return the number.
  • The number is written back on serialization, and is used by equals(), hashCode() and copyFrom().
  • JSON and TextFormat print an unknown number as the number, and read both names and numbers.
  • Enum fields of proto2 files stay closed, even when the enum comes from a proto3 file. Their generated code is unchanged.

Parsing proto3 enum fields is also faster: 12% for singular fields and 57% for packed ones (EnumBenchmark, JDK 26).

Compatibility: UNRECOGNIZED is a new constant in every proto3 enum.

  • Exhaustive switch expressions (and Kotlin when) over a proto3 enum without a default branch no longer compile. Classes compiled before still link, but throw MatchException when they meet UNRECOGNIZED.
  • values() and EnumSet.allOf() include UNRECOGNIZED, and its getValue() throws.
  • An unknown number no longer reads as the zero value. Repeated and map counts include it, and getX(key) returns UNRECOGNIZED instead of throwing.

Use sun.misc.Unsafe only where Netty does (#53)

Since JDK 24, the first use of sun.misc.Unsafe's memory-access methods prints a warning that names the caller (JEP 498). LightProtoCodec looked Unsafe up in its static initializer. Applications where Netty doesn't use Unsafe got the warning from LightProto: Netty 4.2 on Java 25, -Dio.netty.noUnsafe=true, or --sun-misc-unsafe-memory-access=warn|deny.

The codec now looks Unsafe up only when Netty's PlatformDependent.hasUnsafe() is true. Where Netty uses Unsafe, nothing changes; interleaved JDK 26 runs measured parity. Where it doesn't, LightProto takes its paths without Unsafe. Two of them no longer allocate a temporary array per ASCII string.