moznion's tech blog

moznion's technical memo

gowrtr - a library that supports golang code generation

(Japanese article is here: https://moznion.hatenadiary.com/entry/2019/01/14/111719)

I published a library that supports golang code generation, this named gowrtr (pronunciation: go writer). This library has a number of generators for golang code generation.

github.com

As Synopsis shows you:

package main

import (
    "fmt"

    "github.com/moznion/gowrtr/generator"
)

func main() {
    generator := generator.NewRoot(
        generator.NewComment(" THIS CODE WAS AUTO GENERATED"),
        generator.NewPackage("main"),
        generator.NewNewline(),
    ).AddStatements(
        generator.NewFunc(
            nil,
            generator.NewFuncSignature("main"),
        ).AddStatements(
            generator.NewRawStatement(`fmt.Println("hello, world!")`),
        ),
    ).
        EnableGofmt("-s").
        EnableGoimports()

    generated, err := generator.Generate(0)
    if err != nil {
        panic(err)
    }
    fmt.Println(generated)
}

the above code generates the following go code:

// THIS CODE WAS AUTO GENERATED
package main

import "fmt"

func main() {
        fmt.Println("hello, world!")
}

This library works as above.

This example is really simple so it looks it increases the amount of code should write at first glance, but if you want to generate large-scale code, this library should be useful to do that (please refer to the following topic about immutability).

For more detail, please refer to the GoDoc. The documentation also contains examples.

This library has two peculiarities:

  • It can apply code formatters (i.e. gofmt and/or goimports) to the generated code
  • Each method of the library act as immutable

The first one, it can obtain the advantage that "the format of the generated code is unified" and "can check the syntax of the generated code" by applying gofmt. Moreover, it can get the merit that "there is no necessary to think and write about which library should be imported while writing the generator for code generation" with using goimports.

The second means, each method of the generators doesn't change the internal state implicitly so a user can take a snapshot of the generator on demand. This is useful to reuse and derive the code generator instance.


By the way, there is square/javapoet that is a library supports Java code generation in the Java world. That is a great library. gowrtr is inspired by javapoet.

Perhaps this library lacks features and/or notation supports. If so please feel free to let me know.

Enjoy.