private void parseSegments()

in dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/condition/PathParser.java [72:237]


    private void parseSegments(String path) {
        int state = State.INITIAL;
        boolean regexBraceStart = false;
        boolean regexMulti = false;
        String variableName = null;
        int len = path.length();
        for (int i = 0; i < len; i++) {
            char c = path.charAt(i);
            switch (c) {
                case '/':
                    switch (state) {
                        case State.INITIAL:
                        case State.SEGMENT_END:
                            continue;
                        case State.LITERAL_START:
                            if (buf.length() > 0) {
                                appendSegment(Type.LITERAL);
                            }
                            break;
                        case State.WILDCARD_START:
                            appendSegment(Type.WILDCARD);
                            break;
                        case State.REGEX_VARIABLE_START:
                            if (path.charAt(i - 1) != '^' || path.charAt(i - 2) != '[') {
                                regexMulti = true;
                            }
                            buf.append(c);
                            continue;
                        case State.VARIABLE_START:
                        case State.WILDCARD_VARIABLE_START:
                            throw new PathParserException(Messages.MISSING_CLOSE_CAPTURE, path, i);
                        default:
                    }
                    segments.add(SLASH);
                    state = State.SEGMENT_END;
                    continue;
                case '?':
                    switch (state) {
                        case State.INITIAL:
                        case State.LITERAL_START:
                        case State.SEGMENT_END:
                            state = State.WILDCARD_START;
                            break;
                        default:
                    }
                    break;
                case '*':
                    switch (state) {
                        case State.INITIAL:
                        case State.LITERAL_START:
                        case State.SEGMENT_END:
                            state = State.WILDCARD_START;
                            break;
                        case State.VARIABLE_START:
                            if (path.charAt(i - 1) == '{') {
                                state = State.WILDCARD_VARIABLE_START;
                                continue;
                            }
                            break;
                        default:
                    }
                    break;
                case '.':
                    if (state == State.REGEX_VARIABLE_START) {
                        if (path.charAt(i - 1) != '\\') {
                            regexMulti = true;
                        }
                    }
                    break;
                case 'S':
                case 'W':
                    if (state == State.REGEX_VARIABLE_START) {
                        if (path.charAt(i - 1) == '\\') {
                            regexMulti = true;
                        }
                    }
                    break;
                case ':':
                    if (state == State.VARIABLE_START) {
                        state = State.REGEX_VARIABLE_START;
                        variableName = buf.toString();
                        buf.setLength(0);
                        continue;
                    }
                    break;
                case '{':
                    switch (state) {
                        case State.INITIAL:
                        case State.SEGMENT_END:
                            state = State.VARIABLE_START;
                            continue;
                        case State.LITERAL_START:
                            if (buf.length() > 0) {
                                appendSegment(Type.LITERAL);
                            }
                            state = State.VARIABLE_START;
                            continue;
                        case State.VARIABLE_START:
                        case State.WILDCARD_VARIABLE_START:
                            throw new PathParserException(Messages.ILLEGAL_NESTED_CAPTURE, path, i);
                        case State.REGEX_VARIABLE_START:
                            if (path.charAt(i - 1) != '\\') {
                                regexBraceStart = true;
                            }
                            break;
                        default:
                    }
                    break;
                case '}':
                    switch (state) {
                        case State.INITIAL:
                        case State.LITERAL_START:
                        case State.SEGMENT_END:
                            throw new PathParserException(Messages.MISSING_OPEN_CAPTURE, path);
                        case State.VARIABLE_START:
                            appendSegment(Type.VARIABLE, buf.toString());
                            state = State.LITERAL_START;
                            continue;
                        case State.REGEX_VARIABLE_START:
                            if (regexBraceStart) {
                                regexBraceStart = false;
                            } else {
                                if (buf.length() == 0) {
                                    throw new PathParserException(Messages.MISSING_REGEX_CONSTRAINT, path, i);
                                }
                                appendSegment(regexMulti ? Type.PATTERN_MULTI : Type.PATTERN, variableName);
                                regexMulti = false;
                                state = State.LITERAL_START;
                                continue;
                            }
                            break;
                        case State.WILDCARD_VARIABLE_START:
                            appendSegment(Type.WILDCARD_TAIL, buf.toString());
                            state = State.END;
                            continue;
                        default:
                    }
                    break;
                default:
                    if (state == State.INITIAL || state == State.SEGMENT_END) {
                        state = State.LITERAL_START;
                    }
                    break;
            }
            if (state == State.END) {
                throw new PathParserException(Messages.NO_MORE_DATA_ALLOWED, path, i);
            }
            buf.append(c);
        }

        if (buf.length() > 0) {
            switch (state) {
                case State.LITERAL_START:
                    appendSegment(Type.LITERAL);
                    break;
                case State.WILDCARD_START:
                    appendSegment(Type.WILDCARD);
                    break;
                case State.VARIABLE_START:
                case State.REGEX_VARIABLE_START:
                case State.WILDCARD_VARIABLE_START:
                    throw new PathParserException(Messages.MISSING_CLOSE_CAPTURE, path, len - 1);
                default:
            }
        }
    }