Migrate rawStatementArgument()/getStatementSourceReference() callers
[yangtools.git] / yang / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / AbstractResumedStatement.java
1 /*
2  * Copyright (c) 2020 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.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.collect.ImmutableList;
14 import java.util.Collection;
15 import java.util.List;
16 import java.util.Optional;
17 import java.util.stream.Stream;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
21 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
22 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
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.StatementSupport;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
28 import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
29 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
30 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter.ResumedStatement;
31
32 /**
33  * Intermediate subclass of StatementContextBase facing the parser stream via implementation of ResumedStatement. This
34  * shields inference-type substatements from these details.
35  *
36  * @param <A> Argument type
37  * @param <D> Declared Statement representation
38  * @param <E> Effective Statement representation
39  */
40 abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
41         extends StatementContextBase<A, D, E> implements ResumedStatement {
42     private final @NonNull StatementSourceReference statementDeclSource;
43     private final String rawArgument;
44
45     private List<StatementContextBase<?, ?, ?>> effective = ImmutableList.of();
46     private StatementMap substatements = StatementMap.empty();
47     private @Nullable D declaredInstance;
48
49     // Copy constructor
50     AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
51         super(original);
52         this.statementDeclSource = original.statementDeclSource;
53         this.rawArgument = original.rawArgument;
54         this.substatements = original.substatements;
55         this.declaredInstance = original.declaredInstance;
56     }
57
58     AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
59             final String rawArgument) {
60         super(def);
61         this.statementDeclSource = requireNonNull(ref);
62         this.rawArgument = def.support().internArgument(rawArgument);
63     }
64
65     AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
66             final String rawArgument, final CopyType copyType) {
67         super(def, CopyHistory.of(copyType, CopyHistory.original()));
68         this.statementDeclSource = requireNonNull(ref);
69         this.rawArgument = rawArgument;
70     }
71
72     @Override
73     public final Optional<StmtContext<A, D, E>> getOriginalCtx() {
74         return Optional.empty();
75     }
76
77     @Override
78     public final Optional<StmtContext<A, D, E>> getPreviousCopyCtx() {
79         return Optional.empty();
80     }
81
82     @Override
83     public final StatementSourceReference sourceReference() {
84         return statementDeclSource;
85     }
86
87     @Override
88     public final String rawArgument() {
89         return rawArgument;
90     }
91
92     @Override
93     public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
94         return substatements;
95     }
96
97     @Override
98     public final Collection<? extends Mutable<?, ?, ?>> mutableEffectiveSubstatements() {
99         return mutableEffectiveSubstatements(effective);
100     }
101
102     @Override
103     public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef) {
104         effective = removeStatementFromEffectiveSubstatements(effective, statementDef);
105     }
106
107     @Override
108     public final void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef,
109             final String statementArg) {
110         effective = removeStatementFromEffectiveSubstatements(effective, statementDef, statementArg);
111     }
112
113     @Override
114     public final void addEffectiveSubstatement(final Mutable<?, ?, ?> substatement) {
115         effective = addEffectiveSubstatement(effective, substatement);
116     }
117
118     @Override
119     final void addEffectiveSubstatementsImpl(final Collection<? extends Mutable<?, ?, ?>> statements) {
120         effective = addEffectiveSubstatementsImpl(effective, statements);
121     }
122
123     @Override
124     public final D buildDeclared() {
125         final D existing;
126         return (existing = declaredInstance) != null ? existing : loadDeclared();
127     }
128
129     private @NonNull D loadDeclared() {
130         final ModelProcessingPhase phase = getCompletedPhase();
131         checkState(phase == ModelProcessingPhase.FULL_DECLARATION || phase == ModelProcessingPhase.EFFECTIVE_MODEL,
132                 "Cannot build declared instance after phase %s", phase);
133         return declaredInstance = definition().getFactory().createDeclared(this);
134     }
135
136     @Override
137     public StatementDefinition getDefinition() {
138         return publicDefinition();
139     }
140
141     @Override
142     public StatementSourceReference getSourceReference() {
143         return sourceReference();
144     }
145
146     @Override
147     public boolean isFullyDefined() {
148         return fullyDefined();
149     }
150
151     /**
152      * Create a new substatement at the specified offset.
153      *
154      * @param offset Substatement offset
155      * @param def definition context
156      * @param ref source reference
157      * @param argument statement argument
158      * @param <X> new substatement argument type
159      * @param <Y> new substatement declared type
160      * @param <Z> new substatement effective type
161      * @return A new substatement
162      */
163     @SuppressWarnings("checkstyle:methodTypeParameterName")
164     final <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
165             AbstractResumedStatement<X, Y, Z> createSubstatement(final int offset,
166                     final StatementDefinitionContext<X, Y, Z> def, final StatementSourceReference ref,
167                     final String argument) {
168         final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase();
169         checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
170                 "Declared statement cannot be added in effective phase at: %s", sourceReference());
171
172         final Optional<StatementSupport<?, ?, ?>> implicitParent =
173                 definition().getImplicitParentFor(def.getPublicView());
174         if (implicitParent.isPresent()) {
175             return createImplicitParent(offset, implicitParent.get(), ref, argument).createSubstatement(offset, def,
176                     ref, argument);
177         }
178
179         final AbstractResumedStatement<X, Y, Z> ret = new SubstatementContext<>(this, def, ref, argument);
180         substatements = substatements.put(offset, ret);
181         def.onStatementAdded(ret);
182         return ret;
183     }
184
185     @Override
186     final boolean hasEmptySubstatements() {
187         return substatements.size() == 0 && effective.isEmpty();
188     }
189
190     @Override
191     final Iterable<StatementContextBase<?, ?, ?>> effectiveChildrenToComplete() {
192         return effective;
193     }
194
195     @Override
196     final Stream<? extends StmtContext<?, ?, ?>> streamDeclared() {
197         return declaredSubstatements().stream();
198     }
199
200     @Override
201     final Stream<? extends StmtContext<?, ?, ?>> streamEffective() {
202         return effective.stream();
203     }
204
205     /**
206      * Lookup substatement by its offset in this statement.
207      *
208      * @param offset Substatement offset
209      * @return Substatement, or null if substatement does not exist.
210      */
211     final AbstractResumedStatement<?, ?, ?> lookupSubstatement(final int offset) {
212         return substatements.get(offset);
213     }
214
215     final void resizeSubstatements(final int expectedSize) {
216         substatements = substatements.ensureCapacity(expectedSize);
217     }
218
219     final void walkChildren(final ModelProcessingPhase phase) {
220         checkState(isFullyDefined());
221         substatements.forEach(stmt -> {
222             stmt.walkChildren(phase);
223             stmt.endDeclared(phase);
224         });
225     }
226
227     private AbstractResumedStatement<?, ?, ?> createImplicitParent(final int offset,
228             final StatementSupport<?, ?, ?> implicitParent, final StatementSourceReference ref, final String argument) {
229         final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(implicitParent);
230         return createSubstatement(offset, def, ImplicitSubstatement.of(ref), argument);
231     }
232 }