X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fstmt%2Freactor%2FRootStatementContext.java;h=7bb341e73c5dc633de57bb2f739d5b800316a736;hb=12880a5876c644243ba46ce8c674f29a7d0c773a;hp=b24f6e3e04e4db27124921098e92991886ef7961;hpb=82af449e4ef07d80490e79484d0402b81009541e;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java index b24f6e3e04..7bb341e73c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java @@ -8,72 +8,90 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.base.Verify; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.YangVersion; +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; +import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.source.IncludedModuleContext; +import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; /** - * root statement class for a Yang source + * Root statement class for a YANG source. All statements defined in that YANG source are mapped underneath an instance + * of this class, hence recursive lookups from them cross this class. */ public class RootStatementContext, E extends EffectiveStatement> extends StatementContextBase { + public static final YangVersion DEFAULT_VERSION = YangVersion.VERSION_1; + private final SourceSpecificContext sourceContext; private final A argument; - RootStatementContext(final ContextBuilder builder, final SourceSpecificContext sourceContext) { - super(builder); - this.sourceContext = sourceContext; - this.argument = builder.getDefinition().parseArgumentValue(this, builder.getRawArgument()); + private YangVersion version; + private Collection requiredModules = ImmutableSet.of(); + private ModuleIdentifier identifier; + + /** + * References to RootStatementContext of submodules which are included in this source. + */ + private Collection> includedContexts = ImmutableList.of(); + + RootStatementContext(final SourceSpecificContext sourceContext, final StatementDefinitionContext def, + final StatementSourceReference ref, final String rawArgument) { + super(def, ref, rawArgument); + this.sourceContext = Preconditions.checkNotNull(sourceContext); + this.argument = def.parseArgumentValue(this, rawStatementArgument()); + } + + RootStatementContext(final SourceSpecificContext sourceContext, final StatementDefinitionContext def, + final StatementSourceReference ref, final String rawArgument, final YangVersion version, + final ModuleIdentifier identifier) { + this(sourceContext, def, ref, rawArgument); + this.setRootVersion(version); + this.setRootIdentifier(identifier); } RootStatementContext(final RootStatementContext original, final QNameModule newQNameModule, - final TypeOfCopy typeOfCopy) { + final CopyType typeOfCopy) { super(original); - sourceContext = original.sourceContext; + sourceContext = Preconditions.checkNotNull(original.sourceContext); this.argument = original.argument; - copyDeclaredStmts(original, newQNameModule, typeOfCopy); - - copyEffectiveStmts(original, newQNameModule, typeOfCopy); - - } + final Collection> declared = original.mutableDeclaredSubstatements(); + final Collection> effective = original.mutableEffectiveSubstatements(); + final Collection> buffer = new ArrayList<>(declared.size() + effective.size()); - /** - * copies declared statements from original to this' substatements - * - * @param typeOfCopy - * determines whether copy is used by augmentation or uses - * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException - */ - private void copyDeclaredStmts(final RootStatementContext original, final QNameModule newQNameModule, - final TypeOfCopy typeOfCopy) { - Collection> originalDeclaredSubstatements = original.declaredSubstatements(); - for (StmtContext stmtContext : originalDeclaredSubstatements) { - this.addEffectiveSubstatement(stmtContext.createCopy(newQNameModule, this, typeOfCopy)); + for (final Mutable stmtContext : declared) { + if (stmtContext.isSupportedByFeatures()) { + buffer.add(stmtContext.createCopy(newQNameModule, this, typeOfCopy)); + } } - } - - /** - * copies effective statements from original to this' substatements - * - * @param typeOfCopy - * determines whether copy is used by augmentation or uses - * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException - */ - private void copyEffectiveStmts(final RootStatementContext original, final QNameModule newQNameModule, - final TypeOfCopy typeOfCopy) { - Collection> originalEffectiveSubstatements = original.effectiveSubstatements(); - for (StmtContext stmtContext : originalEffectiveSubstatements) { - this.addEffectiveSubstatement(stmtContext.createCopy(newQNameModule, this, typeOfCopy)); + for (final StmtContext stmtContext : effective) { + buffer.add(stmtContext.createCopy(newQNameModule, this, typeOfCopy)); } + + addEffectiveSubstatements(buffer); } /** @@ -92,9 +110,6 @@ public class RootStatementContext, E extends E return sourceContext; } - /** - * @return registry of source context - */ @Override public Registry getBehaviourRegistry() { return sourceContext; @@ -107,6 +122,7 @@ public class RootStatementContext, E extends E /** * @return this as its own root */ + @Nonnull @Override public RootStatementContext getRoot() { return this; @@ -122,28 +138,27 @@ public class RootStatementContext, E extends E } /** - * @return copy of this considering {@link TypeOfCopy} (augment, uses) + * @return copy of this considering {@link CopyType} (augment, uses) * * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException */ @Override - public StatementContextBase createCopy(final StatementContextBase newParent, - final TypeOfCopy typeOfCopy) { + public StatementContextBase createCopy(final StatementContextBase newParent, + final CopyType typeOfCopy) { return createCopy(null, newParent, typeOfCopy); } /** - * @return copy of this considering {@link TypeOfCopy} (augment, uses) + * @return copy of this considering {@link CopyType} (augment, uses) * * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException */ @Override public StatementContextBase createCopy(final QNameModule newQNameModule, - final StatementContextBase newParent, final TypeOfCopy typeOfCopy) { - RootStatementContext copy = new RootStatementContext<>(this, newQNameModule, typeOfCopy); + final StatementContextBase newParent, final CopyType typeOfCopy) { + final RootStatementContext copy = new RootStatementContext<>(this, newQNameModule, typeOfCopy); - copy.addAllToCopyHistory(this.getCopyHistory()); - copy.addToCopyHistory(typeOfCopy); + copy.appendCopyHistory(typeOfCopy, this.getCopyHistory()); if (this.getOriginalCtx() != null) { copy.setOriginalCtx(this.getOriginalCtx()); @@ -154,6 +169,7 @@ public class RootStatementContext, E extends E return copy; } + @Nonnull @Override public Optional getSchemaPath() { return Optional.of(SchemaPath.ROOT); @@ -171,4 +187,132 @@ public class RootStatementContext, E extends E public boolean isConfiguration() { return true; } + + @Override + public boolean isInYangDataExtensionBody() { + return false; + } + + @Override + public boolean isEnabledSemanticVersioning() { + return sourceContext.isEnabledSemanticVersioning(); + } + + @Override + public > V putToLocalStorage(final Class type, final K key, + final V value) { + if (IncludedModuleContext.class.isAssignableFrom(type)) { + if (includedContexts.isEmpty()) { + includedContexts = new ArrayList<>(1); + } + Verify.verify(value instanceof RootStatementContext); + includedContexts.add((RootStatementContext) value); + } + return super.putToLocalStorage(type, key, value); + } + + @Nullable + @Override + public > V getFromLocalStorage(final Class type, final K key) { + return getFromLocalStorage(type, key, new HashSet<>()); + } + + /* + * We need to track already checked RootStatementContexts due to possible + * circular chains of includes between submodules + */ + @Nullable + private > V getFromLocalStorage(final Class type, final K key, + final HashSet> alreadyChecked) { + final V potentialLocal = super.getFromLocalStorage(type, key); + if (potentialLocal != null) { + return potentialLocal; + } + + alreadyChecked.add(this); + for (final RootStatementContext includedSource : includedContexts) { + if (alreadyChecked.contains(includedSource)) { + continue; + } + final V potential = includedSource.getFromLocalStorage(type, key, alreadyChecked); + if (potential != null) { + return potential; + } + } + return null; + } + + @Nullable + @Override + public > Map getAllFromLocalStorage(final Class type) { + return getAllFromLocalStorage(type, new HashSet<>()); + } + + /* + * We need to track already checked RootStatementContexts due to possible + * circular chains of includes between submodules + */ + @Nullable + private > Map getAllFromLocalStorage(final Class type, + final HashSet> alreadyChecked) { + final Map potentialLocal = super.getAllFromLocalStorage(type); + if (potentialLocal != null) { + return potentialLocal; + } + + alreadyChecked.add(this); + for (final RootStatementContext includedSource : includedContexts) { + if (alreadyChecked.contains(includedSource)) { + continue; + } + final Map potential = includedSource.getAllFromLocalStorage(type, alreadyChecked); + if (potential != null) { + return potential; + } + } + return null; + } + + @Override + public YangVersion getRootVersion() { + return version == null ? DEFAULT_VERSION : version; + } + + @Override + public void setRootVersion(final YangVersion version) { + Preconditions.checkArgument(sourceContext.getSupportedVersions().contains(version), + "Unsupported yang version %s in %s", version, getStatementSourceReference()); + Preconditions.checkState(this.version == null, "Version of root %s has been already set to %s", argument, + this.version); + this.version = Preconditions.checkNotNull(version); + } + + @Override + public void addMutableStmtToSeal(final MutableStatement mutableStatement) { + sourceContext.addMutableStmtToSeal(mutableStatement); + } + + @Override + public void addRequiredModule(final ModuleIdentifier dependency) { + Preconditions.checkState(sourceContext.getInProgressPhase() == ModelProcessingPhase.SOURCE_PRE_LINKAGE, + "Add required module is allowed only in ModelProcessingPhase.SOURCE_PRE_LINKAGE phase"); + if (requiredModules.isEmpty()) { + requiredModules = new HashSet<>(); + } + requiredModules.add(dependency); + } + + Collection getRequiredModules() { + return ImmutableSet.copyOf(requiredModules); + } + + @Override + public void setRootIdentifier(final ModuleIdentifier identifier) { + Preconditions.checkNotNull(identifier); + this.identifier = identifier; + } + + ModuleIdentifier getRootIdentifier() { + return identifier; + } }