hguven / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
0 stars 0 forks source link

Enum value and type name clashes in .proto generated files #324

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?

1. Have a C# enum as follows:
public enum AddressType
{
    StreetAddress,
    ZipCode
}

2. Have a C# class named "StreetAddress" or "ZipCode"

3. Populate a runtime model with the StreetAddress/ZipCode class and anything 
that references the AddressType enum (e.g. as a field)

4. Generate a .proto out of the runtime model

What is the expected output? What do you see instead?

C# and .proto have different scoping rules: in proto, enum values are siblings 
of the enum, while in C# they are children of the enum. The result is that the 
above scenario, completely legal in C#, becomes illegal in the generated 
.proto, because there is a clash between the "StreetAddress" enum member and 
the "StreetAddress" message name.
This is an example of the generated .proto:

message Person {
    ...
    optional StreetAddress streetAddress = 2;
}

message StreetAddress {
    ...
}

enum AddressType {
    StreetAddress = 0;
    ZipCode = 1;
}

When running protoc on it, we get the following error:

foo.proto:66:4: "StreetAddress" is already defined.
foo.proto:66:4: Note that enum values use C++ scoping rules, meaning that enum 
values are siblings of their type, not children of it.  Therefore, 
"StreetAddress" must be unique within the global scope, not just within 
"AddressType".

IMHO, since protobuf-net is, by definition, "bridging the gap" between .NET and 
.proto, it should also disambiguate such scoping clashes that derive from the 
.NET->proto conversion, or at least provide the user with a way (e.g. flag, 
option) to turn on an automatic disambiguation (e.g. by prefixing the enum type 
name to the enum value name).

What version of the product are you using? On what operating system?
2.0.0.591, Windows XP

Original issue reported on code.google.com by Gabriele.Giuseppini on 24 Sep 2012 at 3:41

GoogleCodeExporter commented 8 years ago
This is also a problem if you have two enumerations with identical field names.

For instance:

public enum Foo
{
    Default,
    A,
    B,
}

public enum Bar
{
    Default,
    X,
    Y,
}

So it may be smart to represent these in a .proto as:

 namespace Foo {
    enum Enum {
      Default = 0;
      X = 1;
      Y = 2;
    }
  }

  namespace Bar {
    enum Enum {
      Default = 0;
      X = 1;
      Y = 2;
    }
  } 

Original comment by david.boike@gmail.com on 27 Sep 2012 at 4:41

GoogleCodeExporter commented 8 years ago
Hi Marc,

Do you have any update on this issue? I ran into the same problem, and was 
going to fix it with a parse and replace on all my .proto files, but this is 
difficult because of the way the default fields are defined in places where the 
enum is used. Here is an example:

message Source {
   optional SourceType type = 8 [default = TypeA];
...
}
enum SourceType {
   TypeA= 0;
   TypeB= 1;
   TypeC= 2;
   TypeD= 3;
}

If I want to rename the enum values in SourceType to avoid name clashes, I also 
have to search and replace for all default values in every message that 
references this enum. This is not a trivial task (I am replacing these names 
because they are being used all over the place in other messages / enums), is 
it worth spending time on my own solution for this, or do you already have a 
solution / plan to address this issue in the near future?

Thanks <3

Franchesca

Original comment by Franches...@gmail.com on 15 Oct 2012 at 8:27