@ Cached @ DontLabel public Rule range ( final Range < Integer > range ) { Objects . requireNonNull ( range , "range must not be null" ) ; final Range < Integer > realRange = normalizeRange ( range ) ; /* * We always have a lower bound */ final int lowerBound = realRange . lowerEndpoint ( ) ; /* * Handle the case where there is no upper bound */ if ( ! realRange . hasUpperBound ( ) ) return boundedDown ( lowerBound ) ; /* * There is an upper bound. Handle the case where it is 0 or 1. Since * the range is legal, we know that if it is 0, so is the lowerbound; * and if it is one, the lower bound is either 0 or 1. */ final int upperBound = realRange . upperEndpoint ( ) ; if ( upperBound == 0 ) return parser . empty ( ) ; if ( upperBound == 1 ) return lowerBound == 0 ? parser . optional ( rule ) : rule ; /* * So, upper bound is 2 or greater; return the appropriate matcher * according to what the lower bound is. * * Also, if the lower and upper bounds are equal, return a matcher doing * a fixed number of matches. */ if ( lowerBound == 0 ) return boundedUp ( upperBound ) ; return lowerBound == upperBound ? exactly ( lowerBound ) : boundedBoth ( lowerBound , upperBound ) ; }
Core method for building a repeating matcher