Annotations in Providence
The explicit use of annotations is one of the big differences
between Apache Thrift and Providence, and is used for a fair
bit of type modifications.
Syntax
Annotations are specified by adding a set of key-value pairs inside parentheses after a type or field is defined, where the key is a qualified identifier, and the value is a quoted string literal. Note that the annotations apply to whatever was defined before itself. E.g.:
struct MyStruct {
1: string field (annotation.on.field = "value")
2: i32 other (annotation.on.other = "value")
} (annotation.on.struct = "value")
Or in IDL syntax:
ANNOTATIONS ::= '(' ANNOTATION [ [',' ';'] ANNOTATION ]* ')'
ANNOTATION ::= IDENTIFIER ('=' LITERAL)?
ANNOTATED_DEFINITION ::= DEFINITION ANNOTATION?
Annotation Specifications
A number of annotations that modify different subsystems are:
Container Type
The set and map container types uses by default an ImmutableSet or the
ImmutableMap guava classes respectively, which uses a simple hash storage.
Two other variants exists, which is controlled by the container annotations.
container = "SORTED": On fields with set or map type only, will replace the default hash-based container with a sorted container. In java that is theImmutableSortedMapor similar.container = "ORDERED": On fields with set or map type only, will replace the default hash-based container with an order-preserving container. In java that is theLinkedHashMapor similar.
Java Specific Annotations
java.implementsEach java message (union, struct, exception) can implement additional interfaces specified by this annotation. Full package and class name. Note that the message is still a full implementation, so the interface methods need to be implemented (declared) by the generated code, or have default implementations.java.exception.classWhich exception class to inherit from. This must be the full class path of an exception. Note that whether it is an exception is not checked in the generator, it is plainly trusted as the exception class. The exception must have a constructor with a single string argument which sets the exception message.java.service.methods.throwsWhich replaces the declared exceptions with the given exception class on the service interface only. Also note that:- The property is not inherited, and only applies to the methods declared on the service with the annotation.
- All the declared exceptions must extend the given exception.
- The exception class must be available at compile time, and have a constructor that takes the message string only.
- Any exception that not declared, including those that extend the base exception
class will be handled as an application level failure, throwing
PApplicationException. - The client will still only throw the declared exceptions (and
IOException).
java.public.constructorwill create a public constructor with all fields as params. Note that this used to be default on, but is now default off and triggered with this annotation.
Other
message.field: Which field should be used for exception messages. This will default to"message", and will fail silently using the default exception message based ontoString()if the field is not found.deprecated = "<message>": Will mark the associated methods, service or class as being deprecated (should not be used). Since the syntax for deprecating a class is different for each language, it is handled in annotation, and should e.g. generate@Deprecatedannotations in java.json.compact = "": Enables the use of the compact syntax in the json serializer.ref.enum = "program.EnumName": If successfully referencing an enum will add setter for the enum in the builder and arefFieldName()getter that returns the enum name if set AND valid.