Subject: [netmod] enumeration type

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 21 Jan 2014 09:36:32 +0100

Hi,

the definition of the enumeration type (sec. 9.6.4.2) contains another formulation that confuses me:

   If a value is not specified, then one will be automatically assigned.
   If the "enum" substatement is the first one defined, the assigned
   value is zero (0); otherwise, the assigned value is one greater than
   the current highest enum value.

So, for the example in 9.6.5

     leaf myenum {
         type enumeration {
             enum zero;
             enum one;
             enum seven {
                 value 7;
             }
         }
     }

the assignment should be

zero -> 0
one -> 8
seven -> 7

Is this correct?

Lada

--
Ladislav Lhotka, CZ.NIC Labs
PGP Key ID: E74E8C0C

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Tue, 21 Jan 2014 10:10:52 +0100

> So, for the example in 9.6.5

Current in the order of definition, that is:

  zero -> 0
  one -> 1
  seven -> 7

/js

-- 
Juergen Schoenwaelder           Jacobs University Bremen gGmbH
Phone: +49 421 200 3587         Campus Ring 1, 28759 Bremen, Germany
Fax:   +49 421 200 3103         <http://www.jacobs-university.de/>

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 21 Jan 2014 10:18:39 +0100

> Current in the order of definition, that is:

And what if that value is already taken by a subsequent enum entry? That is,

    leaf myenum {
        type enumeration {
            enum zero;
            enum one;
            enum seven {
                value 1;
            }
        }
    }

Lada

---

From: Jernej Tuljak <[email-masked]>
Date: Tue, 21 Jan 2014 10:23:50 +0100

> And what if that value is already taken by a subsequent enum entry? That is,

It counts as double assignment of a single value and is an error. That's 
what our implementation does anyways.

Jernej

> _______________________________________________
> netmod mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netmod

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Tue, 21 Jan 2014 10:29:48 +0100

> And what if that value is already taken by a subsequent enum entry? That is,

I assume this is the same as this and lead to the same result (namely
that the YANG definition is violating a MUST in section 9.6.4.2).

     leaf myenum {
         type enumeration {
             enum zero { value 0; };
             enum one { value 1; };
             enum seven {
                 value 1;
             }
         }
     }

Yes, one can question this automatic value assignment feature -
perhaps it would have been better to allow enumerations without
assigned numeric values. Perhaps something to consider should we ever
revise the YANG specification.

Martin, do you maintain a list of such issues?

/js

---

From: Martin Bjorklund <[email-masked]>
Date: Tue, 21 Jan 2014 10:38:29 +0100 (CET)

> Martin, do you maintain a list of such issues?

Yes.  I will add this issue, altough I don't think this is a problem.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 21 Jan 2014 10:44:55 +0100

On 21 Jan 2014, at 10:23, Jernej Tuljak <[email-masked]> wrote:

> It counts as double assignment of a single value and is an error. That's what our implementation does anyways.

Well, I can’t see how this follows from the text, given that the values needn’t be ordered and can be negative. This value thing really seems overengineered but underspecified - given that the only apparent purpose is to make module updates harder. I’d actually propose the following erratum:

OLD

NEW

  If a value is not specified, an implementation MAY assign any unique value.

And then the restriction in sec. 10

  o  An "enumeration" type may have new enums added, provided the old
     enums's values do not change.

should be applied only to explicit enum values. 

Lada

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Tue, 21 Jan 2014 10:54:09 +0100

> should be applied only to explicit enum values. 

This is not what was intended when RFC 6020 was written and as far as
I can tell this is not what tools implement. Errata are not the way to
change specifications.

/js

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 21 Jan 2014 11:01:22 +0100

> I can tell this is not what tools implement. Errata are not the way to

Then another erratum should clarify this. I think the interpretation I started with (one->8) is compatible with the text, or at least not without reason, because the current highest enum value clearly is 7.

Lada

---

From: Jernej Tuljak <[email-masked]>
Date: Tue, 21 Jan 2014 11:02:43 +0100

> I can tell this is not what tools implement. Errata are not the way to

I think that the text could use a clearer definition of what "current 
highest enum value" is, however.

Jernej

---

From: Andy Bierman <[email-masked]>
Date: Tue, 21 Jan 2014 06:46:24 -0800

Hi,

I do not understand all this fuss over a field used just
for documentation.  The value field is not used
in the protocol.  It is not referenced in any other
YANG statement.

I thought the auto-assignment procedure was clear
when I implemented it.

Andy

On Tue, Jan 21, 2014 at 2:02 AM, Jernej Tuljak <[email-masked]>wrote:

>>> Well, I can’t see how this follows from the text, given that the values
>>> needn’t be ordered and can be negative. This value thing really seems
>>> overengineered but underspecified - given that the only apparent purpose is
>>> to make module updates harder. I’d actually propose the following erratum:
>>>
>>> OLD
>>>

---

From: Jonathan Hansford <[email-masked]>
Date: Tue, 21 Jan 2014 15:23:29 +0000

On 2014-01-21 14:46, Andy Bierman wrote: 

> I do not
understand all this fuss over a field used just 
> I thought the auto-assignment procedure
was clear 

It would appear it isn't clear if
this thread is anything to go by, but if the field is never used (other
than for documentation) and therefore has no interoperability issues
between different implementations then I guess it is up to each
implementer to decide what they do with values. 

> On Tue,
Jan 21, 2014 at 2:02 AM, Jernej Tuljak <[email-masked] [3]>
wrote:
>>> On
Tue, Jan 21, 2014 at 10:44:55AM +0100, Ladislav Lhotka wrote:
Well, I can't see how this follows from the text, given that the values
needn't be ordered and can be negative. This value thing really seems
overengineered but underspecified - given that the only apparent purpose
is to make module updates harder. I'd actually propose the following
erratum:
>>>> If a value is not specified, an
implementation MAY assign any unique value.

>>> This is not
what was intended when RFC 6020 was written and as far as
>>> I can tell
this is not what tools implement. Errata are not the way to
>>> change
specifications.
>> 
>> I think that the text could use a clearer
definition of what "current highest enum value" is, however.
Jernej
>> netmod mailing
list
>> [email-masked] [1]
https://www.ietf.org/mailman/listinfo/netmod [2]

Links:
------
[1]
mailto:[email-masked]
[2]
https://www.ietf.org/mailman/listinfo/netmod
[3]
mailto:[email-masked]

---

From: Andy Bierman <[email-masked]>
Date: Tue, 21 Jan 2014 07:45:47 -0800

On Tue, Jan 21, 2014 at 7:23 AM, Jonathan Hansford
<[email-masked]>wrote:

>  It would appear it isn't clear if this thread is anything to go by, but
> if the field is never used (other than for documentation) and therefore has
> no interoperability issues between different implementations then I guess
> it is up to each implementer to decide what they do with values.
>

It needs to be clear so a module accepted by one YANG compiler does
not get rejected by another one.   I thought the rules were clear, then I
just tested our compiler and it does not complain about some errors. ;-)

AFAIK, rules are: (process enums in document order)
   1) if first enum has a value-stmt, start with that value, else start
with 0
   2) for each enum (2 - n):
       if enum has value-stmt, use that, otherwise use value( enum[N-1] ) +
1
       * generate an error if enum value is <= value( enum[N-1] )

Andy

  Andy

---

From: Andy Bierman <[email-masked]>
Date: Tue, 21 Jan 2014 08:18:49 -0800

On Tue, Jan 21, 2014 at 7:45 AM, Andy Bierman <[email-masked]> wrote:

>
>
>
> On Tue, Jan 21, 2014 at 7:23 AM, Jonathan Hansford <[email-masked]
> > wrote:
>
>        if enum has value-stmt, use that, otherwise use value( enum[N-1] )
> + 1
>

==> Use any unassigned value if current value( enum[N-1] ) == MAXINT

oops -- there is no requirement that the enum values be in ascending order.
The value just has to be unique with the enumeration type.

 ==>     * generate an error if enum value  == any previously assigned value

Andy

>>>>> Well, I can’t see how this follows from the text, given that the
>>>>> values needn’t be ordered and can be negative. This value thing really
>>>>> seems overengineered but underspecified - given that the only apparent
>>>>> purpose is to make module updates harder. I’d actually propose the
>>>>> following erratum:
>>>>>
>>>>> OLD
>>>>>

---

From: Andy Bierman <[email-masked]>
Date: Tue, 21 Jan 2014 08:42:54 -0800

Hi,

Jonathan, you are right -- the rules are not obvious.
Our code does not implement the rules I specified.
It uses the next highest value assigned:

  leaf enum-test {
    type enumeration {
       enum seven { value 7; }
       enum eight;  // value 8
       enum nine;  // value 9
       enum four { value 4; }
       enum ten;   // value 10, not 5
       enum eleven;   // value 11, not 6
    }
  }

Andy

---

From: Per Hedeland <[email-masked]>
Date: Tue, 21 Jan 2014 17:51:51 +0100

>        enum eleven;   // value 11, not 6

That's what RFC 6020 says - it's just your rule listing that is
wrong.:-) But yes, the meaning of "current highest [enum] value" could
use clarification.

--Per

---

From: Juergen Schoenwaelder <[email-masked]>
Date: Tue, 21 Jan 2014 18:56:08 +0100

>        enum eleven;   // value 11, not 6

In C, ten would be 5 and eleven would be 6. I believe we reduce the
number of surprises if we follow C semantics (and as far as I recall
that was the original idea as well). I think "current highest value"
really was meant to be "the last value (in the order of enum
definition)".

Note that we have similar text in section 9.7.4.2.

/js

---

From: Per Hedeland <[email-masked]>
Date: Wed, 22 Jan 2014 00:03:24 +0100

On 2014-01-21 18:56, Juergen Schoenwaelder wrote:
> In C, ten would be 5 and eleven would be 6.

And if you added twelve at the end, it would be 7 just like seven - C
doesn't care, but in YANG it would be an error, and you would either be
required to give a value statement for such cases too (and not just for
the MAXINT case explicitly spelled out in 6020), or the compiler would
have to find an unused value instead of just always using highest + 1
for auto-assignment (quite doable of course, but it's definitely not
what 6020 says).

> I believe we reduce the

I seriously doubt that, given the above - the other parts of the text
don't match. And so far I don't think we've heard of any implementation
doing that (pyang also does the assignment that Andy listed), so I think
it really would have to be considered a changed specification.

> Note that we have similar text in section 9.7.4.2.

Yes, it could also use clarification of "current highest".

--Per

---

From: Andy Bierman <[email-masked]>
Date: Tue, 21 Jan 2014 17:41:56 -0800

> Yes, it could also use clarification of "current highest".
I agree we should not change the behavior now.

The "max value" corner case is not really clear either.

   leaf max-enum-test {
      type enumeration {
         enum max { value 2147483647; }
         enum pick1;
         enum pick2;
         enum minus1 { value -1; }
       }
     }

The compiler is supposed to assign unused values for pick1 and pick2.
Is the compiler supposed to avoid assigning -1 or is the minus1 enum
an error (if -1 happened to be selected for pick1 or pick2).

Andy

---

From: Per Hedeland <[email-masked]>
Date: Wed, 22 Jan 2014 08:15:27 +0100

> The "max value" corner case is not really clear either.

If we use the common interpretation of "current highest value", I can't
see that it is unclear.

> The compiler is supposed to assign unused values for pick1 and pick2.

No, why do you think so? 6020 says:

   If the current highest value is equal to 2147483647, then an enum
   value MUST be specified for "enum" substatements following the one
   with the current highest value.

I.e. in this corner-case, you are required to *specify* values for pick1
and pick2 - the auto-assignment isn't expected to handle it. pyang just
folds this requirement into the <= MAXINT check:

enum.yang:8: error: the enumeration value "2147483648" is not an 32 bit integer
enum.yang:9: error: the enumeration value "2147483649" is not an 32 bit integer

- which is OK I guess.

> an error (if -1 happened to be selected for pick1 or pick2).

So this doesn't apply - but something similar will happen with

    type enumeration {
      enum zero; // value 0
      enum two { value 2; }
      enum one { value 1; }
      enum three; // value 3
      enum four { value 3; }
    }

pyang says:

enum.yang:11: error: the integer value "3" has already been used for the enumeration at enum.yang:10

Again, with the common interpretation of "current highest value", there
is nothing unclear - the compiler never needs to look-ahead for
specified values, auto-assignment always uses highest + 1 - and the
module writer needs to take that into account when mixing enums with and
without specified values (e.g. by reordering the enum statements in the
probably unlikely case that there is a clash and the specified value is
important - putting all those with specified values before those without
will always work, as long as the (even less likely-to-be-a-problem)
MAXINT rule is also observed).

--Per

---

From: Jernej Tuljak <[email-masked]>
Date: Wed, 22 Jan 2014 08:15:57 +0100

Dne 22.1.2014 2:41, pis(e Andy Bierman:
>
>
>
> On Tue, Jan 21, 2014 at 3:03 PM, Per Hedeland <[email-masked] 
> <mailto:[email-masked]>> wrote:
>

Your example violates this MUST before you even get to "minus1". After 
max is reached, all enums must have explicit value substatements. So 
it's an error, but not the one you were wondering about.

I'd also like to point out, that this auto assignment issue also applies 
to bit's position substatement.

Jernej

---

From: Jonathan Hansford <[email-masked]>
Date: Wed, 22 Jan 2014 09:41:56 +0000

On 2014-01-22 07:15, Per Hedeland wrote:

>> On Tue, Jan 21, 2014 at 3:03 PM, Per Hedeland <[email-masked] [1]>
>> wrote:
>>
>>>>> Hi, Jonathan, you are right -- the rules are not obvious. Our
>>>>> code does not implement the rules I specified. It uses the next
>>>>> highest value assigned: leaf enum-test { type enumeration { enum
>>>>> seven { value 7; } enum eight; // value 8 enum nine; // value 9
>>>>> enum four { value 4; } enum ten; // value 10, not 5 enum eleven;
>>>>> // value 11, not 6 } }
>>> And if you added twelve at the end, it would be 7 just like seven -
>>> C doesn't care, but in YANG it would be an error, and you would
>>> either be required to give a value statement for such cases too 
>>> (and
>>> not just for the MAXINT case explicitly spelled out in 6020), or 
>>> the
>>> compiler would have to find an unused value instead of just always
>>> using highest + 1 for auto-assignment (quite doable of course, but
>>> it's definitely not what 6020 says).
>>>
>>>> I believe we reduce the number of surprises if we follow C
>>>> semantics (and as far as I recall that was the original idea as
>>>> well). I think "current highest value" really was meant to be "the
>>>> last value (in the order of enum definition)".
>>> I seriously doubt that, given the above - the other parts of the
>>> text don't match. And so far I don't think we've heard of any
>>> implementation doing that (pyang also does the assignment that Andy
>>> listed), so I think it really would have to
>>>
>>>> d a changed specification. Note that w
>>> r text in section 9.7.4.2. Yes, it could also use clarification of
>>> "current highest".
>> I agree we should not change the behavior now. The "max value" 
>> corner
>> case is not really clear either.
>

I don't believe there is a common interpretation. For a parser the
interpretation would be the highest value currently encountered (i.e. 
the
highest value that has already been parsed). For someone who doesn't 
think
that way, all the values in the enumeration are current.

>
>> leaf max-enum-test { type enumeration { enum max { value 2147483647; 
>> }
>> enum pick1; enum pick2; enum minus1 { value -1; } } } The compiler 
>> is
>> supposed to assign unused values for pick1 and pick2.
>
> and pick2 - the auto-assignment isn't expect> it. pyang just folds 
> this
> requirement into the <= MAXINT check:
>> enum.yang:8: error: the enumeration value "2147483648" is no
> nteger enum.yang:9: error: the enumeration value "2147483649" is not 
> an
> 32 bit integer - which is OK I guess. Is the compiler supposed to 
> avoid
> assigning -1 or is the minus1 enum an error (if -1 happened to be
> selected for pick1 or pick2).
>
> enum.yang:11: error: the integer value "3" has already been used for 
> the
> enumeration at enum.yang:10
>

Links:
------
[1] mailto:[email-masked]

---

From: Per Hedeland <[email-masked]>
Date: Wed, 22 Jan 2014 11:03:34 +0100

On 2014-01-22 10:41, Jonathan Hansford wrote:
>>>> either be required to give a value statement for such cases too (and
>>>> not just for the MAXINT case explicitly spelled out in 6020), or the
>>> I agree we should not change the behavior now. The "max value" corner
> interpretation would be the highest value currently encountered (i.e. the
> highest value that has already been parsed). For someone who doesn't think

Yes, I (too) earlier agreed that it could use clarification, sorry for
being terse here. With "common interpretation", I really meant "the
apparently common interpretation across the YANG implementors that have
spoken up in this thread". The wording was just meant to indicate that
using this interpretation was a condition for considering the remainder
of the spec to be clear...

--Per