/** * Returns a list of values. This is similar to JSON with '[' and ']' * surrounding the list and ',' separating values. */ private List<Object> readList() { if (readChar() != '[') throw new AssertionError(); List<Object> result = new ArrayList<>(); while (true) { if (peekChar() == ']') { // If we see the close brace, finish immediately. This handles [] and ,] cases. pos++; return result; } result.add(readKindAndValue().value()); char c = peekChar(); if (c == ',') { pos++; } else if (c != ']') { throw unexpected("expected ',' or ']'"); } } }
/** * Returns a list of values. This is similar to JSON with '[' and ']' * surrounding the list and ',' separating values. */ private List<Object> readList() { reader.require('['); List<Object> result = new ArrayList<>(); while (true) { // If we see the close brace, finish immediately. This handles [] and ,] cases. if (reader.peekChar(']')) return result; result.add(readKindAndValue().value()); if (reader.peekChar(',')) continue; if (reader.peekChar() != ']') throw reader.unexpected("expected ',' or ']'"); } }
/** Reads a option containing a name, an '=' or ':', and a value. */ private OptionElement readOption(char keyValueSeparator) { boolean isExtension = (peekChar() == '['); boolean isParenthesized = (peekChar() == '('); String name = readName(); // Option name. if (isExtension) { name = "[" + name + "]"; } String subName = null; char c = readChar(); if (c == '.') { // Read nested field name. For example "baz" in "(foo.bar).baz = 12". subName = readName(); c = readChar(); } if (keyValueSeparator == ':' && c == '{') { // In text format, values which are maps can omit a separator. Backtrack so it can be re-read. pos--; } else if (c != keyValueSeparator) { throw unexpected("expected '" + keyValueSeparator + "' in option"); } OptionKindAndValue kindAndValue = readKindAndValue(); OptionElement.Kind kind = kindAndValue.kind(); Object value = kindAndValue.value(); if (subName != null) { value = OptionElement.create(subName, kind, value); kind = OptionElement.Kind.OPTION; } return OptionElement.create(name, kind, value, isParenthesized); }
/** Reads a option containing a name, an '=' or ':', and a value. */ private OptionElement readOption(char keyValueSeparator) { boolean isExtension = (reader.peekChar() == '['); boolean isParenthesized = (reader.peekChar() == '('); String name = reader.readName(); // Option name. if (isExtension) { name = "[" + name + "]"; } String subName = null; char c = reader.readChar(); if (c == '.') { // Read nested field name. For example "baz" in "(foo.bar).baz = 12". subName = reader.readName(); c = reader.readChar(); } if (keyValueSeparator == ':' && c == '{') { // In text format, values which are maps can omit a separator. Backtrack so it can be re-read. reader.pushBack('{'); } else if (c != keyValueSeparator) { throw reader.unexpected("expected '" + keyValueSeparator + "' in option"); } OptionKindAndValue kindAndValue = readKindAndValue(); OptionElement.Kind kind = kindAndValue.kind(); Object value = kindAndValue.value(); if (subName != null) { value = OptionElement.create(subName, kind, value); kind = OptionElement.Kind.OPTION; } return OptionElement.create(name, kind, value, isParenthesized); }