private static void generateDescriptiveTypeInfos(
            Function<DescriptiveTypeSignature, ? extends DescriptiveTypeInfo> descriptiveTypeInfoFactory,
            Map<String, EnumInfo> enums, Map<String, StructInfo> structs,
            Map<String, ExceptionInfo> exceptions, Set<DescriptiveTypeSignature> descriptiveTypes) {

        descriptiveTypes.forEach(type -> {
            final String typeName = type.name();
            if (enums.containsKey(typeName) ||
                structs.containsKey(typeName) ||
                exceptions.containsKey(typeName)) {
                return;
            }

            final DescriptiveTypeInfo newInfo = descriptiveTypeInfoFactory.apply(type);
            if (newInfo instanceof EnumInfo) {
                enums.put(newInfo.name(), (EnumInfo) newInfo);
                return;
            }
            if (newInfo instanceof StructInfo) {
                structs.put(newInfo.name(), (StructInfo) newInfo);
            } else if (newInfo instanceof ExceptionInfo) {
                exceptions.put(newInfo.name(), (ExceptionInfo) newInfo);
            } else {
                throw new Error(); // Should never reach here.
            }

            generateDescriptiveTypeInfos(descriptiveTypeInfoFactory, enums, structs, exceptions,
                                         newInfo.findDescriptiveTypes());
        });
    }
Generates a new {@link ServiceSpecification} from the specified {@link ServiceInfo}s and
the factory {@link Function} that creates {@link DescriptiveTypeInfo}s for the enum, struct or
exception types referred by the specified {@link ServiceInfo}s.
core/src/main/java/com/linecorp/armeria/server/docs/ServiceSpecification.java