Fix BuiltInType mapping
[yangtools.git] / binding / binding-spec / src / main / java / org / opendaylight / yangtools / binding / contract / BuiltInType.java
1 /*
2  * Copyright (c) 2024 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.binding.contract;
9
10 import static java.util.Objects.requireNonNull;
11
12 import org.eclipse.jdt.annotation.NonNull;
13 import org.opendaylight.yangtools.binding.BaseIdentity;
14 import org.opendaylight.yangtools.binding.BindingInstanceIdentifier;
15 import org.opendaylight.yangtools.binding.BitsTypeObject;
16 import org.opendaylight.yangtools.binding.EnumTypeObject;
17 import org.opendaylight.yangtools.binding.UnionTypeObject;
18 import org.opendaylight.yangtools.yang.common.Decimal64;
19 import org.opendaylight.yangtools.yang.common.Empty;
20 import org.opendaylight.yangtools.yang.common.Uint16;
21 import org.opendaylight.yangtools.yang.common.Uint32;
22 import org.opendaylight.yangtools.yang.common.Uint64;
23 import org.opendaylight.yangtools.yang.common.Uint8;
24
25 /**
26  * Mapping of a YANG built-in type to its base Java class. Note that {@code type leafref} does not have an associated
27  * type mapping.
28  *
29  * @param <T> Java type
30  */
31 public final class BuiltInType<T> {
32     // Ordered by RFC7950 section defining the type
33     public static final @NonNull BuiltInType<@NonNull Byte> INT8 = new BuiltInType<>("int8", Byte.class);
34     public static final @NonNull BuiltInType<@NonNull Short> INT16 = new BuiltInType<>("int16", Short.class);
35     public static final @NonNull BuiltInType<@NonNull Integer> INT32 = new BuiltInType<>("int32", Integer.class);
36     public static final @NonNull BuiltInType<@NonNull Long> INT64 = new BuiltInType<>("int64", Long.class);
37     public static final @NonNull BuiltInType<@NonNull Uint8> UINT8 = new BuiltInType<>("uint8", Uint8.class);
38     public static final @NonNull BuiltInType<@NonNull Uint16> UINT16 = new BuiltInType<>("uint16", Uint16.class);
39     public static final @NonNull BuiltInType<@NonNull Uint32> UINT32 = new BuiltInType<>("uint32", Uint32.class);
40     public static final @NonNull BuiltInType<@NonNull Uint64> UINT64 = new BuiltInType<>("uint64", Uint64.class);
41     public static final @NonNull BuiltInType<@NonNull Decimal64> DECIMAL64 =
42         new BuiltInType<>("decimal64", Decimal64.class);
43     public static final @NonNull BuiltInType<@NonNull String> STRING = new BuiltInType<>("string", String.class);
44     public static final @NonNull BuiltInType<@NonNull Boolean> BOOLEAN = new BuiltInType<>("boolean", Boolean.class);
45     public static final @NonNull BuiltInType<@NonNull EnumTypeObject> ENUMERATION =
46         new BuiltInType<>("enumeration", EnumTypeObject.class);
47     public static final @NonNull BuiltInType<@NonNull BitsTypeObject> BITS =
48         new BuiltInType<>("bits", BitsTypeObject.class);
49     public static final @NonNull BuiltInType<byte @NonNull []> BINARY = new BuiltInType<>("binary", byte[].class);
50     public static final @NonNull BuiltInType<@NonNull BaseIdentity> IDENTITYREF =
51         new BuiltInType<>("identityref", BaseIdentity.class);
52     public static final @NonNull BuiltInType<@NonNull Empty> EMPTY = new BuiltInType<>("empty", Empty.class);
53     public static final @NonNull BuiltInType<@NonNull UnionTypeObject> UNION =
54         new BuiltInType<>("union", UnionTypeObject.class);
55     public static final @NonNull BuiltInType<@NonNull BindingInstanceIdentifier> INSTANCE_IDENTIFIER =
56         new BuiltInType<>("instance-identifier", BindingInstanceIdentifier.class);
57
58     private final @NonNull Class<T> javaClass;
59     private final String str;
60
61     private BuiltInType(final @NonNull String str, final @NonNull Class<T> javaClass) {
62         this.str = requireNonNull(str);
63         this.javaClass = requireNonNull(javaClass);
64     }
65
66     public static @NonNull BuiltInType<?> of(final Object obj) {
67         return switch (obj) {
68             case Byte value -> INT8;
69             case Short value -> INT16;
70             case Integer value -> INT32;
71             case Long value -> INT64;
72             case Uint8 value -> UINT8;
73             case Uint16 value -> UINT16;
74             case Uint32 value -> UINT32;
75             case Uint64 value -> UINT64;
76             case Decimal64 value -> DECIMAL64;
77             case String value -> STRING;
78             case Boolean value -> BOOLEAN;
79             case EnumTypeObject value -> ENUMERATION;
80             case BitsTypeObject value -> BITS;
81             case byte[] value -> BINARY;
82             case BaseIdentity value -> IDENTITYREF;
83             case Empty value -> EMPTY;
84             case UnionTypeObject value -> UNION;
85             case BindingInstanceIdentifier value -> INSTANCE_IDENTIFIER;
86             default -> throw new IllegalArgumentException("Invalid value " + obj);
87         };
88     }
89
90     public static @NonNull Object checkValue(final Object obj) {
91         return switch (obj) {
92             case @NonNull Byte value -> value;
93             case @NonNull Short value -> value;
94             case @NonNull Integer value -> value;
95             case @NonNull Long value -> value;
96             case @NonNull Uint8 value -> value;
97             case @NonNull Uint16 value -> value;
98             case @NonNull Uint32 value -> value;
99             case @NonNull Uint64 value -> value;
100             case @NonNull Decimal64 value -> value;
101             case @NonNull String value -> value;
102             case @NonNull Boolean value -> value;
103             case @NonNull EnumTypeObject value -> value;
104             case @NonNull BitsTypeObject value -> value;
105             case byte @NonNull [] value -> value;
106             case @NonNull BaseIdentity value -> value;
107             case @NonNull Empty value -> value;
108             case @NonNull UnionTypeObject value -> value;
109             case @NonNull BindingInstanceIdentifier value -> value;
110             default -> throw new IllegalArgumentException("Invalid value " + obj);
111         };
112     }
113
114     /**
115      * Return the Java class carrying values of this type.
116      *
117      * @return the Java class carrying values of this type
118      */
119     public @NonNull Class<T> javaClass() {
120         return javaClass;
121     }
122
123     /**
124      * Cast an value object to this built-in type. Unlike {@link Class#cast(Object)}, this method does not tolarate
125      * {@code null}s.
126      *
127      * @param obj value object
128      * @return the value object
129      * @throws ClassCastException if the object is not of expected type
130      * @throws NullPointerException if the object is null
131      */
132     public @NonNull T castValue(final Object obj) {
133         return requireNonNull(javaClass.cast(obj));
134     }
135
136     @Override
137     public int hashCode() {
138         return str.hashCode();
139     }
140
141     @Override
142     public boolean equals(final Object obj) {
143         return obj == this || obj instanceof BuiltInType<?> other
144             && javaClass.equals(other.javaClass) && str.equals(other.str);
145     }
146
147     @Override
148     public String toString() {
149         return "YANG " + str;
150     }
151 }