Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#385] Duplicate field definition error when @ProtoField methods over… #386

Merged
merged 1 commit into from
Jan 7, 2025
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 @@ -529,12 +529,12 @@ private void discoverFieldsFromClassMethods(XClass clazz, Map<Integer, ProtoFiel
}

ProtoFieldMetadata existing = fieldsByNumber.get(number);
if (existing != null) {
if (isDuplicateField(existing, fieldMetadata)) {
throw new ProtoSchemaBuilderException("Duplicate field definition. Found two field definitions with number " + number + ": in "
+ fieldMetadata.getLocation() + " and in " + existing.getLocation());
}
existing = fieldsByName.get(fieldMetadata.getName());
if (existing != null) {
if (isDuplicateField(existing, fieldMetadata)) {
throw new ProtoSchemaBuilderException("Duplicate field definition. Found two field definitions with name '" + fieldMetadata.getName() + "': in "
+ fieldMetadata.getLocation() + " and in " + existing.getLocation());
}
Expand All @@ -547,6 +547,16 @@ private void discoverFieldsFromClassMethods(XClass clazz, Map<Integer, ProtoFiel
}
}

private boolean isDuplicateField(ProtoFieldMetadata existing, ProtoFieldMetadata newField) {
if (existing == null)
return false;

if (existing.isArray() || newField.isArray())
return true;

return !newField.getJavaType().isAssignableTo(existing.getJavaType());
}

private Type defaultType(ProtoField annotation, XClass type) {
Type protobufType = annotation == null ? Type.MESSAGE : annotation.type();
if (type == typeFactory.fromClass(byte[].class) && protobufType == Type.MESSAGE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
Expand Down Expand Up @@ -32,6 +33,7 @@
import org.infinispan.protostream.annotations.ProtoReserved.Range;
import org.infinispan.protostream.annotations.ProtoSchema;
import org.infinispan.protostream.annotations.ProtoSyntax;
import org.infinispan.protostream.annotations.impl.processor.tests.testdomain.Inheritance;
import org.infinispan.protostream.annotations.impl.processor.tests.testdomain.SimpleClass;
import org.infinispan.protostream.annotations.impl.processor.tests.testdomain.SimpleEnum;
import org.infinispan.protostream.annotations.impl.processor.tests.testdomain.SimpleRecord;
Expand Down Expand Up @@ -169,6 +171,43 @@ public void testGeneratedInitializer() throws Exception {
assertTrue(protoFile.contains("@MyCustomAnnotation("));
}

@Test
public void testInheritedTypes() {
SerializationContext ctx = ProtobufUtil.newSerializationContext();

GeneratedSchema schema1 = new ParentClassSCIImpl();
schema1.registerSchema(ctx);
schema1.registerMarshallers(ctx);

GeneratedSchema schema2 = new ChildClassSCIImpl();
schema2.registerSchema(ctx);
schema2.registerMarshallers(ctx);
assertFalse(schema2.getProtoFile().contains("ParentType"));
}

@ProtoSchema(
includeClasses = {
Inheritance.Parent.class,
Inheritance.ParentType.class
},
schemaFileName = "Parent.proto",
schemaFilePath = "org/infinispan/protostream/generated_schemas",
syntax = ProtoSyntax.PROTO3
)
interface ParentClassSCI extends SerializationContextInitializer {}

@ProtoSchema(
dependsOn = ParentClassSCI.class,
includeClasses = {
Inheritance.Child.class,
Inheritance.ChildType.class
},
schemaFileName = "Child.proto",
schemaFilePath = "org/infinispan/protostream/generated_schemas",
syntax = ProtoSyntax.PROTO3
)
interface ChildClassSCI extends SerializationContextInitializer {}

@AutoProtoSchemaBuilder(schemaFilePath = "second_initializer", className = "TestInitializer",
basePackages = "org.infinispan.protostream.annotations.impl.processor", syntax = ProtoSyntax.PROTO3)
abstract static class SecondInitializer implements GeneratedSchema {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.infinispan.protostream.annotations.impl.processor.tests.testdomain;

import org.infinispan.protostream.annotations.ProtoFactory;
import org.infinispan.protostream.annotations.ProtoField;

public class Inheritance {
public static class ParentType {
final String message;

@ProtoFactory
public ParentType(String message) {
this.message = message;
}

@ProtoField(1)
public String getMessage() {
return message;
}
}

public static class ChildType extends ParentType {
@ProtoFactory
public ChildType(String message) {
super(message);
}
}

public static class Parent {
final ParentType field;

@ProtoFactory
public Parent(ParentType field) {
this.field = field;
}

@ProtoField(1)
ParentType getField() {
return field;
}
}

public static class Child extends Parent {
@ProtoFactory
public Child(ChildType field) {
super(field);
}

@ProtoField(1)
ChildType getField() {
return (ChildType) super.getField();
}
}
}
Loading