+ /**
+ * Attempt to link the generator corresponding to the original definition for this generator's statements as well as
+ * to all child generators.
+ *
+ * @return Progress indication
+ */
+ final @NonNull LinkageProgress linkOriginalGeneratorRecursive() {
+ if (unlinkedComposites == null) {
+ // We have unset this list (see below), and there is nothing left to do
+ return LinkageProgress.DONE;
+ }
+
+ if (unlinkedChildren == null) {
+ unlinkedChildren = childGenerators.stream()
+ .filter(AbstractExplicitGenerator.class::isInstance)
+ .map(child -> (AbstractExplicitGenerator<?, ?>) child)
+ .collect(Collectors.toList());
+ }
+
+ var progress = LinkageProgress.NONE;
+ if (!unlinkedChildren.isEmpty()) {
+ // Attempt to make progress on child linkage
+ final var it = unlinkedChildren.iterator();
+ while (it.hasNext()) {
+ if (it.next() instanceof AbstractExplicitGenerator<?, ?> explicit && explicit.linkOriginalGenerator()) {
+ progress = LinkageProgress.SOME;
+ it.remove();
+
+ // If this is a composite generator we need to process is further
+ if (explicit instanceof AbstractCompositeGenerator<?, ?> composite) {
+ if (unlinkedComposites.isEmpty()) {
+ unlinkedComposites = new ArrayList<>();
+ }
+ unlinkedComposites.add(composite);
+ }
+ }
+ }
+
+ if (unlinkedChildren.isEmpty()) {
+ // Nothing left to do, make sure any previously-allocated list can be scavenged
+ unlinkedChildren = List.of();
+ }
+ }
+
+ // Process children of any composite children we have.
+ final var it = unlinkedComposites.iterator();
+ while (it.hasNext()) {
+ final var tmp = it.next().linkOriginalGeneratorRecursive();
+ if (tmp != LinkageProgress.NONE) {
+ progress = LinkageProgress.SOME;
+ }
+ if (tmp == LinkageProgress.DONE) {
+ it.remove();
+ }
+ }
+
+ if (unlinkedChildren.isEmpty() && unlinkedComposites.isEmpty()) {
+ // All done, set the list to null to indicate there is nothing left to do in this generator or any of our
+ // children.
+ unlinkedComposites = null;
+ return LinkageProgress.DONE;
+ }
+
+ return progress;
+ }
+
+ @Override
+ final AbstractCompositeGenerator<S, R> getOriginal() {
+ return (AbstractCompositeGenerator<S, R>) super.getOriginal();
+ }
+