1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.googlejavaformat.java.javadoc; 16 17 import static com.google.common.base.Preconditions.checkArgument; 18 import static com.google.common.base.Preconditions.checkNotNull; 19 20 import java.util.regex.Matcher; 21 import java.util.regex.Pattern; 22 23 /** 24 * String reader designed for use from the lexer. Callers invoke the {@link #tryConsume tryConsume*} 25 * methods to specify what characters they expect and then {@link #readAndResetRecorded} to retrieve 26 * and consume the matched characters. This is a slightly odd API -- why not just return the matched 27 * characters from tryConsume? -- but it is convenient for the lexer. 28 */ 29 final class CharStream { 30 String remaining; 31 int toConsume; 32 CharStream(String input)33 CharStream(String input) { 34 this.remaining = checkNotNull(input); 35 } 36 tryConsume(String expected)37 boolean tryConsume(String expected) { 38 if (!remaining.startsWith(expected)) { 39 return false; 40 } 41 toConsume = expected.length(); 42 return true; 43 } 44 45 /* 46 * @param pattern the pattern to search for, which must be anchored to match only at position 0 47 */ tryConsumeRegex(Pattern pattern)48 boolean tryConsumeRegex(Pattern pattern) { 49 Matcher matcher = pattern.matcher(remaining); 50 if (!matcher.find()) { 51 return false; 52 } 53 checkArgument(matcher.start() == 0); 54 toConsume = matcher.end(); 55 return true; 56 } 57 readAndResetRecorded()58 String readAndResetRecorded() { 59 String result = remaining.substring(0, toConsume); 60 remaining = remaining.substring(toConsume); 61 toConsume = 0; // TODO(cpovirk): Set this to a bogus value here and in the constructor. 62 return result; 63 } 64 isExhausted()65 boolean isExhausted() { 66 return remaining.isEmpty(); 67 } 68 } 69