Revert "Unify ORv1 and IIv5"
[yangtools.git] / data / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / ImmutableMountPointNormalizedNodeStreamWriter.java
1 /*
2  * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.impl.schema;
9
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.Beta;
14 import java.io.IOException;
15 import java.util.ArrayDeque;
16 import java.util.Deque;
17 import java.util.List;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.opendaylight.yangtools.yang.common.MountPointLabel;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
21 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.MountPointContext;
23 import org.opendaylight.yangtools.yang.data.api.schema.builder.NormalizedNodeBuilder;
24 import org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter;
25 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
26 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter.MountPointExtension;
27 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedMountpoints.Builder;
28
29 // FIXME: document usage of this
30 @Beta
31 public abstract class ImmutableMountPointNormalizedNodeStreamWriter extends ImmutableNormalizedNodeStreamWriter
32         implements MountPointExtension {
33     @NonNullByDefault
34     private record BuilderEntry(PathArgument identifier, Builder builder) {
35         BuilderEntry {
36             requireNonNull(identifier);
37             requireNonNull(builder);
38         }
39     }
40
41     private final Deque<BuilderEntry> builders = new ArrayDeque<>();
42     private final NormalizationResultHolder holder;
43
44     protected ImmutableMountPointNormalizedNodeStreamWriter(final NormalizationResultHolder holder) {
45         super(holder);
46         this.holder = requireNonNull(holder);
47     }
48
49     @Override
50     public final List<MountPointExtension> supportedExtensions() {
51         return List.of(this);
52     }
53
54     @Override
55     public final NormalizedNodeStreamWriter startMountPoint(final MountPointLabel label,
56             final MountPointContext mountCtx) {
57         final var current = builders.peek();
58         checkState(current != null, "Attempted to emit mount point when no data is open");
59
60         final var mountResult = new NormalizationResultHolder();
61         final var mountDelegate = ImmutableNormalizedNodeStreamWriter.from(mountResult);
62
63         return new ForwardingNormalizedNodeStreamWriter() {
64             @Override
65             protected NormalizedNodeStreamWriter delegate() {
66                 return mountDelegate;
67             }
68
69             @Override
70             public void close() throws IOException {
71                 super.close();
72
73                 final var result = mountResult.getResult();
74                 final var data = result.data();
75                 if (!(data instanceof ContainerNode container)) {
76                     throw new IOException("Unhandled mount data " + data);
77                 }
78
79                 current.builder.withMountPoint(new ImmutableNormalizedMountPoint(label, mountCtx, container,
80                     result.metadata(), result.mountPoints()));
81             }
82         };
83     }
84
85     @Override
86     @SuppressWarnings("rawtypes")
87     final void enter(final PathArgument identifier, final NormalizedNodeBuilder next) {
88         super.enter(identifier, next);
89         builders.push(new BuilderEntry(identifier, ImmutableNormalizedMountpoints.builder()));
90     }
91
92     @Override
93     public final void endNode() {
94         super.endNode();
95
96         final var last = builders.pop();
97         final var mountPoints = last.builder.build();
98         final var current = builders.peek();
99         if (current != null) {
100             if (mountPoints.mountPoint() != null || !mountPoints.getChildren().isEmpty()) {
101                 current.builder.withChild(last.identifier, mountPoints);
102             }
103         } else {
104             // All done
105             holder.setMountPoints(mountPoints);
106         }
107     }
108 }
109