Typed-accessor invokers, built once per field with LambdaMetafactory.
protobuf-java's reflection API pays a FieldAccessorTable lookup on every setField/getField. When the prototype is a generated class, the typed accessors (setFooBar, getFooBar, hasFooBar) are right there — and a metafactory-generated BiFunction/Function calling one runs at direct-interop speed (measured ~3.5 ns/op, vs ~µs through reflection paths), including the primitive boxing bridge the instantiated method type declares.
Everything here is best-effort by construction, in the same spirit as the Java-class hint: derive protoc's accessor name, let findVirtual verify it exists with the expected signature, and return nil on ANY failure — including LambdaMetafactory itself being unavailable, which is what happens under native-image, where the codec silently keeps its reflection path. A wrong derivation is never wrong bytes, only a missed optimisation.
Typed-accessor invokers, built once per field with LambdaMetafactory. protobuf-java's reflection API pays a FieldAccessorTable lookup on every setField/getField. When the prototype is a generated class, the typed accessors (setFooBar, getFooBar, hasFooBar) are right there — and a metafactory-generated BiFunction/Function calling one runs at direct-interop speed (measured ~3.5 ns/op, vs ~µs through reflection paths), including the primitive boxing bridge the instantiated method type declares. Everything here is best-effort by construction, in the same spirit as the Java-class hint: derive protoc's accessor name, let findVirtual verify it exists with the expected signature, and return nil on ANY failure — including LambdaMetafactory itself being unavailable, which is what happens under native-image, where the codec silently keeps its reflection path. A wrong derivation is never wrong bytes, only a missed optimisation.
(accessor-suffix s)protoc's UnderscoresToCamelCase for accessor names: drop underscores, capitalise the letter after an underscore or digit, preserve existing case elsewhere. repeat_count -> RepeatCount, f10 -> F10, camelCaseField -> CamelCaseField. Precision is not load-bearing — a miss just fails findVirtual and the field stays on the reflection path.
protoc's UnderscoresToCamelCase for accessor names: drop underscores, capitalise the letter after an underscore or digit, preserve existing case elsewhere. repeat_count -> RepeatCount, f10 -> F10, camelCaseField -> CamelCaseField. Precision is not load-bearing — a miss just fails findVirtual and the field stays on the reflection path.
(getter-invoker msg-class method-name return-class)(Function msg) applying msgClass.<name>() returning returnClass boxed, or nil.
(Function msg) applying msgClass.<name>() returning returnClass boxed, or nil.
(setter-invoker builder-class method-name param-class)(BiFunction builder value) applying builderClass.<name>(paramClass), or nil.
(BiFunction builder value) applying builderClass.<name>(paramClass), or nil.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |