+ private static void addOrReplaceNode(
+ StatementContextBase<?, ?, ?> refineSubstatementCtx,
+ StatementContextBase<?, ?, ?> refineTargetNodeCtx) {
+
+ StatementDefinition refineSubstatementDef = refineSubstatementCtx
+ .getPublicDefinition();
+ StatementDefinition refineTargetNodeDef = refineTargetNodeCtx
+ .getPublicDefinition();
+
+ if (!isSupportedRefineTarget(refineSubstatementCtx, refineTargetNodeCtx)) {
+ throw new SourceException("Error in module '"
+ + refineSubstatementCtx.getRoot().getStatementArgument()
+ + "' in the refine of uses '"
+ + refineSubstatementCtx.getParentContext()
+ .getStatementArgument()
+ + "': can not perform refine of '"
+ + refineSubstatementCtx.getPublicDefinition()
+ + "' for the target '"
+ + refineTargetNodeCtx.getPublicDefinition() + "'.",
+ refineSubstatementCtx.getStatementSourceReference());
+ }
+
+ if (isAllowedToAddByRefine(refineSubstatementDef)) {
+ refineTargetNodeCtx.addEffectiveSubstatement(refineSubstatementCtx);
+ } else {
+ refineTargetNodeCtx.removeStatementFromEffectiveSubstatements(refineSubstatementDef);
+ refineTargetNodeCtx.addEffectiveSubstatement(refineSubstatementCtx);
+ }
+ }
+
+ private static boolean isAllowedToAddByRefine(
+ StatementDefinition publicDefinition) {
+ Set<StatementDefinition> allowedToAddByRefineDefSet = new HashSet<>();
+ allowedToAddByRefineDefSet.add(Rfc6020Mapping.MUST);
+
+ return allowedToAddByRefineDefSet.contains(publicDefinition);
+ }
+
+ private static boolean isSupportedRefineSubstatement(
+ StatementContextBase<?, ?, ?> refineSubstatementCtx) {
+
+ Collection<?> supportedRefineSubstatements = refineSubstatementCtx
+ .getFromNamespace(ValidationBundlesNamespace.class,
+ ValidationBundleType.SUPPORTED_REFINE_SUBSTATEMENTS);
+
+ return supportedRefineSubstatements == null
+ || supportedRefineSubstatements.isEmpty()
+ || supportedRefineSubstatements.contains(refineSubstatementCtx
+ .getPublicDefinition())
+ || StmtContextUtils.isUnknownStatement(refineSubstatementCtx);
+ }
+
+ private static boolean isSupportedRefineTarget(
+ StatementContextBase<?, ?, ?> refineSubstatementCtx,
+ StatementContextBase<?, ?, ?> refineTargetNodeCtx) {
+
+ Collection<?> supportedRefineTargets = YangValidationBundles.SUPPORTED_REFINE_TARGETS
+ .get(refineSubstatementCtx.getPublicDefinition());
+
+ return supportedRefineTargets == null
+ || supportedRefineTargets.isEmpty()
+ || supportedRefineTargets.contains(refineTargetNodeCtx
+ .getPublicDefinition());
+ }
+