private Stream descendants()

in hollow/src/main/java/com/netflix/hollow/core/read/filter/TypeFilter.java [398:460]


    private Stream<TypeActions> descendants(Rule rule, HollowSchema schema) {
        String type = schema.getName();
        Action action = rule.apply(type, null);
        TypeActions parent = TypeActions.newTypeActions(type, action);

        switch (schema.getSchemaType()) {
            case OBJECT:
                HollowObjectSchema os = (HollowObjectSchema) schema;
                return IntStream
                        .range(0, os.numFields())
                        .boxed()
                        .flatMap(i -> {
                            String field = os.getFieldName(i);
                            Action fa = rule.apply(type, field);
                            if (fa == next) return Stream.empty();
                            TypeActions child = newTypeActions(type, field, fa);
                            Action descendantAction = fa.recursive ? fa : action;
                            if (descendantAction.recursive && os.getFieldType(i) == REFERENCE) {
                                String refType = os.getReferencedType(i);
                                HollowSchema refSchema = schemas.get(refType);
                                assert refSchema != null;
                                Stream<TypeActions> descendants = descendants((t,f) -> descendantAction, refSchema);
                                return Stream.concat(Stream.of(parent, child), descendants);
                            } else {
                                return Stream.of(parent, child);
                            }
                        });

            case SET:
            case LIST:
                if (action == next) {
                    return Stream.empty();
                } else if (action.recursive) {
                    HollowCollectionSchema cs = (HollowCollectionSchema) schema;

                    HollowSchema elemSchema = schemas.get(cs.getElementType());
                    assert elemSchema != null;

                    Stream<TypeActions> descendants = descendants((t, f) -> action, elemSchema);
                    return Stream.concat(Stream.of(parent), descendants);
                } else {
                    return Stream.of(parent);
                }

            case MAP:
                if (action == next) {
                    return Stream.empty();
                } else if (action.recursive) {
                    HollowMapSchema ms = (HollowMapSchema) schema;
                    HollowSchema kSchema = schemas.get(ms.getKeyType());
                    HollowSchema vSchema = schemas.get(ms.getValueType());
                    Stream<TypeActions> descendants = Stream.concat(
                            descendants((t, f) -> action, kSchema),
                            descendants((t1, f1) -> action, vSchema));
                    return Stream.concat(Stream.of(parent), descendants);
                } else {
                    return Stream.of(parent);
                }

            default:
                throw new UnrecognizedSchemaTypeException(type, schema.getSchemaType());
        }
    }