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;
11 import java.util.ArrayList;
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.AnyXmlSchemaNode;
20 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
21 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
22 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
24 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
26 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.Module;
30 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
31 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
32 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
33 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
37 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
38 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
40 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
41 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
42 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
43 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
44 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
45 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
46 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
47 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
48 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
49 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
50 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
51 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
52 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
53 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
54 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
55 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
56 import org.opendaylight.yangtools.yang.model.util.BinaryType;
57 import org.opendaylight.yangtools.yang.model.util.BitsType;
58 import org.opendaylight.yangtools.yang.model.util.BooleanType;
59 import org.opendaylight.yangtools.yang.model.util.Decimal64;
60 import org.opendaylight.yangtools.yang.model.util.EmptyType;
61 import org.opendaylight.yangtools.yang.model.util.EnumerationType;
62 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
63 import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
64 import org.opendaylight.yangtools.yang.model.util.InstanceIdentifier;
65 import org.opendaylight.yangtools.yang.model.util.Int16;
66 import org.opendaylight.yangtools.yang.model.util.Int32;
67 import org.opendaylight.yangtools.yang.model.util.Int64;
68 import org.opendaylight.yangtools.yang.model.util.Int8;
69 import org.opendaylight.yangtools.yang.model.util.Leafref;
70 import org.opendaylight.yangtools.yang.model.util.StringType;
71 import org.opendaylight.yangtools.yang.model.util.Uint16;
72 import org.opendaylight.yangtools.yang.model.util.Uint32;
73 import org.opendaylight.yangtools.yang.model.util.Uint64;
74 import org.opendaylight.yangtools.yang.model.util.Uint8;
75 import org.opendaylight.yangtools.yang.model.util.UnionType;
76 import org.opendaylight.yangtools.yang.model.util.UnknownType;
77 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
78 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
79 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
80 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
81 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
82 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
83 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingMember;
84 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
85 import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
86 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
87 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
88 import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
89 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
90 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder.ChoiceNodeImpl;
91 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
92 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder.ChoiceCaseNodeImpl;
93 import org.opendaylight.yangtools.yang.parser.builder.impl.ConstraintsBuilder;
94 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
95 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl;
96 import org.opendaylight.yangtools.yang.parser.builder.impl.GroupingBuilderImpl;
97 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder;
98 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
99 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
100 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
101 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder.ListSchemaNodeImpl;
102 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
103 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder;
104 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder.NotificationDefinitionImpl;
105 import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
106 import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
107 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
108 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
110 public final class ParserUtils {
112 private ParserUtils() {
116 * Create new SchemaPath from given path and name.
118 * Append new qname to schema path created from name argument.
124 public static SchemaPath createSchemaPath(SchemaPath schemaPath, String name, URI namespace, Date revision, String prefix) {
125 List<QName> path = new ArrayList<QName>();
126 if(schemaPath != null) {
127 path.addAll(schemaPath.getPath());
129 QName newQName = new QName(namespace, revision, prefix, name);
131 boolean abs = schemaPath == null ? true : schemaPath.isAbsolute();
132 return new SchemaPath(path, abs);
136 * Get module import referenced by given prefix.
141 * prefix associated with import
142 * @return ModuleImport based on given prefix
144 public static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) {
145 ModuleImport moduleImport = null;
146 for (ModuleImport mi : builder.getModuleImports()) {
147 if (mi.getPrefix().equals(prefix)) {
156 * Find dependent module based on given prefix
159 * all available modules
163 * target module prefix
165 * current line in yang model
168 public static ModuleBuilder findDependentModuleBuilder(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
169 final ModuleBuilder module, final String prefix, final int line) {
170 ModuleBuilder dependentModule = null;
171 Date dependentModuleRevision = null;
173 if (prefix.equals(module.getPrefix())) {
174 dependentModule = module;
176 final ModuleImport dependentModuleImport = getModuleImport(module, prefix);
177 if (dependentModuleImport == null) {
178 throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'.");
180 final String dependentModuleName = dependentModuleImport.getModuleName();
181 dependentModuleRevision = dependentModuleImport.getRevision();
183 final TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules.get(dependentModuleName);
184 if (moduleBuildersByRevision == null) {
187 if (dependentModuleRevision == null) {
188 dependentModule = moduleBuildersByRevision.lastEntry().getValue();
190 dependentModule = moduleBuildersByRevision.get(dependentModuleRevision);
193 return dependentModule;
197 * Find module from context based on prefix.
201 * @param currentModule
204 * current prefix used to reference dependent module
206 * current line in yang model
207 * @return module based on given prefix if found in context, null otherwise
209 public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule,
210 final String prefix, final int line) {
211 TreeMap<Date, Module> modulesByRevision = new TreeMap<Date, Module>();
213 Date dependentModuleRevision = null;
215 final ModuleImport dependentModuleImport = ParserUtils.getModuleImport(currentModule, prefix);
216 if (dependentModuleImport == null) {
217 throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'.");
219 final String dependentModuleName = dependentModuleImport.getModuleName();
220 dependentModuleRevision = dependentModuleImport.getRevision();
222 for (Module contextModule : context.getModules()) {
223 if (contextModule.getName().equals(dependentModuleName)) {
224 Date revision = contextModule.getRevision();
225 if (revision == null) {
226 revision = new Date(0L);
228 modulesByRevision.put(revision, contextModule);
233 Module result = null;
234 if (dependentModuleRevision == null) {
235 result = modulesByRevision.get(modulesByRevision.firstKey());
237 result = modulesByRevision.get(dependentModuleRevision);
244 * Find grouping by name.
247 * collection of grouping builders to search
250 * @return grouping with given name if present in collection, null otherwise
252 public static GroupingBuilder findGroupingBuilder(Set<GroupingBuilder> groupings, String name) {
253 for (GroupingBuilder grouping : groupings) {
254 if (grouping.getQName().getLocalName().equals(name)) {
262 * Find grouping by name.
265 * collection of grouping definitions to search
268 * @return grouping with given name if present in collection, null otherwise
270 public static GroupingDefinition findGroupingDefinition(Set<GroupingDefinition> groupings, String name) {
271 for (GroupingDefinition grouping : groupings) {
272 if (grouping.getQName().getLocalName().equals(name)) {
280 * Search types for type with given name.
286 * @return type with given name if present in collection, null otherwise
288 public static TypeDefinitionBuilder findTypedefBuilderByName(Set<TypeDefinitionBuilder> types, String name) {
289 for (TypeDefinitionBuilder td : types) {
290 if (td.getQName().getLocalName().equals(name)) {
301 * collection of types
304 * @return type with given name if it is present in collection, null
307 public static TypeDefinition<?> findTypeByName(Set<TypeDefinition<?>> types, String typeName) {
308 for (TypeDefinition<?> type : types) {
309 if (type.getQName().getLocalName().equals(typeName)) {
321 * @return SchemaPath from given String
323 public static SchemaPath parseUsesPath(final String usesPath) {
324 final boolean absolute = usesPath.startsWith("/");
325 final String[] splittedPath = usesPath.split("/");
326 final List<QName> path = new ArrayList<QName>();
328 for (String pathElement : splittedPath) {
329 if (pathElement.length() > 0) {
330 final String[] splittedElement = pathElement.split(":");
331 if (splittedElement.length == 1) {
332 name = new QName(null, null, null, splittedElement[0]);
334 name = new QName(null, null, splittedElement[0], splittedElement[1]);
339 return new SchemaPath(path, absolute);
343 * Get node from collection of refined nodes based on qname.
348 * collections of refined nodes
349 * @return node with given qname if present, null otherwise
351 public static SchemaNodeBuilder getRefined(QName nodeQName, List<SchemaNodeBuilder> refineNodes) {
352 for (SchemaNodeBuilder rn : refineNodes) {
353 if (rn.getQName().equals(nodeQName)) {
361 * Pull restriction from type and add them to constraints.
366 public static void mergeConstraints(final TypeDefinition<?> type, final TypeConstraints constraints) {
367 if (type instanceof DecimalTypeDefinition) {
368 constraints.addRanges(((DecimalTypeDefinition) type).getRangeStatements());
369 constraints.addFractionDigits(((DecimalTypeDefinition) type).getFractionDigits());
370 } else if (type instanceof IntegerTypeDefinition) {
371 constraints.addRanges(((IntegerTypeDefinition) type).getRangeStatements());
372 } else if (type instanceof StringTypeDefinition) {
373 constraints.addPatterns(((StringTypeDefinition) type).getPatterns());
374 constraints.addLengths(((StringTypeDefinition) type).getLengthStatements());
375 } else if (type instanceof BinaryTypeDefinition) {
376 constraints.addLengths(((BinaryTypeDefinition) type).getLengthConstraints());
381 * Add all augment's child nodes to given target.
384 * builder of augment statement
386 * augmentation target node
388 public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final DataNodeContainerBuilder target) {
389 boolean usesAugment = augment.getParent() instanceof UsesNodeBuilder;
390 for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) {
391 builder.setAugmenting(true);
393 if (builder instanceof GroupingMember) {
394 ((GroupingMember) builder).setAddedByUses(true);
397 correctAugmentChildPath(builder, target.getPath());
398 target.addChildNode(builder);
403 * Add all augment's child nodes to given target.
406 * builder of augment statement
408 * augmentation target choice node
410 public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final ChoiceBuilder target) {
411 boolean usesAugment = augment.getParent() instanceof UsesNodeBuilder;
412 for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) {
413 builder.setAugmenting(true);
415 if (builder instanceof GroupingMember) {
416 ((GroupingMember) builder).setAddedByUses(true);
419 correctAugmentChildPath(builder, target.getPath());
420 target.addCase(builder);
424 private static void correctAugmentChildPath(final DataSchemaNodeBuilder childNode, final SchemaPath parentSchemaPath) {
426 List<QName> targetNodePath = new ArrayList<QName>(parentSchemaPath.getPath());
427 targetNodePath.add(childNode.getQName());
428 childNode.setPath(new SchemaPath(targetNodePath, true));
430 // set correct path for all child nodes
431 if (childNode instanceof DataNodeContainerBuilder) {
432 DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) childNode;
433 for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodeBuilders()) {
434 correctAugmentChildPath(child, childNode.getPath());
438 // set correct path for all cases
439 if (childNode instanceof ChoiceBuilder) {
440 ChoiceBuilder choiceBuilder = (ChoiceBuilder) childNode;
441 for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) {
442 correctAugmentChildPath(choiceCaseBuilder, childNode.getPath());
446 // if node can contains type, correct path for this type too
447 if (childNode instanceof TypeAwareBuilder) {
448 TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) childNode;
449 correctTypeAwareNodePath(nodeBuilder, parentSchemaPath);
454 * Repair schema path of node type.
457 * node which contains type statement
458 * @param parentSchemaPath
459 * schema path of parent node
461 private static void correctTypeAwareNodePath(final TypeAwareBuilder node, final SchemaPath parentSchemaPath) {
462 final QName nodeBuilderQName = node.getQName();
463 final TypeDefinition<?> nodeType = node.getType();
466 List<LengthConstraint> lengths = null;
467 List<PatternConstraint> patterns = null;
468 List<RangeConstraint> ranges = null;
470 if (nodeType != null) {
471 if (nodeType instanceof ExtendedType) {
472 ExtendedType et = (ExtendedType) nodeType;
473 if (nodeType.getQName().getLocalName().equals(nodeType.getBaseType().getQName().getLocalName())) {
474 fd = et.getFractionDigits();
475 lengths = et.getLengths();
476 patterns = et.getPatterns();
477 ranges = et.getRanges();
478 if (!hasConstraints(fd, lengths, patterns, ranges)) {
483 TypeDefinition<?> newType = createCorrectTypeDefinition(parentSchemaPath, nodeBuilderQName, nodeType);
484 node.setType(newType);
486 TypeDefinitionBuilder nodeBuilderTypedef = node.getTypedef();
488 fd = nodeBuilderTypedef.getFractionDigits();
489 lengths = nodeBuilderTypedef.getLengths();
490 patterns = nodeBuilderTypedef.getPatterns();
491 ranges = nodeBuilderTypedef.getRanges();
493 String tdbTypeName = nodeBuilderTypedef.getQName().getLocalName();
494 String baseTypeName = null;
495 if (nodeBuilderTypedef.getType() == null) {
496 baseTypeName = nodeBuilderTypedef.getTypedef().getQName().getLocalName();
498 baseTypeName = nodeBuilderTypedef.getType().getQName().getLocalName();
500 if (!(tdbTypeName.equals(baseTypeName))) {
504 if (!hasConstraints(fd, lengths, patterns, ranges)) {
508 SchemaPath newSchemaPath = createNewSchemaPath(nodeBuilderTypedef.getPath(), nodeBuilderQName,
509 nodeBuilderTypedef.getQName());
510 nodeBuilderTypedef.setPath(newSchemaPath);
515 * Check if there are some constraints.
522 * pattern constraints
525 * @return true, if any of constraints are present, false otherwise
527 private static boolean hasConstraints(final Integer fd, final List<LengthConstraint> lengths,
528 final List<PatternConstraint> patterns, final List<RangeConstraint> ranges) {
529 if (fd == null && (lengths == null || lengths.isEmpty()) && (patterns == null || patterns.isEmpty())
530 && (ranges == null || ranges.isEmpty())) {
537 private static TypeDefinition<?> createCorrectTypeDefinition(SchemaPath parentSchemaPath, QName nodeQName,
538 TypeDefinition<?> nodeType) {
539 TypeDefinition<?> result = null;
541 if (nodeType != null) {
542 QName nodeTypeQName = nodeType.getQName();
543 SchemaPath newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, nodeTypeQName);
545 if (nodeType instanceof BinaryTypeDefinition) {
546 BinaryTypeDefinition binType = (BinaryTypeDefinition) nodeType;
548 // List<Byte> bytes = (List<Byte>) binType.getDefaultValue();
549 // workaround to get rid of 'Unchecked cast' warning
550 List<Byte> bytes = new ArrayList<Byte>();
551 Object defaultValue = binType.getDefaultValue();
552 if (defaultValue instanceof List) {
553 for (Object o : List.class.cast(defaultValue)) {
554 if (o instanceof Byte) {
559 result = new BinaryType(newSchemaPath, bytes);
560 } else if (nodeType instanceof BitsTypeDefinition) {
561 BitsTypeDefinition bitsType = (BitsTypeDefinition) nodeType;
562 result = new BitsType(newSchemaPath, bitsType.getBits());
563 } else if (nodeType instanceof BooleanTypeDefinition) {
564 result = new BooleanType(newSchemaPath);
565 } else if (nodeType instanceof DecimalTypeDefinition) {
566 DecimalTypeDefinition decimalType = (DecimalTypeDefinition) nodeType;
567 result = new Decimal64(newSchemaPath, decimalType.getFractionDigits());
568 } else if (nodeType instanceof EmptyTypeDefinition) {
569 result = new EmptyType(newSchemaPath);
570 } else if (nodeType instanceof EnumTypeDefinition) {
571 EnumTypeDefinition enumType = (EnumTypeDefinition) nodeType;
572 result = new EnumerationType(newSchemaPath, (EnumPair) enumType.getDefaultValue(), enumType.getValues());
573 } else if (nodeType instanceof IdentityrefTypeDefinition) {
574 IdentityrefTypeDefinition idrefType = (IdentityrefTypeDefinition) nodeType;
575 result = new IdentityrefType(idrefType.getIdentity(), newSchemaPath);
576 } else if (nodeType instanceof InstanceIdentifierTypeDefinition) {
577 InstanceIdentifierTypeDefinition instIdType = (InstanceIdentifierTypeDefinition) nodeType;
578 return new InstanceIdentifier(newSchemaPath, instIdType.getPathStatement(),
579 instIdType.requireInstance());
580 } else if (nodeType instanceof StringTypeDefinition) {
581 result = createNewStringType(parentSchemaPath, nodeQName, (StringTypeDefinition) nodeType);
582 } else if (nodeType instanceof IntegerTypeDefinition) {
583 result = createNewIntType(parentSchemaPath, nodeQName, (IntegerTypeDefinition) nodeType);
584 } else if (nodeType instanceof UnsignedIntegerTypeDefinition) {
585 result = createNewUintType(parentSchemaPath, nodeQName, (UnsignedIntegerTypeDefinition) nodeType);
586 } else if (nodeType instanceof LeafrefTypeDefinition) {
587 result = new Leafref(newSchemaPath, ((LeafrefTypeDefinition) nodeType).getPathStatement());
588 } else if (nodeType instanceof UnionTypeDefinition) {
589 UnionTypeDefinition unionType = (UnionTypeDefinition) nodeType;
590 return new UnionType(newSchemaPath, unionType.getTypes());
591 } else if (nodeType instanceof ExtendedType) {
592 ExtendedType extType = (ExtendedType) nodeType;
593 result = createNewExtendedType(extType, newSchemaPath);
600 * Create new ExtendedType based on given type and with schema path.
603 * schema path for new type
608 private static ExtendedType createNewExtendedType(final ExtendedType oldType, final SchemaPath newPath) {
609 QName qname = oldType.getQName();
610 TypeDefinition<?> baseType = oldType.getBaseType();
611 String desc = oldType.getDescription();
612 String ref = oldType.getReference();
613 ExtendedType.Builder builder = new ExtendedType.Builder(qname, baseType, desc, ref, newPath);
614 builder.status(oldType.getStatus());
615 builder.lengths(oldType.getLengths());
616 builder.patterns(oldType.getPatterns());
617 builder.ranges(oldType.getRanges());
618 builder.fractionDigits(oldType.getFractionDigits());
619 builder.unknownSchemaNodes(oldType.getUnknownSchemaNodes());
620 return builder.build();
623 private static StringTypeDefinition createNewStringType(final SchemaPath schemaPath, final QName nodeQName,
624 final StringTypeDefinition nodeType) {
625 final List<QName> path = schemaPath.getPath();
626 final List<QName> newPath = new ArrayList<QName>(path);
627 newPath.add(nodeQName);
628 newPath.add(nodeType.getQName());
629 final SchemaPath newSchemaPath = new SchemaPath(newPath, schemaPath.isAbsolute());
630 return new StringType(newSchemaPath);
633 private static IntegerTypeDefinition createNewIntType(final SchemaPath schemaPath, final QName nodeQName,
634 final IntegerTypeDefinition type) {
635 final QName typeQName = type.getQName();
636 final SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName);
637 final String localName = typeQName.getLocalName();
639 if ("int8".equals(localName)) {
640 return new Int8(newSchemaPath);
641 } else if ("int16".equals(localName)) {
642 return new Int16(newSchemaPath);
643 } else if ("int32".equals(localName)) {
644 return new Int32(newSchemaPath);
645 } else if ("int64".equals(localName)) {
646 return new Int64(newSchemaPath);
652 private static UnsignedIntegerTypeDefinition createNewUintType(final SchemaPath schemaPath, final QName nodeQName,
653 final UnsignedIntegerTypeDefinition type) {
654 final QName typeQName = type.getQName();
655 final SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName);
656 final String localName = typeQName.getLocalName();
658 if ("uint8".equals(localName)) {
659 return new Uint8(newSchemaPath);
660 } else if ("uint16".equals(localName)) {
661 return new Uint16(newSchemaPath);
662 } else if ("uint32".equals(localName)) {
663 return new Uint32(newSchemaPath);
664 } else if ("uint64".equals(localName)) {
665 return new Uint64(newSchemaPath);
671 private static SchemaPath createNewSchemaPath(final SchemaPath schemaPath, final QName currentQName,
673 List<QName> newPath = new ArrayList<QName>(schemaPath.getPath());
674 newPath.add(currentQName);
676 return new SchemaPath(newPath, schemaPath.isAbsolute());
680 * Create LeafSchemaNodeBuilder from given LeafSchemaNode.
683 * leaf from which to create builder
686 * @return builder object from leaf
688 public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, String moduleName, int line) {
689 final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(moduleName, line, leaf.getQName(),
691 convertDataSchemaNode(leaf, builder);
692 builder.setConfiguration(leaf.isConfiguration());
693 final TypeDefinition<?> type = leaf.getType();
694 builder.setType(type);
695 builder.setPath(leaf.getPath());
696 builder.setUnknownNodes(leaf.getUnknownSchemaNodes());
697 builder.setDefaultStr(leaf.getDefault());
698 builder.setUnits(leaf.getUnits());
702 public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, String moduleName, int line) {
703 final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(moduleName, line,
704 container.getQName(), container.getPath());
705 convertDataSchemaNode(container, builder);
706 builder.setConfiguration(container.isConfiguration());
707 builder.setUnknownNodes(container.getUnknownSchemaNodes());
708 builder.setChildNodes(container.getChildNodes());
709 builder.setGroupings(container.getGroupings());
710 builder.setTypedefs(container.getTypeDefinitions());
711 builder.setAugmentations(container.getAvailableAugmentations());
712 builder.setUsesnodes(container.getUses());
713 builder.setPresence(container.isPresenceContainer());
717 public static ListSchemaNodeBuilder createList(ListSchemaNode list, String moduleName, int line) {
718 ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(moduleName, line, list.getQName(), list.getPath());
719 convertDataSchemaNode(list, builder);
720 builder.setConfiguration(list.isConfiguration());
721 builder.setUnknownNodes(list.getUnknownSchemaNodes());
722 builder.setTypedefs(list.getTypeDefinitions());
723 builder.setChildNodes(list.getChildNodes());
724 builder.setGroupings(list.getGroupings());
725 builder.setAugmentations(list.getAvailableAugmentations());
726 builder.setUsesnodes(list.getUses());
727 builder.setUserOrdered(builder.isUserOrdered());
731 public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, String moduleName, int line) {
732 final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(moduleName, line, leafList.getQName(),
734 convertDataSchemaNode(leafList, builder);
735 builder.setConfiguration(leafList.isConfiguration());
736 builder.setType(leafList.getType());
737 builder.setUnknownNodes(leafList.getUnknownSchemaNodes());
738 builder.setUserOrdered(leafList.isUserOrdered());
742 public static ChoiceBuilder createChoice(ChoiceNode choice, String moduleName, int line) {
743 final ChoiceBuilder builder = new ChoiceBuilder(moduleName, line, choice.getQName());
744 convertDataSchemaNode(choice, builder);
745 builder.setConfiguration(choice.isConfiguration());
746 builder.setCases(choice.getCases());
747 builder.setUnknownNodes(choice.getUnknownSchemaNodes());
748 builder.setDefaultCase(choice.getDefaultCase());
752 public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, String moduleName, int line) {
753 final AnyXmlBuilder builder = new AnyXmlBuilder(moduleName, line, anyxml.getQName(), anyxml.getPath());
754 convertDataSchemaNode(anyxml, builder);
755 builder.setConfiguration(anyxml.isConfiguration());
756 builder.setUnknownNodes(anyxml.getUnknownSchemaNodes());
760 public static GroupingBuilder createGrouping(GroupingDefinition grouping, String moduleName, int line) {
761 final GroupingBuilderImpl builder = new GroupingBuilderImpl(moduleName, line, grouping.getQName());
762 builder.setPath(grouping.getPath());
763 builder.setChildNodes(grouping.getChildNodes());
764 builder.setGroupings(grouping.getGroupings());
765 builder.setTypedefs(grouping.getTypeDefinitions());
766 builder.setUsesnodes(grouping.getUses());
767 builder.setUnknownNodes(grouping.getUnknownSchemaNodes());
768 builder.setDescription(grouping.getDescription());
769 builder.setReference(grouping.getReference());
770 builder.setStatus(grouping.getStatus());
774 public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, String moduleName, int line) {
775 final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(moduleName, line, typedef.getQName());
776 builder.setPath(typedef.getPath());
777 builder.setDefaultValue(typedef.getDefaultValue());
778 builder.setUnits(typedef.getUnits());
779 builder.setDescription(typedef.getDescription());
780 builder.setReference(typedef.getReference());
781 builder.setStatus(typedef.getStatus());
782 builder.setRanges(typedef.getRanges());
783 builder.setLengths(typedef.getLengths());
784 builder.setPatterns(typedef.getPatterns());
785 builder.setFractionDigits(typedef.getFractionDigits());
786 final TypeDefinition<?> type = typedef.getBaseType();
787 builder.setType(type);
788 builder.setUnits(typedef.getUnits());
789 builder.setUnknownNodes(typedef.getUnknownSchemaNodes());
793 public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, String moduleName,
795 final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(moduleName, line, unknownNode.getQName());
796 builder.setPath(unknownNode.getPath());
797 builder.setUnknownNodes(unknownNode.getUnknownSchemaNodes());
798 builder.setDescription(unknownNode.getDescription());
799 builder.setReference(unknownNode.getReference());
800 builder.setStatus(unknownNode.getStatus());
801 builder.setAddedByUses(unknownNode.isAddedByUses());
802 builder.setNodeType(unknownNode.getNodeType());
803 builder.setNodeParameter(unknownNode.getNodeParameter());
808 * Set DataSchemaNode arguments to builder object
811 * node from which arguments should be read
813 * builder to which arguments should be set
815 private static void convertDataSchemaNode(DataSchemaNode node, DataSchemaNodeBuilder builder) {
816 builder.setPath(node.getPath());
817 builder.setDescription(node.getDescription());
818 builder.setReference(node.getReference());
819 builder.setStatus(node.getStatus());
820 builder.setAugmenting(node.isAugmenting());
821 copyConstraintsFromDefinition(node.getConstraints(), builder.getConstraints());
825 * Copy constraints from constraints definition to constraints builder.
827 * @param nodeConstraints
828 * definition from which constraints will be copied
830 * builder to which constraints will be added
832 private static void copyConstraintsFromDefinition(final ConstraintDefinition nodeConstraints,
833 final ConstraintsBuilder constraints) {
834 final RevisionAwareXPath when = nodeConstraints.getWhenCondition();
835 final Set<MustDefinition> must = nodeConstraints.getMustConstraints();
838 constraints.addWhenCondition(when.toString());
841 for (MustDefinition md : must) {
842 constraints.addMustDefinition(md);
845 constraints.setMandatory(nodeConstraints.isMandatory());
846 constraints.setMinElements(nodeConstraints.getMinElements());
847 constraints.setMaxElements(nodeConstraints.getMaxElements());
850 public static void processAugmentationOnContext(final AugmentationSchemaBuilder augmentBuilder,
851 final List<QName> path, final ModuleBuilder module, final String prefix, final int line,
852 final SchemaContext context) {
853 final Module dependentModule = findModuleFromContext(context, module, prefix, line);
854 if (dependentModule == null) {
855 throw new YangParseException(module.getName(), line, "Failed to find referenced module with prefix "
858 SchemaNode node = dependentModule.getDataChildByName(path.get(0).getLocalName());
860 Set<NotificationDefinition> notifications = dependentModule.getNotifications();
861 for (NotificationDefinition ntf : notifications) {
862 if (ntf.getQName().getLocalName().equals(path.get(0).getLocalName())) {
872 for (int i = 1; i < path.size(); i++) {
873 if (node instanceof DataNodeContainer) {
874 DataNodeContainer ref = (DataNodeContainer) node;
875 node = ref.getDataChildByName(path.get(i).getLocalName());
882 if (node instanceof ContainerSchemaNodeImpl) {
883 // includes container, input and output statement
884 ContainerSchemaNodeImpl c = (ContainerSchemaNodeImpl) node;
885 ContainerSchemaNodeBuilder cb = c.toBuilder();
886 fillAugmentTarget(augmentBuilder, cb);
887 ((AugmentationTargetBuilder) cb).addAugmentation(augmentBuilder);
888 SchemaPath oldPath = cb.getPath();
890 augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
891 augmentBuilder.setResolved(true);
892 module.augmentResolved();
893 } else if (node instanceof ListSchemaNodeImpl) {
894 ListSchemaNodeImpl l = (ListSchemaNodeImpl) node;
895 ListSchemaNodeBuilder lb = l.toBuilder();
896 fillAugmentTarget(augmentBuilder, lb);
897 ((AugmentationTargetBuilder) lb).addAugmentation(augmentBuilder);
898 SchemaPath oldPath = lb.getPath();
900 augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
901 augmentBuilder.setResolved(true);
902 module.augmentResolved();
903 } else if (node instanceof ChoiceNodeImpl) {
904 ChoiceNodeImpl ch = (ChoiceNodeImpl) node;
905 ChoiceBuilder chb = ch.toBuilder();
906 fillAugmentTarget(augmentBuilder, chb);
907 ((AugmentationTargetBuilder) chb).addAugmentation(augmentBuilder);
908 SchemaPath oldPath = chb.getPath();
910 augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
911 augmentBuilder.setResolved(true);
912 module.augmentResolved();
913 } else if (node instanceof ChoiceCaseNodeImpl) {
914 ChoiceCaseNodeImpl chc = (ChoiceCaseNodeImpl) node;
915 ChoiceCaseBuilder chcb = chc.toBuilder();
916 fillAugmentTarget(augmentBuilder, chcb);
917 ((AugmentationTargetBuilder) chcb).addAugmentation(augmentBuilder);
918 SchemaPath oldPath = chcb.getPath();
920 augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
921 augmentBuilder.setResolved(true);
922 module.augmentResolved();
923 } else if (node instanceof NotificationDefinitionImpl) {
924 NotificationDefinitionImpl nd = (NotificationDefinitionImpl) node;
925 NotificationBuilder nb = nd.toBuilder();
926 fillAugmentTarget(augmentBuilder, nb);
927 ((AugmentationTargetBuilder) nb).addAugmentation(augmentBuilder);
928 SchemaPath oldPath = nb.getPath();
930 augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
931 augmentBuilder.setResolved(true);
932 module.augmentResolved();
934 throw new YangParseException(module.getName(), line, "Target of type " + node.getClass()
935 + " cannot be augmented.");
939 public static void processAugmentation(final AugmentationSchemaBuilder augmentBuilder, final List<QName> path,
940 final ModuleBuilder module, final ModuleBuilder dependentModuleBuilder) {
941 DataSchemaNodeBuilder currentParent = null;
942 for (DataSchemaNodeBuilder child : dependentModuleBuilder.getChildNodeBuilders()) {
943 final QName childQName = child.getQName();
944 if (childQName.getLocalName().equals(path.get(0).getLocalName())) {
945 currentParent = child;
950 if (currentParent == null) {
954 for (int i = 1; i < path.size(); i++) {
955 final QName currentQName = path.get(i);
956 DataSchemaNodeBuilder newParent = null;
957 if (currentParent instanceof DataNodeContainerBuilder) {
958 for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodeBuilders()) {
959 final QName childQName = child.getQName();
960 if (childQName.getLocalName().equals(currentQName.getLocalName())) {
965 } else if (currentParent instanceof ChoiceBuilder) {
966 for (ChoiceCaseBuilder caseBuilder : ((ChoiceBuilder) currentParent).getCases()) {
967 final QName caseQName = caseBuilder.getQName();
968 if (caseQName.getLocalName().equals(currentQName.getLocalName())) {
969 newParent = caseBuilder;
975 if (newParent == null) {
976 break; // node not found, quit search
978 currentParent = newParent;
982 final String currentName = currentParent.getQName().getLocalName();
983 final String lastAugmentPathElementName = path.get(path.size() - 1).getLocalName();
984 if (currentName.equals(lastAugmentPathElementName)) {
986 if (currentParent instanceof ChoiceBuilder) {
987 fillAugmentTarget(augmentBuilder, (ChoiceBuilder) currentParent);
989 fillAugmentTarget(augmentBuilder, (DataNodeContainerBuilder) currentParent);
991 ((AugmentationTargetBuilder) currentParent).addAugmentation(augmentBuilder);
992 SchemaPath oldPath = currentParent.getPath();
993 augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
994 augmentBuilder.setResolved(true);
995 module.augmentResolved();
1000 * Create new type builder based on old type with new base type.
1002 * @param newBaseType
1003 * new base type builder
1004 * @param oldExtendedType
1007 * all loaded modules
1011 * current line in module
1012 * @return new type builder based on old type with new base type
1014 public static TypeDefinitionBuilder extendedTypeWithNewBaseTypeBuilder(final TypeDefinitionBuilder newBaseType,
1015 final ExtendedType oldExtendedType, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
1016 final ModuleBuilder module, final int line) {
1017 final TypeConstraints tc = new TypeConstraints(module.getName(), line);
1018 tc.addFractionDigits(oldExtendedType.getFractionDigits());
1019 tc.addLengths(oldExtendedType.getLengths());
1020 tc.addPatterns(oldExtendedType.getPatterns());
1021 tc.addRanges(oldExtendedType.getRanges());
1023 final TypeConstraints constraints = findConstraintsFromTypeBuilder(newBaseType, tc, modules, module, null);
1024 final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
1025 oldExtendedType.getQName());
1026 newType.setTypedef(newBaseType);
1027 newType.setPath(oldExtendedType.getPath());
1028 newType.setDescription(oldExtendedType.getDescription());
1029 newType.setReference(oldExtendedType.getReference());
1030 newType.setStatus(oldExtendedType.getStatus());
1031 newType.setLengths(constraints.getLength());
1032 newType.setPatterns(constraints.getPatterns());
1033 newType.setRanges(constraints.getRange());
1034 newType.setFractionDigits(constraints.getFractionDigits());
1035 newType.setUnits(oldExtendedType.getUnits());
1036 newType.setDefaultValue(oldExtendedType.getDefaultValue());
1037 newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
1042 * Create new type builder based on old type with new base type.
1044 * @param newBaseType
1046 * @param oldExtendedType
1049 * all loaded modules
1053 * current line in module
1054 * @return new type builder based on old type with new base type
1056 public static TypeDefinitionBuilder extendedTypeWithNewBaseType(final TypeDefinition<?> newBaseType,
1057 final ExtendedType oldExtendedType, final ModuleBuilder module, final int line) {
1058 final TypeConstraints tc = new TypeConstraints(module.getName(), line);
1060 final TypeConstraints constraints = findConstraintsFromTypeDefinition(newBaseType, tc);
1061 final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
1062 oldExtendedType.getQName());
1063 newType.setType(newBaseType);
1064 newType.setPath(oldExtendedType.getPath());
1065 newType.setDescription(oldExtendedType.getDescription());
1066 newType.setReference(oldExtendedType.getReference());
1067 newType.setStatus(oldExtendedType.getStatus());
1068 newType.setLengths(constraints.getLength());
1069 newType.setPatterns(constraints.getPatterns());
1070 newType.setRanges(constraints.getRange());
1071 newType.setFractionDigits(constraints.getFractionDigits());
1072 newType.setUnits(oldExtendedType.getUnits());
1073 newType.setDefaultValue(oldExtendedType.getDefaultValue());
1074 newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
1079 * Pull restrictions from type and add them to constraints.
1081 * @param typeToResolve
1082 * type from which constraints will be read
1083 * @param constraints
1084 * constraints object to which constraints will be added
1085 * @return constraints contstraints object containing constraints from given
1088 private static TypeConstraints findConstraintsFromTypeDefinition(final TypeDefinition<?> typeToResolve,
1089 final TypeConstraints constraints) {
1090 // union type cannot be restricted
1091 if (typeToResolve instanceof UnionTypeDefinition) {
1094 if (typeToResolve instanceof ExtendedType) {
1095 ExtendedType extType = (ExtendedType) typeToResolve;
1096 constraints.addFractionDigits(extType.getFractionDigits());
1097 constraints.addLengths(extType.getLengths());
1098 constraints.addPatterns(extType.getPatterns());
1099 constraints.addRanges(extType.getRanges());
1100 return findConstraintsFromTypeDefinition(extType.getBaseType(), constraints);
1102 mergeConstraints(typeToResolve, constraints);
1107 public static TypeConstraints findConstraintsFromTypeBuilder(final TypeAwareBuilder nodeToResolve,
1108 final TypeConstraints constraints, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
1109 final ModuleBuilder builder, final SchemaContext context) {
1111 // union and identityref types cannot be restricted
1112 if (nodeToResolve instanceof UnionTypeBuilder || nodeToResolve instanceof IdentityrefTypeBuilder) {
1116 if (nodeToResolve instanceof TypeDefinitionBuilder) {
1117 TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve;
1118 constraints.addFractionDigits(typedefToResolve.getFractionDigits());
1119 constraints.addLengths(typedefToResolve.getLengths());
1120 constraints.addPatterns(typedefToResolve.getPatterns());
1121 constraints.addRanges(typedefToResolve.getRanges());
1124 TypeDefinition<?> type = nodeToResolve.getType();
1126 return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder, context);
1128 QName qname = type.getQName();
1129 if (type instanceof UnknownType) {
1130 ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder, qname.getPrefix(),
1131 nodeToResolve.getLine());
1132 if (dependentModuleBuilder == null) {
1133 if (context == null) {
1134 throw new YangParseException(builder.getName(), nodeToResolve.getLine(),
1135 "Failed to resolved type constraints.");
1137 Module dm = findModuleFromContext(context, builder, qname.getPrefix(), nodeToResolve.getLine());
1138 TypeDefinition<?> t = findTypeByName(dm.getTypeDefinitions(), qname.getLocalName());
1139 if (t instanceof ExtendedType) {
1140 ExtendedType extType = (ExtendedType) t;
1141 constraints.addFractionDigits(extType.getFractionDigits());
1142 constraints.addLengths(extType.getLengths());
1143 constraints.addPatterns(extType.getPatterns());
1144 constraints.addRanges(extType.getRanges());
1147 mergeConstraints(t, constraints);
1151 TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModuleBuilder,
1152 qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
1153 return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder, context);
1155 } else if (type instanceof ExtendedType) {
1156 ExtendedType extType = (ExtendedType) type;
1157 constraints.addFractionDigits(extType.getFractionDigits());
1158 constraints.addLengths(extType.getLengths());
1159 constraints.addPatterns(extType.getPatterns());
1160 constraints.addRanges(extType.getRanges());
1162 TypeDefinition<?> base = extType.getBaseType();
1163 if (base instanceof UnknownType) {
1164 ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, base.getQName()
1165 .getPrefix(), nodeToResolve.getLine());
1166 TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModule, base
1167 .getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
1168 return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule, context);
1170 // it has to be base yang type
1171 mergeConstraints(type, constraints);
1175 // it is base yang type
1176 mergeConstraints(type, constraints);
1183 * Search for type definition builder by name.
1185 * @param dirtyNodeSchemaPath
1186 * schema path of node which contains unresolved type
1187 * @param dependentModule
1188 * module which should contains referenced type
1190 * name of type definition
1191 * @param currentModuleName
1192 * name of current module
1194 * current line in yang model
1197 public static TypeDefinitionBuilder findTypeDefinitionBuilder(final TypeAwareBuilder nodeToResolve,
1198 final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) {
1200 TypeDefinitionBuilder result = null;
1202 Set<TypeDefinitionBuilder> typedefs = dependentModule.getTypeDefinitionBuilders();
1203 result = findTypedefBuilderByName(typedefs, typeName);
1204 if (result != null) {
1208 Builder parent = nodeToResolve.getParent();
1209 while (parent != null) {
1210 if (parent instanceof DataNodeContainerBuilder) {
1211 typedefs = ((DataNodeContainerBuilder) parent).getTypeDefinitionBuilders();
1212 } else if (parent instanceof RpcDefinitionBuilder) {
1213 typedefs = ((RpcDefinitionBuilder) parent).getTypeDefinitions();
1215 result = findTypedefBuilderByName(typedefs, typeName);
1216 if (result == null) {
1217 parent = parent.getParent();
1223 if (result == null) {
1224 throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found.");