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