Merge branch 'master' into 3.4.x
This commit is contained in:
commit
8f4b8e430a
11
Makefile.am
11
Makefile.am
@ -600,6 +600,12 @@ php_EXTRA_DIST= \
|
||||
php/ext/google/protobuf/upb.c \
|
||||
php/ext/google/protobuf/protobuf.c \
|
||||
php/src/phpdoc.dist.xml \
|
||||
php/src/Google/Protobuf/Descriptor.php \
|
||||
php/src/Google/Protobuf/DescriptorPool.php \
|
||||
php/src/Google/Protobuf/EnumDescriptor.php \
|
||||
php/src/Google/Protobuf/EnumValueDescriptor.php \
|
||||
php/src/Google/Protobuf/FieldDescriptor.php \
|
||||
php/src/Google/Protobuf/OneofDescriptor.php \
|
||||
php/src/Google/Protobuf/Internal/CodedInputStream.php \
|
||||
php/src/Google/Protobuf/Internal/CodedOutputStream.php \
|
||||
php/src/Google/Protobuf/Internal/DescriptorPool.php \
|
||||
@ -612,7 +618,6 @@ php_EXTRA_DIST= \
|
||||
php/src/Google/Protobuf/Internal/EnumDescriptorProto.php \
|
||||
php/src/Google/Protobuf/Internal/EnumOptions.php \
|
||||
php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php \
|
||||
php/src/Google/Protobuf/Internal/EnumValueDescriptor.php \
|
||||
php/src/Google/Protobuf/Internal/EnumValueOptions.php \
|
||||
php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php \
|
||||
php/src/Google/Protobuf/Internal/FieldDescriptorProto.php \
|
||||
@ -628,6 +633,7 @@ php_EXTRA_DIST= \
|
||||
php/src/Google/Protobuf/Internal/FileOptions.php \
|
||||
php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php \
|
||||
php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php \
|
||||
php/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php \
|
||||
php/src/Google/Protobuf/Internal/GPBDecodeException.php \
|
||||
php/src/Google/Protobuf/Internal/GPBJsonWire.php \
|
||||
php/src/Google/Protobuf/Internal/GPBLabel.php \
|
||||
@ -635,6 +641,7 @@ php_EXTRA_DIST= \
|
||||
php/src/Google/Protobuf/Internal/GPBUtil.php \
|
||||
php/src/Google/Protobuf/Internal/GPBWireType.php \
|
||||
php/src/Google/Protobuf/Internal/GPBWire.php \
|
||||
php/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php \
|
||||
php/src/Google/Protobuf/Internal/MapEntry.php \
|
||||
php/src/Google/Protobuf/Internal/MapFieldIter.php \
|
||||
php/src/Google/Protobuf/Internal/MapField.php \
|
||||
@ -661,6 +668,7 @@ php_EXTRA_DIST= \
|
||||
php/tests/array_test.php \
|
||||
php/tests/autoload.php \
|
||||
php/tests/compatibility_test.sh \
|
||||
php/tests/descriptors_test.php \
|
||||
php/tests/encode_decode_test.php \
|
||||
php/tests/gdb_test.sh \
|
||||
php/tests/generated_class_test.php \
|
||||
@ -669,6 +677,7 @@ php_EXTRA_DIST= \
|
||||
php/tests/map_field_test.php \
|
||||
php/tests/memory_leak_test.php \
|
||||
php/tests/php_implementation_test.php \
|
||||
php/tests/proto/test_descriptors.proto \
|
||||
php/tests/proto/test_empty_php_namespace.proto \
|
||||
php/tests/proto/test_import_descriptor_proto.proto \
|
||||
php/tests/proto/test_include.proto \
|
||||
|
@ -16,8 +16,8 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Google\\Protobuf\\Internal\\": "php/src/Google/Protobuf/Internal",
|
||||
"GPBMetadata\\Google\\Protobuf\\Internal\\": "php/src/GPBMetadata/Google/Protobuf/Internal"
|
||||
"Google\\Protobuf\\": "php/src/Google/Protobuf",
|
||||
"GPBMetadata\\Google\\Protobuf\\": "php/src/GPBMetadata/Google/Protobuf"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
conformance_protoc_inputs = \
|
||||
conformance.proto \
|
||||
$(top_srcdir)/src/google/protobuf/test_messages_proto3.proto
|
||||
|
||||
# proto2 input files, should be separated with proto3, as we
|
||||
# can't generate proto2 files for ruby, php and objc
|
||||
$(top_srcdir)/src/google/protobuf/test_messages_proto3.proto
|
||||
|
||||
# proto2 input files, should be separated with proto3, as we
|
||||
# can't generate proto2 files for ruby, php and objc
|
||||
conformance_proto2_protoc_inputs = \
|
||||
$(top_srcdir)/src/google/protobuf/test_messages_proto2.proto
|
||||
$(top_srcdir)/src/google/protobuf/test_messages_proto2.proto
|
||||
|
||||
well_known_type_protoc_inputs = \
|
||||
$(top_srcdir)/src/google/protobuf/any.proto \
|
||||
@ -86,6 +86,8 @@ other_language_protoc_outputs = \
|
||||
google/protobuf/struct.pb.h \
|
||||
google/protobuf/struct.rb \
|
||||
google/protobuf/struct_pb2.py \
|
||||
google/protobuf/TestMessagesProto2.pbobjc.h \
|
||||
google/protobuf/TestMessagesProto2.pbobjc.m \
|
||||
google/protobuf/TestMessagesProto3.pbobjc.h \
|
||||
google/protobuf/TestMessagesProto3.pbobjc.m \
|
||||
google/protobuf/test_messages_proto3.pb.cc \
|
||||
@ -228,7 +230,7 @@ if OBJC_CONFORMANCE_TEST
|
||||
bin_PROGRAMS += conformance-objc
|
||||
|
||||
conformance_objc_SOURCES = conformance_objc.m ../objectivec/GPBProtocolBuffers.m
|
||||
nodist_conformance_objc_SOURCES = Conformance.pbobjc.m google/protobuf/TestMessagesProto3.pbobjc.m
|
||||
nodist_conformance_objc_SOURCES = Conformance.pbobjc.m google/protobuf/TestMessagesProto2.pbobjc.m google/protobuf/TestMessagesProto3.pbobjc.m
|
||||
# On travis, the build fails without the isysroot because whatever system
|
||||
# headers are being found don't include generics support for
|
||||
# NSArray/NSDictionary, the only guess is their image at one time had an odd
|
||||
@ -237,7 +239,7 @@ conformance_objc_CPPFLAGS = -I$(top_srcdir)/objectivec -isysroot `xcrun --sdk ma
|
||||
conformance_objc_LDFLAGS = -framework Foundation
|
||||
# Explicit dep beacuse BUILT_SOURCES are only done before a "make all/check"
|
||||
# so a direct "make test_objc" could fail if parallel enough.
|
||||
conformance_objc-conformance_objc.$(OBJEXT): Conformance.pbobjc.h google/protobuf/TestMessagesProto3.pbobjc.h
|
||||
conformance_objc-conformance_objc.$(OBJEXT): Conformance.pbobjc.h google/protobuf/TestMessagesProto2.pbobjc.h google/protobuf/TestMessagesProto3.pbobjc.h
|
||||
|
||||
endif
|
||||
|
||||
@ -253,7 +255,7 @@ if USE_EXTERNAL_PROTOC
|
||||
# Some implementations include pre-generated versions of well-known types.
|
||||
protoc_middleman: $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:. $(conformance_protoc_inputs)
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --python_out=. --js_out=import_style=commonjs,binary:. $(conformance_proto2_protoc_inputs)
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --objc_out=. --python_out=. --js_out=import_style=commonjs,binary:. $(conformance_proto2_protoc_inputs)
|
||||
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:google-protobuf $(well_known_type_protoc_inputs)
|
||||
## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
|
||||
touch protoc_middleman
|
||||
@ -265,7 +267,7 @@ else
|
||||
# building out-of-tree.
|
||||
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_protoc_inputs) )
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_proto2_protoc_inputs) )
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --objc_out=. --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_proto2_protoc_inputs) )
|
||||
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd/google-protobuf $(well_known_type_protoc_inputs) )
|
||||
## @mkdir -p lite
|
||||
## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )
|
||||
|
@ -78,7 +78,9 @@ message ConformanceRequest {
|
||||
// Which format should the testee serialize its message to?
|
||||
WireFormat requested_output_format = 3;
|
||||
|
||||
// should be set to either "proto2" or "proto3"
|
||||
// The full name for the test message to use; for the moment, either:
|
||||
// protobuf_test_messages.proto3.TestAllTypesProto3 or
|
||||
// protobuf_test_messages.proto2.TestAllTypesProto2.
|
||||
string message_type = 4;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "Conformance.pbobjc.h"
|
||||
#import "google/protobuf/TestMessagesProto2.pbobjc.h"
|
||||
#import "google/protobuf/TestMessagesProto3.pbobjc.h"
|
||||
|
||||
static void Die(NSString *format, ...) __dead2;
|
||||
@ -63,7 +64,7 @@ static NSData *CheckedReadDataOfLength(NSFileHandle *handle, NSUInteger numBytes
|
||||
|
||||
static ConformanceResponse *DoTest(ConformanceRequest *request) {
|
||||
ConformanceResponse *response = [ConformanceResponse message];
|
||||
TestAllTypesProto3 *testMessage = nil;
|
||||
GPBMessage *testMessage = nil;
|
||||
|
||||
switch (request.payloadOneOfCase) {
|
||||
case ConformanceRequest_Payload_OneOfCase_GPBUnsetOneOfCase:
|
||||
@ -71,20 +72,19 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) {
|
||||
break;
|
||||
|
||||
case ConformanceRequest_Payload_OneOfCase_ProtobufPayload: {
|
||||
if ([request.messageType isEqualToString:@"protobuf_test_messages.proto3.TestAllTypesProto3"]) {
|
||||
NSError *error = nil;
|
||||
testMessage = [TestAllTypesProto3 parseFromData:request.protobufPayload
|
||||
error:&error];
|
||||
if (!testMessage) {
|
||||
response.parseError =
|
||||
[NSString stringWithFormat:@"Parse error: %@", error];
|
||||
}
|
||||
} else if ([request.messageType isEqualToString:@"protobuf_test_messages.proto2.TestAllTypesProto2"]) {
|
||||
response.skipped = @"ObjC doesn't support proto2";
|
||||
break;
|
||||
Class msgClass = nil;
|
||||
if ([request.messageType isEqual:@"protobuf_test_messages.proto3.TestAllTypesProto3"]) {
|
||||
msgClass = [Proto3TestAllTypesProto3 class];
|
||||
} else if ([request.messageType isEqual:@"protobuf_test_messages.proto2.TestAllTypesProto2"]) {
|
||||
msgClass = [TestAllTypesProto2 class];
|
||||
} else {
|
||||
Die(@"Protobuf request doesn't have specific payload type");
|
||||
break;
|
||||
Die(@"Protobuf request had an unknown message_type: %@", request.messageType);
|
||||
}
|
||||
NSError *error = nil;
|
||||
testMessage = [msgClass parseFromData:request.protobufPayload error:&error];
|
||||
if (!testMessage) {
|
||||
response.parseError =
|
||||
[NSString stringWithFormat:@"Parse error: %@", error];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -142,7 +142,9 @@ namespace Conformance {
|
||||
public const int MessageTypeFieldNumber = 4;
|
||||
private string messageType_ = "";
|
||||
/// <summary>
|
||||
/// should be set to either "proto2" or "proto3"
|
||||
/// The full name for the test message to use; for the moment, either:
|
||||
/// protobuf_test_messages.proto3.TestAllTypesProto3 or
|
||||
/// protobuf_test_messages.proto2.TestAllTypesProto2.
|
||||
/// </summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public string MessageType {
|
||||
|
@ -198,9 +198,9 @@ namespace ProtobufTestMessages.Proto3 {
|
||||
"AjgBIjkKCk5lc3RlZEVudW0SBwoDRk9PEAASBwoDQkFSEAESBwoDQkFaEAIS",
|
||||
"EAoDTkVHEP///////////wFCDQoLb25lb2ZfZmllbGQiGwoORm9yZWlnbk1l",
|
||||
"c3NhZ2USCQoBYxgBIAEoBSpACgtGb3JlaWduRW51bRIPCgtGT1JFSUdOX0ZP",
|
||||
"TxAAEg8KC0ZPUkVJR05fQkFSEAESDwoLRk9SRUlHTl9CQVoQAkIvCihjb20u",
|
||||
"Z29vZ2xlLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8zSAH4AQFiBnBy",
|
||||
"b3RvMw=="));
|
||||
"TxAAEg8KC0ZPUkVJR05fQkFSEAESDwoLRk9SRUlHTl9CQVoQAkI4Cihjb20u",
|
||||
"Z29vZ2xlLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8zSAH4AQGiAgZQ",
|
||||
"cm90bzNiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, },
|
||||
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto3.ForeignEnum), }, new pbr::GeneratedClrTypeInfo[] {
|
||||
|
@ -156,3 +156,4 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d
|
||||
* [Linter for .proto files](https://github.com/ckaznocha/protoc-gen-lint)
|
||||
* [Protocol Buffers Dynamic Schema - create protobuf schemas programmatically (Java)] (https://github.com/os72/protobuf-dynamic)
|
||||
* [Make protoc plugins in NodeJS](https://github.com/konsumer/node-protoc-plugin)
|
||||
* [ProfaneDB - A Protocol Buffers database](https://profanedb.gitlab.io)
|
||||
|
@ -51,7 +51,7 @@ list_people_gotest: list_people.go list_people_go
|
||||
go test list_people.go list_people_test.go
|
||||
|
||||
javac_middleman: AddPerson.java ListPeople.java protoc_middleman
|
||||
javac AddPerson.java ListPeople.java com/example/tutorial/AddressBookProtos.java
|
||||
javac -cp ../java/core/target/*.jar AddPerson.java ListPeople.java com/example/tutorial/AddressBookProtos.java
|
||||
@touch javac_middleman
|
||||
|
||||
add_person_java: javac_middleman
|
||||
|
@ -28,6 +28,13 @@ These examples are part of the Protocol Buffers tutorial, located at:
|
||||
"-lpthread" from the linker commands (perhaps replacing it with something else).
|
||||
We didn't do this automatically because we wanted to keep the example simple.
|
||||
|
||||
## Java ##
|
||||
|
||||
protobuf-java-*.jar can be generated by:
|
||||
cd ../java
|
||||
mvn package
|
||||
and will be used by "make java"
|
||||
|
||||
## Go ##
|
||||
|
||||
The Go example requires a plugin to the protocol buffer compiler, so it is not
|
||||
|
@ -182,7 +182,7 @@ RUN cd /tmp && \
|
||||
rm -rf protobuf && \
|
||||
git clone https://github.com/google/protobuf.git && \
|
||||
cd protobuf && \
|
||||
git reset --hard 8d97b3d8b5a33650e822460b3b561802c969e86e && \
|
||||
git reset --hard 49b44bff2b6257a119f9c6a342d6151c736586b8 && \
|
||||
cd php && \
|
||||
ln -sfn /usr/local/php-5.5/bin/php /usr/bin/php && \
|
||||
ln -sfn /usr/local/php-5.5/bin/php-config /usr/bin/php-config && \
|
||||
|
@ -98,7 +98,7 @@ RUN composer config -g -- secure-http false
|
||||
RUN cd /tmp && \
|
||||
git clone https://github.com/google/protobuf.git && \
|
||||
cd protobuf/php && \
|
||||
git reset --hard 8d97b3d8b5a33650e822460b3b561802c969e86e && \
|
||||
git reset --hard 49b44bff2b6257a119f9c6a342d6151c736586b8 && \
|
||||
ln -sfn /usr/local/php-5.5/bin/php /usr/bin/php && \
|
||||
ln -sfn /usr/local/php-5.5/bin/php-config /usr/bin/php-config && \
|
||||
ln -sfn /usr/local/php-5.5/bin/phpize /usr/bin/phpize && \
|
||||
|
@ -13,12 +13,8 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Foo\\": "tests/generated/Foo",
|
||||
"Bar\\": "tests/generated/Bar",
|
||||
"Google\\Protobuf\\": "tests/generated/Google/Protobuf",
|
||||
"Google\\Protobuf\\Internal\\": "src/Google/Protobuf/Internal",
|
||||
"GPBMetadata\\": "tests/generated/GPBMetadata",
|
||||
"GPBMetadata\\Google\\Protobuf\\Internal\\": "src/GPBMetadata/Google/Protobuf/Internal",
|
||||
"Google\\Protobuf\\": "src/Google/Protobuf",
|
||||
"GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf",
|
||||
"": "tests/generated"
|
||||
}
|
||||
}
|
||||
|
@ -37,12 +37,27 @@ const int kReservedNamesSize = 3;
|
||||
static void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC);
|
||||
static void descriptor_free_c(Descriptor* object TSRMLS_DC);
|
||||
|
||||
static void field_descriptor_init_c_instance(FieldDescriptor* intern TSRMLS_DC);
|
||||
static void field_descriptor_free_c(FieldDescriptor* object TSRMLS_DC);
|
||||
|
||||
static void enum_descriptor_init_c_instance(EnumDescriptor* intern TSRMLS_DC);
|
||||
static void enum_descriptor_free_c(EnumDescriptor* object TSRMLS_DC);
|
||||
|
||||
static void enum_value_descriptor_init_c_instance(
|
||||
EnumValueDescriptor *intern TSRMLS_DC);
|
||||
static void enum_value_descriptor_free_c(EnumValueDescriptor *object TSRMLS_DC);
|
||||
|
||||
static void descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC);
|
||||
static void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC);
|
||||
|
||||
static void internal_descriptor_pool_free_c(
|
||||
InternalDescriptorPool *object TSRMLS_DC);
|
||||
static void internal_descriptor_pool_init_c_instance(
|
||||
InternalDescriptorPool *pool TSRMLS_DC);
|
||||
|
||||
static void oneof_descriptor_free_c(Oneof* object TSRMLS_DC);
|
||||
static void oneof_descriptor_init_c_instance(Oneof* pool TSRMLS_DC);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Common Utilities
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -169,10 +184,16 @@ void gpb_type_init(TSRMLS_D) {
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static zend_function_entry descriptor_methods[] = {
|
||||
PHP_ME(Descriptor, getClass, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Descriptor, getFullName, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Descriptor, getField, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Descriptor, getFieldCount, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Descriptor, getOneofDecl, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Descriptor, getOneofDeclCount, NULL, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Internal\\Descriptor");
|
||||
DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Descriptor");
|
||||
|
||||
static void descriptor_free_c(Descriptor *self TSRMLS_DC) {
|
||||
if (self->layout) {
|
||||
@ -203,7 +224,6 @@ static void descriptor_free_c(Descriptor *self TSRMLS_DC) {
|
||||
}
|
||||
|
||||
static void descriptor_init_c_instance(Descriptor *desc TSRMLS_DC) {
|
||||
// zend_object_std_init(&desc->std, descriptor_type TSRMLS_CC);
|
||||
desc->msgdef = NULL;
|
||||
desc->layout = NULL;
|
||||
desc->klass = NULL;
|
||||
@ -215,30 +235,217 @@ static void descriptor_init_c_instance(Descriptor *desc TSRMLS_DC) {
|
||||
desc->json_serialize_handlers_preserve = NULL;
|
||||
}
|
||||
|
||||
PHP_METHOD(Descriptor, getClass) {
|
||||
Descriptor *intern = UNBOX(Descriptor, getThis());
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
const char* classname = intern->klass->name;
|
||||
#else
|
||||
const char* classname = ZSTR_VAL(intern->klass->name);
|
||||
#endif
|
||||
PHP_PROTO_RETVAL_STRINGL(classname, strlen(classname), 1);
|
||||
}
|
||||
|
||||
PHP_METHOD(Descriptor, getFullName) {
|
||||
Descriptor *intern = UNBOX(Descriptor, getThis());
|
||||
const char* fullname = upb_msgdef_fullname(intern->msgdef);
|
||||
PHP_PROTO_RETVAL_STRINGL(fullname, strlen(fullname), 1);
|
||||
}
|
||||
|
||||
PHP_METHOD(Descriptor, getField) {
|
||||
long index;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) ==
|
||||
FAILURE) {
|
||||
zend_error(E_USER_ERROR, "Expect integer for index.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Descriptor *intern = UNBOX(Descriptor, getThis());
|
||||
int field_num = upb_msgdef_numfields(intern->msgdef);
|
||||
if (index < 0 || index >= field_num) {
|
||||
zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index);
|
||||
return;
|
||||
}
|
||||
|
||||
upb_msg_field_iter iter;
|
||||
int i;
|
||||
for(upb_msg_field_begin(&iter, intern->msgdef), i = 0;
|
||||
!upb_msg_field_done(&iter) && i < index;
|
||||
upb_msg_field_next(&iter), i++);
|
||||
const upb_fielddef *field = upb_msg_iter_field(&iter);
|
||||
|
||||
PHP_PROTO_HASHTABLE_VALUE field_hashtable_value = get_def_obj(field);
|
||||
if (field_hashtable_value == NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
MAKE_STD_ZVAL(field_hashtable_value);
|
||||
ZVAL_OBJ(field_hashtable_value, field_descriptor_type->create_object(
|
||||
field_descriptor_type TSRMLS_CC));
|
||||
#else
|
||||
field_hashtable_value =
|
||||
field_descriptor_type->create_object(field_descriptor_type TSRMLS_CC);
|
||||
#endif
|
||||
FieldDescriptor *field_php =
|
||||
UNBOX_HASHTABLE_VALUE(FieldDescriptor, field_hashtable_value);
|
||||
field_php->fielddef = field;
|
||||
add_def_obj(field, field_hashtable_value);
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
RETURN_ZVAL(field_hashtable_value, 1, 0);
|
||||
#else
|
||||
++GC_REFCOUNT(field_hashtable_value);
|
||||
RETURN_OBJ(field_hashtable_value);
|
||||
#endif
|
||||
}
|
||||
|
||||
PHP_METHOD(Descriptor, getFieldCount) {
|
||||
Descriptor *intern = UNBOX(Descriptor, getThis());
|
||||
RETURN_LONG(upb_msgdef_numfields(intern->msgdef));
|
||||
}
|
||||
|
||||
PHP_METHOD(Descriptor, getOneofDecl) {
|
||||
long index;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) ==
|
||||
FAILURE) {
|
||||
zend_error(E_USER_ERROR, "Expect integer for index.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Descriptor *intern = UNBOX(Descriptor, getThis());
|
||||
int field_num = upb_msgdef_numoneofs(intern->msgdef);
|
||||
if (index < 0 || index >= field_num) {
|
||||
zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index);
|
||||
return;
|
||||
}
|
||||
|
||||
upb_msg_oneof_iter iter;
|
||||
int i;
|
||||
for(upb_msg_oneof_begin(&iter, intern->msgdef), i = 0;
|
||||
!upb_msg_oneof_done(&iter) && i < index;
|
||||
upb_msg_oneof_next(&iter), i++);
|
||||
upb_oneofdef *oneof = upb_msg_iter_oneof(&iter);
|
||||
|
||||
ZVAL_OBJ(return_value, oneof_descriptor_type->create_object(
|
||||
oneof_descriptor_type TSRMLS_CC));
|
||||
Oneof *oneof_php = UNBOX(Oneof, return_value);
|
||||
oneof_php->oneofdef = oneof;
|
||||
}
|
||||
|
||||
PHP_METHOD(Descriptor, getOneofDeclCount) {
|
||||
Descriptor *intern = UNBOX(Descriptor, getThis());
|
||||
RETURN_LONG(upb_msgdef_numoneofs(intern->msgdef));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// EnumDescriptor
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static zend_function_entry enum_descriptor_methods[] = {
|
||||
PHP_ME(EnumDescriptor, getValue, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(EnumDescriptor, getValueCount, NULL, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS(EnumDescriptor, enum_descriptor,
|
||||
"Google\\Protobuf\\Internal\\EnumDescriptor");
|
||||
"Google\\Protobuf\\EnumDescriptor");
|
||||
|
||||
static void enum_descriptor_free_c(EnumDescriptor *self TSRMLS_DC) {
|
||||
}
|
||||
|
||||
static void enum_descriptor_init_c_instance(EnumDescriptor *self TSRMLS_DC) {
|
||||
// zend_object_std_init(&self->std, enum_descriptor_type TSRMLS_CC);
|
||||
self->enumdef = NULL;
|
||||
self->klass = NULL;
|
||||
}
|
||||
|
||||
PHP_METHOD(EnumDescriptor, getValue) {
|
||||
long index;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) ==
|
||||
FAILURE) {
|
||||
zend_error(E_USER_ERROR, "Expect integer for index.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
EnumDescriptor *intern = UNBOX(EnumDescriptor, getThis());
|
||||
int field_num = upb_enumdef_numvals(intern->enumdef);
|
||||
if (index < 0 || index >= field_num) {
|
||||
zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index);
|
||||
return;
|
||||
}
|
||||
|
||||
upb_enum_iter iter;
|
||||
int i;
|
||||
for(upb_enum_begin(&iter, intern->enumdef), i = 0;
|
||||
!upb_enum_done(&iter) && i < index;
|
||||
upb_enum_next(&iter), i++);
|
||||
|
||||
ZVAL_OBJ(return_value, enum_value_descriptor_type->create_object(
|
||||
enum_value_descriptor_type TSRMLS_CC));
|
||||
EnumValueDescriptor *enum_value_php =
|
||||
UNBOX(EnumValueDescriptor, return_value);
|
||||
enum_value_php->name = upb_enum_iter_name(&iter);
|
||||
enum_value_php->number = upb_enum_iter_number(&iter);
|
||||
}
|
||||
|
||||
PHP_METHOD(EnumDescriptor, getValueCount) {
|
||||
EnumDescriptor *intern = UNBOX(EnumDescriptor, getThis());
|
||||
RETURN_LONG(upb_enumdef_numvals(intern->enumdef));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// EnumValueDescriptor
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static zend_function_entry enum_value_descriptor_methods[] = {
|
||||
PHP_ME(EnumValueDescriptor, getName, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(EnumValueDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS(EnumValueDescriptor, enum_value_descriptor,
|
||||
"Google\\Protobuf\\EnumValueDescriptor");
|
||||
|
||||
static void enum_value_descriptor_free_c(EnumValueDescriptor *self TSRMLS_DC) {
|
||||
}
|
||||
|
||||
static void enum_value_descriptor_init_c_instance(EnumValueDescriptor *self TSRMLS_DC) {
|
||||
self->name = NULL;
|
||||
self->number = 0;
|
||||
}
|
||||
|
||||
PHP_METHOD(EnumValueDescriptor, getName) {
|
||||
EnumValueDescriptor *intern = UNBOX(EnumValueDescriptor, getThis());
|
||||
PHP_PROTO_RETVAL_STRINGL(intern->name, strlen(intern->name), 1);
|
||||
}
|
||||
|
||||
PHP_METHOD(EnumValueDescriptor, getNumber) {
|
||||
EnumValueDescriptor *intern = UNBOX(EnumValueDescriptor, getThis());
|
||||
RETURN_LONG(intern->number);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// FieldDescriptor
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static zend_function_entry field_descriptor_methods[] = {
|
||||
PHP_ME(FieldDescriptor, getName, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(FieldDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(FieldDescriptor, getLabel, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(FieldDescriptor, getType, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(FieldDescriptor, isMap, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(FieldDescriptor, getEnumType, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(FieldDescriptor, getMessageType, NULL, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS(FieldDescriptor, field_descriptor,
|
||||
"Google\\Protobuf\\FieldDescriptor");
|
||||
|
||||
static void field_descriptor_free_c(FieldDescriptor *self TSRMLS_DC) {
|
||||
}
|
||||
|
||||
static void field_descriptor_init_c_instance(FieldDescriptor *self TSRMLS_DC) {
|
||||
self->fielddef = NULL;
|
||||
}
|
||||
|
||||
upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) {
|
||||
switch (type) {
|
||||
#define CASE(descriptor_type, type) \
|
||||
@ -272,6 +479,150 @@ upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PHP_METHOD(FieldDescriptor, getName) {
|
||||
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis());
|
||||
const char* name = upb_fielddef_name(intern->fielddef);
|
||||
PHP_PROTO_RETVAL_STRINGL(name, strlen(name), 1);
|
||||
}
|
||||
|
||||
PHP_METHOD(FieldDescriptor, getNumber) {
|
||||
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis());
|
||||
RETURN_LONG(upb_fielddef_number(intern->fielddef));
|
||||
}
|
||||
|
||||
PHP_METHOD(FieldDescriptor, getLabel) {
|
||||
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis());
|
||||
RETURN_LONG(upb_fielddef_label(intern->fielddef));
|
||||
}
|
||||
|
||||
PHP_METHOD(FieldDescriptor, getType) {
|
||||
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis());
|
||||
RETURN_LONG(upb_fielddef_descriptortype(intern->fielddef));
|
||||
}
|
||||
|
||||
PHP_METHOD(FieldDescriptor, isMap) {
|
||||
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis());
|
||||
RETURN_BOOL(upb_fielddef_ismap(intern->fielddef));
|
||||
}
|
||||
|
||||
PHP_METHOD(FieldDescriptor, getEnumType) {
|
||||
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis());
|
||||
const upb_enumdef *enumdef = upb_fielddef_enumsubdef(intern->fielddef);
|
||||
if (enumdef == NULL) {
|
||||
char error_msg[100];
|
||||
sprintf(error_msg, "Cannot get enum type for non-enum field '%s'",
|
||||
upb_fielddef_name(intern->fielddef));
|
||||
zend_throw_exception(NULL, error_msg, 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
PHP_PROTO_HASHTABLE_VALUE desc = get_def_obj(enumdef);
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
RETURN_ZVAL(desc, 1, 0);
|
||||
#else
|
||||
++GC_REFCOUNT(desc);
|
||||
RETURN_OBJ(desc);
|
||||
#endif
|
||||
}
|
||||
|
||||
PHP_METHOD(FieldDescriptor, getMessageType) {
|
||||
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis());
|
||||
const upb_msgdef *msgdef = upb_fielddef_msgsubdef(intern->fielddef);
|
||||
if (msgdef == NULL) {
|
||||
char error_msg[100];
|
||||
sprintf(error_msg, "Cannot get message type for non-message field '%s'",
|
||||
upb_fielddef_name(intern->fielddef));
|
||||
zend_throw_exception(NULL, error_msg, 0 TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
PHP_PROTO_HASHTABLE_VALUE desc = get_def_obj(msgdef);
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
RETURN_ZVAL(desc, 1, 0);
|
||||
#else
|
||||
++GC_REFCOUNT(desc);
|
||||
RETURN_OBJ(desc);
|
||||
#endif
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Oneof
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static zend_function_entry oneof_descriptor_methods[] = {
|
||||
PHP_ME(Oneof, getName, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Oneof, getField, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Oneof, getFieldCount, NULL, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS(Oneof, oneof_descriptor,
|
||||
"Google\\Protobuf\\OneofDescriptor");
|
||||
|
||||
static void oneof_descriptor_free_c(Oneof *self TSRMLS_DC) {
|
||||
}
|
||||
|
||||
static void oneof_descriptor_init_c_instance(Oneof *self TSRMLS_DC) {
|
||||
self->oneofdef = NULL;
|
||||
}
|
||||
|
||||
PHP_METHOD(Oneof, getName) {
|
||||
Oneof *intern = UNBOX(Oneof, getThis());
|
||||
const char *name = upb_oneofdef_name(intern->oneofdef);
|
||||
PHP_PROTO_RETVAL_STRINGL(name, strlen(name), 1);
|
||||
}
|
||||
|
||||
PHP_METHOD(Oneof, getField) {
|
||||
long index;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) ==
|
||||
FAILURE) {
|
||||
zend_error(E_USER_ERROR, "Expect integer for index.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Oneof *intern = UNBOX(Oneof, getThis());
|
||||
int field_num = upb_oneofdef_numfields(intern->oneofdef);
|
||||
if (index < 0 || index >= field_num) {
|
||||
zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index);
|
||||
return;
|
||||
}
|
||||
|
||||
upb_oneof_iter iter;
|
||||
int i;
|
||||
for(upb_oneof_begin(&iter, intern->oneofdef), i = 0;
|
||||
!upb_oneof_done(&iter) && i < index;
|
||||
upb_oneof_next(&iter), i++);
|
||||
const upb_fielddef *field = upb_oneof_iter_field(&iter);
|
||||
|
||||
PHP_PROTO_HASHTABLE_VALUE field_hashtable_value = get_def_obj(field);
|
||||
if (field_hashtable_value == NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
MAKE_STD_ZVAL(field_hashtable_value);
|
||||
ZVAL_OBJ(field_hashtable_value, field_descriptor_type->create_object(
|
||||
field_descriptor_type TSRMLS_CC));
|
||||
#else
|
||||
field_hashtable_value =
|
||||
field_descriptor_type->create_object(field_descriptor_type TSRMLS_CC);
|
||||
#endif
|
||||
FieldDescriptor *field_php =
|
||||
UNBOX_HASHTABLE_VALUE(FieldDescriptor, field_hashtable_value);
|
||||
field_php->fielddef = field;
|
||||
add_def_obj(field, field_hashtable_value);
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
RETURN_ZVAL(field_hashtable_value, 1, 0);
|
||||
#else
|
||||
++GC_REFCOUNT(field_hashtable_value);
|
||||
RETURN_OBJ(field_hashtable_value);
|
||||
#endif
|
||||
}
|
||||
|
||||
PHP_METHOD(Oneof, getFieldCount) {
|
||||
Oneof *intern = UNBOX(Oneof, getThis());
|
||||
RETURN_LONG(upb_oneofdef_numfields(intern->oneofdef));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// DescriptorPool
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -279,52 +630,79 @@ upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) {
|
||||
static zend_function_entry descriptor_pool_methods[] = {
|
||||
PHP_ME(DescriptorPool, getGeneratedPool, NULL,
|
||||
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
PHP_ME(DescriptorPool, internalAddGeneratedFile, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(DescriptorPool, getDescriptorByClassName, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(DescriptorPool, getEnumDescriptorByClassName, NULL, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_function_entry internal_descriptor_pool_methods[] = {
|
||||
PHP_ME(InternalDescriptorPool, getGeneratedPool, NULL,
|
||||
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
PHP_ME(InternalDescriptorPool, internalAddGeneratedFile, NULL, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS(DescriptorPool, descriptor_pool,
|
||||
"Google\\Protobuf\\DescriptorPool");
|
||||
DEFINE_CLASS(InternalDescriptorPool, internal_descriptor_pool,
|
||||
"Google\\Protobuf\\Internal\\DescriptorPool");
|
||||
|
||||
// wrapper of generated pool
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval* generated_pool_php;
|
||||
zval* internal_generated_pool_php;
|
||||
#else
|
||||
zend_object *generated_pool_php;
|
||||
zend_object *internal_generated_pool_php;
|
||||
#endif
|
||||
DescriptorPool *generated_pool; // The actual generated pool
|
||||
InternalDescriptorPool *generated_pool; // The actual generated pool
|
||||
|
||||
static void init_generated_pool_once(TSRMLS_D) {
|
||||
if (generated_pool_php == NULL) {
|
||||
if (generated_pool == NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
MAKE_STD_ZVAL(generated_pool_php);
|
||||
MAKE_STD_ZVAL(internal_generated_pool_php);
|
||||
ZVAL_OBJ(internal_generated_pool_php,
|
||||
internal_descriptor_pool_type->create_object(
|
||||
internal_descriptor_pool_type TSRMLS_CC));
|
||||
generated_pool = UNBOX(InternalDescriptorPool, internal_generated_pool_php);
|
||||
ZVAL_OBJ(generated_pool_php, descriptor_pool_type->create_object(
|
||||
descriptor_pool_type TSRMLS_CC));
|
||||
generated_pool = UNBOX(DescriptorPool, generated_pool_php);
|
||||
#else
|
||||
internal_generated_pool_php = internal_descriptor_pool_type->create_object(
|
||||
internal_descriptor_pool_type TSRMLS_CC);
|
||||
generated_pool = (InternalDescriptorPool *)((char *)internal_generated_pool_php -
|
||||
XtOffsetOf(InternalDescriptorPool, std));
|
||||
generated_pool_php =
|
||||
descriptor_pool_type->create_object(descriptor_pool_type TSRMLS_CC);
|
||||
generated_pool = (DescriptorPool *)((char *)generated_pool_php -
|
||||
XtOffsetOf(DescriptorPool, std));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void descriptor_pool_init_c_instance(DescriptorPool *pool TSRMLS_DC) {
|
||||
// zend_object_std_init(&pool->std, descriptor_pool_type TSRMLS_CC);
|
||||
static void internal_descriptor_pool_init_c_instance(
|
||||
InternalDescriptorPool *pool TSRMLS_DC) {
|
||||
pool->symtab = upb_symtab_new();
|
||||
|
||||
ALLOC_HASHTABLE(pool->pending_list);
|
||||
zend_hash_init(pool->pending_list, 1, NULL, ZVAL_PTR_DTOR, 0);
|
||||
}
|
||||
|
||||
static void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) {
|
||||
static void internal_descriptor_pool_free_c(
|
||||
InternalDescriptorPool *pool TSRMLS_DC) {
|
||||
upb_symtab_free(pool->symtab);
|
||||
|
||||
zend_hash_destroy(pool->pending_list);
|
||||
FREE_HASHTABLE(pool->pending_list);
|
||||
}
|
||||
|
||||
static void descriptor_pool_init_c_instance(DescriptorPool *pool TSRMLS_DC) {
|
||||
assert(generated_pool != NULL);
|
||||
pool->intern = generated_pool;
|
||||
}
|
||||
|
||||
static void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) {
|
||||
}
|
||||
|
||||
static void validate_enumdef(const upb_enumdef *enumdef) {
|
||||
// Verify that an entry exists with integer value 0. (This is the default
|
||||
// value.)
|
||||
@ -358,6 +736,16 @@ PHP_METHOD(DescriptorPool, getGeneratedPool) {
|
||||
#endif
|
||||
}
|
||||
|
||||
PHP_METHOD(InternalDescriptorPool, getGeneratedPool) {
|
||||
init_generated_pool_once(TSRMLS_C);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
RETURN_ZVAL(internal_generated_pool_php, 1, 0);
|
||||
#else
|
||||
++GC_REFCOUNT(internal_generated_pool_php);
|
||||
RETURN_OBJ(internal_generated_pool_php);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void classname_no_prefix(const char *fullname, const char *package_name,
|
||||
char *class_name) {
|
||||
size_t i = 0, j;
|
||||
@ -455,7 +843,7 @@ static void convert_to_class_name_inplace(const char *package,
|
||||
memcpy(classname + i, prefix, prefix_len);
|
||||
}
|
||||
|
||||
PHP_METHOD(DescriptorPool, internalAddGeneratedFile) {
|
||||
PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) {
|
||||
char *data = NULL;
|
||||
PHP_PROTO_SIZE data_len;
|
||||
upb_filedef **files;
|
||||
@ -466,7 +854,7 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
DescriptorPool *pool = UNBOX(DescriptorPool, getThis());
|
||||
InternalDescriptorPool *pool = UNBOX(InternalDescriptorPool, getThis());
|
||||
CHECK_UPB(files = upb_loaddescriptor(data, data_len, &pool, &status),
|
||||
"Parse binary descriptors to internal descriptors failed");
|
||||
|
||||
@ -550,3 +938,77 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) {
|
||||
upb_filedef_unref(files[0], &pool);
|
||||
upb_gfree(files);
|
||||
}
|
||||
|
||||
PHP_METHOD(DescriptorPool, getDescriptorByClassName) {
|
||||
DescriptorPool *public_pool = UNBOX(DescriptorPool, getThis());
|
||||
InternalDescriptorPool *pool = public_pool->intern;
|
||||
|
||||
char *classname = NULL;
|
||||
PHP_PROTO_SIZE classname_len;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname,
|
||||
&classname_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
PHP_PROTO_CE_DECLARE pce;
|
||||
if (php_proto_zend_lookup_class(classname, classname_len, &pce) ==
|
||||
FAILURE) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
PHP_PROTO_HASHTABLE_VALUE desc = get_ce_obj(PHP_PROTO_CE_UNREF(pce));
|
||||
if (desc == NULL) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
zend_class_entry* instance_ce = HASHTABLE_VALUE_CE(desc);
|
||||
|
||||
if (!instanceof_function(instance_ce, descriptor_type TSRMLS_CC)) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
RETURN_ZVAL(desc, 1, 0);
|
||||
#else
|
||||
++GC_REFCOUNT(desc);
|
||||
RETURN_OBJ(desc);
|
||||
#endif
|
||||
}
|
||||
|
||||
PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName) {
|
||||
DescriptorPool *public_pool = UNBOX(DescriptorPool, getThis());
|
||||
InternalDescriptorPool *pool = public_pool->intern;
|
||||
|
||||
char *classname = NULL;
|
||||
PHP_PROTO_SIZE classname_len;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname,
|
||||
&classname_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
PHP_PROTO_CE_DECLARE pce;
|
||||
if (php_proto_zend_lookup_class(classname, classname_len, &pce) ==
|
||||
FAILURE) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
PHP_PROTO_HASHTABLE_VALUE desc = get_ce_obj(PHP_PROTO_CE_UNREF(pce));
|
||||
if (desc == NULL) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
zend_class_entry* instance_ce = HASHTABLE_VALUE_CE(desc);
|
||||
|
||||
if (!instanceof_function(instance_ce, enum_descriptor_type TSRMLS_CC)) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
RETURN_ZVAL(desc, 1, 0);
|
||||
#else
|
||||
++GC_REFCOUNT(desc);
|
||||
RETURN_OBJ(desc);
|
||||
#endif
|
||||
}
|
||||
|
@ -716,7 +716,7 @@ static void *oneofbytes_handler(void *closure,
|
||||
DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) =
|
||||
oneofdata->oneof_case_num;
|
||||
DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) =
|
||||
&(msg->std.properties_table)[oneofdata->property_ofs];
|
||||
OBJ_PROP(&msg->std, oneofdata->property_ofs);
|
||||
|
||||
return empty_php_string(DEREF(
|
||||
message_data(msg), oneofdata->ofs, CACHED_VALUE*));
|
||||
@ -747,7 +747,7 @@ static void* oneofsubmsg_handler(void* closure, const void* hd) {
|
||||
|
||||
// Create new message.
|
||||
DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) =
|
||||
&(msg->std.properties_table)[oneofdata->property_ofs];
|
||||
OBJ_PROP(&msg->std, oneofdata->property_ofs);
|
||||
ZVAL_OBJ(CACHED_PTR_TO_ZVAL_PTR(
|
||||
DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)),
|
||||
subklass->create_object(subklass TSRMLS_CC));
|
||||
|
@ -172,7 +172,7 @@ static zval* message_get_property(zval* object, zval* member, int type,
|
||||
zend_get_property_info(Z_OBJCE_P(object), member, true TSRMLS_CC);
|
||||
return layout_get(
|
||||
self->descriptor->layout, message_data(self), field,
|
||||
&Z_OBJ_P(object)->properties_table[property_info->offset] TSRMLS_CC);
|
||||
OBJ_PROP(Z_OBJ_P(object), property_info->offset) TSRMLS_CC);
|
||||
#else
|
||||
property_info =
|
||||
zend_get_property_info(Z_OBJCE_P(object), Z_STR_P(member), true);
|
||||
@ -222,7 +222,7 @@ void custom_data_init(const zend_class_entry* ce,
|
||||
// case a collection happens during object creation in layout_init().
|
||||
intern->descriptor = desc;
|
||||
layout_init(desc->layout, message_data(intern),
|
||||
intern->std.properties_table PHP_PROTO_TSRMLS_CC);
|
||||
&intern->std PHP_PROTO_TSRMLS_CC);
|
||||
}
|
||||
|
||||
void build_class_from_descriptor(
|
||||
@ -265,8 +265,7 @@ PHP_METHOD(Message, clear) {
|
||||
zend_class_entry* ce = desc->klass;
|
||||
|
||||
object_properties_init(&msg->std, ce);
|
||||
layout_init(desc->layout, message_data(msg),
|
||||
msg->std.properties_table TSRMLS_CC);
|
||||
layout_init(desc->layout, message_data(msg), &msg->std TSRMLS_CC);
|
||||
}
|
||||
|
||||
PHP_METHOD(Message, mergeFrom) {
|
||||
@ -301,7 +300,8 @@ PHP_METHOD(Message, readOneof) {
|
||||
|
||||
int property_cache_index =
|
||||
msg->descriptor->layout->fields[upb_fielddef_index(field)].cache_index;
|
||||
zval* property_ptr = OBJ_PROP(Z_OBJ_P(getThis()), property_cache_index);
|
||||
zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR(
|
||||
OBJ_PROP(Z_OBJ_P(getThis()), property_cache_index));
|
||||
|
||||
// Unlike singular fields, oneof fields share cached property. So we cannot
|
||||
// let lay_get modify the cached property. Instead, we pass in the return
|
||||
|
@ -63,7 +63,6 @@ static void* get_from_table(const HashTable* t, const void* def) {
|
||||
void** value;
|
||||
if (php_proto_zend_hash_index_find_mem(t, (zend_ulong)def, (void**)&value) ==
|
||||
FAILURE) {
|
||||
zend_error(E_ERROR, "PHP object not found for given definition.\n");
|
||||
return NULL;
|
||||
}
|
||||
return *value;
|
||||
@ -166,6 +165,7 @@ static PHP_RINIT_FUNCTION(protobuf) {
|
||||
|
||||
generated_pool = NULL;
|
||||
generated_pool_php = NULL;
|
||||
internal_generated_pool_php = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -182,21 +182,40 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) {
|
||||
zval_dtor(generated_pool_php);
|
||||
FREE_ZVAL(generated_pool_php);
|
||||
}
|
||||
if (internal_generated_pool_php != NULL) {
|
||||
zval_dtor(internal_generated_pool_php);
|
||||
FREE_ZVAL(internal_generated_pool_php);
|
||||
}
|
||||
#else
|
||||
if (generated_pool_php != NULL) {
|
||||
zval tmp;
|
||||
ZVAL_OBJ(&tmp, generated_pool_php);
|
||||
zval_dtor(&tmp);
|
||||
}
|
||||
if (internal_generated_pool_php != NULL) {
|
||||
zval tmp;
|
||||
ZVAL_OBJ(&tmp, internal_generated_pool_php);
|
||||
zval_dtor(&tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PHP_MINIT_FUNCTION(protobuf) {
|
||||
map_field_init(TSRMLS_C);
|
||||
map_field_iter_init(TSRMLS_C);
|
||||
repeated_field_init(TSRMLS_C);
|
||||
repeated_field_iter_init(TSRMLS_C);
|
||||
gpb_type_init(TSRMLS_C);
|
||||
message_init(TSRMLS_C);
|
||||
descriptor_pool_init(TSRMLS_C);
|
||||
descriptor_init(TSRMLS_C);
|
||||
enum_descriptor_init(TSRMLS_C);
|
||||
enum_value_descriptor_init(TSRMLS_C);
|
||||
field_descriptor_init(TSRMLS_C);
|
||||
gpb_type_init(TSRMLS_C);
|
||||
internal_descriptor_pool_init(TSRMLS_C);
|
||||
map_field_init(TSRMLS_C);
|
||||
map_field_iter_init(TSRMLS_C);
|
||||
message_init(TSRMLS_C);
|
||||
oneof_descriptor_init(TSRMLS_C);
|
||||
repeated_field_init(TSRMLS_C);
|
||||
repeated_field_iter_init(TSRMLS_C);
|
||||
util_init(TSRMLS_C);
|
||||
|
||||
return 0;
|
||||
|
@ -151,7 +151,7 @@
|
||||
|
||||
#define PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL EG(uninitialized_zval_ptr)
|
||||
|
||||
#define OBJ_PROP(PROPERTIES, OFFSET) (PROPERTIES)->properties_table[OFFSET]
|
||||
#define OBJ_PROP(OBJECT, OFFSET) &((OBJECT)->properties_table[OFFSET])
|
||||
|
||||
#define php_proto_zval_ptr_dtor(zval_ptr) \
|
||||
zval_ptr_dtor(&(zval_ptr))
|
||||
@ -185,6 +185,7 @@
|
||||
#define HASHTABLE_VALUE_DTOR ZVAL_PTR_DTOR
|
||||
|
||||
#define PHP_PROTO_HASHTABLE_VALUE zval*
|
||||
#define HASHTABLE_VALUE_CE(val) Z_OBJCE_P(val)
|
||||
|
||||
#define CREATE_HASHTABLE_VALUE(OBJ, WRAPPED_OBJ, OBJ_TYPE, OBJ_CLASS_ENTRY) \
|
||||
OBJ_TYPE* OBJ; \
|
||||
@ -369,6 +370,7 @@ static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht,
|
||||
#define HASHTABLE_VALUE_DTOR php_proto_hashtable_descriptor_release
|
||||
|
||||
#define PHP_PROTO_HASHTABLE_VALUE zend_object*
|
||||
#define HASHTABLE_VALUE_CE(val) val->ce
|
||||
|
||||
#define CREATE_HASHTABLE_VALUE(OBJ, WRAPPED_OBJ, OBJ_TYPE, OBJ_CLASS_ENTRY) \
|
||||
OBJ_TYPE* OBJ; \
|
||||
@ -397,7 +399,9 @@ static inline int php_proto_zend_lookup_class(
|
||||
struct DescriptorPool;
|
||||
struct Descriptor;
|
||||
struct EnumDescriptor;
|
||||
struct EnumValueDescriptor;
|
||||
struct FieldDescriptor;
|
||||
struct InternalDescriptorPool;
|
||||
struct MessageField;
|
||||
struct MessageHeader;
|
||||
struct MessageLayout;
|
||||
@ -410,7 +414,9 @@ struct Oneof;
|
||||
typedef struct DescriptorPool DescriptorPool;
|
||||
typedef struct Descriptor Descriptor;
|
||||
typedef struct EnumDescriptor EnumDescriptor;
|
||||
typedef struct EnumValueDescriptor EnumValueDescriptor;
|
||||
typedef struct FieldDescriptor FieldDescriptor;
|
||||
typedef struct InternalDescriptorPool InternalDescriptorPool;
|
||||
typedef struct MessageField MessageField;
|
||||
typedef struct MessageHeader MessageHeader;
|
||||
typedef struct MessageLayout MessageLayout;
|
||||
@ -431,9 +437,12 @@ ZEND_END_MODULE_GLOBALS(protobuf)
|
||||
void descriptor_init(TSRMLS_D);
|
||||
void enum_descriptor_init(TSRMLS_D);
|
||||
void descriptor_pool_init(TSRMLS_D);
|
||||
void internal_descriptor_pool_init(TSRMLS_D);
|
||||
void field_descriptor_init(TSRMLS_D);
|
||||
void gpb_type_init(TSRMLS_D);
|
||||
void map_field_init(TSRMLS_D);
|
||||
void map_field_iter_init(TSRMLS_D);
|
||||
void oneof_descriptor_init(TSRMLS_D);
|
||||
void repeated_field_init(TSRMLS_D);
|
||||
void repeated_field_iter_init(TSRMLS_D);
|
||||
void util_init(TSRMLS_D);
|
||||
@ -458,22 +467,34 @@ extern zend_class_entry* repeated_field_type;
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
PHP_PROTO_WRAP_OBJECT_START(DescriptorPool)
|
||||
InternalDescriptorPool* intern;
|
||||
PHP_PROTO_WRAP_OBJECT_END
|
||||
|
||||
PHP_METHOD(DescriptorPool, getGeneratedPool);
|
||||
PHP_METHOD(DescriptorPool, getDescriptorByClassName);
|
||||
PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName);
|
||||
|
||||
PHP_PROTO_WRAP_OBJECT_START(InternalDescriptorPool)
|
||||
upb_symtab* symtab;
|
||||
HashTable* pending_list;
|
||||
PHP_PROTO_WRAP_OBJECT_END
|
||||
|
||||
PHP_METHOD(DescriptorPool, getGeneratedPool);
|
||||
PHP_METHOD(DescriptorPool, internalAddGeneratedFile);
|
||||
PHP_METHOD(InternalDescriptorPool, getGeneratedPool);
|
||||
PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile);
|
||||
|
||||
// wrapper of generated pool
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
extern zval* generated_pool_php;
|
||||
extern zval* internal_generated_pool_php;
|
||||
void descriptor_pool_free(void* object TSRMLS_DC);
|
||||
void internal_descriptor_pool_free(void* object TSRMLS_DC);
|
||||
#else
|
||||
extern zend_object *generated_pool_php;
|
||||
extern zend_object *internal_generated_pool_php;
|
||||
void descriptor_pool_free(zend_object* object);
|
||||
void internal_descriptor_pool_free(zend_object* object);
|
||||
#endif
|
||||
extern DescriptorPool* generated_pool; // The actual generated pool
|
||||
extern InternalDescriptorPool* generated_pool; // The actual generated pool
|
||||
|
||||
PHP_PROTO_WRAP_OBJECT_START(Descriptor)
|
||||
const upb_msgdef* msgdef;
|
||||
@ -487,6 +508,13 @@ PHP_PROTO_WRAP_OBJECT_START(Descriptor)
|
||||
const upb_handlers* json_serialize_handlers_preserve;
|
||||
PHP_PROTO_WRAP_OBJECT_END
|
||||
|
||||
PHP_METHOD(Descriptor, getClass);
|
||||
PHP_METHOD(Descriptor, getFullName);
|
||||
PHP_METHOD(Descriptor, getField);
|
||||
PHP_METHOD(Descriptor, getFieldCount);
|
||||
PHP_METHOD(Descriptor, getOneofDecl);
|
||||
PHP_METHOD(Descriptor, getOneofDeclCount);
|
||||
|
||||
extern zend_class_entry* descriptor_type;
|
||||
|
||||
void descriptor_name_set(Descriptor *desc, const char *name);
|
||||
@ -495,14 +523,36 @@ PHP_PROTO_WRAP_OBJECT_START(FieldDescriptor)
|
||||
const upb_fielddef* fielddef;
|
||||
PHP_PROTO_WRAP_OBJECT_END
|
||||
|
||||
PHP_METHOD(FieldDescriptor, getName);
|
||||
PHP_METHOD(FieldDescriptor, getNumber);
|
||||
PHP_METHOD(FieldDescriptor, getLabel);
|
||||
PHP_METHOD(FieldDescriptor, getType);
|
||||
PHP_METHOD(FieldDescriptor, isMap);
|
||||
PHP_METHOD(FieldDescriptor, getEnumType);
|
||||
PHP_METHOD(FieldDescriptor, getMessageType);
|
||||
|
||||
extern zend_class_entry* field_descriptor_type;
|
||||
|
||||
PHP_PROTO_WRAP_OBJECT_START(EnumDescriptor)
|
||||
const upb_enumdef* enumdef;
|
||||
zend_class_entry* klass; // begins as NULL
|
||||
// VALUE module; // begins as nil
|
||||
PHP_PROTO_WRAP_OBJECT_END
|
||||
|
||||
PHP_METHOD(EnumDescriptor, getValue);
|
||||
PHP_METHOD(EnumDescriptor, getValueCount);
|
||||
|
||||
extern zend_class_entry* enum_descriptor_type;
|
||||
|
||||
PHP_PROTO_WRAP_OBJECT_START(EnumValueDescriptor)
|
||||
const char* name;
|
||||
int32_t number;
|
||||
PHP_PROTO_WRAP_OBJECT_END
|
||||
|
||||
PHP_METHOD(EnumValueDescriptor, getName);
|
||||
PHP_METHOD(EnumValueDescriptor, getNumber);
|
||||
|
||||
extern zend_class_entry* enum_value_descriptor_type;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Message class creation.
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -594,7 +644,7 @@ PHP_PROTO_WRAP_OBJECT_END
|
||||
|
||||
MessageLayout* create_layout(const upb_msgdef* msgdef);
|
||||
void layout_init(MessageLayout* layout, void* storage,
|
||||
CACHED_VALUE* properties_table PHP_PROTO_TSRMLS_DC);
|
||||
zend_object* object PHP_PROTO_TSRMLS_DC);
|
||||
zval* layout_get(MessageLayout* layout, const void* storage,
|
||||
const upb_fielddef* field, CACHED_VALUE* cache TSRMLS_DC);
|
||||
void layout_set(MessageLayout* layout, MessageHeader* header,
|
||||
@ -819,6 +869,12 @@ PHP_PROTO_WRAP_OBJECT_START(Oneof)
|
||||
char value[NATIVE_SLOT_MAX_SIZE];
|
||||
PHP_PROTO_WRAP_OBJECT_END
|
||||
|
||||
PHP_METHOD(Oneof, getName);
|
||||
PHP_METHOD(Oneof, getField);
|
||||
PHP_METHOD(Oneof, getFieldCount);
|
||||
|
||||
extern zend_class_entry* oneof_descriptor_type;
|
||||
|
||||
// Oneof case slot value to indicate that no oneof case is set. The value `0` is
|
||||
// safe because field numbers are used as case identifiers, and no field can
|
||||
// have a number of 0.
|
||||
|
@ -275,9 +275,6 @@ void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) {
|
||||
break;
|
||||
case UPB_TYPE_STRING:
|
||||
case UPB_TYPE_BYTES:
|
||||
DEREF(memory, CACHED_VALUE*) = cache;
|
||||
ZVAL_EMPTY_STRING(CACHED_PTR_TO_ZVAL_PTR(cache));
|
||||
break;
|
||||
case UPB_TYPE_MESSAGE:
|
||||
DEREF(memory, CACHED_VALUE*) = cache;
|
||||
break;
|
||||
@ -586,6 +583,8 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
|
||||
upb_msg_oneof_iter oit;
|
||||
size_t off = 0;
|
||||
int i = 0;
|
||||
TSRMLS_FETCH();
|
||||
Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msgdef));
|
||||
|
||||
layout->fields = ALLOC_N(MessageField, nfields);
|
||||
|
||||
@ -612,7 +611,37 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
|
||||
layout->fields[upb_fielddef_index(field)].offset = off;
|
||||
layout->fields[upb_fielddef_index(field)].case_offset =
|
||||
MESSAGE_FIELD_NO_CASE;
|
||||
layout->fields[upb_fielddef_index(field)].cache_index = i++;
|
||||
|
||||
const char* fieldname = upb_fielddef_name(field);
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
|
||||
zend_class_entry* old_scope = EG(scope);
|
||||
EG(scope) = desc->klass;
|
||||
#else
|
||||
zend_class_entry* old_scope = EG(fake_scope);
|
||||
EG(fake_scope) = desc->klass;
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval member;
|
||||
ZVAL_STRINGL(&member, fieldname, strlen(fieldname), 0);
|
||||
zend_property_info* property_info =
|
||||
zend_get_property_info(desc->klass, &member, true TSRMLS_CC);
|
||||
#else
|
||||
zend_string* member = zend_string_init(fieldname, strlen(fieldname), 1);
|
||||
zend_property_info* property_info =
|
||||
zend_get_property_info(desc->klass, member, true);
|
||||
zend_string_release(member);
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
|
||||
EG(scope) = old_scope;
|
||||
#else
|
||||
EG(fake_scope) = old_scope;
|
||||
#endif
|
||||
|
||||
layout->fields[upb_fielddef_index(field)].cache_index =
|
||||
property_info->offset;
|
||||
off += field_size;
|
||||
}
|
||||
|
||||
@ -640,11 +669,40 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
|
||||
// Align the offset .
|
||||
off = align_up_to( off, field_size);
|
||||
// Assign all fields in the oneof this same offset.
|
||||
const char* oneofname = upb_oneofdef_name(oneof);
|
||||
for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit);
|
||||
upb_oneof_next(&fit)) {
|
||||
const upb_fielddef* field = upb_oneof_iter_field(&fit);
|
||||
layout->fields[upb_fielddef_index(field)].offset = off;
|
||||
layout->fields[upb_fielddef_index(field)].cache_index = i;
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
|
||||
zend_class_entry* old_scope = EG(scope);
|
||||
EG(scope) = desc->klass;
|
||||
#else
|
||||
zend_class_entry* old_scope = EG(fake_scope);
|
||||
EG(fake_scope) = desc->klass;
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval member;
|
||||
ZVAL_STRINGL(&member, oneofname, strlen(oneofname), 0);
|
||||
zend_property_info* property_info =
|
||||
zend_get_property_info(desc->klass, &member, true TSRMLS_CC);
|
||||
#else
|
||||
zend_string* member = zend_string_init(oneofname, strlen(oneofname), 1);
|
||||
zend_property_info* property_info =
|
||||
zend_get_property_info(desc->klass, member, true);
|
||||
zend_string_release(member);
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
|
||||
EG(scope) = old_scope;
|
||||
#else
|
||||
EG(fake_scope) = old_scope;
|
||||
#endif
|
||||
|
||||
layout->fields[upb_fielddef_index(field)].cache_index =
|
||||
property_info->offset;
|
||||
}
|
||||
i++;
|
||||
off += field_size;
|
||||
@ -683,7 +741,7 @@ void free_layout(MessageLayout* layout) {
|
||||
}
|
||||
|
||||
void layout_init(MessageLayout* layout, void* storage,
|
||||
CACHED_VALUE* properties_table PHP_PROTO_TSRMLS_DC) {
|
||||
zend_object* object PHP_PROTO_TSRMLS_DC) {
|
||||
int i;
|
||||
upb_msg_field_iter it;
|
||||
for (upb_msg_field_begin(&it, layout->msgdef), i = 0; !upb_msg_field_done(&it);
|
||||
@ -692,22 +750,7 @@ void layout_init(MessageLayout* layout, void* storage,
|
||||
void* memory = slot_memory(layout, storage, field);
|
||||
uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
|
||||
int cache_index = slot_property_cache(layout, storage, field);
|
||||
CACHED_VALUE* property_ptr = &properties_table[cache_index];
|
||||
|
||||
// Clean up initial value by generated code. In the generated code of
|
||||
// previous versions, each php field is given an initial value. However, the
|
||||
// order to initialize these fields may not be consistent with the order of
|
||||
// upb fields.
|
||||
if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(property_ptr)) == IS_STRING) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
if (!IS_INTERNED(Z_STRVAL_PP(property_ptr))) {
|
||||
FREE(Z_STRVAL_PP(property_ptr));
|
||||
}
|
||||
#else
|
||||
zend_string_release(Z_STR_P(property_ptr));
|
||||
#endif
|
||||
}
|
||||
ZVAL_NULL(CACHED_PTR_TO_ZVAL_PTR(property_ptr));
|
||||
CACHED_VALUE* property_ptr = OBJ_PROP(object, cache_index);
|
||||
|
||||
if (upb_fielddef_containingoneof(field)) {
|
||||
memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
|
||||
@ -797,7 +840,7 @@ void layout_set(MessageLayout* layout, MessageHeader* header,
|
||||
header->descriptor->layout->fields[upb_fielddef_index(field)]
|
||||
.cache_index;
|
||||
DEREF(memory, CACHED_VALUE*) =
|
||||
&(header->std.properties_table)[property_cache_index];
|
||||
OBJ_PROP(&header->std, property_cache_index);
|
||||
memory = DEREF(memory, CACHED_VALUE*);
|
||||
break;
|
||||
}
|
||||
@ -964,7 +1007,7 @@ void layout_merge(MessageLayout* layout, MessageHeader* from,
|
||||
int property_cache_index =
|
||||
layout->fields[upb_fielddef_index(field)].cache_index;
|
||||
DEREF(to_memory, CACHED_VALUE*) =
|
||||
&(to->std.properties_table)[property_cache_index];
|
||||
OBJ_PROP(&to->std, property_cache_index);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -10,6 +10,7 @@
|
||||
<file>tests/generated_phpdoc_test.php</file>
|
||||
<file>tests/map_field_test.php</file>
|
||||
<file>tests/well_known_test.php</file>
|
||||
<file>tests/descriptors_test.php</file>
|
||||
<file>tests/generated_service_test.php</file>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
100
php/src/Google/Protobuf/Descriptor.php
Normal file
100
php/src/Google/Protobuf/Descriptor.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace Google\Protobuf;
|
||||
|
||||
use Google\Protobuf\Internal\GetPublicDescriptorTrait;
|
||||
|
||||
class Descriptor
|
||||
{
|
||||
use GetPublicDescriptorTrait;
|
||||
|
||||
private $internal_desc;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __construct($internal_desc)
|
||||
{
|
||||
$this->internal_desc = $internal_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Full protobuf message name
|
||||
*/
|
||||
public function getFullName()
|
||||
{
|
||||
return trim($this->internal_desc->getFullName(), ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string PHP class name
|
||||
*/
|
||||
public function getClass()
|
||||
{
|
||||
return $this->internal_desc->getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index Must be >= 0 and < getFieldCount()
|
||||
* @return FieldDescriptor
|
||||
*/
|
||||
public function getField($index)
|
||||
{
|
||||
return $this->getPublicDescriptor($this->internal_desc->getFieldByIndex($index));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int Number of fields in message
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
return count($this->internal_desc->getField());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index Must be >= 0 and < getOneofDeclCount()
|
||||
* @return OneofDescriptor
|
||||
*/
|
||||
public function getOneofDecl($index)
|
||||
{
|
||||
return $this->getPublicDescriptor($this->internal_desc->getOneofDecl()[$index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int Number of oneofs in message
|
||||
*/
|
||||
public function getOneofDeclCount()
|
||||
{
|
||||
return count($this->internal_desc->getOneofDecl());
|
||||
}
|
||||
}
|
76
php/src/Google/Protobuf/DescriptorPool.php
Normal file
76
php/src/Google/Protobuf/DescriptorPool.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace Google\Protobuf;
|
||||
|
||||
class DescriptorPool
|
||||
{
|
||||
private static $pool;
|
||||
|
||||
private $internal_pool;
|
||||
|
||||
/**
|
||||
* @return DescriptorPool
|
||||
*/
|
||||
public static function getGeneratedPool()
|
||||
{
|
||||
if (!isset(self::$pool)) {
|
||||
self::$pool = new DescriptorPool(\Google\Protobuf\Internal\DescriptorPool::getGeneratedPool());
|
||||
}
|
||||
return self::$pool;
|
||||
}
|
||||
|
||||
private function __construct($internal_pool)
|
||||
{
|
||||
$this->internal_pool = $internal_pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className A fully qualified protobuf class name
|
||||
* @return Descriptor
|
||||
*/
|
||||
public function getDescriptorByClassName($className)
|
||||
{
|
||||
$desc = $this->internal_pool->getDescriptorByClassName($className);
|
||||
return is_null($desc) ? null : $desc->getPublicDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className A fully qualified protobuf class name
|
||||
* @return EnumDescriptor
|
||||
*/
|
||||
public function getEnumDescriptorByClassName($className)
|
||||
{
|
||||
$desc = $this->internal_pool->getEnumDescriptorByClassName($className);
|
||||
return is_null($desc) ? null : $desc->getPublicDescriptor();
|
||||
}
|
||||
}
|
79
php/src/Google/Protobuf/EnumDescriptor.php
Normal file
79
php/src/Google/Protobuf/EnumDescriptor.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace Google\Protobuf;
|
||||
|
||||
class EnumDescriptor
|
||||
{
|
||||
private $internal_desc;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __construct($internal_desc)
|
||||
{
|
||||
$this->internal_desc = $internal_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Full protobuf message name
|
||||
*/
|
||||
public function getFullName()
|
||||
{
|
||||
return $this->internal_desc->getFullName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string PHP class name
|
||||
*/
|
||||
public function getClass()
|
||||
{
|
||||
return $this->internal_desc->getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index Must be >= 0 and < getValueCount()
|
||||
* @return EnumValueDescriptor
|
||||
*/
|
||||
public function getValue($index)
|
||||
{
|
||||
return $this->internal_desc->getValueDescriptorByIndex($index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int Number of values in enum
|
||||
*/
|
||||
public function getValueCount()
|
||||
{
|
||||
return $this->internal_desc->getValueCount();
|
||||
}
|
||||
}
|
@ -30,28 +30,33 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace Google\Protobuf\Internal;
|
||||
namespace Google\Protobuf;
|
||||
|
||||
class EnumValueDescriptor
|
||||
{
|
||||
private $name;
|
||||
private $number;
|
||||
|
||||
public function setName($name)
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __construct($name, $number)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->number = $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setNumber($number)
|
||||
{
|
||||
$this->number = $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getNumber()
|
||||
{
|
||||
return $this->number;
|
117
php/src/Google/Protobuf/FieldDescriptor.php
Normal file
117
php/src/Google/Protobuf/FieldDescriptor.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace Google\Protobuf;
|
||||
|
||||
use Google\Protobuf\Internal\GetPublicDescriptorTrait;
|
||||
use Google\Protobuf\Internal\GPBType;
|
||||
|
||||
class FieldDescriptor
|
||||
{
|
||||
use GetPublicDescriptorTrait;
|
||||
|
||||
private $internal_desc;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __construct($internal_desc)
|
||||
{
|
||||
$this->internal_desc = $internal_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Field name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->internal_desc->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int Protobuf field number
|
||||
*/
|
||||
public function getNumber()
|
||||
{
|
||||
return $this->internal_desc->getNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLabel()
|
||||
{
|
||||
return $this->internal_desc->getLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->internal_desc->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Descriptor Returns a descriptor for the field type if the field type is a message, otherwise throws \Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getMessageType()
|
||||
{
|
||||
if ($this->getType() == GPBType::MESSAGE) {
|
||||
return $this->getPublicDescriptor($this->internal_desc->getMessageType());
|
||||
} else {
|
||||
throw new \Exception("Cannot get message type for non-message field '" . $this->getName() . "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EnumDescriptor Returns an enum descriptor if the field type is an enum, otherwise throws \Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getEnumType()
|
||||
{
|
||||
if ($this->getType() == GPBType::ENUM) {
|
||||
return $this->getPublicDescriptor($this->internal_desc->getEnumType());
|
||||
} else {
|
||||
throw new \Exception("Cannot get enum type for non-enum field '" . $this->getName() . "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isMap()
|
||||
{
|
||||
return $this->internal_desc->isMap();
|
||||
}
|
||||
}
|
@ -34,17 +34,24 @@ namespace Google\Protobuf\Internal;
|
||||
|
||||
class Descriptor
|
||||
{
|
||||
use HasPublicDescriptorTrait;
|
||||
|
||||
private $full_name;
|
||||
private $field = [];
|
||||
private $json_to_field = [];
|
||||
private $name_to_field = [];
|
||||
private $index_to_field = [];
|
||||
private $nested_type = [];
|
||||
private $enum_type = [];
|
||||
private $klass;
|
||||
private $options;
|
||||
private $oneof_decl = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->public_desc = new \Google\Protobuf\Descriptor($this);
|
||||
}
|
||||
|
||||
public function addOneofDecl($oneof)
|
||||
{
|
||||
$this->oneof_decl[] = $oneof;
|
||||
@ -70,6 +77,7 @@ class Descriptor
|
||||
$this->field[$field->getNumber()] = $field;
|
||||
$this->json_to_field[$field->getJsonName()] = $field;
|
||||
$this->name_to_field[$field->getName()] = $field;
|
||||
$this->index_to_field[] = $field;
|
||||
}
|
||||
|
||||
public function getField()
|
||||
@ -124,6 +132,15 @@ class Descriptor
|
||||
}
|
||||
}
|
||||
|
||||
public function getFieldByIndex($index)
|
||||
{
|
||||
if (count($this->index_to_field) <= $index) {
|
||||
return NULL;
|
||||
} else {
|
||||
return $this->index_to_field[$index];
|
||||
}
|
||||
}
|
||||
|
||||
public function setClass($klass)
|
||||
{
|
||||
$this->klass = $klass;
|
||||
@ -179,9 +196,11 @@ class Descriptor
|
||||
}
|
||||
|
||||
// Handle oneof fields.
|
||||
$index = 0;
|
||||
foreach ($proto->getOneofDecl() as $oneof_proto) {
|
||||
$desc->addOneofDecl(
|
||||
OneofDescriptor::buildFromProto($oneof_proto, $desc));
|
||||
OneofDescriptor::buildFromProto($oneof_proto, $desc, $index));
|
||||
$index++;
|
||||
}
|
||||
|
||||
return $desc;
|
||||
|
@ -61,17 +61,17 @@ class DescriptorPool
|
||||
$files->mergeFromString($data);
|
||||
$file = FileDescriptor::buildFromProto($files->getFile()[0]);
|
||||
|
||||
foreach ($file->getMessageType() as &$desc) {
|
||||
foreach ($file->getMessageType() as $desc) {
|
||||
$this->addDescriptor($desc);
|
||||
}
|
||||
unset($desc);
|
||||
|
||||
foreach ($file->getEnumType() as &$desc) {
|
||||
foreach ($file->getEnumType() as $desc) {
|
||||
$this->addEnumDescriptor($desc);
|
||||
}
|
||||
unset($desc);
|
||||
|
||||
foreach ($file->getMessageType() as &$desc) {
|
||||
foreach ($file->getMessageType() as $desc) {
|
||||
$this->crossLink($desc);
|
||||
}
|
||||
unset($desc);
|
||||
@ -129,9 +129,9 @@ class DescriptorPool
|
||||
return $this->class_to_enum_desc[$klass];
|
||||
}
|
||||
|
||||
private function crossLink(&$desc)
|
||||
private function crossLink(Descriptor $desc)
|
||||
{
|
||||
foreach ($desc->getField() as &$field) {
|
||||
foreach ($desc->getField() as $field) {
|
||||
switch ($field->getType()) {
|
||||
case GPBType::MESSAGE:
|
||||
$proto = $field->getMessageType();
|
||||
@ -149,7 +149,7 @@ class DescriptorPool
|
||||
}
|
||||
unset($field);
|
||||
|
||||
foreach ($desc->getNestedType() as &$nested_type) {
|
||||
foreach ($desc->getNestedType() as $nested_type) {
|
||||
$this->crossLink($nested_type);
|
||||
}
|
||||
unset($nested_type);
|
||||
@ -157,7 +157,7 @@ class DescriptorPool
|
||||
|
||||
public function finish()
|
||||
{
|
||||
foreach ($this->class_to_desc as $klass => &$desc) {
|
||||
foreach ($this->class_to_desc as $klass => $desc) {
|
||||
$this->crossLink($desc);
|
||||
}
|
||||
unset($desc);
|
||||
|
@ -33,7 +33,7 @@
|
||||
namespace Google\Protobuf\Internal;
|
||||
|
||||
use Google\Protobuf\Internal\EnumDescriptor;
|
||||
use Google\Protobuf\Internal\EnumValueDescriptor;
|
||||
use Google\Protobuf\EnumValueDescriptor;
|
||||
|
||||
class EnumBuilderContext
|
||||
{
|
||||
@ -51,7 +51,7 @@ class EnumBuilderContext
|
||||
|
||||
public function value($name, $number)
|
||||
{
|
||||
$value = new EnumValueDescriptor();
|
||||
$value = new EnumValueDescriptor($name, $number);
|
||||
$this->descriptor->addValue($number, $value);
|
||||
return $this;
|
||||
}
|
||||
|
@ -2,13 +2,22 @@
|
||||
|
||||
namespace Google\Protobuf\Internal;
|
||||
|
||||
use Google\Protobuf\EnumValueDescriptor;
|
||||
|
||||
class EnumDescriptor
|
||||
{
|
||||
use HasPublicDescriptorTrait;
|
||||
|
||||
private $klass;
|
||||
private $full_name;
|
||||
private $value;
|
||||
private $name_to_value;
|
||||
private $value_descriptor = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->public_desc = new \Google\Protobuf\EnumDescriptor($this);
|
||||
}
|
||||
|
||||
public function setFullName($full_name)
|
||||
{
|
||||
@ -24,6 +33,7 @@ class EnumDescriptor
|
||||
{
|
||||
$this->value[$number] = $value;
|
||||
$this->name_to_value[$value->getName()] = $value;
|
||||
$this->value_descriptor[] = new EnumValueDescriptor($value->getName(), $number);
|
||||
}
|
||||
|
||||
public function getValueByNumber($number)
|
||||
@ -36,6 +46,16 @@ class EnumDescriptor
|
||||
return $this->name_to_value[$name];
|
||||
}
|
||||
|
||||
public function getValueDescriptorByIndex($index)
|
||||
{
|
||||
return $this->value_descriptor[$index];
|
||||
}
|
||||
|
||||
public function getValueCount()
|
||||
{
|
||||
return count($this->value);
|
||||
}
|
||||
|
||||
public function setClass($klass)
|
||||
{
|
||||
$this->klass = $klass;
|
||||
|
@ -34,6 +34,7 @@ namespace Google\Protobuf\Internal;
|
||||
|
||||
class FieldDescriptor
|
||||
{
|
||||
use HasPublicDescriptorTrait;
|
||||
|
||||
private $name;
|
||||
private $json_name;
|
||||
@ -48,6 +49,11 @@ class FieldDescriptor
|
||||
private $is_map;
|
||||
private $oneof_index = -1;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->public_desc = new \Google\Protobuf\FieldDescriptor($this);
|
||||
}
|
||||
|
||||
public function setOneofIndex($index)
|
||||
{
|
||||
$this->oneof_index = $index;
|
||||
|
@ -38,7 +38,7 @@ use Google\Protobuf\Internal\MapField;
|
||||
|
||||
class GPBUtil
|
||||
{
|
||||
public function divideInt64ToInt32($value, &$high, &$low, $trim = false)
|
||||
public static function divideInt64ToInt32($value, &$high, &$low, $trim = false)
|
||||
{
|
||||
$isNeg = (bccomp($value, 0) < 0);
|
||||
if ($isNeg) {
|
||||
|
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace Google\Protobuf\Internal;
|
||||
|
||||
trait GetPublicDescriptorTrait
|
||||
{
|
||||
private function getPublicDescriptor($desc)
|
||||
{
|
||||
return is_null($desc) ? null : $desc->getPublicDescriptor();
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace Google\Protobuf\Internal;
|
||||
|
||||
trait HasPublicDescriptorTrait
|
||||
{
|
||||
private $public_desc;
|
||||
|
||||
public function getPublicDescriptor()
|
||||
{
|
||||
return $this->public_desc;
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ class MapEntry extends Message
|
||||
public $key;
|
||||
public $value;
|
||||
|
||||
public function setKey(&$key) {
|
||||
public function setKey($key) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ class MapEntry extends Message
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function setValue(&$value) {
|
||||
public function setValue($value) {
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
@ -841,7 +841,6 @@ class Message
|
||||
if (is_null($value)) {
|
||||
continue;
|
||||
}
|
||||
$getter = $field->getGetter();
|
||||
$key_field = $field->getMessageType()->getFieldByNumber(1);
|
||||
$value_field = $field->getMessageType()->getFieldByNumber(2);
|
||||
foreach ($value as $tmp_key => $tmp_value) {
|
||||
@ -858,13 +857,12 @@ class Message
|
||||
$this->convertJsonValueToProtoValue(
|
||||
$tmp_value,
|
||||
$value_field);
|
||||
$this->$getter()[$proto_key] = $proto_value;
|
||||
self::kvUpdateHelper($field, $proto_key, $proto_value);
|
||||
}
|
||||
} else if ($field->isRepeated()) {
|
||||
if (is_null($value)) {
|
||||
continue;
|
||||
}
|
||||
$getter = $field->getGetter();
|
||||
foreach ($value as $tmp) {
|
||||
if (is_null($tmp)) {
|
||||
throw new \Exception(
|
||||
@ -872,7 +870,7 @@ class Message
|
||||
}
|
||||
$proto_value =
|
||||
$this->convertJsonValueToProtoValue($tmp, $field);
|
||||
$this->$getter()[] = $proto_value;
|
||||
self::appendHelper($field, $proto_value);
|
||||
}
|
||||
} else {
|
||||
$setter = $field->getSetter();
|
||||
|
@ -34,10 +34,16 @@ namespace Google\Protobuf\Internal;
|
||||
|
||||
class OneofDescriptor
|
||||
{
|
||||
use HasPublicDescriptorTrait;
|
||||
|
||||
private $name;
|
||||
private $fields;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->public_desc = new \Google\Protobuf\OneofDescriptor($this);
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
@ -48,7 +54,7 @@ class OneofDescriptor
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function addField(&$field)
|
||||
public function addField(FieldDescriptor $field)
|
||||
{
|
||||
$this->fields[] = $field;
|
||||
}
|
||||
@ -58,10 +64,15 @@ class OneofDescriptor
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
public static function buildFromProto($oneof_proto)
|
||||
public static function buildFromProto($oneof_proto, $desc, $index)
|
||||
{
|
||||
$oneof = new OneofDescriptor();
|
||||
$oneof->setName($oneof_proto->getName());
|
||||
foreach ($desc->getField() as $field) {
|
||||
if ($field->getOneofIndex() == $index) {
|
||||
$oneof->addField($field);
|
||||
}
|
||||
}
|
||||
return $oneof;
|
||||
}
|
||||
}
|
||||
|
75
php/src/Google/Protobuf/OneofDescriptor.php
Normal file
75
php/src/Google/Protobuf/OneofDescriptor.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace Google\Protobuf;
|
||||
|
||||
use Google\Protobuf\Internal\GetPublicDescriptorTrait;
|
||||
|
||||
class OneofDescriptor
|
||||
{
|
||||
use GetPublicDescriptorTrait;
|
||||
|
||||
private $internal_desc;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __construct($internal_desc)
|
||||
{
|
||||
$this->internal_desc = $internal_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The name of the oneof
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->internal_desc->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index Must be >= 0 and < getFieldCount()
|
||||
* @return FieldDescriptor
|
||||
*/
|
||||
public function getField($index)
|
||||
{
|
||||
return $this->getPublicDescriptor($this->internal_desc->getFields()[$index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int Number of fields in the oneof
|
||||
*/
|
||||
public function getFieldCount()
|
||||
{
|
||||
return count($this->internal_desc->getFields());
|
||||
}
|
||||
}
|
246
php/tests/descriptors_test.php
Normal file
246
php/tests/descriptors_test.php
Normal file
@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
require_once('generated/Descriptors/TestDescriptorsEnum.php');
|
||||
require_once('generated/Descriptors/TestDescriptorsMessage.php');
|
||||
require_once('test_base.php');
|
||||
require_once('test_util.php');
|
||||
|
||||
use Google\Protobuf\DescriptorPool;
|
||||
use Google\Protobuf\Internal\RepeatedField;
|
||||
use Google\Protobuf\Internal\MapField;
|
||||
use Descriptors\TestDescriptorsEnum;
|
||||
use Descriptors\TestDescriptorsMessage;
|
||||
use Descriptors\TestDescriptorsMessage_Sub;
|
||||
|
||||
class DescriptorsTest extends TestBase
|
||||
{
|
||||
|
||||
// Redefine these here for compatibility with c extension
|
||||
const GPBLABEL_OPTIONAL = 1;
|
||||
const GPBLABEL_REQUIRED = 2;
|
||||
const GPBLABEL_REPEATED = 3;
|
||||
|
||||
const GPBTYPE_DOUBLE = 1;
|
||||
const GPBTYPE_FLOAT = 2;
|
||||
const GPBTYPE_INT64 = 3;
|
||||
const GPBTYPE_UINT64 = 4;
|
||||
const GPBTYPE_INT32 = 5;
|
||||
const GPBTYPE_FIXED64 = 6;
|
||||
const GPBTYPE_FIXED32 = 7;
|
||||
const GPBTYPE_BOOL = 8;
|
||||
const GPBTYPE_STRING = 9;
|
||||
const GPBTYPE_GROUP = 10;
|
||||
const GPBTYPE_MESSAGE = 11;
|
||||
const GPBTYPE_BYTES = 12;
|
||||
const GPBTYPE_UINT32 = 13;
|
||||
const GPBTYPE_ENUM = 14;
|
||||
const GPBTYPE_SFIXED32 = 15;
|
||||
const GPBTYPE_SFIXED64 = 16;
|
||||
const GPBTYPE_SINT32 = 17;
|
||||
const GPBTYPE_SINT64 = 18;
|
||||
|
||||
#########################################################
|
||||
# Test descriptor pool.
|
||||
#########################################################
|
||||
|
||||
public function testDescriptorPool()
|
||||
{
|
||||
$pool = DescriptorPool::getGeneratedPool();
|
||||
|
||||
$desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
|
||||
$this->assertInstanceOf('\Google\Protobuf\Descriptor', $desc);
|
||||
|
||||
$enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsEnum()));
|
||||
$this->assertInstanceOf('\Google\Protobuf\EnumDescriptor', $enumDesc);
|
||||
}
|
||||
|
||||
public function testDescriptorPoolIncorrectArgs()
|
||||
{
|
||||
$pool = DescriptorPool::getGeneratedPool();
|
||||
|
||||
$desc = $pool->getDescriptorByClassName('NotAClass');
|
||||
$this->assertNull($desc);
|
||||
|
||||
$desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsEnum()));
|
||||
$this->assertNull($desc);
|
||||
|
||||
$enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsMessage()));
|
||||
$this->assertNull($enumDesc);
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Test descriptor.
|
||||
#########################################################
|
||||
|
||||
public function testDescriptor()
|
||||
{
|
||||
$pool = DescriptorPool::getGeneratedPool();
|
||||
$class = get_class(new TestDescriptorsMessage());
|
||||
$this->assertSame('Descriptors\TestDescriptorsMessage', $class);
|
||||
$desc = $pool->getDescriptorByClassName($class);
|
||||
|
||||
$this->assertSame('descriptors.TestDescriptorsMessage', $desc->getFullName());
|
||||
$this->assertSame($class, $desc->getClass());
|
||||
|
||||
$this->assertInstanceOf('\Google\Protobuf\FieldDescriptor', $desc->getField(0));
|
||||
$this->assertSame(7, $desc->getFieldCount());
|
||||
|
||||
$this->assertInstanceOf('\Google\Protobuf\OneofDescriptor', $desc->getOneofDecl(0));
|
||||
$this->assertSame(1, $desc->getOneofDeclCount());
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Test enum descriptor.
|
||||
#########################################################
|
||||
|
||||
public function testEnumDescriptor()
|
||||
{
|
||||
// WARNINIG - we need to do this so that TestDescriptorsEnum is registered!!?
|
||||
new TestDescriptorsMessage();
|
||||
|
||||
$pool = DescriptorPool::getGeneratedPool();
|
||||
|
||||
$enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsEnum()));
|
||||
|
||||
// Build map of enum values
|
||||
$enumDescMap = [];
|
||||
for ($i = 0; $i < $enumDesc->getValueCount(); $i++) {
|
||||
$enumValueDesc = $enumDesc->getValue($i);
|
||||
$this->assertInstanceOf('\Google\Protobuf\EnumValueDescriptor', $enumValueDesc);
|
||||
$enumDescMap[$enumValueDesc->getNumber()] = $enumValueDesc->getName();
|
||||
}
|
||||
|
||||
$this->assertSame('ZERO', $enumDescMap[0]);
|
||||
$this->assertSame('ONE', $enumDescMap[1]);
|
||||
|
||||
$this->assertSame(2, $enumDesc->getValueCount());
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Test field descriptor.
|
||||
#########################################################
|
||||
|
||||
public function testFieldDescriptor()
|
||||
{
|
||||
$pool = DescriptorPool::getGeneratedPool();
|
||||
$desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
|
||||
|
||||
$fieldDescMap = $this->buildFieldMap($desc);
|
||||
|
||||
// Optional int field
|
||||
$fieldDesc = $fieldDescMap[1];
|
||||
$this->assertSame('optional_int32', $fieldDesc->getName());
|
||||
$this->assertSame(1, $fieldDesc->getNumber());
|
||||
$this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
|
||||
$this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
|
||||
$this->assertFalse($fieldDesc->isMap());
|
||||
|
||||
// Optional enum field
|
||||
$fieldDesc = $fieldDescMap[16];
|
||||
$this->assertSame('optional_enum', $fieldDesc->getName());
|
||||
$this->assertSame(16, $fieldDesc->getNumber());
|
||||
$this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
|
||||
$this->assertSame(self::GPBTYPE_ENUM, $fieldDesc->getType());
|
||||
$this->assertInstanceOf('\Google\Protobuf\EnumDescriptor', $fieldDesc->getEnumType());
|
||||
$this->assertFalse($fieldDesc->isMap());
|
||||
|
||||
// Optional message field
|
||||
$fieldDesc = $fieldDescMap[17];
|
||||
$this->assertSame('optional_message', $fieldDesc->getName());
|
||||
$this->assertSame(17, $fieldDesc->getNumber());
|
||||
$this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
|
||||
$this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
|
||||
$this->assertInstanceOf('\Google\Protobuf\Descriptor', $fieldDesc->getMessageType());
|
||||
$this->assertFalse($fieldDesc->isMap());
|
||||
|
||||
// Repeated int field
|
||||
$fieldDesc = $fieldDescMap[31];
|
||||
$this->assertSame('repeated_int32', $fieldDesc->getName());
|
||||
$this->assertSame(31, $fieldDesc->getNumber());
|
||||
$this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
|
||||
$this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
|
||||
$this->assertFalse($fieldDesc->isMap());
|
||||
|
||||
// Repeated message field
|
||||
$fieldDesc = $fieldDescMap[47];
|
||||
$this->assertSame('repeated_message', $fieldDesc->getName());
|
||||
$this->assertSame(47, $fieldDesc->getNumber());
|
||||
$this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
|
||||
$this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
|
||||
$this->assertInstanceOf('\Google\Protobuf\Descriptor', $fieldDesc->getMessageType());
|
||||
$this->assertFalse($fieldDesc->isMap());
|
||||
|
||||
// Oneof int field
|
||||
// Tested further in testOneofDescriptor()
|
||||
$fieldDesc = $fieldDescMap[51];
|
||||
$this->assertSame('oneof_int32', $fieldDesc->getName());
|
||||
$this->assertSame(51, $fieldDesc->getNumber());
|
||||
$this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
|
||||
$this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
|
||||
$this->assertFalse($fieldDesc->isMap());
|
||||
|
||||
// Map int-enum field
|
||||
$fieldDesc = $fieldDescMap[71];
|
||||
$this->assertSame('map_int32_enum', $fieldDesc->getName());
|
||||
$this->assertSame(71, $fieldDesc->getNumber());
|
||||
$this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
|
||||
$this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
|
||||
$this->assertTrue($fieldDesc->isMap());
|
||||
$mapDesc = $fieldDesc->getMessageType();
|
||||
$this->assertSame('descriptors.TestDescriptorsMessage.MapInt32EnumEntry', $mapDesc->getFullName());
|
||||
$this->assertSame(self::GPBTYPE_INT32, $mapDesc->getField(0)->getType());
|
||||
$this->assertSame(self::GPBTYPE_ENUM, $mapDesc->getField(1)->getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
*/
|
||||
public function testFieldDescriptorEnumException()
|
||||
{
|
||||
$pool = DescriptorPool::getGeneratedPool();
|
||||
$desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
|
||||
$fieldDesc = $desc->getField(0);
|
||||
$fieldDesc->getEnumType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
*/
|
||||
public function testFieldDescriptorMessageException()
|
||||
{
|
||||
$pool = DescriptorPool::getGeneratedPool();
|
||||
$desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
|
||||
$fieldDesc = $desc->getField(0);
|
||||
$fieldDesc->getMessageType();
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Test oneof descriptor.
|
||||
#########################################################
|
||||
|
||||
public function testOneofDescriptor()
|
||||
{
|
||||
$pool = DescriptorPool::getGeneratedPool();
|
||||
$desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
|
||||
|
||||
$fieldDescMap = $this->buildFieldMap($desc);
|
||||
$fieldDesc = $fieldDescMap[51];
|
||||
|
||||
$oneofDesc = $desc->getOneofDecl(0);
|
||||
|
||||
$this->assertSame('my_oneof', $oneofDesc->getName());
|
||||
$fieldDescFromOneof = $oneofDesc->getField(0);
|
||||
$this->assertSame($fieldDesc, $fieldDescFromOneof);
|
||||
$this->assertSame(1, $oneofDesc->getFieldCount());
|
||||
}
|
||||
|
||||
private function buildFieldMap($desc)
|
||||
{
|
||||
$fieldDescMap = [];
|
||||
for ($i = 0; $i < $desc->getFieldCount(); $i++) {
|
||||
$fieldDesc = $desc->getField($i);
|
||||
$fieldDescMap[$fieldDesc->getNumber()] = $fieldDesc;
|
||||
}
|
||||
return $fieldDescMap;
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ use Foo\TestIncludeNamespaceMessage;
|
||||
use Foo\TestIncludePrefixMessage;
|
||||
use Foo\TestMessage;
|
||||
use Foo\TestMessage_Sub;
|
||||
use Foo\TestReverseFieldOrder;
|
||||
use Php\Test\TestNamespace;
|
||||
|
||||
class GeneratedClassTest extends TestBase
|
||||
@ -702,4 +703,16 @@ class GeneratedClassTest extends TestBase
|
||||
$this->assertSame(1, $m->getOptionalInt32());
|
||||
$this->assertSame(2, $m->getOptionalUInt32());
|
||||
}
|
||||
|
||||
#########################################################
|
||||
# Test Reverse Field Order.
|
||||
#########################################################
|
||||
|
||||
public function testReverseFieldOrder()
|
||||
{
|
||||
$m = new TestReverseFieldOrder();
|
||||
$m->setB("abc");
|
||||
$this->assertSame("abc", $m->getB());
|
||||
$this->assertNotSame("abc", $m->getA());
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ require_once('generated/Foo/TestMessage_Sub.php');
|
||||
require_once('generated/Foo/TestPackedMessage.php');
|
||||
require_once('generated/Foo/TestPhpDoc.php');
|
||||
require_once('generated/Foo/TestRandomFieldOrder.php');
|
||||
require_once('generated/Foo/TestReverseFieldOrder.php');
|
||||
require_once('generated/Foo/TestUnpackedMessage.php');
|
||||
require_once('generated/GPBMetadata/Proto/Test.php');
|
||||
require_once('generated/GPBMetadata/Proto/TestEmptyPhpNamespace.php');
|
||||
|
@ -187,3 +187,8 @@ message TestRandomFieldOrder {
|
||||
int64 tag13 = 150;
|
||||
string tag14 = 160;
|
||||
}
|
||||
|
||||
message TestReverseFieldOrder {
|
||||
repeated int32 a = 2;
|
||||
string b = 1;
|
||||
}
|
||||
|
35
php/tests/proto/test_descriptors.proto
Normal file
35
php/tests/proto/test_descriptors.proto
Normal file
@ -0,0 +1,35 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package descriptors;
|
||||
|
||||
message TestDescriptorsMessage {
|
||||
int32 optional_int32 = 1;
|
||||
TestDescriptorsEnum optional_enum = 16;
|
||||
Sub optional_message = 17;
|
||||
|
||||
// Repeated
|
||||
repeated int32 repeated_int32 = 31;
|
||||
repeated Sub repeated_message = 47;
|
||||
|
||||
oneof my_oneof {
|
||||
int32 oneof_int32 = 51;
|
||||
}
|
||||
|
||||
map<int32, EnumSub> map_int32_enum = 71;
|
||||
|
||||
message Sub {
|
||||
int32 a = 1;
|
||||
repeated int32 b = 2;
|
||||
}
|
||||
|
||||
enum EnumSub {
|
||||
ZERO = 0;
|
||||
ONE = 1;
|
||||
}
|
||||
}
|
||||
|
||||
enum TestDescriptorsEnum {
|
||||
ZERO = 0;
|
||||
ONE = 1;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ set -e
|
||||
phpize && ./configure CFLAGS='-g -O0' && make
|
||||
popd
|
||||
|
||||
tests=( array_test.php encode_decode_test.php generated_class_test.php generated_phpdoc_test.php map_field_test.php well_known_test.php generated_service_test.php )
|
||||
tests=( array_test.php encode_decode_test.php generated_class_test.php generated_phpdoc_test.php map_field_test.php well_known_test.php generated_service_test.php descriptors_test.php )
|
||||
|
||||
for t in "${tests[@]}"
|
||||
do
|
||||
|
@ -197,6 +197,7 @@ string ModuleAlias(const string& filename) {
|
||||
string basename = StripProto(filename);
|
||||
StripString(&basename, "-", '$');
|
||||
StripString(&basename, "/", '_');
|
||||
StripString(&basename, ".", '_');
|
||||
return basename + "_pb";
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ syntax = "proto3";
|
||||
|
||||
package protobuf_test_messages.proto3;
|
||||
option java_package = "com.google.protobuf_test_messages.proto3";
|
||||
option objc_class_prefix = "Proto3";
|
||||
|
||||
// This is the default, but we specify it here explicitly.
|
||||
option optimize_for = SPEED;
|
||||
|
11
tests.sh
11
tests.sh
@ -347,7 +347,16 @@ generate_php_test_proto() {
|
||||
# Generate test file
|
||||
rm -rf generated
|
||||
mkdir generated
|
||||
../../src/protoc --php_out=generated proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto proto/test_php_namespace.proto proto/test_empty_php_namespace.proto proto/test_service.proto proto/test_service_namespace.proto
|
||||
../../src/protoc --php_out=generated \
|
||||
proto/test.proto \
|
||||
proto/test_include.proto \
|
||||
proto/test_no_namespace.proto \
|
||||
proto/test_prefix.proto \
|
||||
proto/test_php_namespace.proto \
|
||||
proto/test_empty_php_namespace.proto \
|
||||
proto/test_service.proto \
|
||||
proto/test_service_namespace.proto \
|
||||
proto/test_descriptors.proto
|
||||
pushd ../../src
|
||||
./protoc --php_out=../php/tests/generated google/protobuf/empty.proto
|
||||
./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto
|
||||
|
Loading…
Reference in New Issue
Block a user