// 
// Decompiled by Procyon v0.6.0
// 

package com.google.common.flogger.parser;

public abstract class BraceStyleMessageParser extends MessageParser
{
    private static final char BRACE_STYLE_SEPARATOR = ',';
    
    abstract void parseBraceFormatTerm(final MessageBuilder<?> p0, final int p1, final String p2, final int p3, final int p4, final int p5) throws ParseException;
    
    @Override
    public final void unescape(final StringBuilder out, final String message, final int start, final int end) {
        unescapeBraceFormat(out, message, start, end);
    }
    
    @Override
    protected final <T> void parseImpl(final MessageBuilder<T> builder) throws ParseException {
        final String message = builder.getMessage();
        int pos = nextBraceFormatTerm(message, 0);
    Label_0011:
        while (pos >= 0) {
            final int termStart = pos++;
            final int indexStart = termStart + 1;
            int index = 0;
            while (pos < message.length()) {
                final char c = message.charAt(pos++);
                final int digit = (char)(c - '0');
                if (digit < 10) {
                    index = 10 * index + digit;
                    if (index < 1000000) {
                        continue;
                    }
                    throw ParseException.withBounds("index too large", message, indexStart, pos);
                }
                else {
                    final int indexLen = pos - 1 - indexStart;
                    if (indexLen == 0) {
                        throw ParseException.withBounds("missing index", message, termStart, pos);
                    }
                    if (message.charAt(indexStart) == '0' && indexLen > 1) {
                        throw ParseException.withBounds("index has leading zero", message, indexStart, pos - 1);
                    }
                    int trailingPartStart = 0;
                    Label_0222: {
                        if (c == '}') {
                            trailingPartStart = -1;
                        }
                        else {
                            if (c == ',') {
                                trailingPartStart = pos;
                                while (pos != message.length()) {
                                    if (message.charAt(pos++) == '}') {
                                        break Label_0222;
                                    }
                                }
                                throw ParseException.withStartPosition("unterminated parameter", message, termStart);
                            }
                            throw ParseException.withBounds("malformed index", message, termStart + 1, pos);
                        }
                    }
                    this.parseBraceFormatTerm(builder, index, message, termStart, trailingPartStart, pos);
                    pos = nextBraceFormatTerm(message, pos);
                    continue Label_0011;
                }
            }
            throw ParseException.withStartPosition("unterminated parameter", message, termStart);
        }
    }
    
    static int nextBraceFormatTerm(final String message, int pos) throws ParseException {
    Label_0000:
        while (pos < message.length()) {
            final char c = message.charAt(pos++);
            if (c == '{') {
                return pos - 1;
            }
            if (c != '\'') {
                continue;
            }
            if (pos == message.length()) {
                throw ParseException.withStartPosition("trailing single quote", message, pos - 1);
            }
            if (message.charAt(pos++) == '\'') {
                continue;
            }
            final int quote = pos - 2;
            while (pos != message.length()) {
                if (message.charAt(pos++) == '\'') {
                    continue Label_0000;
                }
            }
            throw ParseException.withStartPosition("unmatched single quote", message, quote);
        }
        return -1;
    }
    
    static void unescapeBraceFormat(final StringBuilder out, final String message, int start, final int end) {
        int pos = start;
        boolean isQuoted = false;
        while (pos < end) {
            char c = message.charAt(pos++);
            if (c != '\\' && c != '\'') {
                continue;
            }
            final int quoteStart = pos - 1;
            if (c == '\\') {
                c = message.charAt(pos++);
                if (c != '\'') {
                    continue;
                }
            }
            out.append(message, start, quoteStart);
            if ((start = pos) == end) {
                break;
            }
            if (isQuoted) {
                isQuoted = false;
            }
            else if (message.charAt(pos) != '\'') {
                isQuoted = true;
            }
            else {
                ++pos;
            }
        }
        if (start < end) {
            out.append(message, start, end);
        }
    }
}
