001/*
002 * Copyright (C) 2017 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.util.concurrent;
018
019import static com.google.common.base.Functions.constant;
020import static com.google.common.base.MoreObjects.toStringHelper;
021import static com.google.common.base.Preconditions.checkArgument;
022import static com.google.common.base.Preconditions.checkNotNull;
023import static com.google.common.base.Preconditions.checkState;
024import static com.google.common.collect.Lists.asList;
025import static com.google.common.util.concurrent.ClosingFuture.State.CLOSED;
026import static com.google.common.util.concurrent.ClosingFuture.State.CLOSING;
027import static com.google.common.util.concurrent.ClosingFuture.State.OPEN;
028import static com.google.common.util.concurrent.ClosingFuture.State.SUBSUMED;
029import static com.google.common.util.concurrent.ClosingFuture.State.WILL_CLOSE;
030import static com.google.common.util.concurrent.ClosingFuture.State.WILL_CREATE_VALUE_AND_CLOSER;
031import static com.google.common.util.concurrent.Futures.getDone;
032import static com.google.common.util.concurrent.Futures.immediateFuture;
033import static com.google.common.util.concurrent.Futures.nonCancellationPropagating;
034import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
035import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
036import static java.util.logging.Level.FINER;
037import static java.util.logging.Level.SEVERE;
038import static java.util.logging.Level.WARNING;
039
040import com.google.common.annotations.J2ktIncompatible;
041import com.google.common.annotations.VisibleForTesting;
042import com.google.common.collect.FluentIterable;
043import com.google.common.collect.ImmutableList;
044import com.google.common.util.concurrent.ClosingFuture.Combiner.AsyncCombiningCallable;
045import com.google.common.util.concurrent.ClosingFuture.Combiner.CombiningCallable;
046import com.google.common.util.concurrent.Futures.FutureCombiner;
047import com.google.errorprone.annotations.CanIgnoreReturnValue;
048import com.google.errorprone.annotations.DoNotMock;
049import com.google.j2objc.annotations.RetainedWith;
050import java.io.Closeable;
051import java.util.IdentityHashMap;
052import java.util.Map;
053import java.util.concurrent.Callable;
054import java.util.concurrent.CancellationException;
055import java.util.concurrent.CountDownLatch;
056import java.util.concurrent.ExecutionException;
057import java.util.concurrent.Executor;
058import java.util.concurrent.Future;
059import java.util.concurrent.RejectedExecutionException;
060import java.util.concurrent.atomic.AtomicReference;
061import javax.annotation.CheckForNull;
062import org.checkerframework.checker.nullness.qual.Nullable;
063
064/**
065 * A step in a pipeline of an asynchronous computation. When the last step in the computation is
066 * complete, some objects captured during the computation are closed.
067 *
068 * <p>A pipeline of {@code ClosingFuture}s is a tree of steps. Each step represents either an
069 * asynchronously-computed intermediate value, or else an exception that indicates the failure or
070 * cancellation of the operation so far. The only way to extract the value or exception from a step
071 * is by declaring that step to be the last step of the pipeline. Nevertheless, we refer to the
072 * "value" of a successful step or the "result" (value or exception) of any step.
073 *
074 * <ol>
075 *   <li>A pipeline starts at its leaf step (or steps), which is created from either a callable
076 *       block or a {@link ListenableFuture}.
077 *   <li>Each other step is derived from one or more input steps. At each step, zero or more objects
078 *       can be captured for later closing.
079 *   <li>There is one last step (the root of the tree), from which you can extract the final result
080 *       of the computation. After that result is available (or the computation fails), all objects
081 *       captured by any of the steps in the pipeline are closed.
082 * </ol>
083 *
084 * <h3>Starting a pipeline</h3>
085 *
086 * Start a {@code ClosingFuture} pipeline {@linkplain #submit(ClosingCallable, Executor) from a
087 * callable block} that may capture objects for later closing. To start a pipeline from a {@link
088 * ListenableFuture} that doesn't create resources that should be closed later, you can use {@link
089 * #from(ListenableFuture)} instead.
090 *
091 * <h3>Derived steps</h3>
092 *
093 * A {@code ClosingFuture} step can be derived from one or more input {@code ClosingFuture} steps in
094 * ways similar to {@link FluentFuture}s:
095 *
096 * <ul>
097 *   <li>by transforming the value from a successful input step,
098 *   <li>by catching the exception from a failed input step, or
099 *   <li>by combining the results of several input steps.
100 * </ul>
101 *
102 * Each derivation can capture the next value or any intermediate objects for later closing.
103 *
104 * <p>A step can be the input to at most one derived step. Once you transform its value, catch its
105 * exception, or combine it with others, you cannot do anything else with it, including declare it
106 * to be the last step of the pipeline.
107 *
108 * <h4>Transforming</h4>
109 *
110 * To derive the next step by asynchronously applying a function to an input step's value, call
111 * {@link #transform(ClosingFunction, Executor)} or {@link #transformAsync(AsyncClosingFunction,
112 * Executor)} on the input step.
113 *
114 * <h4>Catching</h4>
115 *
116 * To derive the next step from a failed input step, call {@link #catching(Class, ClosingFunction,
117 * Executor)} or {@link #catchingAsync(Class, AsyncClosingFunction, Executor)} on the input step.
118 *
119 * <h4>Combining</h4>
120 *
121 * To derive a {@code ClosingFuture} from two or more input steps, pass the input steps to {@link
122 * #whenAllComplete(Iterable)} or {@link #whenAllSucceed(Iterable)} or its overloads.
123 *
124 * <h3>Cancelling</h3>
125 *
126 * Any step in a pipeline can be {@linkplain #cancel(boolean) cancelled}, even after another step
127 * has been derived, with the same semantics as cancelling a {@link Future}. In addition, a
128 * successfully cancelled step will immediately start closing all objects captured for later closing
129 * by it and by its input steps.
130 *
131 * <h3>Ending a pipeline</h3>
132 *
133 * Each {@code ClosingFuture} pipeline must be ended. To end a pipeline, decide whether you want to
134 * close the captured objects automatically or manually.
135 *
136 * <h4>Automatically closing</h4>
137 *
138 * You can extract a {@link Future} that represents the result of the last step in the pipeline by
139 * calling {@link #finishToFuture()}. All objects the pipeline has captured for closing will begin
140 * to be closed asynchronously <b>after</b> the returned {@code Future} is done: the future
141 * completes before closing starts, rather than once it has finished.
142 *
143 * <pre>{@code
144 * FluentFuture<UserName> userName =
145 *     ClosingFuture.submit(
146 *             closer -> closer.eventuallyClose(database.newTransaction(), closingExecutor),
147 *             executor)
148 *         .transformAsync((closer, transaction) -> transaction.queryClosingFuture("..."), executor)
149 *         .transform((closer, result) -> result.get("userName"), directExecutor())
150 *         .catching(DBException.class, e -> "no user", directExecutor())
151 *         .finishToFuture();
152 * }</pre>
153 *
154 * In this example, when the {@code userName} {@link Future} is done, the transaction and the query
155 * result cursor will both be closed, even if the operation is cancelled or fails.
156 *
157 * <h4>Manually closing</h4>
158 *
159 * If you want to close the captured objects manually, after you've used the final result, call
160 * {@link #finishToValueAndCloser(ValueAndCloserConsumer, Executor)} to get an object that holds the
161 * final result. You then call {@link ValueAndCloser#closeAsync()} to close the captured objects.
162 *
163 * <pre>{@code
164 *     ClosingFuture.submit(
165 *             closer -> closer.eventuallyClose(database.newTransaction(), closingExecutor),
166 *             executor)
167 *     .transformAsync((closer, transaction) -> transaction.queryClosingFuture("..."), executor)
168 *     .transform((closer, result) -> result.get("userName"), directExecutor())
169 *     .catching(DBException.class, e -> "no user", directExecutor())
170 *     .finishToValueAndCloser(
171 *         valueAndCloser -> this.userNameValueAndCloser = valueAndCloser, executor);
172 *
173 * // later
174 * try { // get() will throw if the operation failed or was cancelled.
175 *   UserName userName = userNameValueAndCloser.get();
176 *   // do something with userName
177 * } finally {
178 *   userNameValueAndCloser.closeAsync();
179 * }
180 * }</pre>
181 *
182 * In this example, when {@code userNameValueAndCloser.closeAsync()} is called, the transaction and
183 * the query result cursor will both be closed, even if the operation is cancelled or fails.
184 *
185 * <p>Note that if you don't call {@code closeAsync()}, the captured objects will not be closed. The
186 * automatic-closing approach described above is safer.
187 *
188 * @param <V> the type of the value of this step
189 * @since 30.0
190 */
191// TODO(dpb): Consider reusing one CloseableList for the entire pipeline, modulo combinations.
192@DoNotMock("Use ClosingFuture.from(Futures.immediate*Future)")
193@J2ktIncompatible
194@ElementTypesAreNonnullByDefault
195// TODO(dpb): GWT compatibility.
196public final class ClosingFuture<V extends @Nullable Object> {
197
198  private static final LazyLogger logger = new LazyLogger(ClosingFuture.class);
199
200  /**
201   * An object that can capture objects to be closed later, when a {@link ClosingFuture} pipeline is
202   * done.
203   */
204  public static final class DeferredCloser {
205    @RetainedWith private final CloseableList list;
206
207    DeferredCloser(CloseableList list) {
208      this.list = list;
209    }
210
211    /**
212     * Captures an object to be closed when a {@link ClosingFuture} pipeline is done.
213     *
214     * <p>For users of the {@code -jre} flavor of Guava, the object can be any {@code
215     * AutoCloseable}. For users of the {@code -android} flavor, the object must be a {@code
216     * Closeable}. (For more about the flavors, see <a
217     * href="https://github.com/google/guava#adding-guava-to-your-build">Adding Guava to your
218     * build</a>.)
219     *
220     * <p>Be careful when targeting an older SDK than you are building against (most commonly when
221     * building for Android): Ensure that any object you pass implements the interface not just in
222     * your current SDK version but also at the oldest version you support. For example, <a
223     * href="https://developer.android.com/sdk/api_diff/16/">API Level 16</a> is the first version
224     * in which {@code Cursor} is {@code Closeable}. To support older versions, pass a wrapper
225     * {@code Closeable} with a method reference like {@code cursor::close}.
226     *
227     * <p>Note that this method is still binary-compatible between flavors because the erasure of
228     * its parameter type is {@code Object}, not {@code AutoCloseable} or {@code Closeable}.
229     *
230     * @param closeable the object to be closed (see notes above)
231     * @param closingExecutor the object will be closed on this executor
232     * @return the first argument
233     */
234    @CanIgnoreReturnValue
235    @ParametricNullness
236    public <C extends @Nullable Object & @Nullable AutoCloseable> C eventuallyClose(
237        @ParametricNullness C closeable, Executor closingExecutor) {
238      checkNotNull(closingExecutor);
239      if (closeable != null) {
240        list.add(closeable, closingExecutor);
241      }
242      return closeable;
243    }
244  }
245
246  /**
247   * An operation that computes a result.
248   *
249   * @param <V> the type of the result
250   */
251  @FunctionalInterface
252  public interface ClosingCallable<V extends @Nullable Object> {
253    /**
254     * Computes a result, or throws an exception if unable to do so.
255     *
256     * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
257     * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done (but
258     * not before this method completes), even if this method throws or the pipeline is cancelled.
259     */
260    @ParametricNullness
261    V call(DeferredCloser closer) throws Exception;
262  }
263
264  /**
265   * An operation that computes a {@link ClosingFuture} of a result.
266   *
267   * @param <V> the type of the result
268   * @since 30.1
269   */
270  @FunctionalInterface
271  public interface AsyncClosingCallable<V extends @Nullable Object> {
272    /**
273     * Computes a result, or throws an exception if unable to do so.
274     *
275     * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
276     * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done (but
277     * not before this method completes), even if this method throws or the pipeline is cancelled.
278     */
279    ClosingFuture<V> call(DeferredCloser closer) throws Exception;
280  }
281
282  /**
283   * A function from an input to a result.
284   *
285   * @param <T> the type of the input to the function
286   * @param <U> the type of the result of the function
287   */
288  @FunctionalInterface
289  public interface ClosingFunction<T extends @Nullable Object, U extends @Nullable Object> {
290
291    /**
292     * Applies this function to an input, or throws an exception if unable to do so.
293     *
294     * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
295     * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done (but
296     * not before this method completes), even if this method throws or the pipeline is cancelled.
297     */
298    @ParametricNullness
299    U apply(DeferredCloser closer, @ParametricNullness T input) throws Exception;
300  }
301
302  /**
303   * A function from an input to a {@link ClosingFuture} of a result.
304   *
305   * @param <T> the type of the input to the function
306   * @param <U> the type of the result of the function
307   */
308  @FunctionalInterface
309  public interface AsyncClosingFunction<T extends @Nullable Object, U extends @Nullable Object> {
310    /**
311     * Applies this function to an input, or throws an exception if unable to do so.
312     *
313     * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
314     * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done (but
315     * not before this method completes), even if this method throws or the pipeline is cancelled.
316     */
317    ClosingFuture<U> apply(DeferredCloser closer, @ParametricNullness T input) throws Exception;
318  }
319
320  /**
321   * An object that holds the final result of an asynchronous {@link ClosingFuture} operation and
322   * allows the user to close all the closeable objects that were captured during it for later
323   * closing.
324   *
325   * <p>The asynchronous operation will have completed before this object is created.
326   *
327   * @param <V> the type of the value of a successful operation
328   * @see ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor)
329   */
330  public static final class ValueAndCloser<V extends @Nullable Object> {
331
332    private final ClosingFuture<? extends V> closingFuture;
333
334    ValueAndCloser(ClosingFuture<? extends V> closingFuture) {
335      this.closingFuture = checkNotNull(closingFuture);
336    }
337
338    /**
339     * Returns the final value of the associated {@link ClosingFuture}, or throws an exception as
340     * {@link Future#get()} would.
341     *
342     * <p>Because the asynchronous operation has already completed, this method is synchronous and
343     * returns immediately.
344     *
345     * @throws CancellationException if the computation was cancelled
346     * @throws ExecutionException if the computation threw an exception
347     */
348    @ParametricNullness
349    public V get() throws ExecutionException {
350      return getDone(closingFuture.future);
351    }
352
353    /**
354     * Starts closing all closeable objects captured during the {@link ClosingFuture}'s asynchronous
355     * operation on the {@link Executor}s specified by calls to {@link
356     * DeferredCloser#eventuallyClose(Object, Executor)}.
357     *
358     * <p>If any such calls specified {@link MoreExecutors#directExecutor()}, those objects will be
359     * closed synchronously.
360     *
361     * <p>Idempotent: objects will be closed at most once.
362     */
363    public void closeAsync() {
364      closingFuture.close();
365    }
366  }
367
368  /**
369   * Represents an operation that accepts a {@link ValueAndCloser} for the last step in a {@link
370   * ClosingFuture} pipeline.
371   *
372   * @param <V> the type of the final value of a successful pipeline
373   * @see ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor)
374   */
375  @FunctionalInterface
376  public interface ValueAndCloserConsumer<V extends @Nullable Object> {
377
378    /** Accepts a {@link ValueAndCloser} for the last step in a {@link ClosingFuture} pipeline. */
379    void accept(ValueAndCloser<V> valueAndCloser);
380  }
381
382  /**
383   * Starts a {@link ClosingFuture} pipeline by submitting a callable block to an executor.
384   *
385   * @throws java.util.concurrent.RejectedExecutionException if the task cannot be scheduled for
386   *     execution
387   */
388  public static <V extends @Nullable Object> ClosingFuture<V> submit(
389      ClosingCallable<V> callable, Executor executor) {
390    checkNotNull(callable);
391    CloseableList closeables = new CloseableList();
392    TrustedListenableFutureTask<V> task =
393        TrustedListenableFutureTask.create(
394            new Callable<V>() {
395              @Override
396              @ParametricNullness
397              public V call() throws Exception {
398                return callable.call(closeables.closer);
399              }
400
401              @Override
402              public String toString() {
403                return callable.toString();
404              }
405            });
406    executor.execute(task);
407    return new ClosingFuture<>(task, closeables);
408  }
409
410  /**
411   * Starts a {@link ClosingFuture} pipeline by submitting a callable block to an executor.
412   *
413   * @throws java.util.concurrent.RejectedExecutionException if the task cannot be scheduled for
414   *     execution
415   * @since 30.1
416   */
417  public static <V extends @Nullable Object> ClosingFuture<V> submitAsync(
418      AsyncClosingCallable<V> callable, Executor executor) {
419    checkNotNull(callable);
420    CloseableList closeables = new CloseableList();
421    TrustedListenableFutureTask<V> task =
422        TrustedListenableFutureTask.create(
423            new AsyncCallable<V>() {
424              @Override
425              public ListenableFuture<V> call() throws Exception {
426                CloseableList newCloseables = new CloseableList();
427                try {
428                  ClosingFuture<V> closingFuture = callable.call(newCloseables.closer);
429                  closingFuture.becomeSubsumedInto(closeables);
430                  return closingFuture.future;
431                } finally {
432                  closeables.add(newCloseables, directExecutor());
433                }
434              }
435
436              @Override
437              public String toString() {
438                return callable.toString();
439              }
440            });
441    executor.execute(task);
442    return new ClosingFuture<>(task, closeables);
443  }
444
445  /**
446   * Starts a {@link ClosingFuture} pipeline with a {@link ListenableFuture}.
447   *
448   * <p>{@code future}'s value will not be closed when the pipeline is done even if {@code V}
449   * implements {@link Closeable}. In order to start a pipeline with a value that will be closed
450   * when the pipeline is done, use {@link #submit(ClosingCallable, Executor)} instead.
451   */
452  public static <V extends @Nullable Object> ClosingFuture<V> from(ListenableFuture<V> future) {
453    return new ClosingFuture<>(future);
454  }
455
456  /**
457   * Starts a {@link ClosingFuture} pipeline with a {@link ListenableFuture}.
458   *
459   * <p>If {@code future} succeeds, its value will be closed (using {@code closingExecutor)}) when
460   * the pipeline is done, even if the pipeline is canceled or fails.
461   *
462   * <p>Cancelling the pipeline will not cancel {@code future}, so that the pipeline can access its
463   * value in order to close it.
464   *
465   * @param future the future to create the {@code ClosingFuture} from. For discussion of the
466   *     future's result type {@code C}, see {@link DeferredCloser#eventuallyClose(Object,
467   *     Executor)}.
468   * @param closingExecutor the future's result will be closed on this executor
469   * @deprecated Creating {@link Future}s of closeable types is dangerous in general because the
470   *     underlying value may never be closed if the {@link Future} is canceled after its operation
471   *     begins. Consider replacing code that creates {@link ListenableFuture}s of closeable types,
472   *     including those that pass them to this method, with {@link #submit(ClosingCallable,
473   *     Executor)} in order to ensure that resources do not leak. Or, to start a pipeline with a
474   *     {@link ListenableFuture} that doesn't create values that should be closed, use {@link
475   *     ClosingFuture#from}.
476   */
477  @Deprecated
478  public static <C extends @Nullable Object & @Nullable AutoCloseable>
479      ClosingFuture<C> eventuallyClosing(
480          ListenableFuture<C> future, final Executor closingExecutor) {
481    checkNotNull(closingExecutor);
482    final ClosingFuture<C> closingFuture = new ClosingFuture<>(nonCancellationPropagating(future));
483    Futures.addCallback(
484        future,
485        new FutureCallback<@Nullable AutoCloseable>() {
486          @Override
487          public void onSuccess(@CheckForNull AutoCloseable result) {
488            closingFuture.closeables.closer.eventuallyClose(result, closingExecutor);
489          }
490
491          @Override
492          public void onFailure(Throwable t) {}
493        },
494        directExecutor());
495    return closingFuture;
496  }
497
498  /**
499   * Starts specifying how to combine {@link ClosingFuture}s into a single pipeline.
500   *
501   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of
502   *     the {@code futures}, or if any has already been {@linkplain #finishToFuture() finished}
503   */
504  public static Combiner whenAllComplete(Iterable<? extends ClosingFuture<?>> futures) {
505    return new Combiner(false, futures);
506  }
507
508  /**
509   * Starts specifying how to combine {@link ClosingFuture}s into a single pipeline.
510   *
511   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of
512   *     the arguments, or if any has already been {@linkplain #finishToFuture() finished}
513   */
514  public static Combiner whenAllComplete(
515      ClosingFuture<?> future1, ClosingFuture<?>... moreFutures) {
516    return whenAllComplete(asList(future1, moreFutures));
517  }
518
519  /**
520   * Starts specifying how to combine {@link ClosingFuture}s into a single pipeline, assuming they
521   * all succeed. If any fail, the resulting pipeline will fail.
522   *
523   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of
524   *     the {@code futures}, or if any has already been {@linkplain #finishToFuture() finished}
525   */
526  public static Combiner whenAllSucceed(Iterable<? extends ClosingFuture<?>> futures) {
527    return new Combiner(true, futures);
528  }
529
530  /**
531   * Starts specifying how to combine two {@link ClosingFuture}s into a single pipeline, assuming
532   * they all succeed. If any fail, the resulting pipeline will fail.
533   *
534   * <p>Calling this method allows you to use lambdas or method references typed with the types of
535   * the input {@link ClosingFuture}s.
536   *
537   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of
538   *     the arguments, or if any has already been {@linkplain #finishToFuture() finished}
539   */
540  public static <V1 extends @Nullable Object, V2 extends @Nullable Object>
541      Combiner2<V1, V2> whenAllSucceed(ClosingFuture<V1> future1, ClosingFuture<V2> future2) {
542    return new Combiner2<>(future1, future2);
543  }
544
545  /**
546   * Starts specifying how to combine three {@link ClosingFuture}s into a single pipeline, assuming
547   * they all succeed. If any fail, the resulting pipeline will fail.
548   *
549   * <p>Calling this method allows you to use lambdas or method references typed with the types of
550   * the input {@link ClosingFuture}s.
551   *
552   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of
553   *     the arguments, or if any has already been {@linkplain #finishToFuture() finished}
554   */
555  public static <
556          V1 extends @Nullable Object, V2 extends @Nullable Object, V3 extends @Nullable Object>
557      Combiner3<V1, V2, V3> whenAllSucceed(
558          ClosingFuture<V1> future1, ClosingFuture<V2> future2, ClosingFuture<V3> future3) {
559    return new Combiner3<>(future1, future2, future3);
560  }
561
562  /**
563   * Starts specifying how to combine four {@link ClosingFuture}s into a single pipeline, assuming
564   * they all succeed. If any fail, the resulting pipeline will fail.
565   *
566   * <p>Calling this method allows you to use lambdas or method references typed with the types of
567   * the input {@link ClosingFuture}s.
568   *
569   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of
570   *     the arguments, or if any has already been {@linkplain #finishToFuture() finished}
571   */
572  public static <
573          V1 extends @Nullable Object,
574          V2 extends @Nullable Object,
575          V3 extends @Nullable Object,
576          V4 extends @Nullable Object>
577      Combiner4<V1, V2, V3, V4> whenAllSucceed(
578          ClosingFuture<V1> future1,
579          ClosingFuture<V2> future2,
580          ClosingFuture<V3> future3,
581          ClosingFuture<V4> future4) {
582    return new Combiner4<>(future1, future2, future3, future4);
583  }
584
585  /**
586   * Starts specifying how to combine five {@link ClosingFuture}s into a single pipeline, assuming
587   * they all succeed. If any fail, the resulting pipeline will fail.
588   *
589   * <p>Calling this method allows you to use lambdas or method references typed with the types of
590   * the input {@link ClosingFuture}s.
591   *
592   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of
593   *     the arguments, or if any has already been {@linkplain #finishToFuture() finished}
594   */
595  public static <
596          V1 extends @Nullable Object,
597          V2 extends @Nullable Object,
598          V3 extends @Nullable Object,
599          V4 extends @Nullable Object,
600          V5 extends @Nullable Object>
601      Combiner5<V1, V2, V3, V4, V5> whenAllSucceed(
602          ClosingFuture<V1> future1,
603          ClosingFuture<V2> future2,
604          ClosingFuture<V3> future3,
605          ClosingFuture<V4> future4,
606          ClosingFuture<V5> future5) {
607    return new Combiner5<>(future1, future2, future3, future4, future5);
608  }
609
610  /**
611   * Starts specifying how to combine {@link ClosingFuture}s into a single pipeline, assuming they
612   * all succeed. If any fail, the resulting pipeline will fail.
613   *
614   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from any of
615   *     the arguments, or if any has already been {@linkplain #finishToFuture() finished}
616   */
617  public static Combiner whenAllSucceed(
618      ClosingFuture<?> future1,
619      ClosingFuture<?> future2,
620      ClosingFuture<?> future3,
621      ClosingFuture<?> future4,
622      ClosingFuture<?> future5,
623      ClosingFuture<?> future6,
624      ClosingFuture<?>... moreFutures) {
625    return whenAllSucceed(
626        FluentIterable.of(future1, future2, future3, future4, future5, future6)
627            .append(moreFutures));
628  }
629
630  private final AtomicReference<State> state = new AtomicReference<>(OPEN);
631  private final CloseableList closeables;
632  private final FluentFuture<V> future;
633
634  private ClosingFuture(ListenableFuture<V> future) {
635    this(future, new CloseableList());
636  }
637
638  private ClosingFuture(ListenableFuture<V> future, CloseableList closeables) {
639    this.future = FluentFuture.from(future);
640    this.closeables = closeables;
641  }
642
643  /**
644   * Returns a future that finishes when this step does. Calling {@code get()} on the returned
645   * future returns {@code null} if the step is successful or throws the same exception that would
646   * be thrown by calling {@code finishToFuture().get()} if this were the last step. Calling {@code
647   * cancel()} on the returned future has no effect on the {@code ClosingFuture} pipeline.
648   *
649   * <p>{@code statusFuture} differs from most methods on {@code ClosingFuture}: You can make calls
650   * to {@code statusFuture} <i>in addition to</i> the call you make to {@link #finishToFuture()} or
651   * a derivation method <i>on the same instance</i>. This is important because calling {@code
652   * statusFuture} alone does not provide a way to close the pipeline.
653   */
654  public ListenableFuture<?> statusFuture() {
655    return nonCancellationPropagating(future.transform(constant(null), directExecutor()));
656  }
657
658  /**
659   * Returns a new {@code ClosingFuture} pipeline step derived from this one by applying a function
660   * to its value. The function can use a {@link DeferredCloser} to capture objects to be closed
661   * when the pipeline is done.
662   *
663   * <p>If this {@code ClosingFuture} fails, the function will not be called, and the derived {@code
664   * ClosingFuture} will be equivalent to this one.
665   *
666   * <p>If the function throws an exception, that exception is used as the result of the derived
667   * {@code ClosingFuture}.
668   *
669   * <p>Example usage:
670   *
671   * <pre>{@code
672   * ClosingFuture<List<Row>> rowsFuture =
673   *     queryFuture.transform((closer, result) -> result.getRows(), executor);
674   * }</pre>
675   *
676   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
677   * the discussion in the {@link ListenableFuture#addListener} documentation. All its warnings
678   * about heavyweight listeners are also applicable to heavyweight functions passed to this method.
679   *
680   * <p>After calling this method, you may not call {@link #finishToFuture()}, {@link
681   * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, or any other derivation method on
682   * the original {@code ClosingFuture} instance.
683   *
684   * @param function transforms the value of this step to the value of the derived step
685   * @param executor executor to run the function in
686   * @return the derived step
687   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from this
688   *     one, or if this {@code ClosingFuture} has already been {@linkplain #finishToFuture()
689   *     finished}
690   */
691  public <U extends @Nullable Object> ClosingFuture<U> transform(
692      final ClosingFunction<? super V, U> function, Executor executor) {
693    checkNotNull(function);
694    AsyncFunction<V, U> applyFunction =
695        new AsyncFunction<V, U>() {
696          @Override
697          public ListenableFuture<U> apply(V input) throws Exception {
698            return closeables.applyClosingFunction(function, input);
699          }
700
701          @Override
702          public String toString() {
703            return function.toString();
704          }
705        };
706    // TODO(dpb): Switch to future.transformSync when that exists (passing a throwing function).
707    return derive(future.transformAsync(applyFunction, executor));
708  }
709
710  /**
711   * Returns a new {@code ClosingFuture} pipeline step derived from this one by applying a function
712   * that returns a {@code ClosingFuture} to its value. The function can use a {@link
713   * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those
714   * captured by the returned {@link ClosingFuture}).
715   *
716   * <p>If this {@code ClosingFuture} succeeds, the derived one will be equivalent to the one
717   * returned by the function.
718   *
719   * <p>If this {@code ClosingFuture} fails, the function will not be called, and the derived {@code
720   * ClosingFuture} will be equivalent to this one.
721   *
722   * <p>If the function throws an exception, that exception is used as the result of the derived
723   * {@code ClosingFuture}. But if the exception is thrown after the function creates a {@code
724   * ClosingFuture}, then none of the closeable objects in that {@code ClosingFuture} will be
725   * closed.
726   *
727   * <p>Usage guidelines for this method:
728   *
729   * <ul>
730   *   <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a
731   *       {@code ClosingFuture}. If possible, prefer calling {@link #transform(ClosingFunction,
732   *       Executor)} instead, with a function that returns the next value directly.
733   *   <li>Call {@link DeferredCloser#eventuallyClose(Object, Executor) closer.eventuallyClose()}
734   *       for every closeable object this step creates in order to capture it for later closing.
735   *   <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code
736   *       ClosingFuture} call {@link #from(ListenableFuture)}.
737   *   <li>In case this step doesn't create new closeables, you can adapt an API that returns a
738   *       {@link ListenableFuture} to return a {@code ClosingFuture} by wrapping it with a call to
739   *       {@link #withoutCloser(AsyncFunction)}
740   * </ul>
741   *
742   * <p>Example usage:
743   *
744   * <pre>{@code
745   * // Result.getRowsClosingFuture() returns a ClosingFuture.
746   * ClosingFuture<List<Row>> rowsFuture =
747   *     queryFuture.transformAsync((closer, result) -> result.getRowsClosingFuture(), executor);
748   *
749   * // Result.writeRowsToOutputStreamFuture() returns a ListenableFuture that resolves to the
750   * // number of written rows. openOutputFile() returns a FileOutputStream (which implements
751   * // Closeable).
752   * ClosingFuture<Integer> rowsFuture2 =
753   *     queryFuture.transformAsync(
754   *         (closer, result) -> {
755   *           FileOutputStream fos = closer.eventuallyClose(openOutputFile(), closingExecutor);
756   *           return ClosingFuture.from(result.writeRowsToOutputStreamFuture(fos));
757   *      },
758   *      executor);
759   *
760   * // Result.getRowsFuture() returns a ListenableFuture (no new closeables are created).
761   * ClosingFuture<List<Row>> rowsFuture3 =
762   *     queryFuture.transformAsync(withoutCloser(Result::getRowsFuture), executor);
763   *
764   * }</pre>
765   *
766   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
767   * the discussion in the {@link ListenableFuture#addListener} documentation. All its warnings
768   * about heavyweight listeners are also applicable to heavyweight functions passed to this method.
769   * (Specifically, {@code directExecutor} functions should avoid heavyweight operations inside
770   * {@code AsyncClosingFunction.apply}. Any heavyweight operations should occur in other threads
771   * responsible for completing the returned {@code ClosingFuture}.)
772   *
773   * <p>After calling this method, you may not call {@link #finishToFuture()}, {@link
774   * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, or any other derivation method on
775   * the original {@code ClosingFuture} instance.
776   *
777   * @param function transforms the value of this step to a {@code ClosingFuture} with the value of
778   *     the derived step
779   * @param executor executor to run the function in
780   * @return the derived step
781   * @throws IllegalStateException if a {@code ClosingFuture} has already been derived from this
782   *     one, or if this {@code ClosingFuture} has already been {@linkplain #finishToFuture()
783   *     finished}
784   */
785  public <U extends @Nullable Object> ClosingFuture<U> transformAsync(
786      final AsyncClosingFunction<? super V, U> function, Executor executor) {
787    checkNotNull(function);
788    AsyncFunction<V, U> applyFunction =
789        new AsyncFunction<V, U>() {
790          @Override
791          public ListenableFuture<U> apply(V input) throws Exception {
792            return closeables.applyAsyncClosingFunction(function, input);
793          }
794
795          @Override
796          public String toString() {
797            return function.toString();
798          }
799        };
800    return derive(future.transformAsync(applyFunction, executor));
801  }
802
803  /**
804   * Returns an {@link AsyncClosingFunction} that applies an {@link AsyncFunction} to an input,
805   * ignoring the DeferredCloser and returning a {@code ClosingFuture} derived from the returned
806   * {@link ListenableFuture}.
807   *
808   * <p>Use this method to pass a transformation to {@link #transformAsync(AsyncClosingFunction,
809   * Executor)} or to {@link #catchingAsync(Class, AsyncClosingFunction, Executor)} as long as it
810   * meets these conditions:
811   *
812   * <ul>
813   *   <li>It does not need to capture any {@link Closeable} objects by calling {@link
814   *       DeferredCloser#eventuallyClose(Object, Executor)}.
815   *   <li>It returns a {@link ListenableFuture}.
816   * </ul>
817   *
818   * <p>Example usage:
819   *
820   * <pre>{@code
821   * // Result.getRowsFuture() returns a ListenableFuture.
822   * ClosingFuture<List<Row>> rowsFuture =
823   *     queryFuture.transformAsync(withoutCloser(Result::getRowsFuture), executor);
824   * }</pre>
825   *
826   * @param function transforms the value of a {@code ClosingFuture} step to a {@link
827   *     ListenableFuture} with the value of a derived step
828   */
829  public static <V extends @Nullable Object, U extends @Nullable Object>
830      AsyncClosingFunction<V, U> withoutCloser(final AsyncFunction<V, U> function) {
831    checkNotNull(function);
832    return new AsyncClosingFunction<V, U>() {
833      @Override
834      public ClosingFuture<U> apply(DeferredCloser closer, V input) throws Exception {
835        return ClosingFuture.from(function.apply(input));
836      }
837    };
838  }
839
840  /**
841   * Returns a new {@code ClosingFuture} pipeline step derived from this one by applying a function
842   * to its exception if it is an instance of a given exception type. The function can use a {@link
843   * DeferredCloser} to capture objects to be closed when the pipeline is done.
844   *
845   * <p>If this {@code ClosingFuture} succeeds or fails with a different exception type, the
846   * function will not be called, and the derived {@code ClosingFuture} will be equivalent to this
847   * one.
848   *
849   * <p>If the function throws an exception, that exception is used as the result of the derived
850   * {@code ClosingFuture}.
851   *
852   * <p>Example usage:
853   *
854   * <pre>{@code
855   * ClosingFuture<QueryResult> queryFuture =
856   *     queryFuture.catching(
857   *         QueryException.class, (closer, x) -> Query.emptyQueryResult(), executor);
858   * }</pre>
859   *
860   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
861   * the discussion in the {@link ListenableFuture#addListener} documentation. All its warnings
862   * about heavyweight listeners are also applicable to heavyweight functions passed to this method.
863   *
864   * <p>After calling this method, you may not call {@link #finishToFuture()}, {@link
865   * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, or any other derivation method on
866   * the original {@code ClosingFuture} instance.
867   *
868   * @param exceptionType the exception type that triggers use of {@code fallback}. The exception
869   *     type is matched against this step's exception. "This step's exception" means the cause of
870   *     the {@link ExecutionException} thrown by {@link Future#get()} on the {@link Future}
871   *     underlying this step or, if {@code get()} throws a different kind of exception, that
872   *     exception itself. To avoid hiding bugs and other unrecoverable errors, callers should
873   *     prefer more specific types, avoiding {@code Throwable.class} in particular.
874   * @param fallback the function to be called if this step fails with the expected exception type.
875   *     The function's argument is this step's exception. "This step's exception" means the cause
876   *     of the {@link ExecutionException} thrown by {@link Future#get()} on the {@link Future}
877   *     underlying this step or, if {@code get()} throws a different kind of exception, that
878   *     exception itself.
879   * @param executor the executor that runs {@code fallback} if the input fails
880   */
881  public <X extends Throwable> ClosingFuture<V> catching(
882      Class<X> exceptionType, ClosingFunction<? super X, ? extends V> fallback, Executor executor) {
883    return catchingMoreGeneric(exceptionType, fallback, executor);
884  }
885
886  // Avoids generic type capture inconsistency problems where |? extends V| is incompatible with V.
887  private <X extends Throwable, W extends V> ClosingFuture<V> catchingMoreGeneric(
888      Class<X> exceptionType, final ClosingFunction<? super X, W> fallback, Executor executor) {
889    checkNotNull(fallback);
890    AsyncFunction<X, W> applyFallback =
891        new AsyncFunction<X, W>() {
892          @Override
893          public ListenableFuture<W> apply(X exception) throws Exception {
894            return closeables.applyClosingFunction(fallback, exception);
895          }
896
897          @Override
898          public String toString() {
899            return fallback.toString();
900          }
901        };
902    // TODO(dpb): Switch to future.catchingSync when that exists (passing a throwing function).
903    return derive(future.catchingAsync(exceptionType, applyFallback, executor));
904  }
905
906  /**
907   * Returns a new {@code ClosingFuture} pipeline step derived from this one by applying a function
908   * that returns a {@code ClosingFuture} to its exception if it is an instance of a given exception
909   * type. The function can use a {@link DeferredCloser} to capture objects to be closed when the
910   * pipeline is done (other than those captured by the returned {@link ClosingFuture}).
911   *
912   * <p>If this {@code ClosingFuture} fails with an exception of the given type, the derived {@code
913   * ClosingFuture} will be equivalent to the one returned by the function.
914   *
915   * <p>If this {@code ClosingFuture} succeeds or fails with a different exception type, the
916   * function will not be called, and the derived {@code ClosingFuture} will be equivalent to this
917   * one.
918   *
919   * <p>If the function throws an exception, that exception is used as the result of the derived
920   * {@code ClosingFuture}. But if the exception is thrown after the function creates a {@code
921   * ClosingFuture}, then none of the closeable objects in that {@code ClosingFuture} will be
922   * closed.
923   *
924   * <p>Usage guidelines for this method:
925   *
926   * <ul>
927   *   <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a
928   *       {@code ClosingFuture}. If possible, prefer calling {@link #catching(Class,
929   *       ClosingFunction, Executor)} instead, with a function that returns the next value
930   *       directly.
931   *   <li>Call {@link DeferredCloser#eventuallyClose(Object, Executor) closer.eventuallyClose()}
932   *       for every closeable object this step creates in order to capture it for later closing.
933   *   <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code
934   *       ClosingFuture} call {@link #from(ListenableFuture)}.
935   *   <li>In case this step doesn't create new closeables, you can adapt an API that returns a
936   *       {@link ListenableFuture} to return a {@code ClosingFuture} by wrapping it with a call to
937   *       {@link #withoutCloser(AsyncFunction)}
938   * </ul>
939   *
940   * <p>Example usage:
941   *
942   * <pre>{@code
943   * // Fall back to a secondary input stream in case of IOException.
944   * ClosingFuture<InputStream> inputFuture =
945   *     firstInputFuture.catchingAsync(
946   *         IOException.class, (closer, x) -> secondaryInputStreamClosingFuture(), executor);
947   * }
948   * }</pre>
949   *
950   * <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
951   * the discussion in the {@link ListenableFuture#addListener} documentation. All its warnings
952   * about heavyweight listeners are also applicable to heavyweight functions passed to this method.
953   * (Specifically, {@code directExecutor} functions should avoid heavyweight operations inside
954   * {@code AsyncClosingFunction.apply}. Any heavyweight operations should occur in other threads
955   * responsible for completing the returned {@code ClosingFuture}.)
956   *
957   * <p>After calling this method, you may not call {@link #finishToFuture()}, {@link
958   * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, or any other derivation method on
959   * the original {@code ClosingFuture} instance.
960   *
961   * @param exceptionType the exception type that triggers use of {@code fallback}. The exception
962   *     type is matched against this step's exception. "This step's exception" means the cause of
963   *     the {@link ExecutionException} thrown by {@link Future#get()} on the {@link Future}
964   *     underlying this step or, if {@code get()} throws a different kind of exception, that
965   *     exception itself. To avoid hiding bugs and other unrecoverable errors, callers should
966   *     prefer more specific types, avoiding {@code Throwable.class} in particular.
967   * @param fallback the function to be called if this step fails with the expected exception type.
968   *     The function's argument is this step's exception. "This step's exception" means the cause
969   *     of the {@link ExecutionException} thrown by {@link Future#get()} on the {@link Future}
970   *     underlying this step or, if {@code get()} throws a different kind of exception, that
971   *     exception itself.
972   * @param executor the executor that runs {@code fallback} if the input fails
973   */
974  // TODO(dpb): Should this do something special if the function throws CancellationException or
975  // ExecutionException?
976  public <X extends Throwable> ClosingFuture<V> catchingAsync(
977      Class<X> exceptionType,
978      AsyncClosingFunction<? super X, ? extends V> fallback,
979      Executor executor) {
980    return catchingAsyncMoreGeneric(exceptionType, fallback, executor);
981  }
982
983  // Avoids generic type capture inconsistency problems where |? extends V| is incompatible with V.
984  private <X extends Throwable, W extends V> ClosingFuture<V> catchingAsyncMoreGeneric(
985      Class<X> exceptionType,
986      final AsyncClosingFunction<? super X, W> fallback,
987      Executor executor) {
988    checkNotNull(fallback);
989    AsyncFunction<X, W> asyncFunction =
990        new AsyncFunction<X, W>() {
991          @Override
992          public ListenableFuture<W> apply(X exception) throws Exception {
993            return closeables.applyAsyncClosingFunction(fallback, exception);
994          }
995
996          @Override
997          public String toString() {
998            return fallback.toString();
999          }
1000        };
1001    return derive(future.catchingAsync(exceptionType, asyncFunction, executor));
1002  }
1003
1004  /**
1005   * Marks this step as the last step in the {@code ClosingFuture} pipeline.
1006   *
1007   * <p>The returned {@link Future} is completed when the pipeline's computation completes, or when
1008   * the pipeline is cancelled.
1009   *
1010   * <p>All objects the pipeline has captured for closing will begin to be closed asynchronously
1011   * <b>after</b> the returned {@code Future} is done: the future completes before closing starts,
1012   * rather than once it has finished.
1013   *
1014   * <p>After calling this method, you may not call {@link
1015   * #finishToValueAndCloser(ValueAndCloserConsumer, Executor)}, this method, or any other
1016   * derivation method on the original {@code ClosingFuture} instance.
1017   *
1018   * @return a {@link Future} that represents the final value or exception of the pipeline
1019   */
1020  public FluentFuture<V> finishToFuture() {
1021    if (compareAndUpdateState(OPEN, WILL_CLOSE)) {
1022      logger.get().log(FINER, "will close {0}", this);
1023      future.addListener(
1024          new Runnable() {
1025            @Override
1026            public void run() {
1027              checkAndUpdateState(WILL_CLOSE, CLOSING);
1028              close();
1029              checkAndUpdateState(CLOSING, CLOSED);
1030            }
1031          },
1032          directExecutor());
1033    } else {
1034      switch (state.get()) {
1035        case SUBSUMED:
1036          throw new IllegalStateException(
1037              "Cannot call finishToFuture() after deriving another step");
1038
1039        case WILL_CREATE_VALUE_AND_CLOSER:
1040          throw new IllegalStateException(
1041              "Cannot call finishToFuture() after calling finishToValueAndCloser()");
1042
1043        case WILL_CLOSE:
1044        case CLOSING:
1045        case CLOSED:
1046          throw new IllegalStateException("Cannot call finishToFuture() twice");
1047
1048        case OPEN:
1049          throw new AssertionError();
1050      }
1051    }
1052    return future;
1053  }
1054
1055  /**
1056   * Marks this step as the last step in the {@code ClosingFuture} pipeline. When this step is done,
1057   * {@code receiver} will be called with an object that contains the result of the operation. The
1058   * receiver can store the {@link ValueAndCloser} outside the receiver for later synchronous use.
1059   *
1060   * <p>After calling this method, you may not call {@link #finishToFuture()}, this method again, or
1061   * any other derivation method on the original {@code ClosingFuture} instance.
1062   *
1063   * @param consumer a callback whose method will be called (using {@code executor}) when this
1064   *     operation is done
1065   */
1066  public void finishToValueAndCloser(
1067      final ValueAndCloserConsumer<? super V> consumer, Executor executor) {
1068    checkNotNull(consumer);
1069    if (!compareAndUpdateState(OPEN, WILL_CREATE_VALUE_AND_CLOSER)) {
1070      switch (state.get()) {
1071        case SUBSUMED:
1072          throw new IllegalStateException(
1073              "Cannot call finishToValueAndCloser() after deriving another step");
1074
1075        case WILL_CLOSE:
1076        case CLOSING:
1077        case CLOSED:
1078          throw new IllegalStateException(
1079              "Cannot call finishToValueAndCloser() after calling finishToFuture()");
1080
1081        case WILL_CREATE_VALUE_AND_CLOSER:
1082          throw new IllegalStateException("Cannot call finishToValueAndCloser() twice");
1083
1084        case OPEN:
1085          break;
1086      }
1087      throw new AssertionError(state);
1088    }
1089    future.addListener(
1090        new Runnable() {
1091          @Override
1092          public void run() {
1093            provideValueAndCloser(consumer, ClosingFuture.this);
1094          }
1095        },
1096        executor);
1097  }
1098
1099  private static <C extends @Nullable Object, V extends C> void provideValueAndCloser(
1100      ValueAndCloserConsumer<C> consumer, ClosingFuture<V> closingFuture) {
1101    consumer.accept(new ValueAndCloser<C>(closingFuture));
1102  }
1103
1104  /**
1105   * Attempts to cancel execution of this step. This attempt will fail if the step has already
1106   * completed, has already been cancelled, or could not be cancelled for some other reason. If
1107   * successful, and this step has not started when {@code cancel} is called, this step should never
1108   * run.
1109   *
1110   * <p>If successful, causes the objects captured by this step (if already started) and its input
1111   * step(s) for later closing to be closed on their respective {@link Executor}s. If any such calls
1112   * specified {@link MoreExecutors#directExecutor()}, those objects will be closed synchronously.
1113   *
1114   * @param mayInterruptIfRunning {@code true} if the thread executing this task should be
1115   *     interrupted; otherwise, in-progress tasks are allowed to complete, but the step will be
1116   *     cancelled regardless
1117   * @return {@code false} if the step could not be cancelled, typically because it has already
1118   *     completed normally; {@code true} otherwise
1119   */
1120  @CanIgnoreReturnValue
1121  public boolean cancel(boolean mayInterruptIfRunning) {
1122    logger.get().log(FINER, "cancelling {0}", this);
1123    boolean cancelled = future.cancel(mayInterruptIfRunning);
1124    if (cancelled) {
1125      close();
1126    }
1127    return cancelled;
1128  }
1129
1130  private void close() {
1131    logger.get().log(FINER, "closing {0}", this);
1132    closeables.close();
1133  }
1134
1135  private <U extends @Nullable Object> ClosingFuture<U> derive(FluentFuture<U> future) {
1136    ClosingFuture<U> derived = new ClosingFuture<>(future);
1137    becomeSubsumedInto(derived.closeables);
1138    return derived;
1139  }
1140
1141  private void becomeSubsumedInto(CloseableList otherCloseables) {
1142    checkAndUpdateState(OPEN, SUBSUMED);
1143    otherCloseables.add(closeables, directExecutor());
1144  }
1145
1146  /**
1147   * An object that can return the value of the {@link ClosingFuture}s that are passed to {@link
1148   * #whenAllComplete(Iterable)} or {@link #whenAllSucceed(Iterable)}.
1149   *
1150   * <p>Only for use by a {@link CombiningCallable} or {@link AsyncCombiningCallable} object.
1151   */
1152  public static final class Peeker {
1153    private final ImmutableList<ClosingFuture<?>> futures;
1154    private volatile boolean beingCalled;
1155
1156    private Peeker(ImmutableList<ClosingFuture<?>> futures) {
1157      this.futures = checkNotNull(futures);
1158    }
1159
1160    /**
1161     * Returns the value of {@code closingFuture}.
1162     *
1163     * @throws ExecutionException if {@code closingFuture} is a failed step
1164     * @throws CancellationException if the {@code closingFuture}'s future was cancelled
1165     * @throws IllegalArgumentException if {@code closingFuture} is not one of the futures passed to
1166     *     {@link #whenAllComplete(Iterable)} or {@link #whenAllComplete(Iterable)}
1167     * @throws IllegalStateException if called outside of a call to {@link
1168     *     CombiningCallable#call(DeferredCloser, Peeker)} or {@link
1169     *     AsyncCombiningCallable#call(DeferredCloser, Peeker)}
1170     */
1171    @ParametricNullness
1172    public final <D extends @Nullable Object> D getDone(ClosingFuture<D> closingFuture)
1173        throws ExecutionException {
1174      checkState(beingCalled);
1175      checkArgument(futures.contains(closingFuture));
1176      return Futures.getDone(closingFuture.future);
1177    }
1178
1179    @ParametricNullness
1180    private <V extends @Nullable Object> V call(
1181        CombiningCallable<V> combiner, CloseableList closeables) throws Exception {
1182      beingCalled = true;
1183      CloseableList newCloseables = new CloseableList();
1184      try {
1185        return combiner.call(newCloseables.closer, this);
1186      } finally {
1187        closeables.add(newCloseables, directExecutor());
1188        beingCalled = false;
1189      }
1190    }
1191
1192    private <V extends @Nullable Object> FluentFuture<V> callAsync(
1193        AsyncCombiningCallable<V> combiner, CloseableList closeables) throws Exception {
1194      beingCalled = true;
1195      CloseableList newCloseables = new CloseableList();
1196      try {
1197        ClosingFuture<V> closingFuture = combiner.call(newCloseables.closer, this);
1198        closingFuture.becomeSubsumedInto(closeables);
1199        return closingFuture.future;
1200      } finally {
1201        closeables.add(newCloseables, directExecutor());
1202        beingCalled = false;
1203      }
1204    }
1205  }
1206
1207  /**
1208   * A builder of a {@link ClosingFuture} step that is derived from more than one input step.
1209   *
1210   * <p>See {@link #whenAllComplete(Iterable)} and {@link #whenAllSucceed(Iterable)} for how to
1211   * instantiate this class.
1212   *
1213   * <p>Example:
1214   *
1215   * <pre>{@code
1216   * final ClosingFuture<BufferedReader> file1ReaderFuture = ...;
1217   * final ClosingFuture<BufferedReader> file2ReaderFuture = ...;
1218   * ListenableFuture<Integer> numberOfDifferentLines =
1219   *       ClosingFuture.whenAllSucceed(file1ReaderFuture, file2ReaderFuture)
1220   *           .call(
1221   *               (closer, peeker) -> {
1222   *                 BufferedReader file1Reader = peeker.getDone(file1ReaderFuture);
1223   *                 BufferedReader file2Reader = peeker.getDone(file2ReaderFuture);
1224   *                 return countDifferentLines(file1Reader, file2Reader);
1225   *               },
1226   *               executor)
1227   *           .closing(executor);
1228   * }</pre>
1229   */
1230  // TODO(cpovirk): Use simple name instead of fully qualified after we stop building with JDK 8.
1231  @com.google.errorprone.annotations.DoNotMock(
1232      "Use ClosingFuture.whenAllSucceed() or .whenAllComplete() instead.")
1233  public static class Combiner {
1234
1235    private final CloseableList closeables = new CloseableList();
1236
1237    /**
1238     * An operation that returns a result and may throw an exception.
1239     *
1240     * @param <V> the type of the result
1241     */
1242    @FunctionalInterface
1243    public interface CombiningCallable<V extends @Nullable Object> {
1244      /**
1245       * Computes a result, or throws an exception if unable to do so.
1246       *
1247       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1248       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1249       * (but not before this method completes), even if this method throws or the pipeline is
1250       * cancelled.
1251       *
1252       * @param peeker used to get the value of any of the input futures
1253       */
1254      @ParametricNullness
1255      V call(DeferredCloser closer, Peeker peeker) throws Exception;
1256    }
1257
1258    /**
1259     * An operation that returns a {@link ClosingFuture} result and may throw an exception.
1260     *
1261     * @param <V> the type of the result
1262     */
1263    @FunctionalInterface
1264    public interface AsyncCombiningCallable<V extends @Nullable Object> {
1265      /**
1266       * Computes a {@link ClosingFuture} result, or throws an exception if unable to do so.
1267       *
1268       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1269       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1270       * (but not before this method completes), even if this method throws or the pipeline is
1271       * cancelled.
1272       *
1273       * @param peeker used to get the value of any of the input futures
1274       */
1275      ClosingFuture<V> call(DeferredCloser closer, Peeker peeker) throws Exception;
1276    }
1277
1278    private final boolean allMustSucceed;
1279    protected final ImmutableList<ClosingFuture<?>> inputs;
1280
1281    private Combiner(boolean allMustSucceed, Iterable<? extends ClosingFuture<?>> inputs) {
1282      this.allMustSucceed = allMustSucceed;
1283      this.inputs = ImmutableList.copyOf(inputs);
1284      for (ClosingFuture<?> input : inputs) {
1285        input.becomeSubsumedInto(closeables);
1286      }
1287    }
1288
1289    /**
1290     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
1291     * combining function to their values. The function can use a {@link DeferredCloser} to capture
1292     * objects to be closed when the pipeline is done.
1293     *
1294     * <p>If this combiner was returned by a {@link #whenAllSucceed} method and any of the inputs
1295     * fail, so will the returned step.
1296     *
1297     * <p>If the combiningCallable throws a {@code CancellationException}, the pipeline will be
1298     * cancelled.
1299     *
1300     * <p>If the combiningCallable throws an {@code ExecutionException}, the cause of the thrown
1301     * {@code ExecutionException} will be extracted and used as the failure of the derived step.
1302     */
1303    public <V extends @Nullable Object> ClosingFuture<V> call(
1304        final CombiningCallable<V> combiningCallable, Executor executor) {
1305      Callable<V> callable =
1306          new Callable<V>() {
1307            @Override
1308            @ParametricNullness
1309            public V call() throws Exception {
1310              return new Peeker(inputs).call(combiningCallable, closeables);
1311            }
1312
1313            @Override
1314            public String toString() {
1315              return combiningCallable.toString();
1316            }
1317          };
1318      ClosingFuture<V> derived = new ClosingFuture<>(futureCombiner().call(callable, executor));
1319      derived.closeables.add(closeables, directExecutor());
1320      return derived;
1321    }
1322
1323    /**
1324     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
1325     * {@code ClosingFuture}-returning function to their values. The function can use a {@link
1326     * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those
1327     * captured by the returned {@link ClosingFuture}).
1328     *
1329     * <p>If this combiner was returned by a {@link #whenAllSucceed} method and any of the inputs
1330     * fail, so will the returned step.
1331     *
1332     * <p>If the combiningCallable throws a {@code CancellationException}, the pipeline will be
1333     * cancelled.
1334     *
1335     * <p>If the combiningCallable throws an {@code ExecutionException}, the cause of the thrown
1336     * {@code ExecutionException} will be extracted and used as the failure of the derived step.
1337     *
1338     * <p>If the combiningCallable throws any other exception, it will be used as the failure of the
1339     * derived step.
1340     *
1341     * <p>If an exception is thrown after the combiningCallable creates a {@code ClosingFuture},
1342     * then none of the closeable objects in that {@code ClosingFuture} will be closed.
1343     *
1344     * <p>Usage guidelines for this method:
1345     *
1346     * <ul>
1347     *   <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a
1348     *       {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable,
1349     *       Executor)} instead, with a function that returns the next value directly.
1350     *   <li>Call {@link DeferredCloser#eventuallyClose(Object, Executor) closer.eventuallyClose()}
1351     *       for every closeable object this step creates in order to capture it for later closing.
1352     *   <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code
1353     *       ClosingFuture} call {@link #from(ListenableFuture)}.
1354     * </ul>
1355     *
1356     * <p>The same warnings about doing heavyweight operations within {@link
1357     * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here.
1358     */
1359    public <V extends @Nullable Object> ClosingFuture<V> callAsync(
1360        final AsyncCombiningCallable<V> combiningCallable, Executor executor) {
1361      AsyncCallable<V> asyncCallable =
1362          new AsyncCallable<V>() {
1363            @Override
1364            public ListenableFuture<V> call() throws Exception {
1365              return new Peeker(inputs).callAsync(combiningCallable, closeables);
1366            }
1367
1368            @Override
1369            public String toString() {
1370              return combiningCallable.toString();
1371            }
1372          };
1373      ClosingFuture<V> derived =
1374          new ClosingFuture<>(futureCombiner().callAsync(asyncCallable, executor));
1375      derived.closeables.add(closeables, directExecutor());
1376      return derived;
1377    }
1378
1379    private FutureCombiner<@Nullable Object> futureCombiner() {
1380      return allMustSucceed
1381          ? Futures.whenAllSucceed(inputFutures())
1382          : Futures.whenAllComplete(inputFutures());
1383    }
1384
1385
1386    private ImmutableList<FluentFuture<?>> inputFutures() {
1387      return FluentIterable.from(inputs)
1388          .<FluentFuture<?>>transform(future -> future.future)
1389          .toList();
1390    }
1391  }
1392
1393  /**
1394   * A generic {@link Combiner} that lets you use a lambda or method reference to combine two {@link
1395   * ClosingFuture}s. Use {@link #whenAllSucceed(ClosingFuture, ClosingFuture)} to start this
1396   * combination.
1397   *
1398   * @param <V1> the type returned by the first future
1399   * @param <V2> the type returned by the second future
1400   */
1401  public static final class Combiner2<V1 extends @Nullable Object, V2 extends @Nullable Object>
1402      extends Combiner {
1403
1404    /**
1405     * A function that returns a value when applied to the values of the two futures passed to
1406     * {@link #whenAllSucceed(ClosingFuture, ClosingFuture)}.
1407     *
1408     * @param <V1> the type returned by the first future
1409     * @param <V2> the type returned by the second future
1410     * @param <U> the type returned by the function
1411     */
1412    @FunctionalInterface
1413    public interface ClosingFunction2<
1414        V1 extends @Nullable Object, V2 extends @Nullable Object, U extends @Nullable Object> {
1415
1416      /**
1417       * Applies this function to two inputs, or throws an exception if unable to do so.
1418       *
1419       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1420       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1421       * (but not before this method completes), even if this method throws or the pipeline is
1422       * cancelled.
1423       */
1424      @ParametricNullness
1425      U apply(DeferredCloser closer, @ParametricNullness V1 value1, @ParametricNullness V2 value2)
1426          throws Exception;
1427    }
1428
1429    /**
1430     * A function that returns a {@link ClosingFuture} when applied to the values of the two futures
1431     * passed to {@link #whenAllSucceed(ClosingFuture, ClosingFuture)}.
1432     *
1433     * @param <V1> the type returned by the first future
1434     * @param <V2> the type returned by the second future
1435     * @param <U> the type returned by the function
1436     */
1437    @FunctionalInterface
1438    public interface AsyncClosingFunction2<
1439        V1 extends @Nullable Object, V2 extends @Nullable Object, U extends @Nullable Object> {
1440
1441      /**
1442       * Applies this function to two inputs, or throws an exception if unable to do so.
1443       *
1444       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1445       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1446       * (but not before this method completes), even if this method throws or the pipeline is
1447       * cancelled.
1448       */
1449      ClosingFuture<U> apply(
1450          DeferredCloser closer, @ParametricNullness V1 value1, @ParametricNullness V2 value2)
1451          throws Exception;
1452    }
1453
1454    private final ClosingFuture<V1> future1;
1455    private final ClosingFuture<V2> future2;
1456
1457    private Combiner2(ClosingFuture<V1> future1, ClosingFuture<V2> future2) {
1458      super(true, ImmutableList.of(future1, future2));
1459      this.future1 = future1;
1460      this.future2 = future2;
1461    }
1462
1463    /**
1464     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
1465     * combining function to their values. The function can use a {@link DeferredCloser} to capture
1466     * objects to be closed when the pipeline is done.
1467     *
1468     * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture)} and
1469     * any of the inputs fail, so will the returned step.
1470     *
1471     * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled.
1472     *
1473     * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code
1474     * ExecutionException} will be extracted and used as the failure of the derived step.
1475     */
1476    public <U extends @Nullable Object> ClosingFuture<U> call(
1477        final ClosingFunction2<V1, V2, U> function, Executor executor) {
1478      return call(
1479          new CombiningCallable<U>() {
1480            @Override
1481            @ParametricNullness
1482            public U call(DeferredCloser closer, Peeker peeker) throws Exception {
1483              return function.apply(closer, peeker.getDone(future1), peeker.getDone(future2));
1484            }
1485
1486            @Override
1487            public String toString() {
1488              return function.toString();
1489            }
1490          },
1491          executor);
1492    }
1493
1494    /**
1495     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
1496     * {@code ClosingFuture}-returning function to their values. The function can use a {@link
1497     * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those
1498     * captured by the returned {@link ClosingFuture}).
1499     *
1500     * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture)} and
1501     * any of the inputs fail, so will the returned step.
1502     *
1503     * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled.
1504     *
1505     * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code
1506     * ExecutionException} will be extracted and used as the failure of the derived step.
1507     *
1508     * <p>If the function throws any other exception, it will be used as the failure of the derived
1509     * step.
1510     *
1511     * <p>If an exception is thrown after the function creates a {@code ClosingFuture}, then none of
1512     * the closeable objects in that {@code ClosingFuture} will be closed.
1513     *
1514     * <p>Usage guidelines for this method:
1515     *
1516     * <ul>
1517     *   <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a
1518     *       {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable,
1519     *       Executor)} instead, with a function that returns the next value directly.
1520     *   <li>Call {@link DeferredCloser#eventuallyClose(Object, Executor) closer.eventuallyClose()}
1521     *       for every closeable object this step creates in order to capture it for later closing.
1522     *   <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code
1523     *       ClosingFuture} call {@link #from(ListenableFuture)}.
1524     * </ul>
1525     *
1526     * <p>The same warnings about doing heavyweight operations within {@link
1527     * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here.
1528     */
1529    public <U extends @Nullable Object> ClosingFuture<U> callAsync(
1530        final AsyncClosingFunction2<V1, V2, U> function, Executor executor) {
1531      return callAsync(
1532          new AsyncCombiningCallable<U>() {
1533            @Override
1534            public ClosingFuture<U> call(DeferredCloser closer, Peeker peeker) throws Exception {
1535              return function.apply(closer, peeker.getDone(future1), peeker.getDone(future2));
1536            }
1537
1538            @Override
1539            public String toString() {
1540              return function.toString();
1541            }
1542          },
1543          executor);
1544    }
1545  }
1546
1547  /**
1548   * A generic {@link Combiner} that lets you use a lambda or method reference to combine three
1549   * {@link ClosingFuture}s. Use {@link #whenAllSucceed(ClosingFuture, ClosingFuture,
1550   * ClosingFuture)} to start this combination.
1551   *
1552   * @param <V1> the type returned by the first future
1553   * @param <V2> the type returned by the second future
1554   * @param <V3> the type returned by the third future
1555   */
1556  public static final class Combiner3<
1557          V1 extends @Nullable Object, V2 extends @Nullable Object, V3 extends @Nullable Object>
1558      extends Combiner {
1559    /**
1560     * A function that returns a value when applied to the values of the three futures passed to
1561     * {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture)}.
1562     *
1563     * @param <V1> the type returned by the first future
1564     * @param <V2> the type returned by the second future
1565     * @param <V3> the type returned by the third future
1566     * @param <U> the type returned by the function
1567     */
1568    @FunctionalInterface
1569    public interface ClosingFunction3<
1570        V1 extends @Nullable Object,
1571        V2 extends @Nullable Object,
1572        V3 extends @Nullable Object,
1573        U extends @Nullable Object> {
1574      /**
1575       * Applies this function to three inputs, or throws an exception if unable to do so.
1576       *
1577       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1578       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1579       * (but not before this method completes), even if this method throws or the pipeline is
1580       * cancelled.
1581       */
1582      @ParametricNullness
1583      U apply(
1584          DeferredCloser closer,
1585          @ParametricNullness V1 value1,
1586          @ParametricNullness V2 value2,
1587          @ParametricNullness V3 value3)
1588          throws Exception;
1589    }
1590
1591    /**
1592     * A function that returns a {@link ClosingFuture} when applied to the values of the three
1593     * futures passed to {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture)}.
1594     *
1595     * @param <V1> the type returned by the first future
1596     * @param <V2> the type returned by the second future
1597     * @param <V3> the type returned by the third future
1598     * @param <U> the type returned by the function
1599     */
1600    @FunctionalInterface
1601    public interface AsyncClosingFunction3<
1602        V1 extends @Nullable Object,
1603        V2 extends @Nullable Object,
1604        V3 extends @Nullable Object,
1605        U extends @Nullable Object> {
1606      /**
1607       * Applies this function to three inputs, or throws an exception if unable to do so.
1608       *
1609       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1610       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1611       * (but not before this method completes), even if this method throws or the pipeline is
1612       * cancelled.
1613       */
1614      ClosingFuture<U> apply(
1615          DeferredCloser closer,
1616          @ParametricNullness V1 value1,
1617          @ParametricNullness V2 value2,
1618          @ParametricNullness V3 value3)
1619          throws Exception;
1620    }
1621
1622    private final ClosingFuture<V1> future1;
1623    private final ClosingFuture<V2> future2;
1624    private final ClosingFuture<V3> future3;
1625
1626    private Combiner3(
1627        ClosingFuture<V1> future1, ClosingFuture<V2> future2, ClosingFuture<V3> future3) {
1628      super(true, ImmutableList.of(future1, future2, future3));
1629      this.future1 = future1;
1630      this.future2 = future2;
1631      this.future3 = future3;
1632    }
1633
1634    /**
1635     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
1636     * combining function to their values. The function can use a {@link DeferredCloser} to capture
1637     * objects to be closed when the pipeline is done.
1638     *
1639     * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture,
1640     * ClosingFuture)} and any of the inputs fail, so will the returned step.
1641     *
1642     * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled.
1643     *
1644     * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code
1645     * ExecutionException} will be extracted and used as the failure of the derived step.
1646     */
1647    public <U extends @Nullable Object> ClosingFuture<U> call(
1648        final ClosingFunction3<V1, V2, V3, U> function, Executor executor) {
1649      return call(
1650          new CombiningCallable<U>() {
1651            @Override
1652            @ParametricNullness
1653            public U call(DeferredCloser closer, Peeker peeker) throws Exception {
1654              return function.apply(
1655                  closer,
1656                  peeker.getDone(future1),
1657                  peeker.getDone(future2),
1658                  peeker.getDone(future3));
1659            }
1660
1661            @Override
1662            public String toString() {
1663              return function.toString();
1664            }
1665          },
1666          executor);
1667    }
1668
1669    /**
1670     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
1671     * {@code ClosingFuture}-returning function to their values. The function can use a {@link
1672     * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those
1673     * captured by the returned {@link ClosingFuture}).
1674     *
1675     * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture,
1676     * ClosingFuture)} and any of the inputs fail, so will the returned step.
1677     *
1678     * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled.
1679     *
1680     * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code
1681     * ExecutionException} will be extracted and used as the failure of the derived step.
1682     *
1683     * <p>If the function throws any other exception, it will be used as the failure of the derived
1684     * step.
1685     *
1686     * <p>If an exception is thrown after the function creates a {@code ClosingFuture}, then none of
1687     * the closeable objects in that {@code ClosingFuture} will be closed.
1688     *
1689     * <p>Usage guidelines for this method:
1690     *
1691     * <ul>
1692     *   <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a
1693     *       {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable,
1694     *       Executor)} instead, with a function that returns the next value directly.
1695     *   <li>Call {@link DeferredCloser#eventuallyClose(Object, Executor) closer.eventuallyClose()}
1696     *       for every closeable object this step creates in order to capture it for later closing.
1697     *   <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code
1698     *       ClosingFuture} call {@link #from(ListenableFuture)}.
1699     * </ul>
1700     *
1701     * <p>The same warnings about doing heavyweight operations within {@link
1702     * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here.
1703     */
1704    public <U extends @Nullable Object> ClosingFuture<U> callAsync(
1705        final AsyncClosingFunction3<V1, V2, V3, U> function, Executor executor) {
1706      return callAsync(
1707          new AsyncCombiningCallable<U>() {
1708            @Override
1709            public ClosingFuture<U> call(DeferredCloser closer, Peeker peeker) throws Exception {
1710              return function.apply(
1711                  closer,
1712                  peeker.getDone(future1),
1713                  peeker.getDone(future2),
1714                  peeker.getDone(future3));
1715            }
1716
1717            @Override
1718            public String toString() {
1719              return function.toString();
1720            }
1721          },
1722          executor);
1723    }
1724  }
1725
1726  /**
1727   * A generic {@link Combiner} that lets you use a lambda or method reference to combine four
1728   * {@link ClosingFuture}s. Use {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture,
1729   * ClosingFuture)} to start this combination.
1730   *
1731   * @param <V1> the type returned by the first future
1732   * @param <V2> the type returned by the second future
1733   * @param <V3> the type returned by the third future
1734   * @param <V4> the type returned by the fourth future
1735   */
1736  public static final class Combiner4<
1737          V1 extends @Nullable Object,
1738          V2 extends @Nullable Object,
1739          V3 extends @Nullable Object,
1740          V4 extends @Nullable Object>
1741      extends Combiner {
1742    /**
1743     * A function that returns a value when applied to the values of the four futures passed to
1744     * {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture, ClosingFuture)}.
1745     *
1746     * @param <V1> the type returned by the first future
1747     * @param <V2> the type returned by the second future
1748     * @param <V3> the type returned by the third future
1749     * @param <V4> the type returned by the fourth future
1750     * @param <U> the type returned by the function
1751     */
1752    @FunctionalInterface
1753    public interface ClosingFunction4<
1754        V1 extends @Nullable Object,
1755        V2 extends @Nullable Object,
1756        V3 extends @Nullable Object,
1757        V4 extends @Nullable Object,
1758        U extends @Nullable Object> {
1759      /**
1760       * Applies this function to four inputs, or throws an exception if unable to do so.
1761       *
1762       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1763       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1764       * (but not before this method completes), even if this method throws or the pipeline is
1765       * cancelled.
1766       */
1767      @ParametricNullness
1768      U apply(
1769          DeferredCloser closer,
1770          @ParametricNullness V1 value1,
1771          @ParametricNullness V2 value2,
1772          @ParametricNullness V3 value3,
1773          @ParametricNullness V4 value4)
1774          throws Exception;
1775    }
1776
1777    /**
1778     * A function that returns a {@link ClosingFuture} when applied to the values of the four
1779     * futures passed to {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture,
1780     * ClosingFuture)}.
1781     *
1782     * @param <V1> the type returned by the first future
1783     * @param <V2> the type returned by the second future
1784     * @param <V3> the type returned by the third future
1785     * @param <V4> the type returned by the fourth future
1786     * @param <U> the type returned by the function
1787     */
1788    @FunctionalInterface
1789    public interface AsyncClosingFunction4<
1790        V1 extends @Nullable Object,
1791        V2 extends @Nullable Object,
1792        V3 extends @Nullable Object,
1793        V4 extends @Nullable Object,
1794        U extends @Nullable Object> {
1795      /**
1796       * Applies this function to four inputs, or throws an exception if unable to do so.
1797       *
1798       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1799       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1800       * (but not before this method completes), even if this method throws or the pipeline is
1801       * cancelled.
1802       */
1803      ClosingFuture<U> apply(
1804          DeferredCloser closer,
1805          @ParametricNullness V1 value1,
1806          @ParametricNullness V2 value2,
1807          @ParametricNullness V3 value3,
1808          @ParametricNullness V4 value4)
1809          throws Exception;
1810    }
1811
1812    private final ClosingFuture<V1> future1;
1813    private final ClosingFuture<V2> future2;
1814    private final ClosingFuture<V3> future3;
1815    private final ClosingFuture<V4> future4;
1816
1817    private Combiner4(
1818        ClosingFuture<V1> future1,
1819        ClosingFuture<V2> future2,
1820        ClosingFuture<V3> future3,
1821        ClosingFuture<V4> future4) {
1822      super(true, ImmutableList.of(future1, future2, future3, future4));
1823      this.future1 = future1;
1824      this.future2 = future2;
1825      this.future3 = future3;
1826      this.future4 = future4;
1827    }
1828
1829    /**
1830     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
1831     * combining function to their values. The function can use a {@link DeferredCloser} to capture
1832     * objects to be closed when the pipeline is done.
1833     *
1834     * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture,
1835     * ClosingFuture, ClosingFuture)} and any of the inputs fail, so will the returned step.
1836     *
1837     * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled.
1838     *
1839     * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code
1840     * ExecutionException} will be extracted and used as the failure of the derived step.
1841     */
1842    public <U extends @Nullable Object> ClosingFuture<U> call(
1843        final ClosingFunction4<V1, V2, V3, V4, U> function, Executor executor) {
1844      return call(
1845          new CombiningCallable<U>() {
1846            @Override
1847            @ParametricNullness
1848            public U call(DeferredCloser closer, Peeker peeker) throws Exception {
1849              return function.apply(
1850                  closer,
1851                  peeker.getDone(future1),
1852                  peeker.getDone(future2),
1853                  peeker.getDone(future3),
1854                  peeker.getDone(future4));
1855            }
1856
1857            @Override
1858            public String toString() {
1859              return function.toString();
1860            }
1861          },
1862          executor);
1863    }
1864
1865    /**
1866     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
1867     * {@code ClosingFuture}-returning function to their values. The function can use a {@link
1868     * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those
1869     * captured by the returned {@link ClosingFuture}).
1870     *
1871     * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture,
1872     * ClosingFuture, ClosingFuture)} and any of the inputs fail, so will the returned step.
1873     *
1874     * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled.
1875     *
1876     * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code
1877     * ExecutionException} will be extracted and used as the failure of the derived step.
1878     *
1879     * <p>If the function throws any other exception, it will be used as the failure of the derived
1880     * step.
1881     *
1882     * <p>If an exception is thrown after the function creates a {@code ClosingFuture}, then none of
1883     * the closeable objects in that {@code ClosingFuture} will be closed.
1884     *
1885     * <p>Usage guidelines for this method:
1886     *
1887     * <ul>
1888     *   <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a
1889     *       {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable,
1890     *       Executor)} instead, with a function that returns the next value directly.
1891     *   <li>Call {@link DeferredCloser#eventuallyClose(Object, Executor) closer.eventuallyClose()}
1892     *       for every closeable object this step creates in order to capture it for later closing.
1893     *   <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code
1894     *       ClosingFuture} call {@link #from(ListenableFuture)}.
1895     * </ul>
1896     *
1897     * <p>The same warnings about doing heavyweight operations within {@link
1898     * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here.
1899     */
1900    public <U extends @Nullable Object> ClosingFuture<U> callAsync(
1901        final AsyncClosingFunction4<V1, V2, V3, V4, U> function, Executor executor) {
1902      return callAsync(
1903          new AsyncCombiningCallable<U>() {
1904            @Override
1905            public ClosingFuture<U> call(DeferredCloser closer, Peeker peeker) throws Exception {
1906              return function.apply(
1907                  closer,
1908                  peeker.getDone(future1),
1909                  peeker.getDone(future2),
1910                  peeker.getDone(future3),
1911                  peeker.getDone(future4));
1912            }
1913
1914            @Override
1915            public String toString() {
1916              return function.toString();
1917            }
1918          },
1919          executor);
1920    }
1921  }
1922
1923  /**
1924   * A generic {@link Combiner} that lets you use a lambda or method reference to combine five
1925   * {@link ClosingFuture}s. Use {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture,
1926   * ClosingFuture, ClosingFuture)} to start this combination.
1927   *
1928   * @param <V1> the type returned by the first future
1929   * @param <V2> the type returned by the second future
1930   * @param <V3> the type returned by the third future
1931   * @param <V4> the type returned by the fourth future
1932   * @param <V5> the type returned by the fifth future
1933   */
1934  public static final class Combiner5<
1935          V1 extends @Nullable Object,
1936          V2 extends @Nullable Object,
1937          V3 extends @Nullable Object,
1938          V4 extends @Nullable Object,
1939          V5 extends @Nullable Object>
1940      extends Combiner {
1941    /**
1942     * A function that returns a value when applied to the values of the five futures passed to
1943     * {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture, ClosingFuture,
1944     * ClosingFuture)}.
1945     *
1946     * @param <V1> the type returned by the first future
1947     * @param <V2> the type returned by the second future
1948     * @param <V3> the type returned by the third future
1949     * @param <V4> the type returned by the fourth future
1950     * @param <V5> the type returned by the fifth future
1951     * @param <U> the type returned by the function
1952     */
1953    @FunctionalInterface
1954    public interface ClosingFunction5<
1955        V1 extends @Nullable Object,
1956        V2 extends @Nullable Object,
1957        V3 extends @Nullable Object,
1958        V4 extends @Nullable Object,
1959        V5 extends @Nullable Object,
1960        U extends @Nullable Object> {
1961      /**
1962       * Applies this function to five inputs, or throws an exception if unable to do so.
1963       *
1964       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
1965       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
1966       * (but not before this method completes), even if this method throws or the pipeline is
1967       * cancelled.
1968       */
1969      @ParametricNullness
1970      U apply(
1971          DeferredCloser closer,
1972          @ParametricNullness V1 value1,
1973          @ParametricNullness V2 value2,
1974          @ParametricNullness V3 value3,
1975          @ParametricNullness V4 value4,
1976          @ParametricNullness V5 value5)
1977          throws Exception;
1978    }
1979
1980    /**
1981     * A function that returns a {@link ClosingFuture} when applied to the values of the five
1982     * futures passed to {@link #whenAllSucceed(ClosingFuture, ClosingFuture, ClosingFuture,
1983     * ClosingFuture, ClosingFuture)}.
1984     *
1985     * @param <V1> the type returned by the first future
1986     * @param <V2> the type returned by the second future
1987     * @param <V3> the type returned by the third future
1988     * @param <V4> the type returned by the fourth future
1989     * @param <V5> the type returned by the fifth future
1990     * @param <U> the type returned by the function
1991     */
1992    @FunctionalInterface
1993    public interface AsyncClosingFunction5<
1994        V1 extends @Nullable Object,
1995        V2 extends @Nullable Object,
1996        V3 extends @Nullable Object,
1997        V4 extends @Nullable Object,
1998        V5 extends @Nullable Object,
1999        U extends @Nullable Object> {
2000      /**
2001       * Applies this function to five inputs, or throws an exception if unable to do so.
2002       *
2003       * <p>Any objects that are passed to {@link DeferredCloser#eventuallyClose(Object, Executor)
2004       * closer.eventuallyClose()} will be closed when the {@link ClosingFuture} pipeline is done
2005       * (but not before this method completes), even if this method throws or the pipeline is
2006       * cancelled.
2007       */
2008      ClosingFuture<U> apply(
2009          DeferredCloser closer,
2010          @ParametricNullness V1 value1,
2011          @ParametricNullness V2 value2,
2012          @ParametricNullness V3 value3,
2013          @ParametricNullness V4 value4,
2014          @ParametricNullness V5 value5)
2015          throws Exception;
2016    }
2017
2018    private final ClosingFuture<V1> future1;
2019    private final ClosingFuture<V2> future2;
2020    private final ClosingFuture<V3> future3;
2021    private final ClosingFuture<V4> future4;
2022    private final ClosingFuture<V5> future5;
2023
2024    private Combiner5(
2025        ClosingFuture<V1> future1,
2026        ClosingFuture<V2> future2,
2027        ClosingFuture<V3> future3,
2028        ClosingFuture<V4> future4,
2029        ClosingFuture<V5> future5) {
2030      super(true, ImmutableList.of(future1, future2, future3, future4, future5));
2031      this.future1 = future1;
2032      this.future2 = future2;
2033      this.future3 = future3;
2034      this.future4 = future4;
2035      this.future5 = future5;
2036    }
2037
2038    /**
2039     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
2040     * combining function to their values. The function can use a {@link DeferredCloser} to capture
2041     * objects to be closed when the pipeline is done.
2042     *
2043     * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture,
2044     * ClosingFuture, ClosingFuture, ClosingFuture)} and any of the inputs fail, so will the
2045     * returned step.
2046     *
2047     * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled.
2048     *
2049     * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code
2050     * ExecutionException} will be extracted and used as the failure of the derived step.
2051     */
2052    public <U extends @Nullable Object> ClosingFuture<U> call(
2053        final ClosingFunction5<V1, V2, V3, V4, V5, U> function, Executor executor) {
2054      return call(
2055          new CombiningCallable<U>() {
2056            @Override
2057            @ParametricNullness
2058            public U call(DeferredCloser closer, Peeker peeker) throws Exception {
2059              return function.apply(
2060                  closer,
2061                  peeker.getDone(future1),
2062                  peeker.getDone(future2),
2063                  peeker.getDone(future3),
2064                  peeker.getDone(future4),
2065                  peeker.getDone(future5));
2066            }
2067
2068            @Override
2069            public String toString() {
2070              return function.toString();
2071            }
2072          },
2073          executor);
2074    }
2075
2076    /**
2077     * Returns a new {@code ClosingFuture} pipeline step derived from the inputs by applying a
2078     * {@code ClosingFuture}-returning function to their values. The function can use a {@link
2079     * DeferredCloser} to capture objects to be closed when the pipeline is done (other than those
2080     * captured by the returned {@link ClosingFuture}).
2081     *
2082     * <p>If this combiner was returned by {@link #whenAllSucceed(ClosingFuture, ClosingFuture,
2083     * ClosingFuture, ClosingFuture, ClosingFuture)} and any of the inputs fail, so will the
2084     * returned step.
2085     *
2086     * <p>If the function throws a {@code CancellationException}, the pipeline will be cancelled.
2087     *
2088     * <p>If the function throws an {@code ExecutionException}, the cause of the thrown {@code
2089     * ExecutionException} will be extracted and used as the failure of the derived step.
2090     *
2091     * <p>If the function throws any other exception, it will be used as the failure of the derived
2092     * step.
2093     *
2094     * <p>If an exception is thrown after the function creates a {@code ClosingFuture}, then none of
2095     * the closeable objects in that {@code ClosingFuture} will be closed.
2096     *
2097     * <p>Usage guidelines for this method:
2098     *
2099     * <ul>
2100     *   <li>Use this method only when calling an API that returns a {@link ListenableFuture} or a
2101     *       {@code ClosingFuture}. If possible, prefer calling {@link #call(CombiningCallable,
2102     *       Executor)} instead, with a function that returns the next value directly.
2103     *   <li>Call {@link DeferredCloser#eventuallyClose(Object, Executor) closer.eventuallyClose()}
2104     *       for every closeable object this step creates in order to capture it for later closing.
2105     *   <li>Return a {@code ClosingFuture}. To turn a {@link ListenableFuture} into a {@code
2106     *       ClosingFuture} call {@link #from(ListenableFuture)}.
2107     * </ul>
2108     *
2109     * <p>The same warnings about doing heavyweight operations within {@link
2110     * ClosingFuture#transformAsync(AsyncClosingFunction, Executor)} apply here.
2111     */
2112    public <U extends @Nullable Object> ClosingFuture<U> callAsync(
2113        final AsyncClosingFunction5<V1, V2, V3, V4, V5, U> function, Executor executor) {
2114      return callAsync(
2115          new AsyncCombiningCallable<U>() {
2116            @Override
2117            public ClosingFuture<U> call(DeferredCloser closer, Peeker peeker) throws Exception {
2118              return function.apply(
2119                  closer,
2120                  peeker.getDone(future1),
2121                  peeker.getDone(future2),
2122                  peeker.getDone(future3),
2123                  peeker.getDone(future4),
2124                  peeker.getDone(future5));
2125            }
2126
2127            @Override
2128            public String toString() {
2129              return function.toString();
2130            }
2131          },
2132          executor);
2133    }
2134  }
2135
2136  @Override
2137  public String toString() {
2138    // TODO(dpb): Better toString, in the style of Futures.transform etc.
2139    return toStringHelper(this).add("state", state.get()).addValue(future).toString();
2140  }
2141
2142  @SuppressWarnings({"removal", "Finalize"}) // b/260137033
2143  @Override
2144  protected void finalize() {
2145    if (state.get().equals(OPEN)) {
2146      logger.get().log(SEVERE, "Uh oh! An open ClosingFuture has leaked and will close: {0}", this);
2147      FluentFuture<V> unused = finishToFuture();
2148    }
2149  }
2150
2151  private static void closeQuietly(@CheckForNull final AutoCloseable closeable, Executor executor) {
2152    if (closeable == null) {
2153      return;
2154    }
2155    try {
2156      executor.execute(
2157          () -> {
2158            try {
2159              closeable.close();
2160            } catch (Exception e) {
2161              /*
2162               * In guava-jre, any kind of Exception may be thrown because `closeable` has type
2163               * `AutoCloseable`.
2164               *
2165               * In guava-android, the only kinds of Exception that may be thrown are
2166               * RuntimeException and IOException because `closeable` has type `Closeable`—except
2167               * that we have to account for sneaky checked exception.
2168               */
2169              restoreInterruptIfIsInterruptedException(e);
2170              logger.get().log(WARNING, "thrown by close()", e);
2171            }
2172          });
2173    } catch (RejectedExecutionException e) {
2174      if (logger.get().isLoggable(WARNING)) {
2175        logger
2176            .get()
2177            .log(
2178                WARNING,
2179                String.format("while submitting close to %s; will close inline", executor),
2180                e);
2181      }
2182      closeQuietly(closeable, directExecutor());
2183    }
2184  }
2185
2186  private void checkAndUpdateState(State oldState, State newState) {
2187    checkState(
2188        compareAndUpdateState(oldState, newState),
2189        "Expected state to be %s, but it was %s",
2190        oldState,
2191        newState);
2192  }
2193
2194  private boolean compareAndUpdateState(State oldState, State newState) {
2195    return state.compareAndSet(oldState, newState);
2196  }
2197
2198  // TODO(dpb): Should we use a pair of ArrayLists instead of an IdentityHashMap?
2199  private static final class CloseableList extends IdentityHashMap<AutoCloseable, Executor>
2200      implements Closeable {
2201    private final DeferredCloser closer = new DeferredCloser(this);
2202    private volatile boolean closed;
2203    @CheckForNull private volatile CountDownLatch whenClosed;
2204
2205    <V extends @Nullable Object, U extends @Nullable Object>
2206        ListenableFuture<U> applyClosingFunction(
2207            ClosingFunction<? super V, U> transformation, @ParametricNullness V input)
2208            throws Exception {
2209      // TODO(dpb): Consider ways to defer closing without creating a separate CloseableList.
2210      CloseableList newCloseables = new CloseableList();
2211      try {
2212        return immediateFuture(transformation.apply(newCloseables.closer, input));
2213      } finally {
2214        add(newCloseables, directExecutor());
2215      }
2216    }
2217
2218    <V extends @Nullable Object, U extends @Nullable Object>
2219        FluentFuture<U> applyAsyncClosingFunction(
2220            AsyncClosingFunction<V, U> transformation, @ParametricNullness V input)
2221            throws Exception {
2222      // TODO(dpb): Consider ways to defer closing without creating a separate CloseableList.
2223      CloseableList newCloseables = new CloseableList();
2224      try {
2225        ClosingFuture<U> closingFuture = transformation.apply(newCloseables.closer, input);
2226        closingFuture.becomeSubsumedInto(newCloseables);
2227        return closingFuture.future;
2228      } finally {
2229        add(newCloseables, directExecutor());
2230      }
2231    }
2232
2233    @Override
2234    public void close() {
2235      if (closed) {
2236        return;
2237      }
2238      synchronized (this) {
2239        if (closed) {
2240          return;
2241        }
2242        closed = true;
2243      }
2244      for (Map.Entry<AutoCloseable, Executor> entry : entrySet()) {
2245        closeQuietly(entry.getKey(), entry.getValue());
2246      }
2247      clear();
2248      if (whenClosed != null) {
2249        whenClosed.countDown();
2250      }
2251    }
2252
2253    void add(@CheckForNull AutoCloseable closeable, Executor executor) {
2254      checkNotNull(executor);
2255      if (closeable == null) {
2256        return;
2257      }
2258      synchronized (this) {
2259        if (!closed) {
2260          put(closeable, executor);
2261          return;
2262        }
2263      }
2264      closeQuietly(closeable, executor);
2265    }
2266
2267    /**
2268     * Returns a latch that reaches zero when this objects' deferred closeables have been closed.
2269     */
2270    CountDownLatch whenClosedCountDown() {
2271      if (closed) {
2272        return new CountDownLatch(0);
2273      }
2274      synchronized (this) {
2275        if (closed) {
2276          return new CountDownLatch(0);
2277        }
2278        checkState(whenClosed == null);
2279        return whenClosed = new CountDownLatch(1);
2280      }
2281    }
2282  }
2283
2284  /**
2285   * Returns an object that can be used to wait until this objects' deferred closeables have all had
2286   * {@link Runnable}s that close them submitted to each one's closing {@link Executor}.
2287   */
2288  @VisibleForTesting
2289  CountDownLatch whenClosedCountDown() {
2290    return closeables.whenClosedCountDown();
2291  }
2292
2293  /** The state of a {@link CloseableList}. */
2294  enum State {
2295    /** The {@link CloseableList} has not been subsumed or closed. */
2296    OPEN,
2297
2298    /**
2299     * The {@link CloseableList} has been subsumed into another. It may not be closed or subsumed
2300     * into any other.
2301     */
2302    SUBSUMED,
2303
2304    /**
2305     * Some {@link ListenableFuture} has a callback attached that will close the {@link
2306     * CloseableList}, but it has not yet run. The {@link CloseableList} may not be subsumed.
2307     */
2308    WILL_CLOSE,
2309
2310    /**
2311     * The callback that closes the {@link CloseableList} is running, but it has not completed. The
2312     * {@link CloseableList} may not be subsumed.
2313     */
2314    CLOSING,
2315
2316    /** The {@link CloseableList} has been closed. It may not be further subsumed. */
2317    CLOSED,
2318
2319    /**
2320     * {@link ClosingFuture#finishToValueAndCloser(ValueAndCloserConsumer, Executor)} has been
2321     * called. The step may not be further subsumed, nor may {@link #finishToFuture()} be called.
2322     */
2323    WILL_CREATE_VALUE_AND_CLOSER,
2324  }
2325}