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.reactor;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.base.Verify;
13 import java.util.Optional;
14 import org.opendaylight.yangtools.yang.common.QName;
15 import org.opendaylight.yangtools.yang.common.QNameModule;
16 import org.opendaylight.yangtools.yang.common.YangVersion;
17 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
18 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
19 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
20 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
21 import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
23 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
24 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
25 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
27 import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
28 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
31 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
32 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
33 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
35 final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends
36 StatementContextBase<A, D, E> {
37 private final StatementContextBase<?, ?, ?> parent;
38 private final A argument;
40 private volatile SchemaPath schemaPath;
42 SubstatementContext(final StatementContextBase<?, ?, ?> parent, final StatementDefinitionContext<A, D, E> def,
43 final StatementSourceReference ref, final String rawArgument) {
44 super(def, ref, rawArgument);
45 this.parent = requireNonNull(parent, "Parent must not be null");
46 this.argument = def.parseArgumentValue(this, rawStatementArgument());
49 SubstatementContext(final StatementContextBase<?, ?, ?> parent, final StatementDefinitionContext<A, D, E> def,
50 final StatementSourceReference ref, final String rawArgument, final A argument, final CopyType copyType) {
51 super(def, ref, rawArgument, copyType);
52 this.parent = requireNonNull(parent, "Parent must not be null");
53 this.argument = argument;
56 SubstatementContext(final StatementContextBase<A, D, E> original, final StatementContextBase<?, ?, ?> parent,
57 final CopyType copyType, final QNameModule targetModule) {
58 super(original, copyType);
59 this.parent = requireNonNull(parent, "Parent must not be null");
60 this.argument = targetModule == null ? original.getStatementArgument()
61 : original.definition().adaptArgumentValue(original, targetModule);
64 SubstatementContext(final StatementContextBase<A, D, E> original, final StatementContextBase<?, ?, ?> parent) {
66 this.parent = requireNonNull(parent, "Parent must not be null");
67 this.argument = original.getStatementArgument();
71 public StatementContextBase<?, ?, ?> getParentContext() {
76 public StorageNodeType getStorageNodeType() {
77 return StorageNodeType.STATEMENT_LOCAL;
81 public NamespaceStorageNode getParentNamespaceStorage() {
86 public Registry getBehaviourRegistry() {
87 return parent.getBehaviourRegistry();
91 public RootStatementContext<?, ?, ?> getRoot() {
92 return parent.getRoot();
96 public A getStatementArgument() {
100 private SchemaPath createSchemaPath() {
101 final Optional<SchemaPath> maybeParentPath = parent.getSchemaPath();
102 Verify.verify(maybeParentPath.isPresent(), "Parent %s does not have a SchemaPath", parent);
103 final SchemaPath parentPath = maybeParentPath.get();
105 if (StmtContextUtils.isUnknownStatement(this)) {
106 return parentPath.createChild(getPublicDefinition().getStatementName());
108 if (argument instanceof QName) {
109 final QName qname = (QName) argument;
110 if (StmtContextUtils.producesDeclared(this, UsesStatement.class)) {
111 return maybeParentPath.orElse(null);
114 return parentPath.createChild(qname);
116 if (argument instanceof String) {
117 // FIXME: This may yield illegal argument exceptions
118 final Optional<StmtContext<?, ?, ?>> originalCtx = getOriginalCtx();
119 final QName qname = StmtContextUtils.qnameFromArgument(originalCtx.orElse(this), (String) argument);
120 return parentPath.createChild(qname);
122 if (argument instanceof SchemaNodeIdentifier
123 && (StmtContextUtils.producesDeclared(this, AugmentStatement.class)
124 || StmtContextUtils.producesDeclared(this, RefineStatement.class)
125 || StmtContextUtils.producesDeclared(this, DeviationStatement.class))) {
127 return parentPath.createChild(((SchemaNodeIdentifier) argument).getPathFromRoot());
130 // FIXME: this does not look right
131 return maybeParentPath.orElse(null);
135 public Optional<SchemaPath> getSchemaPath() {
136 SchemaPath local = schemaPath;
138 synchronized (this) {
141 local = createSchemaPath();
147 return Optional.ofNullable(local);
151 public boolean isConfiguration() {
152 return isConfiguration(parent);
156 public boolean isEnabledSemanticVersioning() {
157 return parent.isEnabledSemanticVersioning();
161 public YangVersion getRootVersion() {
162 return getRoot().getRootVersion();
166 public void setRootVersion(final YangVersion version) {
167 getRoot().setRootVersion(version);
171 public void addMutableStmtToSeal(final MutableStatement mutableStatement) {
172 getRoot().addMutableStmtToSeal(mutableStatement);
176 public void addRequiredSource(final SourceIdentifier dependency) {
177 getRoot().addRequiredSource(dependency);
181 public void setRootIdentifier(final SourceIdentifier identifier) {
182 getRoot().setRootIdentifier(identifier);
186 protected boolean isIgnoringIfFeatures() {
187 return isIgnoringIfFeatures(parent);
191 protected boolean isIgnoringConfig() {
192 return isIgnoringConfig(parent);
196 protected boolean isParentSupportedByFeatures() {
197 return parent.isSupportedByFeatures();