ec781391a316a9826bd12407bdb7b4066fee0348
[yangtools.git] / parser / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / OriginalStmtCtx.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
9
10 import static com.google.common.base.Verify.verify;
11 import static com.google.common.base.Verify.verifyNotNull;
12 import static java.util.Objects.requireNonNull;
13
14 import com.google.common.collect.ImmutableList;
15 import java.util.Collection;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Optional;
19 import java.util.stream.Stream;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
22 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
27 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 abstract class OriginalStmtCtx<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
32         extends StatementContextBase<A, D, E> {
33     private static final Logger LOG = LoggerFactory.getLogger(OriginalStmtCtx.class);
34
35     private final @NonNull StatementSourceReference ref;
36
37     private List<ReactorStmtCtx<?, ?, ?>> effective = ImmutableList.of();
38
39     OriginalStmtCtx(final OriginalStmtCtx<A, D, E> original) {
40         super(original);
41         this.ref = original.ref;
42     }
43
44     OriginalStmtCtx(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref) {
45         super(def);
46         this.ref = requireNonNull(ref);
47     }
48
49     OriginalStmtCtx(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
50             final CopyType copyType) {
51         super(def, copyType);
52         this.ref = requireNonNull(ref);
53     }
54
55     @Override
56     public final StatementSourceReference sourceReference() {
57         return ref;
58     }
59
60     @Override
61     public final Optional<StmtContext<A, D, E>> getOriginalCtx() {
62         return Optional.empty();
63     }
64
65     @Override
66     public final Optional<StmtContext<A, D, E>> getPreviousCopyCtx() {
67         return Optional.empty();
68     }
69
70     @Override
71     public final Collection<? extends Mutable<?, ?, ?>> mutableEffectiveSubstatements() {
72         return mutableEffectiveSubstatements(effective);
73     }
74
75     @Override
76     public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef) {
77         effective = removeStatementFromEffectiveSubstatements(effective, statementDef);
78     }
79
80     @Override
81     public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef,
82             final String statementArg) {
83         effective = removeStatementFromEffectiveSubstatements(effective, statementDef, statementArg);
84     }
85
86     @Override
87     public final void addEffectiveSubstatement(final Mutable<?, ?, ?> substatement) {
88         effective = addEffectiveSubstatement(effective, substatement);
89         afterAddEffectiveSubstatement(substatement);
90     }
91
92     @Override
93     final void addEffectiveSubstatementsImpl(final Collection<? extends Mutable<?, ?, ?>> statements) {
94         effective = addEffectiveSubstatementsImpl(effective, statements);
95     }
96
97     @Override
98     final Iterator<ReactorStmtCtx<?, ?, ?>> effectiveChildrenToComplete() {
99         return effective.iterator();
100     }
101
102     @Override
103     final Stream<? extends @NonNull ReactorStmtCtx<?, ?, ?>> streamEffective() {
104         return effective.stream().filter(StmtContext::isSupportedToBuildEffective);
105     }
106
107     @Override
108     final OriginalStmtCtx<A, D, E> unmodifiedEffectiveSource() {
109         // This statement is comes from the source
110         return this;
111     }
112
113     @Override
114     final boolean hasEmptySubstatements() {
115         return effective.isEmpty() && mutableDeclaredSubstatements().isEmpty();
116     }
117
118     @Override
119     final boolean noSensitiveSubstatements() {
120         return hasEmptySubstatements()
121             || noSensitiveSubstatements(effective) && noSensitiveSubstatements(mutableDeclaredSubstatements());
122     }
123
124     @Override
125     final void markNoParentRef() {
126         markNoParentRef(mutableDeclaredSubstatements());
127         markNoParentRef(effective);
128     }
129
130     @Override
131     final int sweepSubstatements() {
132         // First we need to sweep all statements, which may trigger sweeps all across the place, for example:
133         // - 'effective' member sweeping a 'substatements' member
134         // - 'substatements' member sweeping a 'substatements' member which came before it during iteration
135         // We then iterate once again, counting what remains unswept
136         final var declared = mutableDeclaredSubstatements();
137
138         sweep(declared);
139         sweep(effective);
140         final int count = countUnswept(declared) + countUnswept(effective);
141         if (count != 0) {
142             LOG.debug("{} children left to sweep from {}", count, this);
143         }
144         effective = null;
145         dropDeclaredSubstatements();
146         return count;
147     }
148
149     abstract void dropDeclaredSubstatements();
150
151     void declarationFinished(final ModelProcessingPhase phase) {
152         finishDeclaration(phase);
153     }
154
155     /**
156      * Ends declared section of current node for the specified phase.
157      *
158      * @param phase processing phase that ended
159      */
160     final void finishDeclaration(final ModelProcessingPhase phase) {
161         definition().onDeclarationFinished(this, phase);
162     }
163
164     final OriginalStmtCtx<?, ?, ?> getResumedSubstatement() {
165         final var local = verifyNotNull(effective);
166         verify(!local.isEmpty(), "Unexpected empty statements");
167         final var ret = local.get(0);
168         verify(ret instanceof OriginalStmtCtx, "Unexpected statement %s", ret);
169         return (OriginalStmtCtx<?, ?, ?>) ret;
170     }
171 }