@ -10,14 +10,15 @@
# include <string>
# include "absl/container/flat_hash_set.h"
# include "absl/strings/ascii.h"
# include "absl/strings/match.h"
# include "absl/strings/str_cat.h"
# include "absl/strings/string_view.h"
# include "google/protobuf/compiler/hpb/context.h"
# include "google/protobuf/compiler/hpb/gen_repeated_fields.h"
# include "google/protobuf/compiler/hpb/gen_utils.h"
# include "google/protobuf/compiler/hpb/keywords.h"
# include "google/protobuf/compiler/hpb/names.h"
# include "google/protobuf/compiler/hpb/output.h"
# include "google/protobuf/descriptor.h"
# include "upb_generator/c/names.h"
# include "upb_generator/minitable/names.h"
@ -33,22 +34,21 @@ void WriteFieldAccessorHazzer(const protobuf::Descriptor* desc,
const protobuf : : FieldDescriptor * field ,
absl : : string_view resolved_field_name ,
absl : : string_view resolved_upbc_name ,
Output & output ) ;
Context & ctx ) ;
void WriteFieldAccessorClear ( const protobuf : : Descriptor * desc ,
const protobuf : : FieldDescriptor * field ,
absl : : string_view resolved_field_name ,
absl : : string_view resolved_upbc_name ,
Output & output ) ;
Context & ctx ) ;
void WriteMapFieldAccessors ( const protobuf : : Descriptor * desc ,
const protobuf : : FieldDescriptor * field ,
absl : : string_view resolved_field_name ,
absl : : string_view resolved_upbc_name ,
Output & output ) ;
absl : : string_view resolved_upbc_name , Context & ctx ) ;
void WriteMapAccessorDefinitions ( const protobuf : : Descriptor * message ,
const protobuf : : FieldDescriptor * field ,
absl : : string_view resolved_field_name ,
absl : : string_view class_name , Output & output ) ;
absl : : string_view class_name , Context & ctx ) ;
// Returns C++ class member name by resolving naming conflicts across
// proto field names (such as clear_ prefixes) and keyword collisions.
@ -75,55 +75,55 @@ NameToFieldDescriptorMap CreateFieldNameMap(
}
void WriteFieldAccessorsInHeader ( const protobuf : : Descriptor * desc ,
Output & output ) {
Context & ctx ) {
// Generate const methods.
OutputIndenter i ( output ) ;
auto field_names = CreateFieldNameMap ( desc ) ;
auto mangler = CreateNameMangler ( desc ) ;
auto indent = ctx . printer ( ) . WithIndent ( ) ;
for ( const auto * field : FieldNumberOrder ( desc ) ) {
std : : string resolved_field_name = ResolveFieldName ( field , field_names ) ;
std : : string resolved_upbc_name = mangler . ResolveFieldName ( field - > name ( ) ) ;
WriteFieldAccessorHazzer ( desc , field , resolved_field_name ,
resolved_upbc_name , output ) ;
resolved_upbc_name , ctx ) ;
WriteFieldAccessorClear ( desc , field , resolved_field_name ,
resolved_upbc_name , output ) ;
resolved_upbc_name , ctx ) ;
if ( field - > is_map ( ) ) {
WriteMapFieldAccessors ( desc , field , resolved_field_name ,
resolved_upbc_name , output ) ;
resolved_upbc_name , ctx ) ;
} else if ( desc - > options ( ) . map_entry ( ) ) {
// TODO Implement map entry
} else if ( field - > is_repeated ( ) ) {
WriteRepeatedFieldsInMessageHeader ( desc , field , resolved_field_name ,
resolved_upbc_name , output ) ;
resolved_upbc_name , ctx ) ;
} else {
// non-repeated.
if ( field - > cpp_type ( ) = = protobuf : : FieldDescriptor : : CPPTYPE_STRING ) {
output ( R " cc(
$ 0 $ 1 ( ) const ;
void set_ $ 1 ( $ 0 value ) ;
) cc " ,
CppConstType ( field ) , resolved_field_name ) ;
ctx . EmitLegacy ( R " cc(
$ 0 $ 1 ( ) const ;
void set_ $ 1 ( $ 0 value ) ;
) cc " ,
CppConstType ( field ) , resolved_field_name ) ;
} else if ( field - > cpp_type ( ) = =
protobuf : : FieldDescriptor : : CPPTYPE_MESSAGE ) {
output ( R " cc(
$ 1 $ 2 ( ) const ;
$ 0 mutable_ $ 2 ( ) ;
/**
* Re - points submessage to the given target .
*
* REQUIRES :
* - both messages must be in the same arena .
*/
void set_alias_ $ 2 ( $ 0 target ) ;
) cc " ,
MessagePtrConstType ( field , /* const */ false ) ,
MessagePtrConstType ( field , /* const */ true ) ,
resolved_field_name ) ;
ctx . EmitLegacy ( R " cc(
$ 1 $ 2 ( ) const ;
$ 0 mutable_ $ 2 ( ) ;
/**
* Re - points submessage to the given target .
*
* REQUIRES :
* - both messages must be in the same arena .
*/
void set_alias_ $ 2 ( $ 0 target ) ;
) cc " ,
MessagePtrConstType ( field , /* const */ false ) ,
MessagePtrConstType ( field , /* const */ true ) ,
resolved_field_name ) ;
} else {
output (
ctx . EmitLegacy (
R " cc(
inline $ 0 $ 1 ( ) const { return $ 2 _ $ 3 ( msg_ ) ; }
inline void set_ $ 1 ( $ 0 value ) { return $ 2 _set_ $ 3 ( msg_ , value ) ; }
@ -139,12 +139,12 @@ void WriteFieldAccessorHazzer(const protobuf::Descriptor* desc,
const protobuf : : FieldDescriptor * field ,
const absl : : string_view resolved_field_name ,
const absl : : string_view resolved_upbc_name ,
Output & output ) {
Context & ctx ) {
// Generate hazzer (if any).
if ( field - > has_presence ( ) ) {
// Has presence.
output ( " inline bool has_$0() const { return $1_has_$2(msg_); } \n " ,
resolved_field_name , MessageName ( desc ) , resolved_upbc_name ) ;
ctx . EmitLegacy ( " inline bool has_$0() const { return $1_has_$2(msg_); } \n " ,
resolved_field_name , MessageName ( desc ) , resolved_upbc_name ) ;
}
}
@ -152,10 +152,10 @@ void WriteFieldAccessorClear(const protobuf::Descriptor* desc,
const protobuf : : FieldDescriptor * field ,
const absl : : string_view resolved_field_name ,
const absl : : string_view resolved_upbc_name ,
Output & output ) {
Context & ctx ) {
if ( field - > has_presence ( ) ) {
output ( " void clear_$0() { $2_clear_$1(msg_); } \n " , resolved_field_name ,
resolved_upbc_name , MessageName ( desc ) ) ;
ctx . EmitLegacy ( " void clear_$0() { $2_clear_$1(msg_); } \n " ,
resolved_field_name , resolved_upbc_name , MessageName ( desc ) ) ;
}
}
@ -163,11 +163,11 @@ void WriteMapFieldAccessors(const protobuf::Descriptor* desc,
const protobuf : : FieldDescriptor * field ,
const absl : : string_view resolved_field_name ,
const absl : : string_view resolved_upbc_name ,
Output & output ) {
Context & ctx ) {
const protobuf : : Descriptor * entry = field - > message_type ( ) ;
const protobuf : : FieldDescriptor * key = entry - > FindFieldByNumber ( 1 ) ;
const protobuf : : FieldDescriptor * val = entry - > FindFieldByNumber ( 2 ) ;
output (
ctx . EmitLegacy (
R " cc(
inline size_t $ 0 _size ( ) const { return $ 1 _ $ 3 _size ( msg_ ) ; }
inline void clear_ $ 0 ( ) { $ 1 _clear_ $ 3 ( msg_ ) ; }
@ -177,7 +177,7 @@ void WriteMapFieldAccessors(const protobuf::Descriptor* desc,
resolved_upbc_name ) ;
if ( val - > cpp_type ( ) = = protobuf : : FieldDescriptor : : CPPTYPE_MESSAGE ) {
output (
ctx . EmitLegacy (
R " cc(
bool set_ $ 0 ( $ 1 key , $ 3 value ) ;
bool set_ $ 0 ( $ 1 key , $ 4 value ) ;
@ -189,7 +189,7 @@ void WriteMapFieldAccessors(const protobuf::Descriptor* desc,
MessagePtrConstType ( val , /* is_const */ true ) ,
MessagePtrConstType ( val , /* is_const */ false ) ) ;
} else {
output (
ctx . EmitLegacy (
R " cc(
bool set_ $ 0 ( $ 1 key , $ 2 value ) ;
absl : : StatusOr < $ 2 > get_ $ 0 ( $ 1 key ) ;
@ -198,40 +198,40 @@ void WriteMapFieldAccessors(const protobuf::Descriptor* desc,
}
}
void WriteAccessorsInSource ( const protobuf : : Descriptor * desc , Output & output ) {
void WriteAccessorsInSource ( const protobuf : : Descriptor * desc , Context & ctx ) {
std : : string class_name = ClassName ( desc ) ;
absl : : StrAppend ( & class_name , " Access " ) ;
outpu t( " namespace internal { \n " ) ;
ctx . Emi t( " namespace internal { \n " ) ;
const char arena_expression [ ] = " arena_ " ;
auto field_names = CreateFieldNameMap ( desc ) ;
auto mangler = CreateNameMangler ( desc ) ;
// Generate const methods.
OutputIndenter i ( output ) ;
auto indent = ctx . printer ( ) . WithIndent ( ) ;
for ( const auto * field : FieldNumberOrder ( desc ) ) {
std : : string resolved_field_name = ResolveFieldName ( field , field_names ) ;
std : : string resolved_upbc_name = mangler . ResolveFieldName ( field - > name ( ) ) ;
if ( field - > is_map ( ) ) {
WriteMapAccessorDefinitions ( desc , field , resolved_field_name , class_name ,
output ) ;
ctx ) ;
} else if ( desc - > options ( ) . map_entry ( ) ) {
// TODO Implement map entry
} else if ( field - > is_repeated ( ) ) {
if ( field - > cpp_type ( ) = = protobuf : : FieldDescriptor : : CPPTYPE_MESSAGE ) {
WriteRepeatedMessageAccessor ( desc , field , resolved_field_name ,
class_name , output ) ;
class_name , ctx ) ;
} else if ( field - > cpp_type ( ) = =
protobuf : : FieldDescriptor : : CPPTYPE_STRING ) {
WriteRepeatedStringAccessor ( desc , field , resolved_field_name ,
class_name , output ) ;
class_name , ctx ) ;
} else {
WriteRepeatedScalarAccessor ( desc , field , resolved_field_name ,
class_name , output ) ;
class_name , ctx ) ;
}
} else {
// non-repeated field.
if ( field - > cpp_type ( ) = = protobuf : : FieldDescriptor : : CPPTYPE_STRING ) {
output (
ctx . EmitLegacy (
R " cc(
$ 1 $ 0 : : $ 2 ( ) const {
return hpb : : interop : : upb : : FromUpbStringView ( $ 3 _ $ 4 ( msg_ ) ) ;
@ -240,7 +240,7 @@ void WriteAccessorsInSource(const protobuf::Descriptor* desc, Output& output) {
class_name , CppConstType ( field ) , resolved_field_name ,
MessageName ( desc ) , resolved_upbc_name ) ;
// Set string.
output (
ctx . EmitLegacy (
R " cc(
void $ 0 : : set_ $ 2 ( $ 1 value ) {
$ 4 _set_ $ 3 ( msg_ , hpb : : interop : : upb : : CopyToUpbStringView ( value , $ 5 ) ) ;
@ -250,7 +250,7 @@ void WriteAccessorsInSource(const protobuf::Descriptor* desc, Output& output) {
resolved_upbc_name , MessageName ( desc ) , arena_expression ) ;
} else if ( field - > cpp_type ( ) = =
protobuf : : FieldDescriptor : : CPPTYPE_MESSAGE ) {
output (
ctx . EmitLegacy (
R " cc(
$ 1 $ 0 : : $ 2 ( ) const {
if ( ! has_ $ 2 ( ) ) {
@ -265,7 +265,7 @@ void WriteAccessorsInSource(const protobuf::Descriptor* desc, Output& output) {
MessageBaseType ( field , /* maybe_const */ false ) ,
resolved_upbc_name ) ;
output (
ctx . EmitLegacy (
R " cc(
$ 1 $ 0 : : mutable_ $ 2 ( ) {
return hpb : : interop : : upb : : MakeHandle < $ 4 > (
@ -286,15 +286,15 @@ void WriteAccessorsInSource(const protobuf::Descriptor* desc, Output& output) {
}
}
}
outpu t( " \n " ) ;
outpu t( " } // namespace internal \n \n " ) ;
ctx . Emi t( " \n " ) ;
ctx . Emi t( " } // namespace internal \n \n " ) ;
}
void WriteMapAccessorDefinitions ( const protobuf : : Descriptor * message ,
const protobuf : : FieldDescriptor * field ,
const absl : : string_view resolved_field_name ,
const absl : : string_view class_name ,
Output & output ) {
Context & ctx ) {
const protobuf : : Descriptor * entry = field - > message_type ( ) ;
const protobuf : : FieldDescriptor * key = entry - > FindFieldByNumber ( 1 ) ;
const protobuf : : FieldDescriptor * val = entry - > FindFieldByNumber ( 2 ) ;
@ -310,7 +310,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
" upb_StringView upb_key = {key.data(), key.size()}; \n " ;
}
if ( val - > cpp_type ( ) = = protobuf : : FieldDescriptor : : CPPTYPE_MESSAGE ) {
output (
ctx . EmitLegacy (
R " cc(
bool $ 0 : : set_ $ 1 ( $ 2 key , $ 3 value ) {
upb_Message * clone = upb_Message_DeepClone (
@ -325,7 +325,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
converted_key_name , upbc_name ,
: : upb : : generator : : MiniTableMessageVarName (
val - > message_type ( ) - > full_name ( ) ) ) ;
output (
ctx . EmitLegacy (
R " cc(
bool $ 0 : : set_ $ 1 ( $ 2 key , $ 3 value ) {
upb_Message * clone = upb_Message_DeepClone (
@ -340,7 +340,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
converted_key_name , upbc_name ,
: : upb : : generator : : MiniTableMessageVarName (
val - > message_type ( ) - > full_name ( ) ) ) ;
output (
ctx . EmitLegacy (
R " cc(
bool $ 0 : : set_alias_ $ 1 ( $ 2 key , $ 3 value ) {
$ 6 return $ 4 _ $ 8 _set (
@ -351,7 +351,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
MessagePtrConstType ( val , /* is_const */ true ) , MessageName ( message ) ,
MessageName ( val - > message_type ( ) ) , optional_conversion_code ,
converted_key_name , upbc_name ) ;
output (
ctx . EmitLegacy (
R " cc(
bool $ 0 : : set_alias_ $ 1 ( $ 2 key , $ 3 value ) {
$ 6 return $ 4 _ $ 8 _set (
@ -362,7 +362,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
MessagePtrConstType ( val , /* is_const */ false ) , MessageName ( message ) ,
MessageName ( val - > message_type ( ) ) , optional_conversion_code ,
converted_key_name , upbc_name ) ;
output (
ctx . EmitLegacy (
R " cc(
absl : : StatusOr < $ 3 > $ 0 : : get_ $ 1 ( $ 2 key ) {
$ 5 * msg_value ;
@ -378,7 +378,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
MessageName ( val - > message_type ( ) ) ,
QualifiedClassName ( val - > message_type ( ) ) , optional_conversion_code ,
converted_key_name , upbc_name ) ;
output (
ctx . EmitLegacy (
R " cc(
void $ 0 : : delete_ $ 1 ( $ 2 key ) { $ 6 $ 4 _ $ 8 _delete ( msg_ , $ 7 ) ; }
) cc " ,
@ -387,7 +387,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
MessageName ( val - > message_type ( ) ) , optional_conversion_code ,
converted_key_name , upbc_name ) ;
} else if ( val - > cpp_type ( ) = = protobuf : : FieldDescriptor : : CPPTYPE_STRING ) {
output (
ctx . EmitLegacy (
R " cc(
bool $ 0 : : set_ $ 1 ( $ 2 key , $ 3 value ) {
$ 5 return $ 4 _ $ 7 _set (
@ -398,7 +398,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
class_name , resolved_field_name , CppConstType ( key ) , CppConstType ( val ) ,
MessageName ( message ) , optional_conversion_code , converted_key_name ,
upbc_name ) ;
output (
ctx . EmitLegacy (
R " cc(
absl : : StatusOr < $ 3 > $ 0 : : get_ $ 1 ( $ 2 key ) {
upb_StringView value ;
@ -412,7 +412,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
class_name , resolved_field_name , CppConstType ( key ) , CppConstType ( val ) ,
MessageName ( message ) , optional_conversion_code , converted_key_name ,
upbc_name ) ;
output (
ctx . EmitLegacy (
R " cc(
void $ 0 : : delete_ $ 1 ( $ 2 key ) { $ 5 $ 4 _ $ 7 _delete ( msg_ , $ 6 ) ; }
) cc " ,
@ -420,7 +420,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
MessageName ( message ) , optional_conversion_code , converted_key_name ,
upbc_name ) ;
} else {
output (
ctx . EmitLegacy (
R " cc(
bool $ 0 : : set_ $ 1 ( $ 2 key , $ 3 value ) {
$ 5 return $ 4 _ $ 7 _set ( msg_ , $ 6 , value , arena_ ) ;
@ -429,7 +429,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
class_name , resolved_field_name , CppConstType ( key ) , CppConstType ( val ) ,
MessageName ( message ) , optional_conversion_code , converted_key_name ,
upbc_name ) ;
output (
ctx . EmitLegacy (
R " cc(
absl : : StatusOr < $ 3 > $ 0 : : get_ $ 1 ( $ 2 key ) {
$ 3 value ;
@ -443,7 +443,7 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
class_name , resolved_field_name , CppConstType ( key ) , CppConstType ( val ) ,
MessageName ( message ) , optional_conversion_code , converted_key_name ,
upbc_name ) ;
output (
ctx . EmitLegacy (
R " cc(
void $ 0 : : delete_ $ 1 ( $ 2 key ) { $ 5 $ 4 _ $ 7 _delete ( msg_ , $ 6 ) ; }
) cc " ,
@ -454,11 +454,11 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
}
void WriteUsingAccessorsInHeader ( const protobuf : : Descriptor * desc ,
MessageClassType handle_type , Output & output ) {
MessageClassType handle_type , Context & ctx ) {
bool read_only = handle_type = = MessageClassType : : kMessageCProxy ;
// Generate const methods.
OutputIndenter i ( output ) ;
auto indent = ctx . printer ( ) . WithIndent ( ) ;
std : : string class_name = ClassName ( desc ) ;
auto field_names = CreateFieldNameMap ( desc ) ;
@ -466,20 +466,22 @@ void WriteUsingAccessorsInHeader(const protobuf::Descriptor* desc,
std : : string resolved_field_name = ResolveFieldName ( field , field_names ) ;
// Generate hazzer (if any).
if ( field - > has_presence ( ) ) {
output ( " using $0Access::has_$1; \n " , class_name , resolved_field_name ) ;
ctx . EmitLegacy ( " using $0Access::has_$1; \n " , class_name ,
resolved_field_name ) ;
if ( ! read_only ) {
output ( " using $0Access::clear_$1; \n " , class_name , resolved_field_name ) ;
ctx . EmitLegacy ( " using $0Access::clear_$1; \n " , class_name ,
resolved_field_name ) ;
}
}
if ( field - > is_map ( ) ) {
output (
ctx . EmitLegacy (
R " cc(
using $ 0 Access : : $ 1 _size ;
using $ 0 Access : : get_ $ 1 ;
) cc " ,
class_name , resolved_field_name ) ;
if ( ! read_only ) {
output (
ctx . EmitLegacy (
R " cc(
using $ 0 Access : : clear_ $ 1 ;
using $ 0 Access : : delete_ $ 1 ;
@ -489,7 +491,7 @@ void WriteUsingAccessorsInHeader(const protobuf::Descriptor* desc,
// only emit set_alias for maps when value is a message
if ( field - > message_type ( ) - > FindFieldByNumber ( 2 ) - > cpp_type ( ) = =
protobuf : : FieldDescriptor : : CPPTYPE_MESSAGE ) {
output (
ctx . EmitLegacy (
R " cc(
using $ 0 Access : : set_alias_ $ 1 ;
) cc " ,
@ -500,67 +502,73 @@ void WriteUsingAccessorsInHeader(const protobuf::Descriptor* desc,
// TODO Implement map entry
} else if ( field - > is_repeated ( ) ) {
WriteRepeatedFieldUsingAccessors ( field , class_name , resolved_field_name ,
output , read_only ) ;
ctx , read_only ) ;
} else {
if ( field - > cpp_type ( ) = = protobuf : : FieldDescriptor : : CPPTYPE_MESSAGE ) {
output ( " using $0Access::$1; \n " , ClassName ( desc ) , resolved_field_name ) ;
ctx . EmitLegacy ( " using $0Access::$1; \n " , ClassName ( desc ) ,
resolved_field_name ) ;
if ( ! read_only ) {
output ( " using $0Access::mutable_$1; \n " , class_name ,
resolved_field_name ) ;
output ( " using $0Access::set_alias_$1; \n " , class_name ,
resolved_field_name ) ;
ctx . EmitLegacy ( " using $0Access::mutable_$1; \n " , class_name ,
resolved_field_name ) ;
ctx . EmitLegacy ( " using $0Access::set_alias_$1; \n " , class_name ,
resolved_field_name ) ;
}
} else {
output ( " using $0Access::$1; \n " , class_name , resolved_field_name ) ;
ctx . EmitLegacy ( " using $0Access::$1; \n " , class_name ,
resolved_field_name ) ;
if ( ! read_only ) {
output ( " using $0Access::set_$1; \n " , class_name , resolved_field_name ) ;
ctx . EmitLegacy ( " using $0Access::set_$1; \n " , class_name ,
resolved_field_name ) ;
}
}
}
}
for ( int i = 0 ; i < desc - > real_oneof_decl_count ( ) ; + + i ) {
const protobuf : : OneofDescriptor * oneof = desc - > oneof_decl ( i ) ;
output ( " using $0Access::$1_case; \n " , class_name , oneof - > name ( ) ) ;
output ( " using $0Access::$1Case; \n " , class_name ,
ToCamelCase ( oneof - > name ( ) , /*lower_first=*/ false ) ) ;
ctx . EmitLegacy ( " using $0Access::$1_case; \n " , class_name , oneof - > name ( ) ) ;
ctx . EmitLegacy ( " using $0Access::$1Case; \n " , class_name ,
ToCamelCase ( oneof - > name ( ) , /*lower_first=*/ false ) ) ;
for ( int j = 0 ; j < oneof - > field_count ( ) ; + + j ) {
const protobuf : : FieldDescriptor * field = oneof - > field ( j ) ;
output ( " using $0Access::k$1; \n " , class_name ,
ToCamelCase ( field - > name ( ) , /*lower_first=*/ false ) ,
field - > number ( ) ) ;
ctx . EmitLegacy ( " using $0Access::k$1; \n " , class_name ,
ToCamelCase ( field - > name ( ) , /*lower_first=*/ false ) ,
field - > number ( ) ) ;
}
output ( " using $0Access::$1_NOT_SET; \n " , class_name ,
absl : : AsciiStrToUpper ( oneof - > name ( ) ) ) ;
ctx . EmitLegacy ( " using $0Access::$1_NOT_SET; \n " , class_name ,
absl : : AsciiStrToUpper ( oneof - > name ( ) ) ) ;
}
}
void WriteOneofAccessorsInHeader ( const protobuf : : Descriptor * desc ,
Output & output ) {
Context & ctx ) {
// Generate const methods.
OutputIndenter i ( output ) ;
auto indent = ctx . printer ( ) . WithIndent ( ) ;
std : : string class_name = ClassName ( desc ) ;
auto field_names = CreateFieldNameMap ( desc ) ;
for ( int i = 0 ; i < desc - > real_oneof_decl_count ( ) ; + + i ) {
const protobuf : : OneofDescriptor * oneof = desc - > oneof_decl ( i ) ;
output ( " enum $0Case { \n " ,
ToCamelCase ( oneof - > name ( ) , /*lower_first=*/ false ) ) ;
ctx . EmitLegacy ( " enum $0Case { \n " ,
ToCamelCase ( oneof - > name ( ) , /*lower_first=*/ false ) ) ;
for ( int j = 0 ; j < oneof - > field_count ( ) ; + + j ) {
const protobuf : : FieldDescriptor * field = oneof - > field ( j ) ;
output ( " k$0 = $1, \n " , ToCamelCase ( field - > name ( ) , /*lower_first=*/ false ) ,
field - > number ( ) ) ;
ctx . EmitLegacy ( " k$0 = $1, \n " ,
ToCamelCase ( field - > name ( ) , /*lower_first=*/ false ) ,
field - > number ( ) ) ;
}
output ( " $0_NOT_SET = 0, \n " , absl : : AsciiStrToUpper ( oneof - > name ( ) ) ) ;
output ( " }; \n \n " ) ;
output ( " $0Case $1_case() const { \n " ,
ToCamelCase ( oneof - > name ( ) , /*lower_first=*/ false ) , oneof - > name ( ) ) ;
ctx . EmitLegacy ( " $0_NOT_SET = 0, \n " , absl : : AsciiStrToUpper ( oneof - > name ( ) ) ) ;
ctx . Emit ( " }; \n \n " ) ;
ctx . EmitLegacy ( " $0Case $1_case() const { \n " ,
ToCamelCase ( oneof - > name ( ) , /*lower_first=*/ false ) ,
oneof - > name ( ) ) ;
for ( int j = 0 ; j < oneof - > field_count ( ) ; + + j ) {
const protobuf : : FieldDescriptor * field = oneof - > field ( j ) ;
std : : string resolved_field_name = ResolveFieldName ( field , field_names ) ;
output ( " if (has_$0()) { return k$1; } \n " , resolved_field_name ,
ToCamelCase ( field - > name ( ) , /*lower_first=*/ false ) ) ;
ctx . EmitLegacy ( " if (has_$0()) { return k$1; } \n " , resolved_field_name ,
ToCamelCase ( field - > name ( ) , /*lower_first=*/ false ) ) ;
}
output ( " return $0_NOT_SET; \n " , absl : : AsciiStrToUpper ( oneof - > name ( ) ) ) ;
output ( " } \n ; " ) ;
ctx . EmitLegacy ( " return $0_NOT_SET; \n " ,
absl : : AsciiStrToUpper ( oneof - > name ( ) ) ) ;
ctx . Emit ( " } \n ; " ) ;
}
}