/* * 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 java.util.Objects.requireNonNull; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.Maps; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import java.util.function.Function; 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.common.UnresolvedQName.Unqualified; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.Submodule; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; 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.FeatureEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.FeatureEffectiveStatementNamespace; 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.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.meta.EffectiveStmtCtx.Current; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToModuleCtx; final class ModuleEffectiveStatementImpl extends AbstractEffectiveModule implements Module, 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 ImmutableList submodules; ModuleEffectiveStatementImpl(final Current stmt, final ImmutableList> substatements, final Collection submodules, final QNameModule qnameModule) { super(stmt, substatements, findPrefix(stmt, substatements, "module", stmt.getRawArgument())); this.qnameModule = requireNonNull(qnameModule); this.submodules = ImmutableList.copyOf(submodules); final String localPrefix = findFirstEffectiveSubstatementArgument(PrefixEffectiveStatement.class).get(); final Builder prefixToModuleBuilder = ImmutableMap.builder(); prefixToModuleBuilder.put(localPrefix, this); appendPrefixes(stmt, prefixToModuleBuilder); 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 = stmt.localNamespacePortion(IncludedSubmoduleNameToModuleCtx.class); nameToSubmodule = includedSubmodules == null ? ImmutableMap.of() : ImmutableMap.copyOf(Maps.transformValues(includedSubmodules, submodule -> (SubmoduleEffectiveStatement) submodule.buildEffective())); qnameToExtension = substatements.stream() .filter(ExtensionEffectiveStatement.class::isInstance) .map(ExtensionEffectiveStatement.class::cast) .collect(ImmutableMap.toImmutableMap(ExtensionEffectiveStatement::argument, Function.identity())); qnameToFeature = substatements.stream() .filter(FeatureEffectiveStatement.class::isInstance) .map(FeatureEffectiveStatement.class::cast) .collect(ImmutableMap.toImmutableMap(FeatureEffectiveStatement::argument, Function.identity())); qnameToIdentity = substatements.stream() .filter(IdentityEffectiveStatement.class::isInstance) .map(IdentityEffectiveStatement.class::cast) .collect(ImmutableMap.toImmutableMap(IdentityEffectiveStatement::argument, Function.identity())); } @Override public ConformanceType conformance() { // FIXME: YANGTOOLS-837: provide an accurate value here return ConformanceType.IMPLEMENT; } @Override public QNameModule localQNameModule() { return qnameModule; } @Override public QNameModule getQNameModule() { return qnameModule; } @Override public Collection getSubmodules() { return submodules; } @Override public ModuleEffectiveStatement asEffectiveStatement() { return this; } @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); } }