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.stmt.rfc6020;
10 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
13 import java.util.Optional;
14 import org.opendaylight.yangtools.concepts.SemVer;
15 import org.opendaylight.yangtools.yang.common.QNameModule;
16 import org.opendaylight.yangtools.yang.common.Revision;
17 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
18 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
19 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
20 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
21 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
23 import org.opendaylight.yangtools.yang.model.repo.api.SemVerSourceIdentifier;
24 import org.opendaylight.yangtools.yang.model.util.ModuleIdentifierImpl;
25 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
26 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
27 import org.opendaylight.yangtools.yang.parser.spi.PreLinkageModuleNamespace;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionModuleNamespace;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionNamespace;
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.meta.SubstatementValidator;
35 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToNamespace;
36 import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToModuleCtx;
37 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleIdentifier;
38 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
39 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
40 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToNamespace;
41 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo;
42 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
43 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
44 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
45 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ModuleEffectiveStatementImpl;
47 public class ModuleStatementSupport extends
48 AbstractStatementSupport<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> {
49 private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(YangStmtMapping
51 .addAny(YangStmtMapping.ANYXML)
52 .addAny(YangStmtMapping.AUGMENT)
53 .addAny(YangStmtMapping.CHOICE)
54 .addOptional(YangStmtMapping.CONTACT)
55 .addAny(YangStmtMapping.CONTAINER)
56 .addOptional(YangStmtMapping.DESCRIPTION)
57 .addAny(YangStmtMapping.DEVIATION)
58 .addAny(YangStmtMapping.EXTENSION)
59 .addAny(YangStmtMapping.FEATURE)
60 .addAny(YangStmtMapping.GROUPING)
61 .addAny(YangStmtMapping.IDENTITY)
62 .addAny(YangStmtMapping.IMPORT)
63 .addAny(YangStmtMapping.INCLUDE)
64 .addAny(YangStmtMapping.LEAF)
65 .addAny(YangStmtMapping.LEAF_LIST)
66 .addAny(YangStmtMapping.LIST)
67 .addMandatory(YangStmtMapping.NAMESPACE)
68 .addAny(YangStmtMapping.NOTIFICATION)
69 .addOptional(YangStmtMapping.ORGANIZATION)
70 .addMandatory(YangStmtMapping.PREFIX)
71 .addOptional(YangStmtMapping.REFERENCE)
72 .addAny(YangStmtMapping.REVISION)
73 .addAny(YangStmtMapping.RPC)
74 .addAny(YangStmtMapping.TYPEDEF)
75 .addAny(YangStmtMapping.USES)
76 .addOptional(YangStmtMapping.YANG_VERSION)
77 .addOptional(SupportedExtensionsMapping.OPENCONFIG_VERSION)
80 public ModuleStatementSupport() {
81 super(YangStmtMapping.MODULE);
85 public String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
90 public ModuleStatement createDeclared(final StmtContext<String, ModuleStatement, ?> ctx) {
91 return new ModuleStatementImpl(ctx);
95 public EffectiveStatement<String, ModuleStatement> createEffective(
96 final StmtContext<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> ctx) {
97 return new ModuleEffectiveStatementImpl(ctx);
101 public void onPreLinkageDeclared(final Mutable<String, ModuleStatement,
102 EffectiveStatement<String, ModuleStatement>> stmt) {
103 final String moduleName = stmt.getStatementArgument();
105 final URI moduleNs = firstAttributeOf(stmt.declaredSubstatements(), NamespaceStatement.class);
106 SourceException.throwIfNull(moduleNs, stmt.getStatementSourceReference(),
107 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
108 stmt.addToNs(ModuleNameToNamespace.class, moduleName, moduleNs);
110 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
111 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
112 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
113 stmt.addToNs(ImpPrefixToNamespace.class, modulePrefix, moduleNs);
115 stmt.addContext(PreLinkageModuleNamespace.class, moduleName, stmt);
117 final Optional<Revision> revisionDate = StmtContextUtils.getLatestRevision(stmt.declaredSubstatements());
118 final QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orElse(null)).intern();
120 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
121 stmt.setRootIdentifier(ModuleIdentifierImpl.create(stmt.getStatementArgument(), revisionDate));
125 public void onLinkageDeclared(final Mutable<String, ModuleStatement,
126 EffectiveStatement<String, ModuleStatement>> stmt) {
128 final Optional<URI> moduleNs = Optional.ofNullable(firstAttributeOf(stmt.declaredSubstatements(),
129 NamespaceStatement.class));
130 SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(),
131 "Namespace of the module [%s] is missing", stmt.getStatementArgument());
133 final Optional<Revision> revisionDate = StmtContextUtils.getLatestRevision(stmt.declaredSubstatements());
134 final QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern();
135 final StmtContext<?, ModuleStatement, EffectiveStatement<String, ModuleStatement>> possibleDuplicateModule =
136 stmt.getFromNamespace(NamespaceToModule.class, qNameModule);
137 if (possibleDuplicateModule != null && possibleDuplicateModule != stmt) {
138 throw new SourceException(stmt.getStatementSourceReference(), "Module namespace collision: %s. At %s",
139 qNameModule.getNamespace(), possibleDuplicateModule.getStatementSourceReference());
142 final ModuleIdentifier moduleIdentifier = ModuleIdentifierImpl.create(stmt.getStatementArgument(),
145 stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt);
146 stmt.addContext(ModuleNamespaceForBelongsTo.class, moduleIdentifier.getName(), stmt);
147 stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
149 final String modulePrefix = firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class);
150 SourceException.throwIfNull(modulePrefix, stmt.getStatementSourceReference(),
151 "Prefix of the module [%s] is missing", stmt.getStatementArgument());
153 stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule);
154 stmt.addToNs(ModuleNameToModuleQName.class, stmt.getStatementArgument(), qNameModule);
155 stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); // tu
156 stmt.addToNs(ModuleCtxToModuleIdentifier.class, stmt, moduleIdentifier);
157 stmt.addToNs(ModuleQNameToModuleName.class, qNameModule, stmt.getStatementArgument());
158 stmt.addToNs(ImportPrefixToModuleCtx.class, modulePrefix, stmt);
160 if (stmt.isEnabledSemanticVersioning()) {
161 addToSemVerModuleNamespace(stmt, moduleIdentifier);
165 private static void addToSemVerModuleNamespace(
166 final Mutable<String, ModuleStatement, EffectiveStatement<String, ModuleStatement>> stmt,
167 final ModuleIdentifier moduleIdentifier) {
168 final String moduleName = stmt.getStatementArgument();
169 final SemVer moduleSemVer = stmt.getFromNamespace(SemanticVersionNamespace.class, stmt);
170 final SemVerSourceIdentifier id = SemVerSourceIdentifier.create(moduleName, moduleSemVer);
171 stmt.addToNs(SemanticVersionModuleNamespace.class, id, stmt);
175 protected SubstatementValidator getSubstatementValidator() {
176 return SUBSTATEMENT_VALIDATOR;