Providence CLI Tool : Code Generator
The code generator (called compiler in Apache Thrift) pvdgen
,
this can be used in place of the maven plugin for non-java projects.
Out of the box, it can generate files for:
json
: Simply writes out the thrift definitions as JSON files, one file per thrift or providence IDL file. Note that acceptance differences between .thrift and .providence files are not propagated through to these files, but they should not pass unless accepted anyway.java
: Writes the standard providence java generated code. See the generator help for detailed instructions.
See pvdgen --help
for more detailed info about the available options.
Developing Generator Modules
See providence-js for an example of how to add a simple external generator. Note that because of the tie-in with the contained descriptions and the type registries the generators may be pretty dependent on the providence version installed.
Creating a generator.
First you need to extend the Generator
class, which does the actual code
generating. The generate
method is given a ProgramTypeRegistry
which
represents a single thrift program file, and references all it's dependencies.
The generateGlobal
is only called once, and can be used to generate "global"
config or other files, e.g. like the JS generator may need to include some
"system" JS files.
public class MyGenerator extends Generator {
private final GeneratorOptions generatorOptions;
private final MyOptions options;
public MyGenerator(FileManager manager, GeneratorOptions generatorOptions, MyOptions jsOptions) throws GeneratorException {
super(manager);
this.options = jsOptions;
this.generatorOptions = generatorOptions;
}
@Override
@SuppressWarnings("resource")
public void generate(ProgramRegistry registry) throws IOException, GeneratorException {
CProgram program = registry.getProgram();
// generate file or files bassed on this program.
}
@Override
public void generateGlobal(GlobalRegistry registry,
Collection<File> inputFiles) throws IOException, GeneratorException {
boolean service = false;
for (ProgramTypeRegistry reg : registry.getLoadedRegistries()) {
CProgram program = reg.getProgram();
if (program.getServices().size() > 0) {
service = true;
break;
}
}
if (service) {
// add service files.
}
}
}
Creating Generator Factory
Second you need to implement the GeneratorFactory
for the generator. This
class is used to find the actual generator (for pvdgen) and to make a generator
instance, parse options etc.
public class MyGeneratorFactory implements GeneratorFactory {
@Override
public String generatorName() {
return "my";
}
@Override
public String generatorDescription() {
return "Generates my stuff";
}
@Override
public void printGeneratorOptionsHelp(PrintStream out) {
System.out.println(" - name : My option.");
}
private JSOptions makeMyOptions(Collection<String> optionNames) {
MyOptions options = new MyOptions();
for (String opt : optionNames) {
switch (opt) {
case "name":
options.name = true;
break;
default:
throw new RuntimeException("No such option for my generator: " + opt);
}
}
options.validate();
return options;
}
@Override
public Generator createGenerator(FileManager manager,
GeneratorOptions generatorOptions,
Collection<String> options) {
return new MyGenerator(manager, generatorOptions, makeMyOptions(options));
}
}
Building a Jar
Then you need to make a jar
file for the generator. This needs to have
the Providence-Generator-Factory
property in the manifest, which must
point to the factory class implemented above.
Packaging
In order to have pvdgen
pick up the generator, you can do one of the
following.
- Add jar file absolute path to
generator_paths
in one of:${HOME}/.pvdrc
(pretty / providence config format, for user testing)/etc/providence/*.json
(json, for native installs)/usr/local/etc/providence/*.json
(json, for homebrew on mac)/${HOME}/.linuxbrew/etc/providence/*.json
(json, for linuxbrew)
- Place the jar file in the
generator
directory under${PREFIX}/share/providence/generator
e.g. like this:/usr/local/share/providence/generator/my.jar
.
Example config files:
config.ProvidenceTools {
generator_paths = [
"/path/to/my.jar"
]
}
{
"generator_paths": [
"/path/to/my.jar"
]
}