diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafety.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafety.java index 7379634fe6d2..693d756accac 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafety.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafety.java @@ -367,16 +367,12 @@ public static Violation create(ConsPStack path) { return new AutoValue_ThreadSafety_Violation(path); } - /** - * @return true if a violation was found - */ + /** Returns true if a violation was found. */ public boolean isPresent() { return !path().isEmpty(); } - /** - * @return the explanation - */ + /** Returns the explanation. */ public String message() { return Joiner.on(", ").join(path()); } @@ -658,6 +654,9 @@ public Violation visitType(Type type, Void s) { } return Violation.absent(); } + if (WellKnownMutability.isProtoEnum(state, type)) { + return Violation.absent(); + } return Violation.of( String.format( "the declaration of type '%s' is not annotated with %s", diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/WellKnownMutability.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/WellKnownMutability.java index 15d135620db3..796758ebce98 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/WellKnownMutability.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/WellKnownMutability.java @@ -342,6 +342,9 @@ private static ImmutableSet buildMutableClasses(List knownMutabl private static final Supplier PROTOCOL_MESSAGE_TYPE = Suppliers.typeFromString("com.google.io.protocol.ProtocolMessage"); + private static final Supplier PROTOCOL_MESSAGE_ENUM = + Suppliers.typeFromString("com.google.protobuf.ProtocolMessageEnum"); + private static boolean isAssignableTo(Type type, Supplier supplier, VisitorState state) { Type to = supplier.get(state); if (to == null) { @@ -371,6 +374,11 @@ public static boolean isProto2MutableMessageClass(VisitorState state, Type type) && !isAssignableTo(type, PROTOCOL_MESSAGE_TYPE, state); } + public static boolean isProtoEnum(VisitorState state, Type type) { + checkNotNull(type); + return isAssignableTo(type, PROTOCOL_MESSAGE_ENUM, state); + } + /** Returns true if the type is an annotation. */ public static boolean isAnnotation(VisitorState state, Type type) { return isAssignableTo(type, Suppliers.ANNOTATION_TYPE, state); diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeCheckerTest.java index cd682d46480f..3a186843e69d 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeCheckerTest.java @@ -1084,4 +1084,21 @@ public void threadSafeRecursiveUpperBound_notThreadsafe() { "}") .doTest(); } + + @Test + public void protoEnum() { + compilationHelper + .addSourceLines( + "E.java", + "import com.google.protobuf.ProtocolMessageEnum;", + "abstract class E implements ProtocolMessageEnum {", + "}") + .addSourceLines( + "Test.java", + "import com.google.errorprone.annotations.ThreadSafe;", + "@ThreadSafe class Test {", + " final E x = null;", + "}") + .doTest(); + } }