2 * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.type;
10 import static com.google.common.base.Verify.verifyNotNull;
12 import com.google.common.collect.ImmutableList;
13 import com.google.common.collect.ImmutableMap;
14 import java.util.Collection;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.yangtools.yang.common.Decimal64;
17 import org.opendaylight.yangtools.yang.common.Empty;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
20 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
21 import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference;
22 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
23 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.BitEffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.EnumEffectiveStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsEffectiveStatement;
27 import org.opendaylight.yangtools.yang.model.api.stmt.LengthEffectiveStatement;
28 import org.opendaylight.yangtools.yang.model.api.stmt.PatternEffectiveStatement;
29 import org.opendaylight.yangtools.yang.model.api.stmt.RangeEffectiveStatement;
30 import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceEffectiveStatement;
31 import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
32 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
33 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
34 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
35 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
36 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
37 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
38 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
39 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
40 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
41 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
42 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
43 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
44 import org.opendaylight.yangtools.yang.model.api.type.Int16TypeDefinition;
45 import org.opendaylight.yangtools.yang.model.api.type.Int32TypeDefinition;
46 import org.opendaylight.yangtools.yang.model.api.type.Int64TypeDefinition;
47 import org.opendaylight.yangtools.yang.model.api.type.Int8TypeDefinition;
48 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
49 import org.opendaylight.yangtools.yang.model.api.type.RangeRestrictedTypeDefinition;
50 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
51 import org.opendaylight.yangtools.yang.model.api.type.TypeDefinitions;
52 import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition;
53 import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition;
54 import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition;
55 import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition;
56 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
57 import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators;
58 import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements;
59 import org.opendaylight.yangtools.yang.model.ri.type.BitsTypeBuilder;
60 import org.opendaylight.yangtools.yang.model.ri.type.EnumerationTypeBuilder;
61 import org.opendaylight.yangtools.yang.model.ri.type.InstanceIdentifierTypeBuilder;
62 import org.opendaylight.yangtools.yang.model.ri.type.InvalidLengthConstraintException;
63 import org.opendaylight.yangtools.yang.model.ri.type.InvalidRangeConstraintException;
64 import org.opendaylight.yangtools.yang.model.ri.type.LengthRestrictedTypeBuilder;
65 import org.opendaylight.yangtools.yang.model.ri.type.RangeRestrictedTypeBuilder;
66 import org.opendaylight.yangtools.yang.model.ri.type.RequireInstanceRestrictedTypeBuilder;
67 import org.opendaylight.yangtools.yang.model.ri.type.RestrictedTypes;
68 import org.opendaylight.yangtools.yang.model.ri.type.StringTypeBuilder;
69 import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
70 import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace;
71 import org.opendaylight.yangtools.yang.parser.spi.meta.BoundStmtCtx;
72 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx;
73 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
74 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
75 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
76 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction;
77 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceContext;
78 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite;
79 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
80 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
81 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
82 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
83 import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
84 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
86 abstract class AbstractTypeStatementSupport extends AbstractTypeSupport<TypeStatement> {
87 private static final SubstatementValidator SUBSTATEMENT_VALIDATOR =
88 SubstatementValidator.builder(YangStmtMapping.TYPE)
89 .addOptional(YangStmtMapping.BASE)
90 .addAny(YangStmtMapping.BIT)
91 .addAny(YangStmtMapping.ENUM)
92 .addOptional(YangStmtMapping.FRACTION_DIGITS)
93 .addOptional(YangStmtMapping.LENGTH)
94 .addOptional(YangStmtMapping.PATH)
95 .addAny(YangStmtMapping.PATTERN)
96 .addOptional(YangStmtMapping.RANGE)
97 .addOptional(YangStmtMapping.REQUIRE_INSTANCE)
98 .addAny(YangStmtMapping.TYPE)
101 private static final ImmutableMap<String, BuiltinEffectiveStatement> STATIC_BUILT_IN_TYPES =
102 ImmutableMap.<String, BuiltinEffectiveStatement>builder()
103 .put(TypeDefinitions.BINARY.getLocalName(), BuiltinEffectiveStatement.BINARY)
104 .put(TypeDefinitions.BOOLEAN.getLocalName(), BuiltinEffectiveStatement.BOOLEAN)
105 .put(TypeDefinitions.EMPTY.getLocalName(), BuiltinEffectiveStatement.EMPTY)
106 // FIXME: this overlaps with DYNAMIC_BUILT_IN_TYPES. One of these is not needed, but we need to decide
107 // what to do. I think we should gradually use per-statement validators, hence go towards dynamic?
108 .put(TypeDefinitions.INSTANCE_IDENTIFIER.getLocalName(), BuiltinEffectiveStatement.INSTANCE_IDENTIFIER)
109 .put(TypeDefinitions.INT8.getLocalName(), BuiltinEffectiveStatement.INT8)
110 .put(TypeDefinitions.INT16.getLocalName(), BuiltinEffectiveStatement.INT16)
111 .put(TypeDefinitions.INT32.getLocalName(), BuiltinEffectiveStatement.INT32)
112 .put(TypeDefinitions.INT64.getLocalName(), BuiltinEffectiveStatement.INT64)
113 .put(TypeDefinitions.STRING.getLocalName(), BuiltinEffectiveStatement.STRING)
114 .put(TypeDefinitions.UINT8.getLocalName(), BuiltinEffectiveStatement.UINT8)
115 .put(TypeDefinitions.UINT16.getLocalName(), BuiltinEffectiveStatement.UINT16)
116 .put(TypeDefinitions.UINT32.getLocalName(), BuiltinEffectiveStatement.UINT32)
117 .put(TypeDefinitions.UINT64.getLocalName(), BuiltinEffectiveStatement.UINT64)
120 private final ImmutableMap<String, StatementSupport<?, ?, ?>> dynamicBuiltInTypes;
122 AbstractTypeStatementSupport(final YangParserConfiguration config) {
123 super(config, SUBSTATEMENT_VALIDATOR);
124 dynamicBuiltInTypes = ImmutableMap.<String, StatementSupport<?, ?, ?>>builder()
125 .put(TypeDefinitions.BITS.getLocalName(), new BitsSpecificationSupport(config))
126 .put(TypeDefinitions.DECIMAL64.getLocalName(), new Decimal64SpecificationSupport(config))
127 .put(TypeDefinitions.ENUMERATION.getLocalName(), new EnumSpecificationSupport(config))
128 .put(TypeDefinitions.IDENTITYREF.getLocalName(), IdentityRefSpecificationSupport.rfc6020Instance(config))
129 .put(TypeDefinitions.INSTANCE_IDENTIFIER.getLocalName(), new InstanceIdentifierSpecificationSupport(config))
130 .put(TypeDefinitions.LEAFREF.getLocalName(), LeafrefSpecificationSupport.rfc6020Instance(config))
131 .put(TypeDefinitions.UNION.getLocalName(), new UnionSpecificationSupport(config))
136 public final void onFullDefinitionDeclared(
137 final Mutable<QName, TypeStatement, EffectiveStatement<QName, TypeStatement>> stmt) {
138 super.onFullDefinitionDeclared(stmt);
140 final BuiltinEffectiveStatement builtin = STATIC_BUILT_IN_TYPES.get(stmt.getRawArgument());
141 if (builtin != null) {
142 stmt.addToNs(BaseTypeNamespace.class, Empty.value(), builtin);
146 final QName typeQName = stmt.getArgument();
147 final ModelActionBuilder typeAction = stmt.newInferenceAction(ModelProcessingPhase.EFFECTIVE_MODEL);
148 final Prerequisite<StmtContext<?, ?, ?>> typePrereq = typeAction.requiresCtx(stmt, TypeNamespace.class,
149 typeQName, ModelProcessingPhase.EFFECTIVE_MODEL);
150 typeAction.mutatesEffectiveCtx(stmt.getParentContext());
153 * If the type does not exist, throw an InferenceException.
154 * If the type exists, store a reference to it in BaseTypeNamespace.
156 typeAction.apply(new InferenceAction() {
158 public void apply(final InferenceContext ctx) {
159 // Note: do not attempt to call buildEffective() here
160 stmt.addToNs(BaseTypeNamespace.class, Empty.value(), typePrereq.resolve(ctx));
164 public void prerequisiteFailed(final Collection<? extends Prerequisite<?>> failed) {
165 InferenceException.throwIf(failed.contains(typePrereq), stmt, "Type [%s] was not found.", typeQName);
171 public boolean hasArgumentSpecificSupports() {
172 return !dynamicBuiltInTypes.isEmpty();
176 public StatementSupport<?, ?, ?> getSupportSpecificForArgument(final String argument) {
177 return dynamicBuiltInTypes.get(argument);
181 protected final TypeStatement createDeclared(final BoundStmtCtx<QName> ctx,
182 final ImmutableList<DeclaredStatement<?>> substatements) {
183 if (substatements.isEmpty()) {
184 final TypeStatement builtin = BuiltinTypeStatement.lookup(ctx.getRawArgument());
185 if (builtin != null) {
189 return DeclaredStatements.createType(ctx.getRawArgument(), ctx.getArgument(), substatements);
193 protected final TypeStatement attachDeclarationReference(final TypeStatement stmt,
194 final DeclarationReference reference) {
195 return DeclaredStatementDecorators.decorateType(stmt, reference);
199 protected EffectiveStatement<QName, TypeStatement> createEffective(final Current<QName, TypeStatement> stmt,
200 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
201 // First look up the proper base type
202 final TypeEffectiveStatement<TypeStatement> typeStmt = resolveType(stmt);
203 if (substatements.isEmpty()) {
207 // Now instantiate the proper effective statement for that type
208 final TypeDefinition<?> baseType = typeStmt.getTypeDefinition();
209 final TypeStatement declared = stmt.declared();
210 if (baseType instanceof BinaryTypeDefinition) {
211 return createBinary(stmt, (BinaryTypeDefinition) baseType, declared, substatements);
212 } else if (baseType instanceof BitsTypeDefinition) {
213 return createBits(stmt, (BitsTypeDefinition) baseType, declared, substatements);
214 } else if (baseType instanceof BooleanTypeDefinition) {
215 return createBoolean(stmt, (BooleanTypeDefinition) baseType, declared, substatements);
216 } else if (baseType instanceof DecimalTypeDefinition) {
217 return createDecimal(stmt, (DecimalTypeDefinition) baseType, declared, substatements);
218 } else if (baseType instanceof EmptyTypeDefinition) {
219 return createEmpty(stmt, (EmptyTypeDefinition) baseType, declared, substatements);
220 } else if (baseType instanceof EnumTypeDefinition) {
221 return createEnum(stmt, (EnumTypeDefinition) baseType, declared, substatements);
222 } else if (baseType instanceof IdentityrefTypeDefinition) {
223 return createIdentityref(stmt, (IdentityrefTypeDefinition) baseType, declared, substatements);
224 } else if (baseType instanceof InstanceIdentifierTypeDefinition) {
225 return createInstanceIdentifier(stmt, (InstanceIdentifierTypeDefinition) baseType, declared, substatements);
226 } else if (baseType instanceof Int8TypeDefinition) {
227 return createIntegral(stmt, declared, substatements,
228 RestrictedTypes.newInt8Builder((Int8TypeDefinition) baseType, typeEffectiveQName(stmt)));
229 } else if (baseType instanceof Int16TypeDefinition) {
230 return createIntegral(stmt, declared, substatements,
231 RestrictedTypes.newInt16Builder((Int16TypeDefinition) baseType, typeEffectiveQName(stmt)));
232 } else if (baseType instanceof Int32TypeDefinition) {
233 return createIntegral(stmt, declared, substatements,
234 RestrictedTypes.newInt32Builder((Int32TypeDefinition) baseType, typeEffectiveQName(stmt)));
235 } else if (baseType instanceof Int64TypeDefinition) {
236 return createIntegral(stmt, declared, substatements,
237 RestrictedTypes.newInt64Builder((Int64TypeDefinition) baseType, typeEffectiveQName(stmt)));
238 } else if (baseType instanceof LeafrefTypeDefinition) {
239 return createLeafref(stmt, (LeafrefTypeDefinition) baseType, declared, substatements);
240 } else if (baseType instanceof StringTypeDefinition) {
241 return createString(stmt, (StringTypeDefinition) baseType, declared, substatements);
242 } else if (baseType instanceof Uint8TypeDefinition) {
243 return createIntegral(stmt, declared, substatements,
244 RestrictedTypes.newUint8Builder((Uint8TypeDefinition) baseType, typeEffectiveQName(stmt)));
245 } else if (baseType instanceof Uint16TypeDefinition) {
246 return createIntegral(stmt, declared, substatements,
247 RestrictedTypes.newUint16Builder((Uint16TypeDefinition) baseType, typeEffectiveQName(stmt)));
248 } else if (baseType instanceof Uint32TypeDefinition) {
249 return createIntegral(stmt, declared, substatements,
250 RestrictedTypes.newUint32Builder((Uint32TypeDefinition) baseType, typeEffectiveQName(stmt)));
251 } else if (baseType instanceof Uint64TypeDefinition) {
252 return createIntegral(stmt, declared, substatements,
253 RestrictedTypes.newUint64Builder((Uint64TypeDefinition) baseType, typeEffectiveQName(stmt)));
254 } else if (baseType instanceof UnionTypeDefinition) {
255 return createUnion(stmt, (UnionTypeDefinition) baseType, declared, substatements);
257 throw new IllegalStateException("Unhandled base type " + baseType);
261 // FIXME: YANGTOOLS-1208: this needs to happen during onFullDefinitionDeclared() and stored (again) in a namespace
262 static final @NonNull QName typeEffectiveQName(final Current<QName, ?> stmt) {
263 return stmt.getArgument().bindTo(stmt.getEffectiveParent().effectiveNamespace()).intern();
267 * Resolve type reference, as pointed to by the context's argument.
269 * @param ctx Statement context
270 * @return Resolved type
271 * @throws SourceException if the target type cannot be found
273 private static @NonNull TypeEffectiveStatement<TypeStatement> resolveType(final Current<QName, ?> ctx) {
274 final Object obj = verifyNotNull(ctx.namespaceItem(BaseTypeNamespace.class, Empty.value()));
275 if (obj instanceof BuiltinEffectiveStatement) {
276 return (BuiltinEffectiveStatement) obj;
277 } else if (obj instanceof StmtContext) {
278 return ((TypedefEffectiveStatement) ((StmtContext<?, ?, ?>) obj).buildEffective())
279 .asTypeEffectiveStatement();
281 throw new InferenceException(ctx, "Unexpected base object %s", obj);
285 private static @NonNull TypeEffectiveStatement<TypeStatement> createBinary(final Current<QName, ?> ctx,
286 final BinaryTypeDefinition baseType, final TypeStatement declared,
287 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
288 final LengthRestrictedTypeBuilder<BinaryTypeDefinition> builder =
289 RestrictedTypes.newBinaryBuilder(baseType, typeEffectiveQName(ctx));
291 for (EffectiveStatement<?, ?> stmt : substatements) {
292 if (stmt instanceof LengthEffectiveStatement) {
293 final LengthEffectiveStatement length = (LengthEffectiveStatement)stmt;
296 builder.setLengthConstraint(length, length.argument());
297 } catch (IllegalStateException e) {
298 throw new SourceException(ctx, e, "Multiple length constraints encountered");
299 } catch (InvalidLengthConstraintException e) {
300 throw new SourceException(ctx, e, "Invalid length constraint %s", length.argument());
305 return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
308 private @NonNull TypeEffectiveStatement<TypeStatement> createBits(final Current<?, ?> ctx,
309 final BitsTypeDefinition baseType, final TypeStatement declared,
310 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
311 final BitsTypeBuilder builder = RestrictedTypes.newBitsBuilder(baseType, ctx.argumentAsTypeQName());
313 for (final EffectiveStatement<?, ?> stmt : substatements) {
314 if (stmt instanceof BitEffectiveStatement) {
315 builder.addBit(addRestrictedBit(ctx, baseType, (BitEffectiveStatement) stmt));
319 return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
322 abstract @NonNull Bit addRestrictedBit(@NonNull EffectiveStmtCtx stmt, @NonNull BitsTypeDefinition base,
323 @NonNull BitEffectiveStatement bit);
325 private static @NonNull TypeEffectiveStatement<TypeStatement> createBoolean(final Current<QName, ?> ctx,
326 final BooleanTypeDefinition baseType, final TypeStatement declared,
327 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
328 return new TypeEffectiveStatementImpl<>(declared, substatements, RestrictedTypes.newBooleanBuilder(baseType,
329 typeEffectiveQName(ctx)));
332 private static @NonNull TypeEffectiveStatement<TypeStatement> createDecimal(final Current<QName, ?> ctx,
333 final DecimalTypeDefinition baseType, final TypeStatement declared,
334 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
335 final RangeRestrictedTypeBuilder<DecimalTypeDefinition, Decimal64> builder =
336 RestrictedTypes.newDecima64Builder(baseType, typeEffectiveQName(ctx));
338 for (EffectiveStatement<?, ?> stmt : substatements) {
339 if (stmt instanceof RangeEffectiveStatement) {
340 final RangeEffectiveStatement range = (RangeEffectiveStatement) stmt;
341 builder.setRangeConstraint(range, range.argument());
343 if (stmt instanceof FractionDigitsEffectiveStatement) {
344 final Integer digits = ((FractionDigitsEffectiveStatement)stmt).argument();
345 SourceException.throwIf(baseType.getFractionDigits() != digits, ctx,
346 "Cannot override fraction-digits from base type %s to %s", baseType, digits);
350 return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
353 private static @NonNull TypeEffectiveStatement<TypeStatement> createEmpty(final Current<QName, ?> ctx,
354 final EmptyTypeDefinition baseType, final TypeStatement declared,
355 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
356 return new TypeEffectiveStatementImpl<>(declared, substatements, RestrictedTypes.newEmptyBuilder(baseType,
357 typeEffectiveQName(ctx)));
360 private @NonNull TypeEffectiveStatement<TypeStatement> createEnum(final Current<?, ?> ctx,
361 final EnumTypeDefinition baseType, final TypeStatement declared,
362 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
363 final EnumerationTypeBuilder builder = RestrictedTypes.newEnumerationBuilder(baseType,
364 ctx.argumentAsTypeQName());
366 for (final EffectiveStatement<?, ?> stmt : substatements) {
367 if (stmt instanceof EnumEffectiveStatement) {
368 builder.addEnum(addRestrictedEnum(ctx, baseType, (EnumEffectiveStatement) stmt));
372 return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
375 abstract @NonNull EnumPair addRestrictedEnum(@NonNull EffectiveStmtCtx stmt, @NonNull EnumTypeDefinition base,
376 @NonNull EnumEffectiveStatement enumStmt);
378 private static @NonNull TypeEffectiveStatement<TypeStatement> createIdentityref(final Current<QName, ?> ctx,
379 final IdentityrefTypeDefinition baseType, final TypeStatement declared,
380 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
381 return new TypeEffectiveStatementImpl<>(declared, substatements, RestrictedTypes.newIdentityrefBuilder(baseType,
382 typeEffectiveQName(ctx)));
385 private static @NonNull TypeEffectiveStatement<TypeStatement> createInstanceIdentifier(final Current<QName, ?> ctx,
386 final InstanceIdentifierTypeDefinition baseType, final TypeStatement declared,
387 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
388 final InstanceIdentifierTypeBuilder builder = RestrictedTypes.newInstanceIdentifierBuilder(baseType,
389 typeEffectiveQName(ctx));
391 for (EffectiveStatement<?, ?> stmt : substatements) {
392 if (stmt instanceof RequireInstanceEffectiveStatement) {
393 builder.setRequireInstance(((RequireInstanceEffectiveStatement)stmt).argument());
397 return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
400 private static <T extends RangeRestrictedTypeDefinition<T, N>, N extends Number & Comparable<N>>
401 @NonNull TypeEffectiveStatement<TypeStatement> createIntegral(final Current<?, ?> ctx,
402 final TypeStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
403 final RangeRestrictedTypeBuilder<T, N> builder) {
404 for (EffectiveStatement<?, ?> stmt : substatements) {
405 if (stmt instanceof RangeEffectiveStatement) {
406 final RangeEffectiveStatement rangeStmt = (RangeEffectiveStatement)stmt;
407 builder.setRangeConstraint(rangeStmt, rangeStmt.argument());
412 return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
413 } catch (InvalidRangeConstraintException e) {
414 throw new SourceException(ctx, e, "Invalid range constraint: %s", e.getOffendingRanges());
418 private static @NonNull TypeEffectiveStatement<TypeStatement> createLeafref(final Current<QName, ?> ctx,
419 final LeafrefTypeDefinition baseType, final TypeStatement declared,
420 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
421 final RequireInstanceRestrictedTypeBuilder<LeafrefTypeDefinition> builder =
422 RestrictedTypes.newLeafrefBuilder(baseType, AbstractTypeStatementSupport.typeEffectiveQName(ctx));
424 for (final EffectiveStatement<?, ?> stmt : substatements) {
425 if (stmt instanceof RequireInstanceEffectiveStatement) {
426 builder.setRequireInstance(((RequireInstanceEffectiveStatement) stmt).argument());
429 return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
432 private static @NonNull TypeEffectiveStatement<TypeStatement> createString(final Current<QName, ?> ctx,
433 final StringTypeDefinition baseType, final TypeStatement declared,
434 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
435 final StringTypeBuilder builder = RestrictedTypes.newStringBuilder(baseType,
436 AbstractTypeStatementSupport.typeEffectiveQName(ctx));
438 for (EffectiveStatement<?, ?> stmt : substatements) {
439 if (stmt instanceof LengthEffectiveStatement) {
440 final LengthEffectiveStatement length = (LengthEffectiveStatement)stmt;
443 builder.setLengthConstraint(length, length.argument());
444 } catch (IllegalStateException e) {
445 throw new SourceException(ctx, e, "Multiple length constraints encountered");
446 } catch (InvalidLengthConstraintException e) {
447 throw new SourceException(ctx, e, "Invalid length constraint %s", length.argument());
450 if (stmt instanceof PatternEffectiveStatement) {
451 builder.addPatternConstraint((PatternEffectiveStatement) stmt);
455 return new TypeEffectiveStatementImpl<>(declared, substatements, builder);
458 private static @NonNull TypeEffectiveStatement<TypeStatement> createUnion(final Current<QName, ?> ctx,
459 final UnionTypeDefinition baseType, final TypeStatement declared,
460 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
461 return new TypeEffectiveStatementImpl<>(declared, substatements, RestrictedTypes.newUnionBuilder(baseType,
462 typeEffectiveQName(ctx)));