Search in sources :

Example 6 with EffectiveStatement

use of org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement in project mdsal by opendaylight.

the class AbstractTypeObjectGenerator method createUnion.

@NonNull
private static GeneratedTransferObject createUnion(final List<GeneratedType> auxiliaryGeneratedTypes, final TypeBuilderFactory builderFactory, final EffectiveStatement<?, ?> definingStatement, final UnionDependencies dependencies, final JavaTypeName typeName, final ModuleGenerator module, final TypeEffectiveStatement<?> type, final boolean isTypedef, final TypeDefinition<?> typedef) {
    final GeneratedUnionBuilder builder = builderFactory.newGeneratedUnionBuilder(typeName);
    builder.addImplementsType(BindingTypes.TYPE_OBJECT);
    builder.setIsUnion(true);
    // builder.setSchemaPath(typedef.getPath());
    builder.setModuleName(module.statement().argument().getLocalName());
    builderFactory.addCodegenInformation(definingStatement, builder);
    annotateDeprecatedIfNecessary(definingStatement, builder);
    // Pattern string is the key, XSD regex is the value. The reason for this choice is that the pattern carries
    // also negation information and hence guarantees uniqueness.
    final Map<String, String> expressions = new HashMap<>();
    // Linear list of properties generated from subtypes. We need this information for runtime types, as it allows
    // direct mapping of type to corresponding property -- without having to resort to re-resolving the leafrefs
    // again.
    final List<String> typeProperties = new ArrayList<>();
    for (EffectiveStatement<?, ?> stmt : type.effectiveSubstatements()) {
        if (stmt instanceof TypeEffectiveStatement) {
            final TypeEffectiveStatement<?> subType = (TypeEffectiveStatement<?>) stmt;
            final QName subName = subType.argument();
            final String localName = subName.getLocalName();
            String propSource = localName;
            final Type generatedType;
            if (TypeDefinitions.UNION.equals(subName)) {
                final JavaTypeName subUnionName = typeName.createEnclosed(provideAvailableNameForGenTOBuilder(typeName.simpleName()));
                final GeneratedTransferObject subUnion = createUnion(auxiliaryGeneratedTypes, builderFactory, definingStatement, dependencies, subUnionName, module, subType, isTypedef, subType.getTypeDefinition());
                builder.addEnclosingTransferObject(subUnion);
                propSource = subUnionName.simpleName();
                generatedType = subUnion;
            } else if (TypeDefinitions.ENUMERATION.equals(subName)) {
                final Enumeration subEnumeration = createEnumeration(builderFactory, typeName.createEnclosed(BindingMapping.getClassName(localName), "$"), module, (EnumTypeDefinition) subType.getTypeDefinition());
                builder.addEnumeration(subEnumeration);
                generatedType = subEnumeration;
            } else if (TypeDefinitions.BITS.equals(subName)) {
                final GeneratedTransferObject subBits = createBits(builderFactory, typeName.createEnclosed(BindingMapping.getClassName(localName), "$"), module, subType.getTypeDefinition(), isTypedef);
                builder.addEnclosingTransferObject(subBits);
                generatedType = subBits;
            } else if (TypeDefinitions.IDENTITYREF.equals(subName)) {
                generatedType = verifyNotNull(dependencies.identityTypes.get(stmt), "Cannot resolve identityref %s in %s", stmt, definingStatement).methodReturnType(builderFactory);
            } else if (TypeDefinitions.LEAFREF.equals(subName)) {
                generatedType = verifyNotNull(dependencies.leafTypes.get(stmt), "Cannot resolve leafref %s in %s", stmt, definingStatement).methodReturnType(builderFactory);
            } else {
                Type baseType = SIMPLE_TYPES.get(subName);
                if (baseType == null) {
                    // This has to be a reference to a typedef, let's lookup it up and pick up its type
                    final AbstractTypeObjectGenerator<?, ?> baseGen = verifyNotNull(dependencies.baseTypes.get(subName), "Cannot resolve base type %s in %s", subName, definingStatement);
                    baseType = baseGen.methodReturnType(builderFactory);
                    // FIXME: This is legacy behaviour for leafrefs:
                    if (baseGen.refType instanceof TypeReference.Leafref) {
                        // if there already is a compatible property, do not generate a new one
                        final Type search = baseType;
                        final String matching = builder.getProperties().stream().filter(prop -> search == ((GeneratedPropertyBuilderImpl) prop).getReturnType()).findFirst().map(GeneratedPropertyBuilder::getName).orElse(null);
                        if (matching != null) {
                            typeProperties.add(matching);
                            continue;
                        }
                        // ... otherwise generate this weird property name
                        propSource = BindingMapping.getUnionLeafrefMemberName(builder.getName(), baseType.getName());
                    }
                }
                expressions.putAll(resolveRegExpressions(subType.getTypeDefinition()));
                generatedType = restrictType(baseType, BindingGeneratorUtil.getRestrictions(type.getTypeDefinition()), builderFactory);
            }
            final String propName = BindingMapping.getPropertyName(propSource);
            typeProperties.add(propName);
            if (builder.containsProperty(propName)) {
                /*
                     *  FIXME: this is not okay, as we are ignoring multiple base types. For example in the case of:
                     *
                     *    type union {
                     *      type string {
                     *        length 1..5;
                     *      }
                     *      type string {
                     *        length 8..10;
                     *      }
                     *    }
                     *
                     *  We are ending up losing the information about 8..10 being an alternative. This is also the case
                     *  for leafrefs -- we are performing property compression as well (see above). While it is alluring
                     *  to merge these into 'length 1..5|8..10', that may not be generally feasible.
                     *
                     *  We should resort to a counter of conflicting names, i.e. the second string would be mapped to
                     *  'string1' or similar.
                     */
                continue;
            }
            final GeneratedPropertyBuilder propBuilder = builder.addProperty(propName).setReturnType(generatedType);
            builder.addEqualsIdentity(propBuilder);
            builder.addHashIdentity(propBuilder);
            builder.addToStringProperty(propBuilder);
        }
    }
    // Record property names if needed
    builder.setTypePropertyNames(typeProperties);
    addStringRegExAsConstant(builder, expressions);
    addUnits(builder, typedef);
    makeSerializable(builder);
    final GeneratedTransferObject ret = builder.build();
    // Define a corresponding union builder. Typedefs are always anchored at a Java package root,
    // so we are placing the builder alongside the union.
    final GeneratedTOBuilder unionBuilder = builderFactory.newGeneratedTOBuilder(unionBuilderName(typeName));
    unionBuilder.setIsUnionBuilder(true);
    unionBuilder.addMethod("getDefaultInstance").setAccessModifier(AccessModifier.PUBLIC).setStatic(true).setReturnType(ret).addParameter(Types.STRING, "defaultValue");
    auxiliaryGeneratedTypes.add(unionBuilder.build());
    return ret;
}
Also used : PathEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.PathEffectiveStatement) GeneratedProperty(org.opendaylight.mdsal.binding.model.api.GeneratedProperty) LoggerFactory(org.slf4j.LoggerFactory) AbstractEnumerationBuilder(org.opendaylight.mdsal.binding.model.ri.generated.type.builder.AbstractEnumerationBuilder) PatternExpression(org.opendaylight.yangtools.yang.model.api.stmt.PatternExpression) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Nullable(org.eclipse.jdt.annotation.Nullable) Map(java.util.Map) TypeDefinition(org.opendaylight.yangtools.yang.model.api.TypeDefinition) AccessModifier(org.opendaylight.mdsal.binding.model.api.AccessModifier) StringTypeDefinition(org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition) Bit(org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit) RuntimeType(org.opendaylight.mdsal.binding.runtime.api.RuntimeType) RangeEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.RangeEffectiveStatement) ImmutableMap(com.google.common.collect.ImmutableMap) Type(org.opendaylight.mdsal.binding.model.api.Type) TypeDefinitions(org.opendaylight.yangtools.yang.model.api.type.TypeDefinitions) BindingTypes(org.opendaylight.mdsal.binding.model.ri.BindingTypes) ResolvedLeafref(org.opendaylight.mdsal.binding.generator.impl.reactor.TypeReference.ResolvedLeafref) Enumeration(org.opendaylight.mdsal.binding.model.api.Enumeration) GeneratedTypeBuilderBase(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase) Collectors(java.util.stream.Collectors) MethodSignatureBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder) List(java.util.List) YangConstants(org.opendaylight.yangtools.yang.common.YangConstants) BitsTypeDefinition(org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition) Optional(java.util.Optional) BindingGeneratorUtil(org.opendaylight.mdsal.binding.generator.BindingGeneratorUtil) NonNull(org.eclipse.jdt.annotation.NonNull) LengthEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.LengthEffectiveStatement) Verify.verifyNotNull(com.google.common.base.Verify.verifyNotNull) HashMap(java.util.HashMap) GeneratedPropertyBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder) ConcreteType(org.opendaylight.mdsal.binding.model.api.ConcreteType) ModifierKind(org.opendaylight.yangtools.yang.model.api.type.ModifierKind) BaseYangTypes(org.opendaylight.mdsal.binding.model.ri.BaseYangTypes) ArrayList(java.util.ArrayList) TypeConstants(org.opendaylight.mdsal.binding.model.ri.TypeConstants) Verify.verify(com.google.common.base.Verify.verify) GeneratedTransferObject(org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject) PatternConstraint(org.opendaylight.yangtools.yang.model.api.type.PatternConstraint) EffectiveStatement(org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement) GeneratedTOBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder) Immutable(org.opendaylight.yangtools.concepts.Immutable) RegexPatterns(org.opendaylight.yangtools.yang.binding.RegexPatterns) Logger(org.slf4j.Logger) Maps(com.google.common.collect.Maps) QName(org.opendaylight.yangtools.yang.common.QName) BindingMapping(org.opendaylight.mdsal.binding.spec.naming.BindingMapping) JavaTypeName(org.opendaylight.mdsal.binding.model.api.JavaTypeName) EnumTypeDefinition(org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition) TypeObject(org.opendaylight.yangtools.yang.binding.TypeObject) PatternEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.PatternEffectiveStatement) ValueRange(org.opendaylight.yangtools.yang.model.api.stmt.ValueRange) Restrictions(org.opendaylight.mdsal.binding.model.api.Restrictions) GeneratedPropertyBuilderImpl(org.opendaylight.mdsal.binding.model.ri.generated.type.builder.GeneratedPropertyBuilderImpl) BaseEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.BaseEffectiveStatement) Types(org.opendaylight.mdsal.binding.model.ri.Types) TypeEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement) GeneratedType(org.opendaylight.mdsal.binding.model.api.GeneratedType) Enumeration(org.opendaylight.mdsal.binding.model.api.Enumeration) HashMap(java.util.HashMap) QName(org.opendaylight.yangtools.yang.common.QName) EnumTypeDefinition(org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition) ArrayList(java.util.ArrayList) GeneratedTOBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder) GeneratedTransferObject(org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject) ResolvedLeafref(org.opendaylight.mdsal.binding.generator.impl.reactor.TypeReference.ResolvedLeafref) RuntimeType(org.opendaylight.mdsal.binding.runtime.api.RuntimeType) Type(org.opendaylight.mdsal.binding.model.api.Type) ConcreteType(org.opendaylight.mdsal.binding.model.api.ConcreteType) GeneratedType(org.opendaylight.mdsal.binding.model.api.GeneratedType) TypeEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement) GeneratedPropertyBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder) JavaTypeName(org.opendaylight.mdsal.binding.model.api.JavaTypeName) NonNull(org.eclipse.jdt.annotation.NonNull)

Example 7 with EffectiveStatement

use of org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement in project mdsal by opendaylight.

the class GeneratorReactor method mapToGenerator.

// Map a statement to the corresponding generator
@NonNull
private AbstractTypeAwareGenerator<?, ?, ?> mapToGenerator() {
    // Some preliminaries first: we need to be in the correct module to walk the path
    final ModuleEffectiveStatement module = inferenceStack.currentModule();
    final ModuleGenerator gen = verifyNotNull(generators.get(module.localQNameModule()), "Cannot find generator for %s", module);
    // Now kick of the search
    final List<EffectiveStatement<?, ?>> stmtPath = inferenceStack.toInference().statementPath();
    final AbstractExplicitGenerator<?, ?> found = gen.findGenerator(stmtPath);
    if (found instanceof AbstractTypeAwareGenerator) {
        return (AbstractTypeAwareGenerator<?, ?, ?>) found;
    }
    throw new VerifyException("Statements " + stmtPath + " resulted in unexpected " + found);
}
Also used : ModuleEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement) EffectiveStatement(org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement) VerifyException(com.google.common.base.VerifyException) ModuleEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement) Objects.requireNonNull(java.util.Objects.requireNonNull) NonNull(org.eclipse.jdt.annotation.NonNull)

Aggregations

EffectiveStatement (org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement)7 NonNull (org.eclipse.jdt.annotation.NonNull)5 ArrayList (java.util.ArrayList)4 List (java.util.List)4 SchemaNode (org.opendaylight.yangtools.yang.model.api.SchemaNode)4 Verify.verify (com.google.common.base.Verify.verify)3 Verify.verifyNotNull (com.google.common.base.Verify.verifyNotNull)3 InputStream (java.io.InputStream)3 Consumes (javax.ws.rs.Consumes)3 WebApplicationException (javax.ws.rs.WebApplicationException)3 Provider (javax.ws.rs.ext.Provider)3 InstanceIdentifierContext (org.opendaylight.restconf.common.context.InstanceIdentifierContext)3 RestconfDocumentedException (org.opendaylight.restconf.common.errors.RestconfDocumentedException)3 Logger (org.slf4j.Logger)3 LoggerFactory (org.slf4j.LoggerFactory)3 ImmutableList (com.google.common.collect.ImmutableList)2 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 DOMMountPointService (org.opendaylight.mdsal.dom.api.DOMMountPointService)2 MediaTypes (org.opendaylight.restconf.nb.rfc8040.MediaTypes)2