Kibo¶
Kibo is the code generator that transforms DSM definitions into C++ and Python infrastructure code.
Overview¶
DSM Definitions → Kibo → Generated Code
(273 lines) ↓ (15,592 lines)
Templates
Kibo uses StringTemplate files (.stg) to generate code from DSM models.
Synopsis¶
java -jar kibo-1.2.0.jar \
-c [converter] \
-n [namespace] \
-d [definitions.dsmb] \
-t [template] \
-o [output]
Options¶
Option |
Description |
|---|---|
|
Target language: |
|
Namespace for generated files |
|
Path to binary definitions ( |
|
Template directory or file |
|
Output directory or file |
|
Disable output messages |
|
Show help |
|
Show version |
C++ Templates¶
Available template groups in templates/cpp/:
Template |
Generated Files |
Purpose |
|---|---|---|
|
|
Types for enum, struct, concept, club |
|
|
DSM definitions, paths, fields |
|
|
Attachment accessors |
|
|
SQLite persistence layer |
|
|
Binary serialization |
|
|
JSON serialization |
|
|
Viper type mappings |
|
|
Bridge C++ classes (static) ↔ Value (dynamic) |
|
|
Content hashing for values |
|
|
Pure function bindings |
|
|
Remote function call API |
|
|
Stateful pool bindings |
|
|
Remote stateful calls |
|
|
Pool exposing attachment API |
|
|
Python module constants for types and paths |
|
|
Random value generation |
|
|
Unit tests |
|
|
Test application entry points |
Python Templates¶
Available template groups in templates/python/:
Template |
Generated File |
Purpose |
|---|---|---|
|
|
Package initialization |
|
|
Viper type definitions |
|
|
Concept, structure, enum classes |
|
|
Attachment API wrappers |
|
|
Database attachment API wrappers |
|
|
Field path constants |
|
|
Type mappings |
|
|
Function pool wrappers |
|
|
Stateful pool wrappers |
|
|
Remote function call wrappers |
|
|
Remote stateful call wrappers |
|
|
Wheel configuration |
Usage Examples¶
Generate All C++ Features¶
# From generate.py
templates = [
'Model', 'Data',
'Attachments', 'Stream', 'Json',
'Database',
'ValueType', 'ValueCodec', 'ValueHasher',
'Fuzz', 'Test'
]
for template in templates:
subprocess.run([
'java', '-jar', 'kibo-1.2.0.jar',
'-c', 'cpp',
'-n', 'MyApp',
'-d', 'model.dsmb',
'-t', f'templates/cpp/{template}',
'-o', 'src/MyApp'
])
Generate Python Package¶
subprocess.run([
'java', '-jar', 'kibo-1.2.0.jar',
'-c', 'python',
'-n', 'mymodel',
'-d', 'model.dsmb',
'-t', 'templates/python/package',
'-o', 'python/mymodel'
])
Complete generate.py Example¶
A production-ready script combining all generation steps:
#!/usr/bin/env python3
"""Complete code generation script for a Viper project."""
import subprocess
import argparse
import base64
import zlib
from dsviper import DSMBuilder
# Configuration
JAR = 'tools/kibo-1.2.0.jar'
KIBO = ['java', '-jar', JAR]
TEMPLATES_CPP = 'templates/cpp'
TEMPLATES_PY = 'templates/python/package'
def check_report(report):
"""Exit on parse errors."""
if report.has_error():
for err in report.errors():
print(repr(err))
exit(1)
def generate_cpp(namespace, dsmb, template, output):
"""Generate C++ code from a template."""
subprocess.run(KIBO + [
'-c', 'cpp', '-n', namespace,
'-d', dsmb, '-t', f'{TEMPLATES_CPP}/{template}',
'-o', output
])
def generate_resource(definitions, output):
"""Generate embedded C++ resource."""
blob = definitions.encode()
with open(output, 'w') as f:
f.write(blob.embed("definitions"))
def generate_python(name, dsmb, definitions, output):
"""Generate Python package with embedded definitions."""
subprocess.run(KIBO + [
'-c', 'python', '-n', name,
'-d', dsmb, '-t', TEMPLATES_PY,
'-o', output
])
# Embed definitions as base64
blob = definitions.encode()
encoded = base64.b64encode(zlib.compress(blob))
with open(f'{output}/resources.py', 'w') as f:
f.write(f"B64_DEFINITIONS = {encoded}")
# Parse DSM
builder = DSMBuilder.assemble("definitions/MyApp")
report, dsm_defs, definitions = builder.parse()
check_report(report)
# Save binary definitions
with open("MyApp.dsmb", "wb") as f:
f.write(dsm_defs.encode())
# Generate C++ (standard templates)
for template in ['Model', 'Data', 'Attachments', 'Stream', 'Database',
'ValueType', 'ValueCodec', 'ValueHasher', 'FunctionPool']:
generate_cpp('MyApp', 'MyApp.dsmb', template, 'src/MyApp')
# Generate embedded resource
generate_resource(definitions, 'src/MyApp/MyApp_Resources.hpp')
# Generate Python package
generate_python('myapp', 'MyApp.dsmb', definitions, 'python/myapp')
print("Generation complete!")
Workflow¶
Step 1: Parse and Encode DSM¶
from dsviper import DSMBuilder
# Parse DSM file
builder = DSMBuilder.assemble("model.dsm")
report, dsm_defs, definitions = builder.parse()
# Check for errors
if report.has_errors():
print(report.errors())
exit(1)
# Save binary format
with open("model.dsmb", "wb") as f:
f.write(dsm_defs.encode().encoded())
Step 2: Generate Embedded Definitions¶
# Generate C++ resource for Definitions.cpp
blob = definitions.encode()
with open("Resources.hpp", "w") as f:
f.write(blob.embed("definitions"))
Step 3: Run Kibo¶
java -jar kibo-1.2.0.jar -c cpp -n MyApp -d model.dsmb -t templates/cpp/Data -o src/
Step 4: Compile and Link¶
The generated code requires linking against the Viper runtime.
Amplification Metrics¶
Project |
DSM Lines |
Generated Lines |
Ratio |
|---|---|---|---|
Graph Editor |
273 |
15,592 |
57x |
Raptor Editor |
2,003 |
126,182 |
63x |
Kibo typically generates 57-63x more code than the input DSM.
What’s Next¶
IDE Integration - VS Code and JetBrains
Templates - Understanding templated features