@Nullable
    private static FieldInfo fieldInfo(AnnotatedValueResolver resolver) {
        final Class<? extends Annotation> annotationType = resolver.annotationType();
        if (annotationType == RequestObject.class) {
            final BeanFactoryId beanFactoryId = resolver.beanFactoryId();
            final AnnotatedBeanFactory<?> factory = AnnotatedBeanFactoryRegistry.find(beanFactoryId);
            final TypeSignature typeSignature;
            if (factory != null) {
                final Builder<AnnotatedValueResolver> builder = ImmutableList.builder();
                factory.constructor().getValue().forEach(builder::add);
                factory.methods().values().forEach(resolvers -> resolvers.forEach(builder::add));
                factory.fields().values().forEach(builder::add);
                final List<AnnotatedValueResolver> resolvers = builder.build();
                if (resolvers.isEmpty()) {
                    // Do not create a FieldInfo if resolvers is empty.
                    return null;
                }

                assert beanFactoryId != null;
                final Class<?> type = beanFactoryId.type();
                typeSignature = new RequestObjectTypeSignature(TypeSignatureType.STRUCT, type.getName(), type,
                                                               new AnnotatedValueResolversWrapper(resolvers));
            } else {
                typeSignature = toTypeSignature(resolver.elementType());
            }
            return FieldInfo.builder(resolver.httpElementName(), typeSignature)
                            .requirement(resolver.shouldExist() ?
                                         FieldRequirement.REQUIRED : FieldRequirement.OPTIONAL)
                            .descriptionInfo(resolver.description())
                            .build();
        }

        if (annotationType != Param.class && annotationType != Header.class) {
            return null;
        }
        final TypeSignature signature;
        if (resolver.hasContainer()) {
            final Class<?> containerType = resolver.containerType();
            assert containerType != null;
            final TypeSignature parameterTypeSignature = toTypeSignature(resolver.elementType());
            if (List.class.isAssignableFrom(containerType)) {
                signature = TypeSignature.ofList(parameterTypeSignature);
            } else if (Set.class.isAssignableFrom(containerType)) {
                signature = TypeSignature.ofSet(parameterTypeSignature);
            } else {
                // Only List and Set are supported for the containerType.
                return null;
            }
        } else {
            signature = toTypeSignature(resolver.elementType());
        }
        return FieldInfo.builder(resolver.httpElementName(), signature)
                        .location(location(resolver))
                        .requirement(resolver.shouldExist() ? FieldRequirement.REQUIRED
                                                            : FieldRequirement.OPTIONAL)
                        .descriptionInfo(resolver.description())
                        .build();
    }
A {@link DocServicePlugin} implementation that supports the {@link AnnotatedService}.
core/src/main/java/com/linecorp/armeria/internal/server/annotation/AnnotatedDocServicePlugin.java