X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-rfc7950%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frfc7950%2Fstmt%2FAbstractEffectiveModule.java;h=8eeb12bf3f5ab92d25ded239f91892bc3dcf1b8b;hb=c6e3f104f035b0d7aee05fdc75d11e1a2de50f3c;hp=3b7dc1f8aa8f9de01a4b9a279704615bea88aea1;hpb=dbe90727194b03e303eb1a245f98eb210f33b512;p=yangtools.git diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveModule.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveModule.java index 3b7dc1f8aa..8eeb12bf3f 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveModule.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveModule.java @@ -7,26 +7,21 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; -import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; import com.google.common.annotations.Beta; import com.google.common.base.MoreObjects; -import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import java.net.URI; import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashMap; +import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.concepts.SemVer; import org.opendaylight.yangtools.openconfig.model.api.OpenConfigVersionEffectiveStatement; @@ -34,7 +29,6 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.Deviation; import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; @@ -45,77 +39,54 @@ import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.ModuleImport; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; -import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; -import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; 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.stmt.BelongsToEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ContactEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ImportEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.OrganizationEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.PrefixEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionEffectiveStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.compat.NotificationNodeContainerCompat; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; -import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToModuleCtx; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToModuleCtx; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; @Beta public abstract class AbstractEffectiveModule> extends - AbstractSchemaEffectiveDocumentedNode implements Module, MutableStatement { + AbstractSchemaEffectiveDocumentedNode implements Module, + NotificationNodeContainerCompat { private final String name; private final String prefix; private final YangVersion yangVersion; private final String organization; private final String contact; - private final Set imports; - private final Set features; - private final Set notifications; - private final Set augmentations; - private final Set rpcs; - private final Set deviations; - private final List extensionNodes; - private final Set identities; - private final @NonNull List unknownNodes; - private final Map childNodes; - private final Set groupings; - private final Set uses; - private final Set> typeDefinitions; - private final Set publicChildNodes; + private final ImmutableSet imports; + private final ImmutableSet features; + private final @NonNull ImmutableSet notifications; + private final ImmutableSet augmentations; + private final ImmutableSet rpcs; + private final ImmutableSet deviations; + private final ImmutableList extensionNodes; + private final ImmutableSet identities; + private final ImmutableSet groupings; + private final ImmutableSet uses; + private final ImmutableSet> typeDefinitions; + private final ImmutableSet publicChildNodes; private final SemVer semanticVersion; - private Set>> - submoduleContextsToBuild; - private Set submodules; - private boolean sealed; - - protected AbstractEffectiveModule(final StmtContext> ctx) { + protected AbstractEffectiveModule( + final @NonNull StmtContext> ctx, + final @NonNull String prefix) { super(ctx); this.name = argument(); - - final EffectiveStatement parentOfPrefix; - if (ctx.getPublicDefinition() == YangStmtMapping.SUBMODULE) { - final Optional optParent = - findFirstEffectiveSubstatement(BelongsToEffectiveStatement.class); - SourceException.throwIf(!optParent.isPresent(), ctx.getStatementSourceReference(), - "Unable to find belongs-to statement in submodule %s.", ctx.getStatementArgument()); - parentOfPrefix = optParent.get(); - } else { - parentOfPrefix = this; - } - - final Optional<@NonNull PrefixEffectiveStatement> prefixStmt = parentOfPrefix.findFirstEffectiveSubstatement( - PrefixEffectiveStatement.class); - SourceException.throwIf(!prefixStmt.isPresent(), ctx.getStatementSourceReference(), - "Unable to resolve prefix for module or submodule %s.", ctx.getStatementArgument()); - this.prefix = prefixStmt.get().argument(); + this.prefix = requireNonNull(prefix); this.yangVersion = findFirstEffectiveSubstatementArgument(YangVersionEffectiveStatement.class) .orElse(YangVersion.VERSION_1); this.semanticVersion = findFirstEffectiveSubstatementArgument(OpenConfigVersionEffectiveStatement.class) @@ -125,85 +96,21 @@ public abstract class AbstractEffectiveModule> substatementsOfSubmodules; - final Map> includedSubmodulesMap = ctx - .getAllFromCurrentStmtCtxNamespace(IncludedSubmoduleNameToModuleCtx.class); - - if (includedSubmodulesMap == null || includedSubmodulesMap.isEmpty()) { - this.submodules = ImmutableSet.of(); - this.submoduleContextsToBuild = ImmutableSet.of(); - substatementsOfSubmodules = ImmutableList.of(); - } else if (YangStmtMapping.MODULE.equals(ctx.getPublicDefinition())) { - /* - * Aggregation of substatements from submodules should be done only - * for modules. In case of submodules it does not make sense because - * of possible circular chains of includes between submodules. - */ - final Set submodulesInit = new HashSet<>(); - final List> substatementsOfSubmodulesInit = new ArrayList<>(); - for (final StmtContext submoduleCtx : includedSubmodulesMap.values()) { - final EffectiveStatement submodule = submoduleCtx.buildEffective(); - Verify.verify(submodule instanceof SubmoduleEffectiveStatement); - Verify.verify(submodule instanceof Module, "Submodule statement %s is not a Module", submodule); - submodulesInit.add((Module) submodule); - substatementsOfSubmodulesInit.addAll(submodule.effectiveSubstatements().stream() - .filter(sub -> sub instanceof SchemaNode || sub instanceof DataNodeContainer) - .collect(Collectors.toList())); - } - - this.submodules = ImmutableSet.copyOf(submodulesInit); - this.submoduleContextsToBuild = ImmutableSet.of(); - substatementsOfSubmodules = ImmutableList.copyOf(substatementsOfSubmodulesInit); - } else { - /* - * Because of possible circular chains of includes between submodules we can - * collect only submodule contexts here and then build them during - * sealing of this statement. - */ - final Set>> - submoduleContextsInit = new HashSet<>(); - for (final StmtContext submoduleCtx : includedSubmodulesMap.values()) { - submoduleContextsInit.add( - (StmtContext>)submoduleCtx); - } - - this.submoduleContextsToBuild = ImmutableSet.copyOf(submoduleContextsInit); - substatementsOfSubmodules = ImmutableList.of(); - } - - if (!submoduleContextsToBuild.isEmpty()) { - ((Mutable) ctx).addMutableStmtToSeal(this); - sealed = false; - } else { - sealed = true; - } - - // init substatements collections - final List> effectiveSubstatements = new ArrayList<>(); - effectiveSubstatements.addAll(effectiveSubstatements()); - effectiveSubstatements.addAll(substatementsOfSubmodules); - - final List unknownNodesInit = new ArrayList<>(); final Set augmentationsInit = new LinkedHashSet<>(); - final Set importsInit = new HashSet<>(); - final Set notificationsInit = new HashSet<>(); - final Set rpcsInit = new HashSet<>(); - final Set deviationsInit = new HashSet<>(); - final Set identitiesInit = new HashSet<>(); - final Set featuresInit = new HashSet<>(); + final Set importsInit = new LinkedHashSet<>(); + final Set notificationsInit = new LinkedHashSet<>(); + final Set rpcsInit = new LinkedHashSet<>(); + final Set deviationsInit = new LinkedHashSet<>(); + final Set identitiesInit = new LinkedHashSet<>(); + final Set featuresInit = new LinkedHashSet<>(); final List extensionNodesInit = new ArrayList<>(); - final Map mutableChildNodes = new LinkedHashMap<>(); - final Set mutableGroupings = new HashSet<>(); - final Set mutableUses = new HashSet<>(); + final Set mutableGroupings = new LinkedHashSet<>(); + final Set mutableUses = new LinkedHashSet<>(); final Set> mutableTypeDefinitions = new LinkedHashSet<>(); final Set mutablePublicChildNodes = new LinkedHashSet<>(); - for (final EffectiveStatement effectiveStatement : effectiveSubstatements) { - if (effectiveStatement instanceof UnknownSchemaNode) { - unknownNodesInit.add((UnknownSchemaNode) effectiveStatement); - } + for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { if (effectiveStatement instanceof AugmentationSchemaNode) { augmentationsInit.add((AugmentationSchemaNode) effectiveStatement); } @@ -229,42 +136,23 @@ public abstract class AbstractEffectiveModule type = typeDef.getTypeDefinition(); - if (!mutableTypeDefinitions.contains(type)) { - mutableTypeDefinitions.add(type); - } else { + final TypeDefinition type = ((TypedefEffectiveStatement) effectiveStatement).getTypeDefinition(); + if (!mutableTypeDefinitions.add(type)) { throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); } } - if (effectiveStatement instanceof GroupingDefinition) { - final GroupingDefinition grp = (GroupingDefinition) effectiveStatement; - if (!mutableGroupings.contains(grp)) { - mutableGroupings.add(grp); - } else { - throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); - } + if (effectiveStatement instanceof GroupingDefinition + && !mutableGroupings.add((GroupingDefinition) effectiveStatement)) { + throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, effectiveStatement); } } - this.unknownNodes = ImmutableList.copyOf(unknownNodesInit); this.augmentations = ImmutableSet.copyOf(augmentationsInit); this.imports = ImmutableSet.copyOf(importsInit); this.notifications = ImmutableSet.copyOf(notificationsInit); @@ -274,12 +162,10 @@ public abstract class AbstractEffectiveModule getImports() { + public Collection getImports() { return imports; } @Override - public Set getSubmodules() { - checkState(sealed, "Attempt to get base submodules from unsealed submodule effective statement %s", - getQNameModule()); - return submodules; - } - - @Override - public Set getFeatures() { + public Collection getFeatures() { return features; } @Override - public Set getNotifications() { + public Collection getNotifications() { return notifications; } @Override - public Set getAugmentations() { + public Collection getAugmentations() { return augmentations; } @Override - public Set getRpcs() { + public Collection getRpcs() { return rpcs; } @Override - public Set getDeviations() { + public Collection getDeviations() { return deviations; } @Override - public List getExtensionSchemaNodes() { + public Collection getExtensionSchemaNodes() { return extensionNodes; } @Override - public Set getIdentities() { + public Collection getIdentities() { return identities; } @Override - public List getUnknownSchemaNodes() { - return unknownNodes; - } - - @Override - public final Set> getTypeDefinitions() { + public final Collection> getTypeDefinitions() { return typeDefinitions; } @Override - public final Set getChildNodes() { + public final Collection getChildNodes() { return publicChildNodes; } @Override - public final Set getGroupings() { + public final Collection getGroupings() { return groupings; } @Override @SuppressWarnings("checkstyle:hiddenField") public final Optional findDataChildByName(final QName name) { - // Child nodes are keyed by their container name, so we can do a direct lookup - return Optional.ofNullable(childNodes.get(requireNonNull(name))); + return findDataSchemaNode(name); } @Override - public Set getUses() { + public Collection getUses() { return uses; } @@ -412,13 +285,23 @@ public abstract class AbstractEffectiveModule (Module) ctx.buildEffective())); - submoduleContextsToBuild = ImmutableSet.of(); - sealed = true; - } + protected static final @NonNull String findPrefix(final @NonNull StmtContext ctx, + final String type, final String name) { + return SourceException.throwIfNull( + StmtContextUtils.firstAttributeOf(ctx.declaredSubstatements(), PrefixStatement.class), + ctx.getStatementSourceReference(), "Unable to resolve prefix for %s %s.", type, name); + } + + // Alright. this is quite ugly + protected final void appendPrefixes(final StmtContext ctx, + final Builder builder) { + streamEffectiveSubstatements(ImportEffectiveStatement.class) + .map(imp -> imp.findFirstEffectiveSubstatementArgument(PrefixEffectiveStatement.class).get()) + .forEach(pfx -> { + final StmtContext importedCtx = + verifyNotNull(ctx.getFromNamespace(ImportPrefixToModuleCtx.class, pfx), + "Failed to resolve prefix %s", pfx); + builder.put(pfx, (ModuleEffectiveStatement) importedCtx.buildEffective()); + }); } }