Skip to content
Snippets Groups Projects
Commit 6d0f8fa6 authored by Ladislav Lhotka's avatar Ladislav Lhotka
Browse files

Turn the graph of identities upside down.

parent f925ff1b
No related branches found
No related tags found
No related merge requests found
......@@ -128,6 +128,11 @@ def test_context(data_model):
with pytest.raises(BadPrefName):
Context.translate_pname("d:foo", stid)
assert Context.feature_expr("feA and not feB", tid) == True
assert not Context.is_derived_from(("all-uses", "test"), ("all-uses", "test"))
assert Context.is_derived_from(("all-uses", "test"), ("licence-property", "test"))
assert Context.is_derived_from(("CC-BY-SA", "testb"), ("share-alike", "test"))
assert not Context.is_derived_from(("CC-BY-SA", "testb"), ("derivatives", "test"))
assert Context.is_derived_from(("CC-BY-SA", "testb"), ("all-uses", "test"))
def test_schema(data_model):
ca = data_model.get_data_node("/test:contA")
......
......@@ -23,7 +23,7 @@ class Context:
cls.revisions = {} # type: Dict[YangIdentifier, List[str]]
cls.prefix_map = {} # type: Dict[ModuleId, Dict[YangIdentifier, ModuleId]]
cls.ns_map = {} # type: Dict[YangIdentifier, YangIdentifier]
cls.derived_identities = {} # type Dict[QualName, MutableSet[QualName]]
cls.identity_bases = {} # type: Dict[QualName, MutableSet[QualName]]
cls.features = set() # type: MutableSet[QualName]
# Regular expressions
......@@ -85,7 +85,6 @@ class Context:
cls.revisions[mod].sort(key=lambda r: "0" if r is None else r)
cls._process_imports()
cls._check_feature_dependences()
cls._identity_derivations()
for mn in cls.implement:
if len(cls.revisions[mn]) > 1:
raise MultipleImplementedRevisions(mn)
......@@ -153,19 +152,6 @@ class Context:
for aug in mod.find_all("augment"):
cls.schema._augment_refine(aug, mid, True)
@classmethod
def _identity_derivations(cls):
"""Create the graph of identity derivations."""
for mid in cls.modules:
for idst in cls.modules[mid].find_all("identity"):
if not cls.if_features(idst, mid): continue
idn = cls.translate_pname(idst.argument, mid)
if idn not in cls.derived_identities:
cls.derived_identities[idn] = set()
for bst in idst.find_all("base"):
bn = cls.translate_pname(bst.argument, mid)
cls.derived_identities.setdefault(bn, set()).add(idn)
@classmethod
def prefix2ns(cls, prefix: YangIdentifier, mid: ModuleId) -> YangIdentifier:
"""Return the namespace corresponding to the prefix."""
......@@ -242,6 +228,18 @@ class Context:
cls.modules[did].find1(kw, loc, required=True))
return (dstmt, did)
@classmethod
def is_derived_from(cls, identity: QualName, base: QualName) -> bool:
"""Return ``True`` if `identity` is derived from `base`."""
try:
bases = cls.identity_bases[identity]
except KeyError:
return False
if base in bases: return True
for ib in bases:
if cls.is_derived_from(ib, base): return True
return False
# Feature handling
@classmethod
......
......@@ -463,6 +463,11 @@ class IdentityrefType(DataType):
i1, s, i2 = raw.partition(":")
return (i2, i1) if s else (i1, self.module_id[0])
def _constraints(self, val: QualName) -> bool:
for b in self.bases:
if not Context.is_derived_from(val, b): return False
return True
def handle_properties(self, stmt: Statement, mid: ModuleId) -> None:
"""Handle type substatements.
......
......@@ -118,6 +118,7 @@ class SchemaNode:
"config": "_config_stmt",
"container": "_container_stmt",
"default": "_default_stmt",
"identity": "_identity_stmt",
"ietf-netconf-acm:default-deny-all": "_nacm_default_deny_stmt",
"ietf-netconf-acm:default-deny-write": "_nacm_default_deny_stmt",
"input": "_input_stmt",
......@@ -254,6 +255,13 @@ class InternalNode(SchemaNode):
if Context.if_features(stmt, mid):
self._handle_child(ContainerNode(), stmt, mid)
def _identity_stmt(self, stmt: Statement, mid: ModuleId) -> None:
"""Handle identity statement."""
if Context.if_features(stmt, mid):
bases = stmt.find_all("base")
Context.identity_bases[(stmt.argument, mid[0])] = set(
[Context.translate_pname(ist.argument, mid) for ist in bases])
def _list_stmt(self, stmt: Statement, mid: ModuleId) -> None:
"""Handle list statement."""
if Context.if_features(stmt, mid):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment