Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ Across open-source XSD generator trackers, certain widely adopted industry schem
- **Extreme Scale & Facet Density**: Massive industrial standards with thousands of types (e.g. NeTEx with 2,400+ types, HL7 CDA with 1,450+ types, UBL with 1,000+ types).
- **Multi-Megabyte Monolithic Schemas**: Massive schema files such as NATO UCI (8.0 MB single file) and HL7 FHIR (2.6 MB).

This corpus ensures PolyXML reliably compiles and generates clean, idiomatic code across all **7 target languages** (Rust, TypeScript, Python, Go, C#, Java, and C++) without crashing or producing conflicting type declarations.
The default validation run checks schema parsing and module ownership. A separate
UCI check generates code and compiles five destination languages; Rust and C++
large-module compilation are tracked in the linked PolyXML issues.

---

Expand Down Expand Up @@ -87,6 +89,7 @@ polyxml-schema-corpus/
│ └── w3c-xmlschema/ # Normative W3C XML Schema definition
├── polyxml.toml # Multi-module workspace configuration (45 modules)
├── runner.py # Automated validation and benchmark harness
├── scripts/check_uci_codegen.py # Bounded UCI generated-code compile check
├── LICENSE # MIT License
├── NOTICE # Standards attribution & third-party copyright notices
└── README.md
Expand All @@ -96,6 +99,20 @@ polyxml-schema-corpus/

## ⚡ Usage

### UCI generated-code compilation

With Python 3.12+, Go, TypeScript (`tsc`), Java, and .NET 8 installed, run:

```bash
python3 scripts/check_uci_codegen.py --bin ../PolyXML/target/debug/polyxml
```

The script generates the four-schema UCI module into a temporary directory,
compiles one language at a time, and uses PolyXML's memory-cap wrapper when it
is available. Select a target with `--lang python` (repeat the option for
several targets). Full Rust and C++ UCI compilation is tracked in
[PolyXML issue #92](https://github.com/polyxml/PolyXML/issues/92).

### 1. Run the Validation & Benchmark Suite

Ensure `polyxml` is installed or compiled in `../PolyXML/target/release/polyxml`:
Expand Down
106 changes: 106 additions & 0 deletions scripts/check_uci_codegen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env python3
"""Generate and compile the UCI module one target at a time.

Rust and C++ are intentionally excluded until PolyXML can split their large
UCI compilation units. This check keeps all output in a temporary directory.
"""

from __future__ import annotations

import argparse
import os
import subprocess
import tempfile
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
SCHEMAS = (
"UCI_Versioning_v2_5_0.xsd",
"UCI_SecurityMarkings_v2_5_0.xsd",
"uci_entity_core.xsd",
"UCI_MessageDefinitions_v2_5_0.xsd",
)
LANGUAGES = ("python", "go", "typescript", "java", "csharp")
OUTPUTS = {"python": "python", "go": "go", "typescript": "ts", "java": "java", "csharp": "csharp"}


def run(command: list[str], *, cwd: Path, timeout: int, memcap: Path) -> None:
command = [str(memcap), *command]
print("$", " ".join(command), flush=True)
env = os.environ.copy()
env.setdefault("POLYXML_MEMCAP_PCT", "35")
env.setdefault("GOMAXPROCS", "2")
result = subprocess.run(command, cwd=cwd, env=env, capture_output=True, text=True, timeout=timeout)
if result.returncode:
raise RuntimeError(
f"command exited {result.returncode}: {' '.join(command)}\n"
+ "\n".join((result.stdout + result.stderr).splitlines()[:25])
)
for line in (result.stdout + result.stderr).splitlines()[-4:]:
print(line)


def manifest(lang: str) -> str:
schemas = ",\n ".join(f'"schemas/defense-uci/{name}"' for name in SCHEMAS)
package = 'package = "org.polyxml.uci"\n' if lang == "java" else ""
return (
'[workspace]\nname = "uci-compile-check"\noutput_base_dir = "generated"\n'
'go_module = "polyxml/uci-check"\n\n'
f'[modules.defense_uci]\nschemas = [\n {schemas},\n]\n\n'
f'[[generate]]\ntarget = "{lang}"\noutput = "{OUTPUTS[lang]}"\n{package}'
)


def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--bin", type=Path, required=True, help="PolyXML CLI executable")
parser.add_argument("--lang", choices=LANGUAGES, action="append", help="Target to check; repeat to select several")
parser.add_argument("--timeout", type=int, default=120, help="Seconds allowed for each command")
args = parser.parse_args()
compiler = args.bin.resolve(strict=True)
selected = args.lang or LANGUAGES
memcap = ROOT.parent / "PolyXML" / "scripts" / "memcap.sh"
if not memcap.is_file():
parser.error(f"memory cap wrapper not found: {memcap}")

with tempfile.TemporaryDirectory(prefix="polyxml-uci-check-") as directory:
work = Path(directory)
(work / "schemas").symlink_to(ROOT / "schemas", target_is_directory=True)
for lang in selected:
print(f"\n== {lang} ==", flush=True)
(work / "polyxml.toml").write_text(manifest(lang))
run([str(compiler), "build", "--config", str(work / "polyxml.toml")], cwd=work, timeout=args.timeout, memcap=memcap)
source = work / "generated" / OUTPUTS[lang] / "defense_uci"
if lang == "python":
command = ["python3", "-m", "py_compile", str(source / "defense_uci.py")]
cwd = work
elif lang == "go":
command = ["go", "test", "./..."]
cwd = work / "generated" / "go"
elif lang == "typescript":
command = ["tsc", "--noEmit", "--skipLibCheck", "--target", "ES2020", str(source / "defense_uci.ts")]
cwd = work
elif lang == "java":
files = sorted(str(path) for path in source.glob("*.java"))
assert files, "no generated Java files"
(work / "java-files.txt").write_text("\n".join(files) + "\n")
classes = work / "java-classes"
classes.mkdir(exist_ok=True)
command = ["javac", "-J-Xmx1500m", "-Xmaxerrs", "10", "-d", str(classes), f"@{work / 'java-files.txt'}"]
cwd = work
else:
project = work / "UciCheck.csproj"
project.write_text(
'<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net8.0</TargetFramework>'
'<EnableDefaultCompileItems>false</EnableDefaultCompileItems></PropertyGroup>'
'<ItemGroup><Compile Include="generated/csharp/defense_uci/*.cs" /></ItemGroup></Project>\n'
)
command = ["dotnet", "build", str(project), "--ignore-failed-sources", "-p:UseSharedCompilation=false"]
cwd = work
run(command, cwd=cwd, timeout=args.timeout, memcap=memcap)
print("\nAll selected UCI targets compiled.")


if __name__ == "__main__":
main()
Loading