-
- /**
- * Config statements are not all that common which means we are performing a recursive search towards the root
- * every time {@link #isConfiguration()} is invoked. This is quite expensive because it causes a linear search
- * for the (usually non-existent) config statement.
- *
- * <p>
- * This method maintains a resolution cache, so once we have returned a result, we will keep on returning the same
- * result without performing any lookups, solely to support {@link SubstatementContext#isConfiguration()}.
- *
- * <p>
- * Note: use of this method implies that {@link #isIgnoringConfig()} is realized with
- * {@link #isIgnoringConfig(StatementContextBase)}.
- */
- final boolean isConfiguration(final StatementContextBase<?, ?, ?> parent) {
- final int fl = flags & SET_CONFIGURATION;
- if (fl != 0) {
- return fl == SET_CONFIGURATION;
- }
- if (isIgnoringConfig(parent)) {
- // Note: SET_CONFIGURATION has been stored in flags
- return true;
- }
-
- final boolean isConfig;
- final Optional<Boolean> optConfig = findSubstatementArgument(ConfigEffectiveStatement.class);
- if (optConfig.isPresent()) {
- isConfig = optConfig.orElseThrow();
- if (isConfig) {
- // Validity check: if parent is config=false this cannot be a config=true
- InferenceException.throwIf(!parent.isConfiguration(), getStatementSourceReference(),
- "Parent node has config=false, this node must not be specifed as config=true");
- }
- } else {
- // If "config" statement is not specified, the default is the same as the parent's "config" value.
- isConfig = parent.isConfiguration();
- }
-
- // Resolved, make sure we cache this return
- flags |= isConfig ? SET_CONFIGURATION : HAVE_CONFIGURATION;
- return isConfig;
- }
-
- protected abstract boolean isIgnoringConfig();
-
- /**
- * This method maintains a resolution cache for ignore config, so once we have returned a result, we will
- * keep on returning the same result without performing any lookups. Exists only to support
- * {@link SubstatementContext#isIgnoringConfig()}.
- *
- * <p>
- * Note: use of this method implies that {@link #isConfiguration()} is realized with
- * {@link #isConfiguration(StatementContextBase)}.
- */
- final boolean isIgnoringConfig(final StatementContextBase<?, ?, ?> parent) {
- final int fl = flags & SET_IGNORE_CONFIG;
- if (fl != 0) {
- return fl == SET_IGNORE_CONFIG;
- }
- if (definition.support().isIgnoringConfig() || parent.isIgnoringConfig()) {
- flags |= SET_IGNORE_CONFIG;
- return true;
- }
-
- flags |= HAVE_IGNORE_CONFIG;
- return false;
- }
-
- protected abstract boolean isIgnoringIfFeatures();
-
- /**
- * This method maintains a resolution cache for ignore if-feature, so once we have returned a result, we will
- * keep on returning the same result without performing any lookups. Exists only to support
- * {@link SubstatementContext#isIgnoringIfFeatures()}.
- */
- final boolean isIgnoringIfFeatures(final StatementContextBase<?, ?, ?> parent) {
- final int fl = flags & SET_IGNORE_IF_FEATURE;
- if (fl != 0) {
- return fl == SET_IGNORE_IF_FEATURE;
- }
- if (definition.support().isIgnoringIfFeatures() || parent.isIgnoringIfFeatures()) {
- flags |= SET_IGNORE_IF_FEATURE;
- return true;
- }
-
- flags |= HAVE_IGNORE_IF_FEATURE;
- return false;
- }
-
- // Exists only to support {SubstatementContext,InferredStatementContext}.getSchemaPath()
- @Deprecated
- final @NonNull Optional<SchemaPath> substatementGetSchemaPath() {
- SchemaPath local = schemaPath;
- if (local == null) {
- synchronized (this) {
- local = schemaPath;
- if (local == null) {
- schemaPath = local = createSchemaPath(coerceParentContext());
- }
- }
- }
-
- return Optional.ofNullable(local);
- }
-
- @Deprecated
- private SchemaPath createSchemaPath(final Mutable<?, ?, ?> parent) {
- final Optional<SchemaPath> maybeParentPath = parent.getSchemaPath();
- verify(maybeParentPath.isPresent(), "Parent %s does not have a SchemaPath", parent);
- final SchemaPath parentPath = maybeParentPath.get();
-
- if (StmtContextUtils.isUnknownStatement(this)) {
- return parentPath.createChild(getPublicDefinition().getStatementName());
- }
- final Object argument = getStatementArgument();
- if (argument instanceof QName) {
- final QName qname = (QName) argument;
- if (producesDeclared(UsesStatement.class)) {
- return maybeParentPath.orElse(null);
- }
-
- return parentPath.createChild(qname);
- }
- if (argument instanceof String) {
- // FIXME: This may yield illegal argument exceptions
- final Optional<StmtContext<A, D, E>> originalCtx = getOriginalCtx();
- final QName qname = StmtContextUtils.qnameFromArgument(originalCtx.orElse(this), (String) argument);
- return parentPath.createChild(qname);
- }
- if (argument instanceof SchemaNodeIdentifier
- && (producesDeclared(AugmentStatement.class) || producesDeclared(RefineStatement.class)
- || producesDeclared(DeviationStatement.class))) {
-
- return parentPath.createChild(((SchemaNodeIdentifier) argument).getNodeIdentifiers());
- }
-
- // FIXME: this does not look right
- return maybeParentPath.orElse(null);
- }
-
- @Override
- public final String toString() {
- return addToStringAttributes(MoreObjects.toStringHelper(this).omitNullValues()).toString();
- }
-
- protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
- return toStringHelper.add("definition", definition).add("rawArgument", rawStatementArgument());
- }