tech.ydb.shaded.google.errorprone.annotations.ThreadSafe Maven / Gradle / Ivy
/*
 * Copyright 2023 The Error Prone Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.errorprone.annotations;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
 * This annotation indicates that the class/interface it is applied to is thread safe
 *
 * An object is thread safe if no sequences of accesses (like reads and writes to public fields
 * or calls to public methods) may put the object into an invalid state, or cause it to violate its
 * contract, regardless of the interleaving of those actions at runtime.
 *
 * 
This annotation has two related-but-distinct purposes:
 *
 * 
 *   - For humans: it indicates that the class/interface (and subclasses) is thread-safe
 *   
 - For machines: it causes the annotated class/interface -- and all of its subtypes -- to be
 *       validated by the {@code com.google.errorprone.bugpatterns.threadsafety.ThreadSafeChecker}
 *       {@code BugChecker}.
 * 
 
 *
 * Note that passing the checks performed by the {@code ThreadSafeChecker} is neither necessary nor
 * sufficient to guarantee the thread safety of a class. In fact, it is not possible to determine
 * thread safety through static code analysis alone, and the goal of {@code ThreadSafeChecker} is to
 * steer the code towards using standard thread-safe patterns, and then to assist the developer in
 * avoiding common mistakes. It is not meant as a substitute for diligent code review by a
 * knowledgeable developer.
 *
 * Also note that the only easy way to guarantee thread-safety of a class is to make it
 * immutable, and you should do that whenever possible (or at the least, make as much of the class
 * be immutable). Otherwise, writing a thread-safe class is inherently tricky and error prone, and
 * keeping it thread-safe is even more so.
 *
 * 
The remainder of this javadoc describes the heuristics enforced by {@code ThreadSafeChecker}
 * and the related {@code com.google.errorprone.bugpatterns.threadsafety.GuardedByChecker} and
 * {@code com.google.errorprone.bugpatterns.threadsafety.ImmutableChecker} on which the former
 * relies.
 *
 * 
The {@code ThreadSafeChecker} heuristics enforce that every field meets at least one of these
 * requirements:
 *
 * 
 *   - It is both {@code final} and its type is deemed inherently deeply thread-safe; and/or
 *   
 - it is annotated with either {@link com.google.errorprone.annotations.concurrent.GuardedBy}
 *       (some other annotations named {@code GuardedBy} also work, though this the preferred);
 * 
 
 *
 * Below, more details about what is meant by "deemed inherently deeply thread-safe" are presented,
 * and, afterwards, more about {@code GuardedBy}.
 *
 * A type is deemed inherently deeply thread-safe if it meets two requirements. The first
 * requirement is that it meets at least one of these four conditions:
 *
 * 
 *   - it is listed as a well-known immutable type in {@code
 *       com.google.errorprone.bugpatterns.threadsafety.WellKnownMutability} (e.g. a field of type
 *       {@link String}); and/or
 *   
 - it is listed as a well-known thread-safe type in {@code
 *       com.google.errorprone.bugpatterns.threadsafety.WellKnownThreadSafety} (e.g. a field of type
 *       {@link java.util.concurrent.atomic.AtomicBoolean}); and/or
 *   
 - it is annotated with {@link Immutable}; and/or
 *   
 - it is annotated with {@link ThreadSafe}.
 * 
 
 *
 * This first requirement means the type is at least inherently shallowly thread-safe.
 *
 * 
Fields annotated with {@code javax.annotation.concurrent.GuardedBy} are likely the meat of a
 * mutable thread-safe class: these are things that need to be mutated, but should be done so in a
 * safe manner -- i.e., (most likely) in critical sections of code that protect their access by
 * means of a lock. See more information in that annotation's javadoc.
 *
 * 
As stated before, the heuristics above are not sufficient to guarantee the thread safety of a
 * class. Also as stated before, thread-safety is tricky, and requires diligent analysis by skilled
 * people. That said, we provide here a few examples of common examples of ways to break these
 * heuristics, so as to help you avoid them:
 *
 * 
 *   - a non-private {@code @GuardedBy} field -- i.e.if a non-private {@code @GuardedBy} field is
 *       accessed outside the class, the code that enforces {@code @GuardedBy} will not prevent
 *       unprotected access and/or modifications to the field;
 *   
 - indirect access to the field. There are several ways in which code may access the objects
 *       stored in the field indirectly (i.e. not directly referencing the field). In all these
 *       cases, {@code @GuardedBy} offers no enforcement. Here's some examples:
 *       
 *         - if the {@code @GuardedBy} field instance is part of an object by a method (e.g. a
 *             simple getter method or constructor parameter);
 *         
 - if a method takes an out-parameter and the method calls a method in that
 *             out-parameter passing the instance of the {@code @GuardedBy} field, and that instance
 *             is stored in the out-parameter (i.e. a simple setter method);
 *       
 
 *    - methods that perform multiple operations -- e.g., if a class {@code Foo} contains a {@code
 *       AtomicInteger} (which is an inherently deeply thread-safe data structure), the following
 *       code makes this class not thread-safe:
 *       
{@code
 * private void incrementMyAtomicInteger() {
 *   myAtomicInteger.set(myAtomicInteger.get() + 1);
 * }
 *
 * }
 *  
 *
 * Also see https://errorprone.info/bugpattern/ThreadSafe
 */
// TODO(b/112275411): when fixed, delete the comment above about non-private fields
@Target({TYPE})
@Retention(RUNTIME)
// Note: besides abiding by the standard behavior of `@Inherited`, the behavior enforced by
// the static analysis effectively applies not only to classes that extend a class annotated with
// @ThreadSafe but *also* applies to classes that implement an annotated interface. This is because
// a class that implements an interface annotated with `@ThreadSafe` either: a. is anonymous, in
// which case the static analysis is implemented to run against it; or b. it is not anonymous, in
// which case the static analysis enforces that the class _also_ have an `@ThreadSafe` annotation.
@Inherited
@Documented
public @interface ThreadSafe {}