--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.api;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
+import org.opendaylight.yangtools.yang.common.XMLNamespace;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+
+/**
+ * A single <a href="https://www.rfc-editor.org/rfc/rfc8525">RFC8525</a> {@code module} or {@code import-only-module}
+ * list entry. Note that the YANG definition has two dissimilar instances, but that really is an artifact of how indexes
+ * work in YANG.
+ *
+ * @param identifier {@link SourceIdentifier} of this module, e.g. the combination of {@code name} and {@code revision}
+ * @param namespace {@link XMLNamespace} of this module
+ * @param submodules Submodules of this module
+ * @param features The set of supported features in this module
+ * @param deviationModuleNames Names of modules containing {@code deviate} statements targetting this module
+ * @param source A {@link SchemaSourceRepresentation} of the module
+ */
+public record YangLibModule(@NonNull SourceIdentifier identifier, @NonNull XMLNamespace namespace,
+ @NonNull ImmutableMap<Unqualified, YangLibSubmodule> submodules, @NonNull ImmutableSet<Unqualified> features,
+ @NonNull ImmutableSet<Unqualified> deviationModuleNames, @NonNull SchemaSourceRepresentation source) {
+ public YangLibModule {
+ requireNonNull(identifier);
+ requireNonNull(namespace);
+ requireNonNull(submodules);
+ requireNonNull(features);
+ requireNonNull(deviationModuleNames);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.api;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableMap;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+
+/**
+ * A single <a href="https://www.rfc-editor.org/rfc/rfc8525">RFC8525</a> {@code module-set}.
+ */
+public record YangLibModuleSet(@NonNull String name,
+ @NonNull ImmutableMap<Unqualified, YangLibModule> modules,
+ @NonNull ImmutableMap<SourceIdentifier, YangLibModule> importOnlyModules) {
+ public YangLibModuleSet {
+ requireNonNull(name);
+ requireNonNull(modules);
+ requireNonNull(importOnlyModules);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.api;
+
+import com.google.common.annotations.Beta;
+import java.io.IOException;
+import java.util.Collection;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+
+/**
+ * A service capable of transforming a {@link YangLibModuleSet} to an {@link EffectiveModelContext}.
+ */
+@Beta
+public interface YangLibResolver {
+ /**
+ * Return enumeration of concrete types of {@link SchemaSourceRepresentation} this resolver supports. Users can use
+ * this information prepare the source they have to a representation which will be accepted by this resolver.
+ *
+ * @return Enumeration of supported schema source representations.
+ */
+ @NonNull Collection<Class<? extends SchemaSourceRepresentation>> supportedSourceRepresentations();
+
+ /**
+ * Build the effective view of a combined view of effective statements.
+ *
+ * @return Effective module statements indexed by their QNameModule.
+ * @throws IOException if a module source cannot be read
+ * @throws YangSyntaxErrorException when a syntactic error is encountered
+ * @throws NullPointerException if {@code moduleSet} is {@code null}
+ * @throws IllegalArgumentException if {@code moduleSet} references an unsupported
+ * {@link SchemaSourceRepresentation}
+ */
+ @NonNull EffectiveModelContext resolveModuleSet(YangLibModuleSet moduleSet) throws IOException, YangParserException;
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.api;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+
+/**
+ * A single <a href="https://www.rfc-editor.org/rfc/rfc8525">RFC8525</a> {@code submodule} list entry.
+ *
+ * @param identifier {@link SourceIdentifier} of this submodule, e.g. the combination of {@code name} and
+ * {@code revision}
+ * @param source A {@link SchemaSourceRepresentation} of the submodule
+ */
+public record YangLibSubmodule(@NonNull SourceIdentifier identifier, @NonNull SchemaSourceRepresentation source) {
+ public YangLibSubmodule {
+ requireNonNull(identifier);
+ requireNonNull(source);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.impl;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.util.Collection;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.kohsuke.MetaInfServices;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.parser.api.YangLibModuleSet;
+import org.opendaylight.yangtools.yang.parser.api.YangLibResolver;
+import org.opendaylight.yangtools.yang.parser.api.YangParserException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * Reference {@link YangLibResolver} implementation.
+ */
+@Beta
+@Singleton
+@MetaInfServices
+@Component(immediate = true)
+public final class DefaultYangLibResolver implements YangLibResolver {
+ private final CrossSourceStatementReactor reactor;
+
+ public DefaultYangLibResolver() {
+ reactor = DefaultReactors.defaultReactorBuilder().build();
+ }
+
+ @Inject
+ @Activate
+ public DefaultYangLibResolver(final @Reference YangXPathParserFactory xpathFactory) {
+ reactor = DefaultReactors.defaultReactorBuilder(xpathFactory).build();
+ }
+
+ @Override
+ public Collection<Class<? extends SchemaSourceRepresentation>> supportedSourceRepresentations() {
+ return DefaultYangParser.REPRESENTATIONS;
+ }
+
+ @Override
+ public EffectiveModelContext resolveModuleSet(final YangLibModuleSet moduleSet)
+ throws IOException, YangParserException {
+ final var act = reactor.newBuild();
+ final var features = ImmutableSet.<QName>builder();
+
+ for (var module : moduleSet.modules().values()) {
+ final var namespace = QNameModule.create(module.namespace(), module.identifier().revision());
+ for (var feat : module.features()) {
+ features.add(feat.bindTo(namespace));
+ }
+
+ act.addSource(DefaultYangParser.sourceToStatementStream(module.source()));
+ }
+
+ for (var module : moduleSet.importOnlyModules().values()) {
+ act.addLibSource(DefaultYangParser.sourceToStatementStream(module.source()));
+ }
+
+ try {
+ return act.setSupportedFeatures(features.build()).buildEffective();
+ } catch (ReactorException e) {
+ throw DefaultYangParser.decodeReactorException(e);
+ }
+ }
+}
import org.xml.sax.SAXException;
final class DefaultYangParser implements YangParser {
- private static final @NonNull Collection<Class<? extends SchemaSourceRepresentation>> REPRESENTATIONS =
+ static final @NonNull Collection<Class<? extends SchemaSourceRepresentation>> REPRESENTATIONS =
ImmutableList.of(IRSchemaSource.class, YangTextSchemaSource.class, YinDomSchemaSource.class,
YinXmlSchemaSource.class, YinTextSchemaSource.class);
}
}
- private static YangParserException decodeReactorException(final ReactorException reported) {
+ static YangParserException decodeReactorException(final ReactorException reported) {
// FIXME: map exception in some reasonable manner
return new YangParserException("Failed to assemble sources", reported);
}
- private static StatementStreamSource sourceToStatementStream(final SchemaSourceRepresentation source)
+ static StatementStreamSource sourceToStatementStream(final SchemaSourceRepresentation source)
throws IOException, YangSyntaxErrorException {
requireNonNull(source);
if (source instanceof IRSchemaSource) {