private static void listElements(
            Set<Object> elements, Set<Attribute<?, ?>> attributes, ConfigurationContext context, boolean root) {
        // some unexpected type erasure force to cast here
        attributes.stream()
                .peek(attribute -> {
                    // root primitive attributes are skipped without this
                    if (root && !(attribute instanceof DescribableAttribute)) {
                        elements.add(attribute);
                    }
                })
                .map(Attribute::getType)
                .map(context::lookup)
                .filter(Objects::nonNull)
                .map(c -> c.getConfigurators(context))
                .flatMap(Collection::stream)
                .filter(elements::add)
                .forEach(configurator ->
                        listElements(elements, ((Configurator) configurator).describe(), context, false));
    }
Recursive configurators tree walk (DFS) and non-describable able attributes. Collects all
configurators starting from root ones in {@link ConfigurationAsCode#getConfigurators()}

@param elements linked set (to save order) of visited elements
@param attributes siblings to find associated configurators and dive to next tree levels
@param context configuration context
@param root is this the first iteration of root attributes
plugin/src/main/java/io/jenkins/plugins/casc/SchemaGeneration.java