Conversation
Replaces the hand-written JSON schema files under scripts/schema/ with a build-time pipeline that emits a single config-schema.json from reflect-cpp-annotated C++ types under palace/schema/types/. Descriptions are transcribed verbatim from PR #716 so generated docs stay in sync with the configuration structs by construction. - palace/schema/utils/: schema-generator utilities (reflect-cpp post-emit passes for defaults, required pruning, additionalProperties, TaggedUnion tag descriptions, anyOf to oneOf rewrite). - palace/schema/types/: annotated mirrors of Palace's config structs. - palace/schema/emit_schema.cpp: standalone helper invoked by CMake to produce build/generated/schema/config-schema.json, which is then embedded via the existing embed_schema.cmake helper. - cmake/EmbedSchema.cmake: rewritten to drive palace_emit_schema. - palace/utils/jsonschema.cpp: drop the external-$ref branch; the single-file schema resolves refs in-document via $defs. - scripts/schema/: hand-written per-section JSONs removed. Bumps CMAKE_CXX_STANDARD to 20 (reflect-cpp floor). Runtime config parsing is untouched in this phase.
Closes the three gaps between Palace's generated schema and PR #716's hand-written version: - Per-enum-value descriptions: `PALACE_SCHEMA_ENUM(E, (V, "desc"), ...)` declares an `enum class` and the matching `enum_descriptions<E>` specialization in one place; the post-emit `inject_enum_descriptions` pass rewrites `{"type":"string","enum":[...]}` to `{"oneOf":[{"const":V,"description":"..."},...]}`. Empty descriptions opt an enumerator out of the prose (bare `{"const": V}`). - x-palace-advanced / x-palace-deprecated: new `PALACE_SCHEMA_DESC_ADVANCED` / `_DEPRECATED` macros attach the flag at the field declaration via a `FieldFlagTag<"FieldName">`-keyed hidden friend; the walker finds it via ADL on the enclosing struct and the `inject_custom_keywords` pass stamps `x-palace-<flag>: true` onto the matching property. 53 advanced + 4 deprecated fields now land correctly. - Root-level conditionals: emit_schema.cpp parses a verbatim copy of PR 716's `allOf`/`if`/`then` block (driven/eigenmode/transient implying the matching `Solver.<Mode>` requirement) and splices it into the root. The block isn't expressible from the C++ types alone.
Introduce `version.hpp` with a `schema_version` constant following the SchemaVer format (MODEL-REVISION-ADDITION), decoupling schema compatibility tracking from `PROJECT_VERSION`. Remove the `PALACE_VERSION` compile definition from the emit_schema target and use the new constant directly instead.
…om $defs - cmake/EmbedSchema.cmake: after palace_emit_schema runs, copy the generated config-schema.json into scripts/schema/ via copy_if_different. The copy is part of the default build (palace_schema_file ALL target), so the committed schema stays in sync with the annotated types. Downstream tooling (docs, Julia validator) consumes the stable scripts/schema/ path; embedding still reads the build-tree copy. The existing check-config GitHub Actions job validates example configs against this file unchanged. - SchemaOptions gains `defs_prefix`. When non-empty, a final `strip_defs_prefix` pass renames each `$defs` entry and rewrites every matching `$ref` string to drop the prefix. emit_schema.cpp sets it to `"palace__schema__"`, so the published schema carries short names (`ProblemData`, `LinearSolverData`, ...) instead of reflect-cpp's fully-qualified `palace__schema__ProblemData`. - scripts/schema/config-schema.json is the baseline generated output — committed alongside the types so `./scripts/validate-config` and ValidateConfig.jl work out of the box.
Replace the previous "prune unneeded from required" heuristic with an
explicit allow-list: fields marked PALACE_SCHEMA_DESC_REQUIRED (and
PALACE_SCHEMA_TAG for tagged-union discriminators) are the only entries
in each `$defs` required array. The marker is expressed as a subtype of
rfl::Description — DescRequired / DescAdvanced / DescDeprecated — so
detection is a pure compile-time type trait, with no hidden-friend or
ADL tricks and no PALACE_SCHEMA_SELF boilerplate on the struct.
Also:
- Drop `default` emission on $ref-bearing properties; the referenced
$defs entry already carries defaults on its own fields.
- Flatten rfl::Validator-induced `allOf: [{minimum,type},{maximum,type}]`
into a single `{minimum, maximum, type}` body.
- Introduce schema_oneof_required<T> trait and inject_oneof_required
pass; specialize for LumpedPort / SurfaceCurrent to match PR 716's
"exactly one of Attributes or Elements" item constraint.
- Remove std::optional usage from annotated types; every field has a
concrete default, optional-ness is expressed only through the
absence of PALACE_SCHEMA_DESC_REQUIRED.
- Strip the `Data` suffix from all struct names (Boundary, Model,
LumpedPort, ...); three collisions with existing enums
(SurfaceFlux, InterfaceDielectric, LinearSolver) are renamed to
SurfaceFluxProbe, DielectricInterface, LinearSolverConfig.
The generated config-schema.json reflects all of the above: required
arrays now match PR 716 per-type, every validator property is flat,
LumpedPort / SurfaceCurrent carry the oneOf mutex, and no $ref
property carries a default.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Collapses Palace's three disconnected schema sources: the C++ structs, the hand-written JSON schemas under scripts/schema/, and PR #716's annotated schema into one C++ source of truth. The new
palace_emit_schemabinary generatesconfig-schema.jsonat build time fromreflect-cpp-annotatedmirrors of the config structs; the embed pipeline picks up the generated file and bakes it intolibpalacevia the existingembed_schema.cmakehelper. The hand-written schema files are deleted.Descriptions in the annotated types are transcribed verbatim from awslabs/palace#716, so the doc-generator output matches PR #716 by construction. CMAKE_CXX_STANDARD bumps to C++20 (
reflect-cppfloor).Test plan
libpalace+palacebuild clean.palace_emit_schemaproduces a 2655-line schema; embedded header regenerates via the CMake custom command.test/unit/test-schema.cpp(sample configs validate against the embedded schema).scripts/schema/ValidateConfig.jlagainst the build-generated path.docs/generate_config_docs.jlagainst the generated schema. The expected output should match PR 716's committed reference.md modulo trivial ordering.