Problem
{version}-structures.json (from mendixmodellib) contains the complete Mendix metamodel schema: type names, storage names, properties, defaults, inheritance, array markers, required fields. This is the single source of truth for how BSON should be structured.
Currently, this information is manually duplicated across dozens of files:
| Information |
In structures.json |
Manually maintained in code |
| Type names ($Type) |
qualifiedName + storageName |
~200 raw string literals in parser/writer |
| Property field names |
properties[].storageName |
Fallback chains like []string{"sortItemList", "NewSortings", "Sortings"} |
| Required fields |
properties[].required |
Hardcoded in writer functions |
| Array markers |
properties[].storageListType |
Hardcoded int32(2) vs int32(3) |
| Default values |
defaultSettings |
Hardcoded, often copied from Studio Pro |
| Type hierarchy |
allCompatibleTypes |
Manual switch/case coverage |
| Widget type info |
Type + property definitions |
3 separate maps in theme_reader.go (100+ entries) |
This causes real bugs: wrong $Type strings → TypeCacheUnknownTypeException (MPR unreadable in Studio Pro), wrong array markers → silent data corruption, incomplete parser coverage → lost data on roundtrip.
Proposal: Data-Driven Metamodel
Treat structures.json as a runtime data source, not just a codegen input. The existing cmd/codegen infrastructure already parses this format — extend it to unlock multiple layers of value.
Layer 1: Compile-Time Safety (constants)
Generate sdk/mpr/bsontype/ package with:
- $Type constants organized by namespace — typos become compiler errors
- StorageName ↔ QualifiedName bidirectional map — eliminates manual mapping (e.g.,
CreateObjectAction ↔ CreateChangeAction)
- Property storage name lookup — eliminates fallback chains
Layer 2: Automated Validation (find bugs without running)
- Parser coverage checker — compare
allCompatibleTypes against parser switch cases, report unhandled types
- Writer required-field checker — verify all
required: true properties are emitted
- Array marker validator —
storageListType tells us the correct marker value, compare against hardcoded values in writer code
Layer 3: Code Generation (reduce hand-written code)
- Default value templates — generate writer defaults from
defaultSettings, no need to extract from Studio Pro
- Widget type registry — generate unified registry replacing the 3 separate maps in theme_reader.go
- DESCRIBE output scaffolding — generate property listing from type definitions
Layer 4: Multi-Version Runtime (version-aware operations)
Embed multiple versions via go:embed, load at runtime based on MPR's Mendix version:
- Version diff — compare two structures.json versions, output: added types, removed properties, changed defaults
- Compatibility checking — MDL script references a type that doesn't exist in the project's Mendix version → actionable error before writing BSON
- Migration guidance — "upgrading from 10.0 to 11.0, these types/properties changed"
Version matching strategy: highest embedded version ≤ project version (conservative — never introduces types the project version doesn't support).
Implementation Path
- Extend
cmd/codegen to generate constants package + registry loader (requires structures.json access)
- Embed 3-4 version snapshots (9.24, 10.0, 10.21, 11.6) for runtime multi-version support
- Incrementally migrate parser/writer to use constants (one domain per PR, no logic changes)
- Add validation commands:
mxcli check --metamodel to surface coverage gaps
Why This Needs Core Developer Access
The structures.json files are in libs/mendixmodellib/reflection-data/ (internal npm package, gitignored). The codegen infrastructure already consumes them — this proposal extends their use from "generate Go structs" to "drive the entire type system."
Problem
{version}-structures.json(frommendixmodellib) contains the complete Mendix metamodel schema: type names, storage names, properties, defaults, inheritance, array markers, required fields. This is the single source of truth for how BSON should be structured.Currently, this information is manually duplicated across dozens of files:
qualifiedName+storageNameproperties[].storageName[]string{"sortItemList", "NewSortings", "Sortings"}properties[].requiredproperties[].storageListTypeint32(2)vsint32(3)defaultSettingsallCompatibleTypesThis causes real bugs: wrong $Type strings →
TypeCacheUnknownTypeException(MPR unreadable in Studio Pro), wrong array markers → silent data corruption, incomplete parser coverage → lost data on roundtrip.Proposal: Data-Driven Metamodel
Treat structures.json as a runtime data source, not just a codegen input. The existing
cmd/codegeninfrastructure already parses this format — extend it to unlock multiple layers of value.Layer 1: Compile-Time Safety (constants)
Generate
sdk/mpr/bsontype/package with:CreateObjectAction↔CreateChangeAction)Layer 2: Automated Validation (find bugs without running)
allCompatibleTypesagainst parser switch cases, report unhandled typesrequired: trueproperties are emittedstorageListTypetells us the correct marker value, compare against hardcoded values in writer codeLayer 3: Code Generation (reduce hand-written code)
defaultSettings, no need to extract from Studio ProLayer 4: Multi-Version Runtime (version-aware operations)
Embed multiple versions via
go:embed, load at runtime based on MPR's Mendix version:Version matching strategy: highest embedded version ≤ project version (conservative — never introduces types the project version doesn't support).
Implementation Path
cmd/codegento generate constants package + registry loader (requires structures.json access)mxcli check --metamodelto surface coverage gapsWhy This Needs Core Developer Access
The structures.json files are in
libs/mendixmodellib/reflection-data/(internal npm package, gitignored). The codegen infrastructure already consumes them — this proposal extends their use from "generate Go structs" to "drive the entire type system."