|
@@ -72,15 +72,13 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor,
|
|
std::sort(fields_by_number_.begin(), fields_by_number_.end(),
|
|
std::sort(fields_by_number_.begin(), fields_by_number_.end(),
|
|
CompareFieldNumbers);
|
|
CompareFieldNumbers);
|
|
|
|
|
|
- if (IsProto2(descriptor_->file())) {
|
|
|
|
- int primitiveCount = 0;
|
|
|
|
- for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
|
|
- const FieldDescriptor* field = descriptor_->field(i);
|
|
|
|
- if (!IsNullable(field)) {
|
|
|
|
- primitiveCount++;
|
|
|
|
- if (has_bit_field_count_ == 0 || (primitiveCount % 32) == 0) {
|
|
|
|
- has_bit_field_count_++;
|
|
|
|
- }
|
|
|
|
|
|
+ int presence_bit_count = 0;
|
|
|
|
+ for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
|
|
+ const FieldDescriptor* field = descriptor_->field(i);
|
|
|
|
+ if (RequiresPresenceBit(field)) {
|
|
|
|
+ presence_bit_count++;
|
|
|
|
+ if (has_bit_field_count_ == 0 || (presence_bit_count % 32) == 0) {
|
|
|
|
+ has_bit_field_count_++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -222,11 +220,12 @@ void MessageGenerator::Generate(io::Printer* printer) {
|
|
printer->Print("\n");
|
|
printer->Print("\n");
|
|
}
|
|
}
|
|
|
|
|
|
- // oneof properties
|
|
|
|
- for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
|
|
- vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
|
|
|
|
- vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
|
|
|
|
- vars["original_name"] = descriptor_->oneof_decl(i)->name();
|
|
|
|
|
|
+ // oneof properties (for real oneofs, which come before synthetic ones)
|
|
|
|
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
|
|
|
|
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
|
|
|
|
+ vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
|
|
|
|
+ vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
|
|
|
|
+ vars["original_name"] = oneof->name();
|
|
printer->Print(
|
|
printer->Print(
|
|
vars,
|
|
vars,
|
|
"private object $name$_;\n"
|
|
"private object $name$_;\n"
|
|
@@ -234,8 +233,8 @@ void MessageGenerator::Generate(io::Printer* printer) {
|
|
"public enum $property_name$OneofCase {\n");
|
|
"public enum $property_name$OneofCase {\n");
|
|
printer->Indent();
|
|
printer->Indent();
|
|
printer->Print("None = 0,\n");
|
|
printer->Print("None = 0,\n");
|
|
- for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
|
|
- const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
|
|
|
|
|
+ for (int j = 0; j < oneof->field_count(); j++) {
|
|
|
|
+ const FieldDescriptor* field = oneof->field(j);
|
|
printer->Print("$field_property_name$ = $index$,\n",
|
|
printer->Print("$field_property_name$ = $index$,\n",
|
|
"field_property_name", GetPropertyName(field),
|
|
"field_property_name", GetPropertyName(field),
|
|
"index", StrCat(field->number()));
|
|
"index", StrCat(field->number()));
|
|
@@ -382,23 +381,24 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
|
|
for (int i = 0; i < has_bit_field_count_; i++) {
|
|
for (int i = 0; i < has_bit_field_count_; i++) {
|
|
printer->Print("_hasBits$i$ = other._hasBits$i$;\n", "i", StrCat(i));
|
|
printer->Print("_hasBits$i$ = other._hasBits$i$;\n", "i", StrCat(i));
|
|
}
|
|
}
|
|
- // Clone non-oneof fields first
|
|
|
|
|
|
+ // Clone non-oneof fields first (treating optional proto3 fields as non-oneof)
|
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
- if (!descriptor_->field(i)->containing_oneof()) {
|
|
|
|
- std::unique_ptr<FieldGeneratorBase> generator(
|
|
|
|
- CreateFieldGeneratorInternal(descriptor_->field(i)));
|
|
|
|
- generator->GenerateCloningCode(printer);
|
|
|
|
|
|
+ const FieldDescriptor* field = descriptor_->field(i);
|
|
|
|
+ if (field->real_containing_oneof()) {
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
- }
|
|
|
|
- // Clone just the right field for each oneof
|
|
|
|
- for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
|
|
|
|
- vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
|
|
|
|
- vars["property_name"] = UnderscoresToCamelCase(
|
|
|
|
- descriptor_->oneof_decl(i)->name(), true);
|
|
|
|
|
|
+ std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
|
|
|
|
+ generator->GenerateCloningCode(printer);
|
|
|
|
+ }
|
|
|
|
+ // Clone just the right field for each real oneof
|
|
|
|
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) {
|
|
|
|
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
|
|
|
|
+ vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
|
|
|
|
+ vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
|
|
printer->Print(vars, "switch (other.$property_name$Case) {\n");
|
|
printer->Print(vars, "switch (other.$property_name$Case) {\n");
|
|
printer->Indent();
|
|
printer->Indent();
|
|
- for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
|
|
- const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
|
|
|
|
|
+ for (int j = 0; j < oneof->field_count(); j++) {
|
|
|
|
+ const FieldDescriptor* field = oneof->field(j);
|
|
std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
|
|
std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
|
|
vars["field_property_name"] = GetPropertyName(field);
|
|
vars["field_property_name"] = GetPropertyName(field);
|
|
printer->Print(
|
|
printer->Print(
|
|
@@ -461,9 +461,9 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
|
|
CreateFieldGeneratorInternal(descriptor_->field(i)));
|
|
CreateFieldGeneratorInternal(descriptor_->field(i)));
|
|
generator->WriteEquals(printer);
|
|
generator->WriteEquals(printer);
|
|
}
|
|
}
|
|
- for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
|
|
- printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n",
|
|
|
|
- "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
|
|
|
|
|
|
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
|
|
|
|
+ printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n",
|
|
|
|
+ "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
|
|
}
|
|
}
|
|
if (has_extension_ranges_) {
|
|
if (has_extension_ranges_) {
|
|
printer->Print(
|
|
printer->Print(
|
|
@@ -488,9 +488,9 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
|
|
CreateFieldGeneratorInternal(descriptor_->field(i)));
|
|
CreateFieldGeneratorInternal(descriptor_->field(i)));
|
|
generator->WriteHash(printer);
|
|
generator->WriteHash(printer);
|
|
}
|
|
}
|
|
- for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
|
|
|
|
- printer->Print("hash ^= (int) $name$Case_;\n",
|
|
|
|
- "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false));
|
|
|
|
|
|
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
|
|
|
|
+ printer->Print("hash ^= (int) $name$Case_;\n",
|
|
|
|
+ "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false));
|
|
}
|
|
}
|
|
if (has_extension_ranges_) {
|
|
if (has_extension_ranges_) {
|
|
printer->Print(
|
|
printer->Print(
|
|
@@ -589,22 +589,24 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
|
|
"if (other == null) {\n"
|
|
"if (other == null) {\n"
|
|
" return;\n"
|
|
" return;\n"
|
|
"}\n");
|
|
"}\n");
|
|
- // Merge non-oneof fields
|
|
|
|
|
|
+ // Merge non-oneof fields, treating optional proto3 fields as normal fields
|
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
for (int i = 0; i < descriptor_->field_count(); i++) {
|
|
- if (!descriptor_->field(i)->containing_oneof()) {
|
|
|
|
- std::unique_ptr<FieldGeneratorBase> generator(
|
|
|
|
- CreateFieldGeneratorInternal(descriptor_->field(i)));
|
|
|
|
- generator->GenerateMergingCode(printer);
|
|
|
|
|
|
+ const FieldDescriptor* field = descriptor_->field(i);
|
|
|
|
+ if (field->real_containing_oneof()) {
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
- }
|
|
|
|
- // Merge oneof fields
|
|
|
|
- for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
|
|
|
|
- vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
|
|
|
|
- vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
|
|
|
|
|
|
+ std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
|
|
|
|
+ generator->GenerateMergingCode(printer);
|
|
|
|
+ }
|
|
|
|
+ // Merge oneof fields (for non-synthetic oneofs)
|
|
|
|
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) {
|
|
|
|
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
|
|
|
|
+ vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
|
|
|
|
+ vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
|
|
printer->Print(vars, "switch (other.$property_name$Case) {\n");
|
|
printer->Print(vars, "switch (other.$property_name$Case) {\n");
|
|
printer->Indent();
|
|
printer->Indent();
|
|
- for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
|
|
|
|
- const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
|
|
|
|
|
|
+ for (int j = 0; j < oneof->field_count(); j++) {
|
|
|
|
+ const FieldDescriptor* field = oneof->field(j);
|
|
vars["field_property_name"] = GetPropertyName(field);
|
|
vars["field_property_name"] = GetPropertyName(field);
|
|
printer->Print(
|
|
printer->Print(
|
|
vars,
|
|
vars,
|
|
@@ -698,8 +700,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
|
|
|
|
|
|
// it's a waste of space to track presence for all values, so we only track them if they're not nullable
|
|
// it's a waste of space to track presence for all values, so we only track them if they're not nullable
|
|
int MessageGenerator::GetPresenceIndex(const FieldDescriptor* descriptor) {
|
|
int MessageGenerator::GetPresenceIndex(const FieldDescriptor* descriptor) {
|
|
- if (IsNullable(descriptor) || !IsProto2(descriptor->file()) ||
|
|
|
|
- descriptor->is_extension()) {
|
|
|
|
|
|
+ if (!RequiresPresenceBit(descriptor)) {
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -709,7 +710,7 @@ int MessageGenerator::GetPresenceIndex(const FieldDescriptor* descriptor) {
|
|
if (field == descriptor) {
|
|
if (field == descriptor) {
|
|
return index;
|
|
return index;
|
|
}
|
|
}
|
|
- if (!IsNullable(field)) {
|
|
|
|
|
|
+ if (RequiresPresenceBit(field)) {
|
|
index++;
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
}
|