@Override
    public Object newClient(ClientBuilderParams params) {
        validateParams(params);

        final Scheme scheme = params.scheme();
        final Class<?> clientType = params.clientType();
        final ClientOptions options = params.options();
        final SerializationFormat serializationFormat = scheme.serializationFormat();

        GrpcClientStubFactory clientStubFactory = options.get(GrpcClientOptions.GRPC_CLIENT_STUB_FACTORY);
        ServiceDescriptor serviceDescriptor = null;

        final List<ServiceDescriptorResolutionException> exceptions = new ArrayList<>();
        if (clientStubFactory == NullGrpcClientStubFactory.INSTANCE) {
            for (GrpcClientStubFactory stubFactory : clientStubFactories) {
                try {
                    serviceDescriptor = stubFactory.findServiceDescriptor(clientType);
                    if (serviceDescriptor != null) {
                        clientStubFactory = stubFactory;
                        break;
                    }
                } catch (ServiceDescriptorResolutionException e) {
                    exceptions.add(e);
                }
            }
        } else {
            serviceDescriptor = clientStubFactory.findServiceDescriptor(clientType);
        }
        if (serviceDescriptor == null) {
            if (!exceptions.isEmpty()) {
                throw new IllegalArgumentException(
                        "Failed to create a gRPC client stub for " + clientType.getName() +
                        ". Possible reasons: no gRPC client stub class or due to one of the " +
                        "following exceptions. " + exceptions);
            }
            throw new IllegalArgumentException(
                    "Unknown client type: " + clientType.getName() +
                    " (expected: a gRPC client stub class, e.g. MyServiceGrpc.MyServiceStub)");
        }

        final Map<MethodDescriptor<?, ?>, String> simpleMethodNames =
                serviceDescriptor.getMethods().stream()
                                 .collect(toImmutableMap(Function.identity(),
                                                         MethodDescriptor::getBareMethodName));

        final ClientBuilderParams newParams =
                addTrailersExtractor(params, options, serializationFormat);
        final HttpClient httpClient = newHttpClient(newParams);

        final GrpcJsonMarshaller jsonMarshaller;
        if (GrpcSerializationFormats.isJson(serializationFormat)) {
            try {
                jsonMarshaller = options.get(GrpcClientOptions.GRPC_JSON_MARSHALLER_FACTORY)
                                        .apply(serviceDescriptor);
            } catch (Exception e) {
                logger.warn("Failed to instantiate a JSON marshaller for gRPC-JSON. " +
                            "Consider using a different serialization format with {}.serializationFormat() " +
                            "or using {}.ofGson() instead.",
                            GrpcClientBuilder.class.getName(), GrpcJsonMarshaller.class.getName(), e);
                throw e;
            }
        } else {
            jsonMarshaller = null;
        }
        final ArmeriaChannel armeriaChannel =
                new ArmeriaChannel(newParams, httpClient, meterRegistry(), scheme.sessionProtocol(),
                                   serializationFormat, jsonMarshaller, simpleMethodNames);
        final Iterable<? extends ClientInterceptor> interceptors = options.get(GrpcClientOptions.INTERCEPTORS);
        final Channel channel;
        if (!Iterables.isEmpty(interceptors)) {
            final Channel intercepted =
                    ClientInterceptors.intercept(armeriaChannel,
                                                 Iterables.toArray(interceptors, ClientInterceptor.class));
            channel = new UnwrappableChannel(intercepted, armeriaChannel);
        } else {
            channel = armeriaChannel;
        }
        final Object clientStub = clientStubFactory.newClientStub(clientType, channel);
        requireNonNull(clientStub, "clientStubFactory.newClientStub() returned null");
        checkState(clientType.isAssignableFrom(clientStub.getClass()),
                   "Unexpected client stub type: %s (expected: %s or its subtype)",
                   clientStub.getClass().getName(), clientType.getName());
        return clientStub;
    }
Creates a new instance from the specified {@link ClientFactory} that supports the "none+http" scheme.

@throws IllegalArgumentException if the specified {@link ClientFactory} does not support HTTP
grpc/src/main/java/com/linecorp/armeria/internal/client/grpc/GrpcClientFactory.java