- private final YangVersion yangVersion;
- private final String organization;
- private final String contact;
- private final Set<ModuleImport> imports;
- private final Set<FeatureDefinition> features;
- private final Set<NotificationDefinition> notifications;
- private final Set<AugmentationSchemaNode> augmentations;
- private final Set<RpcDefinition> rpcs;
- private final Set<Deviation> deviations;
- private final List<ExtensionDefinition> extensionNodes;
- private final Set<IdentitySchemaNode> identities;
- private final @NonNull List<UnknownSchemaNode> unknownNodes;
- private final Map<QName, DataSchemaNode> childNodes;
- private final Set<GroupingDefinition> groupings;
- private final Set<UsesNode> uses;
- private final Set<TypeDefinition<?>> typeDefinitions;
- private final Set<DataSchemaNode> publicChildNodes;
- private final SemVer semanticVersion;
-
- private Set<StmtContext<?, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>>>
- submoduleContextsToBuild;
- private Set<Module> submodules;
- private boolean sealed;
-
- protected AbstractEffectiveModule(final StmtContext<String, D, ? extends EffectiveStatement<String, ?>> ctx) {
- super(ctx);
-
- this.name = argument();
-
- final EffectiveStatement<?, ?> parentOfPrefix;
- if (ctx.getPublicDefinition() == YangStmtMapping.SUBMODULE) {
- final Optional<BelongsToEffectiveStatement> optParent =
- findFirstEffectiveSubstatement(BelongsToEffectiveStatement.class);
- SourceException.throwIf(!optParent.isPresent(), ctx.getStatementSourceReference(),
- "Unable to find belongs-to statement in submodule %s.", ctx.getStatementArgument());
- parentOfPrefix = optParent.get();
- } else {
- parentOfPrefix = this;
- }
-
- final Optional<@NonNull PrefixEffectiveStatement> prefixStmt = parentOfPrefix.findFirstEffectiveSubstatement(
- PrefixEffectiveStatement.class);
- SourceException.throwIf(!prefixStmt.isPresent(), ctx.getStatementSourceReference(),
- "Unable to resolve prefix for module or submodule %s.", ctx.getStatementArgument());
- this.prefix = prefixStmt.get().argument();
- this.yangVersion = findFirstEffectiveSubstatementArgument(YangVersionEffectiveStatement.class)
- .orElse(YangVersion.VERSION_1);
- this.semanticVersion = findFirstEffectiveSubstatementArgument(OpenConfigVersionEffectiveStatement.class)
- .orElse(null);
- this.organization = findFirstEffectiveSubstatementArgument(OrganizationEffectiveStatement.class)
- .orElse(null);
- this.contact = findFirstEffectiveSubstatementArgument(ContactEffectiveStatement.class)
- .orElse(null);
-
- // init submodules and substatements of submodules
- final List<EffectiveStatement<?, ?>> substatementsOfSubmodules;
- final Map<String, StmtContext<?, ?, ?>> includedSubmodulesMap = ctx
- .getAllFromCurrentStmtCtxNamespace(IncludedSubmoduleNameToModuleCtx.class);
-
- if (includedSubmodulesMap == null || includedSubmodulesMap.isEmpty()) {
- this.submodules = ImmutableSet.of();
- this.submoduleContextsToBuild = ImmutableSet.of();
- substatementsOfSubmodules = ImmutableList.of();
- } else if (YangStmtMapping.MODULE.equals(ctx.getPublicDefinition())) {
- /*
- * Aggregation of substatements from submodules should be done only
- * for modules. In case of submodules it does not make sense because
- * of possible circular chains of includes between submodules.
- */
- final Set<Module> submodulesInit = new HashSet<>();
- final List<EffectiveStatement<?, ?>> substatementsOfSubmodulesInit = new ArrayList<>();
- for (final StmtContext<?, ?, ?> submoduleCtx : includedSubmodulesMap.values()) {
- final EffectiveStatement<?, ?> submodule = submoduleCtx.buildEffective();
- Verify.verify(submodule instanceof SubmoduleEffectiveStatement);
- Verify.verify(submodule instanceof Module, "Submodule statement %s is not a Module", submodule);
- submodulesInit.add((Module) submodule);
- substatementsOfSubmodulesInit.addAll(submodule.effectiveSubstatements().stream()
- .filter(sub -> sub instanceof SchemaNode || sub instanceof DataNodeContainer)
- .collect(Collectors.toList()));
- }
-
- this.submodules = ImmutableSet.copyOf(submodulesInit);
- this.submoduleContextsToBuild = ImmutableSet.of();
- substatementsOfSubmodules = ImmutableList.copyOf(substatementsOfSubmodulesInit);
- } else {
- /*
- * Because of possible circular chains of includes between submodules we can
- * collect only submodule contexts here and then build them during
- * sealing of this statement.
- */
- final Set<StmtContext<?, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>>>
- submoduleContextsInit = new HashSet<>();
- for (final StmtContext<?, ?, ?> submoduleCtx : includedSubmodulesMap.values()) {
- submoduleContextsInit.add(
- (StmtContext<?, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>>)submoduleCtx);
- }
-
- this.submoduleContextsToBuild = ImmutableSet.copyOf(submoduleContextsInit);
- substatementsOfSubmodules = ImmutableList.of();
- }
-
- if (!submoduleContextsToBuild.isEmpty()) {
- ((Mutable<?, ?, ?>) ctx).addMutableStmtToSeal(this);
- sealed = false;
- } else {
- sealed = true;
- }
-
- // init substatements collections
- final List<EffectiveStatement<?, ?>> effectiveSubstatements = new ArrayList<>();
- effectiveSubstatements.addAll(effectiveSubstatements());
- effectiveSubstatements.addAll(substatementsOfSubmodules);
-
- final List<UnknownSchemaNode> unknownNodesInit = new ArrayList<>();
- final Set<AugmentationSchemaNode> augmentationsInit = new LinkedHashSet<>();
- final Set<ModuleImport> importsInit = new HashSet<>();
- final Set<NotificationDefinition> notificationsInit = new HashSet<>();
- final Set<RpcDefinition> rpcsInit = new HashSet<>();
- final Set<Deviation> deviationsInit = new HashSet<>();
- final Set<IdentitySchemaNode> identitiesInit = new HashSet<>();
- final Set<FeatureDefinition> featuresInit = new HashSet<>();
- final List<ExtensionDefinition> extensionNodesInit = new ArrayList<>();
-
- final Map<QName, DataSchemaNode> mutableChildNodes = new LinkedHashMap<>();
- final Set<GroupingDefinition> mutableGroupings = new HashSet<>();
- final Set<UsesNode> mutableUses = new HashSet<>();
+ private final ImmutableSet<GroupingDefinition> groupings;
+ private final ImmutableSet<UsesNode> uses;
+ private final ImmutableSet<TypeDefinition<?>> typeDefinitions;
+ private final ImmutableMap<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace;
+
+ protected AbstractEffectiveModule(final D declared,
+ final StmtContext<UnqualifiedQName, D, ? extends EffectiveStatement<UnqualifiedQName, ?>> ctx,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements, final String prefix) {
+ super(declared, ctx, substatements);
+
+ // This check is rather weird, but comes from our desire to lower memory footprint while providing both
+ // EffectiveStatements and SchemaNode interfaces -- which do not overlap completely where child lookups are
+ // concerned. This ensures that we have SchemaTree index available for use with child lookups.
+ final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTree =
+ createSchemaTreeNamespace(ctx.getStatementSourceReference(), effectiveSubstatements());
+ schemaTreeNamespace = ImmutableMap.copyOf(schemaTree);
+
+ // Data tree check, not currently used
+ createDataTreeNamespace(ctx.getStatementSourceReference(), schemaTree.values(), schemaTreeNamespace);
+
+ this.prefix = requireNonNull(prefix);
+
+ final Set<GroupingDefinition> mutableGroupings = new LinkedHashSet<>();
+ final Set<UsesNode> mutableUses = new LinkedHashSet<>();