= Vert.x Codegen

Vert.x Codegen is an annotation processing tool for processing Vert.x API and create API in different JVM lauguages.

Vert.x polyglot langs use code generation for creating https://en.wikipedia.org/wiki/Shim_(computing)[shim] for APIs,
that are thin wrappers in front of the API type.

A shim is the adaptation of a Vert.x API to a JVM language. A shim uses code generation to generate
wrappers in its own language delegating to the Vert.x API, code generation is based on Java annotation
processing.

== Vert.x API

A Vert.x API is a collection of Java types annotated with Codegen annotations that respect a set of constraints to
ensure easy portability of the API to most languages and enable an asynchronous programming model. Such collection
of API types are grouped in modules.

=== Modules

A module contains a collection of Vert.x API and data objects declarations, some shim uses modules for organizing
and loading the Vert.x api:

- the JavaScript shim uses https://en.wikipedia.org/wiki/CommonJS[CommonJS] modules
- the Ruby shim uses Ruby modules
- Ceylon uses Ceylon native modules

NOTE: so far in Java or Groovy the notion of module is not used because it delegates loading to classloaders.

Modules are declared by annotating a Java package with a {@link io.vertx.codegen.annotations.ModuleGen @ModuleGen}
annotation.

[source,java]
----
@ModuleGen(name = "acme", groupPackage="com.acme")
package com.acme.myservice;

import io.vertx.codegen.annotations.ModuleGen;
----

The module _name_ is a namespace for shims that don't support package like naming, like JavaScript `acme-js`
or Ruby `acme`, whereas the _group package_ determines the created package, for instance
`com.acme.groovy.myservice` in Groovy. The group package must be a prefix of the annotated module.

Vert.x modules use the reserved name _vertx-XYZ_ and the reserved group package _io.vertx_.

An API module contains various Vert.x types annotated with {@link io.vertx.codegen.annotations.VertxGen}
or {@link io.vertx.codegen.annotations.DataObject}.

NOTE: using Maven coordinates for name and group package is encouraged: the name corresponding to the
Maven _artifactId_ and the group package corresponding to the `groupId`.

=== Data objects

A Data object_ is a Java class with the only purpose to be a container for data. They are transformed
to and from Json.

In its simplest form, a data object is a Java class following these rules:

1. the class is annotated with {@link io.vertx.codegen.annotations.DataObject}
2. provide a constructor with the `io.vertx.core.json.JsonObject` argument

A data object can also be an interface annotated with `@DataObject`, this is useful when multiple inheritance
is needed. For instance Vert.x Core defines the `KeyCertOptions` and `TrustOptions` data object interfaces and the
`JksOptions` is a data object class that implements both of them because a Java keystore provides support for both.

Data object can also inherit from other data objects. It inherits from the properties of the parent classes.

==== Data object properties

DataObject properties are declared via _getters_, _setters_ or _adders_:

.a getter and a setter
[source,java]
----
public String getHost() {
  return host;
}

public WebServerOptions setHost(String host) {
  this.host = host;
  return this;
}
----

Here is the list of supported property single valued types:

1. any primitive or boxed primitive type
2. `java.lang.String`
3. `io.vertx.core.json.JsonObject` and `io.vertx.core.json.JsonArray`
4. the specific `io.vertx.core.buffer.Buffer` type providing support for byte array
5. Java enums
6. another data object

In addition a data object can also have multi-valued properties as a `java.util.List<V>`/`java.util.Set<V>` or a
`java.util.Map<String, V>` where the `<V>` is a supported single valued type or `java.lang.Object`
that stands for anything converted by `io.vertx.core.json.JsonObject` and `io.vertx.core.json.JsonArray`.

List/set multi-valued properties can be declared via a _setter_ :

.a multi valued setter
[source,java]
----
public WebServerOptions setCertificates(List<String> certificates) {
  this.certificates = certificates;
  return this;
}
----

Or an _adder_ :

.a multi valued adder
[source,java]
----
public WebServerOptions addCertificate(String certificate) {
  this.certificates.add(certificate);
  return this;
}
----

Map properties can only be declared with a _setter_.

NOTE: these examples uses a _fluent_ return types for providing a better API, this is not mandatory but
encouraged.

==== Json conversion

Vert.x requires data object to be convertible from json with the json argument constructor. Altough there
is no strict rules of mapping between the data object properties and the json structure, it is a good thing
to follow a common mapping for users using json data objects (like in JavaScript shim).

Json properties should be named after properties according to JavaBean conversion rules:

- a single valued property follows the JavaBean convention
- a multi valued property declared with a list setter follows the same convention
- a multi valued property declared with an adder must use a singular form and the json property name gets a trailing _s_

In all case, property names are _normalized_, i.e:

- _red_ -> _red_
- _Red_ -> _red_
- _URL_ -> _url_
- _URLFactory_ -> _urlFactory_

==== Jsonifiable data object

When a data object declares a `public JsonObject toJson()` method it can be converted to the json format
and is said _jsonifiable_. Vert.x API types have restriction in the declared method return types, a jsonifiable
data object can be used in Vert.x API method return types or handlers because it can be converted to a json
format, otherwise it is not permitted.

==== Data object converter

Vert.x requires only the conversion from json, but the conversion to json can be useful when the API uses
data objects as return types. The implementation of the data object / json conversion can be tedious and
error prone.

The data object / json conversion can be automated based on the rules given above. Vert.x Core allows to
generate auxilliary classes that implement the conversion logic. The generated converters handle the
type mapping as well as the json naming convention.

Converters are generated when the data object is annotated with `@DataObject(generateConverter=true)`. The
generation happens for the data object properties, not for the ancestor properties, unless `inheritConverter`
is set: `@DataObject(generateConverter=true,inheritConverter=true)`.

The converter is named by appending the `Converter` suffix to the data object class name, e.g,
`ContactDetails` -> `ContactDetailsConverter`. The generated converter has two static methods:

- `public static void fromJson(JsonObject json, ContactDetails obj)`
- `public static void toJson(ContactDetails obj, JsonObject json)`

The former should be used in the json constructor, the later in the `toJson` method.

[source,java]
----
public ContactDetails(JsonObject json) {
  this();
  ContactDetailsConverter.fromJson(json, this);
}

public JsonObject toJson() {
  JsonObject json = new JsonObject();
  ContactDetailsConverter.toJson(this, json);
  return json;
}
----

=== Building types

A few types used throughout Vert.x API are not annotated with `@VertxGen` yet are used for building
the API:

- `io.vertx.core.Handler`
- `java.util.function.Function`
- `io.vertx.core.AsyncResult`
- `io.vertx.core.json.JsonObject`
- `io.vertx.core.json.JsonArray`
- `java.lang.Object`
- `java.lang.Throwable`
- `java.lang.Void`
- `java.lang.String`
- `java.util.List`
- `java.util.Set`
- `java.util.Map`
- primitive and boxed primitives

These types are usually handled natively by shims, for instance the `Handler` type is a function in JavaScript,
a block in Ruby, the same `Handler` in Groovy, a function in Ceylon, etc...

=== Generated types

An API type is a Java interface annotated with {@link io.vertx.codegen.annotations.VertxGen}.

Vert.x provides a async / non blocking / polyglot programming model, code generated API shall follow some
rules to make this possible:

1. the API must be described as a set of Java interfaces, classes are not permitted
2. nested interfaces are not permitted
3. all interfaces to have generation performed on them must be annotated with the `io.vertx.codegen.annotations.VertxGen` annotation
4. fluent methods (methods which return a reference to `this`) must be annotated with the `io.vertx.codegen.annotations.Fluent` annotation
5. methods where the return value must be cached in the API shim must be annotated with the `io.vertx.codegen.annotations.CacheReturn` annotation
6. only certain types are allowed as parameter or return value types for any API methods
7. custom enums should be annotated with `@VertxGen`, although this is not mandatory to allow the usage of existing Java enums
8. nested enums are not permitted
9. default implementations are allowed

An API type can be generic or declare generic methods, type parameters must be unbounded, e.g
`<N extends Number>` is forbidden.

In the perspective of codegen, Java types can be categorized as follow:

. _basic_ type : any primitive/boxed type or `java.lang.String`
. _json_ type : `io.vertx.core.json.JsonObject` or `io.vertx.core.json.JsonArray`
. _api_ type : any type annotated with `io.vertx.codegen.annotations.VertxGen`
. _data object_ type : any type annotated with `io.vertx.codegen.annotations.DataObject`
. _enum_ type : any Java enum
. _collection_ type : `java.util.List<V>`, `java.util.Set<V>` or `java.util.Map<String, V>`
. _java_ type : any other type that can be represented as a Java class. Java types declarations are only permitted
in interfaces allowing them (`@VertxGen(allowJavaTypes = true)`)

Parameterized types are supported but wildcards are not, that is the following type arguments declarations
are *forbidden*:

- `Foo<?>`
- `Foo<? extends Number>`
- `Foo<? super Number>`

Parameterized types are only supported for _api_ generic types, _collection_ types and _java_ types.

Type variables are allowed and carry a special meaning: a type variable is a dynamic form of a _basic_ type and
_json_ type.

_java_ types should be used wisely because they provide a limited compatibility with Vert.x generators.

==== Inheritance

_api_ type can extend other _api_ types.

An _api_ type can either be *concrete* or *abstract*, such information is important for languages not
supporting multiple class inheritance like Groovy:

- _api_ types annotated with {@link io.vertx.codegen.annotations.VertxGen}`(concrete = false)` are meant to be
extended by *concrete* interfaces an can inherit from *abstract* interfaces only.
- _api_ types annotated with {@link io.vertx.codegen.annotations.VertxGen} or {@link io.vertx.codegen.annotations.VertxGen}`(concrete = true)`
are implemented directly by Vertx and can inherit at most one other *concrete* interface and any *abstract* interface

==== Method parameter types

The following method parameter types are allowed:

. any _basic_ type
. any _api_ type or parameterized _api_ type having type variable parameters
. any _java_ type
. any _json_ type
. the `java.lang.Throwable` type
. any _enum_ type
. any _data object_ type that is a non abstract class
. an https://docs.oracle.com/javase/tutorial/java/generics/bounded.html[unbounded type variable], i.e `T extends Number` or `T super Number` are not permitted
. `java.lang.Object`
. a `java.util.List<V>`, `java.util.Set<V>` or `java.util.Map<String, V>` where `<V>` can be a _basic_ type,
a _json_ type, an _api_ type or a `java` type. For list and set `V` can also be an _enum_ type or a _data object_ type

Callback parameters are allowed, i.e types declaring `io.vertx.core.Handler<E>` or
`io.vertx.core.Handler<io.vertx.core.AsyncResult<E>>` where `<E>` can be:

. the `java.lang.Void` type
. any _basic_ type
. any _api_ type
. any _java_ type
. any _json_ type
. the `java.lang.Throwable` type - only for `Handler<R>`
. any _enum_ type
. any _data object_ type with a `toJson` method
. an https://docs.oracle.com/javase/tutorial/java/generics/bounded.html[unbounded type variable], i.e `T extends Number` or `T super Number` are not permitted
. a `java.util.List<V>`, `java.util.Set<V>` or `java.util.Map<String, V>` where `<V>` can be a _basic_ type,
a _json_ type. For list and set `V` can also be an _API_ type, an _enum_ type or a _data object_ type

Function parameters are allowed, i.e types declaring `java.util.function.Function<E, R>` where `<E>` is defined to
be same than for handlers and `<R>` can be:

. any _basic_ type
. any _api_ type
. any _java_ type
. any _json_ type
. the `java.lang.Throwable` type
. any _enum_ type
. any _data object_ type that is a non abstract class
. an unbounded type variable
. a `java.util.List<V>`, `java.util.Set<V>` or `java.util.Map<String, V>` where `<V>` can be a _basic_ type,
a _json_ type or a `java` type. For list and set `V` can also be an _API_ type, an _enum_ type or a _data object_ type

==== Method return type

The following return types are allowed:

. `void` type
. any _basic_ type
. any _api_ type or parameterized _api_ type having type variable parameters
. any _java_ type
. any _json_ type
. the `java.lang.Throwable` type
. any _enum_ type
. any _data object_ type with a `toJson` method
. an https://docs.oracle.com/javase/tutorial/java/generics/bounded.html[unbounded type variable], i.e `T extends Number` or `T super Number` are not permitted
. a `java.util.List<V>`, `java.util.Set<V>` or `java.util.Map<String, V>` where `<V>` can be a _basic_ type,
a _json_ type. For list and set `V` can also be an _API_ type, an _enum_ type or a _data object_ type
. an `Handler<T>` where T is is a among the method parameter types
. an `Handler<AsyncResult<T>>` where T is is a among the method parameter types

==== Method overloading

Some languages don't support method overloading at all. Ruby, JavaScript or  Ceylon to name a few of them.
However the same restriction for Vert.x API would limit API usability.

To accomodate both, overloading is supported when there are no ambiguities between overloaded signatures.
When an API is analyzed an _overload check_ is performed to ensure there is no ambiguity.

Here is an example of possible ambiguity:

.an overload check failure
[source,java]
----
void add(int x, int y);
void add(double x, double y);
----

The JavaScript language use the type number in both cases: at runtime there is no possibility for the
JavaScript shim to know which method to use.

Method declaring `java` types are not checked.

==== Nullable types

Null values have an impact on shim design:

- shims based on value types for dispatching overloaded methods fail for null values, for example a `foo(String)`
method overloaded by a `foo(Buffer)` method invoked with `foo(null)` cannot delegate to the correct underlying method in
JavaScript.
- some shims can leverage this information to provide a better API, for instance an `Optional<String>` Java type or the
`String?` in Ceylon, etc...

Codegen provides the {@link io.vertx.codegen.annotations.Nullable} annotations for annotating types.

Method return type can be {@link io.vertx.codegen.annotations.Nullable}:

[source,java]
----
@Nullable String getAttribute(String name);
----

As well as method parameter type:

[source,java]
----
void close(@Nullable Handler<Void> closeHandler);
----

WARNING: type validation is a non goal of this feature, its purpose is to give hints to the shim
for generating correct code.

These rules apply to {@link io.vertx.codegen.annotations.Nullable} types:

. primitive types cannot be {@link io.vertx.codegen.annotations.Nullable}
. method parameter type can be {@link io.vertx.codegen.annotations.Nullable}
. method return type can be {@link io.vertx.codegen.annotations.Nullable} but not for {@link io.vertx.codegen.annotations.Fluent}
. `io.vertx.core.Handler` type argument can be {@link io.vertx.codegen.annotations.Nullable} but not for
`java.lang.Void` or `io.vertx.core.AsyncResult`
. `io.vertx.core.Handler<io.vertx.core.AsyncResult>` type argument can be {@link io.vertx.codegen.annotations.Nullable}
but not for `java.lang.Void`
. the `java.lang.Object` type is always nullable
. the `<T>` in `<T>` parameter/return, `Handler<T>` or `Handler<AsyncResult<T>>` is implicitly nullable
. the `java.lang.Object` parameter is implicitly nullable
. a method overriding another method `inherits` the {@link io.vertx.codegen.annotations.Nullable} usage of the overriden method
. a method overriding another method cannot declare {@link io.vertx.codegen.annotations.Nullable} in its types

In addition these rules apply to {@link io.vertx.codegen.annotations.Nullable} type arguments:

. methods cannot declare generic api types with nullable type arguments, e.g `<T> void method(GenericApi<Nullable T> api)` is not permitted
. methods can declare nullable collection, e.g `void method(List<Nullable String> list)` is allowed

Besides these rules, nullable types of method parameters have an impact on method overloading: the parameter
at the same position cannot be {@link io.vertx.codegen.annotations.Nullable} more than one time when the number
of method parameters is the same, e.g:

[source,java]
----
void write(@Nullable String s);
void write(@Nullable Buffer s);
----

is not permitted, however:

[source,java]
----
void write(@Nullable String s);
void write(@Nullable String s, String encoding);
----

is permitted because the number of parameters differs.

=== Static methods

Vert.x generated types allow _static_ methods, such methods often plays the role of factory. For instance
`Buffer` instance are obtained by the static method `Buffer.buffer()`, this method is translated to an equivalent
in the shim.

In Javascript:

[source,javascript]
----
var Buffer = require('vertx-js/buffer');
var buf = Buffer.buffer();
----

In Ruby:

[source,ruby]
----
require 'vertx/buffer'
buf = Vertx::Buffer.buffer()
----

In Groovy:

[source,groovy]
----
def buf = io.vertx.groovy.core.Buffer.buffer();
----

=== Ignored methods

Methods annotated with {@link io.vertx.codegen.annotations.GenIgnore} are simply ignored by codegen, this
is useful when the API provides Java specific methods, for instance a method uses a type not permitted
by codegen.

== Shim proxies

A code generated API creates shim proxies delegating method invocation to the API.

.a simplified Buffer API
[source,java]
----
@VertxGen
public interface Buffer {

  static Buffer buffer(String s) {
    return new BufferImpl(s);
  }

  int length();
}
----

A JavaScript generated shim could look like:

.the JavaScript shim
[source,javascript]
----
var JBuffer = io.vertx.core.buffer.Buffer;
var Buffer = function(j_val) {

  // delegate object
  var j_buffer = j_val;
  var that = this;

  this.length = function() {
    return j_buffer.length();
  };
}

Buffer.buffer = function(s) {
  return new Buffer(JBuffer.buffer(s));
}

module.exports = Buffer;
----

The static `buffer` method is translated into the `buffer` method of the `Buffer` module, this method
delegates the call to the Java static method and returns a `Buffer` proxy wrapping the returned buffer.

The instance `length` method is translated into the `length` method of the proxy instance, this method
delegates the call to the Java instance method of the proxied buffer and simply returns the value. The
Nashorn interoperability takes care of converting the `int` type to a JavaScript `Number`.

=== Return values

A shim implements several strategies when returning values from the Vert.x API:

1. a _basic_ value is usually handled by the shim interop
2. an _API_ value creates a proxy to wrap the value
3. a _json_ (object or array) value is translated to the shim equivalent
4. a jsonifiable _data object_ is converted to json or an equivalent
5. an _enum_ value is converted to a string or an equivalent
6. a _collection_ is usually translated to the shim equivalent
7. a `java.lang.Throwable` is usually translated to the shim equivalent
8. a type variable is converted dynamically converted to a _basic_ type or a _json_ type
9. an `Handler<T>` value is what is used in the target language to represent an handler, when this handler is called
it invokes the handler with the value converted using the argument value rules
10. an `Handler<AsyncResult<T>>` value is what is used in the target language to represent an async result handler, when this handler
is _succeeded_ it invokes the handler with the `AsyncResult<T>` wrapping the converted value using the argument value rules,
otherwise it invokes the handler with the `AsyncResult<T>` wrapping the throwable

=== Argument values

A shim implements several strategies when passing values to the Vert.x API:

1. a _basic_ value is usually handled by the shim interop
2. an _API_ value is unwrapped from the shim proxy
3. a _json_ (object or array) value is translated from the shim equivalent
4. a _data object_ is instantiated from the shim equivalent by its `JsonObject` constructor
5. an _enum_ is converted from a string or an equivalent
6. a _collection_ is usually translated from the shim equivalent
7. a type variable or `java.lang.Object` is converted dynamically converted to a _basic_ type or a _json_ type

=== Argument handlers

Argument handlers have a special treatment as the handlers gets a callback.

Usually a shim creates a `io.vertx.core.Handler<E>` instance whose `handle(E)` implementation
calls back the handler argument applying the return value conversion strategy.

For instance the `HttpClient#getNow` method:

[source,java]
----
void getNow(int port, String host, String requestURI, Handler<HttpClientResponse> responseHandler);
----

Can be translated to

[source,javascript]
----
function(port, host, requestURI, responseHandler) {
  j_httpClient.getNow(port, host, requestURI, function(jVal) {
    responseHandler(new HttpClientResponse(jVal));
  }
}
----

The JavaScript code calling passes a `function(result)`:

[source,javascript]
----
vertx.setTimer(1000, function(id) {
  // Timer fired
});
----

`AsyncResult<R>` types also gets a specific treatment, for instance the `HttpServer#listen` method:

[source,java]
----
void listen(int port, String host, Handler<AsyncResult<HttpServer>> listenHandler);
----

Can be translated to

[source,javascript]
----
function(port, host, listenHandler) {
  j_httpServer.listen(port, host, function(ar) {
    if (ar.succeeded()) {
      listenHandler(new HttpServer(ar.result()), null);
    } else {
      listenHandler(null, ar.cause());
    }
  }
}
----

The JavaScript code calling passes a `function(result, err)`:

[source,javascript]
----
server.listen(80, "localhost", function(result, err) {
  if (result != null) {
    // It worked
  } else {
    // It failed
  }
});
----

=== Argument function

Function arguments are `java.util.function.Function` instances, they are usually mapped to the function
type in the target language or an equivalent.

=== Exceptions

todo

=== Method dispatching

When a shim does not support overloading, it needs to handle the dispatch itself to the Java method, usually
based on the argument types when invocation occurs.

todo provide example ?

== Codegen types

The {@link io.vertx.codegen.type.TypeInfo} provides a codegen view of the Java type system.

A type info has a {@link io.vertx.codegen.type.ClassKind} usually used to determine the conversion to apply:

[cols="1,4"]
.Class kinds
|===
| {@link io.vertx.codegen.type.ClassKind#STRING}
| `java.lang.String`
| {@link io.vertx.codegen.type.ClassKind#PRIMITIVE}
| any Java primitive type
| {@link io.vertx.codegen.type.ClassKind#BOXED_PRIMITIVE}
| any Java boxed primitive type
| {@link io.vertx.codegen.type.ClassKind#ENUM}
| any Java enum
| {@link io.vertx.codegen.type.ClassKind#JSON_OBJECT}
| `io.vertx.core.json.JsonObject`
| {@link io.vertx.codegen.type.ClassKind#JSON_ARRAY}
| `io.vertx.core.json.JsonArray`
| {@link io.vertx.codegen.type.ClassKind#THROWABLE}
| `java.lang.Throwable`
| {@link io.vertx.codegen.type.ClassKind#VOID}
| `java.lang.Void`
| {@link io.vertx.codegen.type.ClassKind#OBJECT}
| `java.lang.Object` or an unbounded type variable
| {@link io.vertx.codegen.type.ClassKind#LIST}
| `java.util.List<V>`
| {@link io.vertx.codegen.type.ClassKind#SET}
| `java.util.Set<V>`
| {@link io.vertx.codegen.type.ClassKind#MAP}
| `java.util.Map<String,V>`
| {@link io.vertx.codegen.type.ClassKind#API}
| any _api_ type
| {@link io.vertx.codegen.type.ClassKind#DATA_OBJECT}
| any _data object_ type
| {@link io.vertx.codegen.type.ClassKind#HANDLER}
| `io.vertx.core.Handler<E>`
| {@link io.vertx.codegen.type.ClassKind#FUNCTION}
| `java.util.function.Function<E, R>`
| {@link io.vertx.codegen.type.ClassKind#ASYNC_RESULT}
| `io.vertx.core.AsyncResult<E>`
| {@link io.vertx.codegen.type.ClassKind#OTHER}
| anything else
|===

The `TypeInfo` base class provides common type information

- {@link io.vertx.codegen.type.TypeInfo#getKind} the type {@link io.vertx.codegen.type.ClassKind}
- {@link io.vertx.codegen.type.TypeInfo#getName()} the type name
- {@link io.vertx.codegen.type.TypeInfo#getSimpleName()} the simple name
- {@link io.vertx.codegen.type.TypeInfo#getErased()} returns the corresponding erased type
- {@link io.vertx.codegen.type.TypeInfo#getRaw()} returns the raw type of a parameter type or this type

Besides it provides the {@link io.vertx.codegen.type.TypeInfo#translateName(java.lang.String)} method to
translate the type name using a shim identifier, this is useful for shim using a hierarchical naming, for
instance the translated name of `io.vertx.core.eventbus.EventBus` for the `groovy` identifier is
`io.vertx.groovy.core.eventbus.EventBus`. The position where the identifier is applied is
determined by the {@link io.vertx.codegen.annotations.ModuleGen#groupPackage()} value.

Several subclasses of `TypeInfo` provides specialization when needed:

- {@link io.vertx.codegen.type.ClassTypeInfo} : a java class
- {@link io.vertx.codegen.type.ApiTypeInfo} : `TypeInfo.Class` specialization for _api_ types
- {@link io.vertx.codegen.type.EnumTypeInfo} : `TypeInfo.Class` specialization for _enum_ types
- {@link io.vertx.codegen.type.ParameterizedTypeInfo} : a parameterized type
- {@link io.vertx.codegen.type.PrimitiveTypeInfo} : a primitive type
- {@link io.vertx.codegen.type.VoidTypeInfo} : `void` (and not `java.lang.Void`)
- {@link io.vertx.codegen.type.TypeVariableInfo} : an unbounded type variable

== Codegen models

The codegen processor _validates_ annotated Java program elements (i.e type declaration) and _transforms_  them into models:

1. `ClassModel`
2. `DataObjectModel`
3. `EnumModel`
4. `PackageModel`
5. `ModuleModel`
6. `ProxyModel`

Models are processed by https://en.wikisource.org/wiki/MVEL_Language_Guide[MVEL] templates, when a template is executed it gets access to implicit properties
(i.e properties that are declared by the model).

For `ClassModel` and `DataObjectModel, annotations on methods/properties can be accessed.

For `ModuleModel`, annotations on package can be accessed. Annotation at type level can be retrieved
for `ClassModel`, `DataObjectModel`, `EnumModel` and `ProxyModel`.

=== Class model

For each Java interface annotated with {@link io.vertx.codegen.annotations.VertxGen} a `{@link io.vertx.codegen.ClassModel}` is created.

[cols="1,4"]
.Template properties
|===
| `importedTypes`
| the full list of used types including `java.lang.*` types as `{@link io.vertx.codegen.type.ClassTypeInfo}` that are not in the same package
| `referencedTypes`
| the full list of used types including `java.lang.*` types as `{@link io.vertx.codegen.type.ClassTypeInfo}`
| `referencedDataObjectTypes`
| the full list of used _data object_ types as `{@link io.vertx.codegen.type.ClassTypeInfo}`
| `type`
| the type `{@link io.vertx.codegen.type.ClassTypeInfo}` or `{@link io.vertx.codegen.type.ParameterizedTypeInfo}`
| `typeParams`
| the list of class type params as `List<`{@link io.vertx.codegen.TypeParamInfo.Class}`>`
| `concrete`
| a boolean value indicating if the model is _abstract_ or _concrete_
| `superTypes`
| all direct super types
| `concreteSuperType`
|the concrete direct super type or null
| `abstractSuperTypes`
| a list of all abstract direct super types
| `handlerSuperType`
| the type `io.vertx.core.Handler<T>` when the type implements directly the `Handler` interface
| `methods`
| all the methods as `List<`{@link io.vertx.codegen.MethodInfo}`>`
| `instanceMethods`
| all the instance methods as `List<`{@link io.vertx.codegen.MethodInfo}`>`
| `staticMethods`
| all the static methods as `List<`{@link io.vertx.codegen.MethodInfo}`>`
| `methodsByName`
| a map of methods keyed by name as `Map<String, List<`{@link io.vertx.codegen.MethodInfo}`>>`
| `doc`
| the documentation as {@link io.vertx.codegen.doc.Doc}
|===

todo method info / param info / type param info

=== Data object model

todo

=== Enum model

todo

=== Package model

todo

=== Module model

todo

=== Proxy model

todo

== Code generation

The {@link io.vertx.codegen.CodeGenProcessor} is a Java Annotation Processor that validates and applies
_code generators_ on codegen models.

The processor is declared in the compiler configuration, here is a typical Maven configuration:

[source,xml]
----
<pluginManagement>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <executions>
        <execution>
          <id>default-testCompile</id>
          <configuration>
            <annotationProcessors>
              <annotationProcessor>io.vertx.codegen.CodeGenProcessor</annotationProcessor>
            </annotationProcessors>
            <compilerArgs>
              <arg>-Acodegen.output=${project.basedir}/src/test</arg> <1>
            </compilerArgs>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</pluginManagement>
----
<1> the base output directory for generated files

Code generators are determined from the classpath by looking at the `codegen.json` descriptors, there can
be several generators executed in the same compilation phase. The configuration of a code generator is
quite simple:

[source,json]
----
{
  "name": "Groovy", <1>
  "generators": [ { <2>
    "kind": "class", <3>
    "fileName": "'groovy/' + module.translateQualifiedName(fqn, 'groovy').replace('.', '/') + '.groovy'", <4>
    "templateFileName": "vertx-groovy/template/groovy.templ" <5>
  } ]
}
----
<1> the processor name
<2> an array of generators
<3> the kind of model the generator process : _class_, _dataObject_, _enum_, _package_, _module_, _proxy_
<4> the MVEL expression of the generated file
<5> the MVEL template file name

=== Templating

Templates are written in the MVEL language, documented <a href="https://en.wikisource.org/wiki/MVEL_Language_Guide">here</a>.

Some characters have a special meaning:

- the tab char is used for formatting purpose and is removed
- the *\n* sequence has the same meaning than in a Java string literal

=== Incremental templating

Incremental templating allows the same template to process several models and create a single result. This is
useful when several sources files needs to generate a same file and the output is the result of the models. To
achieve incremental processing, a generator must declares `"incremental": true` in its descriptor.

During the processing phase, the codegen processors collects all the files generated by incremental templates
and groups them by file name. Obviously, the _fileName_ expression of the generator needs to return an appropriate
string.

At the end of the processing phase, templates are invoked for each model, pretty much like the normal templating but
with the following differences:

- the variable `incrementalIndex` gives the sequence number of the current model, starting at 0
- the variable `incrementalSize` gives the total number of models processed by the template
- the variable `session` is a map provided that allows the template to maintain state
- the generated content are appended instead of overwritten

For instance the template:

[source]
----
@if{incrementalIndex==0}
  <html>\n
    <body>\n
      <ul>\n
@end{}
<li>@{type.name}</li>\n
@if{incrementalIndex==incrementalSize-1}
    </ul>\n
  </body>\n
</html>\n
@end{}
----

With `codegen.json`:

[source,json]
----
{
  "name": "index",
  "generators": [ {
    "kind": "class",
    "incremental": true,
    "fileName": "'index.html'",
    "templateFileName": "html-index.templ"
  } ]
}
----

Generates an HTML page with the name of all the API classes.
