Extract AbstractResumedStatement
[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
12 import java.util.Collection;
13 import java.util.Optional;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
16 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
17 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
18 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
19 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
22 import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
23 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
24 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter.ResumedStatement;
25
26 /**
27  * Intermediate subclass of StatementContextBase facing the parser stream via implementation of ResumedStatement. This
28  * shields inference-type substatements from these details.
29  *
30  * @param <A> Argument type
31  * @param <D> Declared Statement representation
32  * @param <E> Effective Statement representation
33  */
34 abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
35         extends StatementContextBase<A, D, E> implements ResumedStatement {
36     private StatementMap substatements = StatementMap.empty();
37
38     AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
39             final String rawArgument) {
40         super(def, ref, rawArgument);
41     }
42
43     AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
44             final String rawArgument, final CopyType copyType) {
45         super(def, ref, rawArgument, copyType);
46     }
47
48     AbstractResumedStatement(final StatementContextBase<A, D, E> original, final CopyType copyType) {
49         super(original, copyType);
50     }
51
52     AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
53         super(original);
54         this.substatements = original.substatements;
55     }
56
57     @Override
58     public Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
59         return substatements.values();
60     }
61
62     @Override
63     public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
64         return substatements.values();
65     }
66
67     @Override
68     public @NonNull StatementDefinition getDefinition() {
69         return getPublicDefinition();
70     }
71
72     @Override
73     public @NonNull StatementSourceReference getSourceReference() {
74         return getStatementSourceReference();
75     }
76
77     @Override
78     public boolean isFullyDefined() {
79         return fullyDefined();
80     }
81
82     /**
83      * Create a new substatement at the specified offset.
84      *
85      * @param offset Substatement offset
86      * @param def definition context
87      * @param ref source reference
88      * @param argument statement argument
89      * @param <X> new substatement argument type
90      * @param <Y> new substatement declared type
91      * @param <Z> new substatement effective type
92      * @return A new substatement
93      */
94     @SuppressWarnings("checkstyle:methodTypeParameterName")
95     final <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
96             AbstractResumedStatement<X, Y, Z> createSubstatement(final int offset,
97                     final StatementDefinitionContext<X, Y, Z> def, final StatementSourceReference ref,
98                     final String argument) {
99         final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase();
100         checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
101                 "Declared statement cannot be added in effective phase at: %s", getStatementSourceReference());
102
103         final Optional<StatementSupport<?, ?, ?>> implicitParent =
104                 definition().getImplicitParentFor(def.getPublicView());
105         if (implicitParent.isPresent()) {
106             return createImplicitParent(offset, implicitParent.get(), ref, argument).createSubstatement(offset, def,
107                     ref, argument);
108         }
109
110         final AbstractResumedStatement<X, Y, Z> ret = new SubstatementContext<>(this, def, ref, argument);
111         substatements = substatements.put(offset, ret);
112         def.onStatementAdded(ret);
113         return ret;
114     }
115
116     /**
117      * Lookup substatement by its offset in this statement.
118      *
119      * @param offset Substatement offset
120      * @return Substatement, or null if substatement does not exist.
121      */
122     final AbstractResumedStatement<?, ?, ?> lookupSubstatement(final int offset) {
123         return substatements.get(offset);
124     }
125
126     final void resizeSubstatements(final int expectedSize) {
127         substatements = substatements.ensureCapacity(expectedSize);
128     }
129
130     final void walkChildren(final ModelProcessingPhase phase) {
131         checkState(isFullyDefined());
132         substatements.values().forEach(stmt -> {
133             stmt.walkChildren(phase);
134             stmt.endDeclared(phase);
135         });
136     }
137
138     private AbstractResumedStatement<?, ?, ?> createImplicitParent(final int offset,
139             final StatementSupport<?, ?, ?> implicitParent, final StatementSourceReference ref, final String argument) {
140         final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(implicitParent);
141         return createSubstatement(offset, def, ImplicitSubstatement.of(ref), argument);
142     }
143 }