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
printer->Print(variables_, "ProtobufCBinaryData $name$$deprecated$;\n");
break;
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");
break;
case FieldDescriptor::LABEL_REPEATED:
......
......@@ -106,7 +106,8 @@ void EnumFieldGenerator::GenerateStructMembers(io::Printer* printer) const
printer->Print(variables_, "$type$ $name$$deprecated$;\n");
break;
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");
break;
case FieldDescriptor::LABEL_REPEATED:
......
......@@ -114,6 +114,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
variables["proto_name"] = descriptor_->name();
variables["descriptor_addr"] = descriptor_addr;
variables["value"] = SimpleItoa(descriptor_->number());
const OneofDescriptor *oneof = descriptor_->containing_oneof();
if (oneof != NULL)
variables["oneofname"] = FullNameToLower(oneof->name());
if (descriptor_->has_default_value()) {
variables["default_value"] = string("&")
......@@ -133,6 +136,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
if (descriptor_->options().deprecated())
variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_DEPRECATED";
if (oneof != NULL)
variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_ONEOF";
printer->Print(variables,
"{\n"
" \"$proto_name$\",\n"
......@@ -144,7 +150,9 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
printer->Print(variables, " 0, /* quantifier_offset */\n");
break;
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");
} else {
printer->Print(variables, " 0, /* quantifier_offset */\n");
......
......@@ -147,6 +147,25 @@ GenerateStructDefinition(io::Printer* printer) {
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,
"struct $dllexport$ _$classname$\n"
"{\n"
......@@ -156,7 +175,27 @@ GenerateStructDefinition(io::Printer* printer) {
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); 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();
......@@ -173,8 +212,18 @@ GenerateStructDefinition(io::Printer* printer) {
" { PROTOBUF_C_MESSAGE_INIT (&$lcclassname$__descriptor) \\\n ");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = descriptor_->field(i);
printer->Print(", ");
field_generators_.get(field).GenerateStaticInit(printer);
if (field->containing_oneof() == NULL) {
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");
......
......@@ -113,7 +113,8 @@ void PrimitiveFieldGenerator::GenerateStructMembers(io::Printer* printer) const
printer->Print(vars, "$c_type$ $name$$deprecated$;\n");
break;
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");
break;
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