@ -72,15 +72,13 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor,
std : : sort ( fields_by_number_ . begin ( ) , fields_by_number_ . end ( ) ,
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 " ) ;
}
// 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 (
vars ,
" private object $name$_; \n "
@ -234,8 +233,8 @@ void MessageGenerator::Generate(io::Printer* printer) {
" public enum $property_name$OneofCase { \n " ) ;
printer - > Indent ( ) ;
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 " ,
" field_property_name " , GetPropertyName ( field ) ,
" index " , StrCat ( field - > number ( ) ) ) ;
@ -382,23 +381,24 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
for ( int i = 0 ; i < has_bit_field_count_ ; 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 + + ) {
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 - > 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 ) ) ;
vars [ " field_property_name " ] = GetPropertyName ( field ) ;
printer - > Print (
@ -461,9 +461,9 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
CreateFieldGeneratorInternal ( descriptor_ - > field ( i ) ) ) ;
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_ ) {
printer - > Print (
@ -488,9 +488,9 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
CreateFieldGeneratorInternal ( descriptor_ - > field ( i ) ) ) ;
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_ ) {
printer - > Print (
@ -589,22 +589,24 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
" if (other == null) { \n "
" return; \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 + + ) {
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 - > 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 ) ;
printer - > Print (
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
int MessageGenerator : : GetPresenceIndex ( const FieldDescriptor * descriptor ) {
if ( IsNullable ( descriptor ) | | ! IsProto2 ( descriptor - > file ( ) ) | |
descriptor - > is_extension ( ) ) {
if ( ! RequiresPresenceBit ( descriptor ) ) {
return - 1 ;
}
@ -709,7 +710,7 @@ int MessageGenerator::GetPresenceIndex(const FieldDescriptor* descriptor) {
if ( field = = descriptor ) {
return index ;
}
if ( ! IsNullable ( field ) ) {
if ( RequiresPresenceBit ( field ) ) {
index + + ;
}
}