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