Refactored uses statement handling in parser.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / GroupingBuilderImpl.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.Collections;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15 import java.util.TreeSet;
16
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
19 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
20 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
21 import org.opendaylight.yangtools.yang.model.api.Status;
22 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
23 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.UsesNode;
25 import org.opendaylight.yangtools.yang.model.api.YangNode;
26 import org.opendaylight.yangtools.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
27 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
28 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
29 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
30 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
31 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
32 import org.opendaylight.yangtools.yang.parser.util.Comparators;
33 import org.opendaylight.yangtools.yang.parser.util.CopyUtils;
34 import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
35 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
36
37 public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder implements GroupingBuilder {
38     private boolean isBuilt;
39     private final GroupingDefinitionImpl instance;
40     private SchemaPath schemaPath;
41     private String description;
42     private String reference;
43     private Status status = Status.CURRENT;
44     private boolean addedByUses;
45
46     public GroupingBuilderImpl(final String moduleName, final int line, final QName qname) {
47         super(moduleName, line, qname);
48         instance = new GroupingDefinitionImpl(qname);
49     }
50
51     @Override
52     public GroupingDefinition build(YangNode parent) {
53         if (!isBuilt) {
54             instance.setParent(parent);
55             instance.setPath(schemaPath);
56             instance.setDescription(description);
57             instance.setReference(reference);
58             instance.setStatus(status);
59             instance.setAddedByUses(addedByUses);
60
61             // CHILD NODES
62             for (DataSchemaNodeBuilder node : addedChildNodes) {
63                 DataSchemaNode child = node.build(instance);
64                 childNodes.put(child.getQName(), child);
65             }
66             instance.setChildNodes(childNodes);
67
68             // GROUPINGS
69             for (GroupingBuilder builder : addedGroupings) {
70                 groupings.add(builder.build(instance));
71             }
72             instance.setGroupings(groupings);
73
74             // TYPEDEFS
75             for (TypeDefinitionBuilder entry : addedTypedefs) {
76                 typedefs.add(entry.build(instance));
77             }
78             instance.setTypeDefinitions(typedefs);
79
80             // USES
81             for (UsesNodeBuilder builder : addedUsesNodes) {
82                 usesNodes.add(builder.build(instance));
83             }
84             instance.setUses(usesNodes);
85
86             // UNKNOWN NODES
87             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
88                 unknownNodes.add(b.build(instance));
89             }
90             Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
91             instance.setUnknownSchemaNodes(unknownNodes);
92
93             isBuilt = true;
94         }
95
96         return instance;
97     }
98
99     @Override
100     public Set<DataSchemaNodeBuilder> instantiateChildNodes(Builder newParent) {
101         final Set<DataSchemaNodeBuilder> nodes = new HashSet<>();
102         for (DataSchemaNodeBuilder node : addedChildNodes) {
103             DataSchemaNodeBuilder copy = CopyUtils.copy(node, newParent, true);
104             ParserUtils.setNodeAddedByUses(copy);
105             nodes.add(copy);
106         }
107         return nodes;
108     }
109
110     @Override
111     public Set<TypeDefinitionBuilder> instantiateTypedefs(Builder newParent) {
112         final Set<TypeDefinitionBuilder> nodes = new HashSet<>();
113         for (TypeDefinitionBuilder node : addedTypedefs) {
114             TypeDefinitionBuilder copy = CopyUtils.copy(node, newParent, true);
115             nodes.add(copy);
116         }
117         return nodes;
118     }
119
120     @Override
121     public Set<GroupingBuilder> instantiateGroupings(Builder newParent) {
122         final Set<GroupingBuilder> nodes = new HashSet<>();
123         for (GroupingBuilder node : addedGroupings) {
124             GroupingBuilder copy = CopyUtils.copy(node, newParent, true);
125             copy.setAddedByUses(true);
126             for (DataSchemaNodeBuilder childNode : copy.getChildNodeBuilders()) {
127                 ParserUtils.setNodeAddedByUses(childNode);
128             }
129             nodes.add(copy);
130         }
131         return nodes;
132     }
133
134     @Override
135     public Set<UnknownSchemaNodeBuilder> instantiateUnknownNodes(Builder newParent) {
136         final Set<UnknownSchemaNodeBuilder> nodes = new HashSet<>();
137         for (UnknownSchemaNodeBuilder node : addedUnknownNodes) {
138             UnknownSchemaNodeBuilder copy = CopyUtils.copy(node, newParent, true);
139             copy.setAddedByUses(true);
140             nodes.add(copy);
141         }
142         return nodes;
143     }
144
145     @Override
146     public void setQName(QName qname) {
147         this.qname = qname;
148     }
149
150     @Override
151     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
152         return addedTypedefs;
153     }
154
155     @Override
156     public void addTypedef(final TypeDefinitionBuilder type) {
157         String typeName = type.getQName().getLocalName();
158         for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
159             throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
160                     + "': typedef with same name already declared at line " + addedTypedef.getLine());
161         }
162         addedTypedefs.add(type);
163     }
164
165     public void setTypedefs(final Set<TypeDefinition<?>> typedefs) {
166         this.typedefs = typedefs;
167     }
168
169     @Override
170     public SchemaPath getPath() {
171         return schemaPath;
172     }
173
174     @Override
175     public void setPath(SchemaPath schemaPath) {
176         this.schemaPath = schemaPath;
177     }
178
179     @Override
180     public String getDescription() {
181         return description;
182     }
183
184     @Override
185     public void setDescription(final String description) {
186         this.description = description;
187     }
188
189     @Override
190     public String getReference() {
191         return reference;
192     }
193
194     @Override
195     public void setReference(final String reference) {
196         this.reference = reference;
197     }
198
199     @Override
200     public Status getStatus() {
201         return status;
202     }
203
204     @Override
205     public void setStatus(final Status status) {
206         this.status = status;
207     }
208
209     @Override
210     public boolean isAddedByUses() {
211         return addedByUses;
212     }
213
214     @Override
215     public void setAddedByUses(final boolean addedByUses) {
216         this.addedByUses = addedByUses;
217     }
218
219     @Override
220     public String toString() {
221         return "grouping " + qname.getLocalName();
222     }
223
224     @Override
225     public int hashCode() {
226         final int prime = 31;
227         int result = 1;
228         result = prime * result + ((parentBuilder == null) ? 0 : parentBuilder.hashCode());
229         result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
230         return result;
231     }
232
233     @Override
234     public boolean equals(Object obj) {
235         if (this == obj) {
236             return true;
237         }
238         if (obj == null) {
239             return false;
240         }
241         if (getClass() != obj.getClass()) {
242             return false;
243         }
244         if (!super.equals(obj)) {
245             return false;
246         }
247         final GroupingBuilderImpl other = (GroupingBuilderImpl) obj;
248         if (parentBuilder == null) {
249             if (other.parentBuilder != null) {
250                 return false;
251             }
252         } else if (!parentBuilder.equals(other.parentBuilder)) {
253             return false;
254         }
255         if (schemaPath == null) {
256             if (other.schemaPath != null) {
257                 return false;
258             }
259         } else if (!schemaPath.equals(other.schemaPath)) {
260             return false;
261         }
262         return true;
263     }
264
265
266     private final class GroupingDefinitionImpl implements GroupingDefinition {
267         private final QName qname;
268         private SchemaPath path;
269         private YangNode parent;
270         private String description;
271         private String reference;
272         private Status status;
273         private boolean addedByUses;
274         private Map<QName, DataSchemaNode> childNodes = Collections.emptyMap();
275         private Set<GroupingDefinition> groupings = Collections.emptySet();
276         private Set<TypeDefinition<?>> typeDefinitions = Collections.emptySet();
277         private Set<UsesNode> uses = Collections.emptySet();
278         private List<UnknownSchemaNode> unknownNodes = Collections.emptyList();
279
280         private GroupingDefinitionImpl(final QName qname) {
281             this.qname = qname;
282         }
283
284         @Override
285         public QName getQName() {
286             return qname;
287         }
288
289         @Override
290         public SchemaPath getPath() {
291             return path;
292         }
293
294         private void setPath(SchemaPath path) {
295             this.path = path;
296         }
297
298         @Override
299         public YangNode getParent() {
300             return parent;
301         }
302
303         private void setParent(YangNode parent) {
304             this.parent = parent;
305         }
306
307         @Override
308         public String getDescription() {
309             return description;
310         }
311
312         private void setDescription(String description) {
313             this.description = description;
314         }
315
316         @Override
317         public String getReference() {
318             return reference;
319         }
320
321         private void setReference(String reference) {
322             this.reference = reference;
323         }
324
325         @Override
326         public Status getStatus() {
327             return status;
328         }
329
330         private void setStatus(Status status) {
331             this.status = status;
332         }
333
334         @Override
335         public boolean isAddedByUses() {
336             return addedByUses;
337         }
338
339         private void setAddedByUses(final boolean addedByUses) {
340             this.addedByUses = addedByUses;
341         }
342
343         @Override
344         public Set<DataSchemaNode> getChildNodes() {
345             final Set<DataSchemaNode> result = new TreeSet<DataSchemaNode>(Comparators.SCHEMA_NODE_COMP);
346             result.addAll(childNodes.values());
347             return result;
348         }
349
350         private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {
351             this.childNodes = childNodes;
352         }
353
354         @Override
355         public Set<GroupingDefinition> getGroupings() {
356             return groupings;
357         }
358
359         private void setGroupings(Set<GroupingDefinition> groupings) {
360             this.groupings = groupings;
361         }
362
363         @Override
364         public Set<UsesNode> getUses() {
365             return uses;
366         }
367
368         private void setUses(Set<UsesNode> uses) {
369             this.uses = uses;
370         }
371
372         @Override
373         public Set<TypeDefinition<?>> getTypeDefinitions() {
374             return typeDefinitions;
375         }
376
377         private void setTypeDefinitions(Set<TypeDefinition<?>> typeDefinitions) {
378             this.typeDefinitions = typeDefinitions;
379         }
380
381         @Override
382         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
383             return unknownNodes;
384         }
385
386         private void setUnknownSchemaNodes(List<UnknownSchemaNode> unknownNodes) {
387             if (unknownNodes != null) {
388                 this.unknownNodes = unknownNodes;
389             }
390         }
391
392         @Override
393         public DataSchemaNode getDataChildByName(QName name) {
394             return childNodes.get(name);
395         }
396
397         @Override
398         public DataSchemaNode getDataChildByName(String name) {
399             DataSchemaNode result = null;
400             for (Map.Entry<QName, DataSchemaNode> entry : childNodes.entrySet()) {
401                 if (entry.getKey().getLocalName().equals(name)) {
402                     result = entry.getValue();
403                     break;
404                 }
405             }
406             return result;
407         }
408
409         @Override
410         public int hashCode() {
411             final int prime = 31;
412             int result = 1;
413             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
414             result = prime * result + ((path == null) ? 0 : path.hashCode());
415             return result;
416         }
417
418         @Override
419         public boolean equals(Object obj) {
420             if (this == obj) {
421                 return true;
422             }
423             if (obj == null) {
424                 return false;
425             }
426             if (getClass() != obj.getClass()) {
427                 return false;
428             }
429             final GroupingDefinitionImpl other = (GroupingDefinitionImpl) obj;
430             if (qname == null) {
431                 if (other.qname != null) {
432                     return false;
433                 }
434             } else if (!qname.equals(other.qname)) {
435                 return false;
436             }
437             if (path == null) {
438                 if (other.path != null) {
439                     return false;
440                 }
441             } else if (!path.equals(other.path)) {
442                 return false;
443             }
444             return true;
445         }
446
447         @Override
448         public String toString() {
449             StringBuilder sb = new StringBuilder(GroupingDefinitionImpl.class.getSimpleName());
450             sb.append("[");
451             sb.append("qname=" + qname);
452             sb.append("]");
453             return sb.toString();
454         }
455     }
456
457 }