Spine Compiler is a collection of tools for generating quality domain models from Protobuf
definitions. It plugs into your Gradle build and extends the code that protoc produces,
turning plain .proto messages into rich domain types — with validation, factory methods,
and other conveniences contributed by pluggable code generators.
The Compiler is part of the Spine SDK and powers code generation across Spine-based projects. It is not limited to them, though: any Protobuf-based JVM project can apply the Compiler and drive it with its own code-generation plugins.
The Compiler treats your Protobuf definitions as a model and processes it reactively:
protocparses the.protofiles. Aprotocplugin bundled with the Compiler captures the result as a code-generation request.- The Compiler reads that request and represents the Protobuf files, types, fields, and options as a model, delivered as a stream of events.
- The plugins you attach observe the model through views and react to it through policies, then emit source code through renderers.
- The renderers create new source files or edit the ones
protocgenerated, producing the final domain model.
A plugin bundles these parts together, so attaching one plugin is enough to contribute a whole feature to the generated code.
- JDK 17 or newer.
- The Protobuf Gradle Plugin (
com.google.protobuf), which the Compiler builds upon.
The Compiler ships as a Gradle plugin published to the Gradle Plugin Portal under the
io.spine.compiler ID. It requires the Protobuf Gradle Plugin, so apply both:
plugins {
java
id("com.google.protobuf") version "<Protobuf plugin version>"
id("io.spine.compiler") version "<Compiler version>"
}The example applies the java plugin; use kotlin("jvm") instead for a Kotlin project — the
Compiler generates code for both. Once applied, the Compiler hooks into the generateProto
tasks, so the generated model is refreshed on every build.
Out of the box the Compiler runs the pipeline without changing the generated code. To make it
do something, attach one or more Compiler plugins: list their classes in the compiler { }
block — nested inside the spine { } extension — and put them on the Compiler classpath with
the spineCompiler configuration.
spine {
compiler {
plugins(
"com.acme.codegen.MyPlugin",
)
}
}
dependencies {
spineCompiler("com.acme:my-codegen:1.0.0")
}Then build the project as usual:
./gradlew buildA Compiler plugin is a class with a parameterless constructor that bundles the components doing the work. The most common component is a renderer, which creates or edits source files:
import io.spine.tools.code.Java
import io.spine.tools.compiler.plugin.Plugin
import io.spine.tools.compiler.render.Renderer
import io.spine.tools.compiler.render.SourceFileSet
/** Modifies the Java sources produced for the Protobuf model. */
public class MyRenderer : Renderer<Java>(Java) {
override fun render(sources: SourceFileSet) {
// Inspect the Protobuf model and create or edit source files here.
}
}
/** Exposes the renderer — and any views or policies — to the Compiler. */
public class MyPlugin : Plugin(renderers = listOf(MyRenderer()))Compile the plugin against the public API artifact:
dependencies {
implementation("io.spine.tools:compiler-api:<Compiler version>")
}Renderers can inspect the Protobuf model through views and react to it through policies. See the
api module and its API documentation for the full set of building blocks.
Spine Compiler is released under the Apache License, Version 2.0.