Bug 6887: [Yang 1.1] Allow enumerations and bits to be subtyped
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / type / BitsTypeBuilder.java
index 082b182709a42a33713f1c8cc9532f4d21c098ba..362f2b8681cfa47d6e8e87a0fd8cde7073aa4a1c 100644 (file)
@@ -16,20 +16,50 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
 
-public final class BitsTypeBuilder extends TypeBuilder<BitsTypeDefinition> {
+public final class BitsTypeBuilder extends AbstractRestrictedTypeBuilder<BitsTypeDefinition> {
     private final Builder<String, Bit> builder = ImmutableMap.builder();
 
     BitsTypeBuilder(final SchemaPath path) {
         super(null, path);
     }
 
+    BitsTypeBuilder(final BitsTypeDefinition baseType, final SchemaPath path) {
+        super(baseType, path);
+    }
+
     public BitsTypeBuilder addBit(@Nonnull final Bit item) {
+        // in case we are dealing with a restricted bits type, validate if the bit is a subset of its base type
+        if (getBaseType() != null) {
+            validateRestrictedBit(item);
+        }
+
         builder.put(item.getName(), item);
+        touch();
         return this;
     }
 
+    private void validateRestrictedBit(@Nonnull final Bit item) {
+        boolean isASubsetOfBaseBits = false;
+        for (Bit baseTypeBit : getBaseType().getBits()) {
+            if (item.getName().equals(baseTypeBit.getName())) {
+                if (item.getPosition() != baseTypeBit.getPosition()) {
+                    throw new InvalidBitDefinitionException(item, "Position of bit '%s' must be the same as the " +
+                            "position of corresponding bit in the base bits type %s.", item.getName(),
+                            getBaseType().getQName());
+                }
+                isASubsetOfBaseBits = true;
+                break;
+            }
+        }
+
+        if (!isASubsetOfBaseBits) {
+            throw new InvalidBitDefinitionException(item, "Bit '%s' is not a subset of its base bits type %s.",
+                    item.getName(), getBaseType().getQName());
+        }
+    }
+
     @Override
-    public BitsTypeDefinition build() {
+    public BitsTypeDefinition buildType() {
         final Map<String, Bit> map = builder.build();
         final Map<Long, Bit> positionMap = new TreeMap<>();
 
@@ -40,6 +70,10 @@ public final class BitsTypeBuilder extends TypeBuilder<BitsTypeDefinition> {
             }
         }
 
-        return new BaseBitsType(getPath(), getUnknownSchemaNodes(), positionMap.values());
+        if (getBaseType() == null) {
+            return new BaseBitsType(getPath(), getUnknownSchemaNodes(), positionMap.values());
+        } else {
+            return new RestrictedBitsType(getBaseType(), getPath(), getUnknownSchemaNodes(), positionMap.values());
+        }
     }
 }