Introduce yangtools.binding.meta
[yangtools.git] / common / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / YangNamespaceContext.java
index 9986eb8e786409421f676b109af7ea86beb46f1a..9e131a863e396d799cc649c447f48cc205a9e346 100644 (file)
@@ -7,50 +7,73 @@
  */
 package org.opendaylight.yangtools.yang.common;
 
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.Beta;
 import java.io.Serializable;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.concepts.Immutable;
 
 /**
  * Interface for mapping between {@link String} prefixes and {@link QNameModule} namespaces. The conceptual model
  * matches prefix mapping inside a YANG {@code module} as defined through the use of {@code prefix} and {@code import}
- * statements and detailed in <a href="https://tools.ietf.org/html/rfc7950#section-7.1.4">RFC7950 Section 7.1.4</a>.
+ * statements and detailed in <a href="https://www.rfc-editor.org/rfc/rfc7950#section-7.1.4">RFC7950 Section 7.1.4</a>.
  *
  * <p>
  * Each namespace context has a set of prefix/namespace mappings. A namespace can be bound to multiple prefixes at the
  * same time.
- *
- * @author Robert Varga
  */
-@Beta
 public interface YangNamespaceContext extends Immutable, Serializable {
     /**
      * Return QNameModule to which a particular prefix is bound.
      *
      * @param prefix Prefix to look up
+     * @return QNameModule bound to specified prefix, or {@code null}
+     * @throws NullPointerException if {@code prefix} is {@code null}
+     */
+    @Nullable QNameModule namespaceForPrefix(String prefix);
+
+    /**
+     * Return QNameModule to which a particular prefix is bound.
+     *
+     * @implSpec Default implementation defers to {@link #namespaceForPrefix(String)}
+     * @param prefix Prefix to look up
      * @return QNameModule bound to specified prefix
-     * @throws NullPointerException if {@code prefix} is null
+     * @throws NullPointerException if {@code prefix} is {@code null}
      */
-    @NonNull Optional<QNameModule> findNamespaceForPrefix(String prefix);
+    default @NonNull Optional<QNameModule> findNamespaceForPrefix(final String prefix) {
+        return Optional.ofNullable(namespaceForPrefix(prefix));
+    }
 
     /**
      * Return a prefix to which a particular QNameModule is bound. If a namespace is bound to multiple prefixes, it is
      * left unspecified which of those prefixes is returned.
      *
      * @param namespace QNameModule to look up
+     * @return Prefix to which the QNameModule is bound, or {@code null}
+     * @throws NullPointerException if {@code module} is {@code null}
+     */
+    @Nullable String prefixForNamespace(QNameModule namespace);
+
+    /**
+     * Return a prefix to which a particular QNameModule is bound. If a namespace is bound to multiple prefixes, it is
+     * left unspecified which of those prefixes is returned.
+     *
+     * @implSpec Default implementation defers to {@link #prefixForNamespace(QNameModule)}
+     * @param namespace QNameModule to look up
      * @return Prefix to which the QNameModule is bound
-     * @throws NullPointerException if {@code module} is null
+     * @throws NullPointerException if {@code module} is {@code null}
      */
-    @NonNull Optional<String> findPrefixForNamespace(QNameModule namespace);
+    default @NonNull Optional<String> findPrefixForNamespace(final QNameModule namespace) {
+        return Optional.ofNullable(prefixForNamespace(namespace));
+    }
 
     /**
      * Create a {@link QName} by resolving a prefix against currently-bound prefixes and combining it with specified
      * local name.
      *
+     * @implSpec
+     *     Default implementation defers to {@link #namespaceForPrefix(String)} and constructs QName based on its
+     *     return.
      * @param prefix Namespace prefix
      * @param localName QName local name
      * @return A QName.
@@ -59,8 +82,10 @@ public interface YangNamespaceContext extends Immutable, Serializable {
      *                                  prefix is not bound in this context.
      */
     default @NonNull QName createQName(final String prefix, final String localName) {
-        final Optional<QNameModule> namespace = findNamespaceForPrefix(prefix);
-        checkArgument(namespace.isPresent(), "Prefix %s is not bound", prefix);
-        return QName.create(namespace.get(), localName);
+        final var namespace = namespaceForPrefix(prefix);
+        if (namespace == null) {
+            throw new IllegalArgumentException("Prefix " + prefix + " is not bound");
+        }
+        return QName.create(namespace, localName);
     }
 }