@Nonnull
	protected Result<AnnotationPrinter> annotationPrinter(@Nonnull AnnotationPathNode path) {
		if (path.getParent() == null) {
			return Result.err(Error.of("Dangling annotation", null));
		}

		Object parent = path.getParent().getValue();
		Result<? extends Printer> parentPrinter;
		if (parent instanceof ClassPathNode classNode) {
			parentPrinter = classPrinter(classNode);
		} else if (parent instanceof ClassMemberPathNode classMember) {
			parentPrinter = memberPrinter(classMember);
		} else {
			return Result.err(Error.of("Invalid parent type", null));
		}

		AnnotationInfo annotation = path.getValue();

		if (parent instanceof Annotated annotated) {

			return parentPrinter.flatMap((printer) -> {
				if (printer instanceof AnnotationHolder holder) {
					return Result.ok(holder.annotation(annotated.getAnnotations().indexOf(annotation)));
				} else {
					return Result.err(Error.of("Parent is not an annotation holder", null));
				}
			});

		} else {
			return Result.err(Error.of("Parent cannot hold annotations", null));
		}
	}
Common pipeline implementation details for all class types.

@param <C>
		Class type which will be assembled.
@param <R>
		Compile return value for JASM {@link Compiler}.
@param <I>
		Class intermediate representation type.

@author Justus Garbe
recaf-core/src/main/java/software/coley/recaf/services/assembler/AbstractAssemblerPipeline.java