///|
/// Plan the existing generation backends from a bounded captured model. Logical
/// unit identity never becomes a filesystem path or changes during decoding.
pub fn Engine::plan_retained_generation(
self : Engine,
unit : @data.IRUnit,
backend : String,
output_root : String,
options~ : Json = Json::object(Map([])),
policy~ : BuildPolicy = SourceOnly,
project~ : String = "generated",
) -> Plan raise {
unit.validate()
// The plan owns its accepted value. The maintained lossless codec snapshots
// nested IR maps and opaque Ion context under the same default budgets.
let registry = @data.Registry::new()
let unit = registry.open_checkpoint("ion-binary", registry.checkpoint(unit))
if !self.generators.contains(backend) {
raise @configuration.Invalid("generation.unsupported_target: " + backend)
}
// Elm has no rich source-context sidecar. Reuse the established checked
// semantic projection boundary before its generator can discard that context.
if backend == "elm" {
ignore(registry.encode("morphir-json", unit))
}
let files = Map::from_array([
(
"morphir.toml", "[project]\nname='retained'\nsource_directory='src'\n[frontend]\nlanguage='ir-json'\n",
),
("src/model.json", ""),
])
let document = @configuration.from_json({
"project": { "name": project },
"workspace": { "out_dir": output_root },
"pipeline": {
"backend": backend,
"validation": match policy {
SourceOnly => "source-only"
Required(_) => "required"
},
"target": match policy {
SourceOnly => "wasm"
Required(target) => target
},
},
"backends": Json::object(Map::from_array([(backend, options)])),
})
let workspace = @workspace.discover(
{ files, directories: ["", "src"], },
overlay=document,
)
let plan = self.plan(Host::memory(files), workspace, Request::new())
{ ..plan, jobs: plan.jobs.map(job => { ..job, retained_unit: Some(unit), }), }
}