ProtocolbuffersParser.java

/* Generated by: CongoCC Parser Generator. ProtocolbuffersParser.java  */
package de.schegge.rosinante.parser;

import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.ListIterator;
import java.util.concurrent.CancellationException;
import de.schegge.rosinante.parser.Token.TokenType;
import static de.schegge.rosinante.parser.Token.TokenType.*;
import de.schegge.rosinante.parser.ast.SyntaxProduction;
import de.schegge.rosinante.parser.ast.ImportProduction;
import de.schegge.rosinante.parser.ast.PackageProduction;
import de.schegge.rosinante.parser.ast.IntegerLiteral;
import de.schegge.rosinante.parser.ast.Constant;
import de.schegge.rosinante.parser.ast.Option;
import de.schegge.rosinante.parser.ast.FieldName;
import de.schegge.rosinante.parser.ast.ExtensionName;
import de.schegge.rosinante.parser.ast.AnyName;
import de.schegge.rosinante.parser.ast.Type;
import de.schegge.rosinante.parser.ast.FieldOption;
import de.schegge.rosinante.parser.ast.FieldOptions;
import de.schegge.rosinante.parser.ast.Field;
import de.schegge.rosinante.parser.ast.MessageBody;
import de.schegge.rosinante.parser.ast.MessageProduction;
import de.schegge.rosinante.parser.ast.EnumField;
import de.schegge.rosinante.parser.ast.EnumBody;
import de.schegge.rosinante.parser.ast.EnumProduction;
import de.schegge.rosinante.parser.ast.Proto;
import de.schegge.rosinante.core.ProtoSources;
import de.schegge.rosinante.core.ProtoVersion;
import java.util.Set;
import java.util.HashSet;


public class ProtocolbuffersParser {
    private ProtoSources sources;
    private boolean initial;
    private Set<String> types;
    private String packageName = "";
    private ProtoVersion protoVersion;

    public ProtocolbuffersParser(String name, ProtoSources sources) throws IOException {
        this(name, sources.getContent(name));
        types = new HashSet<>();
        this.sources = sources;
        this.initial = true;
    }

    public ProtocolbuffersParser(String name, ProtoSources sources, Set<String> types, boolean initial) throws IOException {
        this(name, sources.getImport(name));
        this.types = types;
        this.sources = sources;
        this.initial = initial;
    }

    static final int UNLIMITED = Integer.MAX_VALUE;
    // The last token successfully "consumed"
    Token lastConsumedToken;
    private TokenType nextTokenType;
    private Token currentLookaheadToken;
    private String currentlyParsedProduction;
    private String currentLookaheadProduction;
    EnumSet<TokenType> outerFollowSet;
    private final Token DUMMY_START_TOKEN = new Token();
    private boolean cancelled;

    public void cancel() {
        cancelled = true;
    }

    public boolean isCancelled() {
        return cancelled;
    }

    /** Generated Lexer. */
    private ProtocolbuffersLexer token_source;

    public void setInputSource(String inputSource) {
        token_source.setInputSource(inputSource);
    }

    String getInputSource() {
        return token_source.getInputSource();
    }

    //=================================
    // Generated constructors
    //=================================
    public ProtocolbuffersParser(String inputSource, CharSequence content) {
        this(new ProtocolbuffersLexer(inputSource, content));
    }

    public ProtocolbuffersParser(CharSequence content) {
        this("input", content);
    }

    /**
    * @param inputSource just the name of the input source (typically the filename) that
    * will be used in error messages and so on.
    * @param path The location (typically the filename) from which to get the input to parse
    */
    public ProtocolbuffersParser(String inputSource, Path path) throws IOException {
        this(inputSource, TokenSource.stringFromBytes(Files.readAllBytes(path)));
    }

    public ProtocolbuffersParser(String inputSource, Path path, Charset charset) throws IOException {
        this(inputSource, TokenSource.stringFromBytes(Files.readAllBytes(path), charset));
    }

    /**
    * @param path The location (typically the filename) from which to get the input to parse
    */
    public ProtocolbuffersParser(Path path) throws IOException {
        this(path.toString(), path);
    }

    /** Constructor with user supplied Lexer. */
    public ProtocolbuffersParser(ProtocolbuffersLexer lexer) {
        token_source = lexer;
        lastConsumedToken = DUMMY_START_TOKEN;
        lastConsumedToken.setTokenSource(lexer);
    }

    /**
    * Set the starting line/column for location reporting.
    * By default, this is 1,1.
    */
    public void setStartingPos(int startingLine, int startingColumn) {
        token_source.setStartingPos(startingLine, startingColumn);
    }

    // If the next token is cached, it returns that
    // Otherwise, it goes to the token_source, i.e. the Lexer.
    private final Token nextToken(final Token tok) {
        Token result = token_source.getNextToken(tok);
        while (result.isUnparsed()) {
            result = token_source.getNextToken(result);
        }
        nextTokenType = null;
        return result;
    }

    /**
    * @return the next Token off the stream. This is the same as #getToken(1)
    */
    public final Token getNextToken() {
        return getToken(1);
    }

    /**
    * @param index how many tokens to look ahead
    * @return the specific regular (i.e. parsed) Token index ahead/behind in the stream.
    * If we are in a lookahead, it looks ahead from the currentLookaheadToken
    * Otherwise, it is the lastConsumedToken. If you pass in a negative
    * number it goes backward.
    */
    public final Token getToken(final int index) {
        Token t = currentLookaheadToken == null ? lastConsumedToken : currentLookaheadToken;
        for (int i = 0; i < index; i++) {
            t = nextToken(t);
        }
        for (int i = 0; i > index; i--) {
            t = t.getPrevious();
            if (t == null) break;
        }
        return t;
    }

    private final TokenType nextTokenType() {
        if (nextTokenType == null) {
            nextTokenType = nextToken(lastConsumedToken).getType();
        }
        return nextTokenType;
    }

    boolean activateTokenTypes(TokenType...types) {
        if (token_source.activeTokenTypes == null) return false;
        boolean result = false;
        for (TokenType tt : types) {
            result |= token_source.activeTokenTypes.add(tt);
        }
        if (result) {
            token_source.reset(getToken(0));
            nextTokenType = null;
        }
        return result;
    }

    boolean deactivateTokenTypes(TokenType...types) {
        boolean result = false;
        if (token_source.activeTokenTypes == null) {
            token_source.activeTokenTypes = EnumSet.allOf(TokenType.class);
        }
        for (TokenType tt : types) {
            result |= token_source.activeTokenTypes.remove(tt);
        }
        if (result) {
            token_source.reset(getToken(0));
            nextTokenType = null;
        }
        return result;
    }

    private static HashMap<TokenType[], EnumSet<TokenType>> enumSetCache = new HashMap<>();

    private static EnumSet<TokenType> tokenTypeSet(TokenType first, TokenType...rest) {
        TokenType[] key = new TokenType[1 + rest.length];
        key[0] = first;
        if (rest.length > 0) {
            System.arraycopy(rest, 0, key, 1, rest.length);
        }
        Arrays.sort(key);
        if (enumSetCache.containsKey(key)) {
            return enumSetCache.get(key);
        }
        EnumSet<TokenType> result = (rest.length == 0) ? EnumSet.of(first) : EnumSet.of(first, rest);
        enumSetCache.put(key, result);
        return result;
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:86:1
    final public void Syntax() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Syntax";
        SyntaxProduction thisProduction = null;
        if (buildTree) {
            thisProduction = new SyntaxProduction();
            openNodeScope(thisProduction);
        }
        ParseException parseException2 = null;
        int callStackSize3 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:87:3
            consumeToken(SYNTAX);
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:90:3
            if (protoVersion != null) {
                throw new ParseException("only one syntax production allowed");
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:96:3
            consumeToken(ASSIGN);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:97:3
            consumeToken(STRING_LITERAL);
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:98:3
            protoVersion = switch(lastConsumedToken.toString()) {
                case "\"proto2\"" -> ProtoVersion.PROTO2;
                case "\"proto3\"" -> ProtoVersion.PROTO3;
                default -> throw new ParseException(lastConsumedToken);
            };
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:108:3
            consumeToken(SEMICOLON);
        } catch (ParseException e) {
            parseException2 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize3);
            if (thisProduction != null) {
                if (parseException2 == null) {
                    closeNodeScope(thisProduction, true);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:111:1
    final public void Import() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Import";
        ImportProduction thisProduction = null;
        if (buildTree) {
            thisProduction = new ImportProduction();
            openNodeScope(thisProduction);
        }
        boolean weakFlag = false;
        boolean publicFlag = false;
        ParseException parseException30 = null;
        int callStackSize31 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:116:3
            consumeToken(IMPORT);
            // Code for ZeroOrOne specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:117:3
            // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:117:5
            if (nextTokenType() == WEAK) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:117:5
                consumeToken(WEAK);
                // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:117:12
                weakFlag = true;
            } else if (nextTokenType() == PUBLIC) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:117:35
                consumeToken(PUBLIC);
                // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:117:44
                publicFlag = true;
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:118:3
            consumeToken(STRING_LITERAL);
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:118:20
            try {
                String importString = lastConsumedToken.toString();
                String fileName = importString.substring(1, importString.length() - 1);
                if (initial || publicFlag) {
                    ProtocolbuffersParser parser = new ProtocolbuffersParser(fileName, sources, types, initial && publicFlag);
                    parser.Proto();
                    thisProduction.setSubProto(parser.rootNode());
                }
            } catch (IOException e) {
                throw new ParseException("unknown proto syntax: " + e.getMessage());
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:131:3
            consumeToken(SEMICOLON);
        } catch (ParseException e) {
            parseException30 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize31);
            if (thisProduction != null) {
                if (parseException30 == null) {
                    closeNodeScope(thisProduction, true);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:134:1
    final public void Package() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Package";
        PackageProduction thisProduction = null;
        if (buildTree) {
            thisProduction = new PackageProduction();
            openNodeScope(thisProduction);
        }
        Node packageNode;
        ParseException parseException82 = null;
        int callStackSize83 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:138:3
            consumeToken(PACKAGE);
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:141:3
            if (!"".equals(packageName)) {
                throw new ParseException("only one package production allowed");
            }
            if (nextTokenType() == FULL_IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:147:5
                packageNode = consumeToken(FULL_IDENTIFIER);
            } else if (nextTokenType() == IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:147:39
                packageNode = consumeToken(IDENTIFIER);
            } else {
                pushOntoCallStack("Package", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 147, 5);
                throw new ParseException(lastConsumedToken, first_set$baseprotocolbuffers_ccc$147$5, parsingStack);
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:148:3
            consumeToken(SEMICOLON);
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:149:3
            packageName = packageNode + ".";
        } catch (ParseException e) {
            parseException82 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize83);
            if (thisProduction != null) {
                if (parseException82 == null) {
                    closeNodeScope(thisProduction, true);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:154:1
    final public void IntegerLiteral() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "IntegerLiteral";
        IntegerLiteral thisProduction = null;
        if (buildTree) {
            thisProduction = new IntegerLiteral();
            openNodeScope(thisProduction);
        }
        ParseException parseException123 = null;
        int callStackSize124 = parsingStack.size();
        try {
            // Code for ZeroOrOne specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:155:3
            if (nextTokenType() == _TOKEN_40) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:155:5
                consumeToken(_TOKEN_40);
            }
            if (nextTokenType() == ZERO) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:155:13
                consumeToken(ZERO);
            } else if (nextTokenType() == INTEGER_LITERAL) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:155:22
                consumeToken(INTEGER_LITERAL);
            } else if (nextTokenType() == HEX_LITERAL) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:155:42
                consumeToken(HEX_LITERAL);
            } else if (nextTokenType() == OCT_LITERAL) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:155:58
                consumeToken(OCT_LITERAL);
            } else {
                pushOntoCallStack("IntegerLiteral", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 155, 13);
                throw new ParseException(lastConsumedToken, first_set$baseprotocolbuffers_ccc$155$13, parsingStack);
            }
        } catch (ParseException e) {
            parseException123 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize124);
            if (thisProduction != null) {
                if (parseException123 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    private static final EnumSet<TokenType> Constant_FIRST_SET = Constant_FIRST_SET_init();

    private static EnumSet<TokenType> Constant_FIRST_SET_init() {
        return tokenTypeSet(TRUE, FALSE, ZERO, _TOKEN_40, _TOKEN_41, INTEGER_LITERAL, OCT_LITERAL, HEX_LITERAL, IDENTIFIER, FULL_IDENTIFIER, STRING_LITERAL);
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:158:1
    final public void Constant() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Constant";
        // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:3
        Constant thisProduction = null;
        if (buildTree) {
            thisProduction = new Constant();
            openNodeScope(thisProduction);
        }
        ParseException parseException176 = null;
        int callStackSize177 = parsingStack.size();
        try {
            if (nextTokenType() == FULL_IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:3
                consumeToken(FULL_IDENTIFIER);
            } else if (nextTokenType() == IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:23
                consumeToken(IDENTIFIER);
            } else if (nextTokenType() == STRING_LITERAL) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:38
                consumeToken(STRING_LITERAL);
            } else if (nextTokenType() == TRUE) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:57
                consumeToken(TRUE);
            } else if (nextTokenType() == FALSE) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:66
                consumeToken(FALSE);
            } else if (first_set$baseprotocolbuffers_ccc$159$76.contains(nextTokenType())) {
                // Code for ZeroOrOne specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:76
                // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:78
                if (nextTokenType() == _TOKEN_40) {
                    // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:78
                    consumeToken(_TOKEN_40);
                } else if (nextTokenType() == _TOKEN_41) {
                    // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:84
                    consumeToken(_TOKEN_41);
                }
                // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:159:90
                pushOntoCallStack("Constant", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 159, 90);
                try {
                    IntegerLiteral();
                } finally {
                    popCallStack();
                }
            } else {
                pushOntoCallStack("Constant", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 159, 3);
                throw new ParseException(lastConsumedToken, Constant_FIRST_SET, parsingStack);
            }
        } catch (ParseException e) {
            parseException176 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize177);
            if (thisProduction != null) {
                if (parseException176 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:163:1
    final public void Option() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Option";
        Option thisProduction = null;
        if (buildTree) {
            thisProduction = new Option();
            openNodeScope(thisProduction);
        }
        ParseException parseException252 = null;
        int callStackSize253 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:164:3
            consumeToken(OPTION);
            if (nextTokenType() == OPTION_NAME) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:165:5
                consumeToken(OPTION_NAME);
            } else if (nextTokenType() == IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:165:21
                consumeToken(IDENTIFIER);
            } else {
                pushOntoCallStack("Option", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 165, 5);
                throw new ParseException(lastConsumedToken, first_set$baseprotocolbuffers_ccc$165$5, parsingStack);
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:166:3
            consumeToken(ASSIGN);
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:167:3
            pushOntoCallStack("Option", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 167, 3);
            try {
                Constant();
            } finally {
                popCallStack();
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:168:3
            consumeToken(SEMICOLON);
        } catch (ParseException e) {
            parseException252 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize253);
            if (thisProduction != null) {
                if (parseException252 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    private static final EnumSet<TokenType> FieldName_FIRST_SET = tokenTypeSet(LBRACKET, IDENTIFIER);

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:171:1
    final public void FieldName() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "FieldName";
        // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:172:3
        FieldName thisProduction = null;
        if (buildTree) {
            thisProduction = new FieldName();
            openNodeScope(thisProduction);
        }
        ParseException parseException293 = null;
        int callStackSize294 = parsingStack.size();
        try {
            if (nextTokenType() == LBRACKET) {
                // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:172:3
                pushOntoCallStack("FieldName", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 172, 3);
                try {
                    ExtensionName();
                } finally {
                    popCallStack();
                }
            } else if (nextTokenType() == LBRACKET) {
                // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:172:19
                pushOntoCallStack("FieldName", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 172, 19);
                try {
                    AnyName();
                } finally {
                    popCallStack();
                }
            } else if (nextTokenType() == IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:172:29
                consumeToken(IDENTIFIER);
            } else {
                pushOntoCallStack("FieldName", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 172, 3);
                throw new ParseException(lastConsumedToken, FieldName_FIRST_SET, parsingStack);
            }
        } catch (ParseException e) {
            parseException293 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize294);
            if (thisProduction != null) {
                if (parseException293 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:175:1
    final public void ExtensionName() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "ExtensionName";
        ExtensionName thisProduction = null;
        if (buildTree) {
            thisProduction = new ExtensionName();
            openNodeScope(thisProduction);
        }
        ParseException parseException321 = null;
        int callStackSize322 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:176:3
            consumeToken(LBRACKET);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:176:14
            consumeToken(FULL_IDENTIFIER);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:176:32
            consumeToken(RBRACKET);
        } catch (ParseException e) {
            parseException321 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize322);
            if (thisProduction != null) {
                if (parseException321 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:179:1
    final public void AnyName() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "AnyName";
        AnyName thisProduction = null;
        if (buildTree) {
            thisProduction = new AnyName();
            openNodeScope(thisProduction);
        }
        ParseException parseException337 = null;
        int callStackSize338 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:180:3
            consumeToken(LBRACKET);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:180:14
            consumeToken(FULL_IDENTIFIER);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:180:32
            consumeToken(_TOKEN_42);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:180:36
            consumeToken(FULL_IDENTIFIER);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:180:54
            consumeToken(RBRACKET);
        } catch (ParseException e) {
            parseException337 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize338);
            if (thisProduction != null) {
                if (parseException337 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    private static final EnumSet<TokenType> Type_FIRST_SET = Type_FIRST_SET_init();

    private static EnumSet<TokenType> Type_FIRST_SET_init() {
        return tokenTypeSet(DOUBLE, FLOAT, INT32, INT64, UINT32, UINT64, SINT32, SINT64, STRING, BYTES, BOOL, IDENTIFIER, FULL_IDENTIFIER, TYPE_IDENTIFIER);
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:183:1
    final public void Type() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Type";
        // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:3
        Type thisProduction = null;
        if (buildTree) {
            thisProduction = new Type();
            openNodeScope(thisProduction);
        }
        ParseException parseException361 = null;
        int callStackSize362 = parsingStack.size();
        try {
            if (nextTokenType() == DOUBLE) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:3
                consumeToken(DOUBLE);
            } else if (nextTokenType() == FLOAT) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:14
                consumeToken(FLOAT);
            } else if (nextTokenType() == INT32) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:24
                consumeToken(INT32);
            } else if (nextTokenType() == INT64) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:34
                consumeToken(INT64);
            } else if (nextTokenType() == UINT32) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:44
                consumeToken(UINT32);
            } else if (nextTokenType() == UINT64) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:55
                consumeToken(UINT64);
            } else if (nextTokenType() == SINT32) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:66
                consumeToken(SINT32);
            } else if (nextTokenType() == SINT64) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:77
                consumeToken(SINT64);
            } else if (nextTokenType() == STRING) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:88
                consumeToken(STRING);
            } else if (nextTokenType() == BYTES) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:99
                consumeToken(BYTES);
            } else if (nextTokenType() == BOOL) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:109
                consumeToken(BOOL);
            } else if (nextTokenType() == TYPE_IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:118
                consumeToken(TYPE_IDENTIFIER);
            } else if (nextTokenType() == FULL_IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:138
                consumeToken(FULL_IDENTIFIER);
            } else if (nextTokenType() == IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:184:158
                consumeToken(IDENTIFIER);
            } else {
                pushOntoCallStack("Type", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 184, 3);
                throw new ParseException(lastConsumedToken, Type_FIRST_SET, parsingStack);
            }
        } catch (ParseException e) {
            parseException361 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize362);
            if (thisProduction != null) {
                if (parseException361 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:187:1
    final public void FieldOption() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "FieldOption";
        FieldOption thisProduction = null;
        if (buildTree) {
            thisProduction = new FieldOption();
            openNodeScope(thisProduction);
        }
        ParseException parseException477 = null;
        int callStackSize478 = parsingStack.size();
        try {
            if (nextTokenType() == OPTION_NAME) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:188:5
                consumeToken(OPTION_NAME);
            } else if (nextTokenType() == IDENTIFIER) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:188:21
                consumeToken(IDENTIFIER);
            } else {
                pushOntoCallStack("FieldOption", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 188, 5);
                throw new ParseException(lastConsumedToken, first_set$baseprotocolbuffers_ccc$188$5, parsingStack);
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:189:3
            consumeToken(ASSIGN);
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:190:3
            pushOntoCallStack("FieldOption", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 190, 3);
            try {
                Constant();
            } finally {
                popCallStack();
            }
        } catch (ParseException e) {
            parseException477 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize478);
            if (thisProduction != null) {
                if (parseException477 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:193:1
    final public void FieldOptions() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "FieldOptions";
        FieldOptions thisProduction = null;
        if (buildTree) {
            thisProduction = new FieldOptions();
            openNodeScope(thisProduction);
        }
        ParseException parseException510 = null;
        int callStackSize511 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:194:3
            consumeToken(LBRACKET);
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:195:3
            pushOntoCallStack("FieldOptions", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 195, 3);
            try {
                FieldOption();
            } finally {
                popCallStack();
            }
            // Code for ZeroOrMore specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:195:15
            while (true) {
                if (!(nextTokenType() == COMMA)) break;
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:195:17
                consumeToken(COMMA);
                // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:195:26
                pushOntoCallStack("FieldOptions", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 195, 26);
                try {
                    FieldOption();
                } finally {
                    popCallStack();
                }
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:196:3
            consumeToken(RBRACKET);
        } catch (ParseException e) {
            parseException510 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize511);
            if (thisProduction != null) {
                if (parseException510 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:199:1
    final public void Field() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Field";
        Field thisProduction = null;
        if (buildTree) {
            thisProduction = new Field();
            openNodeScope(thisProduction);
        }
        ParseException parseException542 = null;
        int callStackSize543 = parsingStack.size();
        try {
            // Code for ZeroOrOne specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:200:3
            // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:200:5
            if (nextTokenType() == REPEATED) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:200:5
                consumeToken(REPEATED);
            } else if (nextTokenType() == OPTIONAL) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:200:18
                consumeToken(OPTIONAL);
            }
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:201:3
            pushOntoCallStack("Field", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 201, 3);
            try {
                Type();
            } finally {
                popCallStack();
            }
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:202:3
            pushOntoCallStack("Field", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 202, 3);
            try {
                FieldName();
            } finally {
                popCallStack();
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:203:3
            consumeToken(ASSIGN);
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:204:3
            pushOntoCallStack("Field", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 204, 3);
            try {
                IntegerLiteral();
            } finally {
                popCallStack();
            }
            // Code for ZeroOrOne specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:205:3
            if (nextTokenType() == LBRACKET) {
                // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:205:5
                pushOntoCallStack("Field", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 205, 5);
                try {
                    FieldOptions();
                } finally {
                    popCallStack();
                }
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:206:3
            consumeToken(SEMICOLON);
        } catch (ParseException e) {
            parseException542 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize543);
            if (thisProduction != null) {
                if (parseException542 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:209:1
    final public void MessageBody() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "MessageBody";
        MessageBody thisProduction = null;
        if (buildTree) {
            thisProduction = new MessageBody();
            openNodeScope(thisProduction);
        }
        ParseException parseException602 = null;
        int callStackSize603 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:210:3
            consumeToken(LBRACE);
            // Code for ZeroOrMore specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:211:3
            while (true) {
                // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:211:5
                if (first_set$baseprotocolbuffers_ccc$211$5.contains(nextTokenType())) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:211:5
                    pushOntoCallStack("MessageBody", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 211, 5);
                    try {
                        Field();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == ENUM) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:211:13
                    pushOntoCallStack("MessageBody", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 211, 13);
                    try {
                        Enum();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == MESSAGE) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:211:20
                    pushOntoCallStack("MessageBody", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 211, 20);
                    try {
                        Message();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == OPTION) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:211:30
                    pushOntoCallStack("MessageBody", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 211, 30);
                    try {
                        Option();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == SEMICOLON) {
                    // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:211:39
                    consumeToken(SEMICOLON);
                } else {
                    break;
                }
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:213:3
            consumeToken(RBRACE);
        } catch (ParseException e) {
            parseException602 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize603);
            if (thisProduction != null) {
                if (parseException602 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:216:1
    final public void Message() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Message";
        MessageProduction thisProduction = null;
        if (buildTree) {
            thisProduction = new MessageProduction();
            openNodeScope(thisProduction);
        }
        Node identifier;
        String fullName;
        ParseException parseException662 = null;
        int callStackSize663 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:221:3
            consumeToken(MESSAGE);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:222:3
            identifier = consumeToken(IDENTIFIER);
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:222:29
            fullName = packageName + identifier;
            if (types.contains(fullName)) {
                throw new ParseException("duplicate type name: " + fullName);
            }
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:228:3
            pushOntoCallStack("Message", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 228, 3);
            try {
                MessageBody();
            } finally {
                popCallStack();
            }
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:229:3
            types.add(fullName);
        } catch (ParseException e) {
            parseException662 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize663);
            if (thisProduction != null) {
                if (parseException662 == null) {
                    closeNodeScope(thisProduction, true);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:232:1
    final public void EnumField() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "EnumField";
        EnumField thisProduction = null;
        if (buildTree) {
            thisProduction = new EnumField();
            openNodeScope(thisProduction);
        }
        ParseException parseException686 = null;
        int callStackSize687 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:236:3
            consumeToken(IDENTIFIER);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:238:3
            consumeToken(ASSIGN);
            // Code for ZeroOrOne specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:239:3
            if (nextTokenType() == _TOKEN_40) {
                // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:239:5
                consumeToken(_TOKEN_40);
            }
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:239:10
            pushOntoCallStack("EnumField", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 239, 10);
            try {
                IntegerLiteral();
            } finally {
                popCallStack();
            }
            // Code for ZeroOrOne specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:240:3
            if (nextTokenType() == LBRACKET) {
                // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:240:5
                pushOntoCallStack("EnumField", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 240, 5);
                try {
                    FieldOptions();
                } finally {
                    popCallStack();
                }
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:241:3
            consumeToken(SEMICOLON);
        } catch (ParseException e) {
            parseException686 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize687);
            if (thisProduction != null) {
                if (parseException686 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:244:1
    final public void EnumBody() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "EnumBody";
        EnumBody thisProduction = null;
        if (buildTree) {
            thisProduction = new EnumBody();
            openNodeScope(thisProduction);
        }
        ParseException parseException730 = null;
        int callStackSize731 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:245:3
            consumeToken(LBRACE);
            // Code for ZeroOrMore specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:250:3
            while (true) {
                // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:250:5
                if (nextTokenType() == OPTION) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:250:5
                    pushOntoCallStack("EnumBody", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 250, 5);
                    try {
                        Option();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == IDENTIFIER) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:250:14
                    pushOntoCallStack("EnumBody", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 250, 14);
                    try {
                        EnumField();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == SEMICOLON) {
                    // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:250:26
                    consumeToken(SEMICOLON);
                } else {
                    break;
                }
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:253:3
            consumeToken(RBRACE);
        } catch (ParseException e) {
            parseException730 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize731);
            if (thisProduction != null) {
                if (parseException730 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:256:1
    final public void Enum() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Enum";
        EnumProduction thisProduction = null;
        if (buildTree) {
            thisProduction = new EnumProduction();
            openNodeScope(thisProduction);
        }
        Node identifier;
        String fullName;
        ParseException parseException774 = null;
        int callStackSize775 = parsingStack.size();
        try {
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:261:3
            consumeToken(ENUM);
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:262:3
            identifier = consumeToken(IDENTIFIER);
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:262:29
            fullName = packageName + identifier;
            if (types.contains(fullName)) {
                throw new ParseException("duplicate type name: " + fullName);
            }
            // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:268:3
            pushOntoCallStack("Enum", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 268, 3);
            try {
                EnumBody();
            } finally {
                popCallStack();
            }
            // Code for CodeBlock specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:269:4
            types.add(fullName);
        } catch (ParseException e) {
            parseException774 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize775);
            if (thisProduction != null) {
                if (parseException774 == null) {
                    closeNodeScope(thisProduction, true);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    // /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:272:1
    final public void Proto() {
        if (cancelled) throw new CancellationException();
        String prevProduction = currentlyParsedProduction;
        this.currentlyParsedProduction = "Proto";
        Proto thisProduction = null;
        if (buildTree) {
            thisProduction = new Proto();
            openNodeScope(thisProduction);
        }
        ParseException parseException798 = null;
        int callStackSize799 = parsingStack.size();
        try {
            // Code for ZeroOrMore specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:3
            while (true) {
                // Code for ExpansionChoice specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:5
                if (nextTokenType() == SYNTAX) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:5
                    pushOntoCallStack("Proto", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 279, 5);
                    try {
                        Syntax();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == PACKAGE) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:14
                    pushOntoCallStack("Proto", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 279, 14);
                    try {
                        Package();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == IMPORT) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:24
                    pushOntoCallStack("Proto", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 279, 24);
                    try {
                        Import();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == OPTION) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:33
                    pushOntoCallStack("Proto", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 279, 33);
                    try {
                        Option();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == MESSAGE) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:42
                    pushOntoCallStack("Proto", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 279, 42);
                    try {
                        Message();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == ENUM) {
                    // Code for NonTerminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:52
                    pushOntoCallStack("Proto", "/builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc", 279, 52);
                    try {
                        Enum();
                    } finally {
                        popCallStack();
                    }
                } else if (nextTokenType() == SEMICOLON) {
                    // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:279:59
                    consumeToken(SEMICOLON);
                } else {
                    break;
                }
            }
            // Code for Terminal specified at /builds/schegge-projects/rocinante/rocinante-core/src/main/ccc/base-protocol-buffers.ccc:282:3
            consumeToken(EOF);
        } catch (ParseException e) {
            parseException798 = e;
            throw e;
        } finally {
            restoreCallStack(callStackSize799);
            if (thisProduction != null) {
                if (parseException798 == null) {
                    closeNodeScope(thisProduction, nodeArity() > 1);
                } else {
                    clearNodeScope();
                }
            }
            this.currentlyParsedProduction = prevProduction;
        }
    }

    private static final EnumSet<TokenType> first_set$baseprotocolbuffers_ccc$147$5 = tokenTypeSet(IDENTIFIER, FULL_IDENTIFIER);
    private static final EnumSet<TokenType> first_set$baseprotocolbuffers_ccc$155$13 = tokenTypeSet(ZERO, INTEGER_LITERAL, OCT_LITERAL, HEX_LITERAL);
    private static final EnumSet<TokenType> first_set$baseprotocolbuffers_ccc$159$76 = tokenTypeSet(ZERO, _TOKEN_40, _TOKEN_41, INTEGER_LITERAL, OCT_LITERAL, HEX_LITERAL);
    private static final EnumSet<TokenType> first_set$baseprotocolbuffers_ccc$165$5 = tokenTypeSet(IDENTIFIER, OPTION_NAME);
    private static final EnumSet<TokenType> first_set$baseprotocolbuffers_ccc$188$5 = tokenTypeSet(IDENTIFIER, OPTION_NAME);
    private static final EnumSet<TokenType> first_set$baseprotocolbuffers_ccc$211$5 = first_set$baseprotocolbuffers_ccc$211$5_init();

    private static EnumSet<TokenType> first_set$baseprotocolbuffers_ccc$211$5_init() {
        return tokenTypeSet(REPEATED, OPTIONAL, DOUBLE, FLOAT, INT32, INT64, UINT32, UINT64, SINT32, SINT64, STRING, BYTES, BOOL, IDENTIFIER, FULL_IDENTIFIER, TYPE_IDENTIFIER);
    }

    private ArrayList<NonTerminalCall> parsingStack = new ArrayList<>();
    private ArrayList<NonTerminalCall> lookaheadStack = new ArrayList<>();

    private final void pushOntoCallStack(String methodName, String fileName, int line, int column) {
        parsingStack.add(new NonTerminalCall("ProtocolbuffersParser", token_source, fileName, methodName, line, column, null));
    }

    private final void popCallStack() {
        NonTerminalCall ntc = parsingStack.remove(parsingStack.size() - 1);
        this.currentlyParsedProduction = ntc.productionName;
    }

    private final void restoreCallStack(int prevSize) {
        while (parsingStack.size() > prevSize) {
            popCallStack();
        }
    }

    void dumpLookaheadStack(PrintStream ps) {
        ListIterator<NonTerminalCall> it = lookaheadStack.listIterator(lookaheadStack.size());
        while (it.hasPrevious()) {
            it.previous().dump(ps);
        }
    }

    void dumpCallStack(PrintStream ps) {
        ListIterator<NonTerminalCall> it = parsingStack.listIterator(parsingStack.size());
        while (it.hasPrevious()) {
            it.previous().dump(ps);
        }
    }

    void dumpLookaheadCallStack(PrintStream ps) {
        ps.println("Current Parser Production is: " + currentlyParsedProduction);
        ps.println("Current Lookahead Production is: " + currentLookaheadProduction);
        ps.println("---Lookahead Stack---");
        dumpLookaheadStack(ps);
        ps.println("---Call Stack---");
        dumpCallStack(ps);
    }

    public boolean isParserTolerant() {
        return false;
    }

    public void setParserTolerant(boolean tolerantParsing) {
        if (tolerantParsing) {
            throw new UnsupportedOperationException("This parser was not built with that feature!");
        }
    }

    private Token consumeToken(TokenType expectedType) {
        Token nextToken = nextToken(lastConsumedToken);
        if (nextToken.getType() != expectedType) {
            nextToken = handleUnexpectedTokenType(expectedType, nextToken);
        }
        this.lastConsumedToken = nextToken;
        this.nextTokenType = null;
        if (buildTree && tokensAreNodes) {
            pushNode(lastConsumedToken);
        }
        return lastConsumedToken;
    }

    private Token handleUnexpectedTokenType(TokenType expectedType, Token nextToken) {
        throw new ParseException(nextToken, EnumSet.of(expectedType), parsingStack);
    }

    private boolean buildTree = true;
    private boolean tokensAreNodes = true;
    private boolean unparsedTokensAreNodes = false;

    public boolean isTreeBuildingEnabled() {
        return buildTree;
    }

    public void setUnparsedTokensAreNodes(boolean unparsedTokensAreNodes) {
        this.unparsedTokensAreNodes = unparsedTokensAreNodes;
    }

    public void setTokensAreNodes(boolean tokensAreNodes) {
        this.tokensAreNodes = tokensAreNodes;
    }

    NodeScope currentNodeScope = new NodeScope();

    /**
    * @return the root node of the AST. It only makes sense to call
    * this after a successful parse.
    */
    public Node rootNode() {
        return currentNodeScope.rootNode();
    }

    /**
    * push a node onto the top of the node stack
    * @param n the node to push
    */
    public void pushNode(Node n) {
        currentNodeScope.add(n);
    }

    /**
    * @return the node on the top of the stack, and remove it from the
    * stack.
    */
    public Node popNode() {
        return currentNodeScope.pop();
    }

    /**
    * @return the node currently on the top of the tree-building stack.
    */
    public Node peekNode() {
        return currentNodeScope.peek();
    }

    /**
    * Puts the node on the top of the stack. However, unlike pushNode()
    * it replaces the node that is currently on the top of the stack.
    * This is effectively equivalent to popNode() followed by pushNode(n)
    * @param n the node to poke
    */
    public void pokeNode(Node n) {
        currentNodeScope.poke(n);
    }

    /**
    * @return the number of Nodes on the tree-building stack in the current node
    * scope.
    */
    public int nodeArity() {
        return currentNodeScope.size();
    }

    private void clearNodeScope() {
        currentNodeScope.clear();
    }

    private void openNodeScope(Node n) {
        new NodeScope();
        if (n != null) {
            n.setTokenSource(lastConsumedToken.getTokenSource());
            // We set the begin/end offsets based on the ending location
            // of the last consumed token. So, we start with a Node
            // of length zero. Typically this is overridden in the
            // closeNodeScope() method, unless this node has no children
            n.setBeginOffset(lastConsumedToken.getEndOffset());
            n.setEndOffset(n.getBeginOffset());
            n.setTokenSource(this.token_source);
            n.open();
        }
    }

    /* A definite node is constructed from a specified number of
    * children.  That number of nodes are popped from the stack and
    * made the children of the definite node.  Then the definite node
    * is pushed on to the stack.
    */
    private boolean closeNodeScope(Node n, int num) {
        n.setEndOffset(lastConsumedToken.getEndOffset());
        currentNodeScope.close();
        ArrayList<Node> nodes = new ArrayList<Node>();
        for (int i = 0; i < num; i++) {
            nodes.add(popNode());
        }
        Collections.reverse(nodes);
        for (Node child : nodes) {
            if (child.getInputSource() == n.getInputSource()) {
                n.setBeginOffset(child.getBeginOffset());
                break;
            }
        }
        for (Node child : nodes) {
            if (unparsedTokensAreNodes && child instanceof Token) {
                Token tok = (Token) child;
                while (tok.previousCachedToken() != null && tok.previousCachedToken().isUnparsed()) {
                    tok = tok.previousCachedToken();
                }
                boolean locationSet = false;
                while (tok.isUnparsed()) {
                    n.addChild(tok);
                    if (!locationSet && tok.getInputSource() == n.getInputSource() && tok.getBeginOffset() < n.getBeginOffset()) {
                        n.setBeginOffset(tok.getBeginOffset());
                        locationSet = true;
                    }
                    tok = tok.nextCachedToken();
                }
            }
            if (child.getInputSource() == n.getInputSource()) {
                n.setEndOffset(child.getEndOffset());
            }
            n.addChild(child);
        }
        n.close();
        pushNode(n);
        return true;
    }

    /**
    * A conditional node is constructed if the condition is true.  All
    * the nodes that have been pushed since the node was opened are
    * made children of the conditional node, which is then pushed
    * on to the stack.  If the condition is false the node is not
    * constructed and they are left on the stack.
    */
    private boolean closeNodeScope(Node n, boolean condition) {
        if (n == null || !condition) {
            currentNodeScope.close();
            return false;
        }
        return closeNodeScope(n, nodeArity());
    }

    public boolean getBuildTree() {
        return buildTree;
    }

    public void setBuildTree(boolean buildTree) {
        this.buildTree = buildTree;
    }


    @SuppressWarnings("serial")
    class NodeScope extends ArrayList<Node> {
        NodeScope parentScope;

        NodeScope() {
            this.parentScope = ProtocolbuffersParser.this.currentNodeScope;
            ProtocolbuffersParser.this.currentNodeScope = this;
        }

        boolean isRootScope() {
            return parentScope == null;
        }

        Node rootNode() {
            NodeScope ns = this;
            while (ns.parentScope != null) {
                ns = ns.parentScope;
            }
            return ns.isEmpty() ? null : ns.get(0);
        }

        Node peek() {
            if (isEmpty()) {
                return parentScope == null ? null : parentScope.peek();
            }
            return get(size() - 1);
        }

        Node pop() {
            return isEmpty() ? parentScope.pop() : remove(size() - 1);
        }

        void poke(Node n) {
            if (isEmpty()) {
                parentScope.poke(n);
            } else {
                set(size() - 1, n);
            }
        }

        void close() {
            parentScope.addAll(this);
            ProtocolbuffersParser.this.currentNodeScope = parentScope;
        }

        int nestingLevel() {
            int result = 0;
            NodeScope parent = this;
            while (parent.parentScope != null) {
                result++;
                parent = parent.parentScope;
            }
            return result;
        }

        public NodeScope clone() {
            NodeScope clone = (NodeScope) super.clone();
            if (parentScope != null) {
                clone.parentScope = parentScope.clone();
            }
            return clone;
        }

    }

}