Simplify InferredStatementContext.hasEmptySubstatements()
[yangtools.git] / parser / yang-parser-reactor / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / BehaviourNamespaceAccess.java
1 /*
2  * Copyright (c) 2023 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.parser.stmt.reactor;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.MoreObjects;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Map.Entry;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
19 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.GlobalStorage;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
23
24 /**
25  * A {@link NamespaceAccess} backed by a {@link NamespaceBehaviour}. Also holds reference to {@link BuildGlobalContext}.
26  */
27 final class BehaviourNamespaceAccess<K, V> extends NamespaceAccess<K, V> {
28     private final @NonNull NamespaceBehaviour<K, V> behaviour;
29     private final @NonNull GlobalStorage globalStorage;
30
31     // FIXME: Change this to Multimap, once issue with modules is resolved.
32     private List<KeyedValueAddedListener<K>> listeners;
33     private List<PredicateValueAddedListener<K, V>> predicateListeners;
34
35     BehaviourNamespaceAccess(final GlobalStorage globalStorage, final NamespaceBehaviour<K, V> behaviour) {
36         this.globalStorage = requireNonNull(globalStorage);
37         this.behaviour = requireNonNull(behaviour);
38     }
39
40     @Override
41     ParserNamespace<K, V> namespace() {
42         return behaviour.namespace();
43     }
44
45     @Override
46     V valueFrom(final NamespaceStorage storage, final K key) {
47         return behaviour.getFrom(globalStorage, storage, key);
48     }
49
50     @Override
51     void valueTo(final NamespaceStorage storage, final K key, final V value) {
52         behaviour.addTo(globalStorage, storage, key, value);
53
54         if (listeners != null) {
55             final var toNotify = new ArrayList<KeyedValueAddedListener<K>>();
56             final var it = listeners.iterator();
57             while (it.hasNext()) {
58                 final var listener = it.next();
59                 if (listener.isRequestedValue(this, storage, value)) {
60                     it.remove();
61                     toNotify.add(listener);
62                 }
63             }
64             for (var listener : toNotify) {
65                 listener.onValueAdded(value);
66             }
67
68             if (listeners != null && listeners.isEmpty()) {
69                 listeners = null;
70             }
71         }
72
73         if (predicateListeners != null) {
74             final var it = predicateListeners.iterator();
75             while (it.hasNext()) {
76                 if (it.next().onValueAdded(key, value)) {
77                     it.remove();
78                 }
79             }
80             if (predicateListeners != null && predicateListeners.isEmpty()) {
81                 predicateListeners = null;
82             }
83         }
84     }
85
86     @Override
87     Map<K, V> allFrom(final NamespaceStorage storage) {
88         return behaviour.getAllFrom(globalStorage, storage);
89     }
90
91     @Override
92     Entry<K, V> entryFrom(final NamespaceStorage storage, final NamespaceKeyCriterion<K> criterion) {
93         return behaviour.getFrom(globalStorage, storage, criterion);
94     }
95
96     @Override
97     void addListener(final KeyedValueAddedListener<K> listener) {
98         if (listeners == null) {
99             listeners = new ArrayList<>();
100         }
101         listeners.add(listener);
102     }
103
104     @Override
105     void addListener(final PredicateValueAddedListener<K, V> listener) {
106         if (predicateListeners == null) {
107             predicateListeners = new ArrayList<>();
108         }
109         predicateListeners.add(listener);
110     }
111
112     @Override
113     public String toString() {
114         return MoreObjects.toStringHelper(this).add("behaviour", behaviour).toString();
115     }
116 }