Seal YangSourceDefinition
[mdsal.git] / binding / mdsal-binding-model-api / src / main / java / org / opendaylight / mdsal / binding / model / api / YangSourceDefinition.java
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, 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.mdsal.binding.model.api;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.Beta;
14 import com.google.common.collect.ImmutableList;
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.Optional;
18 import java.util.stream.Collectors;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
21 import org.opendaylight.yangtools.yang.model.api.Module;
22 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
24 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
27
28 /**
29  * DTO capturing the YANG source definition which lead to a {@link GeneratedType} being emitted.
30  */
31 @Beta
32 @NonNullByDefault
33 public abstract sealed class YangSourceDefinition {
34     public static final class Multiple extends YangSourceDefinition {
35         private final List<? extends SchemaNode> nodes;
36
37         Multiple(final ModuleEffectiveStatement module, final Collection<? extends SchemaNode> nodes) {
38             super(module);
39             this.nodes = ImmutableList.copyOf(nodes);
40         }
41
42         /**
43          * Return the defining SchemaNodes. Each node is guaranteed to implement {@link EffectiveStatement} and have
44          * a corresponding declared statement.
45          *
46          * @return defining SchemaNodes, guaranteed to be non-empty
47          */
48         public List<? extends SchemaNode> getNodes() {
49             return nodes.stream().filter(node -> node instanceof EffectiveStatement
50                 && ((EffectiveStatement<?, ?>) node).getDeclared() != null).collect(Collectors.toList());
51         }
52     }
53
54     public static final class Single extends YangSourceDefinition {
55         private final DocumentedNode node;
56
57         Single(final ModuleEffectiveStatement module, final DocumentedNode node) {
58             super(module);
59             this.node = requireNonNull(node);
60         }
61
62         /**
63          * Return the defining DocumentedNode. The node is guaranteed to implement {@link EffectiveStatement} and have
64          * a corresponding declared statement.
65          *
66          * @return defining SchemaNodes, guaranteed to be non-empty
67          */
68         public DocumentedNode getNode() {
69             return node;
70         }
71     }
72
73     private final ModuleEffectiveStatement module;
74
75     private YangSourceDefinition(final ModuleEffectiveStatement module) {
76         this.module = requireNonNull(module);
77     }
78
79     public static Optional<YangSourceDefinition> of(final Module module) {
80         final ModuleEffectiveStatement effective = module.asEffectiveStatement();
81         final ModuleStatement declared = effective.getDeclared();
82         if (declared != null) {
83             return Optional.of(new Single(effective, module));
84         }
85         return Optional.empty();
86     }
87
88     public static Optional<YangSourceDefinition> of(final Module module, final SchemaNode node) {
89         return of(module.asEffectiveStatement(), node);
90     }
91
92     public static Optional<YangSourceDefinition> of(final ModuleEffectiveStatement module, final SchemaNode node) {
93         if (node instanceof EffectiveStatement) {
94             final DeclaredStatement<?> declared = ((EffectiveStatement<?, ?>) node).getDeclared();
95             if (declared != null) {
96                 return Optional.of(new Single(module, node));
97             }
98         }
99         return Optional.empty();
100     }
101
102     public static Optional<YangSourceDefinition> of(final Module module, final Collection<? extends SchemaNode> nodes) {
103         checkArgument(!nodes.isEmpty());
104
105         final boolean anyDeclared = nodes.stream().anyMatch(
106             node -> node instanceof EffectiveStatement && ((EffectiveStatement<?, ?>) node).getDeclared() != null);
107         if (anyDeclared) {
108             return Optional.of(new Multiple(module.asEffectiveStatement(), nodes));
109         }
110         return Optional.empty();
111     }
112
113     /**
114      * Return the defining YANG module.
115      *
116      * @return Defining YANG module.
117      */
118     public final ModuleEffectiveStatement getModule() {
119         return module;
120     }
121 }