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