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;
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;
27 * Intermediate subclass of StatementContextBase facing the parser stream via implementation of ResumedStatement. This
28 * shields inference-type substatements from these details.
30 * @param <A> Argument type
31 * @param <D> Declared Statement representation
32 * @param <E> Effective Statement representation
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();
38 AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
39 final String rawArgument) {
40 super(def, ref, rawArgument);
43 AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
44 final String rawArgument, final CopyType copyType) {
45 super(def, ref, rawArgument, copyType);
48 AbstractResumedStatement(final StatementContextBase<A, D, E> original, final CopyType copyType) {
49 super(original, copyType);
52 AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
54 this.substatements = original.substatements;
58 public Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
59 return substatements.values();
63 public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
64 return substatements.values();
68 public @NonNull StatementDefinition getDefinition() {
69 return getPublicDefinition();
73 public @NonNull StatementSourceReference getSourceReference() {
74 return getStatementSourceReference();
78 public boolean isFullyDefined() {
79 return fullyDefined();
83 * Create a new substatement at the specified offset.
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
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());
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,
110 final AbstractResumedStatement<X, Y, Z> ret = new SubstatementContext<>(this, def, ref, argument);
111 substatements = substatements.put(offset, ret);
112 def.onStatementAdded(ret);
117 * Lookup substatement by its offset in this statement.
119 * @param offset Substatement offset
120 * @return Substatement, or null if substatement does not exist.
122 final AbstractResumedStatement<?, ?, ?> lookupSubstatement(final int offset) {
123 return substatements.get(offset);
126 final void resizeSubstatements(final int expectedSize) {
127 substatements = substatements.ensureCapacity(expectedSize);
130 final void walkChildren(final ModelProcessingPhase phase) {
131 checkState(isFullyDefined());
132 substatements.values().forEach(stmt -> {
133 stmt.walkChildren(phase);
134 stmt.endDeclared(phase);
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);