2 * Copyright (c) 2013 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.util;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Date;
13 import java.util.List;
16 import java.util.TreeMap;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
20 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
21 import org.opendaylight.yangtools.yang.model.api.Module;
22 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
23 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
24 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
25 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
27 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
28 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
29 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
30 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
31 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
32 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
33 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
34 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
35 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
36 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
37 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
38 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
39 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
40 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
41 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
42 import org.opendaylight.yangtools.yang.model.util.BinaryType;
43 import org.opendaylight.yangtools.yang.model.util.BitsType;
44 import org.opendaylight.yangtools.yang.model.util.BooleanType;
45 import org.opendaylight.yangtools.yang.model.util.Decimal64;
46 import org.opendaylight.yangtools.yang.model.util.EmptyType;
47 import org.opendaylight.yangtools.yang.model.util.EnumerationType;
48 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
49 import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
50 import org.opendaylight.yangtools.yang.model.util.InstanceIdentifier;
51 import org.opendaylight.yangtools.yang.model.util.Leafref;
52 import org.opendaylight.yangtools.yang.model.util.StringType;
53 import org.opendaylight.yangtools.yang.model.util.UnionType;
54 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
55 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
56 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
57 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
58 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
59 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
60 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
61 import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
62 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
63 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
64 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
65 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder.ChoiceNodeImpl;
66 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
67 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder.ChoiceCaseNodeImpl;
68 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
69 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl;
70 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder;
71 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
72 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder.ListSchemaNodeImpl;
73 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
74 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder;
75 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder.NotificationDefinitionImpl;
76 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
78 public final class ParserUtils {
80 private ParserUtils() {
84 * Create new SchemaPath from given path and qname.
90 public static SchemaPath createSchemaPath(SchemaPath schemaPath, QName... qname) {
91 List<QName> path = new ArrayList<>(schemaPath.getPath());
92 path.addAll(Arrays.asList(qname));
93 return new SchemaPath(path, schemaPath.isAbsolute());
97 * Get module import referenced by given prefix.
102 * prefix associated with import
103 * @return ModuleImport based on given prefix
105 public static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) {
106 ModuleImport moduleImport = null;
107 for (ModuleImport mi : builder.getModuleImports()) {
108 if (mi.getPrefix().equals(prefix)) {
117 * Find dependent module based on given prefix
120 * all available modules
124 * target module prefix
126 * current line in yang model
127 * @return module builder if found, null otherwise
129 public static ModuleBuilder findDependentModuleBuilder(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
130 final ModuleBuilder module, final String prefix, final int line) {
131 ModuleBuilder dependentModule = null;
132 Date dependentModuleRevision = null;
134 if (prefix.equals(module.getPrefix())) {
135 dependentModule = module;
137 final ModuleImport dependentModuleImport = getModuleImport(module, prefix);
138 if (dependentModuleImport == null) {
139 throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'.");
141 final String dependentModuleName = dependentModuleImport.getModuleName();
142 dependentModuleRevision = dependentModuleImport.getRevision();
144 final TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules.get(dependentModuleName);
145 if (moduleBuildersByRevision == null) {
148 if (dependentModuleRevision == null) {
149 dependentModule = moduleBuildersByRevision.lastEntry().getValue();
151 dependentModule = moduleBuildersByRevision.get(dependentModuleRevision);
154 return dependentModule;
158 * Find module from context based on prefix.
162 * @param currentModule
165 * current prefix used to reference dependent module
167 * current line in yang model
168 * @return module based on given prefix if found in context, null otherwise
170 public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule,
171 final String prefix, final int line) {
172 TreeMap<Date, Module> modulesByRevision = new TreeMap<Date, Module>();
174 final ModuleImport dependentModuleImport = ParserUtils.getModuleImport(currentModule, prefix);
175 if (dependentModuleImport == null) {
176 throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'.");
178 final String dependentModuleName = dependentModuleImport.getModuleName();
179 final Date dependentModuleRevision = dependentModuleImport.getRevision();
181 for (Module contextModule : context.getModules()) {
182 if (contextModule.getName().equals(dependentModuleName)) {
183 Date revision = contextModule.getRevision();
184 if (revision == null) {
185 revision = new Date(0L);
187 modulesByRevision.put(revision, contextModule);
192 Module result = null;
193 if (dependentModuleRevision == null) {
194 result = modulesByRevision.get(modulesByRevision.firstKey());
196 result = modulesByRevision.get(dependentModuleRevision);
203 * Parse XPath string.
207 * @return SchemaPath from given String
209 public static SchemaPath parseXPathString(final String xpathString) {
210 final boolean absolute = xpathString.startsWith("/");
211 final String[] splittedPath = xpathString.split("/");
212 final List<QName> path = new ArrayList<QName>();
214 for (String pathElement : splittedPath) {
215 if (pathElement.length() > 0) {
216 final String[] splittedElement = pathElement.split(":");
217 if (splittedElement.length == 1) {
218 name = new QName(null, null, null, splittedElement[0]);
220 name = new QName(null, null, splittedElement[0], splittedElement[1]);
225 return new SchemaPath(path, absolute);
229 * Add all augment's child nodes to given target.
232 * builder of augment statement
234 * augmentation target node
236 public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final DataNodeContainerBuilder target) {
237 for (DataSchemaNodeBuilder child : augment.getChildNodeBuilders()) {
238 DataSchemaNodeBuilder childCopy = CopyUtils.copy(child, target, false);
239 childCopy.setAugmenting(true);
240 correctNodePath(child, target.getPath());
241 correctNodePath(childCopy, target.getPath());
243 target.addChildNode(childCopy);
244 } catch (YangParseException e) {
245 // more descriptive message
246 throw new YangParseException(augment.getModuleName(), augment.getLine(),
247 "Failed to perform augmentation: " + e.getMessage());
251 for (UsesNodeBuilder usesNode : augment.getUsesNodes()) {
252 UsesNodeBuilder copy = CopyUtils.copyUses(usesNode, target);
253 target.addUsesNode(copy);
258 * Add all augment's child nodes to given target.
261 * builder of augment statement
263 * augmentation target choice node
265 public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final ChoiceBuilder target) {
266 for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) {
267 DataSchemaNodeBuilder childCopy = CopyUtils.copy(builder, target, false);
268 childCopy.setAugmenting(true);
269 correctNodePath(builder, target.getPath());
270 correctNodePath(childCopy, target.getPath());
271 target.addCase(childCopy);
273 for (UsesNodeBuilder usesNode : augment.getUsesNodes()) {
274 if (usesNode != null) {
275 throw new YangParseException(augment.getModuleName(), augment.getLine(),
276 "Error in augment parsing: cannot augment uses to choice");
281 static void correctNodePath(final SchemaNodeBuilder node, final SchemaPath parentSchemaPath) {
283 List<QName> targetNodePath = new ArrayList<QName>(parentSchemaPath.getPath());
284 targetNodePath.add(node.getQName());
285 node.setPath(new SchemaPath(targetNodePath, true));
287 // set correct path for all child nodes
288 if (node instanceof DataNodeContainerBuilder) {
289 DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) node;
290 for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodeBuilders()) {
291 correctNodePath(child, node.getPath());
295 // set correct path for all cases
296 if (node instanceof ChoiceBuilder) {
297 ChoiceBuilder choiceBuilder = (ChoiceBuilder) node;
298 for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) {
299 correctNodePath(choiceCaseBuilder, node.getPath());
303 // if node can contains type, correct path for this type too
304 if (node instanceof TypeAwareBuilder) {
305 TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) node;
306 correctTypeAwareNodePath(nodeBuilder);
311 * Repair schema path of node type.
314 * node which contains type statement
315 * @param parentSchemaPath
316 * schema path of parent node
318 public static void correctTypeAwareNodePath(final TypeAwareBuilder node) {
319 final SchemaPath parentSchemaPath = node.getPath();
320 final TypeDefinition<?> nodeType = node.getType();
323 if (node instanceof UnionTypeBuilder) {
324 for (TypeDefinitionBuilder tdb : ((UnionTypeBuilder) node).getTypedefs()) {
325 SchemaPath newSchemaPath = createSchemaPath(node.getPath(), tdb.getQName());
326 tdb.setPath(newSchemaPath);
327 correctTypeAwareNodePath(tdb);
329 List<TypeDefinition<?>> oldTypes = ((UnionTypeBuilder) node).getTypes();
330 List<TypeDefinition<?>> newTypes = new ArrayList<>();
331 for (TypeDefinition<?> td : oldTypes) {
332 TypeDefinition<?> newType = createCorrectTypeDefinition(node.getPath(), td);
333 newTypes.add(newType);
336 oldTypes.addAll(newTypes);
340 // handle identityref type
341 if (node instanceof IdentityrefTypeBuilder) {
346 if (nodeType == null) {
347 TypeDefinitionBuilder nodeTypedef = node.getTypedef();
348 SchemaPath newSchemaPath = createSchemaPath(parentSchemaPath, nodeTypedef.getQName());
349 nodeTypedef.setPath(newSchemaPath);
350 correctTypeAwareNodePath(nodeTypedef);
352 TypeDefinition<?> newType = createCorrectTypeDefinition(parentSchemaPath, nodeType);
353 node.setType(newType);
358 public static TypeDefinition<?> createCorrectTypeDefinition(SchemaPath parentSchemaPath, TypeDefinition<?> nodeType) {
359 TypeDefinition<?> result = null;
361 if (nodeType != null) {
362 SchemaPath newSchemaPath = createSchemaPath(parentSchemaPath, nodeType.getQName());
364 if (nodeType instanceof BinaryTypeDefinition) {
365 BinaryTypeDefinition binType = (BinaryTypeDefinition) nodeType;
367 // List<Byte> bytes = (List<Byte>) binType.getDefaultValue();
368 // workaround to get rid of 'Unchecked cast' warning
369 List<Byte> bytes = new ArrayList<Byte>();
370 Object defaultValue = binType.getDefaultValue();
371 if (defaultValue instanceof List) {
372 for (Object o : List.class.cast(defaultValue)) {
373 if (o instanceof Byte) {
378 result = new BinaryType(newSchemaPath, bytes);
379 } else if (nodeType instanceof BitsTypeDefinition) {
380 BitsTypeDefinition bitsType = (BitsTypeDefinition) nodeType;
381 result = new BitsType(newSchemaPath, bitsType.getBits());
382 } else if (nodeType instanceof BooleanTypeDefinition) {
383 result = new BooleanType(newSchemaPath);
384 } else if (nodeType instanceof DecimalTypeDefinition) {
385 DecimalTypeDefinition decimalType = (DecimalTypeDefinition) nodeType;
386 result = new Decimal64(newSchemaPath, decimalType.getFractionDigits());
387 } else if (nodeType instanceof EmptyTypeDefinition) {
388 result = new EmptyType(newSchemaPath);
389 } else if (nodeType instanceof EnumTypeDefinition) {
390 EnumTypeDefinition enumType = (EnumTypeDefinition) nodeType;
391 result = new EnumerationType(newSchemaPath, (EnumPair) enumType.getDefaultValue(), enumType.getValues());
392 } else if (nodeType instanceof IdentityrefTypeDefinition) {
393 IdentityrefTypeDefinition idrefType = (IdentityrefTypeDefinition) nodeType;
394 result = new IdentityrefType(idrefType.getIdentity(), newSchemaPath);
395 } else if (nodeType instanceof InstanceIdentifierTypeDefinition) {
396 InstanceIdentifierTypeDefinition instIdType = (InstanceIdentifierTypeDefinition) nodeType;
397 return new InstanceIdentifier(newSchemaPath, instIdType.getPathStatement(),
398 instIdType.requireInstance());
399 } else if (nodeType instanceof StringTypeDefinition) {
400 result = new StringType(newSchemaPath);
401 } else if (nodeType instanceof IntegerTypeDefinition) {
402 result = TypeUtils.createNewIntType(newSchemaPath, (IntegerTypeDefinition) nodeType);
403 } else if (nodeType instanceof UnsignedIntegerTypeDefinition) {
404 result = TypeUtils.createNewUintType(newSchemaPath, (UnsignedIntegerTypeDefinition) nodeType);
405 } else if (nodeType instanceof LeafrefTypeDefinition) {
406 result = new Leafref(newSchemaPath, ((LeafrefTypeDefinition) nodeType).getPathStatement());
407 } else if (nodeType instanceof UnionTypeDefinition) {
408 UnionTypeDefinition unionType = (UnionTypeDefinition) nodeType;
409 return new UnionType(newSchemaPath, unionType.getTypes());
410 } else if (nodeType instanceof ExtendedType) {
411 ExtendedType extType = (ExtendedType) nodeType;
412 result = TypeUtils.createNewExtendedType(extType, newSchemaPath);
419 * Find augment target node and perform augmentation.
422 * @param firstNodeParent
423 * parent of first node in path
425 * path to augment target
426 * @return true if augment process succeed, false otherwise
428 public static boolean processAugmentation(final AugmentationSchemaBuilder augment, final Builder firstNodeParent,
429 final List<QName> path) {
430 // traverse augment target path and try to reach target node
431 String currentName = null;
432 Builder currentParent = firstNodeParent;
434 for (int i = 0; i < path.size(); i++) {
435 QName qname = path.get(i);
437 currentName = qname.getLocalName();
438 if (currentParent instanceof DataNodeContainerBuilder) {
439 DataSchemaNodeBuilder nodeFound = ((DataNodeContainerBuilder) currentParent)
440 .getDataChildByName(currentName);
441 // if not found as regular child, search in uses
442 if (nodeFound == null) {
443 boolean found = false;
444 for (UsesNodeBuilder unb : ((DataNodeContainerBuilder) currentParent).getUsesNodes()) {
445 DataSchemaNodeBuilder result = findNodeInUses(currentName, unb);
446 if (result != null) {
447 currentParent = result;
452 // if not found even in uses nodes, return false
457 currentParent = nodeFound;
459 } else if (currentParent instanceof ChoiceBuilder) {
460 currentParent = ((ChoiceBuilder) currentParent).getCaseNodeByName(currentName);
462 throw new YangParseException(augment.getModuleName(), augment.getLine(),
463 "Error in augment parsing: failed to find node " + currentName);
466 // if node in path not found, return false
467 if (currentParent == null) {
471 if (!(currentParent instanceof DataSchemaNodeBuilder)) {
472 throw new YangParseException(
473 augment.getModuleName(),
475 "Error in augment parsing: The target node MUST be either a container, list, choice, case, input, output, or notification node.");
478 if (currentParent instanceof ChoiceBuilder) {
479 fillAugmentTarget(augment, (ChoiceBuilder) currentParent);
481 fillAugmentTarget(augment, (DataNodeContainerBuilder) currentParent);
483 ((AugmentationTargetBuilder) currentParent).addAugmentation(augment);
484 SchemaPath oldPath = ((DataSchemaNodeBuilder) currentParent).getPath();
485 augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
486 augment.setResolved(true);
491 private static DataSchemaNodeBuilder findNodeInUses(String localName, UsesNodeBuilder uses) {
492 GroupingBuilder target = uses.getGroupingBuilder();
493 for (DataSchemaNodeBuilder child : target.getChildNodeBuilders()) {
494 if (child.getQName().getLocalName().equals(localName)) {
498 for (UsesNodeBuilder usesNode : target.getUsesNodes()) {
499 DataSchemaNodeBuilder result = findNodeInUses(localName, usesNode);
500 if (result != null) {
508 * Find augment target node in given context and perform augmentation.
512 * path to augment target
516 * current prefix of target module
518 * SchemaContext containing already resolved modules
519 * @return true if augment process succeed, false otherwise
521 public static boolean processAugmentationOnContext(final AugmentationSchemaBuilder augment, final List<QName> path,
522 final ModuleBuilder module, final String prefix, final SchemaContext context) {
523 final int line = augment.getLine();
524 final Module dependentModule = findModuleFromContext(context, module, prefix, line);
525 if (dependentModule == null) {
526 throw new YangParseException(module.getName(), line,
527 "Error in augment parsing: failed to find module with prefix " + prefix + ".");
530 String currentName = path.get(0).getLocalName();
531 SchemaNode currentParent = dependentModule.getDataChildByName(currentName);
532 if (currentParent == null) {
533 Set<NotificationDefinition> notifications = dependentModule.getNotifications();
534 for (NotificationDefinition ntf : notifications) {
535 if (ntf.getQName().getLocalName().equals(currentName)) {
541 if (currentParent == null) {
542 throw new YangParseException(module.getName(), line, "Error in augment parsing: failed to find node "
543 + currentName + ".");
546 for (int i = 1; i < path.size(); i++) {
547 currentName = path.get(i).getLocalName();
548 if (currentParent instanceof DataNodeContainer) {
549 currentParent = ((DataNodeContainer) currentParent).getDataChildByName(currentName);
550 } else if (currentParent instanceof ChoiceNode) {
551 currentParent = ((ChoiceNode) currentParent).getCaseNodeByName(currentName);
553 throw new YangParseException(augment.getModuleName(), line,
554 "Error in augment parsing: failed to find node " + currentName);
556 // if node in path not found, return false
557 if (currentParent == null) {
558 throw new YangParseException(module.getName(), line, "Error in augment parsing: failed to find node "
559 + currentName + ".");
563 if (currentParent instanceof ContainerSchemaNodeImpl) {
564 // includes container, input and output statement
565 ContainerSchemaNodeImpl c = (ContainerSchemaNodeImpl) currentParent;
566 ContainerSchemaNodeBuilder cb = c.toBuilder();
567 fillAugmentTarget(augment, cb);
568 ((AugmentationTargetBuilder) cb).addAugmentation(augment);
569 SchemaPath oldPath = cb.getPath();
571 augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
572 augment.setResolved(true);
573 } else if (currentParent instanceof ListSchemaNodeImpl) {
574 ListSchemaNodeImpl l = (ListSchemaNodeImpl) currentParent;
575 ListSchemaNodeBuilder lb = l.toBuilder();
576 fillAugmentTarget(augment, lb);
577 ((AugmentationTargetBuilder) lb).addAugmentation(augment);
578 SchemaPath oldPath = lb.getPath();
580 augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
581 augment.setResolved(true);
582 } else if (currentParent instanceof ChoiceNodeImpl) {
583 ChoiceNodeImpl ch = (ChoiceNodeImpl) currentParent;
584 ChoiceBuilder chb = ch.toBuilder();
585 fillAugmentTarget(augment, chb);
586 ((AugmentationTargetBuilder) chb).addAugmentation(augment);
587 SchemaPath oldPath = chb.getPath();
589 augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
590 augment.setResolved(true);
591 } else if (currentParent instanceof ChoiceCaseNodeImpl) {
592 ChoiceCaseNodeImpl chc = (ChoiceCaseNodeImpl) currentParent;
593 ChoiceCaseBuilder chcb = chc.toBuilder();
594 fillAugmentTarget(augment, chcb);
595 ((AugmentationTargetBuilder) chcb).addAugmentation(augment);
596 SchemaPath oldPath = chcb.getPath();
598 augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
599 augment.setResolved(true);
600 } else if (currentParent instanceof NotificationDefinitionImpl) {
601 NotificationDefinitionImpl nd = (NotificationDefinitionImpl) currentParent;
602 NotificationBuilder nb = nd.toBuilder();
603 fillAugmentTarget(augment, nb);
604 ((AugmentationTargetBuilder) nb).addAugmentation(augment);
605 SchemaPath oldPath = nb.getPath();
607 augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
608 augment.setResolved(true);
610 throw new YangParseException(module.getName(), line, "Target of type " + currentParent.getClass()
611 + " cannot be augmented.");
617 public static QName findFullQName(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
618 final ModuleBuilder module, final IdentityrefTypeBuilder idref) {
620 String baseString = idref.getBaseString();
621 if (baseString.contains(":")) {
622 String[] splittedBase = baseString.split(":");
623 if (splittedBase.length > 2) {
624 throw new YangParseException(module.getName(), idref.getLine(), "Failed to parse identityref base: "
627 String prefix = splittedBase[0];
628 String name = splittedBase[1];
629 ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix, idref.getLine());
630 result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name);
632 result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString);
638 * Get module in which this node is defined.
641 * @return builder of module where this node is defined
643 public static ModuleBuilder getParentModule(Builder node) {
644 if(node instanceof ModuleBuilder) {
645 return (ModuleBuilder)node;
648 Builder parent = node.getParent();
649 while (!(parent instanceof ModuleBuilder)) {
650 parent = parent.getParent();
652 return (ModuleBuilder) parent;