1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! Code generation — transforms a [`Registry`](crate::Registry) into source code for target
//! languages.
//!
//! Each language has its own submodule (`kotlin`, `csharp`, `swift`, `typescript`) behind a
//! feature flag. The generation pipeline has three layers:
//!
//! - **Generator** ([`CodeGen`]) — top-level entry point that writes a complete output file
//! from a registry.
//! - **Emitter** ([`Emitter`]) — walks the [`Format`](crate::reflection::format::Format) AST
//! inside each [`Container`] and emits the target language equivalent for each node
//! (type declarations, fields, serialization logic, etc.).
//! - **Installer** — (language-specific) scaffolds project files, package manifests, and
//! generated source into an output directory.
//!
//! Shared infrastructure:
//! - [`CodeGeneratorConfig`] — configuration (package name, encoding, custom types, etc.)
//! - [`indent`] — indentation-aware writer
//! - [`module`] — splits a registry by namespace into separate output modules
/// Utility function to generate indented text
/// Modules for code generation that map to Namespaces declared as `#[facet(fg::namespace = "my_namespace")]`
/// Support for code-generation in C#
/// Support for code-generation in Java.
///
/// **Deprecated since 0.16.0:** The Java generator is deprecated. Use the Kotlin generator instead.
/// Support for code-generation in Kotlin
/// Support for code-generation in Swift
/// Support for code-generation in TypeScript
/// Common configuration objects and traits used in public APIs.
use ;
pub use *;
use IndentWrite;
use crate::;
pub const SERDE_NAMESPACE: &str = "serde";
pub const BINCODE_NAMESPACE: &str = "bincode";
// TODO: Consider renaming `CodeGen` → `CodeGenerator` and the per-language
// `CodeGenerator` structs → `KotlinCodeGenerator`, `CSharpCodeGenerator`, etc.
// The current names are confusing: the trait sounds like a utility and the
// struct sounds like the trait.
/// Transforms a [`Registry`] into a complete source file. Each target language provides
/// its own implementation.
/// A borrowed view of a single type definition (struct or enum) from the
/// [`Registry`], ready to be passed to [`Emitter::write`].
/// Emits target-language source code for a single AST node.
///
/// `Emitter` is the core abstraction of the code-generation pipeline. Each target
/// language defines a zero-sized (or near-zero-sized) **language tag** type — e.g.
/// [`csharp::CSharp`], [`kotlin::Kotlin`], [`swift::Swift`], [`typescript::TypeScript`]
/// — and then provides `Emitter<L>` implementations for the AST node types that
/// need to be rendered in that language.
///
/// # Type parameter
///
/// `L` is the **language tag**. It serves two purposes:
///
/// 1. **Dispatch** — A single AST type (e.g. [`Container`], [`Module`](module::Module),
/// `Named<Format>`) can implement `Emitter<L>` once per language, and the compiler
/// resolves the correct implementation from the tag alone.
/// 2. **Configuration** — Language tags carry per-invocation settings such as the
/// target [`Encoding`] (None / Json / Bincode), so implementations
/// can conditionally emit serialization methods.
///
/// # Typical implementors
///
/// | AST node | What it emits |
/// |---|---|
/// | [`Module`](module::Module) | File header: imports, package/namespace declarations |
/// | [`Container`] | A complete type: struct, enum, sealed class, etc. |
/// | `Named<Format>` | A single field / property declaration |
/// | `Format` | An inline type expression (e.g. `List<Int>`, `Optional<String>`) |
/// | `Doc` | Documentation comment (`///`, `/** */`, etc.) |
///
/// # Usage
///
/// Generators ([`CodeGen`] implementations) create an [`IndentedWriter`](indent::IndentedWriter),
/// construct the language tag, and then call `write` on each node in sequence:
///
/// ```rust,ignore
/// let w = &mut IndentedWriter::new(out, IndentConfig::Space(4));
/// let lang = CSharp::new(Encoding::Json);
///
/// Module::new(&config).write(w, lang)?; // header
/// for container in containers {
/// container.write(w, lang)?; // each type
/// }
/// ```