2 * Copyright (c) 2019 PANTHEON.tech, s.r.o. 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.data.impl.schema;
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.annotations.Beta;
14 import com.google.common.collect.ImmutableMap;
15 import java.io.IOException;
16 import java.util.ArrayDeque;
17 import java.util.Deque;
18 import java.util.List;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
23 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedMetadata;
24 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.builder.NormalizedNodeBuilder;
26 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter.MetadataExtension;
27 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedMetadata.Builder;
30 * A {@link NormalizedMetadata}-aware {@link ImmutableMetadataNormalizedNodeStreamWriter}. It advertizes the
31 * {@link MetadataExtension} extension.
34 public class ImmutableMetadataNormalizedNodeStreamWriter extends ImmutableNormalizedNodeStreamWriter
35 implements MetadataExtension {
37 * Snapshot of currently-open data- and metadatastate.
39 public static final class State {
40 final BuilderEntry metaBuilder;
41 final NormalizedNode.Builder dataBuilder;
43 State(final NormalizedNode.Builder dataBuilder, final BuilderEntry metadataBuilder) {
44 this.dataBuilder = requireNonNull(dataBuilder);
45 metaBuilder = requireNonNull(metadataBuilder);
48 public NormalizedNode.Builder getDataBuilder() {
52 public Builder getMetaBuilder() {
53 return metaBuilder.builder;
58 private record BuilderEntry(PathArgument identifier, Builder builder) {
60 requireNonNull(identifier);
61 requireNonNull(builder);
65 private final Deque<BuilderEntry> builders = new ArrayDeque<>();
66 private final NormalizationResultHolder holder;
68 protected ImmutableMetadataNormalizedNodeStreamWriter(final State state) {
69 super(state.dataBuilder);
70 builders.push(state.metaBuilder);
74 protected ImmutableMetadataNormalizedNodeStreamWriter(final NormalizationResultHolder holder) {
76 this.holder = requireNonNull(holder);
80 public final List<MetadataExtension> supportedExtensions() {
85 public final void metadata(final ImmutableMap<QName, Object> metadata) throws IOException {
86 final var current = builders.peek();
87 checkState(current != null, "Attempted to emit metadata when no metadata is open");
88 current.builder.withAnnotations(metadata);
92 * Remove the currently-open builders for data and metadata from the stack.
94 * @return Builder state.
96 protected final @NonNull State popState() {
97 return new State(popBuilder(), builders.pop());
101 @SuppressWarnings("rawtypes")
102 final void enter(final PathArgument identifier, final NormalizedNodeBuilder next) {
103 super.enter(identifier, next);
104 builders.push(new BuilderEntry(identifier, ImmutableNormalizedMetadata.builder()));
108 public final void endNode() {
111 final var last = builders.pop();
112 final var metadata = last.builder.build();
113 final var current = builders.peek();
114 if (current != null) {
115 if (!metadata.getAnnotations().isEmpty() || !metadata.getChildren().isEmpty()) {
116 current.builder.withChild(last.identifier, metadata);
120 holder.setMetadata(metadata);