Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ void addLogicalTypeConversions(SpecificData specificData) {
private String suffix = ".java";
private List<Object> additionalVelocityTools = Collections.emptyList();

private String nullSafeAnnotationNullable = "org.jetbrains.annotations.Nullable";
private String nullSafeAnnotationNotNull = "org.jetbrains.annotations.NotNull";

private String recordSpecificClass = "org.apache.avro.specific.SpecificRecordBase";

private String errorSpecificClass = "org.apache.avro.specific.SpecificExceptionBase";
Expand Down Expand Up @@ -244,12 +247,42 @@ public boolean isCreateNullSafeAnnotations() {
}

/**
* Set to true to add jetbrains @Nullable and @NotNull annotations
* Set to true to add @Nullable and @NotNull annotations. By default, JetBrains
* annotations are used (org.jetbrains.annotations.Nullable and
* org.jetbrains.annotations.NotNull) but this can be overridden using
* {@link #setNullSafeAnnotationNullable)} and
* {@link #setNullSafeAnnotationNotNull)}.
*/
public void setCreateNullSafeAnnotations(boolean createNullSafeAnnotations) {
this.createNullSafeAnnotations = createNullSafeAnnotations;
}

public String getNullSafeAnnotationNullable() {
return this.nullSafeAnnotationNullable;
}

/**
* Sets the annotation to use for nullable fields. Default is
* "org.jetbrains.annotations.Nullable". The annotation must include the full
* package path.
*/
public void setNullSafeAnnotationNullable(String nullSafeAnnotationNullable) {
this.nullSafeAnnotationNullable = nullSafeAnnotationNullable;
}

public String getNullSafeAnnotationNotNull() {
return this.nullSafeAnnotationNotNull;
}

/**
* Sets the annotation to use for non-nullable fields. Default is
* "org.jetbrains.annotations.NotNull". The annotation must include the full
* package path.
*/
public void setNullSafeAnnotationNotNull(String nullSafeAnnotationNotNull) {
this.nullSafeAnnotationNotNull = nullSafeAnnotationNotNull;
}

public boolean isCreateOptionalGetters() {
return this.createOptionalGetters;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public class ${this.mangleTypeIdentifier($schema.getName())} extends ${this.getS
#end
#end
*/
public ${this.mangleTypeIdentifier($schema.getName())}(#foreach($field in $schema.getFields())#if(${this.createNullSafeAnnotations})#if(${field.schema().isNullable()})@org.jetbrains.annotations.Nullable#else@org.jetbrains.annotations.NotNull#end #end${this.javaType($field.schema())} ${this.mangle($field.name())}#if($foreach.count < $schema.getFields().size()), #end#end) {
public ${this.mangleTypeIdentifier($schema.getName())}(#foreach($field in $schema.getFields())#if(${this.createNullSafeAnnotations})#if(${field.schema().isNullable()})@${this.nullSafeAnnotationNullable}#else@${this.nullSafeAnnotationNotNull}#end #end${this.javaType($field.schema())} ${this.mangle($field.name())}#if($foreach.count < $schema.getFields().size()), #end#end) {
#foreach ($field in $schema.getFields())
${this.generateSetterCode($field.schema(), ${this.mangle($field.name())}, ${this.mangle($field.name())})}
#end
Expand Down Expand Up @@ -244,9 +244,9 @@ public class ${this.mangleTypeIdentifier($schema.getName())} extends ${this.getS
*/
#if(${this.createNullSafeAnnotations})
#if (${field.schema().isNullable()})
@org.jetbrains.annotations.Nullable
@${this.nullSafeAnnotationNullable}
#else
@org.jetbrains.annotations.NotNull
@${this.nullSafeAnnotationNotNull}
#end
#end
public ${this.javaUnbox($field.schema(), false)} ${this.generateGetMethod($schema, $field)}() {
Expand All @@ -273,7 +273,7 @@ public class ${this.mangleTypeIdentifier($schema.getName())} extends ${this.getS
#end
* @param value the value to set.
*/
public void ${this.generateSetMethod($schema, $field)}(#if(${this.createNullSafeAnnotations})#if(${field.schema().isNullable()})@org.jetbrains.annotations.Nullable#else@org.jetbrains.annotations.NotNull#end #end${this.javaUnbox($field.schema(), false)} value) {
public void ${this.generateSetMethod($schema, $field)}(#if(${this.createNullSafeAnnotations})#if(${field.schema().isNullable()})@${this.nullSafeAnnotationNullable}#else@${this.nullSafeAnnotationNotNull}#end #end${this.javaUnbox($field.schema(), false)} value) {
${this.generateSetterCode($field.schema(), ${this.mangle($field.name(), $schema.isError())}, "value")}
}
#end
Expand Down Expand Up @@ -429,7 +429,7 @@ public class ${this.mangleTypeIdentifier($schema.getName())} extends ${this.getS
* @param value The value of '${this.mangle($field.name(), $schema.isError())}'.
* @return This builder.
*/
public #if ($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder ${this.generateSetMethod($schema, $field)}(#if(${this.createNullSafeAnnotations})#if(${field.schema().isNullable()})@org.jetbrains.annotations.Nullable#else@org.jetbrains.annotations.NotNull#end #end${this.javaUnbox($field.schema(), false)} value) {
public #if ($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder ${this.generateSetMethod($schema, $field)}(#if(${this.createNullSafeAnnotations})#if(${field.schema().isNullable()})@${this.nullSafeAnnotationNullable}#else@${this.nullSafeAnnotationNotNull}#end #end${this.javaUnbox($field.schema(), false)} value) {
validate(fields()[$field.pos()], value);
#if (${this.hasBuilder($field.schema())})
this.${this.mangle($field.name(), $schema.isError())}Builder = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,10 @@ public abstract class AbstractAvroMojo extends AbstractMojo {
protected boolean createSetters;

/**
* The createNullSafeAnnotations parameter adds JetBrains {@literal @}Nullable
* and {@literal @}NotNull annotations for fhe fields of the record. The default
* is to not include annotations.
* If set to true, {@literal @}Nullable and {@literal @}NotNull annotations are
* added to fields of the record. The default is false. If enabled, JetBrains
* annotations are used by default but other annotations can be specified via
* the nullSafeAnnotationNullable and nullSafeAnnotationNotNull parameters.
*
* @parameter property="createNullSafeAnnotations"
*
Expand All @@ -195,6 +196,32 @@ public abstract class AbstractAvroMojo extends AbstractMojo {
*/
protected boolean createNullSafeAnnotations = false;

/**
* Controls which annotation should be added to nullable fields if
* createNullSafeAnnotations is enabled. The default is
* org.jetbrains.annotations.Nullable.
*
* @parameter property="nullSafeAnnotationNullable"
*
* @see <a href=
* "https://www.jetbrains.com/help/idea/annotating-source-code.html#nullability-annotations">
* JetBrains nullability annotations</a>
*/
protected String nullSafeAnnotationNullable = "org.jetbrains.annotations.Nullable";

/**
* Controls which annotation should be added to non-nullable fields if
* createNullSafeAnnotations is enabled. The default is
* org.jetbrains.annotations.NotNull.
*
* @parameter property="nullSafeAnnotationNotNull"
*
* @see <a href=
* "https://www.jetbrains.com/help/idea/annotating-source-code.html#nullability-annotations">
* JetBrains nullability annotations</a>
*/
protected String nullSafeAnnotationNotNull = "org.jetbrains.annotations.NotNull";

/**
* A set of fully qualified class names of custom
* {@link org.apache.avro.Conversion} implementations to add to the compiler.
Expand Down Expand Up @@ -405,6 +432,8 @@ private void doCompile(File sourceFileForModificationDetection, SpecificCompiler
compiler.setOptionalGettersForNullableFieldsOnly(optionalGettersForNullableFieldsOnly);
compiler.setCreateSetters(createSetters);
compiler.setCreateNullSafeAnnotations(createNullSafeAnnotations);
compiler.setNullSafeAnnotationNullable(nullSafeAnnotationNullable);
compiler.setNullSafeAnnotationNotNull(nullSafeAnnotationNotNull);
compiler.setEnableDecimalLogicalType(enableDecimalLogicalType);
try {
for (String customConversion : customConversions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,20 @@ public int run(InputStream in, PrintStream out, PrintStream err, List<String> or
if (origArgs.size() < 3) {
System.err
.println("Usage: [-encoding <outputencoding>] [-string] [-bigDecimal] [-fieldVisibility <visibilityType>] "
+ "[-noSetters] [-nullSafeAnnotations] [-addExtraOptionalGetters] [-optionalGetters <optionalGettersType>] "
+ "[-templateDir <templateDir>] (schema|protocol) input... outputdir");
+ "[-noSetters] [-nullSafeAnnotations] [-nullSafeAnnotationNullable <nullableAnnotation>] "
+ "[-nullSafeAnnotationNotNull <notNullAnnotation>] [-addExtraOptionalGetters] "
+ "[-optionalGetters <optionalGettersType>] [-templateDir <templateDir>] "
+ "(schema|protocol) input... outputdir");
System.err.println(" input - input files or directories");
System.err.println(" outputdir - directory to write generated java");
System.err.println(" -encoding <outputencoding> - set the encoding of " + "output file(s)");
System.err.println(" -string - use java.lang.String instead of Utf8");
System.err.println(" -fieldVisibility [private|public] - use either and default private");
System.err.println(" -noSetters - do not generate setters");
System.err.println(" -nullSafeAnnotations - add @Nullable and @NotNull annotations");
System.err.println(" -nullSafeAnnotationNullable - full package path of annotation to use for nullable fields");
System.err
.println(" -nullSafeAnnotationNotNull - full package path of annotation to use for non-nullable fields");
System.err
.println(" -addExtraOptionalGetters - generate extra getters with this format: 'getOptional<FieldName>'");
System.err.println(
Expand All @@ -74,13 +79,16 @@ public int run(InputStream in, PrintStream out, PrintStream err, List<String> or
compilerOpts.useLogicalDecimal = false;
compilerOpts.createSetters = true;
compilerOpts.createNullSafeAnnotations = false;
compilerOpts.nullSafeAnnotationNullable = Optional.empty();
compilerOpts.nullSafeAnnotationNotNull = Optional.empty();
compilerOpts.optionalGettersType = Optional.empty();
compilerOpts.addExtraOptionalGetters = false;
compilerOpts.encoding = Optional.empty();
compilerOpts.templateDir = Optional.empty();
compilerOpts.fieldVisibility = Optional.empty();

List<String> args = new ArrayList<>(origArgs);
int arg = 0;

if (args.contains("-noSetters")) {
compilerOpts.createSetters = false;
Expand All @@ -92,11 +100,24 @@ public int run(InputStream in, PrintStream out, PrintStream err, List<String> or
args.remove(args.indexOf("-nullSafeAnnotations"));
}

if (args.contains("-nullSafeAnnotationNullable")) {
arg = args.indexOf("-nullSafeAnnotationNullable") + 1;
compilerOpts.nullSafeAnnotationNullable = Optional.of(args.get(arg));
args.remove(arg);
args.remove(arg - 1);
}

if (args.contains("-nullSafeAnnotationNotNull")) {
arg = args.indexOf("-nullSafeAnnotationNotNull") + 1;
compilerOpts.nullSafeAnnotationNotNull = Optional.of(args.get(arg));
args.remove(arg);
args.remove(arg - 1);
}

if (args.contains("-addExtraOptionalGetters")) {
compilerOpts.addExtraOptionalGetters = true;
args.remove(args.indexOf("-addExtraOptionalGetters"));
}
int arg = 0;

if (args.contains("-optionalGetters")) {
arg = args.indexOf("-optionalGetters") + 1;
Expand Down Expand Up @@ -180,6 +201,8 @@ private void executeCompiler(SpecificCompiler compiler, CompilerOptions opts, Fi
compiler.setStringType(opts.stringType);
compiler.setCreateSetters(opts.createSetters);
compiler.setCreateNullSafeAnnotations(opts.createNullSafeAnnotations);
opts.nullSafeAnnotationNullable.ifPresent(compiler::setNullSafeAnnotationNullable);
opts.nullSafeAnnotationNotNull.ifPresent(compiler::setNullSafeAnnotationNotNull);

opts.optionalGettersType.ifPresent(choice -> {
compiler.setGettersReturnOptional(true);
Expand Down Expand Up @@ -276,6 +299,8 @@ private static class CompilerOptions {
boolean useLogicalDecimal;
boolean createSetters;
boolean createNullSafeAnnotations;
Optional<String> nullSafeAnnotationNullable;
Optional<String> nullSafeAnnotationNotNull;
boolean addExtraOptionalGetters;
Optional<OptionalGettersType> optionalGettersType;
Optional<String> templateDir;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{"type":"record", "name":"JetBrainsNullSafeAnnotationsFieldsTest", "namespace": "avro.examples.baseball", "doc":"Test that @org.jetbrains.annotations.Nullable and @org.jetbrains.annotations.NotNull annotations are created for all fields",
"fields": [
{"name": "name", "type": "string"},
{"name": "nullable_name", "type": ["string", "null"]},
{"name": "favorite_number", "type": "int"},
{"name": "nullable_favorite_number", "type": ["int", "null"]}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{"type":"record", "name":"JSpecifyNullSafeAnnotationsFieldsTest", "namespace": "avro.examples.baseball", "doc":"Test that @org.jspecify.annotations.Nullable and @org.jspecify.annotations.NonNull annotations are created for all fields",
"fields": [
{"name": "name", "type": "string"},
{"name": "nullable_name", "type": ["string", "null"]},
{"name": "favorite_number", "type": "int"},
{"name": "nullable_favorite_number", "type": ["int", "null"]}
]
}

This file was deleted.

Loading