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.controller.yang.parser.impl;
10 import static org.opendaylight.controller.yang.parser.util.ParserUtils.*;
13 import java.io.FileInputStream;
14 import java.io.FileNotFoundException;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.Date;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.LinkedHashMap;
24 import java.util.LinkedHashSet;
25 import java.util.List;
27 import java.util.Map.Entry;
28 import java.util.NoSuchElementException;
30 import java.util.TreeMap;
32 import org.antlr.v4.runtime.ANTLRInputStream;
33 import org.antlr.v4.runtime.CommonTokenStream;
34 import org.antlr.v4.runtime.tree.ParseTree;
35 import org.antlr.v4.runtime.tree.ParseTreeWalker;
36 import org.opendaylight.controller.antlrv4.code.gen.YangLexer;
37 import org.opendaylight.controller.antlrv4.code.gen.YangParser;
38 import org.opendaylight.controller.yang.common.QName;
39 import org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode;
40 import org.opendaylight.controller.yang.model.api.ChoiceNode;
41 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
42 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
43 import org.opendaylight.controller.yang.model.api.GroupingDefinition;
44 import org.opendaylight.controller.yang.model.api.IdentitySchemaNode;
45 import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
46 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
47 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
48 import org.opendaylight.controller.yang.model.api.Module;
49 import org.opendaylight.controller.yang.model.api.SchemaContext;
50 import org.opendaylight.controller.yang.model.api.SchemaPath;
51 import org.opendaylight.controller.yang.model.api.TypeDefinition;
52 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
53 import org.opendaylight.controller.yang.model.api.UsesNode;
54 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
55 import org.opendaylight.controller.yang.model.util.ExtendedType;
56 import org.opendaylight.controller.yang.model.util.IdentityrefType;
57 import org.opendaylight.controller.yang.model.util.UnknownType;
58 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
59 import org.opendaylight.controller.yang.parser.builder.api.Builder;
60 import org.opendaylight.controller.yang.parser.builder.api.DataNodeContainerBuilder;
61 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
62 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
63 import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
64 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
65 import org.opendaylight.controller.yang.parser.builder.api.TypeAwareBuilder;
66 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
67 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
68 import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
69 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
70 import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
71 import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl;
72 import org.opendaylight.controller.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
73 import org.opendaylight.controller.yang.parser.builder.impl.IdentityrefTypeBuilder;
74 import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
75 import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
76 import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
77 import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
78 import org.opendaylight.controller.yang.parser.builder.impl.RpcDefinitionBuilder;
79 import org.opendaylight.controller.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
80 import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder;
81 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
82 import org.opendaylight.controller.yang.parser.builder.impl.UsesNodeBuilderImpl;
83 import org.opendaylight.controller.yang.parser.builder.impl.UsesNodeBuilderImpl.UsesNodeImpl;
84 import org.opendaylight.controller.yang.parser.util.ModuleDependencySort;
85 import org.opendaylight.controller.yang.parser.util.RefineHolder;
86 import org.opendaylight.controller.yang.parser.util.RefineUtils;
87 import org.opendaylight.controller.yang.parser.util.TypeConstraints;
88 import org.opendaylight.controller.yang.parser.util.YangParseException;
89 import org.opendaylight.controller.yang.validator.YangModelBasicValidator;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
93 import com.google.common.collect.Lists;
94 import com.google.common.collect.Maps;
95 import com.google.common.collect.Sets;
97 public final class YangParserImpl implements YangModelParser {
98 private static final Logger logger = LoggerFactory.getLogger(YangParserImpl.class);
101 public Set<Module> parseYangModels(final List<File> yangFiles) {
102 return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values());
106 public Set<Module> parseYangModels(final List<File> yangFiles, final SchemaContext context) {
107 if (yangFiles != null) {
108 final Map<InputStream, File> inputStreams = Maps.newHashMap();
110 for (final File yangFile : yangFiles) {
112 inputStreams.put(new FileInputStream(yangFile), yangFile);
113 } catch (FileNotFoundException e) {
114 logger.warn("Exception while reading yang file: " + yangFile.getName(), e);
118 Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
120 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(
121 Lists.newArrayList(inputStreams.keySet()), builderToStreamMap);
123 for (InputStream is : inputStreams.keySet()) {
126 } catch (IOException e) {
127 logger.debug("Failed to close stream.");
131 return new LinkedHashSet<Module>(buildWithContext(modules, context).values());
133 return Collections.emptySet();
137 public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams) {
138 return Sets.newHashSet(parseYangModelsFromStreamsMapped(yangModelStreams).values());
142 public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams, SchemaContext context) {
143 if (yangModelStreams != null) {
144 Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
145 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersWithContext(
146 yangModelStreams, builderToStreamMap, context);
147 return new LinkedHashSet<Module>(buildWithContext(modules, context).values());
149 return Collections.emptySet();
153 public Map<File, Module> parseYangModelsMapped(List<File> yangFiles) {
154 if (yangFiles != null) {
155 final Map<InputStream, File> inputStreams = Maps.newHashMap();
157 for (final File yangFile : yangFiles) {
159 inputStreams.put(new FileInputStream(yangFile), yangFile);
160 } catch (FileNotFoundException e) {
161 logger.warn("Exception while reading yang file: " + yangFile.getName(), e);
165 Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
166 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(
167 Lists.newArrayList(inputStreams.keySet()), builderToStreamMap);
169 for (InputStream is : inputStreams.keySet()) {
172 } catch (IOException e) {
173 logger.debug("Failed to close stream.");
177 Map<File, Module> retVal = Maps.newLinkedHashMap();
178 Map<ModuleBuilder, Module> builderToModuleMap = build(modules);
180 for (Entry<ModuleBuilder, Module> builderToModule : builderToModuleMap.entrySet()) {
181 retVal.put(inputStreams.get(builderToStreamMap.get(builderToModule.getKey())),
182 builderToModule.getValue());
187 return Collections.emptyMap();
191 public Map<InputStream, Module> parseYangModelsFromStreamsMapped(final List<InputStream> yangModelStreams) {
192 Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
194 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(yangModelStreams,
196 Map<InputStream, Module> retVal = Maps.newLinkedHashMap();
197 Map<ModuleBuilder, Module> builderToModuleMap = build(modules);
199 for (Entry<ModuleBuilder, Module> builderToModule : builderToModuleMap.entrySet()) {
200 retVal.put(builderToStreamMap.get(builderToModule.getKey()), builderToModule.getValue());
206 public SchemaContext resolveSchemaContext(final Set<Module> modules) {
207 return new SchemaContextImpl(modules);
210 private ModuleBuilder[] parseModuleBuilders(List<InputStream> inputStreams,
211 Map<ModuleBuilder, InputStream> streamToBuilderMap) {
213 final ParseTreeWalker walker = new ParseTreeWalker();
214 final List<ParseTree> trees = parseStreams(inputStreams);
215 final ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
218 new YangModelBasicValidator(walker).validate(trees);
220 YangParserListenerImpl yangModelParser = null;
221 for (int i = 0; i < trees.size(); i++) {
222 yangModelParser = new YangParserListenerImpl();
223 walker.walk(yangModelParser, trees.get(i));
224 ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder();
226 // We expect the order of trees and streams has to be the same
227 streamToBuilderMap.put(moduleBuilder, inputStreams.get(i));
228 builders[i] = moduleBuilder;
233 private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(final List<InputStream> yangFileStreams,
234 Map<ModuleBuilder, InputStream> streamToBuilderMap) {
235 return resolveModuleBuildersWithContext(yangFileStreams, streamToBuilderMap, null);
238 private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersWithContext(
239 final List<InputStream> yangFileStreams, final Map<ModuleBuilder, InputStream> streamToBuilderMap,
240 final SchemaContext context) {
241 final ModuleBuilder[] builders = parseModuleBuilders(yangFileStreams, streamToBuilderMap);
243 // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER
244 // of items stored in map.
245 final LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = new LinkedHashMap<String, TreeMap<Date, ModuleBuilder>>();
247 // module dependency graph sorted
248 List<ModuleBuilder> sorted = null;
249 if (context == null) {
250 sorted = ModuleDependencySort.sort(builders);
252 sorted = ModuleDependencySort.sortWithContext(context, builders);
255 for (final ModuleBuilder builder : sorted) {
256 if (builder == null) {
259 final String builderName = builder.getName();
260 Date builderRevision = builder.getRevision();
261 if (builderRevision == null) {
262 builderRevision = new Date(0L);
264 TreeMap<Date, ModuleBuilder> builderByRevision = modules.get(builderName);
265 if (builderByRevision == null) {
266 builderByRevision = new TreeMap<Date, ModuleBuilder>();
268 builderByRevision.put(builderRevision, builder);
269 modules.put(builderName, builderByRevision);
274 private List<ParseTree> parseStreams(final List<InputStream> yangStreams) {
275 final List<ParseTree> trees = new ArrayList<ParseTree>();
276 for (InputStream yangStream : yangStreams) {
277 trees.add(parseStream(yangStream));
282 private ParseTree parseStream(final InputStream yangStream) {
283 ParseTree result = null;
285 final ANTLRInputStream input = new ANTLRInputStream(yangStream);
286 final YangLexer lexer = new YangLexer(input);
287 final CommonTokenStream tokens = new CommonTokenStream(lexer);
288 final YangParser parser = new YangParser(tokens);
289 parser.removeErrorListeners();
290 parser.addErrorListener(new YangErrorListener());
292 result = parser.yang();
293 } catch (IOException e) {
294 logger.warn("Exception while reading yang file: " + yangStream, e);
299 private Map<ModuleBuilder, Module> build(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
300 // fix unresolved nodes
301 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
302 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
303 final ModuleBuilder moduleBuilder = childEntry.getValue();
304 fixUnresolvedNodes(modules, moduleBuilder);
307 resolveAugments(modules);
310 // LinkedHashMap MUST be used otherwise the values will not maintain
312 // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html
313 final Map<ModuleBuilder, Module> result = new LinkedHashMap<ModuleBuilder, Module>();
314 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
315 final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
316 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
317 final ModuleBuilder moduleBuilder = childEntry.getValue();
318 final Module module = moduleBuilder.build();
319 modulesByRevision.put(childEntry.getKey(), module);
320 result.put(moduleBuilder, module);
326 private Map<ModuleBuilder, Module> buildWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
327 SchemaContext context) {
328 // fix unresolved nodes
329 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
330 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
331 final ModuleBuilder moduleBuilder = childEntry.getValue();
332 fixUnresolvedNodesWithContext(modules, moduleBuilder, context);
335 resolveAugmentsWithContext(modules, context);
338 // LinkedHashMap MUST be used otherwise the values will not maintain
340 // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html
341 final Map<ModuleBuilder, Module> result = new LinkedHashMap<ModuleBuilder, Module>();
342 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
343 final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
344 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
345 final ModuleBuilder moduleBuilder = childEntry.getValue();
346 final Module module = moduleBuilder.build();
347 modulesByRevision.put(childEntry.getKey(), module);
348 result.put(moduleBuilder, module);
354 private void fixUnresolvedNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
355 resolveDirtyNodes(modules, builder);
356 resolveIdentities(modules, builder);
357 resolveUsesRefine(modules, builder);
358 resolveUnknownNodes(modules, builder);
361 private void fixUnresolvedNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
362 final ModuleBuilder builder, final SchemaContext context) {
363 resolveDirtyNodesWithContext(modules, builder, context);
364 resolveIdentitiesWithContext(modules, builder, context);
365 resolveUsesRefineWithContext(modules, builder, context);
366 resolveUnknownNodesWithContext(modules, builder, context);
370 * Search for dirty nodes (node which contains UnknownType) and resolve
374 * all available modules
378 private void resolveDirtyNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
379 final Map<List<String>, TypeAwareBuilder> dirtyNodes = module.getDirtyNodes();
380 if (!dirtyNodes.isEmpty()) {
381 for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes.entrySet()) {
382 final TypeAwareBuilder nodeToResolve = entry.getValue();
384 if (nodeToResolve instanceof UnionTypeBuilder) {
385 // special handling for union types
386 resolveTypeUnion((UnionTypeBuilder) nodeToResolve, modules, module);
387 } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
388 // special handling for identityref types
389 IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef();
390 nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath()));
392 resolveType(nodeToResolve, modules, module);
398 private void resolveDirtyNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
399 final ModuleBuilder module, SchemaContext context) {
400 final Map<List<String>, TypeAwareBuilder> dirtyNodes = module.getDirtyNodes();
401 if (!dirtyNodes.isEmpty()) {
402 for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes.entrySet()) {
403 final TypeAwareBuilder nodeToResolve = entry.getValue();
405 if (nodeToResolve instanceof UnionTypeBuilder) {
406 // special handling for union types
407 resolveTypeUnionWithContext((UnionTypeBuilder) nodeToResolve, modules, module, context);
408 } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
409 // special handling for identityref types
410 IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef();
411 nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath()));
413 resolveTypeWithContext(nodeToResolve, modules, module, context);
420 * Resolve unknown type of node. It is assumed that type of node is either
421 * UnknownType or ExtendedType with UnknownType as base type.
423 * @param nodeToResolve
424 * node with type to resolve
430 private void resolveType(final TypeAwareBuilder nodeToResolve,
431 final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
432 TypeDefinitionBuilder resolvedType = null;
433 final int line = nodeToResolve.getLine();
434 final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
435 final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
436 final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, unknownTypeQName.getPrefix(),
439 final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve.getPath(),
440 dependentModule, unknownTypeQName.getLocalName(), module.getName(), line);
442 if (nodeToResolveType instanceof ExtendedType) {
443 final ExtendedType extType = (ExtendedType) nodeToResolveType;
444 final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType,
445 modules, module, nodeToResolve.getLine());
446 resolvedType = newType;
448 resolvedType = targetTypeBuilder;
451 // validate constraints
452 final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve,
453 new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, null);
454 constraints.validateConstraints();
456 nodeToResolve.setTypedef(resolvedType);
460 * Resolve unknown type of node. It is assumed that type of node is either
461 * UnknownType or ExtendedType with UnknownType as base type.
463 * @param nodeToResolve
464 * node with type to resolve
470 * SchemaContext containing already resolved modules
472 private void resolveTypeWithContext(final TypeAwareBuilder nodeToResolve,
473 final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
474 final SchemaContext context) {
475 TypeDefinitionBuilder resolvedType = null;
476 final int line = nodeToResolve.getLine();
477 final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
478 final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
479 final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module,
480 unknownTypeQName.getPrefix(), line);
482 if (dependentModuleBuilder == null) {
483 final Module dependentModule = findModuleFromContext(context, module, unknownTypeQName.getPrefix(), line);
484 final Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
485 final TypeDefinition<?> type = findTypeByName(types, unknownTypeQName.getLocalName());
487 if (nodeToResolveType instanceof ExtendedType) {
488 final ExtendedType extType = (ExtendedType) nodeToResolveType;
489 final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(type, extType, module,
490 nodeToResolve.getLine());
492 nodeToResolve.setTypedef(newType);
494 if (nodeToResolve instanceof TypeDefinitionBuilder) {
495 TypeDefinitionBuilder tdb = (TypeDefinitionBuilder) nodeToResolve;
496 TypeConstraints tc = findConstraintsFromTypeBuilder(nodeToResolve,
497 new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, context);
498 tdb.setLengths(tc.getLength());
499 tdb.setPatterns(tc.getPatterns());
500 tdb.setRanges(tc.getRange());
501 tdb.setFractionDigits(tc.getFractionDigits());
503 nodeToResolve.setType(type);
507 final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve.getPath(),
508 dependentModuleBuilder, unknownTypeQName.getLocalName(), module.getName(), line);
510 if (nodeToResolveType instanceof ExtendedType) {
511 final ExtendedType extType = (ExtendedType) nodeToResolveType;
512 final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType,
513 modules, module, nodeToResolve.getLine());
514 resolvedType = newType;
516 resolvedType = targetTypeBuilder;
519 // validate constraints
520 final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve, new TypeConstraints(
521 module.getName(), nodeToResolve.getLine()), modules, module, context);
522 constraints.validateConstraints();
524 nodeToResolve.setTypedef(resolvedType);
528 private void resolveTypeUnion(final UnionTypeBuilder union,
529 final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
531 final List<TypeDefinition<?>> unionTypes = union.getTypes();
532 final List<TypeDefinition<?>> toRemove = new ArrayList<TypeDefinition<?>>();
533 for (TypeDefinition<?> unionType : unionTypes) {
534 if (unionType instanceof UnknownType) {
535 final UnknownType ut = (UnknownType) unionType;
536 final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
537 .getPrefix(), union.getLine());
538 final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union.getPath(), dependentModule,
539 ut.getQName().getLocalName(), builder.getName(), union.getLine());
540 union.setTypedef(resolvedType);
542 } else if (unionType instanceof ExtendedType) {
543 final ExtendedType extType = (ExtendedType) unionType;
544 final TypeDefinition<?> extTypeBase = extType.getBaseType();
545 if (extTypeBase instanceof UnknownType) {
546 final UnknownType ut = (UnknownType) extTypeBase;
547 final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
548 .getPrefix(), union.getLine());
549 final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union.getPath(),
550 dependentModule, ut.getQName().getLocalName(), builder.getName(), union.getLine());
552 final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
553 extType, modules, builder, union.getLine());
555 union.setTypedef(newType);
556 toRemove.add(extType);
560 unionTypes.removeAll(toRemove);
563 private void resolveTypeUnionWithContext(final UnionTypeBuilder union,
564 final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder,
565 final SchemaContext context) {
567 final List<TypeDefinition<?>> unionTypes = union.getTypes();
568 final List<TypeDefinition<?>> toRemove = new ArrayList<TypeDefinition<?>>();
569 for (TypeDefinition<?> unionType : unionTypes) {
570 if (unionType instanceof UnknownType) {
571 final UnknownType ut = (UnknownType) unionType;
572 final QName utQName = ut.getQName();
573 final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder,
574 utQName.getPrefix(), union.getLine());
576 if (dependentModuleBuilder == null) {
577 Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(),
579 Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
580 TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
584 final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union.getPath(),
585 dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine());
586 union.setTypedef(resolvedType);
590 } else if (unionType instanceof ExtendedType) {
591 final ExtendedType extType = (ExtendedType) unionType;
592 TypeDefinition<?> extTypeBase = extType.getBaseType();
593 if (extTypeBase instanceof UnknownType) {
594 final UnknownType ut = (UnknownType) extTypeBase;
595 final QName utQName = ut.getQName();
596 final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder,
597 utQName.getPrefix(), union.getLine());
599 if (dependentModuleBuilder == null) {
600 final Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(),
602 Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
603 TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
604 final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(type, extType, builder, 0);
606 union.setTypedef(newType);
607 toRemove.add(extType);
609 final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union.getPath(),
610 dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine());
612 final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
613 extType, modules, builder, union.getLine());
615 union.setTypedef(newType);
616 toRemove.add(extType);
621 unionTypes.removeAll(toRemove);
625 * Go through all augment definitions and resolve them. It is expected that
626 * modules are already sorted by their dependencies. This method also finds
627 * augment target node and add child nodes to it.
630 * all available modules
632 private void resolveAugments(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
633 final List<ModuleBuilder> allModulesList = new ArrayList<ModuleBuilder>();
634 final Set<ModuleBuilder> allModulesSet = new HashSet<ModuleBuilder>();
635 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
636 for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
637 allModulesList.add(inner.getValue());
638 allModulesSet.add(inner.getValue());
642 for (int i = 0; i < allModulesList.size(); i++) {
643 final ModuleBuilder module = allModulesList.get(i);
644 // try to resolve augments in module
645 resolveAugment(modules, module);
646 // while all augments are not resolved
647 final Iterator<ModuleBuilder> allModulesIterator = allModulesSet.iterator();
648 while (!(module.getAugmentsResolved() == module.getAugments().size())) {
649 ModuleBuilder nextModule = null;
650 // try resolve other module augments
652 nextModule = allModulesIterator.next();
653 resolveAugment(modules, nextModule);
654 } catch (NoSuchElementException e) {
655 throw new YangParseException("Failed to resolve augments in module '" + module.getName() + "'.", e);
657 // then try to resolve first module again
658 resolveAugment(modules, module);
664 * Tries to resolve augments in given module. If augment target node is not
668 * all available modules
672 private void resolveAugment(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
673 if (module.getAugmentsResolved() < module.getAugments().size()) {
674 for (AugmentationSchemaBuilder augmentBuilder : module.getAugments()) {
676 if (!augmentBuilder.isResolved()) {
677 final SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();
678 final List<QName> path = augmentTargetSchemaPath.getPath();
680 final QName qname = path.get(0);
681 String prefix = qname.getPrefix();
682 if (prefix == null) {
683 prefix = module.getPrefix();
686 final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix,
687 augmentBuilder.getLine());
688 processAugmentation(augmentBuilder, path, module, qname, dependentModule);
696 * Go through all augment definitions and resolve them. This method works in
697 * same way as {@link #resolveAugments(Map)} except that if target node is
698 * not found in loaded modules, it search for target node in given context.
703 * SchemaContext containing already resolved modules
705 private void resolveAugmentsWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
706 final SchemaContext context) {
707 final List<ModuleBuilder> allModulesList = new ArrayList<ModuleBuilder>();
708 final Set<ModuleBuilder> allModulesSet = new HashSet<ModuleBuilder>();
709 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
710 for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
711 allModulesList.add(inner.getValue());
712 allModulesSet.add(inner.getValue());
716 for (int i = 0; i < allModulesList.size(); i++) {
717 final ModuleBuilder module = allModulesList.get(i);
718 // try to resolve augments in module
719 resolveAugmentWithContext(modules, module, context);
720 // while all augments are not resolved
721 final Iterator<ModuleBuilder> allModulesIterator = allModulesSet.iterator();
722 while (!(module.getAugmentsResolved() == module.getAugments().size())) {
723 ModuleBuilder nextModule = null;
724 // try resolve other module augments
726 nextModule = allModulesIterator.next();
727 resolveAugmentWithContext(modules, nextModule, context);
728 } catch (NoSuchElementException e) {
729 throw new YangParseException("Failed to resolve augments in module '" + module.getName() + "'.", e);
731 // then try to resolve first module again
732 resolveAugmentWithContext(modules, module, context);
738 * Tries to resolve augments in given module. If augment target node is not
742 * all available modules
746 private void resolveAugmentWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
747 final ModuleBuilder module, final SchemaContext context) {
748 if (module.getAugmentsResolved() < module.getAugments().size()) {
750 for (AugmentationSchemaBuilder augmentBuilder : module.getAugments()) {
751 final int line = augmentBuilder.getLine();
753 if (!augmentBuilder.isResolved()) {
754 final List<QName> path = augmentBuilder.getTargetPath().getPath();
755 final QName qname = path.get(0);
756 String prefix = qname.getPrefix();
757 if (prefix == null) {
758 prefix = module.getPrefix();
761 // try to find augment target module in loaded modules...
762 final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix,
764 if (dependentModuleBuilder == null) {
765 // perform augmentation on module from context and
766 // continue to next augment
767 processAugmentationOnContext(augmentBuilder, path, module, prefix, line, context);
770 processAugmentation(augmentBuilder, path, module, qname, dependentModuleBuilder);
779 * Go through identity statements defined in current module and resolve
780 * their 'base' statement if present.
785 * module being resolved
787 private void resolveIdentities(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
788 final Set<IdentitySchemaNodeBuilder> identities = module.getIdentities();
789 for (IdentitySchemaNodeBuilder identity : identities) {
790 final String baseIdentityName = identity.getBaseIdentityName();
791 if (baseIdentityName != null) {
792 String baseIdentityPrefix = null;
793 String baseIdentityLocalName = null;
794 if (baseIdentityName.contains(":")) {
795 final String[] splitted = baseIdentityName.split(":");
796 baseIdentityPrefix = splitted[0];
797 baseIdentityLocalName = splitted[1];
799 baseIdentityPrefix = module.getPrefix();
800 baseIdentityLocalName = baseIdentityName;
802 final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, baseIdentityPrefix,
805 final Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule.getIdentities();
806 for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
807 if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) {
808 identity.setBaseIdentity(idBuilder);
816 * Go through identity statements defined in current module and resolve
817 * their 'base' statement. Method tries to find base identity in given
818 * modules. If base identity is not found, method will search it in context.
825 * SchemaContext containing already resolved modules
827 private void resolveIdentitiesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
828 final ModuleBuilder module, final SchemaContext context) {
829 final Set<IdentitySchemaNodeBuilder> identities = module.getIdentities();
830 for (IdentitySchemaNodeBuilder identity : identities) {
831 final String baseIdentityName = identity.getBaseIdentityName();
832 if (baseIdentityName != null) {
833 String baseIdentityPrefix = null;
834 String baseIdentityLocalName = null;
835 if (baseIdentityName.contains(":")) {
836 final String[] splitted = baseIdentityName.split(":");
837 baseIdentityPrefix = splitted[0];
838 baseIdentityLocalName = splitted[1];
840 baseIdentityPrefix = module.getPrefix();
841 baseIdentityLocalName = baseIdentityName;
843 final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module,
844 baseIdentityPrefix, identity.getLine());
846 if (dependentModuleBuilder == null) {
847 final Module dependentModule = findModuleFromContext(context, module, baseIdentityPrefix,
849 final Set<IdentitySchemaNode> dependentModuleIdentities = dependentModule.getIdentities();
850 for (IdentitySchemaNode idNode : dependentModuleIdentities) {
851 if (idNode.getQName().getLocalName().equals(baseIdentityLocalName)) {
852 identity.setBaseIdentity(idNode);
856 final Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModuleBuilder
858 for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
859 if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) {
860 identity.setBaseIdentity(idBuilder);
869 * Go through uses statements defined in current module and resolve their
875 * module being resolved
877 private void resolveUsesRefine(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
878 final Map<List<String>, UsesNodeBuilder> moduleUses = module.getUsesNodes();
879 for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses.entrySet()) {
881 final UsesNodeBuilder usesNode = entry.getValue();
882 final int line = usesNode.getLine();
883 final GroupingBuilder targetGrouping = getTargetGroupingFromModules(usesNode, modules, module);
884 usesNode.setGroupingPath(targetGrouping.getPath());
885 for (RefineHolder refine : usesNode.getRefines()) {
886 final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder(targetGrouping,
887 refine, module.getName());
888 if(nodeToRefine instanceof GroupingMember) {
889 ((GroupingMember)nodeToRefine).setAddedByUses(true);
891 RefineUtils.performRefine(nodeToRefine, refine, line);
892 usesNode.addRefineNode(nodeToRefine);
896 processUsesNode(usesNode, targetGrouping);
901 * Tries to search target grouping in given modules and resolve refine
902 * nodes. If grouping is not found in modules, method tries to find it in
903 * modules from context.
910 * SchemaContext containing already resolved modules
912 private void resolveUsesRefineWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
913 final ModuleBuilder module, final SchemaContext context) {
914 final Map<List<String>, UsesNodeBuilder> moduleUses = module.getUsesNodes();
915 for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses.entrySet()) {
916 final UsesNodeBuilder usesNode = entry.getValue();
917 final int line = usesNode.getLine();
919 final GroupingBuilder targetGroupingBuilder = getTargetGroupingFromModules(usesNode, modules, module);
920 if (targetGroupingBuilder == null) {
921 final GroupingDefinition targetGrouping = getTargetGroupingFromContext(usesNode, module, context);
922 usesNode.setGroupingPath(targetGrouping.getPath());
923 for (RefineHolder refine : usesNode.getRefines()) {
924 final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingDefinition(
925 targetGrouping, refine, module.getName());
926 if(nodeToRefine instanceof GroupingMember) {
927 ((GroupingMember)nodeToRefine).setAddedByUses(true);
929 RefineUtils.performRefine(nodeToRefine, refine, line);
930 usesNode.addRefineNode(nodeToRefine);
933 processUsesNode(usesNode, targetGrouping);
935 usesNode.setGroupingPath(targetGroupingBuilder.getPath());
936 for (RefineHolder refine : usesNode.getRefines()) {
937 final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder(
938 targetGroupingBuilder, refine, module.getName());
939 if(nodeToRefine instanceof GroupingMember) {
940 ((GroupingMember)nodeToRefine).setAddedByUses(true);
942 RefineUtils.performRefine(nodeToRefine, refine, line);
943 usesNode.addRefineNode(nodeToRefine);
946 processUsesNode(usesNode, targetGroupingBuilder);
952 * Search given modules for grouping by name defined in uses node.
955 * builder of uses statement
960 * @return grouping with given name if found, null otherwise
962 private GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
963 final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
964 final int line = usesBuilder.getLine();
965 final String groupingString = usesBuilder.getGroupingName();
966 String groupingPrefix;
969 if (groupingString.contains(":")) {
970 String[] splitted = groupingString.split(":");
971 if (splitted.length != 2 || groupingString.contains("/")) {
972 throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
974 groupingPrefix = splitted[0];
975 groupingName = splitted[1];
977 groupingPrefix = module.getPrefix();
978 groupingName = groupingString;
981 ModuleBuilder dependentModule = null;
982 if (groupingPrefix.equals(module.getPrefix())) {
983 dependentModule = module;
985 dependentModule = findDependentModuleBuilder(modules, module, groupingPrefix, line);
988 if (dependentModule == null) {
992 List<QName> path = usesBuilder.getParent().getPath().getPath();
993 GroupingBuilder result = null;
994 Set<GroupingBuilder> groupings = dependentModule.getModuleGroupings();
995 result = findGroupingBuilder(groupings, groupingName);
997 if (result == null) {
998 Builder currentNode = null;
999 final List<String> currentPath = new ArrayList<String>();
1000 currentPath.add(dependentModule.getName());
1002 for (int i = 0; i < path.size(); i++) {
1003 QName qname = path.get(i);
1004 currentPath.add(qname.getLocalName());
1005 currentNode = dependentModule.getModuleNode(currentPath);
1007 if (currentNode instanceof RpcDefinitionBuilder) {
1008 groupings = ((RpcDefinitionBuilder) currentNode).getGroupings();
1009 } else if (currentNode instanceof DataNodeContainerBuilder) {
1010 groupings = ((DataNodeContainerBuilder) currentNode).getGroupingBuilders();
1012 groupings = Collections.emptySet();
1015 result = findGroupingBuilder(groupings, groupingName);
1016 if (result != null) {
1026 * Search context for grouping by name defined in uses node.
1028 * @param usesBuilder
1029 * builder of uses statement
1033 * SchemaContext containing already resolved modules
1034 * @return grouping with given name if found, null otherwise
1036 private GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder,
1037 final ModuleBuilder module, final SchemaContext context) {
1038 final int line = usesBuilder.getLine();
1039 String groupingString = usesBuilder.getGroupingName();
1040 String groupingPrefix;
1041 String groupingName;
1043 if (groupingString.contains(":")) {
1044 String[] splitted = groupingString.split(":");
1045 if (splitted.length != 2 || groupingString.contains("/")) {
1046 throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
1048 groupingPrefix = splitted[0];
1049 groupingName = splitted[1];
1051 groupingPrefix = module.getPrefix();
1052 groupingName = groupingString;
1055 Module dependentModule = findModuleFromContext(context, module, groupingPrefix, line);
1056 return findGroupingDefinition(dependentModule.getGroupings(), groupingName);
1060 * Add nodes defined in target grouping to current context.
1063 * @param targetGrouping
1065 private void processUsesNode(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
1066 List<SchemaNodeBuilder> refineNodes = usesNode.getRefineNodes();
1067 DataNodeContainerBuilder parent = usesNode.getParent();
1068 SchemaPath parentPath = parent.getPath();
1069 for (DataSchemaNodeBuilder child : targetGrouping.getChildNodeBuilders()) {
1070 // if node is refined, take it from refined nodes and continue
1071 SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes);
1072 if(refined != null) {
1073 refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName()));
1074 parent.addChildNode((DataSchemaNodeBuilder)refined);
1078 DataSchemaNodeBuilder newChild = null;
1079 if (child instanceof AnyXmlBuilder) {
1080 newChild = new AnyXmlBuilder((AnyXmlBuilder) child);
1081 } else if (child instanceof ChoiceBuilder) {
1082 newChild = new ChoiceBuilder((ChoiceBuilder) child);
1083 } else if (child instanceof ContainerSchemaNodeBuilder) {
1084 newChild = new ContainerSchemaNodeBuilder((ContainerSchemaNodeBuilder) child);
1085 } else if (child instanceof LeafListSchemaNodeBuilder) {
1086 newChild = new LeafListSchemaNodeBuilder((LeafListSchemaNodeBuilder) child);
1087 } else if (child instanceof LeafSchemaNodeBuilder) {
1088 newChild = new LeafSchemaNodeBuilder((LeafSchemaNodeBuilder) child);
1089 } else if (child instanceof ListSchemaNodeBuilder) {
1090 newChild = new ListSchemaNodeBuilder((ListSchemaNodeBuilder) child);
1093 if (newChild instanceof GroupingMember) {
1094 ((GroupingMember) newChild).setAddedByUses(true);
1096 newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName()));
1097 parent.addChildNode(newChild);
1099 for (GroupingBuilder g : targetGrouping.getGroupingBuilders()) {
1100 GroupingBuilder newGrouping = new GroupingBuilderImpl(g);
1101 newGrouping.setAddedByUses(true);
1102 newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName()));
1103 parent.addGrouping(newGrouping);
1105 for (TypeDefinitionBuilder td : targetGrouping.getTypeDefinitionBuilders()) {
1106 TypeDefinitionBuilder newType = new TypeDefinitionBuilderImpl(td);
1107 newType.setAddedByUses(true);
1108 newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName()));
1109 parent.addTypedef(newType);
1111 for (UsesNodeBuilder un : targetGrouping.getUses()) {
1112 UsesNodeBuilder newUses = new UsesNodeBuilderImpl(un);
1113 newUses.setAddedByUses(true);
1114 // uses has not path
1115 parent.addUsesNode(newUses);
1117 for (UnknownSchemaNodeBuilder un : targetGrouping.getUnknownNodes()) {
1118 UnknownSchemaNodeBuilder newUn = new UnknownSchemaNodeBuilder(un);
1119 newUn.setAddedByUses(true);
1120 newUn.setPath(createSchemaPath(parentPath, un.getQName().getLocalName()));
1121 parent.addUnknownSchemaNode(newUn);
1125 private void processUsesNode(final UsesNodeBuilder usesNode, final GroupingDefinition targetGrouping) {
1126 final int line = usesNode.getLine();
1127 List<SchemaNodeBuilder> refineNodes = usesNode.getRefineNodes();
1128 DataNodeContainerBuilder parent = usesNode.getParent();
1129 SchemaPath parentPath = parent.getPath();
1130 for (DataSchemaNode child : targetGrouping.getChildNodes()) {
1131 // if node is refined, take it from refined nodes and continue
1132 SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes);
1133 if(refined != null) {
1134 refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName()));
1135 parent.addChildNode((DataSchemaNodeBuilder)refined);
1139 DataSchemaNodeBuilder newChild = null;
1140 if (child instanceof AnyXmlSchemaNode) {
1141 newChild = createAnyXml((AnyXmlSchemaNode) child, line);
1142 } else if (child instanceof ChoiceNode) {
1143 newChild = createChoice((ChoiceNode) child, line);
1144 } else if (child instanceof ContainerSchemaNode) {
1145 newChild = createContainer((ContainerSchemaNode) child, line);
1146 } else if (child instanceof LeafListSchemaNode) {
1147 newChild = createLeafList((LeafListSchemaNode) child, line);
1148 } else if (child instanceof LeafSchemaNode) {
1149 newChild = createLeafBuilder((LeafSchemaNode) child, line);
1150 } else if (child instanceof ListSchemaNode) {
1151 newChild = createList((ListSchemaNode) child, line);
1154 if (newChild instanceof GroupingMember) {
1155 ((GroupingMember) newChild).setAddedByUses(true);
1157 newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName()));
1158 parent.addChildNode(newChild);
1160 for (GroupingDefinition g : targetGrouping.getGroupings()) {
1161 GroupingBuilder newGrouping = createGrouping(g, line);
1162 newGrouping.setAddedByUses(true);
1163 newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName()));
1164 parent.addGrouping(newGrouping);
1166 for (TypeDefinition<?> td : targetGrouping.getTypeDefinitions()) {
1167 TypeDefinitionBuilder newType = createTypedef((ExtendedType) td, line);
1168 newType.setAddedByUses(true);
1169 newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName()));
1170 parent.addTypedef(newType);
1172 for (UsesNode un : targetGrouping.getUses()) {
1173 if (un instanceof UsesNodeImpl) {
1174 UsesNodeBuilder newUses = new UsesNodeBuilderImpl(((UsesNodeImpl) un).toBuilder());
1175 newUses.setAddedByUses(true);
1176 // uses has not path
1177 parent.addUsesNode(newUses);
1180 for (UnknownSchemaNode un : targetGrouping.getUnknownSchemaNodes()) {
1181 UnknownSchemaNodeBuilder newNode = createUnknownSchemaNode(un, line);
1182 newNode.setAddedByUses(true);
1183 newNode.setPath(createSchemaPath(parentPath, un.getQName().getLocalName()));
1184 parent.addUnknownSchemaNode(newNode);
1188 private QName findFullQName(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
1189 final IdentityrefTypeBuilder idref) {
1190 QName result = null;
1191 String baseString = idref.getBaseString();
1192 if (baseString.contains(":")) {
1193 String[] splittedBase = baseString.split(":");
1194 if (splittedBase.length > 2) {
1195 throw new YangParseException(module.getName(), idref.getLine(), "Failed to parse identityref base: "
1198 String prefix = splittedBase[0];
1199 String name = splittedBase[1];
1200 ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix, idref.getLine());
1201 result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name);
1203 result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString);
1208 private void resolveUnknownNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
1209 for (UnknownSchemaNodeBuilder usnb : module.getUnknownNodes()) {
1210 QName nodeType = usnb.getNodeType();
1211 if (nodeType.getNamespace() == null || nodeType.getRevision() == null) {
1213 ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, nodeType.getPrefix(),
1215 QName newNodeType = new QName(dependentModule.getNamespace(), dependentModule.getRevision(),
1216 nodeType.getPrefix(), nodeType.getLocalName());
1217 usnb.setNodeType(newNodeType);
1218 } catch (YangParseException e) {
1219 logger.debug(module.getName(), usnb.getLine(), "Failed to find unknown node type: " + nodeType);
1225 private void resolveUnknownNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
1226 final ModuleBuilder module, SchemaContext context) {
1227 for (UnknownSchemaNodeBuilder unknownNodeBuilder : module.getUnknownNodes()) {
1228 QName nodeType = unknownNodeBuilder.getNodeType();
1229 if (nodeType.getNamespace() == null || nodeType.getRevision() == null) {
1231 ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module,
1232 nodeType.getPrefix(), unknownNodeBuilder.getLine());
1234 QName newNodeType = null;
1235 if (dependentModuleBuilder == null) {
1236 Module dependentModule = findModuleFromContext(context, module, nodeType.getPrefix(),
1237 unknownNodeBuilder.getLine());
1238 newNodeType = new QName(dependentModule.getNamespace(), dependentModule.getRevision(),
1239 nodeType.getPrefix(), nodeType.getLocalName());
1241 newNodeType = new QName(dependentModuleBuilder.getNamespace(),
1242 dependentModuleBuilder.getRevision(), nodeType.getPrefix(), nodeType.getLocalName());
1245 unknownNodeBuilder.setNodeType(newNodeType);
1246 } catch (YangParseException e) {
1247 logger.debug(module.getName(), unknownNodeBuilder.getLine(), "Failed to find unknown node type: "