+ private static @NonNull DataTree createDataTree(final DataTreeConfiguration treeConfig,
+ final EffectiveModelContext initialSchemaContext, final boolean maskMandatory) {
+ final DataSchemaNode rootSchemaNode = getRootSchemaNode(initialSchemaContext, treeConfig.getRootPath());
+ final NormalizedNode<?, ?> rootDataNode = createRoot((DataNodeContainer)rootSchemaNode,
+ treeConfig.getRootPath());
+ return new InMemoryDataTree(TreeNodeFactory.createTreeNode(rootDataNode, Version.initial()), treeConfig,
+ initialSchemaContext, rootSchemaNode, maskMandatory);
+ }
+
+ private static @NonNull NormalizedNode<?, ?> createRoot(final DataNodeContainer schemaNode,
+ final YangInstanceIdentifier path) {
+ if (path.isEmpty()) {
+ checkArgument(schemaNode instanceof ContainerLike,
+ "Conceptual tree root has to be a container, not %s", schemaNode);
+ return ROOT_CONTAINER;
+ }
+
+ final PathArgument arg = path.getLastPathArgument();
+ if (schemaNode instanceof ContainerSchemaNode) {
+ checkArgument(arg instanceof NodeIdentifier, "Mismatched container %s path %s", schemaNode, path);
+ return ImmutableContainerNodeBuilder.create().withNodeIdentifier((NodeIdentifier) arg).build();
+ } else if (schemaNode instanceof ListSchemaNode) {
+ // This can either be a top-level list or its individual entry
+ if (arg instanceof NodeIdentifierWithPredicates) {
+ return ImmutableNodes.mapEntryBuilder().withNodeIdentifier((NodeIdentifierWithPredicates) arg).build();
+ }
+ checkArgument(arg instanceof NodeIdentifier, "Mismatched list %s path %s", schemaNode, path);
+ return ImmutableNodes.mapNodeBuilder().withNodeIdentifier((NodeIdentifier) arg).build();
+ } else {
+ throw new IllegalArgumentException("Unsupported root schema " + schemaNode);
+ }
+ }
+
+ private static @NonNull NormalizedNode<?, ?> createRoot(final YangInstanceIdentifier path) {
+ if (path.isEmpty()) {
+ return ROOT_CONTAINER;
+ }
+
+ final PathArgument arg = path.getLastPathArgument();
+ if (arg instanceof NodeIdentifier) {
+ return ImmutableContainerNodeBuilder.create().withNodeIdentifier((NodeIdentifier) arg).build();
+ }
+ if (arg instanceof NodeIdentifierWithPredicates) {
+ return ImmutableNodes.mapEntryBuilder().withNodeIdentifier((NodeIdentifierWithPredicates) arg).build();
+ }
+
+ // FIXME: implement augmentations and leaf-lists
+ throw new IllegalArgumentException("Unsupported root node " + arg);
+ }
+
+ private static DataSchemaNode getRootSchemaNode(final EffectiveModelContext schemaContext,
+ final YangInstanceIdentifier rootPath) {
+ final DataSchemaContextTree contextTree = DataSchemaContextTree.from(schemaContext);
+ final Optional<DataSchemaContextNode<?>> rootContextNode = contextTree.findChild(rootPath);
+ checkArgument(rootContextNode.isPresent(), "Failed to find root %s in schema context", rootPath);
+
+ final DataSchemaNode rootSchemaNode = rootContextNode.get().getDataSchemaNode();
+ checkArgument(rootSchemaNode instanceof DataNodeContainer, "Root %s resolves to non-container type %s",
+ rootPath, rootSchemaNode);
+ return rootSchemaNode;