Skip to content

Commit

Permalink
Make Serializable and Memoized extensions work together.
Browse files Browse the repository at this point in the history
The Serializable extension has to call the constructor of the AutoValue class as part of its implementation of `readResolve`. The class whose constructor is called must be the *final* one in the chain of subclasses generated by extensions. That is not necessarily the subclass generated by the Serializable extension.

RELNOTES=Fixed an issue when Serializable and Memoized extensions are used together.
PiperOrigin-RevId: 430458407
  • Loading branch information
eamonnmcmanus authored and Google Java Core Libraries committed Feb 23, 2022
1 parent d11a8a7 commit e01968d
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ private static final class Generator {
.collect(toImmutableList());

TypeName classTypeName =
getClassTypeName(ClassName.get(context.packageName(), className), typeVariableNames);
getClassTypeName(
ClassName.get(context.packageName(), context.finalAutoValueClassName()),
typeVariableNames);
this.proxyGenerator =
new ProxyGenerator(
classTypeName, typeVariableNames, propertyMirrors, buildSerializersMap());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static org.junit.Assert.assertThrows;

import com.google.auto.value.AutoValue;
import com.google.auto.value.extension.memoized.Memoized;
import com.google.auto.value.extension.serializable.SerializableAutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
Expand Down Expand Up @@ -449,4 +450,48 @@ public void complexType() {

assertThat(reserialized).isEqualTo(complexType);
}

/**
* Type that uses both {@code @SerializableAutoValue} and {@code @Memoized}, showing that the two
* extensions work correctly together.
*/
@SerializableAutoValue
@AutoValue
abstract static class SerializeMemoize implements Serializable {
abstract Optional<Integer> number();
private transient int methodCount;

@Memoized
Optional<Integer> negate() {
methodCount++;
return number().map(n -> -n);
}

static SerializeMemoize.Builder builder() {
return new AutoValue_SerializableAutoValueExtensionTest_SerializeMemoize.Builder();
}

@AutoValue.Builder
abstract static class Builder {
abstract Builder setNumber(Optional<Integer> number);
abstract SerializeMemoize build();
}
}

@Test
public void serializeMemoize() {
SerializeMemoize instance1 = SerializeMemoize.builder().setNumber(Optional.of(17)).build();
assertThat(instance1.methodCount).isEqualTo(0);
assertThat(instance1.negate()).hasValue(-17);
assertThat(instance1.methodCount).isEqualTo(1);
assertThat(instance1.negate()).hasValue(-17);
assertThat(instance1.methodCount).isEqualTo(1);
SerializeMemoize instance2 = SerializableTester.reserialize(instance1);
assertThat(instance2.methodCount).isEqualTo(0);
assertThat(instance2.negate()).hasValue(-17);
assertThat(instance2.methodCount).isEqualTo(1);
assertThat(instance2.negate()).hasValue(-17);
assertThat(instance2.methodCount).isEqualTo(1);

}
}

0 comments on commit e01968d

Please sign in to comment.