@ -83,7 +83,7 @@ std::string PhpName(const std::string& full_name, bool is_descriptor);
std : : string DefaultForField ( FieldDescriptor * field ) ;
std : : string IntToString ( int32 value ) ;
std : : string FilenameToClassname ( const string & filename ) ;
std : : string GeneratedMetadataFileName ( const std : : string & proto_ file,
std : : string GeneratedMetadataFileName ( const FileDescriptor * file ,
bool is_descriptor ) ;
std : : string LabelForField ( FieldDescriptor * field ) ;
std : : string TypeName ( FieldDescriptor * field ) ;
@ -94,6 +94,9 @@ void Indent(io::Printer* printer);
void Outdent ( io : : Printer * printer ) ;
void GenerateMessageDocComment ( io : : Printer * printer , const Descriptor * message ,
int is_descriptor ) ;
void GenerateMessageConstructorDocComment ( io : : Printer * printer ,
const Descriptor * message ,
int is_descriptor ) ;
void GenerateFieldDocComment ( io : : Printer * printer , const FieldDescriptor * field ,
int is_descriptor , int function_type ) ;
void GenerateEnumDocComment ( io : : Printer * printer , const EnumDescriptor * enum_ ,
@ -105,31 +108,40 @@ void GenerateServiceDocComment(io::Printer* printer,
void GenerateServiceMethodDocComment ( io : : Printer * printer ,
const MethodDescriptor * method ) ;
std : : string RenameEmpty ( const std : : string & name ) {
if ( name = = " Empty " ) {
return " GPBEmpty " ;
} else {
return name ;
std : : string ReservedNamePrefix ( const string & classname ,
const FileDescriptor * file ) {
bool is_reserved = false ;
string lower = classname ;
transform ( lower . begin ( ) , lower . end ( ) , lower . begin ( ) , : : tolower ) ;
for ( int i = 0 ; i < kReservedNamesSize ; i + + ) {
if ( lower = = kReservedNames [ i ] ) {
is_reserved = true ;
break ;
}
}
}
std : : string MessageFullName ( const Descriptor * message , bool is_descriptor ) {
if ( is_descriptor ) {
return StringReplace ( message - > full_name ( ) ,
" google.protobuf " ,
" google.protobuf.internal " , false ) ;
} else {
return message - > full_name ( ) ;
if ( is_reserved ) {
if ( file - > package ( ) = = " google.protobuf " ) {
return " GPB " ;
} else {
return " PB " ;
}
}
return " " ;
}
std : : string EnumFullName ( const EnumDescriptor * envm , bool is_descriptor ) {
template < typename DescriptorType >
std : : string DescriptorFullName ( const DescriptorType * desc , bool is_descriptor ) {
if ( is_descriptor ) {
return StringReplace ( envm - > full_name ( ) ,
return StringReplace ( desc - > full_name ( ) ,
" google.protobuf " ,
" google.protobuf.internal " , false ) ;
} else {
return envm - > full_name ( ) ;
return desc - > full_name ( ) ;
}
}
@ -141,22 +153,43 @@ std::string ClassNamePrefix(const string& classname,
return prefix ;
}
bool is_reserved = false ;
return ReservedNamePrefix ( classname , desc - > file ( ) ) ;
}
template < typename DescriptorType >
std : : string GeneratedClassName ( const DescriptorType * desc ) {
std : : string classname = ClassNamePrefix ( desc - > name ( ) , desc ) + desc - > name ( ) ;
const Descriptor * containing = desc - > containing_type ( ) ;
while ( containing ! = NULL ) {
classname = ClassNamePrefix ( containing - > name ( ) , desc ) + containing - > name ( )
+ ' \\ ' + classname ;
containing = containing - > containing_type ( ) ;
}
return classname ;
}
std : : string GeneratedClassName ( const ServiceDescriptor * desc ) {
std : : string classname = desc - > name ( ) ;
return ClassNamePrefix ( classname , desc ) + classname ;
}
template < typename DescriptorType >
std : : string LegacyGeneratedClassName ( const DescriptorType * desc ) {
std : : string classname = desc - > name ( ) ;
const Descriptor * containing = desc - > containing_type ( ) ;
while ( containing ! = NULL ) {
classname = containing - > name ( ) + ' _ ' + classname ;
containing = containing - > containing_type ( ) ;
}
return ClassNamePrefix ( classname , desc ) + classname ;
}
std : : string ClassNamePrefix ( const string & classname ) {
string lower = classname ;
transform ( lower . begin ( ) , lower . end ( ) , lower . begin ( ) , : : tolower ) ;
for ( int i = 0 ; i < kReservedNamesSize ; i + + ) {
if ( lower = = kReservedNames [ i ] ) {
is_reserved = true ;
break ;
}
}
if ( is_reserved ) {
if ( desc - > file ( ) - > package ( ) = = " google.protobuf " ) {
return " GPB " ;
} else {
return " PB " ;
}
}
@ -192,34 +225,39 @@ std::string ConstantNamePrefix(const string& classname) {
}
template < typename DescriptorType >
std : : string NamespacedName ( const string & classname ,
const DescriptorType * desc , bool is_descriptor ) {
std : : string RootPhpNamespace ( const DescriptorType * desc , bool is_descriptor ) {
if ( desc - > file ( ) - > options ( ) . has_php_namespace ( ) ) {
const string & php_namespace = desc - > file ( ) - > options ( ) . php_namespace ( ) ;
if ( php_namespace ! = " " ) {
return php_namespace + ' \\ ' + classname ;
} else {
return classname ;
return php_namespace ;
}
return " " ;
}
if ( desc - > file ( ) - > package ( ) = = " " ) {
return classname ;
} else {
return PhpName ( desc - > file ( ) - > package ( ) , is_descriptor ) + ' \\ ' +
classname ;
if ( desc - > file ( ) - > package ( ) ! = " " ) {
return PhpName ( desc - > file ( ) - > package ( ) , is_descriptor ) ;
}
return " " ;
}
template < typename DescriptorType >
std : : string FullClassName ( const DescriptorType * desc , bool is_descriptor ) {
string classname = GeneratedClassName ( desc ) ;
return NamespacedName ( classname , desc , is_descriptor ) ;
string php_namespace = RootPhpNamespace ( desc , is_descriptor ) ;
if ( php_namespace ! = " " ) {
return php_namespace + " \\ " + classname ;
}
return classname ;
}
std : : string FullClassName ( const ServiceDescriptor * desc , bool is_descriptor ) {
string classname = GeneratedClassName ( desc ) ;
return NamespacedName ( classname , desc , is_descriptor ) ;
template < typename DescriptorType >
std : : string LegacyFullClassName ( const DescriptorType * desc , bool is_descriptor ) {
string classname = LegacyGeneratedClassName ( desc ) ;
string php_namespace = RootPhpNamespace ( desc , is_descriptor ) ;
if ( php_namespace ! = " " ) {
return php_namespace + " \\ " + classname ;
}
return classname ;
}
std : : string PhpName ( const std : : string & full_name , bool is_descriptor ) {
@ -227,20 +265,23 @@ std::string PhpName(const std::string& full_name, bool is_descriptor) {
return kDescriptorPackageName ;
}
std : : string segment ;
std : : string result ;
bool cap_next_letter = true ;
for ( int i = 0 ; i < full_name . size ( ) ; i + + ) {
if ( ' a ' < = full_name [ i ] & & full_name [ i ] < = ' z ' & & cap_next_letter ) {
resul t + = full_name [ i ] + ( ' A ' - ' a ' ) ;
segmen t + = full_name [ i ] + ( ' A ' - ' a ' ) ;
cap_next_letter = false ;
} else if ( full_name [ i ] = = ' . ' ) {
result + = ' \\ ' ;
result + = ClassNamePrefix ( segment ) + segment + ' \\ ' ;
segment = " " ;
cap_next_letter = true ;
} else {
resul t + = full_name [ i ] ;
segmen t + = full_name [ i ] ;
cap_next_letter = false ;
}
}
result + = ClassNamePrefix ( segment ) + segment ;
return result ;
}
@ -268,11 +309,13 @@ std::string DefaultForField(const FieldDescriptor* field) {
}
}
std : : string GeneratedMetadataFileName ( const std : : string & proto_ file,
std : : string GeneratedMetadataFileName ( const FileDescriptor * file ,
bool is_descriptor ) {
const string & proto_file = file - > name ( ) ;
int start_index = 0 ;
int first_index = proto_file . find_first_of ( " / " , start_index ) ;
std : : string result = " GPBMetadata/ " ;
std : : string result = " " ;
std : : string segment = " " ;
if ( proto_file = = kEmptyFile ) {
return kEmptyMetadataFile ;
@ -290,24 +333,44 @@ std::string GeneratedMetadataFileName(const std::string& proto_file,
file_no_suffix = proto_file . substr ( 0 , lastindex ) ;
}
while ( first_index ! = string : : npos ) {
result + = UnderscoresToCamelCase (
file_no_suffix . substr ( start_index , first_index - start_index ) , true ) ;
result + = " / " ;
start_index = first_index + 1 ;
first_index = file_no_suffix . find_first_of ( " / " , start_index ) ;
if ( file - > options ( ) . has_php_metadata_namespace ( ) ) {
const string & php_metadata_namespace =
file - > options ( ) . php_metadata_namespace ( ) ;
if ( php_metadata_namespace ! = " " & & php_metadata_namespace ! = " \\ " ) {
result + = php_metadata_namespace ;
std : : replace ( result . begin ( ) , result . end ( ) , ' \\ ' , ' / ' ) ;
if ( result . at ( result . size ( ) - 1 ) ! = ' / ' ) {
result + = " / " ;
}
}
} else {
result + = " GPBMetadata/ " ;
while ( first_index ! = string : : npos ) {
segment = UnderscoresToCamelCase (
file_no_suffix . substr ( start_index , first_index - start_index ) , true ) ;
result + = ReservedNamePrefix ( segment , file ) + segment + " / " ;
start_index = first_index + 1 ;
first_index = file_no_suffix . find_first_of ( " / " , start_index ) ;
}
}
// Append file name.
result + = RenameEmpty ( UnderscoresToCamelCase (
file_no_suffix . substr ( start_index , first_index - start_index ) , true ) ) ;
int file_name_start = file_no_suffix . find_last_of ( " / " ) ;
if ( file_name_start = = string : : npos ) {
file_name_start = 0 ;
} else {
file_name_start + = 1 ;
}
segment = UnderscoresToCamelCase (
file_no_suffix . substr ( file_name_start , first_index - file_name_start ) , true ) ;
return result + = " .php " ;
return result + ReservedNamePrefix ( segment , file ) + segment + " .php " ;
}
std : : string GeneratedMessageFileName ( const Descriptor * message ,
template < typename DescriptorType >
std : : string GeneratedClassFileName ( const DescriptorType * desc ,
bool is_descriptor ) {
std : : string result = FullClassName ( message , is_descriptor ) ;
std : : string result = FullClassName ( desc , is_descriptor ) ;
for ( int i = 0 ; i < result . size ( ) ; i + + ) {
if ( result [ i ] = = ' \\ ' ) {
result [ i ] = ' / ' ;
@ -316,9 +379,11 @@ std::string GeneratedMessageFileName(const Descriptor* message,
return result + " .php " ;
}
std : : string GeneratedEnumFileName ( const EnumDescriptor * en ,
bool is_descriptor ) {
std : : string result = FullClassName ( en , is_descriptor ) ;
template < typename DescriptorType >
std : : string LegacyGeneratedClassFileName ( const DescriptorType * desc ,
bool is_descriptor ) {
std : : string result = LegacyFullClassName ( desc , is_descriptor ) ;
for ( int i = 0 ; i < result . size ( ) ; i + + ) {
if ( result [ i ] = = ' \\ ' ) {
result [ i ] = ' / ' ;
@ -461,10 +526,10 @@ std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor)
std : : string EnumOrMessageSuffix (
const FieldDescriptor * field , bool is_descriptor ) {
if ( field - > cpp_type ( ) = = FieldDescriptor : : CPPTYPE_MESSAGE ) {
return " , ' " + Message FullName( field - > message_type ( ) , is_descriptor ) + " ' " ;
return " , ' " + Descriptor FullName( field - > message_type ( ) , is_descriptor ) + " ' " ;
}
if ( field - > cpp_type ( ) = = FieldDescriptor : : CPPTYPE_ENUM ) {
return " , ' " + Enum FullName( field - > enum_type ( ) , is_descriptor ) + " ' " ;
return " , ' " + Descriptor FullName( field - > enum_type ( ) , is_descriptor ) + " ' " ;
}
return " " ;
}
@ -651,11 +716,11 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor,
} else if ( field - > cpp_type ( ) = = FieldDescriptor : : CPPTYPE_MESSAGE ) {
printer - > Print (
" GPBUtil::checkMessage($var, \\ ^class_name^::class); \n " ,
" class_name " , FullClassName ( field - > message_type ( ) , is_descriptor ) ) ;
" class_name " , Legacy FullClassName( field - > message_type ( ) , is_descriptor ) ) ;
} else if ( field - > cpp_type ( ) = = FieldDescriptor : : CPPTYPE_ENUM ) {
printer - > Print (
" GPBUtil::checkEnum($var, \\ ^class_name^::class); \n " ,
" class_name " , FullClassName ( field - > enum_type ( ) , is_descriptor ) ) ;
" class_name " , Legacy FullClassName( field - > enum_type ( ) , is_descriptor ) ) ;
} else if ( field - > cpp_type ( ) = = FieldDescriptor : : CPPTYPE_STRING ) {
printer - > Print (
" GPBUtil::checkString($var, ^utf8^); \n " ,
@ -711,7 +776,7 @@ void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) {
printer - > Print (
" $pool->addEnum('^name^', "
" \\ Google \\ Protobuf \\ Internal \\ ^class_name^::class) \n " ,
" name " , Enum FullName( en , true ) ,
" name " , Descriptor FullName( en , true ) ,
" class_name " , en - > name ( ) ) ;
Indent ( printer ) ;
@ -743,13 +808,13 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message,
if ( message - > options ( ) . map_entry ( ) ) {
return ;
}
string class_name = name_prefix . empty ( ) ?
message - > name ( ) : name_prefix + " _ " + message - > name ( ) ;
string class_name = ( name_prefix . empty ( ) ? " " : name_prefix + " \\ " ) +
ReservedNamePrefix ( message - > name ( ) , message - > file ( ) ) + message - > name ( ) ;
printer - > Print (
" $pool->addMessage('^message^', "
" \\ Google \\ Protobuf \\ Internal \\ ^class_name^::class) \n " ,
" message " , Message FullName( message , true ) ,
" message " , Descriptor FullName( message , true ) ,
" class_name " , class_name ) ;
Indent ( printer ) ;
@ -851,7 +916,7 @@ void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor,
continue ;
}
std : : string dependency_filename =
GeneratedMetadataFileName ( name , is_descriptor ) ;
GeneratedMetadataFileName ( file - > dependency ( i ) , is_descriptor ) ;
printer - > Print (
" \\ ^name^::initOnce(); \n " ,
" name " , FilenameToClassname ( dependency_filename ) ) ;
@ -945,7 +1010,7 @@ std::string FilenameToClassname(const string& filename) {
void GenerateMetadataFile ( const FileDescriptor * file ,
bool is_descriptor ,
GeneratorContext * generator_context ) {
std : : string filename = GeneratedMetadataFileName ( file - > name ( ) , is_descriptor ) ;
std : : string filename = GeneratedMetadataFileName ( file , is_descriptor ) ;
std : : unique_ptr < io : : ZeroCopyOutputStream > output (
generator_context - > Open ( filename ) ) ;
io : : Printer printer ( output . get ( ) , ' ^ ' ) ;
@ -955,11 +1020,11 @@ void GenerateMetadataFile(const FileDescriptor* file,
std : : string fullname = FilenameToClassname ( filename ) ;
int lastindex = fullname . find_last_of ( " \\ " ) ;
printer . Print (
" namespace ^name^; \n \n " ,
" name " , fullname . substr ( 0 , lastindex ) ) ;
if ( lastindex ! = string : : npos ) {
printer . Print (
" namespace ^name^; \n \n " ,
" name " , fullname . substr ( 0 , lastindex ) ) ;
printer . Print (
" class ^name^ \n "
" { \n " ,
@ -978,9 +1043,47 @@ void GenerateMetadataFile(const FileDescriptor* file,
printer . Print ( " } \n \n " ) ;
}
template < typename DescriptorType >
void LegacyGenerateClassFile ( const FileDescriptor * file , const DescriptorType * desc ,
bool is_descriptor ,
GeneratorContext * generator_context ) {
std : : string filename = LegacyGeneratedClassFileName ( desc , is_descriptor ) ;
std : : unique_ptr < io : : ZeroCopyOutputStream > output (
generator_context - > Open ( filename ) ) ;
io : : Printer printer ( output . get ( ) , ' ^ ' ) ;
GenerateHead ( file , & printer ) ;
std : : string php_namespace = RootPhpNamespace ( desc , is_descriptor ) ;
if ( php_namespace ! = " " ) {
printer . Print (
" namespace ^name^; \n \n " ,
" name " , php_namespace ) ;
}
std : : string newname = FullClassName ( desc , is_descriptor ) ;
printer . Print ( " if (false) { \n " ) ;
Indent ( & printer ) ;
printer . Print ( " /** \n " ) ;
printer . Print ( " * This class is deprecated. Use ^new^ instead. \n " ,
" new " , newname ) ;
printer . Print ( " * @deprecated \n " ) ;
printer . Print ( " */ \n " ) ;
printer . Print ( " class ^old^ {} \n " ,
" old " , LegacyGeneratedClassName ( desc ) ) ;
Outdent ( & printer ) ;
printer . Print ( " } \n " ) ;
printer . Print ( " class_exists(^new^::class); \n " ,
" new " , GeneratedClassName ( desc ) ) ;
printer . Print ( " @trigger_error('^old^ is deprecated and will be removed in "
" the next major release. Use ^fullname^ instead', E_USER_DEPRECATED); \n \n " ,
" old " , LegacyFullClassName ( desc , is_descriptor ) ,
" fullname " , newname ) ;
}
void GenerateEnumFile ( const FileDescriptor * file , const EnumDescriptor * en ,
bool is_descriptor , GeneratorContext * generator_context ) {
std : : string filename = GeneratedEnumFileName ( en , is_descriptor ) ;
std : : string filename = GeneratedClass FileName ( en , is_descriptor ) ;
std : : unique_ptr < io : : ZeroCopyOutputStream > output (
generator_context - > Open ( filename ) ) ;
io : : Printer printer ( output . get ( ) , ' ^ ' ) ;
@ -990,32 +1093,22 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
std : : string fullname = FilenameToClassname ( filename ) ;
int lastindex = fullname . find_last_of ( " \\ " ) ;
if ( file - > options ( ) . has_php_namespace ( ) ) {
const string & php_namespace = file - > options ( ) . php_namespace ( ) ;
if ( ! php_namespace . empty ( ) ) {
printer . Print (
" namespace ^name^; \n \n " ,
" name " , php_namespace ) ;
}
} else if ( ! file - > package ( ) . empty ( ) ) {
if ( lastindex ! = string : : npos ) {
printer . Print (
" namespace ^name^; \n \n " ,
" name " , fullname . substr ( 0 , lastindex ) ) ;
}
GenerateEnumDocComment ( & printer , en , is_descriptor ) ;
if ( lastindex ! = string : : npos ) {
printer . Print (
" class ^name^ \n "
" { \n " ,
" name " , fullname . substr ( lastindex + 1 ) ) ;
} else {
printer . Print (
" class ^name^ \n "
" { \n " ,
" name " , fullname ) ;
fullname = fullname . substr ( lastindex + 1 ) ;
}
GenerateEnumDocComment ( & printer , en , is_descriptor ) ;
printer . Print (
" class ^name^ \n "
" { \n " ,
" name " , fullname ) ;
Indent ( & printer ) ;
for ( int i = 0 ; i < en - > value_count ( ) ; i + + ) {
@ -1028,6 +1121,17 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
Outdent ( & printer ) ;
printer . Print ( " } \n \n " ) ;
// write legacy file for backwards compatiblity with nested messages and enums
if ( en - > containing_type ( ) ! = NULL ) {
printer . Print (
" // Adding a class alias for backwards compatibility with the previous class name. \n " ) ;
printer . Print (
" class_alias(^new^::class, \\ ^old^::class); \n \n " ,
" new " , fullname ,
" old " , LegacyFullClassName ( en , is_descriptor ) ) ;
LegacyGenerateClassFile ( file , en , is_descriptor , generator_context ) ;
}
}
void GenerateMessageFile ( const FileDescriptor * file , const Descriptor * message ,
@ -1039,7 +1143,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
return ;
}
std : : string filename = GeneratedMessage FileName ( message , is_descriptor ) ;
std : : string filename = GeneratedClass FileName ( message , is_descriptor ) ;
std : : unique_ptr < io : : ZeroCopyOutputStream > output (
generator_context - > Open ( filename ) ) ;
io : : Printer printer ( output . get ( ) , ' ^ ' ) ;
@ -1049,14 +1153,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
std : : string fullname = FilenameToClassname ( filename ) ;
int lastindex = fullname . find_last_of ( " \\ " ) ;
if ( file - > options ( ) . has_php_namespace ( ) ) {
const string & php_namespace = file - > options ( ) . php_namespace ( ) ;
if ( ! php_namespace . empty ( ) ) {
printer . Print (
" namespace ^name^; \n \n " ,
" name " , php_namespace ) ;
}
} else if ( ! file - > package ( ) . empty ( ) ) {
if ( lastindex ! = string : : npos ) {
printer . Print (
" namespace ^name^; \n \n " ,
" name " , fullname . substr ( 0 , lastindex ) ) ;
@ -1066,16 +1163,13 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
GenerateMessageDocComment ( & printer , message , is_descriptor ) ;
if ( lastindex ! = string : : npos ) {
printer . Print (
" class ^name^ extends \\ Google \\ Protobuf \\ Internal \\ Message \n "
" { \n " ,
" name " , fullname . substr ( lastindex + 1 ) ) ;
} else {
printer . Print (
" class ^name^ extends \\ Google \\ Protobuf \\ Internal \\ Message \n "
" { \n " ,
" name " , fullname ) ;
fullname = fullname . substr ( lastindex + 1 ) ;
}
printer . Print (
" class ^name^ extends \\ Google \\ Protobuf \\ Internal \\ Message \n "
" { \n " ,
" name " , fullname ) ;
Indent ( & printer ) ;
// Field and oneof definitions.
@ -1089,16 +1183,17 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
}
printer . Print ( " \n " ) ;
GenerateMessageConstructorDocComment ( & printer , message , is_descriptor ) ;
printer . Print (
" public function __construct() { \n " ) ;
" public function __construct($data = NULL ) { \n " ) ;
Indent ( & printer ) ;
std : : string metadata_filename =
GeneratedMetadataFileName ( file - > name ( ) , is_descriptor ) ;
GeneratedMetadataFileName ( file , is_descriptor ) ;
std : : string metadata_fullname = FilenameToClassname ( metadata_filename ) ;
printer . Print (
" \\ ^fullname^::initOnce(); \n "
" parent::__construct(); \n " ,
" parent::__construct($data ); \n " ,
" fullname " , metadata_fullname ) ;
Outdent ( & printer ) ;
@ -1126,6 +1221,17 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
Outdent ( & printer ) ;
printer . Print ( " } \n \n " ) ;
// write legacy file for backwards compatiblity with nested messages and enums
if ( message - > containing_type ( ) ! = NULL ) {
printer . Print (
" // Adding a class alias for backwards compatibility with the previous class name. \n " ) ;
printer . Print (
" class_alias(^new^::class, \\ ^old^::class); \n \n " ,
" new " , fullname ,
" old " , LegacyFullClassName ( message , is_descriptor ) ) ;
LegacyGenerateClassFile ( file , message , is_descriptor , generator_context ) ;
}
// Nested messages and enums.
for ( int i = 0 ; i < message - > nested_type_count ( ) ; i + + ) {
GenerateMessageFile ( file , message - > nested_type ( i ) , is_descriptor ,
@ -1150,14 +1256,9 @@ void GenerateServiceFile(const FileDescriptor* file,
std : : string fullname = FilenameToClassname ( filename ) ;
int lastindex = fullname . find_last_of ( " \\ " ) ;
if ( file - > options ( ) . has_php_namespace ( ) ) {
const string & php_namespace = file - > options ( ) . php_namespace ( ) ;
if ( ! php_namespace . empty ( ) ) {
printer . Print (
" namespace ^name^; \n \n " ,
" name " , php_namespace ) ;
}
} else if ( ! file - > package ( ) . empty ( ) ) {
if ( ! file - > options ( ) . php_namespace ( ) . empty ( ) | |
( ! file - > options ( ) . has_php_namespace ( ) & & ! file - > package ( ) . empty ( ) ) | |
lastindex ! = string : : npos ) {
printer . Print (
" namespace ^name^; \n \n " ,
" name " , fullname . substr ( 0 , lastindex ) ) ;
@ -1251,7 +1352,8 @@ static string EscapePhpdoc(const string& input) {
}
static void GenerateDocCommentBodyForLocation (
io : : Printer * printer , const SourceLocation & location ) {
io : : Printer * printer , const SourceLocation & location , bool trailingNewline ,
int indentCount ) {
string comments = location . leading_comments . empty ( ) ?
location . trailing_comments : location . leading_comments ;
if ( ! comments . empty ( ) ) {
@ -1272,14 +1374,16 @@ static void GenerateDocCommentBodyForLocation(
// Most lines should start with a space. Watch out for lines that start
// with a /, since putting that right after the leading asterisk will
// close the comment.
if ( ! lines [ i ] . empty ( ) & & lines [ i ] [ 0 ] = = ' / ' ) {
if ( indentCount = = 0 & & ! lines [ i ] . empty ( ) & & lines [ i ] [ 0 ] = = ' / ' ) {
printer - > Print ( " * ^line^ \n " , " line " , lines [ i ] ) ;
} else {
printer - > Print ( " *^line^ \n " , " line " , lines [ i ] ) ;
std : : string indent = std : : string ( indentCount , ' ' ) ;
printer - > Print ( " *^ind^^line^ \n " , " ind " , indent , " line " , lines [ i ] ) ;
}
}
printer - > Print (
" * \n " ) ;
if ( trailingNewline ) {
printer - > Print ( " * \n " ) ;
}
}
}
@ -1288,7 +1392,7 @@ static void GenerateDocCommentBody(
io : : Printer * printer , const DescriptorType * descriptor ) {
SourceLocation location ;
if ( descriptor - > GetSourceLocation ( & location ) ) {
GenerateDocCommentBodyForLocation ( printer , location ) ;
GenerateDocCommentBodyForLocation ( printer , location , true , 0 ) ;
}
}
@ -1310,10 +1414,41 @@ void GenerateMessageDocComment(io::Printer* printer,
printer - > Print (
" * Generated from protobuf message <code>^messagename^</code> \n "
" */ \n " ,
" fullname " , EscapePhpdoc ( Php Name( message - > full_name ( ) , is_descriptor ) ) ,
" fullname " , EscapePhpdoc ( FullClass Name( message , is_descriptor ) ) ,
" messagename " , EscapePhpdoc ( message - > full_name ( ) ) ) ;
}
void GenerateMessageConstructorDocComment ( io : : Printer * printer ,
const Descriptor * message ,
int is_descriptor ) {
// In theory we should have slightly different comments for setters, getters,
// etc., but in practice everyone already knows the difference between these
// so it's redundant information.
// We start the comment with the main body based on the comments from the
// .proto file (if present). We then end with the field declaration, e.g.:
// optional string foo = 5;
// If the field is a group, the debug string might end with {.
printer - > Print ( " /** \n " ) ;
printer - > Print ( " * Constructor. \n " ) ;
printer - > Print ( " * \n " ) ;
printer - > Print ( " * @param array $data { \n " ) ;
printer - > Print ( " * Optional. Data for populating the Message object. \n " ) ;
printer - > Print ( " * \n " ) ;
for ( int i = 0 ; i < message - > field_count ( ) ; i + + ) {
const FieldDescriptor * field = message - > field ( i ) ;
printer - > Print ( " * @type ^php_type^ $^var^ \n " ,
" php_type " , PhpSetterTypeName ( field , is_descriptor ) ,
" var " , field - > name ( ) ) ;
SourceLocation location ;
if ( field - > GetSourceLocation ( & location ) ) {
GenerateDocCommentBodyForLocation ( printer , location , false , 10 ) ;
}
}
printer - > Print ( " * } \n " ) ;
printer - > Print ( " */ \n " ) ;
}
void GenerateServiceDocComment ( io : : Printer * printer ,
const ServiceDescriptor * service ) {
printer - > Print ( " /** \n " ) ;
@ -1355,9 +1490,9 @@ void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
printer - > Print ( " /** \n " ) ;
GenerateDocCommentBody ( printer , enum_ ) ;
printer - > Print (
" * Protobuf enum <code>^fullname^</code> \n "
" * Protobuf typ e <code>^fullname^</code> \n "
" */ \n " ,
" fullname " , EscapePhpdoc ( PhpName ( enum_ - > full_name ( ) , is_descriptor ) ) ) ;
" fullname " , EscapePhpdoc ( enum_ - > full_name ( ) ) ) ;
}
void GenerateEnumValueDocComment ( io : : Printer * printer ,
@ -1410,31 +1545,6 @@ bool Generator::Generate(const FileDescriptor* file, const string& parameter,
return true ;
}
std : : string GeneratedClassName ( const Descriptor * desc ) {
std : : string classname = desc - > name ( ) ;
const Descriptor * containing = desc - > containing_type ( ) ;
while ( containing ! = NULL ) {
classname = containing - > name ( ) + ' _ ' + classname ;
containing = containing - > containing_type ( ) ;
}
return ClassNamePrefix ( classname , desc ) + classname ;
}
std : : string GeneratedClassName ( const EnumDescriptor * desc ) {
std : : string classname = desc - > name ( ) ;
const Descriptor * containing = desc - > containing_type ( ) ;
while ( containing ! = NULL ) {
classname = containing - > name ( ) + ' _ ' + classname ;
containing = containing - > containing_type ( ) ;
}
return ClassNamePrefix ( classname , desc ) + classname ;
}
std : : string GeneratedClassName ( const ServiceDescriptor * desc ) {
std : : string classname = desc - > name ( ) ;
return ClassNamePrefix ( classname , desc ) + classname ;
}
} // namespace php
} // namespace compiler
} // namespace protobuf