2 * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
13 import java.util.Collection;
14 import java.util.Optional;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
18 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
19 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
25 import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
26 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
27 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter.ResumedStatement;
30 * Intermediate subclass of StatementContextBase facing the parser stream via implementation of ResumedStatement. This
31 * shields inference-type substatements from these details.
33 * @param <A> Argument type
34 * @param <D> Declared Statement representation
35 * @param <E> Effective Statement representation
37 abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
38 extends StatementContextBase<A, D, E> implements ResumedStatement {
39 private final @NonNull StatementSourceReference statementDeclSource;
40 private final String rawArgument;
42 private StatementMap substatements = StatementMap.empty();
43 private @Nullable D declaredInstance;
46 AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
48 this.statementDeclSource = original.statementDeclSource;
49 this.rawArgument = original.rawArgument;
50 this.substatements = original.substatements;
51 this.declaredInstance = original.declaredInstance;
54 AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
55 final String rawArgument) {
57 this.statementDeclSource = requireNonNull(ref);
58 this.rawArgument = def.support().internArgument(rawArgument);
61 AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
62 final String rawArgument, final CopyType copyType) {
63 super(def, CopyHistory.of(copyType, CopyHistory.original()));
64 this.statementDeclSource = requireNonNull(ref);
65 this.rawArgument = rawArgument;
69 public final Optional<StmtContext<?, ?, ?>> getOriginalCtx() {
70 return Optional.empty();
74 public final Optional<? extends StmtContext<?, ?, ?>> getPreviousCopyCtx() {
75 return Optional.empty();
79 public final StatementSourceReference getStatementSourceReference() {
80 return statementDeclSource;
84 public final String rawStatementArgument() {
89 public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
90 return substatements.values();
94 public final D buildDeclared() {
95 final D existing = declaredInstance;
96 if (existing != null) {
99 final ModelProcessingPhase phase = getCompletedPhase();
100 checkState(phase == ModelProcessingPhase.FULL_DECLARATION || phase == ModelProcessingPhase.EFFECTIVE_MODEL,
101 "Cannot build declared instance after phase %s", phase);
102 return declaredInstance = definition().getFactory().createDeclared(this);
106 public @NonNull StatementDefinition getDefinition() {
107 return getPublicDefinition();
111 public @NonNull StatementSourceReference getSourceReference() {
112 return getStatementSourceReference();
116 public boolean isFullyDefined() {
117 return fullyDefined();
121 * Create a new substatement at the specified offset.
123 * @param offset Substatement offset
124 * @param def definition context
125 * @param ref source reference
126 * @param argument statement argument
127 * @param <X> new substatement argument type
128 * @param <Y> new substatement declared type
129 * @param <Z> new substatement effective type
130 * @return A new substatement
132 @SuppressWarnings("checkstyle:methodTypeParameterName")
133 final <X, Y extends DeclaredStatement<X>, Z extends EffectiveStatement<X, Y>>
134 AbstractResumedStatement<X, Y, Z> createSubstatement(final int offset,
135 final StatementDefinitionContext<X, Y, Z> def, final StatementSourceReference ref,
136 final String argument) {
137 final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase();
138 checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
139 "Declared statement cannot be added in effective phase at: %s", getStatementSourceReference());
141 final Optional<StatementSupport<?, ?, ?>> implicitParent =
142 definition().getImplicitParentFor(def.getPublicView());
143 if (implicitParent.isPresent()) {
144 return createImplicitParent(offset, implicitParent.get(), ref, argument).createSubstatement(offset, def,
148 final AbstractResumedStatement<X, Y, Z> ret = new SubstatementContext<>(this, def, ref, argument);
149 substatements = substatements.put(offset, ret);
150 def.onStatementAdded(ret);
155 * Lookup substatement by its offset in this statement.
157 * @param offset Substatement offset
158 * @return Substatement, or null if substatement does not exist.
160 final AbstractResumedStatement<?, ?, ?> lookupSubstatement(final int offset) {
161 return substatements.get(offset);
164 final void resizeSubstatements(final int expectedSize) {
165 substatements = substatements.ensureCapacity(expectedSize);
168 final void walkChildren(final ModelProcessingPhase phase) {
169 checkState(isFullyDefined());
170 substatements.values().forEach(stmt -> {
171 stmt.walkChildren(phase);
172 stmt.endDeclared(phase);
176 private AbstractResumedStatement<?, ?, ?> createImplicitParent(final int offset,
177 final StatementSupport<?, ?, ?> implicitParent, final StatementSourceReference ref, final String argument) {
178 final StatementDefinitionContext<?, ?, ?> def = new StatementDefinitionContext<>(implicitParent);
179 return createSubstatement(offset, def, ImplicitSubstatement.of(ref), argument);