Commit 9db84a3b authored by Ilya Lipnitskiy's avatar Ilya Lipnitskiy

protoc-c: Implement oneofs

parent 2e465cfd
...@@ -101,7 +101,8 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const ...@@ -101,7 +101,8 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
printer->Print(variables_, "ProtobufCBinaryData $name$$deprecated$;\n"); printer->Print(variables_, "ProtobufCBinaryData $name$$deprecated$;\n");
break; break;
case FieldDescriptor::LABEL_OPTIONAL: case FieldDescriptor::LABEL_OPTIONAL:
printer->Print(variables_, "protobuf_c_boolean has_$name$$deprecated$;\n"); if (descriptor_->containing_oneof() == NULL)
printer->Print(variables_, "protobuf_c_boolean has_$name$$deprecated$;\n");
printer->Print(variables_, "ProtobufCBinaryData $name$$deprecated$;\n"); printer->Print(variables_, "ProtobufCBinaryData $name$$deprecated$;\n");
break; break;
case FieldDescriptor::LABEL_REPEATED: case FieldDescriptor::LABEL_REPEATED:
......
...@@ -106,7 +106,8 @@ void EnumFieldGenerator::GenerateStructMembers(io::Printer* printer) const ...@@ -106,7 +106,8 @@ void EnumFieldGenerator::GenerateStructMembers(io::Printer* printer) const
printer->Print(variables_, "$type$ $name$$deprecated$;\n"); printer->Print(variables_, "$type$ $name$$deprecated$;\n");
break; break;
case FieldDescriptor::LABEL_OPTIONAL: case FieldDescriptor::LABEL_OPTIONAL:
printer->Print(variables_, "protobuf_c_boolean has_$name$$deprecated$;\n"); if (descriptor_->containing_oneof() == NULL)
printer->Print(variables_, "protobuf_c_boolean has_$name$$deprecated$;\n");
printer->Print(variables_, "$type$ $name$$deprecated$;\n"); printer->Print(variables_, "$type$ $name$$deprecated$;\n");
break; break;
case FieldDescriptor::LABEL_REPEATED: case FieldDescriptor::LABEL_REPEATED:
......
...@@ -114,6 +114,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer, ...@@ -114,6 +114,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
variables["proto_name"] = descriptor_->name(); variables["proto_name"] = descriptor_->name();
variables["descriptor_addr"] = descriptor_addr; variables["descriptor_addr"] = descriptor_addr;
variables["value"] = SimpleItoa(descriptor_->number()); variables["value"] = SimpleItoa(descriptor_->number());
const OneofDescriptor *oneof = descriptor_->containing_oneof();
if (oneof != NULL)
variables["oneofname"] = FullNameToLower(oneof->name());
if (descriptor_->has_default_value()) { if (descriptor_->has_default_value()) {
variables["default_value"] = string("&") variables["default_value"] = string("&")
...@@ -133,6 +136,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer, ...@@ -133,6 +136,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
if (descriptor_->options().deprecated()) if (descriptor_->options().deprecated())
variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_DEPRECATED"; variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_DEPRECATED";
if (oneof != NULL)
variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_ONEOF";
printer->Print(variables, printer->Print(variables,
"{\n" "{\n"
" \"$proto_name$\",\n" " \"$proto_name$\",\n"
...@@ -144,7 +150,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer, ...@@ -144,7 +150,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
printer->Print(variables, " 0, /* quantifier_offset */\n"); printer->Print(variables, " 0, /* quantifier_offset */\n");
break; break;
case FieldDescriptor::LABEL_OPTIONAL: case FieldDescriptor::LABEL_OPTIONAL:
if (optional_uses_has) { if (oneof != NULL) {
printer->Print(variables, " offsetof($classname$, $oneofname$_case),\n");
} else if (optional_uses_has) {
printer->Print(variables, " offsetof($classname$, has_$name$),\n"); printer->Print(variables, " offsetof($classname$, has_$name$),\n");
} else { } else {
printer->Print(variables, " 0, /* quantifier_offset */\n"); printer->Print(variables, " 0, /* quantifier_offset */\n");
......
...@@ -147,6 +147,25 @@ GenerateStructDefinition(io::Printer* printer) { ...@@ -147,6 +147,25 @@ GenerateStructDefinition(io::Printer* printer) {
vars["dllexport"] = dllexport_decl_ + " "; vars["dllexport"] = dllexport_decl_ + " ";
} }
// Generate the case enums for unions
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["oneofname"] = FullNameToUpper(oneof->name());
vars["foneofname"] = FullNameToC(oneof->full_name());
printer->Print("typedef enum {\n");
printer->Indent();
printer->Print(vars, "$ucclassname$__$oneofname$__NOT_SET = 0,\n");
for (int j = 0; j < oneof->field_count(); j++) {
const FieldDescriptor *field = oneof->field(j);
vars["fieldname"] = FullNameToUpper(field->name());
vars["fieldnum"] = SimpleItoa(field->number());
printer->Print(vars, "$ucclassname$__$oneofname$_$fieldname$ = $fieldnum$,\n");
}
printer->Outdent();
printer->Print(vars, "} $foneofname$Case;\n\n");
}
printer->Print(vars, printer->Print(vars,
"struct $dllexport$ _$classname$\n" "struct $dllexport$ _$classname$\n"
"{\n" "{\n"
...@@ -156,7 +175,27 @@ GenerateStructDefinition(io::Printer* printer) { ...@@ -156,7 +175,27 @@ GenerateStructDefinition(io::Printer* printer) {
printer->Indent(); printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) { for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = descriptor_->field(i); const FieldDescriptor *field = descriptor_->field(i);
field_generators_.get(field).GenerateStructMembers(printer); if (field->containing_oneof() == NULL) {
field_generators_.get(field).GenerateStructMembers(printer);
}
}
// Generate unions from oneofs.
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["oneofname"] = FullNameToLower(oneof->name());
vars["foneofname"] = FullNameToC(oneof->full_name());
printer->Print(vars, "$foneofname$Case $oneofname$_case;\n");
printer->Print("union {\n");
printer->Indent();
for (int j = 0; j < oneof->field_count(); j++) {
const FieldDescriptor *field = oneof->field(j);
field_generators_.get(field).GenerateStructMembers(printer);
}
printer->Outdent();
printer->Print(vars, "};\n");
} }
printer->Outdent(); printer->Outdent();
...@@ -173,8 +212,18 @@ GenerateStructDefinition(io::Printer* printer) { ...@@ -173,8 +212,18 @@ GenerateStructDefinition(io::Printer* printer) {
" { PROTOBUF_C_MESSAGE_INIT (&$lcclassname$__descriptor) \\\n "); " { PROTOBUF_C_MESSAGE_INIT (&$lcclassname$__descriptor) \\\n ");
for (int i = 0; i < descriptor_->field_count(); i++) { for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = descriptor_->field(i); const FieldDescriptor *field = descriptor_->field(i);
printer->Print(", "); if (field->containing_oneof() == NULL) {
field_generators_.get(field).GenerateStaticInit(printer); printer->Print(", ");
field_generators_.get(field).GenerateStaticInit(printer);
}
}
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["foneofname"] = FullNameToUpper(oneof->full_name());
// Initialize the case enum
printer->Print(vars, ", $foneofname$__NOT_SET");
// Initialize the enum
printer->Print(", {}");
} }
printer->Print(" }\n\n\n"); printer->Print(" }\n\n\n");
......
...@@ -113,7 +113,8 @@ void PrimitiveFieldGenerator::GenerateStructMembers(io::Printer* printer) const ...@@ -113,7 +113,8 @@ void PrimitiveFieldGenerator::GenerateStructMembers(io::Printer* printer) const
printer->Print(vars, "$c_type$ $name$$deprecated$;\n"); printer->Print(vars, "$c_type$ $name$$deprecated$;\n");
break; break;
case FieldDescriptor::LABEL_OPTIONAL: case FieldDescriptor::LABEL_OPTIONAL:
printer->Print(vars, "protobuf_c_boolean has_$name$$deprecated$;\n"); if (descriptor_->containing_oneof() == NULL)
printer->Print(vars, "protobuf_c_boolean has_$name$$deprecated$;\n");
printer->Print(vars, "$c_type$ $name$$deprecated$;\n"); printer->Print(vars, "$c_type$ $name$$deprecated$;\n");
break; break;
case FieldDescriptor::LABEL_REPEATED: case FieldDescriptor::LABEL_REPEATED:
......
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