summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AbstractYangStatementComparator.java59
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AugmentComparator.java50
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/BaseComparator.java53
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ChangeType.java42
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java495
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompareType.java23
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityInfo.java48
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRule.java330
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRules.java149
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ConfigComparator.java78
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DefaultComparator.java41
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DescriptionComparator.java40
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/EnumBitComparator.java43
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IdentifierComparator.java40
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IfFeatureComparator.java42
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MandatoryComparator.java63
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MaxElementsComparator.java69
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MinElementsComparator.java63
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ModuleComparator.java86
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/NamespaceComparator.java39
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/OperationComparator.java90
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/PatternComparator.java43
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/RangeLengthComparator.java67
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ReferenceComparator.java40
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/SchemaNodeComparator.java182
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/StatusComparator.java73
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/TypeStatementComparator.java122
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UniqueComparator.java105
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UnitsComparator.java41
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ValuePositionComparator.java39
-rw-r--r--yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java8
32 files changed, 2664 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index af665ab..d0d38f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@ target/
*.iws
*.iml
*.ipr
+.idea
### Eclipse ###
.apt_generated
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AbstractYangStatementComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AbstractYangStatementComparator.java
new file mode 100644
index 0000000..5e3af0f
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AbstractYangStatementComparator.java
@@ -0,0 +1,59 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.stmt.YangStatement;
+
+
+public abstract class AbstractYangStatementComparator<T extends YangStatement> implements YangStatementComparator<T> {
+ /**
+ * constructor.
+ */
+ public AbstractYangStatementComparator() {
+ }
+
+ /**
+ * get compatibility rules.
+ *
+ * @return rules
+ */
+ public CompatibilityRules getCompatibilityRules() {
+ return CompatibilityRules.getInstance();
+ }
+
+ /**
+ * get change information.
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return list of change information.
+ */
+ protected abstract List<CompatibilityRule.ChangeInfo> getChangeInfo(T left, T right);
+
+ /**
+ * the default compatibility result.
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo change information
+ * @return compatibility result
+ */
+ protected abstract CompatibilityInfo defaultCompatibility(T left, T right,
+ CompatibilityRule.ChangeInfo changeInfo);
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AugmentComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AugmentComparator.java
new file mode 100644
index 0000000..44fd21b
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/AugmentComparator.java
@@ -0,0 +1,50 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.stmt.Augment;
+
+public class AugmentComparator extends SchemaNodeComparator<Augment> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ public List<YangCompareResult> compare(Augment left, Augment right) {
+ if (left != null) {
+ if (left.getEffectiveSchemaNodeChildren().size() == 0) {
+ left = null;
+ }
+ }
+ if (right != null) {
+ if (right.getEffectiveSchemaNodeChildren().size() == 0) {
+ right = null;
+ }
+ }
+ List<YangCompareResult> compareResults = new ArrayList<>();
+ if (left == null && right == null) {
+ return compareResults;
+ }
+ return compareChildren(left, right);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/BaseComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/BaseComparator.java
new file mode 100644
index 0000000..d362fdd
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/BaseComparator.java
@@ -0,0 +1,53 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.Base;
+import org.yangcentral.yangkit.model.api.stmt.Identity;
+import org.yangcentral.yangkit.model.api.stmt.Type;
+
+
+public class BaseComparator extends CommonYangStatementComparator<Base> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Base left, Base right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ Base temp = left;
+ if (temp == null) {
+ temp = right;
+ }
+ if (temp.getParentStatement() instanceof Identity) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "delete a base for identity,it's non-backward-compatible.");
+ }
+ } else if (temp.getParentStatement() instanceof Type) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.ADDED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "add a new base for identity-ref, it's non-backward-compatible.");
+ }
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ChangeType.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ChangeType.java
new file mode 100644
index 0000000..6f7f818
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ChangeType.java
@@ -0,0 +1,42 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+
+
+public enum ChangeType {
+ ADD("add"),
+ MODIFY("modify"),
+ DELETE("delete");
+ private String description;
+
+ /**
+ *
+ * @param description
+ */
+ private ChangeType(String description) {
+ this.description = description;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getName() {
+ return this.description;
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java
new file mode 100644
index 0000000..8b03304
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java
@@ -0,0 +1,495 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.base.Cardinality;
+import org.yangcentral.yangkit.base.YangElement;
+import org.yangcentral.yangkit.base.YangStatementDef;
+import org.yangcentral.yangkit.model.api.stmt.IdentifierRef;
+import org.yangcentral.yangkit.model.api.stmt.Referencable;
+import org.yangcentral.yangkit.model.api.stmt.SchemaNode;
+import org.yangcentral.yangkit.model.api.stmt.YangBuiltinStatement;
+import org.yangcentral.yangkit.model.api.stmt.YangStatement;
+import org.yangcentral.yangkit.model.api.stmt.YangUnknown;
+
+
+public class CommonYangStatementComparator<T extends YangStatement> extends AbstractYangStatementComparator<T> {
+ public static final int OPTION_ONLY_META = 1;
+ public static final int OPTION_ONLY_SCHEMA = 2;
+ public static final int OPTION_ALL = 3;
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(T left, T right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ if (left == null) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.ADDED);
+ return changeInfos;
+ }
+
+ if (right == null) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.DELETED);
+ return changeInfos;
+ }
+ if (!yangStatementIsEqual(left, right)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED);
+ }
+
+ int leftIndex = getIndex(left);
+ int rightIndex = getIndex(right);
+ if (leftIndex != rightIndex) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED);
+ }
+ return changeInfos;
+ }
+
+ /**
+ *
+ * @param stmt
+ * @return
+ */
+ private int getIndex(T stmt) {
+ YangStatement parentStmt = stmt.getParentStatement();
+ if (null == parentStmt) {
+ return -1;
+ }
+ int index = -1;
+ for (int i = 0; i < parentStmt.getSubElements().size(); i++) {
+ YangElement subElement = parentStmt.getSubElements().get(i);
+ if (subElement instanceof YangStatement) {
+ index++;
+ if (subElement == stmt) {
+ return index;
+ }
+ }
+ }
+ return index;
+ }
+
+ /**
+ *
+ * @param changeInfo
+ * @return
+ */
+ protected ChangeType getChangeType(CompatibilityRule.ChangeInfo changeInfo) {
+ switch (changeInfo) {
+ case ADDED:
+ case MANDATORY_ADDED: {
+ return ChangeType.ADD;
+ }
+ case DELETED: {
+ return ChangeType.DELETE;
+ }
+ default: {
+ return ChangeType.MODIFY;
+ }
+ }
+ }
+
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(T left, T right, CompatibilityRule.ChangeInfo changeInfo) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.BC, null);
+ }
+
+ /**
+ * get statement string representation.
+ *
+ * @param stmt statement
+ * @return string
+ */
+ public static String getStatement(YangStatement stmt) {
+ if (stmt == null) {
+ return null;
+ }
+ String statement = null;
+ if (stmt instanceof YangBuiltinStatement) {
+ statement = stmt.getYangKeyword().getLocalName();
+ } else {
+ YangUnknown unknown = (YangUnknown) stmt;
+ if (unknown.getExtension() == null) {
+ return unknown.getKeyword();
+ }
+ String moduleName = unknown.getExtension().getContext().getCurModule().getMainModule().getArgStr();
+ String extensionName = unknown.getExtension().getArgStr();
+ statement = moduleName + ":" + extensionName;
+ }
+ return statement;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ protected List<YangCompareResult> compareChildren(T left, T right) {
+ List<YangCompareResult> compareResults =
+ compareStatements(left == null ? new ArrayList<>() : left.getEffectiveSubStatements(),
+ right == null ? new ArrayList<>() : right.getEffectiveSubStatements(), OPTION_ONLY_META);
+ return compareResults;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ public List<YangCompareResult> compare(T left, T right) {
+ List<YangCompareResult> compareResults = new ArrayList<>();
+ List<CompatibilityRule.ChangeInfo> changeInfos = getChangeInfo(left, right);
+ if (!changeInfos.isEmpty()) {
+ YangStatement effectiveStmt = left == null ? right : left;
+ String statement = getStatement(effectiveStmt);
+ String parentStmt = getStatement(effectiveStmt.getParentStatement());
+ for (CompatibilityRule.ChangeInfo changeInfo : changeInfos) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.IGNORE) {
+ continue;
+ }
+ CompatibilityRule compatibilityRule = null;
+ if (null != getCompatibilityRules()) {
+ compatibilityRule = getCompatibilityRules().searchRule(statement, parentStmt, changeInfo);
+ }
+ if (compatibilityRule == null) {
+ //ignore sequence change
+ if (changeInfo != CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED) {
+ YangStatementCompareResult statementCompareResult =
+ new YangStatementCompareResult(getChangeType(changeInfo), left, right);
+ statementCompareResult.setCompatibilityInfo(defaultCompatibility(left, right, changeInfo));
+ compareResults.add(statementCompareResult);
+ }
+
+ } else {
+ YangStatementCompareResult statementCompareResult =
+ new YangStatementCompareResult(getChangeType(changeInfo), left, right);
+ statementCompareResult.setCompatibilityInfo(
+ new CompatibilityInfo(compatibilityRule.getCompatibility(),
+ compatibilityRule.getDescription()));
+ compareResults.add(statementCompareResult);
+ }
+
+ }
+ }
+
+ //sub statements
+ if (left != null && right != null) {
+ compareResults.addAll(compareChildren(left, right));
+ }
+ return compareResults;
+ }
+
+ /**
+ * calculate the similarity.
+ *
+ * @param src source statement
+ * @param candidate candidate statement
+ * @return similarity
+ */
+ public static int calSimilarity(YangStatement src, YangStatement candidate) {
+ if (!src.getYangKeyword().equals(candidate.getYangKeyword())) {
+ return 0;
+ }
+ int similarity = 1;
+
+ if (!src.equals(candidate)) {
+ return similarity;
+ }
+ similarity++;
+ List<YangStatement> srcSubStatements = src.getEffectiveSubStatements();
+ List<YangStatement> candidateSubStatements = candidate.getEffectiveSubStatements();
+ if (srcSubStatements.size() != candidateSubStatements.size()) {
+ return similarity;
+ }
+ similarity++;
+ List<YangStatement> matched = new ArrayList<>();
+ for (YangStatement srcSubStatement : srcSubStatements) {
+ int maxSubSimilarity = 0;
+ YangStatement maxsimliaritySubStatement = null;
+ for (YangStatement candidateSubStatment : candidateSubStatements) {
+ if (contains(matched, candidateSubStatment)) {
+ continue;
+ }
+ int subSimilarity = calSimilarity(srcSubStatement, candidateSubStatment);
+ if (subSimilarity > maxSubSimilarity) {
+ maxSubSimilarity = subSimilarity;
+ maxsimliaritySubStatement = candidateSubStatment;
+ }
+ }
+ similarity += maxSubSimilarity;
+ matched.add(maxsimliaritySubStatement);
+ }
+ return similarity;
+
+ }
+
+ /**
+ * whether list contains an object.
+ *
+ * @param list a list
+ * @param obj object
+ * @return true or false
+ */
+ public static boolean contains(List list, Object obj) {
+ if (list == null) {
+ return false;
+ }
+ for (Object src : list) {
+ if (src == obj) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * search statement from target except matched statements.
+ *
+ * @param statement statement
+ * @param target target statements
+ * @param matched matched statements
+ * @return the searched statement
+ */
+ public static YangStatement searchStatement(YangStatement statement, List<YangStatement> target,
+ List<YangStatement> matched) {
+ if (null == target || target.size() == 0) {
+ return null;
+ }
+ List<YangStatement> matchedTargetStmts = new ArrayList<>();
+ for (YangStatement rightSubStatement : target) {
+ if (contains(matched, rightSubStatement)) {
+ continue;
+ }
+ if (yangStatementIsEqual(statement, rightSubStatement)) {
+ matchedTargetStmts.add(rightSubStatement);
+ continue;
+ }
+ }
+ if (matchedTargetStmts.size() == 1) {
+ return matchedTargetStmts.get(0);
+ } else if (matchedTargetStmts.size() > 1) {
+ int maxSimilarity = 0;
+ YangStatement maxSimilarStatement = null;
+ for (YangStatement matchedTargetStmt : matchedTargetStmts) {
+ int similarity = calSimilarity(statement, matchedTargetStmt);
+ if (similarity <= 1) {
+ continue;
+ }
+ if (similarity > maxSimilarity) {
+ maxSimilarity = similarity;
+ maxSimilarStatement = matchedTargetStmt;
+ }
+ }
+ if (maxSimilarStatement != null) {
+ return maxSimilarStatement;
+ }
+ }
+
+ if (statement.getParentStatement() == null) {
+ return null;
+ }
+
+ YangStatementDef statementDef = statement.getContext().getYangSpecification()
+ .getStatementDef(statement.getParentStatement().getYangKeyword());
+ if (statementDef == null) {
+ if (statement.getParentStatement() instanceof YangUnknown) {
+ //unknown will be treated as cardinality with non-unbounded
+ for (YangStatement rightSubStatement : target) {
+ if (contains(matched, rightSubStatement)) {
+ continue;
+ }
+ return rightSubStatement;
+ }
+ return null;
+ } else {
+ return null;
+ }
+ }
+
+ Cardinality cardinality = statementDef.getSubStatementCardinality(statement.getYangKeyword());
+ if (cardinality == null) {
+ if (statement instanceof YangUnknown) {
+ //unknown will be treated as cardinality with non-unbounded
+ for (YangStatement rightSubStatement : target) {
+ if (contains(matched, rightSubStatement)) {
+ continue;
+ }
+ return rightSubStatement;
+ }
+ }
+ return null;
+ }
+ if (cardinality.isUnbounded()) {
+ return null;
+ }
+
+ for (YangStatement rightSubStatement : target) {
+ if (contains(matched, rightSubStatement)) {
+ continue;
+ }
+ return rightSubStatement;
+ }
+ return null;
+ }
+
+ /**
+ * whether the left statement is equal with right statement.
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return true or false
+ */
+ public static boolean yangStatementIsEqual(YangStatement left, YangStatement right) {
+ if ((left instanceof SchemaNode) && (right instanceof SchemaNode)) {
+ SchemaNode leftSchemaNode = (SchemaNode) left;
+ SchemaNode rightSchemaNode = (SchemaNode) right;
+ if (!left.getContext().getNamespace().equals(right.getContext().getNamespace())) {
+ return false;
+ }
+ if (!yangStatementIsEqual((YangStatement) leftSchemaNode.getClosestAncestorNode(),
+ (YangStatement) rightSchemaNode.getClosestAncestorNode())) {
+ return false;
+ }
+ }
+ if ((left instanceof IdentifierRef) && (right instanceof IdentifierRef)) {
+ if (!left.getYangKeyword().equals(right.getYangKeyword())) {
+ return false;
+ }
+ YangStatement leftRefStatement = ((IdentifierRef) left).getReferenceStatement();
+ YangStatement rightRefStatement = ((IdentifierRef) right).getReferenceStatement();
+ if (leftRefStatement != null && leftRefStatement.equals(rightRefStatement)) {
+ return true;
+ } else if (leftRefStatement == null && rightRefStatement == null) {
+ if (left.getArgStr().equals(right.getArgStr())) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ return left.equals(right);
+ }
+
+ /**
+ * compare the two list of statements.
+ *
+ * @param leftElements the list of left statements
+ * @param rightElements the list of right statements
+ * @param option OPTION_ONLY_META =1/OPTION_ONLY_SCHEMA=2/OPTION_ALL=3
+ * @return compare result
+ */
+ public static List<YangCompareResult> compareStatements(List<? extends YangStatement> leftElements,
+ List<? extends YangStatement> rightElements, int option) {
+ List<YangCompareResult> compareResults = new ArrayList<>();
+ List<YangStatement> foundStatements = new ArrayList<>();
+
+ if (leftElements.size() > 0) {
+ for (YangStatement subElement : leftElements) {
+ YangStatement leftSubStatement = subElement;
+ if (option == OPTION_ONLY_META) {
+ if ((leftSubStatement instanceof SchemaNode)
+ || (leftSubStatement instanceof Referencable)) {
+ continue;
+ }
+ } else if (option == OPTION_ONLY_SCHEMA) {
+ if (!(leftSubStatement instanceof SchemaNode)) {
+ continue;
+ }
+ }
+ if (leftSubStatement instanceof SchemaNode) {
+ SchemaNode leftSchemaNode = (SchemaNode) leftSubStatement;
+ if (!leftSchemaNode.isActive()) {
+ continue;
+ }
+ }
+
+ List<YangStatement> rightSubStatements = new ArrayList<>();
+ for (YangStatement rightElement : rightElements) {
+ if (leftSubStatement.getYangKeyword().equals(rightElement.getYangKeyword())) {
+ rightSubStatements.add(rightElement);
+ }
+ }
+ if (rightSubStatements.size() == 0) {
+ //no right statement, so change type is delete
+ YangStatementComparator comparator =
+ YangComparatorRegister.getInstance().getComparator(getStatement(leftSubStatement));
+ compareResults.addAll(comparator.compare(leftSubStatement, null));
+ continue;
+ }
+ YangStatement matchedRightSubStatement =
+ searchStatement(leftSubStatement, rightSubStatements, foundStatements);
+ if (null == matchedRightSubStatement) {
+ YangStatementComparator comparator =
+ YangComparatorRegister.getInstance().getComparator(getStatement(leftSubStatement));
+ compareResults.addAll(comparator.compare(leftSubStatement, null));
+ } else {
+ foundStatements.add(matchedRightSubStatement);
+ YangStatementComparator comparator = YangComparatorRegister.getInstance().getComparator(
+ getStatement(leftSubStatement == null ? matchedRightSubStatement : leftSubStatement));
+ compareResults.addAll(comparator.compare(leftSubStatement, matchedRightSubStatement));
+ }
+ }
+ }
+ if (rightElements.size() > 0) {
+ for (YangStatement subElement : rightElements) {
+ if (option == OPTION_ONLY_META) {
+ if ((subElement instanceof SchemaNode)
+ || (subElement instanceof Referencable)) {
+ continue;
+ }
+ } else if (option == OPTION_ONLY_SCHEMA) {
+ if (!(subElement instanceof SchemaNode)) {
+ continue;
+ }
+ }
+ if (subElement instanceof SchemaNode) {
+ SchemaNode rightSchemaNode = (SchemaNode) subElement;
+ if (!rightSchemaNode.isActive()) {
+ continue;
+ }
+ }
+ YangStatement rightSubElement = subElement;
+ if (contains(foundStatements, rightSubElement)) {
+ continue;
+ }
+ YangStatementComparator comparator =
+ YangComparatorRegister.getInstance().getComparator(getStatement(rightSubElement));
+ compareResults.addAll(comparator.compare(null, rightSubElement));
+ }
+ }
+ return compareResults;
+ }
+
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompareType.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompareType.java
new file mode 100644
index 0000000..acceac3
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompareType.java
@@ -0,0 +1,23 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+public enum CompareType {
+ STMT,
+ TREE,
+ COMPATIBLE_CHECK
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityInfo.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityInfo.java
new file mode 100644
index 0000000..c27993a
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityInfo.java
@@ -0,0 +1,48 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+public class CompatibilityInfo {
+ private final CompatibilityRule.Compatibility compatibility;
+ private final String description;
+
+ /**
+ * constructor.
+ * @param compatibility compatibility
+ * @param description description
+ */
+ public CompatibilityInfo(CompatibilityRule.Compatibility compatibility, String description) {
+ this.compatibility = compatibility;
+ this.description = description;
+ }
+
+ /**
+ * get the compatibility.
+ * @return compatibility.
+ */
+ public CompatibilityRule.Compatibility getCompatibility() {
+ return compatibility;
+ }
+
+ /**
+ * get the description.
+ * @return string.
+ */
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRule.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRule.java
new file mode 100644
index 0000000..b983048
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRule.java
@@ -0,0 +1,330 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dom4j.Element;
+
+
+public class CompatibilityRule {
+ private final String ruleId;
+ private String parentStmt;
+ private final List<String> statements;//[module_name:]keyword, for example, container/huawei-extension:filter
+ //private List<RuleType> ruleTypes;//STMT OR TREE
+ private final ChangeInfo condition;
+ private List<ChangeInfo> exceptConditions;
+ private final Compatibility compatibility;
+ private String description;
+
+ /**
+ * constructor.
+ *
+ * @param ruleId rule id
+ * @param statements statements can be applied
+ * @param condition matched condition
+ * @param compatibility compatibility
+ */
+ public CompatibilityRule(String ruleId, List<String> statements, ChangeInfo condition,
+ Compatibility compatibility) {
+ this.ruleId = ruleId;
+ this.statements = statements;
+ //this.ruleTypes = ruleTypes;
+ this.condition = condition;
+ this.compatibility = compatibility;
+ }
+
+ /**
+ * get parent statement.
+ *
+ * @return statement.
+ */
+ public String getParentStmt() {
+ return parentStmt;
+ }
+
+ /**
+ * set parent statement.
+ *
+ * @param parentStmt parent statement
+ */
+ public void setParentStmt(String parentStmt) {
+ this.parentStmt = parentStmt;
+ }
+
+ /**
+ * get except conditions.
+ *
+ * @return list of change info
+ */
+ public List<ChangeInfo> getExceptConditions() {
+ return exceptConditions;
+ }
+
+ /**
+ * set except conditions.
+ *
+ * @param exceptConditions conditions
+ */
+ public void setExceptCondition(List<ChangeInfo> exceptConditions) {
+ this.exceptConditions = exceptConditions;
+ }
+
+ /**
+ * set description.
+ *
+ * @param description description.
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * get rule id.
+ *
+ * @return rule id
+ */
+ public String getRuleId() {
+ return ruleId;
+ }
+
+ /**
+ * get applied statements.
+ *
+ * @return statements
+ */
+ public List<String> getStatements() {
+ return statements;
+ }
+
+
+ /**
+ * get condition.
+ *
+ * @return condition
+ */
+ public ChangeInfo getCondition() {
+ return condition;
+ }
+
+ public Compatibility getCompatibility() {
+ return compatibility;
+ }
+
+ /**
+ * get description.
+ *
+ * @return description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * the definition of rule type.
+ */
+ public enum RuleType {
+ STMT("stmt"),
+ TREE("tree");
+ private String name;
+
+ private RuleType(String name) {
+ this.name = name;
+ }
+
+ /**
+ * get rule type from name.
+ *
+ * @param name name
+ * @return rule type
+ */
+ public static RuleType forName(String name) {
+ if (name.equals(STMT.name)) {
+ return STMT;
+ } else if (name.equals(TREE.name)) {
+ return TREE;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * the definition of change info.
+ */
+ public enum ChangeInfo {
+ ANY("any"),//any changes, including added,deleted,changed
+ IGNORE("ignore"),//ignore any changes
+ /*any sub statement is deleted for stmt type, and any schema child node is deleted for tree type
+ */
+ DELETED("deleted"),
+ /* any sub statement is added for stmt type, and any schema child node is added for tree type*/
+ ADDED("added"),
+ MANDATORY_ADDED("mandatory-added"),// add mandatory schema node
+ /*the meaning has been changed,for example, builtin-type changed for type, value changed for enumeration*/
+ CHANGED("changed"),
+ /* any sub statements sequence changed for stmt type, and any schema child nodes sequence changed for
+ tree type, it can be applied to any statement.
+ */
+ SEQUENCE_CHANGED("sequence-changed"),
+ /*expand the scope, for range,it means larger range, for length, it means larger length, for fraction-digits,
+ * it means a lower value, for min-elements, it means a lower value, for max-elements, it means a higher value,
+ * for mandatory, it means from true to false, for config, it means from false to true
+ * for unique, it means one or more attributes are deleted*/
+ EXPAND("expand"),
+ /*reduce the scope, for range,it means smaller range, for length, it means smaller length, for fraction-digits,
+ * it means a higher value, for min-elements, it means a higher value, for max-elements, it means a lower value,
+ * for mandatory, it means from false to true, for config, it means from true to false,
+ * for unique, it means new attributes are added */
+ REDUCE("reduce"),
+ /* for example type from int8 to int16,it is treated non-backward-compatible default. it can be applied to
+ type statement*/
+ INTEGER_TYPE_CHANGED("integer-type-changed");
+ private String name;
+
+ private ChangeInfo(String name) {
+ this.name = name;
+ }
+
+ /**
+ * get name.
+ *
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * get change info from name.
+ *
+ * @param name name
+ * @return change info
+ */
+ public static ChangeInfo forName(String name) {
+ if (name.equals(ANY.name)) {
+ return ANY;
+ } else if (name.equals(IGNORE.getName())) {
+ return IGNORE;
+ } else if (name.equals(EXPAND.getName())) {
+ return EXPAND;
+ } else if (name.equals(REDUCE.getName())) {
+ return REDUCE;
+ } else if (name.equals(CHANGED.getName())) {
+ return CHANGED;
+ } else if (name.equals(INTEGER_TYPE_CHANGED.getName())) {
+ return INTEGER_TYPE_CHANGED;
+ } else if (name.equals(SEQUENCE_CHANGED.getName())) {
+ return SEQUENCE_CHANGED;
+ } else if (name.equals(DELETED.getName())) {
+ return DELETED;
+ } else if (name.equals(ADDED.getName())) {
+ return ADDED;
+ } else if (name.equals(MANDATORY_ADDED.getName())) {
+ return MANDATORY_ADDED;
+ }
+
+ return null;
+ }
+
+ }
+
+ /**
+ * the definition of compatibility.
+ */
+ public enum Compatibility {
+ BC("backward-compatible"),
+ NBC("non-backward-compatible"),
+ UNKNOWN("unknown");
+ private String name;
+
+ private Compatibility(String name) {
+ this.name = name;
+ }
+
+ /**
+ * get name.
+ *
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * get compatibility from name.
+ *
+ * @param name name
+ * @return compatibility
+ */
+ public static Compatibility forName(String name) {
+ if (name.equals(BC.getName())) {
+ return BC;
+ } else if (name.equals(NBC.name)) {
+ return NBC;
+ } else if (name.equals(UNKNOWN.name)) {
+ return UNKNOWN;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * deserialize compatibility rule from xml.
+ *
+ * @param element xml element
+ * @return compatibility rule.
+ */
+ public static CompatibilityRule deserialize(Element element) {
+
+ Element statementsElement = element.element("statements");
+ List<Element> statementElementList = statementsElement.elements("statement");
+ List<String> statements = null;
+ if (statementElementList != null && statementElementList.size() > 0) {
+ statements = new ArrayList<>();
+ for (Element statementElement : statementElementList) {
+ statements.add(statementElement.getTextTrim());
+ }
+ }
+ List<RuleType> types = new ArrayList<>();
+ List<Element> typeElements = element.elements("type");
+ for (Element typeElement : typeElements) {
+ types.add(RuleType.forName(typeElement.getTextTrim()));
+ }
+ ChangeInfo condition = ChangeInfo.forName(element.elementText("condition"));
+ List<ChangeInfo> exceptConditions = null;
+ List<Element> exceptConditionElements = element.elements("except-condition");
+ if (exceptConditionElements != null && exceptConditionElements.size() > 0) {
+ exceptConditions = new ArrayList<>();
+ for (Element exceptConditionElement : exceptConditionElements) {
+ exceptConditions.add(ChangeInfo.forName(exceptConditionElement.getTextTrim()));
+ }
+ }
+ Compatibility compatibility = Compatibility.forName(element.elementText("compatible"));
+ String description = element.elementText("description");
+ Element ruleIdElement = element.element("rule-id");
+ String ruleId = ruleIdElement.getTextTrim();
+ CompatibilityRule rule = new CompatibilityRule(ruleId, statements, condition, compatibility);
+ rule.setExceptCondition(exceptConditions);
+ rule.setDescription(description);
+ Element parentStmtElement = element.element("parent-statement");
+ if (parentStmtElement != null) {
+ rule.setParentStmt(parentStmtElement.getTextTrim());
+ }
+ return rule;
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRules.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRules.java
new file mode 100644
index 0000000..cbab987
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CompatibilityRules.java
@@ -0,0 +1,149 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dom4j.Document;
+import org.dom4j.Element;
+
+public class CompatibilityRules {
+ private final List<CompatibilityRule> compatibilityRules = new ArrayList<>();
+ private static final CompatibilityRules instance = new CompatibilityRules();
+
+ private CompatibilityRules() {
+
+ }
+
+ /**
+ * add a compatibility rule.
+ *
+ * @param rule rule
+ * @return true or false
+ */
+ public boolean addCompatibilityRule(CompatibilityRule rule) {
+ if (null != getCompatibilityRule(rule.getRuleId())) {
+ return false;
+ }
+ return compatibilityRules.add(rule);
+ }
+
+ /**
+ * get compatibility rules.
+ *
+ * @return rules
+ */
+ public List<CompatibilityRule> getCompatibilityRules() {
+ return compatibilityRules;
+ }
+
+ /**
+ * get compatibility rule by specified rule id.
+ *
+ * @param ruleId rule id
+ * @return rule
+ */
+ public CompatibilityRule getCompatibilityRule(String ruleId) {
+ for (CompatibilityRule rule : compatibilityRules) {
+ if (rule.getRuleId().equals(ruleId)) {
+ return rule;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * get instance of compatibility rules.
+ *
+ * @return rules instance.
+ */
+ public static CompatibilityRules getInstance() {
+ return instance;
+ }
+
+ /**
+ * deserialize from xml document.
+ *
+ * @param document xml document
+ */
+ public void deserialize(Document document) {
+ compatibilityRules.clear();
+ Element root = document.getRootElement();
+ List<Element> children = root.elements("rule");
+ for (Element ruleElement : children) {
+ CompatibilityRule rule = CompatibilityRule.deserialize(ruleElement);
+ addCompatibilityRule(rule);
+ }
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ private boolean matchCondition(CompatibilityRule left, CompatibilityRule.ChangeInfo right) {
+ if (left.getCondition() == CompatibilityRule.ChangeInfo.ANY) {
+ return true;
+ } else if (left.getCondition() == CompatibilityRule.ChangeInfo.IGNORE) {
+ return false;
+ }
+ if (left.getCondition() == right) {
+ return true;
+ }
+ if (left.getCondition() == CompatibilityRule.ChangeInfo.CHANGED
+ && (right == CompatibilityRule.ChangeInfo.EXPAND
+ || right == CompatibilityRule.ChangeInfo.REDUCE
+ || right == CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED
+ || right == CompatibilityRule.ChangeInfo.INTEGER_TYPE_CHANGED)) {
+ if (left.getExceptConditions() != null && left.getExceptConditions().contains(right)) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * search rule by some arguments.
+ *
+ * @param statement statement
+ * @param parentStmt parent statement
+ * @param changeInfo change info
+ * @return matched rule
+ */
+ public CompatibilityRule searchRule(String statement, String parentStmt,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ for (CompatibilityRule rule : compatibilityRules) {
+ if (rule.getStatements().contains(statement)) {
+ if (rule.getParentStmt() != null) {
+ if (parentStmt == null) {
+ continue;
+ }
+ if (!rule.getParentStmt().equals(parentStmt)) {
+ continue;
+ }
+ }
+ if (matchCondition(rule, changeInfo)) {
+ return rule;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ConfigComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ConfigComparator.java
new file mode 100644
index 0000000..a0018d7
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ConfigComparator.java
@@ -0,0 +1,78 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.schema.SchemaTreeType;
+import org.yangcentral.yangkit.model.api.stmt.Config;
+import org.yangcentral.yangkit.model.api.stmt.SchemaNode;
+
+
+public class ConfigComparator extends CommonYangStatementComparator<Config> {
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Config left, Config right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ changeInfos.addAll(super.getChangeInfo(left, right));
+ if (left.getContext().getSelf() instanceof SchemaNode) {
+ SchemaNode schemaNode = (SchemaNode) left.getContext().getSelf();
+ if (schemaNode.getSchemaTreeType() != SchemaTreeType.DATATREE) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.IGNORE);
+ return changeInfos;
+ }
+ } else if (left.getParentStatement() != null) {
+ if (left.getParentStatement() instanceof SchemaNode) {
+ SchemaNode schemaNode = (SchemaNode) left.getParentStatement();
+ if (schemaNode.getSchemaTreeType() != SchemaTreeType.DATATREE) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.IGNORE);
+ return changeInfos;
+ }
+ }
+ }
+ if (left.isConfig() && !right.isConfig()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE);
+ } else if (!left.isConfig() && right.isConfig()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ }
+
+ return changeInfos;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Config left, Config right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "config is changed from false to true, it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DefaultComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DefaultComparator.java
new file mode 100644
index 0000000..f7b1c13
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DefaultComparator.java
@@ -0,0 +1,41 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.Default;
+
+
+public class DefaultComparator extends CommonYangStatementComparator<Default> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Default left, Default right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.DELETED
+ || changeInfo == CompatibilityRule.ChangeInfo.CHANGED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "delete or change default statement, it's non-backward-compatible");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DescriptionComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DescriptionComparator.java
new file mode 100644
index 0000000..2b5db1c
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/DescriptionComparator.java
@@ -0,0 +1,40 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.Description;
+
+
+public class DescriptionComparator extends CommonYangStatementComparator<Description> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Description left, Description right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "delete description statement, it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/EnumBitComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/EnumBitComparator.java
new file mode 100644
index 0000000..e0fb3ef
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/EnumBitComparator.java
@@ -0,0 +1,43 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.YangStatement;
+
+
+public class EnumBitComparator extends CommonYangStatementComparator {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(YangStatement left, YangStatement right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "delete an enum, it's non-backward-compatible.");
+ } else if (changeInfo == CompatibilityRule.ChangeInfo.ADDED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.BC,
+ "add a new enum, it's backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IdentifierComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IdentifierComparator.java
new file mode 100644
index 0000000..3eff979
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IdentifierComparator.java
@@ -0,0 +1,40 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.YangStatement;
+
+
+public class IdentifierComparator extends CommonYangStatementComparator {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(YangStatement left, YangStatement right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "the statement is deleted, "
+ + "it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IfFeatureComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IfFeatureComparator.java
new file mode 100644
index 0000000..dfa0199
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/IfFeatureComparator.java
@@ -0,0 +1,42 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.IfFeature;
+
+
+public class IfFeatureComparator extends CommonYangStatementComparator<IfFeature> {
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(IfFeature left, IfFeature right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.ADDED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "add a new if-feature,"
+ + "it's non-backward-compatible.");
+ } else if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.UNKNOWN,
+ "if-feature is changed, it's compatibility is unknown.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MandatoryComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MandatoryComparator.java
new file mode 100644
index 0000000..375d69b
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MandatoryComparator.java
@@ -0,0 +1,63 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.yangcentral.yangkit.model.api.stmt.Mandatory;
+
+
+public class MandatoryComparator extends CommonYangStatementComparator<Mandatory> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Mandatory left, Mandatory right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+
+ if (left.getValue() && !right.getValue()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ } else if (!left.getValue() && right.getValue()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE);
+ }
+ if (super.getChangeInfo(left, right).contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED);
+ }
+ return changeInfos;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Mandatory left, Mandatory right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "mandatory is changed from false to true,"
+ + "it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MaxElementsComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MaxElementsComparator.java
new file mode 100644
index 0000000..1361ef2
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MaxElementsComparator.java
@@ -0,0 +1,69 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.stmt.MaxElements;
+
+
+public class MaxElementsComparator extends CommonYangStatementComparator<MaxElements> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(MaxElements left, MaxElements right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ if (left.isUnbounded() && !right.isUnbounded()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE);
+ } else if (!left.isUnbounded() && right.isUnbounded()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ } else if (!left.isUnbounded() && !right.isUnbounded()) {
+ if (left.getValue() < right.getValue()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ } else if (left.getValue() > right.getValue()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE);
+ }
+ }
+ if (super.getChangeInfo(left, right).contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED);
+ }
+ return changeInfos;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(MaxElements left, MaxElements right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "the max-elements is reduced,"
+ + "it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MinElementsComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MinElementsComparator.java
new file mode 100644
index 0000000..f97e313
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/MinElementsComparator.java
@@ -0,0 +1,63 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.stmt.MinElements;
+
+
+public class MinElementsComparator extends CommonYangStatementComparator<MinElements> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(MinElements left, MinElements right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ if (left.getValue() > right.getValue()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ } else if (left.getValue() < right.getValue()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE);
+ }
+ if (super.getChangeInfo(left, right).contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED);
+ }
+ return changeInfos;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(MinElements left, MinElements right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "min-elements is increased,"
+ + "it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ModuleComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ModuleComparator.java
new file mode 100644
index 0000000..9c9bb7f
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ModuleComparator.java
@@ -0,0 +1,86 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.yangcentral.yangkit.model.api.stmt.MainModule;
+import org.yangcentral.yangkit.model.api.stmt.Module;
+
+
+
+public class ModuleComparator extends CommonYangStatementComparator<Module> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Module left, Module right) {
+ return super.getChangeInfo(left, right);
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Module left, Module right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.DELETED
+ || changeInfo == CompatibilityRule.ChangeInfo.CHANGED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "delete a module or change module name,"
+ + "it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<YangCompareResult> compareChildren(Module left, Module right) {
+ List<YangCompareResult> results = new ArrayList<>();
+ Module temp = left;
+ if (temp == null) {
+ temp = right;
+ }
+ results.addAll(compareStatements(left == null ? new ArrayList<>() : left.getEffectiveMetaStatements(),
+ right == null ? new ArrayList<>() : right.getEffectiveMetaStatements(), OPTION_ALL));
+ results.addAll(compareStatements(left == null ? new ArrayList<>() : left.getEffectiveLinkageStatement(),
+ right == null ? new ArrayList<>() : right.getEffectiveLinkageStatement(), OPTION_ALL));
+ if (temp instanceof MainModule) {
+ results.addAll(compareStatements(left == null ? new ArrayList<>() : left.getEffectiveDefinitionStatement(),
+ right == null ? new ArrayList<>() : right.getEffectiveDefinitionStatement(), OPTION_ONLY_META));
+ results.addAll(compareStatements(
+ left == null ? new ArrayList<>() : YangComparator.getEffectiveSchemaNodeChildren(left),
+ right == null ? new ArrayList<>() : YangComparator.getEffectiveSchemaNodeChildren(right),
+ OPTION_ONLY_SCHEMA));
+ }
+ return results;
+ }
+
+
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/NamespaceComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/NamespaceComparator.java
new file mode 100644
index 0000000..8ea9953
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/NamespaceComparator.java
@@ -0,0 +1,39 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.Namespace;
+
+
+public class NamespaceComparator extends CommonYangStatementComparator<Namespace> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Namespace left, Namespace right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "namespace MUST NOT be changed.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/OperationComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/OperationComparator.java
new file mode 100644
index 0000000..58cde02
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/OperationComparator.java
@@ -0,0 +1,90 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.stmt.Operation;
+import org.yangcentral.yangkit.model.api.stmt.SchemaNode;
+import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer;
+import org.yangcentral.yangkit.model.api.stmt.YangStatement;
+
+
+
+public class OperationComparator extends SchemaNodeComparator<Operation> {
+
+ /**
+ *
+ * @param schemaNodeContainer
+ * @return
+ */
+ private boolean hasActiveSchemaChildren(SchemaNodeContainer schemaNodeContainer) {
+ for (SchemaNode schemaNode : schemaNodeContainer.getSchemaNodeChildren()) {
+ if (schemaNode.isActive()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<YangCompareResult> compareChildren(Operation left, Operation right) {
+ List<YangCompareResult> compareResults = new ArrayList<>();
+ compareResults.addAll(compareStatements(left == null ? new ArrayList<>() : left.getEffectiveSubStatements(),
+ right == null ? new ArrayList<>() : right.getEffectiveSubStatements(), OPTION_ONLY_META));
+
+
+ List<YangStatement> leftSchemaChildren = new ArrayList<>();
+ List<YangStatement> rightSchemaChildren = new ArrayList<>();
+ //input
+ if (left.getInput() != null && left.getInput().isActive()) {
+ //check input's schema children, only more than zero can be add to left schema array
+ if (hasActiveSchemaChildren(left.getInput())) {
+ leftSchemaChildren.add(left.getInput());
+ }
+ }
+ if (right.getInput() != null && right.getInput().isActive()) {
+ //check input's schema children, only more than zero can be add to right schema array
+ if (hasActiveSchemaChildren(right.getInput())) {
+ rightSchemaChildren.add(right.getInput());
+ }
+ }
+ //output
+ if (left.getOutput() != null && left.getOutput().isActive()) {
+ //check output's schema children, only more than zero can be add to left schema array
+ if (hasActiveSchemaChildren(left.getOutput())) {
+ leftSchemaChildren.add(left.getOutput());
+ }
+ }
+ if (right.getOutput() != null && right.getOutput().isActive()) {
+ //check out's schema children, only more than zero can be add to right schema array
+ if (hasActiveSchemaChildren(right.getOutput())) {
+ rightSchemaChildren.add(right.getOutput());
+ }
+ }
+ compareResults.addAll(compareStatements(leftSchemaChildren, rightSchemaChildren, OPTION_ALL));
+ return compareResults;
+ }
+}
+
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/PatternComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/PatternComparator.java
new file mode 100644
index 0000000..83f3f9b
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/PatternComparator.java
@@ -0,0 +1,43 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.type.Pattern;
+
+
+public class PatternComparator extends CommonYangStatementComparator<Pattern> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Pattern left, Pattern right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.ADDED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "add a pattern, it's non-backward-compatible.");
+ } else if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.UNKNOWN,
+ "change a pattern, the compatibility is unknown.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/RangeLengthComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/RangeLengthComparator.java
new file mode 100644
index 0000000..076b7bf
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/RangeLengthComparator.java
@@ -0,0 +1,67 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.stmt.type.SectionExpression;
+
+
+public class RangeLengthComparator extends CommonYangStatementComparator<SectionExpression> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(SectionExpression left, SectionExpression right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ if (!left.equals(right)) {
+ if (left.isSubSet(right)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ } else if (right.isSubSet(left)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE);
+ }
+ }
+
+ List<CompatibilityRule.ChangeInfo> superChangeInfos = super.getChangeInfo(left, right);
+ if (superChangeInfos.contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED);
+ }
+ return changeInfos;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(SectionExpression left, SectionExpression right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, "the range or length is reduced, "
+ + "it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ReferenceComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ReferenceComparator.java
new file mode 100644
index 0000000..be50fa1
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ReferenceComparator.java
@@ -0,0 +1,40 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.Reference;
+
+
+public class ReferenceComparator extends CommonYangStatementComparator<Reference> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Reference left, Reference right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.DELETED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "delete reference, it;s non-backward-compatible");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/SchemaNodeComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/SchemaNodeComparator.java
new file mode 100644
index 0000000..ff6de53
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/SchemaNodeComparator.java
@@ -0,0 +1,182 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.stmt.SchemaNode;
+import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer;
+
+
+
+public class SchemaNodeComparator<T extends SchemaNode> extends CommonYangStatementComparator<T> {
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(T left, T right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ if (left == null && right != null) {
+ if (right.isMandatory()) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.MANDATORY_ADDED);
+ } else {
+ changeInfos.add(CompatibilityRule.ChangeInfo.ADDED);
+ }
+ } else if (left != null && right == null) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.DELETED);
+ } else if (left != null && right != null) {
+ changeInfos.addAll(super.getChangeInfo(left, right));
+ }
+ return changeInfos;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(T left, T right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.MANDATORY_ADDED
+ || changeInfo == CompatibilityRule.ChangeInfo.DELETED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, null);
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<YangCompareResult> compareChildren(T left, T right) {
+ List<YangCompareResult> results = new ArrayList<>();
+ results.addAll(super.compareChildren(left, right));
+
+ SchemaNode temp = left;
+ if (temp == null) {
+ temp = right;
+ }
+ if ((temp instanceof SchemaNodeContainer)) {
+ SchemaNodeContainer leftContainer = (SchemaNodeContainer) left;
+ SchemaNodeContainer rightContainer = (SchemaNodeContainer) right;
+ results.addAll(compareStatements(leftContainer == null ? new ArrayList<>() :
+ YangComparator.getEffectiveSchemaNodeChildren(leftContainer),
+ rightContainer == null ? new ArrayList<>() :
+ YangComparator.getEffectiveSchemaNodeChildren(rightContainer), OPTION_ONLY_SCHEMA));
+ }
+ return results;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ public List<YangCompareResult> compare(T left, T right) {
+ List<YangCompareResult> compareResults = new ArrayList<>();
+ if (left == null && right == null) {
+ return compareResults;
+ }
+ List<CompatibilityRule.ChangeInfo> changeInfos = getChangeInfo(left, right);
+ List<YangTreeCompareResult> treeCompareResults = new ArrayList<>();
+ SchemaNode temp = right;
+ if (temp == null) {
+ temp = left;
+ }
+ String statement = getStatement(temp);
+ String parentStatement = getStatement(temp.getParentStatement());
+ if (!changeInfos.isEmpty()) {
+ for (CompatibilityRule.ChangeInfo changeInfo : changeInfos) {
+
+ CompatibilityRule compatibilityRule = null;
+ if (getCompatibilityRules() != null) {
+ compatibilityRule = getCompatibilityRules().searchRule(statement, parentStatement, changeInfo);
+ }
+ if (compatibilityRule == null) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED) {
+ continue;
+ }
+ YangTreeCompareResult treeCompareResult =
+ new YangTreeCompareResult(temp.getSchemaPath(), getChangeType(changeInfo));
+ treeCompareResult.setLeft(left);
+ treeCompareResult.setRight(right);
+ treeCompareResult.setCompatibilityInfo(defaultCompatibility(left, right, changeInfo));
+ treeCompareResults.add(treeCompareResult);
+ } else {
+ YangTreeCompareResult treeCompareResult =
+ new YangTreeCompareResult(temp.getSchemaPath(), getChangeType(changeInfo));
+ treeCompareResult.setLeft(left);
+ treeCompareResult.setRight(right);
+ treeCompareResult.setCompatibilityInfo(new CompatibilityInfo(compatibilityRule.getCompatibility(),
+ compatibilityRule.getDescription()));
+ treeCompareResults.add(treeCompareResult);
+ }
+ }
+ compareResults.addAll(treeCompareResults);
+ }
+
+ //sub statements
+ if (left != null && right != null) {
+ List<YangCompareResult> childrenResults = compareChildren(left, right);
+ for (YangCompareResult childResult : childrenResults) {
+ if (childResult instanceof YangStatementCompareResult) {
+ if (treeCompareResults.isEmpty()) {
+ YangTreeCompareResult treeCompareResult =
+ new YangTreeCompareResult(temp.getSchemaPath(), ChangeType.MODIFY);
+ treeCompareResult.setLeft(left);
+ treeCompareResult.setRight(right);
+ treeCompareResult.setCompatibilityInfo(
+ new CompatibilityInfo(CompatibilityRule.Compatibility.BC, null));
+ treeCompareResults.add(treeCompareResult);
+ compareResults.add(treeCompareResult);
+ }
+ for (YangTreeCompareResult treeCompareResult : treeCompareResults) {
+ treeCompareResult.addMetaCompareResult(childResult);
+ if (childResult.getCompatibilityInfo().getCompatibility()
+ == CompatibilityRule.Compatibility.NBC) {
+ treeCompareResult.setCompatibilityInfo(
+ new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, null));
+ } else if (childResult.getCompatibilityInfo().getCompatibility()
+ == CompatibilityRule.Compatibility.UNKNOWN) {
+ if (treeCompareResult.getCompatibilityInfo().getCompatibility()
+ == CompatibilityRule.Compatibility.BC) {
+ treeCompareResult.setCompatibilityInfo(
+ new CompatibilityInfo(CompatibilityRule.Compatibility.UNKNOWN, null));
+ }
+ }
+ }
+ } else {
+ compareResults.add(childResult);
+ }
+ }
+ }
+ return compareResults;
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/StatusComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/StatusComparator.java
new file mode 100644
index 0000000..8a6df4d
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/StatusComparator.java
@@ -0,0 +1,73 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.yangcentral.yangkit.model.api.stmt.Status;
+import org.yangcentral.yangkit.model.api.stmt.StatusStmt;
+
+
+
+
+public class StatusComparator extends CommonYangStatementComparator<StatusStmt> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(StatusStmt left, StatusStmt right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ if (!left.equals(right)) {
+ if (left.getStatus() == Status.CURRENT) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ } else if (left.getStatus() == Status.DEPRECATED && right.getStatus() == Status.OBSOLETE) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ } else {
+ changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE);
+ }
+ }
+ List<CompatibilityRule.ChangeInfo> superChangeInfos = super.getChangeInfo(left, right);
+ if (superChangeInfos.contains(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED);
+ }
+ return changeInfos;
+ }
+
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(StatusStmt left, StatusStmt right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.REDUCE) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "un-acceptable change of status,"
+ + "changed from current to deprecated or obsolete and changed from deprecated "
+ + "to obsolete ard acceptable.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/TypeStatementComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/TypeStatementComparator.java
new file mode 100644
index 0000000..d934cfb
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/TypeStatementComparator.java
@@ -0,0 +1,122 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yangcentral.yangkit.model.api.restriction.YangInteger;
+import org.yangcentral.yangkit.model.api.stmt.Type;
+import org.yangcentral.yangkit.model.api.stmt.YangStatement;
+
+
+
+/**
+ * comparator for type statement.
+ *
+ * @since 2022-06-10
+ */
+public class TypeStatementComparator extends CommonYangStatementComparator<Type> {
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Type left, Type right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ if (left == null && right != null) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.ADDED);
+ return changeInfos;
+ } else if (left != null && right == null) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.DELETED);
+ return changeInfos;
+ } else if (left == null && right == null) {
+ return changeInfos;
+ }
+ if (left.getRestriction().getClass() == right.getRestriction().getClass()) {
+ return changeInfos;
+ }
+ if (left.getRestriction().getClass() != right.getRestriction().getClass()) {
+ if ((left.getRestriction() instanceof YangInteger) && (right.getRestriction() instanceof YangInteger)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.INTEGER_TYPE_CHANGED);
+ } else {
+ if (!changeInfos.contains(CompatibilityRule.ChangeInfo.CHANGED)) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED);
+ }
+ }
+ }
+ return changeInfos;
+ }
+
+ @Override
+ public List<YangCompareResult> compare(Type left, Type right) {
+ List<YangCompareResult> compareResults = new ArrayList<>();
+ List<CompatibilityRule.ChangeInfo> changeInfos = getChangeInfo(left, right);
+
+ if (!changeInfos.isEmpty()) {
+ YangStatement effectiveStmt = left == null ? right : left;
+ String statement = getStatement(effectiveStmt);
+ String parentStmt = getStatement(effectiveStmt.getParentStatement());
+ for (CompatibilityRule.ChangeInfo changeInfo : changeInfos) {
+ CompatibilityRule compatibilityRule = null;
+ if (getCompatibilityRules() != null) {
+ compatibilityRule = getCompatibilityRules().searchRule(statement, parentStmt, changeInfo);
+ }
+ if (compatibilityRule == null) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.SEQUENCE_CHANGED) {
+ continue;
+ }
+ YangStatementCompareResult statementCompareResult =
+ new YangStatementCompareResult(getChangeType(changeInfo), left, right);
+ statementCompareResult.setCompatibilityInfo(defaultCompatibility(left, right, changeInfo));
+ compareResults.add(statementCompareResult);
+ } else {
+ YangStatementCompareResult statementCompareResult =
+ new YangStatementCompareResult(getChangeType(changeInfo), left, right);
+ statementCompareResult.setCompatibilityInfo(
+ new CompatibilityInfo(compatibilityRule.getCompatibility(),
+ compatibilityRule.getDescription()));
+ compareResults.add(statementCompareResult);
+ }
+
+ }
+ }
+
+ //sub statements
+ if (left != null && right != null) {
+ if (left.getRestriction().getClass() != right.getRestriction().getClass()) {
+ if ((left.getRestriction() instanceof YangInteger) && (right.getRestriction() instanceof YangInteger)) {
+ compareResults.addAll(compareChildren(left, right));
+ }
+ } else {
+ compareResults.addAll(compareChildren(left, right));
+ }
+
+ }
+ return compareResults;
+ }
+
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Type left, Type right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED
+ || changeInfo == CompatibilityRule.ChangeInfo.INTEGER_TYPE_CHANGED
+ || changeInfo == CompatibilityRule.ChangeInfo.DELETED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC, null);
+ }
+
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+
+
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UniqueComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UniqueComparator.java
new file mode 100644
index 0000000..1611818
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UniqueComparator.java
@@ -0,0 +1,105 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.yangcentral.yangkit.model.api.stmt.Leaf;
+import org.yangcentral.yangkit.model.api.stmt.Unique;
+import org.yangcentral.yangkit.model.api.stmt.YangStatement;
+
+
+public class UniqueComparator extends CommonYangStatementComparator<Unique> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @return
+ */
+ @Override
+ protected List<CompatibilityRule.ChangeInfo> getChangeInfo(Unique left, Unique right) {
+ List<CompatibilityRule.ChangeInfo> changeInfos = new ArrayList<>();
+ if (left == null && right != null) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.ADDED);
+ } else if (left != null && right == null) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.DELETED);
+ } else {
+ if (!left.equals(right)) {
+ int leftSize = left.getUniqueNodes().size();
+ int rightSize = right.getUniqueNodes().size();
+ if (leftSize == rightSize) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED);
+ } else if (leftSize < rightSize) {
+ boolean notfind = false;
+ for (int i = 0; i < leftSize; i++) {
+ Leaf leftUnique = left.getUniqueNodes().get(i);
+ List<YangStatement> rightUniques = new ArrayList<>();
+ for (Leaf rightUnique : right.getUniqueNodes()) {
+ rightUniques.add(rightUnique);
+ }
+ if (searchStatement(leftUnique, rightUniques, new ArrayList<>()) == null) {
+ notfind = true;
+ }
+ }
+ if (notfind) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED);
+ } else {
+ changeInfos.add(CompatibilityRule.ChangeInfo.REDUCE);
+ }
+ } else {
+ boolean notfind = false;
+ for (int i = 0; i < rightSize; i++) {
+ Leaf rightUnique = right.getUniqueNodes().get(i);
+ List<YangStatement> leftUniques = new ArrayList<>();
+ for (Leaf leftUnique : left.getUniqueNodes()) {
+ leftUniques.add(leftUnique);
+ }
+ if (searchStatement(rightUnique, leftUniques, new ArrayList<>()) == null) {
+ notfind = true;
+ }
+ }
+ if (notfind) {
+ changeInfos.add(CompatibilityRule.ChangeInfo.CHANGED);
+ } else {
+ changeInfos.add(CompatibilityRule.ChangeInfo.EXPAND);
+ }
+ }
+ }
+ }
+
+ return changeInfos;
+ }
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Unique left, Unique right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.ADDED
+ || changeInfo == CompatibilityRule.ChangeInfo.REDUCE) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "add new unique or add a new node on unique is non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UnitsComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UnitsComparator.java
new file mode 100644
index 0000000..f484af2
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/UnitsComparator.java
@@ -0,0 +1,41 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.Units;
+
+
+public class UnitsComparator extends CommonYangStatementComparator<Units> {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(Units left, Units right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.DELETED
+ || changeInfo == CompatibilityRule.ChangeInfo.CHANGED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "delete or change units, it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ValuePositionComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ValuePositionComparator.java
new file mode 100644
index 0000000..c680dea
--- /dev/null
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/ValuePositionComparator.java
@@ -0,0 +1,39 @@
+/*
+Copyright 2023 Huawei Technologies
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+package org.onap.modeling.yangkit.comparator;
+
+import org.yangcentral.yangkit.model.api.stmt.YangStatement;
+
+
+public class ValuePositionComparator extends CommonYangStatementComparator {
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
+ @Override
+ protected CompatibilityInfo defaultCompatibility(YangStatement left, YangStatement right,
+ CompatibilityRule.ChangeInfo changeInfo) {
+ if (changeInfo == CompatibilityRule.ChangeInfo.CHANGED) {
+ return new CompatibilityInfo(CompatibilityRule.Compatibility.NBC,
+ "change value or position, it's non-backward-compatible.");
+ }
+ return super.defaultCompatibility(left, right, changeInfo);
+ }
+}
diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java
index cc6992a..3825a74 100644
--- a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java
+++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/WhenMustComparator.java
@@ -19,6 +19,14 @@ package org.onap.modeling.yangkit.comparator;
import org.yangcentral.yangkit.model.api.stmt.YangStatement;
public class WhenMustComparator extends CommonYangStatementComparator {
+
+ /**
+ *
+ * @param left left statement
+ * @param right right statement
+ * @param changeInfo
+ * @return
+ */
@Override
protected CompatibilityInfo defaultCompatibility(YangStatement left, YangStatement right,
CompatibilityRule.ChangeInfo changeInfo) {