void parse() {
        if (closed) {
            throw new MimeParsingException("Parser is closed");
        }

        try {
            while (true) {
                switch (state) {
                    case START_MESSAGE:
                        logger.trace("state={}", State.START_MESSAGE);
                        state = State.SKIP_PREAMBLE;
                        break;

                    case SKIP_PREAMBLE:
                        logger.trace("state={}", State.SKIP_PREAMBLE);
                        skipPreamble();
                        if (boundaryStart == -1) {
                            // Need more data; DecodedHttpStreamMessage will handle.
                            return;
                        }
                        logger.trace("Skipped the preamble.");
                        state = State.START_PART;
                        break;

                    case START_PART:
                        logger.trace("state={}", State.START_PART);
                        bodyPartHeadersBuilder = HttpHeaders.builder();
                        bodyPartBuilder = BodyPart.builder();
                        state = State.HEADERS;
                        break;

                    case HEADERS:
                        logger.trace("state={}", State.HEADERS);
                        assert bodyPartHeadersBuilder != null;
                        assert bodyPartBuilder != null;

                        final String headerLine = readHeaderLine();
                        if (headerLine == null) {
                            // Need more data; DecodedHttpStreamMessage will handle.
                            return;
                        }
                        if (!headerLine.isEmpty()) {
                            final int index = headerLine.indexOf(':');
                            if (index < 0) {
                                throw new MimeParsingException("Invalid header line: " + headerLine);
                            }
                            final String key = headerLine.substring(0, index).trim();
                            // Skip ':' from value
                            final String value = headerLine.substring(index + 1).trim();
                            bodyPartHeadersBuilder.add(key, value);
                            break;
                        }
                        state = State.BODY;
                        startOfLine = true;

                        bodyPartPublisher = multipartDecoder.onBodyPartBegin();
                        final BodyPart bodyPart = bodyPartBuilder.headers(bodyPartHeadersBuilder.build())
                                                                 .content(bodyPartPublisher)
                                                                 .build();
                        out.add(bodyPart);
                        break;

                    case BODY:
                        logger.trace("state={}", State.BODY);
                        assert bodyPartPublisher != null;

                        final ByteBuf bodyContent = readBody();
                        if (bodyContent == NEED_MORE) {
                            final BodyPartPublisher currentPublisher = bodyPartPublisher;
                            currentPublisher.whenConsumed().thenRun(() -> {
                                if (currentPublisher.demand() > 0 && !currentPublisher.isComplete()) {
                                    multipartDecoder.requestUpstreamForBodyPartData();
                                }
                            });
                            return;
                        }
                        if (boundaryStart != -1) {
                            startOfLine = false;
                        }
                        // Use tryWrite() to avoid throwing exception.
                        // For example, when body part is cancelled, MimeParser need to ignore it without
                        // throwing exception.
                        bodyPartPublisher.tryWrite(HttpData.wrap(bodyContent));
                        break;

                    case END_PART:
                        logger.trace("state={}", State.END_PART);
                        if (done) {
                            state = State.END_MESSAGE;
                        } else {
                            state = State.START_PART;
                        }
                        assert bodyPartPublisher != null;
                        bodyPartPublisher.close();
                        bodyPartPublisher = null;
                        bodyPartHeadersBuilder = null;
                        bodyPartBuilder = null;
                        break;

                    case END_MESSAGE:
                        logger.trace("state={}", State.END_MESSAGE);
                        return;

                    default:
                        // nothing to do
                }
            }
        } catch (MimeParsingException ex) {
            throw ex;
        } catch (Throwable ex) {
            throw new MimeParsingException(ex);
        }
    }
Advances parsing.
@throws MimeParsingException if an error occurs during parsing
core/src/main/java/com/linecorp/armeria/common/multipart/MimeParser.java