2 * Copyright (c) 2015 Cisco Systems, Inc. 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.rfc7950.stmt.submodule;
10 import static com.google.common.base.Preconditions.checkState;
11 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
13 import com.google.common.collect.ImmutableSet;
14 import com.google.common.collect.Iterables;
15 import java.util.HashSet;
17 import java.util.Objects;
18 import java.util.Optional;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.opendaylight.yangtools.yang.common.QNameModule;
22 import org.opendaylight.yangtools.yang.common.Revision;
23 import org.opendaylight.yangtools.yang.model.api.Module;
24 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionEffectiveStatement;
27 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleEffectiveStatement;
28 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
29 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveModule;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
31 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
32 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
33 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
34 import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToModuleCtx;
35 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
36 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
38 final class SubmoduleEffectiveStatementImpl extends AbstractEffectiveModule<SubmoduleStatement>
39 implements SubmoduleEffectiveStatement, MutableStatement {
41 private final QNameModule qnameModule;
43 private Set<StmtContext<?, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>>> submoduleContexts;
44 private ImmutableSet<Module> submodules;
45 private boolean sealed;
47 SubmoduleEffectiveStatementImpl(final StmtContext<String, SubmoduleStatement, SubmoduleEffectiveStatement> ctx) {
48 super(ctx, findSubmodulePrefix(ctx));
50 final String belongsToModuleName = firstAttributeOf(ctx.declaredSubstatements(), BelongsToStatement.class);
51 final QNameModule belongsToModuleQName = ctx.getFromNamespace(ModuleNameToModuleQName.class,
54 final Optional<Revision> submoduleRevision = findFirstEffectiveSubstatementArgument(
55 RevisionEffectiveStatement.class);
56 this.qnameModule = QNameModule.create(belongsToModuleQName.getNamespace(), submoduleRevision).intern();
59 * Because of possible circular chains of includes between submodules we can
60 * collect only submodule contexts here and then build them during
61 * sealing of this statement.
63 final Map<String, StmtContext<?, ?, ?>> includedSubmodulesMap = ctx.getAllFromCurrentStmtCtxNamespace(
64 IncludedSubmoduleNameToModuleCtx.class);
65 if (includedSubmodulesMap != null) {
66 final Set<StmtContext<?, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>>>
67 submoduleContextsInit = new HashSet<>();
68 for (final StmtContext<?, ?, ?> submoduleCtx : includedSubmodulesMap.values()) {
69 submoduleContextsInit.add(
70 (StmtContext<?, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>>)submoduleCtx);
72 submoduleContexts = ImmutableSet.copyOf(submoduleContextsInit);
74 submoduleContexts = ImmutableSet.of();
77 if (!submoduleContexts.isEmpty()) {
78 ((Mutable<?, ?, ?>) ctx).addMutableStmtToSeal(this);
81 submodules = ImmutableSet.of();
87 public QNameModule getQNameModule() {
92 public Set<Module> getSubmodules() {
93 checkState(sealed, "Attempt to get base submodules from unsealed submodule effective statement %s",
99 public int hashCode() {
100 return Objects.hash(getName(), getYangVersion(), qnameModule);
104 public boolean equals(final Object obj) {
108 if (!(obj instanceof SubmoduleEffectiveStatementImpl)) {
111 final SubmoduleEffectiveStatementImpl other = (SubmoduleEffectiveStatementImpl) obj;
112 return Objects.equals(getName(), other.getName()) && qnameModule.equals(other.qnameModule)
113 && Objects.equals(getYangVersion(), other.getYangVersion());
119 submodules = ImmutableSet.copyOf(Iterables.transform(submoduleContexts,
120 ctx -> (Module) ctx.buildEffective()));
121 submoduleContexts = ImmutableSet.of();
126 private static @NonNull String findSubmodulePrefix(final StmtContext<String, ?, ?> ctx) {
127 final String name = ctx.getStatementArgument();
128 final StmtContext<?, ?, ?> belongsTo = SourceException.throwIfNull(
129 StmtContextUtils.findFirstDeclaredSubstatement(ctx, BelongsToStatement.class),
130 ctx.getStatementSourceReference(), "Unable to find belongs-to statement in submodule %s.", name);
131 return findPrefix(belongsTo, "submodule", name);