Status: New
Owner: liuj...@google.com
Labels: Type-Defect Priority-Medium

New issue 515 by peterhan...@yahoo.com: More intelligent enums
http://code.google.com/p/protobuf/issues/detail?id=515

(this is a RFE, not a defect)

Currently if you define:

  enum Foo {
        NONE=0;
        FOO1=1;
     }
  enum Bar {
        NONE=0;
        BAR1=1;
     }


it won't compile because the same enum value, NONE, is used in two different enums within the same proto file.

This is by design: Protobuf recognizes that the above construct will not work in C++ and therefore rejects it (no matter the output language). See Issue #12. The reason for the name collision is due to the somewhat odd implementation of enums in C++.

For other languages, like Java, there is no name conflict in the generated code so it is unfair to punish all other languages for the shortcomings of C++.

The existing restriction is extremely annoying as there aren't really any good alternatives. Each alternative has its own problems. (alternatives would be : use one proto file per enum, embed enums inside a message, etc)

Let's be constructive: The big question is how to improve on this without breaking the millions of lines of C++ code that depend on the existing behavior?

This group discussion has the solution: https://groups.google.com/forum/#!topic/protobuf/d-AqClgnDKM (alopecoid's suggestion is the one I like, it is clean, clear and doesn't break any existing code)

I'll just re-iterate alopecoid's suggestion here.
The basic suggestion is to add an option to enums:

  enum Foo {
        option use_namespace = true;
        NONE=0;
        FOO1=1;
     }
  enum Bar {
        option use_namespace = true;
        NONE=0;
        BAR1=1;
     }


This option would default to 'false', meaning the exact behavior of protobuf compiler today. However if the option is true the compiler will no longer fault on the above construct (for any output language). For C++ it will then generate C++ code like this:


  namespace Foo {
    enum Enum {
      NONE = 0;
      FOO1 = 1;
    }
  }

  namespace Bar {
    enum Enum {
      NONE = 0;
      BAR1 = 1;
    }
  }


and the enums would then be referenced in C++ code like Foo::NONE and Bar::NONE.

For other languages that also use unscoped enums (like C++) the generated code for such language will have to find their own solution to the problem. (are there any such languages at all?)

For languages that use scoped enums (most languages that I can think of, example: Java) the option would have no effect. It is the same code being generated in both cases.

I like the suggestion because it doesn't break any existing code.





--
You received this message because this project is configured to send all issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

--
You received this message because you are subscribed to the Google Groups "Protocol 
Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
Visit this group at http://groups.google.com/group/protobuf?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to