/** Reads a reserved tags and names list like "reserved 10, 12 to 14, 'foo';". */ private ReservedElement readReserved(Location location, String documentation) { ImmutableList.Builder<Object> valuesBuilder = ImmutableList.builder(); while (true) { char c = reader.peekChar(); if (c == '"' || c == '\'') { valuesBuilder.add(reader.readQuotedString()); } else { int tagStart = reader.readInt(); c = reader.peekChar(); if (c != ',' && c != ';') { if (!reader.readWord().equals("to")) { throw reader.unexpected("expected ',', ';', or 'to'"); } int tagEnd = reader.readInt(); valuesBuilder.add(Range.closed(tagStart, tagEnd)); } else { valuesBuilder.add(tagStart); } } c = reader.readChar(); if (c == ';') break; if (c != ',') throw reader.unexpected("expected ',' or ';'"); } ImmutableList<Object> values = valuesBuilder.build(); if (values.isEmpty()) { throw reader.unexpected("'reserved' must have at least one field name or tag"); } return ReservedElement.create(location, documentation, values); }
/** Reads extensions like "extensions 101;" or "extensions 101 to max;". */ private ExtensionsElement readExtensions(Location location, String documentation) { int start = reader.readInt(); // Range start. int end = start; if (reader.peekChar() != ';') { if (!"to".equals(reader.readWord())) throw reader.unexpected("expected ';' or 'to'"); String s = reader.readWord(); // Range end. if (s.equals("max")) { end = Util.MAX_TAG_VALUE; } else { end = Integer.parseInt(s); } } reader.require(';'); return ExtensionsElement.create(location, start, end, documentation); }
private GroupElement readGroup(Location location, String documentation, Field.Label label) { String name = reader.readWord(); reader.require('='); int tag = reader.readInt(); GroupElement.Builder builder = GroupElement.builder(location) .label(label) .name(name) .tag(tag) .documentation(documentation); ImmutableList.Builder<FieldElement> fields = ImmutableList.builder(); reader.require('{'); while (true) { String nestedDocumentation = reader.readDocumentation(); if (reader.peekChar('}')) break; Location fieldLocation = reader.location(); String fieldLabel = reader.readWord(); Object field = readField(nestedDocumentation, fieldLocation, fieldLabel); if (!(field instanceof FieldElement)) { throw reader.unexpected("expected field declaration, was " + field); } fields.add((FieldElement) field); } return builder.fields(fields.build()) .build(); }
/** Reads an field declaration and returns it. */ private FieldElement readField( Location location, String documentation, @Nullable Field.Label label, String type) { String name = reader.readName(); reader.require('='); int tag = reader.readInt(); FieldElement.Builder builder = FieldElement.builder(location) .label(label) .type(type) .name(name) .tag(tag); List<OptionElement> options = new OptionReader(reader).readOptions(); reader.require(';'); options = new ArrayList<>(options); // Mutable copy for extractDefault. String defaultValue = stripDefault(options); documentation = reader.tryAppendTrailingDocumentation(documentation); return builder.documentation(documentation) .defaultValue(defaultValue) .options(ImmutableList.copyOf(options)) .build(); }
/** Reads an enum constant like "ROCK = 0;". The label is the constant name. */ private EnumConstantElement readEnumConstant( String documentation, Location location, String label) { reader.require('='); int tag = reader.readInt(); ImmutableList<OptionElement> options = new OptionReader(reader).readOptions(); reader.require(';'); documentation = reader.tryAppendTrailingDocumentation(documentation); return EnumConstantElement.builder(location) .name(label) .tag(tag) .documentation(documentation) .options(options) .build(); }
/** Reads a reserved tags and names list like "reserved 10, 12 to 14, 'foo';". */ private ReservedElement readReserved(Location location, String documentation) { ImmutableList.Builder<Object> valuesBuilder = ImmutableList.builder(); while (true) { char c = reader.peekChar(); if (c == '"' || c == '\'') { valuesBuilder.add(reader.readQuotedString()); } else { int tagStart = reader.readInt(); c = reader.peekChar(); if (c != ',' && c != ';') { if (!reader.readWord().equals("to")) { throw reader.unexpected("expected ',', ';', or 'to'"); } int tagEnd = reader.readInt(); valuesBuilder.add(Range.closed(tagStart, tagEnd)); } else { valuesBuilder.add(tagStart); } } c = reader.readChar(); if (c == ';') break; if (c != ',') throw reader.unexpected("expected ',' or ';'"); } ImmutableList<Object> values = valuesBuilder.build(); if (values.isEmpty()) { throw reader.unexpected("'reserved' must have at least one field name or tag"); } return ReservedElement.create(location, documentation, values); }
/** Reads extensions like "extensions 101;" or "extensions 101 to max;". */ private ExtensionsElement readExtensions(Location location, String documentation) { int start = reader.readInt(); // Range start. int end = start; if (reader.peekChar() != ';') { if (!"to".equals(reader.readWord())) throw reader.unexpected("expected ';' or 'to'"); String s = reader.readWord(); // Range end. if (s.equals("max")) { end = Util.MAX_TAG_VALUE; } else { end = Integer.parseInt(s); } } reader.require(';'); return ExtensionsElement.create(location, start, end, documentation); }
private GroupElement readGroup(String documentation, Field.Label label) { String name = reader.readWord(); reader.require('='); int tag = reader.readInt(); GroupElement.Builder builder = GroupElement.builder() .label(label) .name(name) .tag(tag) .documentation(documentation); ImmutableList.Builder<FieldElement> fields = ImmutableList.builder(); reader.require('{'); while (true) { String nestedDocumentation = reader.readDocumentation(); if (reader.peekChar('}')) break; Location location = reader.location(); String fieldLabel = reader.readWord(); Object field = readField(nestedDocumentation, location, fieldLabel); if (!(field instanceof FieldElement)) { throw reader.unexpected("expected field declaration, was " + field); } fields.add((FieldElement) field); } return builder.fields(fields.build()) .build(); }
/** Reads an enum constant like "ROCK = 0;". The label is the constant name. */ private EnumConstantElement readEnumConstant( String documentation, Location location, String label) { reader.require('='); int tag = reader.readInt(); ImmutableList.Builder<OptionElement> options = ImmutableList.builder(); if (reader.peekChar() == '[') { reader.readChar(); while (true) { options.add(readOption('=')); char c = reader.readChar(); if (c == ']') { break; } if (c != ',') { throw reader.unexpected("Expected ',' or ']"); } } } reader.require(';'); documentation = reader.tryAppendTrailingDocumentation(documentation); return EnumConstantElement.builder(location) .name(label) .tag(tag) .documentation(documentation) .options(options.build()) .build(); }
String name = reader.readName(); reader.require('='); int tag = reader.readInt();