Bug 2366 - Effective statement implementation
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / SubstatementContext.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
9
10 import java.util.List;
11 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.GroupingUtils;
12 import org.opendaylight.yangtools.yang.common.QNameModule;
13 import java.util.Collection;
14 import org.opendaylight.yangtools.yang.common.QName;
15 import com.google.common.base.Preconditions;
16 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
17 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
18 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
19 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
20 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
21
22 class SubstatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
23         extends StatementContextBase<A, D, E> {
24
25     private final StatementContextBase<?, ?, ?> parent;
26     private final A argument;
27
28     SubstatementContext(StatementContextBase<?, ?, ?> parent,
29             ContextBuilder<A, D, E> builder) throws SourceException {
30         super(builder);
31         this.parent = Preconditions.checkNotNull(parent,
32                 "Parent must not be null");
33         this.argument = builder.getDefinition().parseArgumentValue(this,
34                 builder.getRawArgument());
35     }
36
37     SubstatementContext(SubstatementContext<A, D, E> original,
38             QNameModule newQNameModule,
39             StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
40             throws SourceException {
41         super(original);
42         this.parent = newParent;
43
44         if (newQNameModule != null && original.argument instanceof QName) {
45             QName originalQName = (QName) original.argument;
46             this.argument = (A) QName.create(newQNameModule,
47                     originalQName.getLocalName());
48         } else {
49             this.argument = original.argument;
50         }
51
52         copyDeclaredStmts(original, newQNameModule, typeOfCopy);
53
54         copyEffectiveStmts(original, newQNameModule, typeOfCopy);
55     }
56
57     private void copyDeclaredStmts(SubstatementContext<A, D, E> original,
58             QNameModule newQNameModule, TypeOfCopy typeOfCopy)
59             throws SourceException {
60         Collection<? extends StatementContextBase<?, ?, ?>> originalDeclaredSubstatements = original
61                 .declaredSubstatements();
62         for (StatementContextBase<?, ?, ?> stmtContext : originalDeclaredSubstatements) {
63             if (GroupingUtils.needToCopyByUses(stmtContext)) {
64                 StatementContextBase<?, ?, ?> copy = stmtContext.createCopy(
65                         newQNameModule, this, typeOfCopy);
66                 this.addEffectiveSubstatement(copy);
67             } else if (GroupingUtils.isReusedByUses(stmtContext)) {
68                 this.addEffectiveSubstatement(stmtContext);
69             }
70         }
71     }
72
73     private void copyEffectiveStmts(SubstatementContext<A, D, E> original,
74             QNameModule newQNameModule, TypeOfCopy typeOfCopy)
75             throws SourceException {
76         Collection<? extends StatementContextBase<?, ?, ?>> originalEffectiveSubstatements = original
77                 .effectiveSubstatements();
78         for (StatementContextBase<?, ?, ?> stmtContext : originalEffectiveSubstatements) {
79             if (GroupingUtils.needToCopyByUses(stmtContext)) {
80                 StatementContextBase<?, ?, ?> copy = stmtContext.createCopy(
81                         newQNameModule, this, typeOfCopy);
82                 this.addEffectiveSubstatement(copy);
83             } else if (GroupingUtils.isReusedByUses(stmtContext)) {
84                 this.addEffectiveSubstatement(stmtContext);
85             }
86         }
87     }
88
89     @Override
90     public StatementContextBase<?, ?, ?> getParentContext() {
91         return parent;
92     }
93
94     @Override
95     public NamespaceStorageNode getParentNamespaceStorage() {
96         return parent;
97     }
98
99     @Override
100     public Registry getBehaviourRegistry() {
101         return parent.getBehaviourRegistry();
102     }
103
104     @Override
105     public RootStatementContext<?, ?, ?> getRoot() {
106         return parent.getRoot();
107     }
108
109     @Override
110     public A getStatementArgument() {
111         return argument;
112     }
113
114     @Override
115     public StatementContextBase<A, D, E> createCopy(QNameModule newQNameModule,
116             StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
117             throws SourceException {
118         SubstatementContext<A, D, E> copy = new SubstatementContext<>(this,
119                 newQNameModule, newParent, typeOfCopy);
120         copy.setTypeOfCopy(typeOfCopy);
121         copy.setOriginalCtx(this);
122         return copy;
123     }
124
125     @Override
126     public List<Object> getArgumentsFromRoot() {
127         List<Object> argumentsFromRoot = parent.getArgumentsFromRoot();
128         argumentsFromRoot.add(argument);
129         return argumentsFromRoot;
130     }
131
132     @Override
133     public boolean isRootContext() {
134         return false;
135     }
136 }