@@ -828,9 +828,11 @@ static void fill_segment(const char *segment, int length,
828828static void fill_namespace (const char * package , const char * php_namespace ,
829829 stringsink * classname ) {
830830 if (php_namespace != NULL ) {
831- stringsink_string (classname , NULL , php_namespace , strlen (php_namespace ),
832- NULL );
833- stringsink_string (classname , NULL , "\\" , 1 , NULL );
831+ if (strlen (php_namespace ) != 0 ) {
832+ stringsink_string (classname , NULL , php_namespace , strlen (php_namespace ),
833+ NULL );
834+ stringsink_string (classname , NULL , "\\" , 1 , NULL );
835+ }
834836 } else if (package != NULL ) {
835837 int i = 0 , j , offset = 0 ;
836838 size_t package_len = strlen (package );
@@ -882,11 +884,23 @@ static void fill_classname(const char *fullname,
882884 }
883885}
884886
885- static zend_class_entry * register_class (const upb_filedef * file ,
886- const char * fullname ,
887- PHP_PROTO_HASHTABLE_VALUE desc_php ,
888- bool use_nested_submsg ,
889- bool is_enum TSRMLS_DC ) {
887+ static void fill_classname_for_desc (void * desc , bool is_enum ) {
888+ const upb_filedef * file ;
889+ const char * fullname ;
890+ bool use_nested_submsg ;
891+
892+ if (is_enum ) {
893+ EnumDescriptorInternal * enumdesc = desc ;
894+ file = upb_enumdef_file (enumdesc -> enumdef );
895+ fullname = upb_enumdef_fullname (enumdesc -> enumdef );
896+ use_nested_submsg = enumdesc -> use_nested_submsg ;
897+ } else {
898+ DescriptorInternal * msgdesc = desc ;
899+ file = upb_msgdef_file (msgdesc -> msgdef );
900+ fullname = upb_msgdef_fullname (msgdesc -> msgdef );
901+ use_nested_submsg = msgdesc -> use_nested_submsg ;
902+ }
903+
890904 // Prepend '.' to package name to make it absolute. In the 5 additional
891905 // bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if
892906 // given message is google.protobuf.Empty.
@@ -896,36 +910,75 @@ static zend_class_entry *register_class(const upb_filedef *file,
896910 size_t classname_len =
897911 classname_len_max (fullname , package , php_namespace , prefix );
898912 char * after_package ;
899- zend_class_entry * ret ;
900913 stringsink namesink ;
901914 stringsink_init (& namesink );
902915
903916 fill_namespace (package , php_namespace , & namesink );
904917 fill_classname (fullname , package , prefix , & namesink , use_nested_submsg );
905918 stringsink_string (& namesink , NULL , "\0" , 1 , NULL );
906919
920+ if (is_enum ) {
921+ EnumDescriptorInternal * enumdesc = desc ;
922+ enumdesc -> classname = strdup (namesink .ptr );
923+ } else {
924+ DescriptorInternal * msgdesc = desc ;
925+ msgdesc -> classname = strdup (namesink .ptr );
926+ }
927+
928+ stringsink_uninit (& namesink );
929+ }
930+
931+ void register_class (void * desc , bool is_enum TSRMLS_DC ) {
932+ const char * classname ;
933+ const char * fullname ;
934+ zend_class_entry * ret ;
935+
936+ if (is_enum ) {
937+ EnumDescriptorInternal * enumdesc = desc ;
938+ if (enumdesc -> klass ) {
939+ return ;
940+ }
941+ classname = enumdesc -> classname ;
942+ fullname = upb_enumdef_fullname (enumdesc -> enumdef );
943+ } else {
944+ DescriptorInternal * msgdesc = desc ;
945+ if (msgdesc -> klass ) {
946+ return ;
947+ }
948+ if (!msgdesc -> classname ) {
949+ return ;
950+ }
951+ classname = msgdesc -> classname ;
952+ fullname = upb_msgdef_fullname (msgdesc -> msgdef );
953+ }
954+
907955 PHP_PROTO_CE_DECLARE pce ;
908- if (php_proto_zend_lookup_class (namesink . ptr , namesink . len - 1 , & pce ) ==
956+ if (php_proto_zend_lookup_class (classname , strlen ( classname ) , & pce ) ==
909957 FAILURE ) {
910958 zend_error (
911959 E_ERROR ,
912- "Generated message class %s hasn't been defined (%s, %s, %s, %s )" ,
913- namesink . ptr , fullname , package , php_namespace , prefix );
914- return NULL ;
960+ "Generated message class %s hasn't been defined (%s)" ,
961+ classname );
962+ return ;
915963 }
916964 ret = PHP_PROTO_CE_UNREF (pce );
917- add_ce_obj (ret , desc_php );
918965 if (is_enum ) {
919- EnumDescriptor * desc = UNBOX_HASHTABLE_VALUE (EnumDescriptor , desc_php );
920- add_ce_enumdesc (ret , desc -> intern );
921- add_proto_enumdesc (fullname , desc -> intern );
966+ EnumDescriptorInternal * enumdesc = desc ;
967+ add_ce_enumdesc (ret , desc );
968+ add_proto_enumdesc (fullname , desc );
969+ enumdesc -> klass = ret ;
922970 } else {
923- Descriptor * desc = UNBOX_HASHTABLE_VALUE (Descriptor , desc_php );
924- add_ce_desc (ret , desc -> intern );
925- add_proto_desc (fullname , desc -> intern );
971+ DescriptorInternal * msgdesc = desc ;
972+ add_ce_desc (ret , desc );
973+ msgdesc -> klass = ret ;
974+ // Map entries don't have existing php class.
975+ if (!upb_msgdef_mapentry (msgdesc -> msgdef )) {
976+ if (msgdesc -> layout == NULL ) {
977+ MessageLayout * layout = create_layout (msgdesc -> msgdef );
978+ msgdesc -> layout = layout ;
979+ }
980+ }
926981 }
927- stringsink_uninit (& namesink );
928- return ret ;
929982}
930983
931984bool depends_on_descriptor (const google_protobuf_FileDescriptorProto * file ) {
@@ -1019,6 +1072,8 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
10191072 desc -> intern -> pool = pool ;
10201073 desc -> intern -> layout = NULL ;
10211074 desc -> intern -> klass = NULL ;
1075+ desc -> intern -> use_nested_submsg = use_nested_submsg ;
1076+ desc -> intern -> classname = NULL ;
10221077
10231078 add_def_obj (desc -> intern -> msgdef , desc_php );
10241079 add_msgdef_desc (desc -> intern -> msgdef , desc -> intern );
@@ -1029,15 +1084,9 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
10291084 continue ;
10301085 }
10311086
1032- desc -> intern -> klass =
1033- register_class (file , upb_msgdef_fullname (msgdef ), desc_php ,
1034- use_nested_submsg , false TSRMLS_CC );
1035-
1036- if (desc -> intern -> klass == NULL ) {
1037- return ;
1038- }
1039-
1040- build_class_from_descriptor (desc_php TSRMLS_CC );
1087+ fill_classname_for_desc (desc -> intern , false);
1088+ add_class_desc (desc -> intern -> classname , desc -> intern );
1089+ add_proto_desc (upb_msgdef_fullname (desc -> intern -> msgdef ), desc -> intern );
10411090 }
10421091
10431092 for (i = 0 ; i < upb_filedef_enumcount (file ); i ++ ) {
@@ -1046,16 +1095,13 @@ void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
10461095 desc -> intern = SYS_MALLOC (EnumDescriptorInternal );
10471096 desc -> intern -> enumdef = enumdef ;
10481097 desc -> intern -> klass = NULL ;
1098+ desc -> intern -> use_nested_submsg = use_nested_submsg ;
1099+ desc -> intern -> classname = NULL ;
10491100
10501101 add_def_obj (desc -> intern -> enumdef , desc_php );
10511102 add_enumdef_enumdesc (desc -> intern -> enumdef , desc -> intern );
1052- desc -> intern -> klass =
1053- register_class (file , upb_enumdef_fullname (enumdef ), desc_php ,
1054- use_nested_submsg , true TSRMLS_CC );
1055-
1056- if (desc -> intern -> klass == NULL ) {
1057- return ;
1058- }
1103+ fill_classname_for_desc (desc -> intern , true);
1104+ add_class_enumdesc (desc -> intern -> classname , desc -> intern );
10591105 }
10601106}
10611107
@@ -1144,9 +1190,17 @@ PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName) {
11441190 RETURN_NULL ();
11451191 }
11461192
1147- PHP_PROTO_HASHTABLE_VALUE desc_php = get_ce_obj (PHP_PROTO_CE_UNREF (pce ));
1193+ zend_class_entry * ce = PHP_PROTO_CE_UNREF (pce );
1194+
1195+ PHP_PROTO_HASHTABLE_VALUE desc_php = get_ce_obj (ce );
11481196 if (desc_php == NULL ) {
1149- EnumDescriptorInternal * intern = get_ce_enumdesc (PHP_PROTO_CE_UNREF (pce ));
1197+ #if PHP_MAJOR_VERSION < 7
1198+ EnumDescriptorInternal * intern = get_class_enumdesc (ce -> name );
1199+ #else
1200+ EnumDescriptorInternal * intern = get_class_enumdesc (ZSTR_VAL (ce -> name ));
1201+ #endif
1202+ register_class (intern , true TSRMLS_CC );
1203+
11501204 if (intern == NULL ) {
11511205 RETURN_NULL ();
11521206 }
@@ -1164,7 +1218,7 @@ PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName) {
11641218 EnumDescriptor * desc = UNBOX_HASHTABLE_VALUE (EnumDescriptor , desc_php );
11651219 desc -> intern = intern ;
11661220 add_def_obj (intern -> enumdef , desc_php );
1167- add_ce_obj (PHP_PROTO_CE_UNREF ( pce ) , desc_php );
1221+ add_ce_obj (ce , desc_php );
11681222 }
11691223
11701224 zend_class_entry * instance_ce = HASHTABLE_VALUE_CE (desc_php );
0 commit comments