[protobuf] Issue 515 in protobuf: More intelligent enums

2013-05-27 Thread protobuf

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.




Re: [protobuf] Issue 515 in protobuf: More intelligent enums

2013-05-27 Thread Michael Haberler

Am 27.05.2013 um 22:07 schrieb proto...@googlecode.com:

 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.

I like it too, also because it resolves an issue I have with wrapping existing 
objects - assume you have some C typedefs

typedef enum { FOO=0, BAR=1 } obj1_t;
typedef enum { BAZ=2, XXX=3 } obj2_t;

then I cant have a proto enum like so:

enum ObjTypes {
   FOO = 0;
   BAR = 1;
   BAZ = 2;
   XXX = 3;
}

without renaming the enums in the proto enum; the namespace proposal would 
solve that issue with no apparent downside

- Michael


 
 
 
 
 
 -- 
 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.
 

-- 
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.