Make RangeRestrictedTypeDefinition type-aware
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / type / RestrictedTypes.java
1 /*
2  * Copyright (c) 2015 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.yangtools.yang.model.util.type;
9
10 import com.google.common.annotations.Beta;
11 import java.math.BigDecimal;
12 import java.math.BigInteger;
13 import javax.annotation.Nonnull;
14 import org.eclipse.jdt.annotation.Nullable;
15 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
16 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
17 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
18 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
19 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
20 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
21 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
22 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
23 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
24 import org.opendaylight.yangtools.yang.model.api.type.Int16TypeDefinition;
25 import org.opendaylight.yangtools.yang.model.api.type.Int32TypeDefinition;
26 import org.opendaylight.yangtools.yang.model.api.type.Int64TypeDefinition;
27 import org.opendaylight.yangtools.yang.model.api.type.Int8TypeDefinition;
28 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
29 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
30 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
31 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
32 import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition;
33 import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition;
34 import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition;
35 import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition;
36 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
37
38 /**
39  * Restricted types are a refinement of the restrictions applied to a particular type. YANG defines restrictions only
40  * on a subset of the base types, but conceptually any such definition can hold unknown nodes.
41  *
42  * <p>
43  * 1) Restrictable
44  *    binary (length)
45  *    int{8,16,32,64} (range)
46  *    string (length, patterns)
47  *    uint{8,16,32,64} (range)
48  *    decimal64 (range)
49  *    instance-identifier (require-instance)
50  *
51  * <p>
52  * 2) Non-restrictable
53  *    boolean
54  *    bits
55  *    empty (ignores default on derivation)
56  *    enumeration
57  *    identityref
58  *    leafref
59  *    union
60  *
61  * <p>
62  * This class holds methods which allow creation of restricted types using {@link TypeBuilder} and its subclasses. Each
63  * restricted type is logically anchored at a {@link SchemaPath}, but can be substituted by its base type if it does
64  * not contribute any additional restrictions. TypeBuilder instances take this into account, and result in the base type
65  * being returned from the builder when the base type and restricted type are semantically equal.
66  *
67  * <p>
68  * Restricted types inherit the default value, description, reference, status and units from the base type, if that type
69  * defines them.
70  */
71 @Beta
72 public final class RestrictedTypes {
73     private RestrictedTypes() {
74         throw new UnsupportedOperationException();
75     }
76
77     public static LengthRestrictedTypeBuilder<BinaryTypeDefinition> newBinaryBuilder(
78             @Nonnull final BinaryTypeDefinition baseType, @Nonnull final SchemaPath path) {
79         return new LengthRestrictedTypeBuilder<BinaryTypeDefinition>(baseType, path) {
80             @Override
81             BinaryTypeDefinition buildType(final @Nullable LengthConstraint lengthConstraint) {
82                 return new RestrictedBinaryType(getBaseType(), getPath(), getUnknownSchemaNodes(), lengthConstraint);
83             }
84
85             @Override
86             LengthConstraint typeLengthConstraints() {
87                 /**
88                  * Length constraint imposed on YANG binary type by our implementation. byte[].length is an integer,
89                  * capping our ability to support arbitrary binary data.
90                  */
91                 return JavaLengthConstraints.INTEGER_SIZE_CONSTRAINTS;
92             }
93         };
94     }
95
96     public static BitsTypeBuilder newBitsBuilder(final BitsTypeDefinition baseType, final SchemaPath path) {
97         return new BitsTypeBuilder(baseType, path);
98     }
99
100     public static TypeBuilder<BooleanTypeDefinition> newBooleanBuilder(@Nonnull final BooleanTypeDefinition baseType,
101             @Nonnull final SchemaPath path) {
102         return new AbstractRestrictedTypeBuilder<BooleanTypeDefinition>(baseType, path) {
103             @Override
104             BooleanTypeDefinition buildType() {
105                 return new RestrictedBooleanType(getBaseType(), getPath(), getUnknownSchemaNodes());
106             }
107         };
108     }
109
110     public static RangeRestrictedTypeBuilder<DecimalTypeDefinition, BigDecimal> newDecima64Builder(
111             final DecimalTypeDefinition baseType, final SchemaPath path) {
112         return new RangeRestrictedTypeBuilderWithBase<DecimalTypeDefinition, BigDecimal>(baseType, path) {
113             @Override
114             DecimalTypeDefinition buildType(final RangeConstraint<BigDecimal> rangeConstraint) {
115                 return new RestrictedDecimalType(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
116             }
117         };
118     }
119
120     public static TypeBuilder<EmptyTypeDefinition> newEmptyBuilder(final EmptyTypeDefinition baseType,
121             final SchemaPath path) {
122         return new AbstractRestrictedTypeBuilder<EmptyTypeDefinition>(baseType, path) {
123             @Override
124             EmptyTypeDefinition buildType() {
125                 return new RestrictedEmptyType(getBaseType(), getPath(), getUnknownSchemaNodes());
126             }
127         };
128     }
129
130     public static EnumerationTypeBuilder newEnumerationBuilder(final EnumTypeDefinition baseType,
131             final SchemaPath path) {
132         return new EnumerationTypeBuilder(baseType, path);
133     }
134
135     public static TypeBuilder<IdentityrefTypeDefinition> newIdentityrefBuilder(final IdentityrefTypeDefinition baseType,
136             final SchemaPath path) {
137         return new AbstractRestrictedTypeBuilder<IdentityrefTypeDefinition>(baseType, path) {
138             @Override
139             IdentityrefTypeDefinition buildType() {
140                 return new RestrictedIdentityrefType(getBaseType(), getPath(), getUnknownSchemaNodes());
141             }
142         };
143     }
144
145     public static InstanceIdentifierTypeBuilder newInstanceIdentifierBuilder(
146             final InstanceIdentifierTypeDefinition baseType, final SchemaPath path) {
147         return new InstanceIdentifierTypeBuilder(baseType, path);
148     }
149
150     public static RequireInstanceRestrictedTypeBuilder<LeafrefTypeDefinition> newLeafrefBuilder(
151             final LeafrefTypeDefinition baseType, final SchemaPath path) {
152         return new RequireInstanceRestrictedTypeBuilder<LeafrefTypeDefinition>(baseType, path) {
153             @Override
154             LeafrefTypeDefinition buildType() {
155                 if (getRequireInstance() == getBaseType().requireInstance()) {
156                     return getBaseType();
157                 }
158                 return new RestrictedLeafrefType(getBaseType(), getPath(), getUnknownSchemaNodes(),
159                         getRequireInstance());
160             }
161         };
162     }
163
164     public static RangeRestrictedTypeBuilder<Int8TypeDefinition, Byte> newInt8Builder(
165             final Int8TypeDefinition baseType, final SchemaPath path) {
166         return new RangeRestrictedTypeBuilderWithBase<Int8TypeDefinition, Byte>(baseType, path) {
167             @Override
168             Int8TypeDefinition buildType(final RangeConstraint<Byte> rangeConstraint) {
169                 return new RestrictedInt8Type(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
170             }
171         };
172     }
173
174     public static RangeRestrictedTypeBuilder<Int16TypeDefinition, Short> newInt16Builder(
175             final Int16TypeDefinition baseType, final SchemaPath path) {
176         return new RangeRestrictedTypeBuilderWithBase<Int16TypeDefinition, Short>(baseType, path) {
177             @Override
178             Int16TypeDefinition buildType(final RangeConstraint<Short> rangeConstraint) {
179                 return new RestrictedInt16Type(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
180             }
181         };
182     }
183
184     public static RangeRestrictedTypeBuilder<Int32TypeDefinition, Integer> newInt32Builder(
185             final Int32TypeDefinition baseType, final SchemaPath path) {
186         return new RangeRestrictedTypeBuilderWithBase<Int32TypeDefinition, Integer>(baseType, path) {
187             @Override
188             Int32TypeDefinition buildType(final RangeConstraint<Integer> rangeConstraint) {
189                 return new RestrictedInt32Type(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
190             }
191         };
192     }
193
194     public static RangeRestrictedTypeBuilder<Int64TypeDefinition, Long> newInt64Builder(
195             final Int64TypeDefinition baseType, final SchemaPath path) {
196         return new RangeRestrictedTypeBuilderWithBase<Int64TypeDefinition, Long>(baseType, path) {
197             @Override
198             Int64TypeDefinition buildType(final RangeConstraint<Long> rangeConstraint) {
199                 return new RestrictedInt64Type(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
200             }
201         };
202     }
203
204     public static StringTypeBuilder newStringBuilder(final StringTypeDefinition baseType, final SchemaPath path) {
205         return new StringTypeBuilder(baseType, path);
206     }
207
208     public static TypeBuilder<UnionTypeDefinition> newUnionBuilder(final UnionTypeDefinition baseType,
209             final SchemaPath path) {
210         return new AbstractRestrictedTypeBuilder<UnionTypeDefinition>(baseType, path) {
211             @Override
212             UnionTypeDefinition buildType() {
213                 return new RestrictedUnionType(getBaseType(), getPath(), getUnknownSchemaNodes());
214             }
215         };
216     }
217
218     public static RangeRestrictedTypeBuilder<Uint8TypeDefinition, Short> newUint8Builder(
219             final Uint8TypeDefinition baseType, final SchemaPath path) {
220         return new RangeRestrictedTypeBuilderWithBase<Uint8TypeDefinition, Short>(baseType, path) {
221             @Override
222             Uint8TypeDefinition buildType(final RangeConstraint<Short> rangeConstraint) {
223                 return new RestrictedUint8Type(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
224             }
225         };
226     }
227
228     public static RangeRestrictedTypeBuilder<Uint16TypeDefinition, Integer> newUint16Builder(
229             final Uint16TypeDefinition baseType, final SchemaPath path) {
230         return new RangeRestrictedTypeBuilderWithBase<Uint16TypeDefinition, Integer>(baseType, path) {
231             @Override
232             Uint16TypeDefinition buildType(final RangeConstraint<Integer> rangeConstraint) {
233                 return new RestrictedUint16Type(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
234             }
235         };
236     }
237
238     public static RangeRestrictedTypeBuilder<Uint32TypeDefinition, Long> newUint32Builder(
239             final Uint32TypeDefinition baseType, final SchemaPath path) {
240         return new RangeRestrictedTypeBuilderWithBase<Uint32TypeDefinition, Long>(baseType, path) {
241             @Override
242             Uint32TypeDefinition buildType(final RangeConstraint<Long> rangeConstraint) {
243                 return new RestrictedUint32Type(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
244             }
245         };
246     }
247
248     public static RangeRestrictedTypeBuilder<Uint64TypeDefinition, BigInteger> newUint64Builder(
249             final Uint64TypeDefinition baseType, final SchemaPath path) {
250         return new RangeRestrictedTypeBuilderWithBase<Uint64TypeDefinition, BigInteger>(baseType, path) {
251             @Override
252             Uint64TypeDefinition buildType(final RangeConstraint<BigInteger> rangeConstraint) {
253                 return new RestrictedUint64Type(getBaseType(), getPath(), getUnknownSchemaNodes(), rangeConstraint);
254             }
255         };
256     }
257 }