From b44538d140f6d1ecbfc61ce6bab5dcc13fd65fe2 Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Thu, 13 Feb 2025 00:57:38 +0100 Subject: [PATCH] AVRO-4119: [java] Make Nullable and NotNull annotations configurable Add nullSafeAnnotationNullable and nullSafeAnnotationNotNull configuration options to allow specifying the exact annotations to use when createNullSafeAnnotations is enabled. This allows using annotations besides the JetBrains annotations (which remain the default for backward-compatibility). --- .../compiler/specific/SpecificCompiler.java | 35 +- .../specific/templates/java/classic/record.vm | 10 +- .../apache/avro/mojo/AbstractAvroMojo.java | 35 +- .../avro/tool/SpecificCompilerTool.java | 31 +- ...etbrainsnullsafeannotationsfieldstest.avsc | 8 + ...jspecifynullsafeannotationsfieldstest.avsc | 8 + .../input/nullsafeannotationsfieldstest.avsc | 8 - ...JSpecifyNullSafeAnnotationsFieldsTest.java | 594 ++++++++++++++++++ ...tBrainsNullSafeAnnotationsFieldsTest.java} | 96 +-- .../avro/tool/TestSpecificCompilerTool.java | 33 +- pom.xml | 3 +- 11 files changed, 784 insertions(+), 77 deletions(-) create mode 100644 lang/java/tools/src/test/compiler/input/jetbrainsnullsafeannotationsfieldstest.avsc create mode 100644 lang/java/tools/src/test/compiler/input/jspecifynullsafeannotationsfieldstest.avsc delete mode 100644 lang/java/tools/src/test/compiler/input/nullsafeannotationsfieldstest.avsc create mode 100644 lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JSpecifyNullSafeAnnotationsFieldsTest.java rename lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/{NullSafeAnnotationsFieldsTest.java => JetBrainsNullSafeAnnotationsFieldsTest.java} (73%) diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java index cad00e943f2..31a4a495bfd 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java @@ -131,6 +131,9 @@ void addLogicalTypeConversions(SpecificData specificData) { private String suffix = ".java"; private List 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"; @@ -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; } diff --git a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm index eef50ec7208..d08f099ec93 100755 --- a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm +++ b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm @@ -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 @@ -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)}() { @@ -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 @@ -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; diff --git a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java index 7dc203b0357..282801cbbf9 100644 --- a/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java +++ b/lang/java/maven-plugin/src/main/java/org/apache/avro/mojo/AbstractAvroMojo.java @@ -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" * @@ -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 + * JetBrains nullability annotations + */ + 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 + * JetBrains nullability annotations + */ + 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. @@ -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) { diff --git a/lang/java/tools/src/main/java/org/apache/avro/tool/SpecificCompilerTool.java b/lang/java/tools/src/main/java/org/apache/avro/tool/SpecificCompilerTool.java index d82929e940f..ed55c4ff47b 100644 --- a/lang/java/tools/src/main/java/org/apache/avro/tool/SpecificCompilerTool.java +++ b/lang/java/tools/src/main/java/org/apache/avro/tool/SpecificCompilerTool.java @@ -50,8 +50,10 @@ public int run(InputStream in, PrintStream out, PrintStream err, List or if (origArgs.size() < 3) { System.err .println("Usage: [-encoding ] [-string] [-bigDecimal] [-fieldVisibility ] " - + "[-noSetters] [-nullSafeAnnotations] [-addExtraOptionalGetters] [-optionalGetters ] " - + "[-templateDir ] (schema|protocol) input... outputdir"); + + "[-noSetters] [-nullSafeAnnotations] [-nullSafeAnnotationNullable ] " + + "[-nullSafeAnnotationNotNull ] [-addExtraOptionalGetters] " + + "[-optionalGetters ] [-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 - set the encoding of " + "output file(s)"); @@ -59,6 +61,9 @@ public int run(InputStream in, PrintStream out, PrintStream err, List or 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'"); System.err.println( @@ -74,6 +79,8 @@ public int run(InputStream in, PrintStream out, PrintStream err, List 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(); @@ -81,6 +88,7 @@ public int run(InputStream in, PrintStream out, PrintStream err, List or compilerOpts.fieldVisibility = Optional.empty(); List args = new ArrayList<>(origArgs); + int arg = 0; if (args.contains("-noSetters")) { compilerOpts.createSetters = false; @@ -92,11 +100,24 @@ public int run(InputStream in, PrintStream out, PrintStream err, List 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; @@ -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); @@ -276,6 +299,8 @@ private static class CompilerOptions { boolean useLogicalDecimal; boolean createSetters; boolean createNullSafeAnnotations; + Optional nullSafeAnnotationNullable; + Optional nullSafeAnnotationNotNull; boolean addExtraOptionalGetters; Optional optionalGettersType; Optional templateDir; diff --git a/lang/java/tools/src/test/compiler/input/jetbrainsnullsafeannotationsfieldstest.avsc b/lang/java/tools/src/test/compiler/input/jetbrainsnullsafeannotationsfieldstest.avsc new file mode 100644 index 00000000000..07d9d904be0 --- /dev/null +++ b/lang/java/tools/src/test/compiler/input/jetbrainsnullsafeannotationsfieldstest.avsc @@ -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"]} + ] +} diff --git a/lang/java/tools/src/test/compiler/input/jspecifynullsafeannotationsfieldstest.avsc b/lang/java/tools/src/test/compiler/input/jspecifynullsafeannotationsfieldstest.avsc new file mode 100644 index 00000000000..e20ad36b1b6 --- /dev/null +++ b/lang/java/tools/src/test/compiler/input/jspecifynullsafeannotationsfieldstest.avsc @@ -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"]} + ] +} diff --git a/lang/java/tools/src/test/compiler/input/nullsafeannotationsfieldstest.avsc b/lang/java/tools/src/test/compiler/input/nullsafeannotationsfieldstest.avsc deleted file mode 100644 index 04ef43e34ef..00000000000 --- a/lang/java/tools/src/test/compiler/input/nullsafeannotationsfieldstest.avsc +++ /dev/null @@ -1,8 +0,0 @@ -{"type":"record", "name":"NullSafeAnnotationsFieldsTest", "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"]} - ] -} diff --git a/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JSpecifyNullSafeAnnotationsFieldsTest.java b/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JSpecifyNullSafeAnnotationsFieldsTest.java new file mode 100644 index 00000000000..1fa56857f8f --- /dev/null +++ b/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JSpecifyNullSafeAnnotationsFieldsTest.java @@ -0,0 +1,594 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package avro.examples.baseball; + +import org.apache.avro.specific.SpecificData; +import org.apache.avro.util.Utf8; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +/** Test that @org.jspecify.annotations.Nullable and @org.jspecify.annotations.NonNull annotations are created for all fields */ +@org.apache.avro.specific.AvroGenerated +public class JSpecifyNullSafeAnnotationsFieldsTest extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = 2433229483110849489L; + + + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"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\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"nullable_name\",\"type\":[{\"type\":\"string\",\"avro.java.string\":\"String\"},\"null\"]},{\"name\":\"favorite_number\",\"type\":\"int\"},{\"name\":\"nullable_favorite_number\",\"type\":[\"int\",\"null\"]}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static final SpecificData MODEL$ = new SpecificData(); + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder<>(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder<>(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageEncoder instance used by this class. + * @return the message encoder used by this class + */ + public static BinaryMessageEncoder getEncoder() { + return ENCODER; + } + + /** + * Return the BinaryMessageDecoder instance used by this class. + * @return the message decoder used by this class + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder<>(MODEL$, SCHEMA$, resolver); + } + + /** + * Serializes this JSpecifyNullSafeAnnotationsFieldsTest to a ByteBuffer. + * @return a buffer holding the serialized data for this instance + * @throws java.io.IOException if this instance could not be serialized + */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** + * Deserializes a JSpecifyNullSafeAnnotationsFieldsTest from a ByteBuffer. + * @param b a byte buffer holding serialized data for an instance of this class + * @return a JSpecifyNullSafeAnnotationsFieldsTest instance decoded from the given buffer + * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class + */ + public static JSpecifyNullSafeAnnotationsFieldsTest fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + private java.lang.String name; + private java.lang.String nullable_name; + private int favorite_number; + private java.lang.Integer nullable_favorite_number; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public JSpecifyNullSafeAnnotationsFieldsTest() {} + + /** + * All-args constructor. + * @param name The new value for name + * @param nullable_name The new value for nullable_name + * @param favorite_number The new value for favorite_number + * @param nullable_favorite_number The new value for nullable_favorite_number + */ + public JSpecifyNullSafeAnnotationsFieldsTest(@org.jspecify.annotations.NonNull java.lang.String name, @org.jspecify.annotations.Nullable java.lang.String nullable_name, @org.jspecify.annotations.NonNull java.lang.Integer favorite_number, @org.jspecify.annotations.Nullable java.lang.Integer nullable_favorite_number) { + this.name = name; + this.nullable_name = nullable_name; + this.favorite_number = favorite_number; + this.nullable_favorite_number = nullable_favorite_number; + } + + @Override + public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; } + + @Override + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + + // Used by DatumWriter. Applications should not call. + @Override + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return name; + case 1: return nullable_name; + case 2: return favorite_number; + case 3: return nullable_favorite_number; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + // Used by DatumReader. Applications should not call. + @Override + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: name = value$ != null ? value$.toString() : null; break; + case 1: nullable_name = value$ != null ? value$.toString() : null; break; + case 2: favorite_number = (java.lang.Integer)value$; break; + case 3: nullable_favorite_number = (java.lang.Integer)value$; break; + default: throw new IndexOutOfBoundsException("Invalid index: " + field$); + } + } + + /** + * Gets the value of the 'name' field. + * @return The value of the 'name' field. + */ + @org.jspecify.annotations.NonNull + public java.lang.String getName() { + return name; + } + + + /** + * Sets the value of the 'name' field. + * @param value the value to set. + */ + public void setName(@org.jspecify.annotations.NonNull java.lang.String value) { + this.name = value; + } + + /** + * Gets the value of the 'nullable_name' field. + * @return The value of the 'nullable_name' field. + */ + @org.jspecify.annotations.Nullable + public java.lang.String getNullableName() { + return nullable_name; + } + + + /** + * Sets the value of the 'nullable_name' field. + * @param value the value to set. + */ + public void setNullableName(@org.jspecify.annotations.Nullable java.lang.String value) { + this.nullable_name = value; + } + + /** + * Gets the value of the 'favorite_number' field. + * @return The value of the 'favorite_number' field. + */ + @org.jspecify.annotations.NonNull + public int getFavoriteNumber() { + return favorite_number; + } + + + /** + * Sets the value of the 'favorite_number' field. + * @param value the value to set. + */ + public void setFavoriteNumber(@org.jspecify.annotations.NonNull int value) { + this.favorite_number = value; + } + + /** + * Gets the value of the 'nullable_favorite_number' field. + * @return The value of the 'nullable_favorite_number' field. + */ + @org.jspecify.annotations.Nullable + public java.lang.Integer getNullableFavoriteNumber() { + return nullable_favorite_number; + } + + + /** + * Sets the value of the 'nullable_favorite_number' field. + * @param value the value to set. + */ + public void setNullableFavoriteNumber(@org.jspecify.annotations.Nullable java.lang.Integer value) { + this.nullable_favorite_number = value; + } + + /** + * Creates a new JSpecifyNullSafeAnnotationsFieldsTest RecordBuilder. + * @return A new JSpecifyNullSafeAnnotationsFieldsTest RecordBuilder + */ + public static avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder newBuilder() { + return new avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder(); + } + + /** + * Creates a new JSpecifyNullSafeAnnotationsFieldsTest RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new JSpecifyNullSafeAnnotationsFieldsTest RecordBuilder + */ + public static avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder newBuilder(avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder other) { + if (other == null) { + return new avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder(); + } else { + return new avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder(other); + } + } + + /** + * Creates a new JSpecifyNullSafeAnnotationsFieldsTest RecordBuilder by copying an existing JSpecifyNullSafeAnnotationsFieldsTest instance. + * @param other The existing instance to copy. + * @return A new JSpecifyNullSafeAnnotationsFieldsTest RecordBuilder + */ + public static avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder newBuilder(avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest other) { + if (other == null) { + return new avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder(); + } else { + return new avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder(other); + } + } + + /** + * RecordBuilder for JSpecifyNullSafeAnnotationsFieldsTest instances. + */ + @org.apache.avro.specific.AvroGenerated + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private java.lang.String name; + private java.lang.String nullable_name; + private int favorite_number; + private java.lang.Integer nullable_favorite_number; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$, MODEL$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder other) { + super(other); + if (isValidValue(fields()[0], other.name)) { + this.name = data().deepCopy(fields()[0].schema(), other.name); + fieldSetFlags()[0] = other.fieldSetFlags()[0]; + } + if (isValidValue(fields()[1], other.nullable_name)) { + this.nullable_name = data().deepCopy(fields()[1].schema(), other.nullable_name); + fieldSetFlags()[1] = other.fieldSetFlags()[1]; + } + if (isValidValue(fields()[2], other.favorite_number)) { + this.favorite_number = data().deepCopy(fields()[2].schema(), other.favorite_number); + fieldSetFlags()[2] = other.fieldSetFlags()[2]; + } + if (isValidValue(fields()[3], other.nullable_favorite_number)) { + this.nullable_favorite_number = data().deepCopy(fields()[3].schema(), other.nullable_favorite_number); + fieldSetFlags()[3] = other.fieldSetFlags()[3]; + } + } + + /** + * Creates a Builder by copying an existing JSpecifyNullSafeAnnotationsFieldsTest instance + * @param other The existing instance to copy. + */ + private Builder(avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest other) { + super(SCHEMA$, MODEL$); + if (isValidValue(fields()[0], other.name)) { + this.name = data().deepCopy(fields()[0].schema(), other.name); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.nullable_name)) { + this.nullable_name = data().deepCopy(fields()[1].schema(), other.nullable_name); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.favorite_number)) { + this.favorite_number = data().deepCopy(fields()[2].schema(), other.favorite_number); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.nullable_favorite_number)) { + this.nullable_favorite_number = data().deepCopy(fields()[3].schema(), other.nullable_favorite_number); + fieldSetFlags()[3] = true; + } + } + + /** + * Gets the value of the 'name' field. + * @return The value. + */ + public java.lang.String getName() { + return name; + } + + + /** + * Sets the value of the 'name' field. + * @param value The value of 'name'. + * @return This builder. + */ + public avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder setName(@org.jspecify.annotations.NonNull java.lang.String value) { + validate(fields()[0], value); + this.name = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'name' field has been set. + * @return True if the 'name' field has been set, false otherwise. + */ + public boolean hasName() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'name' field. + * @return This builder. + */ + public avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder clearName() { + name = null; + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'nullable_name' field. + * @return The value. + */ + public java.lang.String getNullableName() { + return nullable_name; + } + + + /** + * Sets the value of the 'nullable_name' field. + * @param value The value of 'nullable_name'. + * @return This builder. + */ + public avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder setNullableName(@org.jspecify.annotations.Nullable java.lang.String value) { + validate(fields()[1], value); + this.nullable_name = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'nullable_name' field has been set. + * @return True if the 'nullable_name' field has been set, false otherwise. + */ + public boolean hasNullableName() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'nullable_name' field. + * @return This builder. + */ + public avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder clearNullableName() { + nullable_name = null; + fieldSetFlags()[1] = false; + return this; + } + + /** + * Gets the value of the 'favorite_number' field. + * @return The value. + */ + public int getFavoriteNumber() { + return favorite_number; + } + + + /** + * Sets the value of the 'favorite_number' field. + * @param value The value of 'favorite_number'. + * @return This builder. + */ + public avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder setFavoriteNumber(@org.jspecify.annotations.NonNull int value) { + validate(fields()[2], value); + this.favorite_number = value; + fieldSetFlags()[2] = true; + return this; + } + + /** + * Checks whether the 'favorite_number' field has been set. + * @return True if the 'favorite_number' field has been set, false otherwise. + */ + public boolean hasFavoriteNumber() { + return fieldSetFlags()[2]; + } + + + /** + * Clears the value of the 'favorite_number' field. + * @return This builder. + */ + public avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder clearFavoriteNumber() { + fieldSetFlags()[2] = false; + return this; + } + + /** + * Gets the value of the 'nullable_favorite_number' field. + * @return The value. + */ + public java.lang.Integer getNullableFavoriteNumber() { + return nullable_favorite_number; + } + + + /** + * Sets the value of the 'nullable_favorite_number' field. + * @param value The value of 'nullable_favorite_number'. + * @return This builder. + */ + public avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder setNullableFavoriteNumber(@org.jspecify.annotations.Nullable java.lang.Integer value) { + validate(fields()[3], value); + this.nullable_favorite_number = value; + fieldSetFlags()[3] = true; + return this; + } + + /** + * Checks whether the 'nullable_favorite_number' field has been set. + * @return True if the 'nullable_favorite_number' field has been set, false otherwise. + */ + public boolean hasNullableFavoriteNumber() { + return fieldSetFlags()[3]; + } + + + /** + * Clears the value of the 'nullable_favorite_number' field. + * @return This builder. + */ + public avro.examples.baseball.JSpecifyNullSafeAnnotationsFieldsTest.Builder clearNullableFavoriteNumber() { + nullable_favorite_number = null; + fieldSetFlags()[3] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public JSpecifyNullSafeAnnotationsFieldsTest build() { + try { + JSpecifyNullSafeAnnotationsFieldsTest record = new JSpecifyNullSafeAnnotationsFieldsTest(); + record.name = fieldSetFlags()[0] ? this.name : (java.lang.String) defaultValue(fields()[0]); + record.nullable_name = fieldSetFlags()[1] ? this.nullable_name : (java.lang.String) defaultValue(fields()[1]); + record.favorite_number = fieldSetFlags()[2] ? this.favorite_number : (java.lang.Integer) defaultValue(fields()[2]); + record.nullable_favorite_number = fieldSetFlags()[3] ? this.nullable_favorite_number : (java.lang.Integer) defaultValue(fields()[3]); + return record; + } catch (org.apache.avro.AvroMissingFieldException e) { + throw e; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + + @Override protected boolean hasCustomCoders() { return true; } + + @Override public void customEncode(org.apache.avro.io.Encoder out) + throws java.io.IOException + { + out.writeString(this.name); + + if (this.nullable_name == null) { + out.writeIndex(1); + out.writeNull(); + } else { + out.writeIndex(0); + out.writeString(this.nullable_name); + } + + out.writeInt(this.favorite_number); + + if (this.nullable_favorite_number == null) { + out.writeIndex(1); + out.writeNull(); + } else { + out.writeIndex(0); + out.writeInt(this.nullable_favorite_number); + } + + } + + @Override public void customDecode(org.apache.avro.io.ResolvingDecoder in) + throws java.io.IOException + { + org.apache.avro.Schema.Field[] fieldOrder = in.readFieldOrderIfDiff(); + if (fieldOrder == null) { + this.name = in.readString(); + + if (in.readIndex() != 0) { + in.readNull(); + this.nullable_name = null; + } else { + this.nullable_name = in.readString(); + } + + this.favorite_number = in.readInt(); + + if (in.readIndex() != 0) { + in.readNull(); + this.nullable_favorite_number = null; + } else { + this.nullable_favorite_number = in.readInt(); + } + + } else { + for (int i = 0; i < 4; i++) { + switch (fieldOrder[i].pos()) { + case 0: + this.name = in.readString(); + break; + + case 1: + if (in.readIndex() != 0) { + in.readNull(); + this.nullable_name = null; + } else { + this.nullable_name = in.readString(); + } + break; + + case 2: + this.favorite_number = in.readInt(); + break; + + case 3: + if (in.readIndex() != 0) { + in.readNull(); + this.nullable_favorite_number = null; + } else { + this.nullable_favorite_number = in.readInt(); + } + break; + + default: + throw new java.io.IOException("Corrupt ResolvingDecoder."); + } + } + } + } +} + + + + + + + + + + diff --git a/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/NullSafeAnnotationsFieldsTest.java b/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JetBrainsNullSafeAnnotationsFieldsTest.java similarity index 73% rename from lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/NullSafeAnnotationsFieldsTest.java rename to lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JetBrainsNullSafeAnnotationsFieldsTest.java index 1da1fcde0e5..44db6edcae1 100644 --- a/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/NullSafeAnnotationsFieldsTest.java +++ b/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JetBrainsNullSafeAnnotationsFieldsTest.java @@ -13,26 +13,26 @@ /** Test that @org.jetbrains.annotations.Nullable and @org.jetbrains.annotations.NotNull annotations are created for all fields */ @org.apache.avro.specific.AvroGenerated -public class NullSafeAnnotationsFieldsTest extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { - private static final long serialVersionUID = 2020521726426674816L; +public class JetBrainsNullSafeAnnotationsFieldsTest extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = 4199351420542345651L; - public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"NullSafeAnnotationsFieldsTest\",\"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\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"nullable_name\",\"type\":[{\"type\":\"string\",\"avro.java.string\":\"String\"},\"null\"]},{\"name\":\"favorite_number\",\"type\":\"int\"},{\"name\":\"nullable_favorite_number\",\"type\":[\"int\",\"null\"]}]}"); + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"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\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"nullable_name\",\"type\":[{\"type\":\"string\",\"avro.java.string\":\"String\"},\"null\"]},{\"name\":\"favorite_number\",\"type\":\"int\"},{\"name\":\"nullable_favorite_number\",\"type\":[\"int\",\"null\"]}]}"); public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } private static final SpecificData MODEL$ = new SpecificData(); - private static final BinaryMessageEncoder ENCODER = + private static final BinaryMessageEncoder ENCODER = new BinaryMessageEncoder<>(MODEL$, SCHEMA$); - private static final BinaryMessageDecoder DECODER = + private static final BinaryMessageDecoder DECODER = new BinaryMessageDecoder<>(MODEL$, SCHEMA$); /** * Return the BinaryMessageEncoder instance used by this class. * @return the message encoder used by this class */ - public static BinaryMessageEncoder getEncoder() { + public static BinaryMessageEncoder getEncoder() { return ENCODER; } @@ -40,7 +40,7 @@ public static BinaryMessageEncoder getEncoder() { * Return the BinaryMessageDecoder instance used by this class. * @return the message decoder used by this class */ - public static BinaryMessageDecoder getDecoder() { + public static BinaryMessageDecoder getDecoder() { return DECODER; } @@ -49,12 +49,12 @@ public static BinaryMessageDecoder getDecoder() { * @param resolver a {@link SchemaStore} used to find schemas by fingerprint * @return a BinaryMessageDecoder instance for this class backed by the given SchemaStore */ - public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { return new BinaryMessageDecoder<>(MODEL$, SCHEMA$, resolver); } /** - * Serializes this NullSafeAnnotationsFieldsTest to a ByteBuffer. + * Serializes this JetBrainsNullSafeAnnotationsFieldsTest to a ByteBuffer. * @return a buffer holding the serialized data for this instance * @throws java.io.IOException if this instance could not be serialized */ @@ -63,12 +63,12 @@ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { } /** - * Deserializes a NullSafeAnnotationsFieldsTest from a ByteBuffer. + * Deserializes a JetBrainsNullSafeAnnotationsFieldsTest from a ByteBuffer. * @param b a byte buffer holding serialized data for an instance of this class - * @return a NullSafeAnnotationsFieldsTest instance decoded from the given buffer + * @return a JetBrainsNullSafeAnnotationsFieldsTest instance decoded from the given buffer * @throws java.io.IOException if the given bytes could not be deserialized into an instance of this class */ - public static NullSafeAnnotationsFieldsTest fromByteBuffer( + public static JetBrainsNullSafeAnnotationsFieldsTest fromByteBuffer( java.nio.ByteBuffer b) throws java.io.IOException { return DECODER.decode(b); } @@ -83,7 +83,7 @@ public static NullSafeAnnotationsFieldsTest fromByteBuffer( * to their default values from the schema. If that is desired then * one should use newBuilder(). */ - public NullSafeAnnotationsFieldsTest() {} + public JetBrainsNullSafeAnnotationsFieldsTest() {} /** * All-args constructor. @@ -92,7 +92,7 @@ public NullSafeAnnotationsFieldsTest() {} * @param favorite_number The new value for favorite_number * @param nullable_favorite_number The new value for nullable_favorite_number */ - public NullSafeAnnotationsFieldsTest(@org.jetbrains.annotations.NotNull java.lang.String name, @org.jetbrains.annotations.Nullable java.lang.String nullable_name, @org.jetbrains.annotations.NotNull java.lang.Integer favorite_number, @org.jetbrains.annotations.Nullable java.lang.Integer nullable_favorite_number) { + public JetBrainsNullSafeAnnotationsFieldsTest(@org.jetbrains.annotations.NotNull java.lang.String name, @org.jetbrains.annotations.Nullable java.lang.String nullable_name, @org.jetbrains.annotations.NotNull java.lang.Integer favorite_number, @org.jetbrains.annotations.Nullable java.lang.Integer nullable_favorite_number) { this.name = name; this.nullable_name = nullable_name; this.favorite_number = favorite_number; @@ -203,45 +203,45 @@ public void setNullableFavoriteNumber(@org.jetbrains.annotations.Nullable java.l } /** - * Creates a new NullSafeAnnotationsFieldsTest RecordBuilder. - * @return A new NullSafeAnnotationsFieldsTest RecordBuilder + * Creates a new JetBrainsNullSafeAnnotationsFieldsTest RecordBuilder. + * @return A new JetBrainsNullSafeAnnotationsFieldsTest RecordBuilder */ - public static avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder newBuilder() { - return new avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder(); + public static avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder newBuilder() { + return new avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder(); } /** - * Creates a new NullSafeAnnotationsFieldsTest RecordBuilder by copying an existing Builder. + * Creates a new JetBrainsNullSafeAnnotationsFieldsTest RecordBuilder by copying an existing Builder. * @param other The existing builder to copy. - * @return A new NullSafeAnnotationsFieldsTest RecordBuilder + * @return A new JetBrainsNullSafeAnnotationsFieldsTest RecordBuilder */ - public static avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder newBuilder(avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder other) { + public static avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder newBuilder(avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder other) { if (other == null) { - return new avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder(); + return new avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder(); } else { - return new avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder(other); + return new avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder(other); } } /** - * Creates a new NullSafeAnnotationsFieldsTest RecordBuilder by copying an existing NullSafeAnnotationsFieldsTest instance. + * Creates a new JetBrainsNullSafeAnnotationsFieldsTest RecordBuilder by copying an existing JetBrainsNullSafeAnnotationsFieldsTest instance. * @param other The existing instance to copy. - * @return A new NullSafeAnnotationsFieldsTest RecordBuilder + * @return A new JetBrainsNullSafeAnnotationsFieldsTest RecordBuilder */ - public static avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder newBuilder(avro.examples.baseball.NullSafeAnnotationsFieldsTest other) { + public static avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder newBuilder(avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest other) { if (other == null) { - return new avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder(); + return new avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder(); } else { - return new avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder(other); + return new avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder(other); } } /** - * RecordBuilder for NullSafeAnnotationsFieldsTest instances. + * RecordBuilder for JetBrainsNullSafeAnnotationsFieldsTest instances. */ @org.apache.avro.specific.AvroGenerated - public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase - implements org.apache.avro.data.RecordBuilder { + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { private java.lang.String name; private java.lang.String nullable_name; @@ -257,7 +257,7 @@ private Builder() { * Creates a Builder by copying an existing Builder. * @param other The existing Builder to copy. */ - private Builder(avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder other) { + private Builder(avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder other) { super(other); if (isValidValue(fields()[0], other.name)) { this.name = data().deepCopy(fields()[0].schema(), other.name); @@ -278,10 +278,10 @@ private Builder(avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder oth } /** - * Creates a Builder by copying an existing NullSafeAnnotationsFieldsTest instance + * Creates a Builder by copying an existing JetBrainsNullSafeAnnotationsFieldsTest instance * @param other The existing instance to copy. */ - private Builder(avro.examples.baseball.NullSafeAnnotationsFieldsTest other) { + private Builder(avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest other) { super(SCHEMA$, MODEL$); if (isValidValue(fields()[0], other.name)) { this.name = data().deepCopy(fields()[0].schema(), other.name); @@ -315,7 +315,7 @@ public java.lang.String getName() { * @param value The value of 'name'. * @return This builder. */ - public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder setName(@org.jetbrains.annotations.NotNull java.lang.String value) { + public avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder setName(@org.jetbrains.annotations.NotNull java.lang.String value) { validate(fields()[0], value); this.name = value; fieldSetFlags()[0] = true; @@ -335,7 +335,7 @@ public boolean hasName() { * Clears the value of the 'name' field. * @return This builder. */ - public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder clearName() { + public avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder clearName() { name = null; fieldSetFlags()[0] = false; return this; @@ -355,7 +355,7 @@ public java.lang.String getNullableName() { * @param value The value of 'nullable_name'. * @return This builder. */ - public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder setNullableName(@org.jetbrains.annotations.Nullable java.lang.String value) { + public avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder setNullableName(@org.jetbrains.annotations.Nullable java.lang.String value) { validate(fields()[1], value); this.nullable_name = value; fieldSetFlags()[1] = true; @@ -375,7 +375,7 @@ public boolean hasNullableName() { * Clears the value of the 'nullable_name' field. * @return This builder. */ - public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder clearNullableName() { + public avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder clearNullableName() { nullable_name = null; fieldSetFlags()[1] = false; return this; @@ -395,7 +395,7 @@ public int getFavoriteNumber() { * @param value The value of 'favorite_number'. * @return This builder. */ - public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder setFavoriteNumber(@org.jetbrains.annotations.NotNull int value) { + public avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder setFavoriteNumber(@org.jetbrains.annotations.NotNull int value) { validate(fields()[2], value); this.favorite_number = value; fieldSetFlags()[2] = true; @@ -415,7 +415,7 @@ public boolean hasFavoriteNumber() { * Clears the value of the 'favorite_number' field. * @return This builder. */ - public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder clearFavoriteNumber() { + public avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder clearFavoriteNumber() { fieldSetFlags()[2] = false; return this; } @@ -434,7 +434,7 @@ public java.lang.Integer getNullableFavoriteNumber() { * @param value The value of 'nullable_favorite_number'. * @return This builder. */ - public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder setNullableFavoriteNumber(@org.jetbrains.annotations.Nullable java.lang.Integer value) { + public avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder setNullableFavoriteNumber(@org.jetbrains.annotations.Nullable java.lang.Integer value) { validate(fields()[3], value); this.nullable_favorite_number = value; fieldSetFlags()[3] = true; @@ -454,7 +454,7 @@ public boolean hasNullableFavoriteNumber() { * Clears the value of the 'nullable_favorite_number' field. * @return This builder. */ - public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder clearNullableFavoriteNumber() { + public avro.examples.baseball.JetBrainsNullSafeAnnotationsFieldsTest.Builder clearNullableFavoriteNumber() { nullable_favorite_number = null; fieldSetFlags()[3] = false; return this; @@ -462,9 +462,9 @@ public avro.examples.baseball.NullSafeAnnotationsFieldsTest.Builder clearNullabl @Override @SuppressWarnings("unchecked") - public NullSafeAnnotationsFieldsTest build() { + public JetBrainsNullSafeAnnotationsFieldsTest build() { try { - NullSafeAnnotationsFieldsTest record = new NullSafeAnnotationsFieldsTest(); + JetBrainsNullSafeAnnotationsFieldsTest record = new JetBrainsNullSafeAnnotationsFieldsTest(); record.name = fieldSetFlags()[0] ? this.name : (java.lang.String) defaultValue(fields()[0]); record.nullable_name = fieldSetFlags()[1] ? this.nullable_name : (java.lang.String) defaultValue(fields()[1]); record.favorite_number = fieldSetFlags()[2] ? this.favorite_number : (java.lang.Integer) defaultValue(fields()[2]); @@ -479,8 +479,8 @@ public NullSafeAnnotationsFieldsTest build() { } @SuppressWarnings("unchecked") - private static final org.apache.avro.io.DatumWriter - WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); @Override public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException { @@ -488,8 +488,8 @@ public NullSafeAnnotationsFieldsTest build() { } @SuppressWarnings("unchecked") - private static final org.apache.avro.io.DatumReader - READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); @Override public void readExternal(java.io.ObjectInput in) throws java.io.IOException { diff --git a/lang/java/tools/src/test/java/org/apache/avro/tool/TestSpecificCompilerTool.java b/lang/java/tools/src/test/java/org/apache/avro/tool/TestSpecificCompilerTool.java index 03768fea4b6..1f4aac91f96 100644 --- a/lang/java/tools/src/test/java/org/apache/avro/tool/TestSpecificCompilerTool.java +++ b/lang/java/tools/src/test/java/org/apache/avro/tool/TestSpecificCompilerTool.java @@ -58,8 +58,10 @@ public class TestSpecificCompilerTool { "avro/examples/baseball/Position.java"); private static final File TEST_EXPECTED_STRING_PLAYER = new File(TEST_EXPECTED_STRING_OUTPUT_DIR, "avro/examples/baseball/Player.java"); - private static final File TEST_EXPECTED_STRING_NULL_SAFE_ANNOTATIONS_TEST = new File(TEST_EXPECTED_STRING_OUTPUT_DIR, - "avro/examples/baseball/NullSafeAnnotationsFieldsTest.java"); + private static final File TEST_EXPECTED_STRING_JET_BRAINS_NULL_SAFE_ANNOTATIONS_TEST = new File( + TEST_EXPECTED_STRING_OUTPUT_DIR, "avro/examples/baseball/JetBrainsNullSafeAnnotationsFieldsTest.java"); + private static final File TEST_EXPECTED_STRING_JSPECIFY_NULL_SAFE_ANNOTATIONS_TEST = new File( + TEST_EXPECTED_STRING_OUTPUT_DIR, "avro/examples/baseball/JSpecifyNullSafeAnnotationsFieldsTest.java"); private static final File TEST_EXPECTED_STRING_FIELDTEST = new File(TEST_EXPECTED_STRING_OUTPUT_DIR, "avro/examples/baseball/FieldTest.java"); private static final File TEST_EXPECTED_STRING_PROTO = new File(TEST_EXPECTED_STRING_OUTPUT_DIR, @@ -85,8 +87,10 @@ public class TestSpecificCompilerTool { "avro/examples/baseball/Position.java"); private static final File TEST_OUTPUT_STRING_FIELDTEST = new File(TEST_OUTPUT_STRING_DIR, "avro/examples/baseball/FieldTest.java"); - private static final File TEST_OUTPUT_STRING_NULL_SAFE_ANNOTATIONS_TEST = new File(TEST_OUTPUT_STRING_DIR, - "avro/examples/baseball/NullSafeAnnotationsFieldsTest.java"); + private static final File TEST_OUTPUT_STRING_JET_BRAINS_NULL_SAFE_ANNOTATIONS_TEST = new File(TEST_OUTPUT_STRING_DIR, + "avro/examples/baseball/JetBrainsNullSafeAnnotationsFieldsTest.java"); + private static final File TEST_OUTPUT_STRING_JSPECIFY_NULL_SAFE_ANNOTATIONS_TEST = new File(TEST_OUTPUT_STRING_DIR, + "avro/examples/baseball/JSpecifyNullSafeAnnotationsFieldsTest.java"); private static final File TEST_OUTPUT_STRING_PROTO = new File(TEST_OUTPUT_STRING_DIR, "avro/examples/baseball/Proto.java"); @@ -114,12 +118,25 @@ void compileSchemaWithOptionalGettersForNullableFieldsOnly() throws Exception { } @Test - void compileSchemaWithNullSafeAnnotationsFields() throws Exception { + void compileSchemaWithJetBrainsNullSafeAnnotationsFields() throws Exception { - TEST_OUTPUT_STRING_NULL_SAFE_ANNOTATIONS_TEST.delete(); + TEST_OUTPUT_STRING_JET_BRAINS_NULL_SAFE_ANNOTATIONS_TEST.delete(); doCompile(new String[] { "-encoding", "UTF-8", "-nullSafeAnnotations", "-string", "schema", - TEST_INPUT_DIR.toString() + "/nullsafeannotationsfieldstest.avsc", TEST_OUTPUT_STRING_DIR.getPath() }); - assertFileMatch(TEST_EXPECTED_STRING_NULL_SAFE_ANNOTATIONS_TEST, TEST_OUTPUT_STRING_NULL_SAFE_ANNOTATIONS_TEST); + TEST_INPUT_DIR.toString() + "/jetbrainsnullsafeannotationsfieldstest.avsc", TEST_OUTPUT_STRING_DIR.getPath() }); + assertFileMatch(TEST_EXPECTED_STRING_JET_BRAINS_NULL_SAFE_ANNOTATIONS_TEST, + TEST_OUTPUT_STRING_JET_BRAINS_NULL_SAFE_ANNOTATIONS_TEST); + } + + @Test + void compileSchemaWithJSpecifyNullSafeAnnotationsFields() throws Exception { + + TEST_OUTPUT_STRING_JSPECIFY_NULL_SAFE_ANNOTATIONS_TEST.delete(); + doCompile(new String[] { "-encoding", "UTF-8", "-nullSafeAnnotations", "-nullSafeAnnotationNullable", + "org.jspecify.annotations.Nullable", "-nullSafeAnnotationNotNull", "org.jspecify.annotations.NonNull", + "-string", "schema", TEST_INPUT_DIR.toString() + "/jspecifynullsafeannotationsfieldstest.avsc", + TEST_OUTPUT_STRING_DIR.getPath() }); + assertFileMatch(TEST_EXPECTED_STRING_JSPECIFY_NULL_SAFE_ANNOTATIONS_TEST, + TEST_OUTPUT_STRING_JSPECIFY_NULL_SAFE_ANNOTATIONS_TEST); } @Test diff --git a/pom.xml b/pom.xml index 9f6c3f925ce..5dcc7e3f846 100644 --- a/pom.xml +++ b/pom.xml @@ -457,7 +457,8 @@ lang/java/avro/src/test/java/org/apache/avro/specific/TestRecordWithoutLogicalTypes.java lang/java/avro/src/test/java/org/apache/avro/specific/int$.java lang/java/ipc-netty/src/test/resources/**/*.txt - lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/NullSafeAnnotationsFieldsTest.java + lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JetBrainsNullSafeAnnotationsFieldsTest.java + lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/JSpecifyNullSafeAnnotationsFieldsTest.java lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Player.java lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Position.java lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/FieldTest.java