zerodds_lang_rules/decode_java.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3//! The Java column's decoder: [`crate::emit::decode`] bound to the Java
4//! backend.
5//!
6//! The counterpart of [`crate::decode_c`], and the same shape: the walk
7//! is shared and what is left here is the binding plus the one step the
8//! generic walk cannot take — prepending the Table 9 defaulters.
9
10use crate::emit::decode;
11use crate::emit::java::Java;
12use crate::encode::EncodeError;
13use zerodds_ast::{Ast, TypeNode};
14use zerodds_ast_core::Id;
15use zerodds_ast_layout::key::LayoutKey;
16use zerodds_lang_cst::java;
17
18pub use crate::emit::encode::CodecOptions as JavaCodecOptions;
19
20/// The name of the Java decoder function for a type.
21///
22/// zerodds-lint: recursion-depth 1 — this does not recurse. The callee
23/// is `decode::decoder_name::<Java>`; `dds_bounded_recursion` compares only the last
24/// segment of a call path, so it reads as a self-call.
25#[must_use]
26pub fn decoder_name(ast: &Ast, id: Id<TypeNode>) -> String {
27 decode::decoder_name::<Java>(ast, id)
28}
29
30/// Build the Java decoder for every type in the model, under one plan.
31///
32/// # Errors
33/// As [`decode::decoder`], and when a Table 9 defaulter cannot be built.
34pub fn java_decoder(
35 ast: &Ast,
36 key: LayoutKey,
37 options: JavaCodecOptions,
38) -> Result<Vec<java::Member>, EncodeError> {
39 with_defaulters(ast, decode::decoder::<Java>(ast, key, options)?)
40}
41
42/// The Java decoder for the types one root reaches, and no others.
43///
44/// # Errors
45/// As [`java_decoder`].
46pub fn java_decoder_from(
47 ast: &Ast,
48 root: Id<TypeNode>,
49 key: LayoutKey,
50 options: JavaCodecOptions,
51) -> Result<Vec<java::Member>, EncodeError> {
52 with_defaulters(ast, decode::decoder_from::<Java>(ast, root, key, options)?)
53}
54
55/// The Table 9 defaulters, ahead of the decoders that call them.
56///
57/// `java_defaulters_called_by` emits one only for a type a value can
58/// actually go missing at, so nothing it returns is a `static` function
59/// with no caller — which the probe compiles as an error under
60/// `-Xlint:all -Werror`.
61fn with_defaulters(
62 ast: &Ast,
63 decoders: Vec<java::Member>,
64) -> Result<Vec<java::Member>, EncodeError> {
65 let mut out = crate::default_java::java_defaulters_called_by(ast, &decoders)?;
66 out.extend(decoders);
67 Ok(out)
68}