2 * Copyright (c) 2015 Cisco Systems, Inc. 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.model.ri.stmt.impl.eff;
10 import com.google.common.collect.ImmutableList;
11 import java.lang.invoke.MethodHandles;
12 import java.lang.invoke.MethodHandles.Lookup;
13 import java.lang.invoke.VarHandle;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
17 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
18 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
19 import org.opendaylight.yangtools.yang.model.api.stmt.DefaultEffectiveStatement;
20 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement;
21 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
27 import org.opendaylight.yangtools.yang.model.api.stmt.UnitsEffectiveStatement;
28 import org.opendaylight.yangtools.yang.model.ri.type.DerivedTypes;
29 import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultArgument.WithSubstatements;
30 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.SchemaNodeMixin;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 public final class TypedefEffectiveStatementImpl extends WithSubstatements<QName, TypedefStatement>
35 implements TypedefEffectiveStatement, SchemaNodeMixin<TypedefStatement> {
36 private static final Logger LOG = LoggerFactory.getLogger(TypedefEffectiveStatementImpl.class);
38 private static final VarHandle TYPE_DEFINITION;
39 private static final VarHandle TYPE_STATEMENT;
42 final Lookup lookup = MethodHandles.lookup();
44 TYPE_DEFINITION = lookup.findVarHandle(TypedefEffectiveStatementImpl.class, "typeDefinition",
45 TypeDefinition.class);
46 TYPE_STATEMENT = lookup.findVarHandle(TypedefEffectiveStatementImpl.class, "typeStatement",
47 ProxyTypeEffectiveStatement.class);
48 } catch (NoSuchFieldException | IllegalAccessException e) {
49 throw new ExceptionInInitializerError(e);
53 private final int flags;
55 // Accessed via TYPE_DEFINITION
56 @SuppressWarnings("unused")
57 private volatile TypeDefinition<?> typeDefinition;
58 // Accessed via TYPE_STATEMENT
59 @SuppressWarnings("unused")
60 private volatile ProxyTypeEffectiveStatement typeStatement;
62 public TypedefEffectiveStatementImpl(final TypedefStatement declared, final int flags,
63 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
64 super(declared, substatements);
74 public TypeDefinition<?> getTypeDefinition() {
75 final var existing = (TypeDefinition<?>) TYPE_DEFINITION.getAcquire(this);
76 return existing != null ? existing : loadTypeDefinition();
80 public TypeEffectiveStatement<TypeStatement> asTypeEffectiveStatement() {
81 final ProxyTypeEffectiveStatement local = (ProxyTypeEffectiveStatement) TYPE_STATEMENT.getAcquire(this);
82 return local != null ? local : loadTypeStatement();
85 private @NonNull TypeDefinition<?> loadTypeDefinition() {
86 final var type = findFirstEffectiveSubstatement(TypeEffectiveStatement.class).orElseThrow();
87 final var builder = DerivedTypes.derivedTypeBuilder(type.getTypeDefinition(), argument());
89 for (final EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
90 if (stmt instanceof DefaultEffectiveStatement dflt) {
91 builder.setDefaultValue(dflt.argument());
92 } else if (stmt instanceof DescriptionEffectiveStatement description) {
93 builder.setDescription(description.argument());
94 } else if (stmt instanceof ReferenceEffectiveStatement reference) {
95 builder.setReference(reference.argument());
96 } else if (stmt instanceof StatusEffectiveStatement status) {
97 builder.setStatus(status.argument());
98 } else if (stmt instanceof UnitsEffectiveStatement units) {
99 builder.setUnits(units.argument());
100 } else if (stmt instanceof UnknownSchemaNode unknown) {
101 // FIXME: should not directly implement, I think
102 builder.addUnknownSchemaNode(unknown);
103 } else if (!(stmt instanceof TypeEffectiveStatement)) {
104 LOG.debug("Ignoring statement {}", stmt);
108 final var created = builder.build();
109 final var witness = TYPE_DEFINITION.compareAndExchangeRelease(this, null, created);
110 return witness == null ? created : (TypeDefinition<?>) witness;
113 private @NonNull ProxyTypeEffectiveStatement loadTypeStatement() {
114 final var created = new ProxyTypeEffectiveStatement();
115 final var witness = TYPE_STATEMENT.compareAndExchangeRelease(this, null, created);
116 return witness == null ? created : (ProxyTypeEffectiveStatement) witness;
119 private final class ProxyTypeEffectiveStatement implements TypeEffectiveStatement<TypeStatement> {
121 public TypeStatement getDeclared() {
126 public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
127 return TypedefEffectiveStatementImpl.this.effectiveSubstatements();
131 public QName argument() {
132 return TypedefEffectiveStatementImpl.this.argument();
136 public TypeDefinition<?> getTypeDefinition() {
137 return TypedefEffectiveStatementImpl.this.getTypeDefinition();