docs(sdk-java): bridge-ref parity for the inbound value_type annotation (#4087) - #4153
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
⏭️ Performance benchmarks were skippedPerf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to To run them on this PR, do any of the following, then push a commit (or re-run CI):
|
…on (#4087) #4087 migrated the Java bridge to the node-level InboundValue.value_type sparse annotation (removing InboundClassValue.class_ty) and added the outbound union selected_option_index, but left the Java bridge-ref docs describing the pre-migration wire shape. Bring the two docs back to truth: ref-java-inbound-encoding.md - add value_type = 1 to the InboundValue proto block; document reserved field 1 on InboundClassValue - new "The value_type annotation" section: how Java (a Reject-policy typed producer) threads the contextual declared union — BamlTypedValue for top-level args, fieldDescs for class fields, item/value types for containers — and emits value_type for the three canonical cases (empty container arm, overlapping arm, literal-vs-primitive) - class identity / generic type_args now on value_type.class_ty (not the class_value payload); media kind on value_type.media.kind - union-arm and empty-container rows/notes updated for arm fidelity; deviation flag records typed-producer vs Python's dynamic SelectDefault ref-java-outbound-decoding.md - union-variant decoding: honors canonical selected_option_index (field 8) first, structural armMatchesValue only as fallback; deviation flag updated Docs-only; verified against ProtoWriter/ProtoReader/TypeRegistry/emit.rs and the engine (bridge_ctypes value_decode, bex_engine conversion). Full battery green: sdkgen_java 92 + clippy, baml_bridge gradle test+jar, sdk_test_java nextest 10/10 (+1 skip).
a0eab2a to
14816da
Compare
|
Important Review skippedNo new commits to review since the last review. ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThe Java bridge references now document node-level inbound type annotations, contextual generic reification, empty-container union fidelity, and Rust decoding mappings. Outbound union decoding documentation specifies canonical index-based arm selection with structural matching fallback. ChangesJava bridge reference updates
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@baml_language/sdks/agent-docs/bridge-ref/ref-java-inbound-encoding.md`:
- Around line 200-212: Update the sparse value_type documentation around the
“value_type annotation” sections to match encodeInboundValue: when selectedArm
is true, contextualType is promoted to exactNodeType and the selected arm is
annotated eagerly, including unambiguous primitive types. Keep the three
canonical ambiguity cases as explanations of when the annotation is necessary,
rather than limiting emission to those cases, and apply the same wording
consistently in the referenced sections.
- Around line 584-593: The inbound wire-payload documentation should separate
class identity from enum identity: keep the class FQN and generic-argument
description scoped to InboundValue.value_type, then add a distinct clause
explaining that enum instances use the InboundEnumValue oneof payload with its
name and variant fields.
- Around line 294-307: Update the documentation paragraph describing non-generic
or unbound instances so it does not claim byte identity with pre-generics
encoding; state that the output is byte-identical to post-#4087 non-generic
encoding, or remove the byte-level claim. Keep the existing explanation of empty
type arguments and node-level value_type behavior unchanged.
In `@baml_language/sdks/agent-docs/bridge-ref/ref-java-outbound-decoding.md`:
- Around line 549-552: Update decodeUnionWithDesc to preserve the raw
selectedOptionIndex returned by extractUnionSelectedType when wrapping the
wire-selected union arm; avoid recomputing the arm via
arms.indexOf(selectedType), which collapses duplicate or equivalent types to the
first declaration. Keep structural armMatchesValue fallback behavior unchanged
when no wire index is present.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: b7a7135a-b8ad-4b0b-a783-956012e08493
📒 Files selected for processing (2)
baml_language/sdks/agent-docs/bridge-ref/ref-java-inbound-encoding.mdbaml_language/sdks/agent-docs/bridge-ref/ref-java-outbound-decoding.md
Binary size checks passed✅ 7 passed
Generated by |
Four corrections from CodeRabbit on #4153, each verified against the encoder/decoder before applying: 1. Eager arm annotation (inbound). ProtoWriter sets exactNodeType = selectedArm ? contextualType : null (:229) and the tail (:349-368) writes value_type for EVERY representable selected-arm node, not only shape-ambiguous ones — an `int | string` Arm0(7L) still writes value_type: int. Reword the "value_type annotation" section and the union table row: annotation is eager within a selected-arm subtree; the three canonical cases explain WHY the channel exists, not a per-node gate. The sparseness is at the boundary (non-arm containers stay bare). 2. Byte-identical claim (inbound). writeClassType always writes value_type.class_ty.name (:402-411); ceae8ea relocated ALL class identity off InboundClassValue.class_ty, so a non-generic class's wire is NOT byte-identical to the pre-migration encoding. Scope the claim to "the generics-reification channel adds nothing" and drop the cross-migration byte-identical assertion (deviation + practical-consequences bullet). 3. Enum identity (inbound). Enum FQN + variant ride InboundEnumValue.name/value, not value_type. Split the practical- consequences clause that lumped enum FQNs into value_type. 4. Descriptor-path union decode (outbound). decodeUnionWithDesc resolves the arm by TYPE (arms.indexOf(selectedType), :1219), not the raw wire index. Clarify that this is unambiguous because canonical union members are structurally distinct (baml_type::normalize canonicalize_union sort+dedups, normalize.rs:1601) — so the string|string duplicate-arm scenario is unrepresentable, and value-resolution is robust to any wire/descriptor order difference. Docs-only; no runtime/codegen change.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
baml_language/sdks/agent-docs/bridge-ref/ref-java-inbound-encoding.md (1)
372-374: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winFix the empty-container arm example.
Arm1(int[])is inconsistent withint[] | string[]:int[]is the first-declared arm, so this cannot demonstrate selecting a non-first arm. Usestring[] | int[], or change it toArm0(int[])and remove the “instead of the first-declared arm” wording.🛠️ Proposed fix
-- **Empty container arm** (`int[] | string[]`, empty `Arm1(int[])`): the list +- **Empty container arm** (`string[] | int[]`, empty `Arm1(int[])`): the list🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@baml_language/sdks/agent-docs/bridge-ref/ref-java-inbound-encoding.md` around lines 372 - 374, Correct the empty-container arm example so it demonstrates selection of a non-first arm: change the union ordering to string[] | int[] while retaining Arm1(int[]), or use Arm0(int[]) and remove the claim that it differs from the first-declared arm. Keep the surrounding explanation consistent with the chosen correction.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@baml_language/sdks/agent-docs/bridge-ref/ref-java-inbound-encoding.md`:
- Around line 372-374: Correct the empty-container arm example so it
demonstrates selection of a non-first arm: change the union ordering to string[]
| int[] while retaining Arm1(int[]), or use Arm0(int[]) and remove the claim
that it differs from the first-declared arm. Keep the surrounding explanation
consistent with the chosen correction.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 520ddd30-7084-438c-a309-f6eeff14cb85
📒 Files selected for processing (2)
baml_language/sdks/agent-docs/bridge-ref/ref-java-inbound-encoding.mdbaml_language/sdks/agent-docs/bridge-ref/ref-java-outbound-decoding.md
🚧 Files skipped from review as they are similar to previous changes (1)
- baml_language/sdks/agent-docs/bridge-ref/ref-java-outbound-decoding.md
Summary
Parity investigation of the Java bridge against the new inbound
value_typeABI annotation introduced in ceae8ea (#4087). Finding: #4087 already implemented the Java encoder/decoder support and the empty-list arm-fidelity test contract end-to-end — the one gap it left was the Javabridge-refdocs, which still describe the pre-migration wire shape. This PR is that docs parity fix. No runtime/codegen change was warranted.What #4087 already did (verified, no change needed)
value_typefor the selected arm exactly in the ambiguity cases:BamlTypedValue(value, descriptor)for top-level args (emit.rs), parallelfieldDescs[]for class fields, item/value types for containers (ProtoWriter.encodeInboundValue). Covers empty-container arms, overlapping arms, and literal-vs-primitive. Java registers theRejectambiguity policy (a typed producer), so it annotates rather than leaning on Python's dynamicSelectDefault.value_typeonly for class identity and media kind; Java matches both (now onvalue_type.class_ty/value_type.media.kind) and additionally annotates selected union arms — the extra information the sparse channel exists to carry for a typed producer.ProtoReaderhonors the new canonicalselected_option_index(field 8), falling back to structuralarmMatchesValueonly when absent.TestUnions.test_round_trip_str_or_int_listalready asserts full arm fidelity (empty viaArm0staysArm0, viaArm1staysArm1).Docs brought back to truth
ref-java-inbound-encoding.md: addvalue_type = 1to theInboundValueproto; new "Thevalue_typeannotation" section (how Java threads the contextual union); class identity / generic args now onvalue_type.class_ty, media kind onvalue_type.media.kind; union-arm + empty-container rows/notes; typed-producer-vs-dynamic deviation flag.ref-java-outbound-decoding.md: union-variant decoding documents theselected_option_index-first resolution.Test plan (full battery, cold builds)
bridge_ctypesvalue_decode: 18 passedbex_engineconversion (union arm selection): 71 passedsdkgen_java: 92 passed;cargo clippy -p sdkgen_java: cleanbaml_bridgegradletest jar: BUILD SUCCESSFULcargo nextest run -p sdk_test_java: 10 passed, 1 skipped — all four fixture suites (docstrings_etc, function_calls, llm_functions, type_shapes), each javac + junitDocs-only change; no fixture/test counts changed.
Summary by CodeRabbit
value_type, class identity and reified generic type args, and improved union/empty-container annotation rules.selected_option_indexwhen available, with clear structural fallback, null handling, and error behavior.