Code Generator (tqlgen)
April 22, 2026 · View on GitHub
import "github.com/CaliLuke/go-typeql/tqlgen" -- pkg.go.dev
tqlgen generates Go struct definitions from TypeQL schema files. It produces structs with gotype.BaseEntity/BaseRelation embeds and typedb:"..." tags, ready for use with the ORM.
When parsing schema annotations, tqlgen decodes escaped string literals used in TypeQL string values, including unicode escapes such as \u0041 and \u{1F600} in @regex(...) and @values(...).
CLI Usage
go run github.com/CaliLuke/go-typeql/tqlgen/cmd/tqlgen \
-schema schema.tql \
-out models_gen.go \
-pkg models
Flags
| Flag | Default | Description |
|---|---|---|
-schema | (required) | Path to TypeQL .tql schema file |
-out | stdout | Output file path |
-pkg | models | Go package name |
-acronyms | true | Apply Go naming conventions for acronyms (ID, URL, API, etc.) |
-skip-abstract | true | Skip abstract types in output |
-inherit | true | Propagate parent owns to children |
-enums | true | Generate string constants from @values constraints |
-registry | false | Generate a schema registry instead of Go structs |
-dto | false | Generate DTO structs (Out/Create/Patch) for HTTP APIs |
-id-field | ID | ID field name in Out DTOs |
-strict-out | false | Make required fields non-pointer in Out structs |
-skip-relation-out | false | Skip generating relation Out structs |
-schema-version | (none) | Embed a schema version string in the generated header |
-version | -- | Print tqlgen version and exit |
What It Generates
Given a TypeQL schema, tqlgen produces:
- Go structs embedding
gotype.BaseEntityorgotype.BaseRelation typedb:"..."tags with attribute names,key,unique, andcard=options- Role player fields with
role:nametags - Pointer types for optional fields (non-key attributes without explicit cardinality)
time.Timeimports when datetime attributes are present- String constants from
@valuesconstraints (when-enums=true) - A
// Code generated by tqlgen. DO NOT EDIT.header
Example
Input (schema.tql)
define
attribute name, value string;
attribute email, value string;
attribute age, value long;
attribute start_date, value datetime;
entity person,
owns name @key,
owns email @unique,
owns age,
plays employment:employee;
entity company,
owns name @key,
plays employment:employer;
relation employment,
relates employee,
relates employer,
owns start_date;
Output
// Code generated by tqlgen. DO NOT EDIT.
package models
import (
"github.com/CaliLuke/go-typeql/gotype"
"time"
)
type Person struct {
gotype.BaseEntity
Name string `typedb:"name,key"`
Email *string `typedb:"email,unique"`
Age *int64 `typedb:"age"`
}
type Company struct {
gotype.BaseEntity
Name string `typedb:"name,key"`
}
type Employment struct {
gotype.BaseRelation
Employee *Person `typedb:"role:employee"`
Employer *Company `typedb:"role:employer"`
StartDate *time.Time `typedb:"start_date"`
}
Enum Constants
When an attribute has @values constraints, tqlgen generates typed string constants (enabled by default, disable with -enums=false):
attribute status, value string @values("proposed", "accepted", "rejected");
Generates:
// Status values for the "status" attribute.
const (
StatusProposed = "proposed"
StatusAccepted = "accepted"
StatusRejected = "rejected"
)
Registry Mode
The -registry flag generates a schema registry file instead of Go structs. This is useful for applications that need runtime access to schema metadata (type constants, parent maps, attribute lookups, relation schemas) without reflection.
tqlgen -schema schema.tql -registry -out registry_gen.go -pkg graph
The registry file contains:
- Type constants —
const TypePerson = "person",const RelEmployment = "employment" - Entity parents —
EntityParentsmap for inheritance lookups - Entity attributes —
EntityAttributesmap of type → sorted owned attributes - Entity keys —
EntityKeysmap of type →@keyattribute names - Abstract tracking —
EntityAbstractandRelationAbstractmaps - Attribute value types —
AttributeValueTypesmap of attribute → TypeDB value type - Attribute enum values —
AttributeEnumValuesmap for@values-constrained attributes - All attribute types —
AllAttributeTypessorted slice - Relation schemas —
RelationSchemamap with N roles (not limited to binary) and player types - Relation attributes —
RelationAttributesmap of relation → owned attributes - Relation parents —
RelationParentsmap for relation inheritance - Sorted type lists —
AllEntityTypesandAllRelationTypesslices - Schema hash —
SchemaHashconstant (SHA256 prefix) when schema text is provided - Convenience functions —
GetEntityKeys(),IsAbstractEntity(),IsAbstractRelation(),GetRolePlayers(),GetEntityAttributes(),GetRelationAttributes()
Programmatic usage:
data := tqlgen.BuildRegistryData(schema, tqlgen.RegistryConfig{
PackageName: "graph",
UseAcronyms: true,
SkipAbstract: true,
Enums: true,
SchemaText: schemaStr, // optional: enables SchemaHash in output
})
err := tqlgen.RenderRegistry(os.Stdout, data)
DTO Mode
The -dto flag generates Out/Create/Patch struct variants for HTTP API layers:
tqlgen -schema schema.tql -dto -out dto_gen.go -pkg dto
For each non-abstract entity Foo:
FooOut— response struct withID,Type, and all attribute fieldsFooCreate— create request with required fields non-pointer (@key,@unique,@card(1+)) and optional fields as*TFooPatch— partial update with all fields as*T(nil = don't update)
For each non-abstract relation Bar:
BarOut— response with role player IIDs and owned attributesBarCreate— request with role player IDs and owned attributes
Plus Go interfaces (EntityOut, EntityCreate, EntityPatch, RelationOut, RelationCreate) with TypeName() string methods.
DTO Configuration
dtoCfg := tqlgen.DTOConfig{
PackageName: "dto",
UseAcronyms: true,
SkipAbstract: true,
StrictOut: false, // true = required fields non-pointer in Out
IDFieldName: "ID",
ExcludeEntities: []string{"internal-counter"},
SkipRelationOut: false,
// Shared base structs for entity hierarchies
BaseStructs: []tqlgen.BaseStructConfig{{
SourceEntity: "artifact",
BaseName: "BaseArtifact",
InheritedAttrs: []string{"name", "status"},
}},
// Per-field overrides
EntityFieldOverrides: []tqlgen.EntityFieldOverride{{
Entity: "person", Field: "email", Variant: "create",
Required: boolPtr(false),
}},
}
data := tqlgen.BuildDTOData(schema, dtoCfg)
err := tqlgen.RenderDTO(os.Stdout, data)
Programmatic API
For use in tooling or migration workflows, you can parse schemas and render programmatically:
schema, err := tqlgen.ParseSchemaFile("schema.tql")
// or from a string:
schema, err := tqlgen.ParseSchema(schemaStr)
// Propagate parent owns to children
schema.AccumulateInheritance()
// Render to Go source
err = tqlgen.Render(os.Stdout, schema, tqlgen.DefaultConfig())
The ParsedSchema struct contains Attributes, Entities, Relations, Functions, and Structs slices. It is also used by the migration system (see Schema) for diffing against the live database schema.
Inheritance Propagation
AccumulateInheritance() merges parent owns/plays clauses into children, so each child struct has the complete set of fields. Child definitions override parent ones for the same attribute name. This is enabled by default in the CLI (-inherit=true).
Comment Annotations
ExtractAnnotations parses comment annotations above type definitions. Three syntaxes are supported:
# @key value— space-separated# @key(value)— parenthesized# @key— bare flag (empty string value)
annots := tqlgen.ExtractAnnotations(schemaText)
// annots["person"]["description"] = "A person entity"
// annots["project"]["prefix"] = "PROJ"
// annots["secret"]["internal"] = ""
Naming Conventions
tqlgen converts kebab-case and snake_case TypeDB names to PascalCase Go names. With -acronyms=true (the default), common Go acronyms are uppercased: user-id becomes UserID, api-url becomes APIURL.
The recognized acronyms are: ID, URL, UUID, API, HTTP, IID, NF.
Supported TypeQL Features
attributedefinitions with value types (string, long, double, boolean, datetime)entityandrelationdefinitions withsub(inheritance)@abstract,@key,@unique,@card(...)annotationsrelateswith optionalas(role override) and@card(...)playsclauses (used for role player type resolution)@regex,@rangeannotations (parsed but not emitted as Go constraints)@valuesannotations (parsed; emitted as string constants when-enums=true)- Escaped TypeQL string literals in annotations, including unicode escape forms
\uXXXXand\u{...} fundefinitions (parsed for signature extraction, not emitted as Go code)structdefinitions (parsed for field extraction)- Comment annotations (
# @key value,# @key(value),# @keyabove type definitions)
The parser uses participle/v2. TypeQL functions are stripped via pre-processing (truncate at first fun) rather than being parsed by the grammar.