Subject: [netmod] prefixes in groupings

From: Andy Bierman <[email-masked]>
Date: Mon, 29 Jun 2009 08:21:35 -0700

Hi,

   module x {
     prefix x;
     ...

     import my-identities {
        prefix y;
        revision-date 2009-05-04;
     }

     identity B  { base y:A; }

     grouping bar {
       container a { ... }
     }

     grouping foo {
       uses bar {
          augment "x:a" {  // legal reference to a?? (yes!)
            leaf z { ... }
          }
       }
       leaf xxx {
          type identityref { base y:A; }
          default x:B;
       }
     }
  }

Is it clear from leaf xxx that this issue has nothing
to do with XPath?  The prefixes declared in module x
are the ones available for use everywhere in module x.
Anything less would be too confusing.

I strongly oppose any special handling of
XPath expressions within groupings.  YANG's version
of XPath is special enough already.  It's more work to
enforce the proposed CLR, than it is to just do the right thing.
You have to resolve prefixes everywhere within the grouping.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 29 Jun 2009 18:08:45 +0200

> You have to resolve prefixes everywhere within the grouping.

So what's the right thing if you have an expression inside a grouping
like this:

must "a < x:b and x:b < ../y:c";

where "x" is the prefix of the module in which the grouping appears?
When and how are the QNames resolved? Does the result depend on the
module where the grouping is used - whether it is "x", "y" or yet
another module?

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Mon, 29 Jun 2009 09:35:51 -0700

> module where the grouping is used - whether it is "x", "y" or yet

All prefixes need to be resolved in the module where they are appear.
Any string with prefixes in it has to be resolved this way.
Prefixes cannot be resolved in the 'uses' module.

  uses x:foo;

This is an internal expansion.
It is not a text replacement like #define in C.

Note that a deviation-stmt like this may not work if
it is in a different module than your grouping:

  deviation blah/a {
     deviate delete {

Unless the imports/prefixes match in both modules,
this deviation statement is going to do the wrong thing.

This goes for applying defaults, resolving types, whatever.

Nobody said it was a goal to make YANG easy to use
for tool developers.  For YANG writers, if you stick
to what you know, you're OK.  In other words, the localized
cost is good.  It's easy to do most things right, and not
so easy for the rest.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 30 Jun 2009 09:45:37 +0200

> Prefixes cannot be resolved in the 'uses' module.

YANG rules state that unprefixed names belong to the namespace of the
local module, so "a" above would be equivalent to "x:a". But we want
this to work in the module where the grouping is used:

grouping lease-times {
    container lease-times {
        must "lease-time <= max-lease-time";
	leaf lease-time { ... }
        leaf max-lease-time { ... }
    }
}

I think it would be quite consistent (no CLR at all) to say that
unprefixed names in groupings have null NS URI and these and only these
names adopt the namespace of the module where the grouping is used.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Tue, 30 Jun 2009 05:34:01 -0700

> names adopt the namespace of the module where the grouping is used.

I disagree.
All the prefixes need to be resolved at the same time,
using the same set of prefix to namespace mappings.
Just because the XPath expression is in a grouping
is not a special condition.

   must "../foo = 7 or ../x:foo = 9";

Are foo and x:foo the same node?
Only the data model writer of this module,
where this expression appears, knows that for sure.
The expression cannot mean x:foo in one module
and something else in another module.  That's
why all the namespaces are resolved in the [sub]module where
they appear.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 30 Jun 2009 16:44:09 +0200

>    must "../foo = 7 or ../x:foo = 9";

I the schema tree (outside any grouping) "../foo" and "../x:foo" indeed
are the same node if "x" is the NS prefix of the local module.

I don't know, maybe we mean the same thing, you probably also want the
unprefixed names in XPath expressions within groupings to get the
namespace of the module where the grouping is used, right?

In, other words:

module xxx {
    prefix x;
    namespace "http://example.com/xxx";
    import yyy { prefix y; }
    grouping ggg {
        x:foo ---> ns="http://example.com/xxx", localname="foo" (fixed)
        y:bar ---> ns="http://example.com/yyy", localname="bar" (fixed)
        baz   ---> ns=<null>, localname="baz" (gets NS of the module 
                                               where ggg is used).
    }
}

Or do you want to resolve "baz" right away to
ns="http://example.com/xxx", localname="baz" and never change it?

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Tue, 30 Jun 2009 08:54:15 -0700

> ns="http://example.com/xxx", localname="baz" and never change it?

I don't understand this grouping 'ggg'.
It is not legal YANG.  You cannot declare
the 'y:bar' object.  Module xxx can
only declare its own objects in a grouping.
The objects themselves will end up with the namespace
of the final 'uses stmt'.

This is not the same as prefixes used in sub-statements
within these objects, like type-stmt, unique-stmt, default-stmt, etc.

The leaf-stmt syntax does not allow the identifier to have
a prefix, even if it is the local module prefix.

   leaf foo {  }

   leaf x:foo { }   // not allowed

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 30 Jun 2009 19:01:19 +0200

> It is not legal YANG.  You cannot declare

Yes, this was just a schematic shortcut. These symbols were supposed to
be in XPath expressions, for example 'must'.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 30 Jun 2009 19:42:56 +0200 (CEST)

> be in XPath expressions, for example 'must'.

I'm not sure I agree.  Let's try a simpler example, w/o XPath:

  module x {
    prefix p;
    ...
    
    grouping foo {
      typedef {
        type int32;
      }
      leaf a {
        type p:t1;
      }
    }
  }

  module y {
    prefix p;
    ...
    import x {
      prefix x;
    }
    typedef t1 {
      type string;
    }

    uses foo;
  }

Now, in module 'y', there will be a leaf 'a'.  The type of 'a' is 't1'
as defined in the grouping 'foo' in module 'x', i.e. an int32.   It is
NOT a string.  So, symbols are "lexically scoped", i.e. the symbol is
identified from its lexical scope.

We want the same handling for node identifiers in 'augment', 'must'
etc, i.e. also in XPath.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 30 Jun 2009 20:22:27 +0200

> identified from its lexical scope.

'uses foo;' means that 'leaf a', which is defined in a grouping in
module 'x' becomes part of the data tree in module 'y' and assumes the
namespace of 'y'. If 'grouping foo' in addition contained the same
symbol 'a' in an XPath expression, e.g. in 'must', it is IMO necessary
that when the XPath expression is evaluated, 'a' in it still corresponds
to the same 'leaf a'. This means that it must be the same QName, i.e.,
have the namespace of module y. Otherwise the 'must condition' in my
earlier example cound never work properly.

grouping lease-times {
    container lease-times {

I agree that all symbols with explicit namespace prefixes should keep
the namespace corresponding to that prefix in the module where the
grouping is defined.

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Tue, 30 Jun 2009 11:46:29 -0700

> We want the same handling for node identifiers in 'augment', 'must'

That's what we already implemented, right?

It is obvious by inspection that all prefixes in the grouping
are relative to the current [sub]module, and uses/grouping
is in no way, shape, or form, anything like #define in C?

Imagine if there were locally scoped identityref typedefs,
locally scoped groupings with this entire scenario
repeated recursively, all inside the context of module y.

YANG requires that the correct namespace-to-prefix associations
are done in the correct context, all the time. What text in the
draft even suggests anything different?

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 30 Jun 2009 20:51:48 +0200 (CEST)

> That's what we already implemented, right?

Exactly.

Lada, do you have any concerns at this point?

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 30 Jun 2009 22:02:20 +0200

> Lada, do you have any concerns at this point?

Still the same concern: what happens to unprefixed names in XPath
expressions that appear inside groupings, specifically, which namespace
URI they have if they are evaluated in a different module - not the one
where the grouping is defined.

Lada
 
-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 30 Jun 2009 22:13:13 +0200 (CEST)

> where the grouping is defined.

If a must/when expression in a grouping refers to a node in the
grouping - with or without prefix - at conceptual evaluation time they
will always refer to the node within the grouping, i.e. with the
namespace of the module where the grouping is used.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Wed, 01 Jul 2009 08:03:19 +0200

> namespace of the module where the grouping is used.

Example:

module xxx {
    prefix x;
            type uint8;
        }
    }
}

module yyy {
    prefix y;
    namespace "http://example.com/yyy";
    import xxx { prefix x; }
    grouping bar {
        container c {
            must "x:a < y:b";
            uses x:foo;
            leaf b {
                type uint8;
            }
        }
    }
}

module zzz {
    prefix z;
    namespace "http://example.com/zzz";
    import yyy { prefix y; }
    uses bar;
}

So, if I interpret your statement correctly, the following instance is
valid according to module zzz:

<c xmlns="http://example.com/zzz">
  <a>1</a>
  <b>2</b>
</c>

I think such juggling with namespaces is hardly acceptable. Also, it
contradicts what Andy said earlier:
"All prefixes need to be resolved in the module where they are appear."

Lada

-- 
Ladislav Lhotka, CESNET
PGP Key ID: E74E8C0C