/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module; import static com.google.common.base.Verify.verifyNotNull; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatementNamespace; import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.FeatureEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.FeatureEffectiveStatementNamespace; import org.opendaylight.yangtools.yang.model.api.stmt.FeatureStatement; import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatementNamespace; import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement; 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.ModuleStatement; import org.opendaylight.yangtools.yang.model.api.stmt.PrefixEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleEffectiveStatement; import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveModule; import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace; import org.opendaylight.yangtools.yang.parser.spi.FeatureNamespace; import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToModuleCtx; import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToModuleCtx; import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName; final class ModuleEffectiveStatementImpl extends AbstractEffectiveModule implements ModuleEffectiveStatement { private final ImmutableMap nameToSubmodule; private final ImmutableMap qnameToExtension; private final ImmutableMap qnameToFeature; private final ImmutableMap qnameToIdentity; private final ImmutableMap prefixToModule; private final ImmutableMap namespaceToPrefix; private final @NonNull QNameModule qnameModule; private final ImmutableSet submodules; private ModuleEffectiveStatementImpl(final @NonNull ModuleStmtContext ctx) { super(ctx, findPrefix(ctx.delegate(), "module", ctx.getStatementArgument())); submodules = ctx.getSubmodules(); qnameModule = verifyNotNull(ctx.getFromNamespace(ModuleCtxToModuleQName.class, ctx.delegate())); final String localPrefix = findFirstEffectiveSubstatementArgument(PrefixEffectiveStatement.class).get(); final Builder prefixToModuleBuilder = ImmutableMap.builder(); prefixToModuleBuilder.put(localPrefix, this); streamEffectiveSubstatements(ImportEffectiveStatement.class) .map(imp -> imp.findFirstEffectiveSubstatementArgument(PrefixEffectiveStatement.class).get()) .forEach(prefix -> { final StmtContext importedCtx = verifyNotNull(ctx.getFromNamespace(ImportPrefixToModuleCtx.class, prefix), "Failed to resolve prefix %s", prefix); prefixToModuleBuilder.put(prefix, (ModuleEffectiveStatement) importedCtx.buildEffective()); }); prefixToModule = prefixToModuleBuilder.build(); final Map tmp = Maps.newLinkedHashMapWithExpectedSize(prefixToModule.size() + 1); tmp.put(qnameModule, localPrefix); for (Entry e : prefixToModule.entrySet()) { tmp.putIfAbsent(e.getValue().localQNameModule(), e.getKey()); } namespaceToPrefix = ImmutableMap.copyOf(tmp); final Map> includedSubmodules = ctx.getAllFromCurrentStmtCtxNamespace(IncludedSubmoduleNameToModuleCtx.class); nameToSubmodule = includedSubmodules == null ? ImmutableMap.of() : ImmutableMap.copyOf(Maps.transformValues(includedSubmodules, submodule -> (SubmoduleEffectiveStatement) submodule.buildEffective())); final Map> extensions = ctx.getAllFromCurrentStmtCtxNamespace(ExtensionNamespace.class); qnameToExtension = extensions == null ? ImmutableMap.of() : ImmutableMap.copyOf(Maps.transformValues(extensions, StmtContext::buildEffective)); final Map> features = ctx.getAllFromCurrentStmtCtxNamespace(FeatureNamespace.class); qnameToFeature = features == null ? ImmutableMap.of() : ImmutableMap.copyOf(Maps.transformValues(features, StmtContext::buildEffective)); final Map> identities = ctx.getAllFromCurrentStmtCtxNamespace(IdentityNamespace.class); qnameToIdentity = identities == null ? ImmutableMap.of() : ImmutableMap.copyOf(Maps.transformValues(identities, StmtContext::buildEffective)); } ModuleEffectiveStatementImpl(final StmtContext ctx) { this(ModuleStmtContext.create(ctx)); } @Override public @NonNull QNameModule localQNameModule() { return qnameModule; } @Override public @NonNull QNameModule getQNameModule() { return qnameModule; } @Override public ImmutableSet getSubmodules() { return submodules; } @Override @SuppressWarnings("unchecked") public > Optional> getNamespaceContents( final @NonNull Class namespace) { if (PrefixToEffectiveModuleNamespace.class.equals(namespace)) { return Optional.of((Map) prefixToModule); } if (QNameModuleToPrefixNamespace.class.equals(namespace)) { return Optional.of((Map) namespaceToPrefix); } if (NameToEffectiveSubmoduleNamespace.class.equals(namespace)) { return Optional.of((Map) nameToSubmodule); } if (ExtensionEffectiveStatementNamespace.class.equals(namespace)) { return Optional.of((Map) qnameToExtension); } if (FeatureEffectiveStatementNamespace.class.equals(namespace)) { return Optional.of((Map) qnameToFeature); } if (IdentityEffectiveStatementNamespace.class.equals(namespace)) { return Optional.of((Map) qnameToIdentity); } return super.getNamespaceContents(namespace); } @Override public int hashCode() { return Objects.hash(getName(), getYangVersion(), qnameModule); } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (!(obj instanceof ModuleEffectiveStatementImpl)) { return false; } ModuleEffectiveStatementImpl other = (ModuleEffectiveStatementImpl) obj; return Objects.equals(getName(), other.getName()) && qnameModule.equals(other.qnameModule) && Objects.equals(getYangVersion(), other.getYangVersion()); } }