Refactored uses statement handling in parser.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / UsesNodeBuilderImpl.java
1 /*
2  * Copyright (c) 2013 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.builder.impl;
9
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17
18 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
19 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
20 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
22 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.UsesNode;
24 import org.opendaylight.yangtools.yang.model.api.YangNode;
25 import org.opendaylight.yangtools.yang.parser.builder.api.AbstractBuilder;
26 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
27 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
28 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
29 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
30 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
31 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
32 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
33 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
34 import org.opendaylight.yangtools.yang.parser.util.RefineHolder;
35 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
36
37 public final class UsesNodeBuilderImpl extends AbstractBuilder implements UsesNodeBuilder {
38     private boolean isBuilt;
39     private UsesNodeImpl instance;
40     private DataNodeContainerBuilder parentBuilder;
41     private final String groupingName;
42     private SchemaPath groupingPath;
43     private GroupingDefinition groupingDefinition;
44     private GroupingBuilder groupingBuilder;
45     private boolean addedByUses;
46     private boolean augmenting;
47     private boolean resolved;
48     private AugmentationSchemaBuilder parentAugment;
49     private final Set<AugmentationSchema> augments = new HashSet<>();
50     private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<>();
51     private final List<SchemaNodeBuilder> refineBuilders = new ArrayList<>();
52     private final List<RefineHolder> refines = new ArrayList<>();
53
54     /**
55      * Copies of target grouping child nodes.
56      */
57     private final Set<DataSchemaNodeBuilder> targetChildren = new HashSet<>();
58
59     /**
60      * Copies of target grouping groupings.
61      */
62     private final Set<GroupingBuilder> targetGroupings = new HashSet<>();
63
64     /**
65      * Copies of target grouping typedefs.
66      */
67     private final Set<TypeDefinitionBuilder> targetTypedefs = new HashSet<>();
68
69     /**
70      * Copies of target grouping unknown nodes.
71      */
72     private final List<UnknownSchemaNodeBuilder> targetUnknownNodes = new ArrayList<>();
73
74     private final boolean isCopy;
75     private boolean dataCollected;
76
77     @Override
78     public boolean isCopy() {
79         return isCopy;
80     }
81
82     @Override
83     public boolean isDataCollected() {
84         return dataCollected;
85     }
86
87     @Override
88     public void setDataCollected(boolean dataCollected) {
89         this.dataCollected = dataCollected;
90     }
91
92     public UsesNodeBuilderImpl(final String moduleName, final int line, final String groupingName) {
93         super(moduleName, line);
94         this.groupingName = groupingName;
95         isCopy = false;
96     }
97
98     public UsesNodeBuilderImpl(final String moduleName, final int line, final String groupingName, final boolean isCopy) {
99         super(moduleName, line);
100         this.groupingName = groupingName;
101         this.isCopy = isCopy;
102     }
103
104     @Override
105     public UsesNode build(YangNode parent) {
106         if (!isBuilt) {
107             instance = new UsesNodeImpl(groupingPath);
108             instance.setAddedByUses(addedByUses);
109             instance.setParent(parent);
110
111             // AUGMENTATIONS
112             for (AugmentationSchemaBuilder builder : addedAugments) {
113                 augments.add(builder.build(instance));
114             }
115             instance.setAugmentations(augments);
116
117             // REFINES
118             final Map<SchemaPath, SchemaNode> refineNodes = new HashMap<>();
119             for (SchemaNodeBuilder refineBuilder : refineBuilders) {
120                 SchemaNode refineNode = refineBuilder.build(instance);
121                 refineNodes.put(refineNode.getPath(), refineNode);
122             }
123             instance.setRefines(refineNodes);
124
125             // UNKNOWN NODES
126             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
127                 unknownNodes.add(b.build(instance));
128             }
129             instance.setUnknownSchemaNodes(unknownNodes);
130
131             isBuilt = true;
132         }
133
134         return instance;
135     }
136
137     @Override
138     public DataNodeContainerBuilder getParent() {
139         return parentBuilder;
140     }
141
142     @Override
143     public void setParent(Builder parent) {
144         if (!(parent instanceof DataNodeContainerBuilder)) {
145             throw new YangParseException(moduleName, line,
146                     "Parent of 'uses' has to be instance of DataNodeContainerBuilder, but was: '" + parent + "'.");
147         }
148         this.parentBuilder = (DataNodeContainerBuilder) parent;
149     }
150
151     @Override
152     public SchemaPath getGroupingPath() {
153         return groupingPath;
154     }
155
156     @Override
157     public GroupingDefinition getGroupingDefinition() {
158         return groupingDefinition;
159     }
160
161     @Override
162     public void setGroupingDefinition(GroupingDefinition groupingDefinition) {
163         this.groupingDefinition = groupingDefinition;
164         if (groupingDefinition != null) {
165             this.groupingPath = groupingDefinition.getPath();
166         }
167     }
168
169     @Override
170     public GroupingBuilder getGroupingBuilder() {
171         return groupingBuilder;
172     }
173
174     @Override
175     public void setGrouping(GroupingBuilder grouping) {
176         this.groupingBuilder = grouping;
177         if (groupingBuilder != null) {
178             this.groupingPath = groupingBuilder.getPath();
179         }
180     }
181
182     @Override
183     public String getGroupingPathAsString() {
184         return groupingName;
185     }
186
187     @Override
188     public Set<AugmentationSchemaBuilder> getAugmentations() {
189         return addedAugments;
190     }
191
192     @Override
193     public void addAugment(final AugmentationSchemaBuilder augmentBuilder) {
194         addedAugments.add(augmentBuilder);
195     }
196
197     @Override
198     public boolean isAddedByUses() {
199         return addedByUses;
200     }
201     @Override
202     public void setAddedByUses(final boolean addedByUses) {
203         this.addedByUses = addedByUses;
204     }
205
206     @Override
207     public boolean isAugmenting() {
208         return augmenting;
209     }
210
211     @Override
212     public void setAugmenting(boolean augmenting) {
213         this.augmenting = augmenting;
214     }
215
216     @Override
217     public boolean isResolved() {
218         return resolved;
219     }
220
221     @Override
222     public void setResolved(boolean resolved) {
223         this.resolved = resolved;
224     }
225
226     @Override
227     public AugmentationSchemaBuilder getParentAugment() {
228         return parentAugment;
229     }
230
231     @Override
232     public void setParentAugment(AugmentationSchemaBuilder augment) {
233         this.parentAugment = augment;
234     }
235
236     @Override
237     public List<SchemaNodeBuilder> getRefineNodes() {
238         return refineBuilders;
239     }
240
241     @Override
242     public void addRefineNode(DataSchemaNodeBuilder refineNode) {
243         refineBuilders.add(refineNode);
244     }
245
246     @Override
247     public List<RefineHolder> getRefines() {
248         return refines;
249     }
250
251     @Override
252     public void addRefine(RefineHolder refine) {
253         refines.add(refine);
254     }
255
256     @Override
257     public Set<DataSchemaNodeBuilder> getTargetChildren() {
258         return targetChildren;
259     }
260
261     @Override
262     public Set<GroupingBuilder> getTargetGroupings() {
263         return targetGroupings;
264     }
265
266     @Override
267     public Set<TypeDefinitionBuilder> getTargetTypedefs() {
268         return targetTypedefs;
269     }
270
271     @Override
272     public List<UnknownSchemaNodeBuilder> getTargetUnknownNodes() {
273         return targetUnknownNodes;
274     }
275
276     @Override
277     public int hashCode() {
278         final int prime = 31;
279         int result = 1;
280         result = prime * result + ((groupingName == null) ? 0 : groupingName.hashCode());
281         result = prime * result + ((parentBuilder == null) ? 0 : parentBuilder.hashCode());
282         return result;
283     }
284
285     @Override
286     public boolean equals(Object obj) {
287         if (this == obj) {
288             return true;
289         }
290         if (obj == null) {
291             return false;
292         }
293         if (getClass() != obj.getClass()) {
294             return false;
295         }
296         UsesNodeBuilderImpl other = (UsesNodeBuilderImpl) obj;
297         if (groupingName == null) {
298             if (other.groupingName != null) {
299                 return false;
300             }
301         } else if (!groupingName.equals(other.groupingName)) {
302             return false;
303         }
304         if (parentBuilder == null) {
305             if (other.parentBuilder != null) {
306                 return false;
307             }
308         } else if (!parentBuilder.equals(other.parentBuilder)) {
309             return false;
310         }
311         return true;
312     }
313
314     @Override
315     public String toString() {
316         return "uses '" + groupingName + "'";
317     }
318
319     public final class UsesNodeImpl implements UsesNode {
320         private YangNode parent;
321         private final SchemaPath groupingPath;
322         private Set<AugmentationSchema> augmentations = Collections.emptySet();
323         private boolean addedByUses;
324         private Map<SchemaPath, SchemaNode> refines = Collections.emptyMap();
325         private List<UnknownSchemaNode> unknownNodes = Collections.emptyList();
326
327         @Override
328         public YangNode getParent() {
329             return parent;
330         }
331
332         private void setParent(YangNode parent) {
333             this.parent = parent;
334         }
335
336         private UsesNodeImpl(final SchemaPath groupingPath) {
337             this.groupingPath = groupingPath;
338         }
339
340         @Override
341         public SchemaPath getGroupingPath() {
342             return groupingPath;
343         }
344
345         @Override
346         public Set<AugmentationSchema> getAugmentations() {
347             return augmentations;
348         }
349
350         private void setAugmentations(final Set<AugmentationSchema> augmentations) {
351             if (augmentations != null) {
352                 this.augmentations = augmentations;
353             }
354         }
355
356         @Override
357         public boolean isAugmenting() {
358             return false;
359         }
360
361         @Override
362         public boolean isAddedByUses() {
363             return addedByUses;
364         }
365
366         private void setAddedByUses(final boolean addedByUses) {
367             this.addedByUses = addedByUses;
368         }
369
370         @Override
371         public Map<SchemaPath, SchemaNode> getRefines() {
372             return refines;
373         }
374
375         private void setRefines(Map<SchemaPath, SchemaNode> refines) {
376             if (refines != null) {
377                 this.refines = refines;
378             }
379         }
380
381         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
382             return unknownNodes;
383         }
384
385         private void setUnknownSchemaNodes(List<UnknownSchemaNode> unknownSchemaNodes) {
386             if (unknownSchemaNodes != null) {
387                 this.unknownNodes = unknownSchemaNodes;
388             }
389         }
390
391         public UsesNodeBuilder toBuilder() {
392             return UsesNodeBuilderImpl.this;
393         }
394
395         @Override
396         public int hashCode() {
397             final int prime = 31;
398             int result = 1;
399             result = prime * result + ((groupingPath == null) ? 0 : groupingPath.hashCode());
400             result = prime * result + ((augmentations == null) ? 0 : augmentations.hashCode());
401             return result;
402         }
403
404         @Override
405         public boolean equals(Object obj) {
406             if (this == obj) {
407                 return true;
408             }
409             if (obj == null) {
410                 return false;
411             }
412             if (getClass() != obj.getClass()) {
413                 return false;
414             }
415             final UsesNodeImpl other = (UsesNodeImpl) obj;
416             if (groupingPath == null) {
417                 if (other.groupingPath != null) {
418                     return false;
419                 }
420             } else if (!groupingPath.equals(other.groupingPath)) {
421                 return false;
422             }
423             if (augmentations == null) {
424                 if (other.augmentations != null) {
425                     return false;
426                 }
427             } else if (!augmentations.equals(other.augmentations)) {
428                 return false;
429             }
430             return true;
431         }
432
433         @Override
434         public String toString() {
435             StringBuilder sb = new StringBuilder(UsesNodeImpl.class.getSimpleName());
436             sb.append("[groupingPath=");
437             sb.append(groupingPath);
438             sb.append("]");
439             return sb.toString();
440         }
441     }
442
443 }