001/*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 */
014
015package com.google.common.base;
016
017import static com.google.common.base.Strings.lenientFormat;
018
019import com.google.common.annotations.GwtCompatible;
020import com.google.errorprone.annotations.CanIgnoreReturnValue;
021import java.util.Objects;
022import org.jspecify.annotations.Nullable;
023
024/**
025 * Static convenience methods that help a method or constructor check whether it was invoked
026 * correctly (that is, whether its <i>preconditions</i> were met).
027 *
028 * <p>If the precondition is not met, the {@code Preconditions} method throws an unchecked exception
029 * of a specified type, which helps the method in which the exception was thrown communicate that
030 * its caller has made a mistake. This allows constructs such as
031 *
032 * {@snippet :
033 * public static double sqrt(double value) {
034 *   if (value < 0) {
035 *     throw new IllegalArgumentException("input is negative: " + value);
036 *   }
037 *   // calculate square root
038 * }
039 * }
040 *
041 * <p>to be replaced with the more compact
042 *
043 * {@snippet :
044 * public static double sqrt(double value) {
045 *   checkArgument(value >= 0, "input is negative: %s", value);
046 *   // calculate square root
047 * }
048 * }
049 *
050 * <p>so that a hypothetical bad caller of this method, such as:
051 *
052 * {@snippet :
053 * void exampleBadCaller() {
054 *   double d = sqrt(-1.0);
055 * }
056 * }
057 *
058 * <p>would be flagged as having called {@code sqrt()} with an illegal argument.
059 *
060 * <h2>Performance</h2>
061 *
062 * <p>Avoid passing message arguments that are expensive to compute; your code will always compute
063 * them, even though they usually won't be needed. If you have such arguments, use the conventional
064 * if/throw idiom instead.
065 *
066 * <p>Depending on your message arguments, memory may be allocated for boxing and varargs array
067 * creation. However, the methods of this class have a large number of overloads that prevent such
068 * allocations in many common cases.
069 *
070 * <p>The message string is not formatted unless the exception will be thrown, so the cost of the
071 * string formatting itself should not be a concern.
072 *
073 * <p>As with any performance concerns, you should consider profiling your code (in a production
074 * environment if possible) before spending a lot of effort on tweaking a particular element.
075 *
076 * <h2>Other types of preconditions</h2>
077 *
078 * <p>Not every type of precondition failure is supported by these methods. Continue to throw
079 * standard JDK exceptions such as {@link java.util.NoSuchElementException} or {@link
080 * UnsupportedOperationException} in the situations they are intended for.
081 *
082 * <h2>Non-preconditions</h2>
083 *
084 * <p>It is of course possible to use the methods of this class to check for invalid conditions
085 * which are <i>not the caller's fault</i>. Doing so is <b>not recommended</b> because it is
086 * misleading to future readers of the code and of stack traces. See <a
087 * href="https://github.com/google/guava/wiki/ConditionalFailuresExplained">Conditional failures
088 * explained</a> in the Guava User Guide for more advice. Notably, {@link Verify} offers assertions
089 * similar to those in this class for non-precondition checks.
090 *
091 * <h2>{@code java.util.Objects.requireNonNull()}</h2>
092 *
093 * <p>Projects which use {@code com.google.common} should generally avoid the use of {@link
094 * Objects#requireNonNull(Object)}. Instead, use whichever of {@link #checkNotNull(Object)} or
095 * {@link Verify#verifyNotNull(Object)} is appropriate to the situation. (The same goes for the
096 * message-accepting overloads.)
097 *
098 * <h2>Only {@code %s} is supported</h2>
099 *
100 * <p>{@code Preconditions} uses {@link Strings#lenientFormat} to format error message template
101 * strings. This only supports the {@code "%s"} specifier, not the full range of {@link
102 * java.util.Formatter} specifiers. However, note that if the number of arguments does not match the
103 * number of occurrences of {@code "%s"} in the format string, {@code Preconditions} will still
104 * behave as expected, and will still include all argument values in the error message; the message
105 * will simply not be formatted exactly as intended.
106 *
107 * <h2>More information</h2>
108 *
109 * <p>See the Guava User Guide on <a
110 * href="https://github.com/google/guava/wiki/PreconditionsExplained">using {@code
111 * Preconditions}</a>.
112 *
113 * @author Kevin Bourrillion
114 * @since 2.0
115 */
116@GwtCompatible
117public final class Preconditions {
118  private Preconditions() {}
119
120  /**
121   * Ensures the truth of an expression involving one or more parameters to the calling method.
122   *
123   * @param expression a boolean expression
124   * @throws IllegalArgumentException if {@code expression} is false
125   */
126  public static void checkArgument(boolean expression) {
127    if (!expression) {
128      throw new IllegalArgumentException();
129    }
130  }
131
132  /**
133   * Ensures the truth of an expression involving one or more parameters to the calling method.
134   *
135   * @param expression a boolean expression
136   * @param errorMessage the exception message to use if the check fails; will be converted to a
137   *     string using {@link String#valueOf(Object)}
138   * @throws IllegalArgumentException if {@code expression} is false
139   */
140  public static void checkArgument(boolean expression, @Nullable Object errorMessage) {
141    if (!expression) {
142      throw new IllegalArgumentException(Platform.stringValueOf(errorMessage));
143    }
144  }
145
146  /**
147   * Ensures the truth of an expression involving one or more parameters to the calling method.
148   *
149   * @param expression a boolean expression
150   * @param errorMessageTemplate a template for the exception message should the check fail. The
151   *     message is formed by replacing each {@code %s} placeholder in the template with an
152   *     argument. These are matched by position - the first {@code %s} gets {@code
153   *     errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in
154   *     square braces. Unmatched placeholders will be left as-is.
155   * @param errorMessageArgs the arguments to be substituted into the message template. Arguments
156   *     are converted to strings using {@link String#valueOf(Object)}.
157   * @throws IllegalArgumentException if {@code expression} is false
158   */
159  public static void checkArgument(
160      boolean expression,
161      String errorMessageTemplate,
162      @Nullable Object @Nullable ... errorMessageArgs) {
163    if (!expression) {
164      throw new IllegalArgumentException(
165          Platform.lenientFormat(errorMessageTemplate, errorMessageArgs));
166    }
167  }
168
169  /**
170   * Ensures the truth of an expression involving one or more parameters to the calling method.
171   *
172   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
173   *
174   * @since 20.0 (varargs overload since 2.0)
175   */
176  public static void checkArgument(
177      boolean expression, String errorMessageTemplate, char p1) {
178    if (!expression) {
179      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1));
180    }
181  }
182
183  /**
184   * Ensures the truth of an expression involving one or more parameters to the calling method.
185   *
186   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
187   *
188   * @since 20.0 (varargs overload since 2.0)
189   */
190  public static void checkArgument(
191      boolean expression, String errorMessageTemplate, int p1) {
192    if (!expression) {
193      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1));
194    }
195  }
196
197  /**
198   * Ensures the truth of an expression involving one or more parameters to the calling method.
199   *
200   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
201   *
202   * @since 20.0 (varargs overload since 2.0)
203   */
204  public static void checkArgument(
205      boolean expression, String errorMessageTemplate, long p1) {
206    if (!expression) {
207      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1));
208    }
209  }
210
211  /**
212   * Ensures the truth of an expression involving one or more parameters to the calling method.
213   *
214   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
215   *
216   * @since 20.0 (varargs overload since 2.0)
217   */
218  public static void checkArgument(
219      boolean expression, String errorMessageTemplate, @Nullable Object p1) {
220    if (!expression) {
221      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1));
222    }
223  }
224
225  /**
226   * Ensures the truth of an expression involving one or more parameters to the calling method.
227   *
228   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
229   *
230   * @since 20.0 (varargs overload since 2.0)
231   */
232  public static void checkArgument(
233      boolean expression, String errorMessageTemplate, char p1, char p2) {
234    if (!expression) {
235      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
236    }
237  }
238
239  /**
240   * Ensures the truth of an expression involving one or more parameters to the calling method.
241   *
242   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
243   *
244   * @since 20.0 (varargs overload since 2.0)
245   */
246  public static void checkArgument(
247      boolean expression, String errorMessageTemplate, char p1, int p2) {
248    if (!expression) {
249      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
250    }
251  }
252
253  /**
254   * Ensures the truth of an expression involving one or more parameters to the calling method.
255   *
256   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
257   *
258   * @since 20.0 (varargs overload since 2.0)
259   */
260  public static void checkArgument(
261      boolean expression, String errorMessageTemplate, char p1, long p2) {
262    if (!expression) {
263      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
264    }
265  }
266
267  /**
268   * Ensures the truth of an expression involving one or more parameters to the calling method.
269   *
270   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
271   *
272   * @since 20.0 (varargs overload since 2.0)
273   */
274  public static void checkArgument(
275      boolean expression,
276      String errorMessageTemplate,
277      char p1,
278      @Nullable Object p2) {
279    if (!expression) {
280      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
281    }
282  }
283
284  /**
285   * Ensures the truth of an expression involving one or more parameters to the calling method.
286   *
287   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
288   *
289   * @since 20.0 (varargs overload since 2.0)
290   */
291  public static void checkArgument(
292      boolean expression, String errorMessageTemplate, int p1, char p2) {
293    if (!expression) {
294      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
295    }
296  }
297
298  /**
299   * Ensures the truth of an expression involving one or more parameters to the calling method.
300   *
301   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
302   *
303   * @since 20.0 (varargs overload since 2.0)
304   */
305  public static void checkArgument(
306      boolean expression, String errorMessageTemplate, int p1, int p2) {
307    if (!expression) {
308      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
309    }
310  }
311
312  /**
313   * Ensures the truth of an expression involving one or more parameters to the calling method.
314   *
315   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
316   *
317   * @since 20.0 (varargs overload since 2.0)
318   */
319  public static void checkArgument(
320      boolean expression, String errorMessageTemplate, int p1, long p2) {
321    if (!expression) {
322      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
323    }
324  }
325
326  /**
327   * Ensures the truth of an expression involving one or more parameters to the calling method.
328   *
329   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
330   *
331   * @since 20.0 (varargs overload since 2.0)
332   */
333  public static void checkArgument(
334      boolean expression,
335      String errorMessageTemplate,
336      int p1,
337      @Nullable Object p2) {
338    if (!expression) {
339      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
340    }
341  }
342
343  /**
344   * Ensures the truth of an expression involving one or more parameters to the calling method.
345   *
346   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
347   *
348   * @since 20.0 (varargs overload since 2.0)
349   */
350  public static void checkArgument(
351      boolean expression, String errorMessageTemplate, long p1, char p2) {
352    if (!expression) {
353      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
354    }
355  }
356
357  /**
358   * Ensures the truth of an expression involving one or more parameters to the calling method.
359   *
360   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
361   *
362   * @since 20.0 (varargs overload since 2.0)
363   */
364  public static void checkArgument(
365      boolean expression, String errorMessageTemplate, long p1, int p2) {
366    if (!expression) {
367      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
368    }
369  }
370
371  /**
372   * Ensures the truth of an expression involving one or more parameters to the calling method.
373   *
374   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
375   *
376   * @since 20.0 (varargs overload since 2.0)
377   */
378  public static void checkArgument(
379      boolean expression, String errorMessageTemplate, long p1, long p2) {
380    if (!expression) {
381      throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
382    }
383  }
384
385  /**
386   * Ensures the truth of an expression involving one or more parameters to the calling method.
387   *
388   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
389   *
390   * @since 20.0 (varargs overload since 2.0)
391   */
392  public static void checkArgument(
393      boolean expression,
394      String errorMessageTemplate,
395      long p1,
396      @Nullable Object p2) {
397    if (!expression) {
398      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
399    }
400  }
401
402  /**
403   * Ensures the truth of an expression involving one or more parameters to the calling method.
404   *
405   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
406   *
407   * @since 20.0 (varargs overload since 2.0)
408   */
409  public static void checkArgument(
410      boolean expression,
411      String errorMessageTemplate,
412      @Nullable Object p1,
413      char p2) {
414    if (!expression) {
415      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
416    }
417  }
418
419  /**
420   * Ensures the truth of an expression involving one or more parameters to the calling method.
421   *
422   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
423   *
424   * @since 20.0 (varargs overload since 2.0)
425   */
426  public static void checkArgument(
427      boolean expression,
428      String errorMessageTemplate,
429      @Nullable Object p1,
430      int p2) {
431    if (!expression) {
432      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
433    }
434  }
435
436  /**
437   * Ensures the truth of an expression involving one or more parameters to the calling method.
438   *
439   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
440   *
441   * @since 20.0 (varargs overload since 2.0)
442   */
443  public static void checkArgument(
444      boolean expression,
445      String errorMessageTemplate,
446      @Nullable Object p1,
447      long p2) {
448    if (!expression) {
449      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
450    }
451  }
452
453  /**
454   * Ensures the truth of an expression involving one or more parameters to the calling method.
455   *
456   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
457   *
458   * @since 20.0 (varargs overload since 2.0)
459   */
460  public static void checkArgument(
461      boolean expression,
462      // TODO(user): Make errorMessageTemplate consistently @Nullable across overloads.
463      @Nullable String errorMessageTemplate,
464      @Nullable Object p1,
465      @Nullable Object p2) {
466    if (!expression) {
467      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
468    }
469  }
470
471  /**
472   * Ensures the truth of an expression involving one or more parameters to the calling method.
473   *
474   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
475   *
476   * @since 20.0 (varargs overload since 2.0)
477   */
478  public static void checkArgument(
479      boolean expression,
480      String errorMessageTemplate,
481      @Nullable Object p1,
482      @Nullable Object p2,
483      @Nullable Object p3) {
484    if (!expression) {
485      throw new IllegalArgumentException(Platform.lenientFormat(errorMessageTemplate, p1, p2, p3));
486    }
487  }
488
489  /**
490   * Ensures the truth of an expression involving one or more parameters to the calling method.
491   *
492   * <p>See {@link #checkArgument(boolean, String, Object...)} for details.
493   *
494   * @since 20.0 (varargs overload since 2.0)
495   */
496  public static void checkArgument(
497      boolean expression,
498      String errorMessageTemplate,
499      @Nullable Object p1,
500      @Nullable Object p2,
501      @Nullable Object p3,
502      @Nullable Object p4) {
503    if (!expression) {
504      throw new IllegalArgumentException(
505          Platform.lenientFormat(errorMessageTemplate, p1, p2, p3, p4));
506    }
507  }
508
509  /**
510   * Ensures the truth of an expression involving the state of the calling instance, but not
511   * involving any parameters to the calling method.
512   *
513   * @param expression a boolean expression
514   * @throws IllegalStateException if {@code expression} is false
515   * @see Verify#verify Verify.verify()
516   */
517  public static void checkState(boolean expression) {
518    if (!expression) {
519      throw new IllegalStateException();
520    }
521  }
522
523  /**
524   * Ensures the truth of an expression involving the state of the calling instance, but not
525   * involving any parameters to the calling method.
526   *
527   * @param expression a boolean expression
528   * @param errorMessage the exception message to use if the check fails; will be converted to a
529   *     string using {@link String#valueOf(Object)}
530   * @throws IllegalStateException if {@code expression} is false
531   * @see Verify#verify Verify.verify()
532   */
533  public static void checkState(boolean expression, @Nullable Object errorMessage) {
534    if (!expression) {
535      throw new IllegalStateException(Platform.stringValueOf(errorMessage));
536    }
537  }
538
539  /**
540   * Ensures the truth of an expression involving the state of the calling instance, but not
541   * involving any parameters to the calling method.
542   *
543   * @param expression a boolean expression
544   * @param errorMessageTemplate a template for the exception message should the check fail. The
545   *     message is formed by replacing each {@code %s} placeholder in the template with an
546   *     argument. These are matched by position - the first {@code %s} gets {@code
547   *     errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in
548   *     square braces. Unmatched placeholders will be left as-is.
549   * @param errorMessageArgs the arguments to be substituted into the message template. Arguments
550   *     are converted to strings using {@link String#valueOf(Object)}.
551   * @throws IllegalStateException if {@code expression} is false
552   * @see Verify#verify Verify.verify()
553   */
554  public static void checkState(
555      boolean expression,
556      /*
557       * TODO(cpovirk): Consider removing @Nullable here, as we've done with the other methods'
558       * errorMessageTemplate parameters: It is unlikely that callers intend for their string
559       * template to be null (though we do handle that case gracefully at runtime). I've left this
560       * one as it is because one of our users has defined a wrapper API around Preconditions,
561       * declaring a checkState method that accepts a possibly null template. So we'd need to update
562       * that user first.
563       */
564      @Nullable String errorMessageTemplate,
565      @Nullable Object @Nullable ... errorMessageArgs) {
566    if (!expression) {
567      throw new IllegalStateException(
568          Platform.lenientFormat(errorMessageTemplate, errorMessageArgs));
569    }
570  }
571
572  /**
573   * Ensures the truth of an expression involving the state of the calling instance, but not
574   * involving any parameters to the calling method.
575   *
576   * <p>See {@link #checkState(boolean, String, Object...)} for details.
577   *
578   * @since 20.0 (varargs overload since 2.0)
579   */
580  public static void checkState(
581      boolean expression, String errorMessageTemplate, char p1) {
582    if (!expression) {
583      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1));
584    }
585  }
586
587  /**
588   * Ensures the truth of an expression involving the state of the calling instance, but not
589   * involving any parameters to the calling method.
590   *
591   * <p>See {@link #checkState(boolean, String, Object...)} for details.
592   *
593   * @since 20.0 (varargs overload since 2.0)
594   */
595  public static void checkState(
596      boolean expression, String errorMessageTemplate, int p1) {
597    if (!expression) {
598      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1));
599    }
600  }
601
602  /**
603   * Ensures the truth of an expression involving the state of the calling instance, but not
604   * involving any parameters to the calling method.
605   *
606   * <p>See {@link #checkState(boolean, String, Object...)} for details.
607   *
608   * @since 20.0 (varargs overload since 2.0)
609   */
610  public static void checkState(
611      boolean expression, String errorMessageTemplate, long p1) {
612    if (!expression) {
613      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1));
614    }
615  }
616
617  /**
618   * Ensures the truth of an expression involving the state of the calling instance, but not
619   * involving any parameters to the calling method.
620   *
621   * <p>See {@link #checkState(boolean, String, Object...)} for details.
622   *
623   * @since 20.0 (varargs overload since 2.0)
624   */
625  public static void checkState(
626      boolean expression, String errorMessageTemplate, @Nullable Object p1) {
627    if (!expression) {
628      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1));
629    }
630  }
631
632  /**
633   * Ensures the truth of an expression involving the state of the calling instance, but not
634   * involving any parameters to the calling method.
635   *
636   * <p>See {@link #checkState(boolean, String, Object...)} for details.
637   *
638   * @since 20.0 (varargs overload since 2.0)
639   */
640  public static void checkState(
641      boolean expression, String errorMessageTemplate, char p1, char p2) {
642    if (!expression) {
643      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
644    }
645  }
646
647  /**
648   * Ensures the truth of an expression involving the state of the calling instance, but not
649   * involving any parameters to the calling method.
650   *
651   * <p>See {@link #checkState(boolean, String, Object...)} for details.
652   *
653   * @since 20.0 (varargs overload since 2.0)
654   */
655  public static void checkState(
656      boolean expression, String errorMessageTemplate, char p1, int p2) {
657    if (!expression) {
658      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
659    }
660  }
661
662  /**
663   * Ensures the truth of an expression involving the state of the calling instance, but not
664   * involving any parameters to the calling method.
665   *
666   * <p>See {@link #checkState(boolean, String, Object...)} for details.
667   *
668   * @since 20.0 (varargs overload since 2.0)
669   */
670  public static void checkState(
671      boolean expression, String errorMessageTemplate, char p1, long p2) {
672    if (!expression) {
673      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
674    }
675  }
676
677  /**
678   * Ensures the truth of an expression involving the state of the calling instance, but not
679   * involving any parameters to the calling method.
680   *
681   * <p>See {@link #checkState(boolean, String, Object...)} for details.
682   *
683   * @since 20.0 (varargs overload since 2.0)
684   */
685  public static void checkState(
686      boolean expression,
687      String errorMessageTemplate,
688      char p1,
689      @Nullable Object p2) {
690    if (!expression) {
691      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
692    }
693  }
694
695  /**
696   * Ensures the truth of an expression involving the state of the calling instance, but not
697   * involving any parameters to the calling method.
698   *
699   * <p>See {@link #checkState(boolean, String, Object...)} for details.
700   *
701   * @since 20.0 (varargs overload since 2.0)
702   */
703  public static void checkState(
704      boolean expression, String errorMessageTemplate, int p1, char p2) {
705    if (!expression) {
706      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
707    }
708  }
709
710  /**
711   * Ensures the truth of an expression involving the state of the calling instance, but not
712   * involving any parameters to the calling method.
713   *
714   * <p>See {@link #checkState(boolean, String, Object...)} for details.
715   *
716   * @since 20.0 (varargs overload since 2.0)
717   */
718  public static void checkState(
719      boolean expression, String errorMessageTemplate, int p1, int p2) {
720    if (!expression) {
721      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
722    }
723  }
724
725  /**
726   * Ensures the truth of an expression involving the state of the calling instance, but not
727   * involving any parameters to the calling method.
728   *
729   * <p>See {@link #checkState(boolean, String, Object...)} for details.
730   *
731   * @since 20.0 (varargs overload since 2.0)
732   */
733  public static void checkState(
734      boolean expression, String errorMessageTemplate, int p1, long p2) {
735    if (!expression) {
736      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
737    }
738  }
739
740  /**
741   * Ensures the truth of an expression involving the state of the calling instance, but not
742   * involving any parameters to the calling method.
743   *
744   * <p>See {@link #checkState(boolean, String, Object...)} for details.
745   *
746   * @since 20.0 (varargs overload since 2.0)
747   */
748  public static void checkState(
749      boolean expression,
750      String errorMessageTemplate,
751      int p1,
752      @Nullable Object p2) {
753    if (!expression) {
754      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
755    }
756  }
757
758  /**
759   * Ensures the truth of an expression involving the state of the calling instance, but not
760   * involving any parameters to the calling method.
761   *
762   * <p>See {@link #checkState(boolean, String, Object...)} for details.
763   *
764   * @since 20.0 (varargs overload since 2.0)
765   */
766  public static void checkState(
767      boolean expression, String errorMessageTemplate, long p1, char p2) {
768    if (!expression) {
769      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
770    }
771  }
772
773  /**
774   * Ensures the truth of an expression involving the state of the calling instance, but not
775   * involving any parameters to the calling method.
776   *
777   * <p>See {@link #checkState(boolean, String, Object...)} for details.
778   *
779   * @since 20.0 (varargs overload since 2.0)
780   */
781  public static void checkState(
782      boolean expression, String errorMessageTemplate, long p1, int p2) {
783    if (!expression) {
784      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
785    }
786  }
787
788  /**
789   * Ensures the truth of an expression involving the state of the calling instance, but not
790   * involving any parameters to the calling method.
791   *
792   * <p>See {@link #checkState(boolean, String, Object...)} for details.
793   *
794   * @since 20.0 (varargs overload since 2.0)
795   */
796  public static void checkState(
797      boolean expression, String errorMessageTemplate, long p1, long p2) {
798    if (!expression) {
799      throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
800    }
801  }
802
803  /**
804   * Ensures the truth of an expression involving the state of the calling instance, but not
805   * involving any parameters to the calling method.
806   *
807   * <p>See {@link #checkState(boolean, String, Object...)} for details.
808   *
809   * @since 20.0 (varargs overload since 2.0)
810   */
811  public static void checkState(
812      boolean expression,
813      String errorMessageTemplate,
814      long p1,
815      @Nullable Object p2) {
816    if (!expression) {
817      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
818    }
819  }
820
821  /**
822   * Ensures the truth of an expression involving the state of the calling instance, but not
823   * involving any parameters to the calling method.
824   *
825   * <p>See {@link #checkState(boolean, String, Object...)} for details.
826   *
827   * @since 20.0 (varargs overload since 2.0)
828   */
829  public static void checkState(
830      boolean expression,
831      String errorMessageTemplate,
832      @Nullable Object p1,
833      char p2) {
834    if (!expression) {
835      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
836    }
837  }
838
839  /**
840   * Ensures the truth of an expression involving the state of the calling instance, but not
841   * involving any parameters to the calling method.
842   *
843   * <p>See {@link #checkState(boolean, String, Object...)} for details.
844   *
845   * @since 20.0 (varargs overload since 2.0)
846   */
847  public static void checkState(
848      boolean expression,
849      String errorMessageTemplate,
850      @Nullable Object p1,
851      int p2) {
852    if (!expression) {
853      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
854    }
855  }
856
857  /**
858   * Ensures the truth of an expression involving the state of the calling instance, but not
859   * involving any parameters to the calling method.
860   *
861   * <p>See {@link #checkState(boolean, String, Object...)} for details.
862   *
863   * @since 20.0 (varargs overload since 2.0)
864   */
865  public static void checkState(
866      boolean expression,
867      String errorMessageTemplate,
868      @Nullable Object p1,
869      long p2) {
870    if (!expression) {
871      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
872    }
873  }
874
875  /**
876   * Ensures the truth of an expression involving the state of the calling instance, but not
877   * involving any parameters to the calling method.
878   *
879   * <p>See {@link #checkState(boolean, String, Object...)} for details.
880   *
881   * @since 20.0 (varargs overload since 2.0)
882   */
883  public static void checkState(
884      boolean expression,
885      String errorMessageTemplate,
886      @Nullable Object p1,
887      @Nullable Object p2) {
888    if (!expression) {
889      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
890    }
891  }
892
893  /**
894   * Ensures the truth of an expression involving the state of the calling instance, but not
895   * involving any parameters to the calling method.
896   *
897   * <p>See {@link #checkState(boolean, String, Object...)} for details.
898   *
899   * @since 20.0 (varargs overload since 2.0)
900   */
901  public static void checkState(
902      boolean expression,
903      String errorMessageTemplate,
904      @Nullable Object p1,
905      @Nullable Object p2,
906      @Nullable Object p3) {
907    if (!expression) {
908      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2, p3));
909    }
910  }
911
912  /**
913   * Ensures the truth of an expression involving the state of the calling instance, but not
914   * involving any parameters to the calling method.
915   *
916   * <p>See {@link #checkState(boolean, String, Object...)} for details.
917   *
918   * @since 20.0 (varargs overload since 2.0)
919   */
920  public static void checkState(
921      boolean expression,
922      String errorMessageTemplate,
923      @Nullable Object p1,
924      @Nullable Object p2,
925      @Nullable Object p3,
926      @Nullable Object p4) {
927    if (!expression) {
928      throw new IllegalStateException(Platform.lenientFormat(errorMessageTemplate, p1, p2, p3, p4));
929    }
930  }
931
932  /*
933   * Preconditions.checkNotNull is *intended* for performing eager null checks on parameters that a
934   * nullness checker can already "prove" are non-null. That means that the first parameter to
935   * checkNotNull *should* be annotated to require it to be non-null.
936   *
937   * However, for a variety of reasons, Google developers have written a ton of code over the past
938   * decade that assumes that they can use checkNotNull for non-precondition checks. I had hoped to
939   * take a principled stand on this, but the amount of such code is simply overwhelming. To avoid
940   * creating a lot of compile errors that users would not find to be informative, we're giving in
941   * and allowing callers to pass arguments that a nullness checker believes could be null.
942   *
943   * We still encourage people to use requireNonNull over checkNotNull for non-precondition checks.
944   */
945
946  /**
947   * Ensures that an object reference passed as a parameter to the calling method is not null.
948   *
949   * @param reference an object reference
950   * @return the non-null reference that was validated
951   * @throws NullPointerException if {@code reference} is null
952   * @see Verify#verifyNotNull Verify.verifyNotNull()
953   */
954  @CanIgnoreReturnValue
955  public static <T> T checkNotNull(@Nullable T reference) {
956    if (reference == null) {
957      throw new NullPointerException();
958    }
959    return reference;
960  }
961
962  /**
963   * Ensures that an object reference passed as a parameter to the calling method is not null.
964   *
965   * @param reference an object reference
966   * @param errorMessage the exception message to use if the check fails; will be converted to a
967   *     string using {@link String#valueOf(Object)}
968   * @return the non-null reference that was validated
969   * @throws NullPointerException if {@code reference} is null
970   * @see Verify#verifyNotNull Verify.verifyNotNull()
971   */
972  @CanIgnoreReturnValue
973  public static <T> T checkNotNull(@Nullable T reference, @Nullable Object errorMessage) {
974    if (reference == null) {
975      throw new NullPointerException(Platform.stringValueOf(errorMessage));
976    }
977    return reference;
978  }
979
980  /**
981   * Ensures that an object reference passed as a parameter to the calling method is not null.
982   *
983   * @param reference an object reference
984   * @param errorMessageTemplate a template for the exception message should the check fail. The
985   *     message is formed by replacing each {@code %s} placeholder in the template with an
986   *     argument. These are matched by position - the first {@code %s} gets {@code
987   *     errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message in
988   *     square braces. Unmatched placeholders will be left as-is.
989   * @param errorMessageArgs the arguments to be substituted into the message template. Arguments
990   *     are converted to strings using {@link String#valueOf(Object)}.
991   * @return the non-null reference that was validated
992   * @throws NullPointerException if {@code reference} is null
993   * @see Verify#verifyNotNull Verify.verifyNotNull()
994   */
995  @CanIgnoreReturnValue
996  public static <T> T checkNotNull(
997      @Nullable T reference,
998      String errorMessageTemplate,
999      @Nullable Object @Nullable ... errorMessageArgs) {
1000    if (reference == null) {
1001      throw new NullPointerException(
1002          Platform.lenientFormat(errorMessageTemplate, errorMessageArgs));
1003    }
1004    return reference;
1005  }
1006
1007  /**
1008   * Ensures that an object reference passed as a parameter to the calling method is not null.
1009   *
1010   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1011   *
1012   * @since 20.0 (varargs overload since 2.0)
1013   */
1014  @CanIgnoreReturnValue
1015  public static <T> T checkNotNull(
1016      @Nullable T reference, String errorMessageTemplate, char p1) {
1017    if (reference == null) {
1018      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1));
1019    }
1020    return reference;
1021  }
1022
1023  /**
1024   * Ensures that an object reference passed as a parameter to the calling method is not null.
1025   *
1026   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1027   *
1028   * @since 20.0 (varargs overload since 2.0)
1029   */
1030  @CanIgnoreReturnValue
1031  public static <T> T checkNotNull(
1032      @Nullable T reference, String errorMessageTemplate, int p1) {
1033    if (reference == null) {
1034      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1));
1035    }
1036    return reference;
1037  }
1038
1039  /**
1040   * Ensures that an object reference passed as a parameter to the calling method is not null.
1041   *
1042   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1043   *
1044   * @since 20.0 (varargs overload since 2.0)
1045   */
1046  @CanIgnoreReturnValue
1047  public static <T> T checkNotNull(
1048      @Nullable T reference, String errorMessageTemplate, long p1) {
1049    if (reference == null) {
1050      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1));
1051    }
1052    return reference;
1053  }
1054
1055  /**
1056   * Ensures that an object reference passed as a parameter to the calling method is not null.
1057   *
1058   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1059   *
1060   * @since 20.0 (varargs overload since 2.0)
1061   */
1062  @CanIgnoreReturnValue
1063  public static <T> T checkNotNull(
1064      @Nullable T reference,
1065      String errorMessageTemplate,
1066      @Nullable Object p1) {
1067    if (reference == null) {
1068      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1));
1069    }
1070    return reference;
1071  }
1072
1073  /**
1074   * Ensures that an object reference passed as a parameter to the calling method is not null.
1075   *
1076   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1077   *
1078   * @since 20.0 (varargs overload since 2.0)
1079   */
1080  @CanIgnoreReturnValue
1081  public static <T> T checkNotNull(
1082      @Nullable T reference, String errorMessageTemplate, char p1, char p2) {
1083    if (reference == null) {
1084      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1085    }
1086    return reference;
1087  }
1088
1089  /**
1090   * Ensures that an object reference passed as a parameter to the calling method is not null.
1091   *
1092   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1093   *
1094   * @since 20.0 (varargs overload since 2.0)
1095   */
1096  @CanIgnoreReturnValue
1097  public static <T> T checkNotNull(
1098      @Nullable T reference, String errorMessageTemplate, char p1, int p2) {
1099    if (reference == null) {
1100      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1101    }
1102    return reference;
1103  }
1104
1105  /**
1106   * Ensures that an object reference passed as a parameter to the calling method is not null.
1107   *
1108   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1109   *
1110   * @since 20.0 (varargs overload since 2.0)
1111   */
1112  @CanIgnoreReturnValue
1113  public static <T> T checkNotNull(
1114      @Nullable T reference, String errorMessageTemplate, char p1, long p2) {
1115    if (reference == null) {
1116      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1117    }
1118    return reference;
1119  }
1120
1121  /**
1122   * Ensures that an object reference passed as a parameter to the calling method is not null.
1123   *
1124   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1125   *
1126   * @since 20.0 (varargs overload since 2.0)
1127   */
1128  @CanIgnoreReturnValue
1129  public static <T> T checkNotNull(
1130      @Nullable T reference,
1131      String errorMessageTemplate,
1132      char p1,
1133      @Nullable Object p2) {
1134    if (reference == null) {
1135      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
1136    }
1137    return reference;
1138  }
1139
1140  /**
1141   * Ensures that an object reference passed as a parameter to the calling method is not null.
1142   *
1143   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1144   *
1145   * @since 20.0 (varargs overload since 2.0)
1146   */
1147  @CanIgnoreReturnValue
1148  public static <T> T checkNotNull(
1149      @Nullable T reference, String errorMessageTemplate, int p1, char p2) {
1150    if (reference == null) {
1151      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1152    }
1153    return reference;
1154  }
1155
1156  /**
1157   * Ensures that an object reference passed as a parameter to the calling method is not null.
1158   *
1159   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1160   *
1161   * @since 20.0 (varargs overload since 2.0)
1162   */
1163  @CanIgnoreReturnValue
1164  public static <T> T checkNotNull(
1165      @Nullable T reference, String errorMessageTemplate, int p1, int p2) {
1166    if (reference == null) {
1167      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1168    }
1169    return reference;
1170  }
1171
1172  /**
1173   * Ensures that an object reference passed as a parameter to the calling method is not null.
1174   *
1175   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1176   *
1177   * @since 20.0 (varargs overload since 2.0)
1178   */
1179  @CanIgnoreReturnValue
1180  public static <T> T checkNotNull(
1181      @Nullable T reference, String errorMessageTemplate, int p1, long p2) {
1182    if (reference == null) {
1183      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1184    }
1185    return reference;
1186  }
1187
1188  /**
1189   * Ensures that an object reference passed as a parameter to the calling method is not null.
1190   *
1191   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1192   *
1193   * @since 20.0 (varargs overload since 2.0)
1194   */
1195  @CanIgnoreReturnValue
1196  public static <T> T checkNotNull(
1197      @Nullable T reference,
1198      String errorMessageTemplate,
1199      int p1,
1200      @Nullable Object p2) {
1201    if (reference == null) {
1202      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
1203    }
1204    return reference;
1205  }
1206
1207  /**
1208   * Ensures that an object reference passed as a parameter to the calling method is not null.
1209   *
1210   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1211   *
1212   * @since 20.0 (varargs overload since 2.0)
1213   */
1214  @CanIgnoreReturnValue
1215  public static <T> T checkNotNull(
1216      @Nullable T reference, String errorMessageTemplate, long p1, char p2) {
1217    if (reference == null) {
1218      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1219    }
1220    return reference;
1221  }
1222
1223  /**
1224   * Ensures that an object reference passed as a parameter to the calling method is not null.
1225   *
1226   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1227   *
1228   * @since 20.0 (varargs overload since 2.0)
1229   */
1230  @CanIgnoreReturnValue
1231  public static <T> T checkNotNull(
1232      @Nullable T reference, String errorMessageTemplate, long p1, int p2) {
1233    if (reference == null) {
1234      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1235    }
1236    return reference;
1237  }
1238
1239  /**
1240   * Ensures that an object reference passed as a parameter to the calling method is not null.
1241   *
1242   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1243   *
1244   * @since 20.0 (varargs overload since 2.0)
1245   */
1246  @CanIgnoreReturnValue
1247  public static <T> T checkNotNull(
1248      @Nullable T reference, String errorMessageTemplate, long p1, long p2) {
1249    if (reference == null) {
1250      throw new NullPointerException(lenientFormat(errorMessageTemplate, p1, p2));
1251    }
1252    return reference;
1253  }
1254
1255  /**
1256   * Ensures that an object reference passed as a parameter to the calling method is not null.
1257   *
1258   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1259   *
1260   * @since 20.0 (varargs overload since 2.0)
1261   */
1262  @CanIgnoreReturnValue
1263  public static <T> T checkNotNull(
1264      @Nullable T reference,
1265      String errorMessageTemplate,
1266      long p1,
1267      @Nullable Object p2) {
1268    if (reference == null) {
1269      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
1270    }
1271    return reference;
1272  }
1273
1274  /**
1275   * Ensures that an object reference passed as a parameter to the calling method is not null.
1276   *
1277   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1278   *
1279   * @since 20.0 (varargs overload since 2.0)
1280   */
1281  @CanIgnoreReturnValue
1282  public static <T> T checkNotNull(
1283      @Nullable T reference,
1284      String errorMessageTemplate,
1285      @Nullable Object p1,
1286      char p2) {
1287    if (reference == null) {
1288      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
1289    }
1290    return reference;
1291  }
1292
1293  /**
1294   * Ensures that an object reference passed as a parameter to the calling method is not null.
1295   *
1296   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1297   *
1298   * @since 20.0 (varargs overload since 2.0)
1299   */
1300  @CanIgnoreReturnValue
1301  public static <T> T checkNotNull(
1302      @Nullable T reference,
1303      String errorMessageTemplate,
1304      @Nullable Object p1,
1305      int p2) {
1306    if (reference == null) {
1307      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
1308    }
1309    return reference;
1310  }
1311
1312  /**
1313   * Ensures that an object reference passed as a parameter to the calling method is not null.
1314   *
1315   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1316   *
1317   * @since 20.0 (varargs overload since 2.0)
1318   */
1319  @CanIgnoreReturnValue
1320  public static <T> T checkNotNull(
1321      @Nullable T reference,
1322      String errorMessageTemplate,
1323      @Nullable Object p1,
1324      long p2) {
1325    if (reference == null) {
1326      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
1327    }
1328    return reference;
1329  }
1330
1331  /**
1332   * Ensures that an object reference passed as a parameter to the calling method is not null.
1333   *
1334   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1335   *
1336   * @since 20.0 (varargs overload since 2.0)
1337   */
1338  @CanIgnoreReturnValue
1339  public static <T> T checkNotNull(
1340      @Nullable T reference,
1341      String errorMessageTemplate,
1342      @Nullable Object p1,
1343      @Nullable Object p2) {
1344    if (reference == null) {
1345      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2));
1346    }
1347    return reference;
1348  }
1349
1350  /**
1351   * Ensures that an object reference passed as a parameter to the calling method is not null.
1352   *
1353   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1354   *
1355   * @since 20.0 (varargs overload since 2.0)
1356   */
1357  @CanIgnoreReturnValue
1358  public static <T> T checkNotNull(
1359      @Nullable T reference,
1360      String errorMessageTemplate,
1361      @Nullable Object p1,
1362      @Nullable Object p2,
1363      @Nullable Object p3) {
1364    if (reference == null) {
1365      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2, p3));
1366    }
1367    return reference;
1368  }
1369
1370  /**
1371   * Ensures that an object reference passed as a parameter to the calling method is not null.
1372   *
1373   * <p>See {@link #checkNotNull(Object, String, Object...)} for details.
1374   *
1375   * @since 20.0 (varargs overload since 2.0)
1376   */
1377  @CanIgnoreReturnValue
1378  public static <T> T checkNotNull(
1379      @Nullable T reference,
1380      String errorMessageTemplate,
1381      @Nullable Object p1,
1382      @Nullable Object p2,
1383      @Nullable Object p3,
1384      @Nullable Object p4) {
1385    if (reference == null) {
1386      throw new NullPointerException(Platform.lenientFormat(errorMessageTemplate, p1, p2, p3, p4));
1387    }
1388    return reference;
1389  }
1390
1391  /*
1392   * All recent hotspots (as of 2009) *really* like to have the natural code
1393   *
1394   * if (guardExpression) {
1395   *    throw new BadException(messageExpression);
1396   * }
1397   *
1398   * refactored so that messageExpression is moved to a separate String-returning method.
1399   *
1400   * if (guardExpression) {
1401   *    throw new BadException(badMsg(...));
1402   * }
1403   *
1404   * The alternative natural refactorings into void or Exception-returning methods are much slower.
1405   * This is a big deal - we're talking factors of 2-8 in microbenchmarks, not just 10-20%. (This is
1406   * a hotspot optimizer bug, which should be fixed, but that's a separate, big project).
1407   *
1408   * The coding pattern above is heavily used in java.util, e.g. in ArrayList. There is a
1409   * RangeCheckMicroBenchmark in the JDK that was used to test this.
1410   *
1411   * But the methods in this class want to throw different exceptions, depending on the args, so it
1412   * appears that this pattern is not directly applicable. But we can use the ridiculous, devious
1413   * trick of throwing an exception in the middle of the construction of another exception. Hotspot
1414   * is fine with that.
1415   */
1416
1417  /**
1418   * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size
1419   * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive.
1420   *
1421   * @param index a user-supplied index identifying an element of an array, list or string
1422   * @param size the size of that array, list or string
1423   * @return the value of {@code index}
1424   * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size}
1425   * @throws IllegalArgumentException if {@code size} is negative
1426   */
1427  @CanIgnoreReturnValue
1428  public static int checkElementIndex(int index, int size) {
1429    return checkElementIndex(index, size, "index");
1430  }
1431
1432  /**
1433   * Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size
1434   * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive.
1435   *
1436   * @param index a user-supplied index identifying an element of an array, list or string
1437   * @param size the size of that array, list or string
1438   * @param desc the text to use to describe this index in an error message
1439   * @return the value of {@code index}
1440   * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size}
1441   * @throws IllegalArgumentException if {@code size} is negative
1442   */
1443  @CanIgnoreReturnValue
1444  public static int checkElementIndex(int index, int size, String desc) {
1445    // Carefully optimized for execution by hotspot (explanatory comment above)
1446    if (index < 0 || index >= size) {
1447      throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
1448    }
1449    return index;
1450  }
1451
1452  private static String badElementIndex(int index, int size, String desc) {
1453    if (index < 0) {
1454      return lenientFormat("%s (%s) must not be negative", desc, index);
1455    } else if (size < 0) {
1456      throw new IllegalArgumentException("negative size: " + size);
1457    } else { // index >= size
1458      return lenientFormat("%s (%s) must be less than size (%s)", desc, index, size);
1459    }
1460  }
1461
1462  /**
1463   * Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of
1464   * size {@code size}. A position index may range from zero to {@code size}, inclusive.
1465   *
1466   * <p><b>Java 9 users:</b> consider using {@link Objects#checkIndex} instead. However, note that
1467   * {@code checkIndex()} throws {@code IndexOutOfBoundsException} when {@code size} is negative,
1468   * while this method throws {@code IllegalArgumentException}.
1469   *
1470   * @param index a user-supplied index identifying a position in an array, list or string
1471   * @param size the size of that array, list or string
1472   * @return the value of {@code index}
1473   * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size}
1474   * @throws IllegalArgumentException if {@code size} is negative
1475   */
1476  @CanIgnoreReturnValue
1477  public static int checkPositionIndex(int index, int size) {
1478    return checkPositionIndex(index, size, "index");
1479  }
1480
1481  /**
1482   * Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of
1483   * size {@code size}. A position index may range from zero to {@code size}, inclusive.
1484   *
1485   * @param index a user-supplied index identifying a position in an array, list or string
1486   * @param size the size of that array, list or string
1487   * @param desc the text to use to describe this index in an error message
1488   * @return the value of {@code index}
1489   * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size}
1490   * @throws IllegalArgumentException if {@code size} is negative
1491   */
1492  @CanIgnoreReturnValue
1493  public static int checkPositionIndex(int index, int size, String desc) {
1494    // Carefully optimized for execution by hotspot (explanatory comment above)
1495    if (index < 0 || index > size) {
1496      throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc));
1497    }
1498    return index;
1499  }
1500
1501  private static String badPositionIndex(int index, int size, String desc) {
1502    if (index < 0) {
1503      return lenientFormat("%s (%s) must not be negative", desc, index);
1504    } else if (size < 0) {
1505      throw new IllegalArgumentException("negative size: " + size);
1506    } else { // index > size
1507      return lenientFormat("%s (%s) must not be greater than size (%s)", desc, index, size);
1508    }
1509  }
1510
1511  /**
1512   * Ensures that {@code start} and {@code end} specify valid <i>positions</i> in an array, list or
1513   * string of size {@code size}, and are in order. A position index may range from zero to {@code
1514   * size}, inclusive.
1515   *
1516   * @param start a user-supplied index identifying a starting position in an array, list or string
1517   * @param end a user-supplied index identifying an ending position in an array, list or string
1518   * @param size the size of that array, list or string
1519   * @throws IndexOutOfBoundsException if either index is negative or is greater than {@code size},
1520   *     or if {@code end} is less than {@code start}
1521   * @throws IllegalArgumentException if {@code size} is negative
1522   */
1523  public static void checkPositionIndexes(int start, int end, int size) {
1524    // Carefully optimized for execution by hotspot (explanatory comment above)
1525    if (start < 0 || end < start || end > size) {
1526      throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
1527    }
1528  }
1529
1530  private static String badPositionIndexes(int start, int end, int size) {
1531    if (start < 0 || start > size) {
1532      return badPositionIndex(start, size, "start index");
1533    }
1534    if (end < 0 || end > size) {
1535      return badPositionIndex(end, size, "end index");
1536    }
1537    // end < start
1538    return lenientFormat("end index (%s) must not be less than start index (%s)", end, start);
1539  }
1540}