Commit d2658e25 authored by Robert Edmonds's avatar Robert Edmonds

protoc-c: preserve case in C enum value names (Issue #129)

there is some confusion with regard to the use of lower case letters in
enum values. take the following message definition:

    message LowerCase {
      enum CaseEnum {
        UPPER = 1;
        lower = 2;
      }
      optional CaseEnum value = 1 [default = lower];
    }

this generates the following C enum:

    typedef enum _LowerCase__CaseEnum {
      LOWER_CASE__CASE_ENUM__UPPER = 1,
      LOWER_CASE__CASE_ENUM__lower = 2
        _PROTOBUF_C_FORCE_ENUM_TO_BE_INT_SIZE(LOWER_CASE__CASE_ENUM)
    } LowerCase__CaseEnum;

note that the case of the enum value 'lower' was preserved in the C
symbol name as 'LOWER_CASE__CASE_ENUM__lower', but that the _INIT macro
references the same enum value with the (non-existent) C symbol name
'LOWER_CASE__CASE_ENUM__LOWER':

    #define LOWER_CASE__INIT \
     { PROTOBUF_C_MESSAGE_INIT (&lower_case__descriptor) \
        , 0,LOWER_CASE__CASE_ENUM__LOWER }

additionally, the ProtobufCEnumValue array generated also refers to the
same enum value with the (non-existent) upper cased version:

    const ProtobufCEnumValue lower_case__case_enum__enum_values_by_number[2] =
    {
      { "UPPER", "LOWER_CASE__CASE_ENUM__UPPER", 1 },
      { "lower", "LOWER_CASE__CASE_ENUM__LOWER", 2 },
    };

we should preserve the existing behavior of copying the case from the
enum values in the message definition and fix up the places where the
(non-existent) upper case version is used, rather than changing the enum
definition itself to match the case used in the _INIT macro and
enum_values_by_number array, because it's possible that there might be
existing working code that uses enum values with lower case letters that
would be affected by such a change.

incidentally, google's C++ protobuf implementation preserves case in
enum values. protoc --cpp_out generates the following enum declaration
for the message descriptor above:

    enum LowerCase_CaseEnum {
      LowerCase_CaseEnum_UPPER = 1,
      LowerCase_CaseEnum_lower = 2
    };
parent 1f15ba9c
......@@ -142,7 +142,7 @@ void EnumGenerator::GenerateValueInitializer(io::Printer *printer, int index)
const EnumValueDescriptor *vd = descriptor_->value(index);
map<string, string> vars;
vars["enum_value_name"] = vd->name();
vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name()) + "__" + ToUpper(vd->name());
vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name()) + "__" + vd->name();
vars["value"] = SimpleItoa(vd->number());
printer->Print(vars,
" { \"$enum_value_name$\", \"$c_enum_value_name$\", $value$ },\n");
......
......@@ -82,7 +82,7 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
if (descriptor->has_default_value()) {
const EnumValueDescriptor* default_value = descriptor->default_value_enum();
(*variables)["default"] = FullNameToUpper(default_value->type()->full_name())
+ "__" + ToUpper(default_value->name());
+ "__" + default_value->name();
} else
(*variables)["default"] = "0";
(*variables)["deprecated"] = FieldDeprecated(descriptor);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment