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