Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
4c57e847
Commit
4c57e847
authored
Apr 20, 2017
by
Paul Yang
Committed by
GitHub
Apr 20, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prepend "PB" to generated classes whose name are reserved words. (#2990)
parent
b97cd573
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
160 additions
and
58 deletions
+160
-58
def.c
php/ext/google/protobuf/def.c
+80
-43
Message.php
php/src/Google/Protobuf/Internal/Message.php
+1
-0
descriptor.php
php/src/Google/Protobuf/descriptor.php
+25
-9
generated_class_test.php
php/tests/generated_class_test.php
+11
-0
memory_leak_test.php
php/tests/memory_leak_test.php
+3
-0
test.proto
php/tests/proto/test.proto
+10
-0
test_prefix.proto
php/tests/proto/test_prefix.proto
+5
-0
php_generator.cc
src/google/protobuf/compiler/php/php_generator.cc
+25
-6
No files found.
php/ext/google/protobuf/def.c
View file @
4c57e847
...
...
@@ -30,6 +30,9 @@
#include "protobuf.h"
const
char
*
const
kReservedNames
[]
=
{
"Empty"
};
const
int
kReservedNamesSize
=
1
;
// Forward declare.
static
void
descriptor_init_c_instance
(
Descriptor
*
intern
TSRMLS_DC
);
static
void
descriptor_free_c
(
Descriptor
*
object
TSRMLS_DC
);
...
...
@@ -355,58 +358,90 @@ PHP_METHOD(DescriptorPool, getGeneratedPool) {
#endif
}
static
void
convert_to_class_name_inplace
(
char
*
class_name
,
const
char
*
fullname
,
const
char
*
prefix
,
const
char
*
package_name
)
{
static
void
classname_no_prefix
(
const
char
*
fullname
,
const
char
*
package_name
,
char
*
class_name
)
{
size_t
i
=
0
,
j
;
bool
first_char
=
true
;
bool
first_char
=
true
,
is_reserved
=
false
;
size_t
pkg_name_len
=
package_name
==
NULL
?
0
:
strlen
(
package_name
);
size_t
prefix_len
=
prefix
==
NULL
?
0
:
strlen
(
prefix
);
size_t
message_name_start
=
package_name
==
NULL
?
0
:
pkg_name_len
+
1
;
size_t
message_len
=
(
strlen
(
fullname
)
-
message_name_start
);
// In php, class name cannot be Empty.
if
(
strcmp
(
"google.protobuf.Empty"
,
fullname
)
==
0
)
{
strcpy
(
class_name
,
"
\\
Google
\\
Protobuf
\\
GPBEmpty"
);
return
;
// Submessage is concatenated with its containing messages by '_'.
for
(
j
=
message_name_start
;
j
<
message_name_start
+
message_len
;
j
++
)
{
if
(
fullname
[
j
]
==
'.'
)
{
class_name
[
i
++
]
=
'_'
;
}
else
{
class_name
[
i
++
]
=
fullname
[
j
];
}
}
}
static
const
char
*
classname_prefix
(
const
char
*
classname
,
const
char
*
prefix_given
,
const
char
*
package_name
)
{
size_t
i
;
bool
is_reserved
=
false
;
if
(
prefix_given
!=
NULL
&&
strcmp
(
prefix_given
,
""
)
!=
0
)
{
return
prefix_given
;
}
for
(
i
=
0
;
i
<
kReservedNamesSize
;
i
++
)
{
if
(
strcmp
(
kReservedNames
[
i
],
classname
)
==
0
)
{
is_reserved
=
true
;
break
;
}
}
if
(
is_reserved
)
{
if
(
package_name
!=
NULL
&&
strcmp
(
"google.protobuf"
,
package_name
)
==
0
)
{
return
"GPB"
;
}
else
{
return
"PB"
;
}
}
return
""
;
}
static
void
convert_to_class_name_inplace
(
const
char
*
package
,
const
char
*
prefix
,
char
*
classname
)
{
size_t
package_len
=
package
==
NULL
?
0
:
strlen
(
package
);
size_t
prefix_len
=
prefix
==
NULL
?
0
:
strlen
(
prefix
);
size_t
classname_len
=
strlen
(
classname
);
int
i
=
0
,
j
;
bool
first_char
=
true
;
int
offset
=
package_len
!=
0
?
2
:
0
;
for
(
j
=
0
;
j
<
classname_len
;
j
++
)
{
classname
[
package_len
+
prefix_len
+
classname_len
+
offset
-
1
-
j
]
=
classname
[
classname_len
-
j
-
1
];
}
if
(
p
kg_nam
e_len
!=
0
)
{
class
_
name
[
i
++
]
=
'\\'
;
for
(
j
=
0
;
j
<
p
kg_nam
e_len
;
j
++
)
{
if
(
p
ackag
e_len
!=
0
)
{
classname
[
i
++
]
=
'\\'
;
for
(
j
=
0
;
j
<
p
ackag
e_len
;
j
++
)
{
// php packages are divided by '\'.
if
(
package
_name
[
j
]
==
'.'
)
{
class
_
name
[
i
++
]
=
'\\'
;
if
(
package
[
j
]
==
'.'
)
{
classname
[
i
++
]
=
'\\'
;
first_char
=
true
;
}
else
if
(
first_char
)
{
// PHP package uses camel case.
if
(
package
_name
[
j
]
<
'A'
||
package_nam
e
[
j
]
>
'Z'
)
{
class
_name
[
i
++
]
=
package_nam
e
[
j
]
+
'A'
-
'a'
;
if
(
package
[
j
]
<
'A'
||
packag
e
[
j
]
>
'Z'
)
{
class
name
[
i
++
]
=
packag
e
[
j
]
+
'A'
-
'a'
;
}
else
{
class
_name
[
i
++
]
=
package_nam
e
[
j
];
class
name
[
i
++
]
=
packag
e
[
j
];
}
first_char
=
false
;
}
else
{
class
_name
[
i
++
]
=
package_nam
e
[
j
];
class
name
[
i
++
]
=
packag
e
[
j
];
}
}
class
_
name
[
i
++
]
=
'\\'
;
classname
[
i
++
]
=
'\\'
;
}
if
(
prefix_len
>
0
)
{
strcpy
(
class_name
+
i
,
prefix
);
i
+=
prefix_len
;
}
// Submessage is concatenated with its containing messages by '_'.
for
(
j
=
message_name_start
;
j
<
message_name_start
+
message_len
;
j
++
)
{
if
(
fullname
[
j
]
==
'.'
)
{
class_name
[
i
++
]
=
'_'
;
}
else
{
class_name
[
i
++
]
=
fullname
[
j
];
}
}
memcpy
(
classname
+
i
,
prefix
,
prefix_len
);
}
PHP_METHOD
(
DescriptorPool
,
internalAddGeneratedFile
)
{
...
...
@@ -455,25 +490,27 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) {
* bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if \
* given message is google.protobuf.Empty.*/
\
const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \
const char *prefix
= upb_filedef_phpprefix(files[0]);
\
size_t
klass_name_len = strlen(fullname) + 5;
\
if (prefix
!= NULL) {
\
klass_name_len += strlen(prefix);
\
const char *prefix
_given = upb_filedef_phpprefix(files[0]);
\
size_t
classname_len = strlen(fullname) + 5;
\
if (prefix
_given != NULL) {
\
classname_len += strlen(prefix_given);
\
} \
char *klass_name = ecalloc(sizeof(char), klass_name_len); \
convert_to_class_name_inplace(klass_name, fullname, prefix, \
upb_filedef_package(files[0])); \
char *classname = ecalloc(sizeof(char), classname_len); \
const char *package = upb_filedef_package(files[0]); \
classname_no_prefix(fullname, package, classname); \
const char *prefix = classname_prefix(classname, prefix_given, package); \
convert_to_class_name_inplace(package, prefix, classname); \
PHP_PROTO_CE_DECLARE pce; \
if (php_proto_zend_lookup_class(
klass_name, strlen(klass_name), &pce) ==
\
if (php_proto_zend_lookup_class(
classname, strlen(classname), &pce) ==
\
FAILURE) { \
zend_error(E_ERROR, "Generated message class %s hasn't been defined", \
klass_name);
\
classname);
\
return; \
} else { \
desc->klass = PHP_PROTO_CE_UNREF(pce); \
} \
add_ce_obj(desc->klass, desc_php); \
efree(
klass_name);
\
efree(
classname);
\
break; \
}
...
...
php/src/Google/Protobuf/Internal/Message.php
View file @
4c57e847
...
...
@@ -71,6 +71,7 @@ class Message
return
;
}
$pool
=
DescriptorPool
::
getGeneratedPool
();
var_dump
(
get_class
(
$this
));
$this
->
desc
=
$pool
->
getDescriptorByClassName
(
get_class
(
$this
));
foreach
(
$this
->
desc
->
getField
()
as
$field
)
{
$setter
=
$field
->
getSetter
();
...
...
php/src/Google/Protobuf/descriptor.php
View file @
4c57e847
...
...
@@ -220,20 +220,36 @@ class Descriptor
}
}
function
getClassName
WithoutPackage
(
$name
,
function
getClassName
Prefix
(
$
class
name
,
$file_proto
)
{
if
(
$name
===
"Empty"
&&
$file_proto
->
getPackage
()
===
"google.protobuf"
)
{
return
"GPBEmpty"
;
}
else
{
$option
=
$file_proto
->
getOptions
();
$prefix
=
is_null
(
$option
)
?
""
:
$option
->
getPhpClassPrefix
();
// Nested message class names are seperated by '_', and package names
// are seperated by '\'.
return
$prefix
.
implode
(
'_'
,
array_map
(
'ucwords'
,
explode
(
'.'
,
$name
)));
if
(
$prefix
!==
""
)
{
return
$prefix
;
}
$reserved_words
=
array
(
"Empty"
);
foreach
(
$reserved_words
as
$reserved_word
)
{
if
(
$classname
===
$reserved_word
)
{
if
(
$file_proto
->
getPackage
()
===
"google.protobuf"
)
{
return
"GPB"
;
}
else
{
return
"PB"
;
}
}
}
return
""
;
}
function
getClassNameWithoutPackage
(
$name
,
$file_proto
)
{
$classname
=
implode
(
'_'
,
array_map
(
'ucwords'
,
explode
(
'.'
,
$name
)));
return
getClassNamePrefix
(
$classname
,
$file_proto
)
.
$classname
;
}
function
getFullClassName
(
...
...
php/tests/generated_class_test.php
View file @
4c57e847
...
...
@@ -865,4 +865,15 @@ class GeneratedClassTest extends TestBase
$m
->
setPrefixMessage
(
$n
);
$this
->
assertSame
(
1
,
$m
->
getPrefixMessage
()
->
getA
());
}
#########################################################
# Test prefix for reserved words.
#########################################################
public
function
testPrefixForReservedWords
()
{
$m
=
new
\Foo\TestMessage_Empty
();
$m
=
new
\Foo\PBEmpty
();
$m
=
new
\PrefixEmpty
();
}
}
php/tests/memory_leak_test.php
View file @
4c57e847
...
...
@@ -5,11 +5,14 @@
require_once
(
'generated/NoNamespaceEnum.php'
);
require_once
(
'generated/NoNamespaceMessage.php'
);
require_once
(
'generated/NoNamespaceMessage_NestedEnum.php'
);
require_once
(
'generated/PrefixEmpty.php'
);
require_once
(
'generated/PrefixTestPrefix.php'
);
require_once
(
'generated/Bar/TestInclude.php'
);
require_once
(
'generated/Foo/PBEmpty.php'
);
require_once
(
'generated/Foo/TestEnum.php'
);
require_once
(
'generated/Foo/TestIncludePrefixMessage.php'
);
require_once
(
'generated/Foo/TestMessage.php'
);
require_once
(
'generated/Foo/TestMessage_Empty.php'
);
require_once
(
'generated/Foo/TestMessage_NestedEnum.php'
);
require_once
(
'generated/Foo/TestMessage_Sub.php'
);
require_once
(
'generated/Foo/TestPackedMessage.php'
);
...
...
php/tests/proto/test.proto
View file @
4c57e847
...
...
@@ -108,6 +108,11 @@ message TestMessage {
}
NestedEnum
optional_nested_enum
=
101
;
// Test prefix for reserved words.
message
Empty
{
int32
a
=
1
;
}
}
enum
TestEnum
{
...
...
@@ -116,6 +121,11 @@ enum TestEnum {
TWO
=
2
;
}
// Test prefix for reserved words.
message
Empty
{
int32
a
=
1
;
}
message
TestPackedMessage
{
repeated
int32
repeated_int32
=
90
[
packed
=
true
];
repeated
int64
repeated_int64
=
91
[
packed
=
true
];
...
...
php/tests/proto/test_prefix.proto
View file @
4c57e847
...
...
@@ -5,3 +5,8 @@ option php_class_prefix = "Prefix";
message
TestPrefix
{
int32
a
=
1
;
}
// Test prefix for reserved words.
message
Empty
{
int32
a
=
1
;
}
src/google/protobuf/compiler/php/php_generator.cc
View file @
4c57e847
...
...
@@ -49,6 +49,8 @@ const std::string kDescriptorMetadataFile =
"GPBMetadata/Google/Protobuf/Internal/Descriptor.php"
;
const
std
::
string
kDescriptorDirName
=
"Google/Protobuf/Internal"
;
const
std
::
string
kDescriptorPackageName
=
"Google
\\
Protobuf
\\
Internal"
;
const
char
*
const
kReservedNames
[]
=
{
"Empty"
};
const
int
kReservedNamesSize
=
1
;
namespace
google
{
namespace
protobuf
{
...
...
@@ -105,14 +107,31 @@ std::string EnumFullName(const EnumDescriptor* envm, bool is_descriptor) {
}
template
<
typename
DescriptorType
>
std
::
string
ClassNamePrefix
(
const
DescriptorType
*
desc
)
{
// Empty cannot be php class name.
if
(
desc
->
name
()
==
"Empty"
&&
desc
->
file
()
->
package
()
==
"google.protobuf"
)
{
std
::
string
ClassNamePrefix
(
const
string
&
classname
,
const
DescriptorType
*
desc
)
{
const
string
&
prefix
=
(
desc
->
file
()
->
options
()).
php_class_prefix
();
if
(
prefix
!=
""
)
{
return
prefix
;
}
bool
is_reserved
=
false
;
for
(
int
i
=
0
;
i
<
kReservedNamesSize
;
i
++
)
{
if
(
classname
==
kReservedNames
[
i
])
{
is_reserved
=
true
;
break
;
}
}
if
(
is_reserved
)
{
if
(
desc
->
file
()
->
package
()
==
"google.protobuf"
)
{
return
"GPB"
;
}
else
{
return
(
desc
->
file
()
->
options
()).
php_class_prefix
();
return
"PB"
;
}
}
return
""
;
}
...
...
@@ -124,7 +143,7 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
classname
=
containing
->
name
()
+
'_'
+
classname
;
containing
=
containing
->
containing_type
();
}
classname
=
ClassNamePrefix
(
desc
)
+
classname
;
classname
=
ClassNamePrefix
(
classname
,
desc
)
+
classname
;
if
(
desc
->
file
()
->
package
()
==
""
)
{
return
classname
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment