tomato·bazeldocs v0 · latest
Docs/Reference/Modules/rules_lang

rules_lang

rules_lang is a Bazel ruleset published to the tomato-bazel registry.

Latest0.5.0
Versions9 · 1 yanked
CategoryBazel rules
MaintainersMatt Marshall
Registryhttps://registry.tbzl.dev/modules/rules_lang/
Sourcegithub.com/tomato-bazel/rules_lang
MODULE.bazelstarlark
bazel_dep(name = "rules_lang", version = "0.5.0")

View source & releases on GitHub ↗

Public Bazel rules for the polyglot universal-IR codec (@rules_lang).

The rule packages (polyglot/, rules/) are public; the engine + AST source stay private in GitLab aion/polyglot. The Lean atlas — the compiled Polyglot.* olean the rules project through — is consumed as a prebuilt, per-arch release asset (//lean:atlas), so consumers (aion, rules_postgres) resolve rules_lang anonymously: no private-source access, no per-consumer token.

Layout

  • polyglot/aion.bzlaion_spec / aion_emit (a Lir spec → target source via the imported atlas’s OfLir.render) + aion_emit_toolchain.
  • polyglot/sql.bzl — SQL parse rules + //polyglot/sql:postgres_toolchain_type (the libpg_query impl is the consumer’s, via rules_postgres).
  • rules/aion.bzl — compat shim re-exporting //polyglot:aion.bzl.
  • lean/lean_imported_library(atlas) over the per-arch release olean + the pinned Lean toolchain hook.

The atlas

Built by the private engine’s release CI and attached to atlas-v<ver> releases here as polyglot_atlas-<os>_<arch>.tar.gz. //lean:atlas.bzl http_archives the arch-matching asset; //lean:atlas exposes it as LeanInfo with no recompile.

Bootstrap status: olean-only core (the aion/sql rules + the atlas import). The tool-invoking rules (rules/typescript, rules/c) are not yet published.

Rules & providers#

Generated with Stardoc from the module's .bzl sources.

from docs/aion.md

Polyglot.Aion — spec → multi-language source emit pipeline (public API).

Architecture (upgraded from the initial macro to a real provider / aspect / toolchain stack — see INTERNAL.md):

  • aion_spec rule — wraps a Polyglot.Core.Lir.Module-producing Lean module in an AionSpecInfo provider.
  • aion_emit_toolchain rule — defines a per-target-language projection (import_module, render_fn, src_files) as an AionEmitToolchainInfo provider. Repos register their own toolchains; no rules_lang edits needed for a new language.
  • aion_emit macro — composes the internal _aion_emit_main_gen rule (which reads both providers and writes the lean Main) with lean_emit (which compiles).
  • aion_spec_aspect — propagates AionSpecInfo through dep graphs for additional consumers (doc-gen, fixture-validation, metrics).

Default usage (point at a registered toolchain by label):

load("@rules_lang//rules:aion.bzl", "aion_spec", "aion_emit")

aion_spec(
    name   = "logger_spec",
    srcs   = [
        "LoggerSpec.lean",                    # builds loggerModule
        "LoggerEmit/LoggerEmit.lean",         # catalog
    ],
    module = "Aion.V0.Logger.LoggerSpec",
    symbol = "loggerModule",
)

aion_emit(
    name   = "logger_ts",
    spec   = ":logger_spec",
    target = "@rules_lang//polyglot:typescript_aion_emit_toolchain",
    out    = "logger.ts",
    deps   = LAKE_PACKAGES,
)

Shortcut: target accepts the bare language name "typescript" / "sql" / "python" / "rust" and resolves to the corresponding @rules_lang//polyglot:<lang>_aion_emit_toolchain label. Custom toolchains use an explicit label.

Adding a new target language (in any repo):

aion_emit_toolchain(
    name = "haskell_aion_emit_toolchain",
    language = "haskell",
    import_module = "Polyglot.Haskell",
    render_fn = "Polyglot.Haskell.OfLir.render",
    src_files = [
      "@polyglot_ast//:Polyglot/Core/Lir.lean",
      "@polyglot_ast//:Polyglot/Core.lean",
      "@polyglot_ast//:Polyglot/Haskell/OfLir.lean",
    ],
)

Then use target = ":haskell_aion_emit_toolchain" (or its full label from another package).

aion_emit_toolchain

load("@rules_lang//polyglot:aion.bzl", "aion_emit_toolchain")

aion_emit_toolchain(name, atlas, import_module, language, render_fn)

Defines a per-target-language projection for aion_emit. Each language registers one of these; aion_emit(target = ":<tc>", ...) consumes it via the provider. Adding a new target language is a new aion_emit_toolchain declaration — no rules_lang edits needed.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
atlasThe imported polyglot atlas (a lean_imported_library over the prebuilt olean): provides Core.Lir + the language’s Render/OfLir as compiled oleans, no source recompile. Forwarded as LeanInfo so aion_emit’s lean_emit deps on it.Labelrequired
import_moduleLean module the generated Main imports to reach the lowering (e.g. Polyglot.Typescript).Stringrequired
languageHuman-readable language identifier (e.g. typescript, sql).Stringrequired
render_fnFully-qualified Lean function name Lir.Module → String (e.g. Polyglot.Typescript.OfLir.render).Stringrequired

aion_spec

load("@rules_lang//polyglot:aion.bzl", "aion_spec")

aion_spec(name, srcs, module, symbol)

Wraps a set of Lean files producing a Polyglot.Core.Lir.Module into an AionSpecInfo-bearing target. Consumers like aion_emit, doc-gen, fixture-validation, etc. read the provider.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
srcsLean files. Must include the module defining the spec_symbol Lir.Module value and any catalog modules it imports.List of labelsrequired
moduleFully-qualified Lean module path housing the Lir.Module value (e.g. Aion.V0.Logger.LoggerSpec).Stringrequired
symbolName of the Lir.Module value within that module (e.g. loggerModule).Stringrequired

AionEmitToolchainInfo

load("@rules_lang//polyglot:aion.bzl", "AionEmitToolchainInfo")

AionEmitToolchainInfo(import_module, render_fn, language)

Toolchain config for projecting a Lir.Module to one specific target language.

FIELDS

NameDescription
import_moduleLean module the generated Main imports to reach the lowering (e.g. Polyglot.Typescript).
render_fnfully-qualified Lean function name Lir.Module → String (e.g. Polyglot.Typescript.OfLir.render).
languagehuman-readable language identifier (e.g. typescript, sql) — surfaced in progress messages.

AionSpecInfo

load("@rules_lang//polyglot:aion.bzl", "AionSpecInfo")

AionSpecInfo(srcs, module, symbol)

Information about an aion_spec target — a Lean module producing a Polyglot.Core.Lir.Module.

FIELDS

NameDescription
srcsdepset of .lean files (the spec module + any catalog modules it imports).
modulefully-qualified Lean module path housing the Lir.Module value (e.g. Aion.V0.Logger.LoggerSpec).
symbolname of the Lir.Module value within that module (e.g. loggerModule).

aion_emit

load("@rules_lang//polyglot:aion.bzl", "aion_emit")

aion_emit(name, spec, target, out, deps, visibility)

Project a Lir-spec target to source via the toolchain’s lowering.

PARAMETERS

NameDescriptionDefault Value
nametarget name. The lean compilation runs as <name> (a lean_emit underneath); the Main-generation step is <name>_main_gen (private intermediate).none
speclabel of an aion_spec target (provides AionSpecInfo).none
targeteither a bare language name ("typescript", "sql", "python", "rust") — resolved to the registered toolchain at @rules_lang//polyglot:<lang>_aion_emit_toolchain — or an explicit label of an aion_emit_toolchain target.none
outemitted source filename (e.g. "logger.ts").none
depslean_emit deps (typically LAKE_PACKAGES).None
visibilityforwarded to the emitted lean_emit target.None

aion_spec_aspect

load("@rules_lang//polyglot:aion.bzl", "aion_spec_aspect")

aion_spec_aspect()

Walks a target’s deps / spec / specs attrs collecting AionSpecInfo records. Adds an AionSpecCollection provider with a depset of all specs reachable through that subgraph.

Apply to rule attrs via attr.label(aspects = [aion_spec_aspect]) in a consumer rule’s definition. Then inside that rule’s impl, read ctx.attr.<edge>[AionSpecCollection].specs to iterate the specs.

ASPECT ATTRIBUTES

NameType
depsString
specString
specsString

ATTRIBUTES

from docs/sql.md

Polyglot.Sql — the SQL parse/projection Bazel axis.

A proto_library-shaped layering for SQL: raw sources at the top, parsed AST in the middle, projection rules (json / proto / lean / catalog) at the bottom. Each dialect (postgres, sqlite, …) plugs in via a toolchain implementing one of the per-dialect toolchain types declared in //polyglot/sql:BUILD.bazel.

sql_library                 ← raw .sql sources, dialect-tagged
    │   SqlInfo {srcs, dialect}

sql_ast_library             ← dialect parser → canonical AST file
    │   SqlAstInfo {asts: [(sql, ast, format)], dialect}

    ├──► sql_json_library   (future projection — AST as JSON)
    ├──► sql_proto_library  (future projection — AST as protobuf bytes)
    ├──► sql_lean_library   (future projection — AST decoded into Lean)

    └──► sql_catalog_library
             SqlCatalogInfo {snapshot: lean/json/ttl, dialect}
             ← folds DDL stmt-by-stmt and emits a cumulative
             `Pg.Catalog.Snapshot` (or dialect-equivalent).

Aspect: sql_ast_aspect propagates over deps of any rule and attaches an AST artifact per transitively-reachable sql_library source. Useful for sweeps that want to lint every SQL in a build closure without declaring a parse rule per file.

This skeleton ships:

  • SqlInfo, SqlAstInfo, SqlCatalogInfo, SqlToolchainInfo
  • sql_library
  • sql_ast_library (postgres dialect path wired; sqlite stub)
  • sql_catalog_library (postgres path delegates to a Python tool that decodes .pgpb via protoc- generated bindings and emits a Lean Pg.Catalog.Snapshot)
  • sql_ast_aspect

The json / proto / lean projection rules are placeholders pending the proto-grounded Lean codegen track (see the “future” comment in the roadmap — Pg.Ast generated from @libpg_query//:pg_query.proto).

sql_ast_library

load("@rules_lang//polyglot:sql.bzl", "sql_ast_library")

sql_ast_library(name, deps)

Parses each .sql source in deps via the dialect’s toolchain.

Output is one AST file per source (currently .pgpb for postgres). Downstream sql_*_library projection rules consume the resulting SqlAstInfo.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depssql_library targets to parse.List of labelsrequired

sql_catalog_library

load("@rules_lang//polyglot:sql.bzl", "sql_catalog_library")

sql_catalog_library(name, deps, folder, module_name, output_format)

Folds a sequence of parsed DDL ASTs into a catalog snapshot.

Walks every CREATE SCHEMA / DOMAIN / TYPE / TABLE / FUNCTION across the transitive sql_ast_library closure, maintains running catalog state, and emits a single snapshot file in the requested format.

Dialect-neutral: dispatches to the folder binary, which the dialect’s ecosystem supplies (e.g. rules_postgres provides @rules_postgres//tools:pgpb_to_snapshot). For convenience, dialect-specific wrappers (pg_sql_catalog_library) pre-fill folder so consumers don’t have to.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depssql_ast_library targets whose ASTs should be folded.List of labelsrequired
folderDialect-specific catalog-folder binary. Consumes one or more AST files (in lexicographic order by short_path) and emits a snapshot file. Invocation: —module —output [—format ] [ …] For postgres: @rules_postgres//tools:pgpb_to_snapshot.Labelrequired
module_nameLean (or analogous) module name (defaults to target name).Stringoptional""
output_formatOutput projection format.Stringoptional"lean"

sql_library

load("@rules_lang//polyglot:sql.bzl", "sql_library")

sql_library(name, deps, srcs, dialect)

Declares a set of .sql source files of a single dialect.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depsOther sql_library targets to roll up. Must match dialect.List of labelsoptional[]
srcsSQL source files contributed by this library.List of labelsoptional[]
dialectSQL dialect of the sources.Stringoptional"postgres"

SqlAstInfo

load("@rules_lang//polyglot:sql.bzl", "SqlAstInfo")

SqlAstInfo(asts, dialect)

Carries parsed AST files alongside their SQL sources.

Each entry of asts is a struct(sql=File, ast=File, format=string). format lets downstream projection rules pick the correct decoder (e.g. ‘libpg_query_protobuf’ vs ‘sqlite_native’).

FIELDS

NameDescription
astsdepset[struct(sql: File, ast: File, format: string)]
dialectstring

SqlCatalogInfo

load("@rules_lang//polyglot:sql.bzl", "SqlCatalogInfo")

SqlCatalogInfo(snapshot, dialect, output_format)

Carries a cumulative catalog snapshot folded over DDLs.

The snapshot File is the final emitted artifact (Lean source by default; future support for JSON/TTL via the output_format attribute). dialect matches the upstream SqlAstInfo.dialect.

FIELDS

NameDescription
snapshotFile — emitted Pg.Catalog.Snapshot artifact.
dialectstring
output_formatstring — ‘lean’ | ‘json’ | ‘ttl’

SqlInfo

load("@rules_lang//polyglot:sql.bzl", "SqlInfo")

SqlInfo(srcs, dialect)

Carries raw SQL source files plus their declared dialect.

Surfaced by sql_library and propagated through deps. The dialect is what tells sql_ast_library which toolchain to resolve.

FIELDS

NameDescription
srcsdepset[File] — .sql source files (transitively).
dialectstring — ‘postgres’ | ‘sqlite’ | …

SqlToolchainInfo

load("@rules_lang//polyglot:sql.bzl", "SqlToolchainInfo")

SqlToolchainInfo(parser, parser_format, proto_descriptor, version, dialect)

The dialect-specific parser binary + format contract.

Every *_sql_toolchain rule emits this. parser is invoked as <parser> <input.sql> > <output.ast>. parser_format is what downstream projection rules use to pick the right decoder.

FIELDS

NameDescription
parserFile — executable; consumes .sql arg, emits AST on stdout.
parser_formatstring — ‘libpg_query_protobuf’ | …
proto_descriptorFile or None — .proto schema (if AST is proto-shaped).
versionstring — parser version (e.g. ‘17-6.2.2’).
dialectstring — matches the toolchain_type’s dialect tag.

sql_ast_aspect

load("@rules_lang//polyglot:sql.bzl", "sql_ast_aspect")

sql_ast_aspect()

Propagates over deps, attaching SqlAstInfo to every transitive sql_library. Lets downstream rules consume parsed ASTs without per-file sql_ast_library declarations.

ASPECT ATTRIBUTES

NameType
depsString

ATTRIBUTES

Conformance#

No gate findings. 8 contested atoms. See how gating works or the full report.

Contested atoms

Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.

AtomResolved hereElsewhere
apple_support 1.24.2 2.2.0 ×1
bazel_skylib 1.8.2 1.9.0 ×2
nlohmann_json 3.6.1 3.12.0.bcr.1 ×1
protobuf 33.4 34.0.bcr.1 ×2
rules_jvm_external 6.7 6.8 ×4
rules_python 1.7.0 2.0.1 ×1
rules_swift 3.1.2 3.6.1 ×1
upb 0.0.0-20220923-a547704 0.0.0-20230516-61a97ef ×1

Dependencies#

rules_lang in the registry graph — what it depends on (left) and what depends on it (right).

Depends on

rules_lean0.5.5platforms1.0.0bazel_skylib1.8.2rules_cc0.2.17rules_shell0.6.1rules_python1.7.0rules_proto7.1.0protobuf33.4stardoc0.7.2dev

Used by (1 in the registry)

Versions#

9 published versions, newest first. Each resolves to an immutable, integrity-checked archive.

VersionIntegrity (sha256)Source archive
0.5.0 latest JwgvKH6SHeWUzHuE… tag archive ↗
0.4.5 O1VcoOS95d4WRb+p… tag archive ↗
0.4.4 Z2UEmBjFxes0tjXF… tag archive ↗
0.4.3 KiTiI7gppfPHkeVu… tag archive ↗
0.4.2 yanked AHxoUj0VyIfP8BOf… tag archive ↗
0.4.1 U81m4f46arpvmgMb… tag archive ↗
0.4.0 0Vmo/dEANDsO4DZ5… tag archive ↗
0.3.0 gqiH8oLmvFzuxyle… tag archive ↗
0.2.0 dGlGvgFhUnIWlIih… tag archive ↗

Changelog#

All notable changes to rules_lang. The format is loosely Keep a Changelog — version headers mirror the published bazel-registry entries.

0.5.0 — the Lean toolchain registration is dev-scoped (consumers stop paying for it)

register_toolchains("@rules_lang_lake//:lean_toolchain_def") was at module scope, non-dev. Registration is EAGER: Bazel loads a registered toolchain’s package to read its toolchain_type, and loading that package runs the lake_workspace repository rule. Non-dev, that propagates to every transitive consumer — so a repo that takes rules_lang as a bazel_dep materialized @rules_lang_lake (Lean toolchain download + extraction) during ANALYSIS of targets with no Lean anywhere in their graph, including pure-Rust ones. There is no consumer-side escape: a --config=lean-style opt-in cannot suppress a registration made inside a dependency module.

It is now dev_dependency = True. Nothing else changes:

  • rules_lang’s own Lean targets are unaffected. Dev registrations still apply when the module is ROOT, which is the case for this repo’s own builds and CI. //smoke (a lean_library against //lean:atlas) resolves the toolchain exactly as before.
  • No consumer relied on it. Every downstream repo with Lean targets already registers its own lake workspace’s toolchain — rules_texlive (@cweb_lean_ws//:lean_toolchain_def), agentic_ide_runtime and agora (@lake_deps//:lean_toolchain_def), aion (--extra_toolchains=@lake_deps//: lean_toolchain_def under --config=lean). None of them reach for @rules_lang_lake.

Minor rather than patch because this removes a toolchain from rules_lang’s transitive surface. If a consumer was silently resolving @rules_lang_lake’s Lean toolchain for its own lean_* targets, it will now fail toolchain resolution and must register its own — which is the correct outcome, since rules_lang’s toolchain is pinned to rules_lang’s lean-toolchain, not the consumer’s.

0.4.0 — cross-repo emit boundary

  • Adds the polyglot.emit.v1 emit boundary: //proto/{lir,lir_codec,emit}.proto
    • //tools/emit:manifest_packer (the Python packer) + the //tools/emit:emit_manifest.bzl polyglot_emit_manifest rule. A producer (e.g. aion/lean) renders source Lean-side via the atlas (//polyglot:typescript_aion_emit_toolchain) and packs it into a TranslationManifest binpb; a consumer (aion/lift’s aion_ts_package, aion/sql) decodes + assembles it with no Lean toolchain and no second renderer. Adds rules_proto + protobuf deps.

0.3.0 — atlas-v0.3.1: Syntax precedence kernel

  • //lean:atlas now bundles the generic Syntax.Expr AST + the Syntax.Prec operator-precedence engine, alongside the existing Core/Lir, Sql, Typescript, Java, Wasm, Yaml. Consumers (e.g. rules_texlive’s Pascal-H parser) reach it via deps = ["@rules_lang//lean:atlas"]. Points //lean:atlas.bzl at the atlas-v0.3.1 release (both per-arch tarballs verified to contain Syntax/{Expr,Prec}.olean); //smoke now gates the Syntax load.

0.2.0 — //rules/c rule definitions

  • Ports the //rules/c C/clang AST-dump + struct-diff + LLVM-IR rule defs (c_ast_dump_single, c_ast_struct_diff_test_suite, rust_llvm_ir_single) plus the cli/ python helpers, so consumers (e.g. rules_postgres Gate 3) resolve the loads without private-engine access. The heavy Rust diff/IR tools (//crates/pipeline) stay private in aion/polyglot — only the rule defs live here, as lazy default-attr labels. Adds rules_cc + rules_python deps and makes rules_shell non-dev.

0.1.0 — public split: rules layer + imported atlas olean

  • Initial public release. The @rules_lang rule layer (polyglot/, rules/) is public; the engine + AST source stay private in GitLab aion/polyglot.
  • lean_imported_library(//lean:atlas) consumes the compiled Polyglot.* atlas olean as a prebuilt, per-arch GitHub release asset (atlas-v<ver>) — no engine source, no recompile; consumers resolve anonymously.
  • polyglot/aion.bzlaion_spec / aion_emit (a Lir spec → target source via the imported atlas’s OfLir.render) + aion_emit_toolchain.
  • polyglot/sql.bzl — SQL parse rules + //polyglot/sql:postgres_toolchain_type (the libpg_query impl is the consumer’s, via rules_postgres).
  • Stardoc reference docs for aion.bzl + sql.bzl, gated by //docs diff_tests.

← All modules