@Override
    public HttpResponse convertResponse(ServiceRequestContext ctx, ResponseHeaders headers,
                                        @Nullable Object result, HttpHeaders trailers) throws Exception {
        final MediaType contentType = headers.contentType();
        final boolean isJson = isJson(contentType);

        if (isJsonSeq(contentType)) {
            checkArgument(result != null, "a null value is not allowed for %s", contentType);
            final Function<Object, String> toJson = this::toJson;
            if (result instanceof Publisher) {
                @SuppressWarnings("unchecked")
                final Publisher<Object> publisher = (Publisher<Object>) result;
                try {
                    return (HttpResponse) fromPublisherMH.invoke(headers, publisher, trailers, toJson);
                } catch (Throwable ex) {
                    throw new IllegalStateException(
                            "Failed to call JsonTextSequences.fromPublisher() through reflection", ex);
                }
            }
            if (result instanceof Stream) {
                @SuppressWarnings("unchecked")
                final Stream<Object> stream = (Stream<Object>) result;
                try {
                    return (HttpResponse) fromStreamMH
                            .invoke(headers, stream, trailers, ctx.blockingTaskExecutor(), toJson);
                } catch (Throwable ex) {
                    throw new IllegalStateException(
                            "Failed to call JsonTextSequences.fromStream() through reflection", ex);
                }
            }
            try {
                return (HttpResponse) fromObjectMH.invoke(headers, result, trailers, toJson);
            } catch (Throwable ex) {
                throw new IllegalStateException(
                        "Failed to call JsonTextSequences.fromObject() through reflection", ex);
            }
        }

        if (result instanceof Message) {
            if (isJson) {
                assert contentType != null;
                final Charset charset = contentType.charset(StandardCharsets.UTF_8);
                return HttpResponse.of(headers, toJsonHttpData(result, charset), trailers);
            }

            if (contentType == null) {
                return HttpResponse.of(headers.toBuilder().contentType(MediaType.PROTOBUF).build(),
                                       toProtobuf(result), trailers);
            } else if (isProtobuf(contentType)) {
                return HttpResponse.of(headers, toProtobuf(result), trailers);
            } else {
                return ResponseConverterFunction.fallthrough();
            }
        }

        if (isJson) {
            assert contentType != null;
            checkArgument(result != null, "a null value is not allowed for %s", contentType);
            final Charset charset = contentType.charset(StandardCharsets.UTF_8);

            if (result instanceof Publisher) {
                @SuppressWarnings("unchecked")
                final Publisher<Object> publisher = (Publisher<Object>) result;
                return aggregateFrom(publisher, headers, trailers, obj -> toJsonHttpData(obj, charset), ctx);
            }
            if (result instanceof Stream) {
                @SuppressWarnings("unchecked")
                final Stream<Object> stream = (Stream<Object>) result;
                return aggregateFrom(stream, headers, trailers, obj -> toJsonHttpData(obj, charset),
                                     ctx.blockingTaskExecutor());
            }
            return HttpResponse.of(headers, toJsonHttpData(result, charset), trailers);
        } else {
            throw new IllegalArgumentException(
                    "Cannot convert a " + result + " to Protocol Buffers wire format");
        }
    }
Creates an instance with the specified {@link Printer}.
protobuf/src/main/java/com/linecorp/armeria/server/protobuf/ProtobufResponseConverterFunction.java