BUG-3399: fix BaseYangTypes' range constraints
[yangtools.git] / code-generator / binding-type-provider / src / main / java / org / opendaylight / yangtools / sal / binding / yang / types / BaseYangTypes.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. 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.sal.binding.yang.types;
9
10 import com.google.common.base.Optional;
11 import java.math.BigDecimal;
12 import java.math.BigInteger;
13 import java.util.Collections;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17 import org.opendaylight.yangtools.binding.generator.util.Types;
18 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
19 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions;
20 import org.opendaylight.yangtools.sal.binding.model.api.Type;
21 import org.opendaylight.yangtools.yang.binding.BindingMapping;
22 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
23 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
26 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
27 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
28 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
29 import org.opendaylight.yangtools.yang.model.util.BaseConstraints;
30
31 public final class BaseYangTypes {
32     /**
33      * mapping of basic built-in YANG types (keys) to JAVA
34      * {@link org.opendaylight.yangtools.sal.binding.model.api.Type Type}. This
35      * map is filled with mapping data in static initialization block
36      */
37     private static Map<String, Type> typeMap = new HashMap<String, Type>();
38
39     /**
40      * <code>Type</code> representation of <code>boolean</code> YANG type
41      */
42     public static final Type BOOLEAN_TYPE = Types.typeForClass(Boolean.class);
43
44     /**
45      * <code>Type</code> representation of <code>empty</code> YANG type
46      */
47     public static final Type EMPTY_TYPE = Types.typeForClass(Boolean.class);
48
49     public static final Type ENUM_TYPE = Types.typeForClass(Enum.class);
50
51     /**
52      * <code>Type</code> representation of <code>int8</code> YANG type
53      */
54     public static final Type INT8_TYPE = Types.typeForClass(Byte.class);
55
56     /**
57      * <code>Type</code> representation of <code>int16</code> YANG type
58      */
59     public static final Type INT16_TYPE = Types.typeForClass(Short.class);
60
61     /**
62      * <code>Type</code> representation of <code>int32</code> YANG type
63      */
64     public static final Type INT32_TYPE = Types.typeForClass(Integer.class);
65
66     /**
67      * <code>Type</code> representation of <code>int64</code> YANG type
68      */
69     public static final Type INT64_TYPE = Types.typeForClass(Long.class);
70
71     /**
72      * <code>Type</code> representation of <code>string</code> YANG type
73      */
74     public static final Type STRING_TYPE = Types.typeForClass(String.class);
75
76     /**
77      * <code>Type</code> representation of <code>decimal64</code> YANG type
78      */
79     public static final Type DECIMAL64_TYPE = Types.typeForClass(BigDecimal.class);
80
81     /**
82      * <code>Type</code> representation of <code>uint8</code> YANG type
83      */
84     public static final Type UINT8_TYPE = Types.typeForClass(Short.class, singleRangeRestrictions((short)0, (short)255));
85
86     /**
87      * <code>Type</code> representation of <code>uint16</code> YANG type
88      */
89     public static final Type UINT16_TYPE = Types.typeForClass(Integer.class, singleRangeRestrictions(0, 65535));
90
91     /**
92      * <code>Type</code> representation of <code>uint32</code> YANG type
93      */
94     public static final Type UINT32_TYPE = Types.typeForClass(Long.class, singleRangeRestrictions(0L, 4294967295L));
95
96     /**
97      * <code>Type</code> representation of <code>uint64</code> YANG type
98      */
99     public static final Type UINT64_TYPE = Types.typeForClass(BigInteger.class,
100             singleRangeRestrictions(BigInteger.ZERO, new BigInteger("18446744073709551615")));
101
102     public static final Type UNION_TYPE = new UnionType();
103
104     /**
105      * <code>Type</code> representation of <code>binary</code> YANG type
106      */
107     public static final Type BINARY_TYPE = Types.primitiveType("byte[]", null);
108
109     public static final Type INSTANCE_IDENTIFIER = Types.parameterizedTypeFor(Types
110             .typeForClass(InstanceIdentifier.class));
111
112     /**
113      * It is undesirable to create instance of this class.
114      */
115     private BaseYangTypes() {
116     }
117
118     static {
119         typeMap.put("boolean", BOOLEAN_TYPE);
120         typeMap.put("empty", EMPTY_TYPE);
121         typeMap.put("enumeration", ENUM_TYPE);
122         typeMap.put("int8", INT8_TYPE);
123         typeMap.put("int16", INT16_TYPE);
124         typeMap.put("int32", INT32_TYPE);
125         typeMap.put("int64", INT64_TYPE);
126         typeMap.put("string", STRING_TYPE);
127         typeMap.put("decimal64", DECIMAL64_TYPE);
128         typeMap.put("uint8", UINT8_TYPE);
129         typeMap.put("uint16", UINT16_TYPE);
130         typeMap.put("uint32", UINT32_TYPE);
131         typeMap.put("uint64", UINT64_TYPE);
132         typeMap.put("union", UNION_TYPE);
133         typeMap.put("binary", BINARY_TYPE);
134         typeMap.put("instance-identifier", INSTANCE_IDENTIFIER);
135     }
136
137     public static final TypeProvider BASE_YANG_TYPES_PROVIDER = new TypeProvider() {
138         /**
139          * Searches <code>Type</code> value to which is YANG <code>type</code>
140          * mapped.
141          *
142          * @param type
143          *            string with YANG type name
144          * @return java <code>Type</code> representation of <code>type</code>
145          */
146         @Override
147         public Type javaTypeForYangType(final String type) {
148             return typeMap.get(type);
149         }
150
151         /**
152          * Searches <code>Type</code> value to which is YANG <code>type</code>
153          * mapped.
154          *
155          * @param type
156          *            type definition representation of YANG type
157          * @return java <code>Type</code> representation of <code>type</code>.
158          *         If <code>type</code> isn't found then <code>null</code> is
159          *         returned.
160          */
161         @Override
162         public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode) {
163             if (type != null) {
164                 return typeMap.get(type.getQName().getLocalName());
165             }
166
167             return null;
168         }
169
170         @Override
171         public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode,
172                 final Restrictions restrictions) {
173             String typeName = type.getQName().getLocalName();
174             switch (typeName) {
175             case "binary":
176                 return restrictions == null ? Types.BYTE_ARRAY : Types.primitiveType("byte[]", restrictions);
177             case "decimal64":
178                 return Types.typeForClass(BigDecimal.class, restrictions);
179             case "enumeration":
180                 return Types.typeForClass(Enum.class, restrictions);
181             case "int8":
182                 return Types.typeForClass(Byte.class, restrictions);
183             case "int16":
184                 return Types.typeForClass(Short.class, restrictions);
185             case "int32":
186                 return Types.typeForClass(Integer.class, restrictions);
187             case "int64":
188                 return Types.typeForClass(Long.class, restrictions);
189             case "string":
190                 return Types.typeForClass(String.class, restrictions);
191             case "uint8":
192                 return Types.typeForClass(Short.class, restrictions);
193             case "uint16":
194                 return Types.typeForClass(Integer.class, restrictions);
195             case "uint32":
196                 return Types.typeForClass(Long.class, restrictions);
197             case "uint64":
198                 return Types.typeForClass(BigInteger.class, restrictions);
199             case "union" :
200                 return UNION_TYPE;
201             default:
202                 return javaTypeForSchemaDefinitionType(type, parentNode);
203             }
204         }
205
206         @Override
207         public String getTypeDefaultConstruction(final LeafSchemaNode node) {
208             return null;
209         }
210
211         @Override
212         public String getConstructorPropertyName(final SchemaNode node) {
213             return null;
214         }
215
216         @Override
217         public String getParamNameFromType(final TypeDefinition<?> type) {
218             return "_" + BindingMapping.getPropertyName(type.getQName().getLocalName());
219         }
220     };
221
222     private static <T extends Number> Restrictions singleRangeRestrictions(final T min, final T max) {
223         return new Restrictions() {
224             @Override
225             public boolean isEmpty() {
226                 return false;
227             }
228
229             @Override
230             public List<RangeConstraint> getRangeConstraints() {
231                 return Collections.singletonList(BaseConstraints.newRangeConstraint(min, max,
232                         Optional.<String> absent(), Optional.<String> absent()));
233             }
234
235             @Override
236             public List<PatternConstraint> getPatternConstraints() {
237                 return Collections.emptyList();
238             }
239
240             @Override
241             public List<LengthConstraint> getLengthConstraints() {
242                 return Collections.emptyList();
243             }
244         };
245     }
246
247     public static final class UnionType implements Type {
248         @Override
249         public String getPackageName() {
250             return null;
251         }
252         @Override
253         public String getName() {
254             return "Union";
255         }
256         @Override
257         public String getFullyQualifiedName() {
258             return "Union";
259         }
260     }
261
262 }