Populate parser/ hierarchy
[yangtools.git] / yang / rfc7952-data-util / src / main / java / org / opendaylight / yangtools / rfc7952 / data / util / ImmutableNormalizedMetadataStreamWriter.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.rfc7952.data.util;
9
10 import static com.google.common.base.Preconditions.checkState;
11
12 import com.google.common.annotations.Beta;
13 import com.google.common.collect.ImmutableMap;
14 import java.io.IOException;
15 import java.util.ArrayDeque;
16 import java.util.Deque;
17 import java.util.Optional;
18 import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadata;
19 import org.opendaylight.yangtools.rfc7952.data.api.StreamWriterMetadataExtension;
20 import org.opendaylight.yangtools.rfc7952.data.util.ImmutableNormalizedMetadata.Builder;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
23
24 /**
25  * A simple {@link StreamWriterMetadataExtension} implementation, which takes care of building
26  * {@link NormalizedMetadata} based on additional nesting instructions.
27  */
28 @Beta
29 public final class ImmutableNormalizedMetadataStreamWriter implements StreamWriterMetadataExtension {
30     private final Deque<Builder> builders = new ArrayDeque<>();
31
32     private ImmutableNormalizedMetadata result;
33
34     public void enter(final PathArgument identifier) {
35         checkNotDone();
36         builders.push(ImmutableNormalizedMetadata.builder().withIdentifier(identifier));
37     }
38
39     public void exit() {
40         checkNotDone();
41         final ImmutableNormalizedMetadata metadata = builders.pop().build();
42         final Builder parent = builders.peek();
43         if (parent != null) {
44             if (!metadata.getAnnotations().isEmpty()) {
45                 parent.withChild(metadata);
46             }
47         } else {
48             result = metadata;
49         }
50     }
51
52     public Optional<NormalizedMetadata> getResult() {
53         checkState(result != null, "Metadata tree has not been completely built");
54         return result.getAnnotations().isEmpty() ? Optional.empty() : Optional.of(result);
55     }
56
57     @Override
58     public void metadata(final ImmutableMap<QName, Object> metadata) throws IOException {
59         builders.peek().withAnnotations(metadata);
60     }
61
62     private void checkNotDone() {
63         checkState(result != null, "Metadata already completed");
64     }
65 }