|  | @@ -84,33 +84,6 @@ std::string RenameEmpty(const std::string& name) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -std::string MessagePrefix(const Descriptor* message) {
 | 
	
		
			
				|  |  | -  // Empty cannot be php class name.
 | 
	
		
			
				|  |  | -  if (message->name() == "Empty" &&
 | 
	
		
			
				|  |  | -      message->file()->package() == "google.protobuf") {
 | 
	
		
			
				|  |  | -    return "GPB";
 | 
	
		
			
				|  |  | -  } else {
 | 
	
		
			
				|  |  | -    return (message->file()->options()).php_class_prefix();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -std::string MessageName(const Descriptor* message, bool is_descriptor) {
 | 
	
		
			
				|  |  | -  string message_name = message->name();
 | 
	
		
			
				|  |  | -  const Descriptor* descriptor = message->containing_type();
 | 
	
		
			
				|  |  | -  while (descriptor != NULL) {
 | 
	
		
			
				|  |  | -    message_name = descriptor->name() + '_' + message_name;
 | 
	
		
			
				|  |  | -    descriptor = descriptor->containing_type();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  message_name = MessagePrefix(message) + message_name;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if (message->file()->package() == "") {
 | 
	
		
			
				|  |  | -    return message_name;
 | 
	
		
			
				|  |  | -  } else {
 | 
	
		
			
				|  |  | -    return PhpName(message->file()->package(), is_descriptor) + '\\' +
 | 
	
		
			
				|  |  | -           message_name;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  std::string MessageFullName(const Descriptor* message, bool is_descriptor) {
 | 
	
		
			
				|  |  |    if (is_descriptor) {
 | 
	
		
			
				|  |  |      return StringReplace(message->full_name(),
 | 
	
	
		
			
				|  | @@ -131,19 +104,34 @@ std::string EnumFullName(const EnumDescriptor* envm, bool is_descriptor) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -std::string EnumClassName(const EnumDescriptor* envm) {
 | 
	
		
			
				|  |  | -  string enum_class_name = envm->name();
 | 
	
		
			
				|  |  | -  const Descriptor* descriptor = envm->containing_type();
 | 
	
		
			
				|  |  | -  while (descriptor != NULL) {
 | 
	
		
			
				|  |  | -    enum_class_name = descriptor->name() + '_' + enum_class_name;
 | 
	
		
			
				|  |  | -    descriptor = descriptor->containing_type();
 | 
	
		
			
				|  |  | +template <typename DescriptorType>
 | 
	
		
			
				|  |  | +std::string ClassNamePrefix(const DescriptorType* desc) {
 | 
	
		
			
				|  |  | +  // Empty cannot be php class name.
 | 
	
		
			
				|  |  | +  if (desc->name() == "Empty" &&
 | 
	
		
			
				|  |  | +      desc->file()->package() == "google.protobuf") {
 | 
	
		
			
				|  |  | +    return "GPB";
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    return (desc->file()->options()).php_class_prefix();
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  return enum_class_name;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -std::string EnumName(const EnumDescriptor* envm, bool is_descriptor) {
 | 
	
		
			
				|  |  | -  string enum_name = EnumClassName(envm);
 | 
	
		
			
				|  |  | -  return PhpName(envm->file()->package(), is_descriptor) + '\\' + enum_name;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +template <typename DescriptorType>
 | 
	
		
			
				|  |  | +std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
 | 
	
		
			
				|  |  | +  string classname = desc->name();
 | 
	
		
			
				|  |  | +  const Descriptor* containing = desc->containing_type();
 | 
	
		
			
				|  |  | +  while (containing != NULL) {
 | 
	
		
			
				|  |  | +    classname = containing->name() + '_' + classname;
 | 
	
		
			
				|  |  | +    containing = containing->containing_type();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  classname = ClassNamePrefix(desc) + classname;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (desc->file()->package() == "") {
 | 
	
		
			
				|  |  | +    return classname;
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    return PhpName(desc->file()->package(), is_descriptor) + '\\' +
 | 
	
		
			
				|  |  | +           classname;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  std::string PhpName(const std::string& full_name, bool is_descriptor) {
 | 
	
	
		
			
				|  | @@ -231,7 +219,7 @@ std::string GeneratedMetadataFileName(const std::string& proto_file,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  std::string GeneratedMessageFileName(const Descriptor* message,
 | 
	
		
			
				|  |  |                                       bool is_descriptor) {
 | 
	
		
			
				|  |  | -  std::string result = MessageName(message, is_descriptor);
 | 
	
		
			
				|  |  | +  std::string result = FullClassName(message, is_descriptor);
 | 
	
		
			
				|  |  |    for (int i = 0; i < result.size(); i++) {
 | 
	
		
			
				|  |  |      if (result[i] == '\\') {
 | 
	
		
			
				|  |  |        result[i] = '/';
 | 
	
	
		
			
				|  | @@ -242,7 +230,7 @@ std::string GeneratedMessageFileName(const Descriptor* message,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  std::string GeneratedEnumFileName(const EnumDescriptor* en,
 | 
	
		
			
				|  |  |                                    bool is_descriptor) {
 | 
	
		
			
				|  |  | -  std::string result = EnumName(en, is_descriptor);
 | 
	
		
			
				|  |  | +  std::string result = FullClassName(en, is_descriptor);
 | 
	
		
			
				|  |  |    for (int i = 0; i < result.size(); i++) {
 | 
	
		
			
				|  |  |      if (result[i] == '\\') {
 | 
	
		
			
				|  |  |        result[i] = '/';
 | 
	
	
		
			
				|  | @@ -456,12 +444,12 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor,
 | 
	
		
			
				|  |  |        printer->Print(
 | 
	
		
			
				|  |  |            ", \\^class_name^);\n",
 | 
	
		
			
				|  |  |            "class_name",
 | 
	
		
			
				|  |  | -          MessageName(value->message_type(), is_descriptor) + "::class");
 | 
	
		
			
				|  |  | +          FullClassName(value->message_type(), is_descriptor) + "::class");
 | 
	
		
			
				|  |  |      } else if (value->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
 | 
	
		
			
				|  |  |        printer->Print(
 | 
	
		
			
				|  |  | -          ", ^class_name^);\n",
 | 
	
		
			
				|  |  | +          ", \\^class_name^);\n",
 | 
	
		
			
				|  |  |            "class_name",
 | 
	
		
			
				|  |  | -          EnumName(value->enum_type(), is_descriptor) + "::class");
 | 
	
		
			
				|  |  | +          FullClassName(value->enum_type(), is_descriptor) + "::class");
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  |        printer->Print(");\n");
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -474,23 +462,23 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor,
 | 
	
		
			
				|  |  |        printer->Print(
 | 
	
		
			
				|  |  |            ", \\^class_name^);\n",
 | 
	
		
			
				|  |  |            "class_name",
 | 
	
		
			
				|  |  | -          MessageName(field->message_type(), is_descriptor) + "::class");
 | 
	
		
			
				|  |  | +          FullClassName(field->message_type(), is_descriptor) + "::class");
 | 
	
		
			
				|  |  |      } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
 | 
	
		
			
				|  |  |        printer->Print(
 | 
	
		
			
				|  |  | -          ", ^class_name^);\n",
 | 
	
		
			
				|  |  | +          ", \\^class_name^);\n",
 | 
	
		
			
				|  |  |            "class_name",
 | 
	
		
			
				|  |  | -          EnumName(field->enum_type(), is_descriptor) + "::class");
 | 
	
		
			
				|  |  | +          FullClassName(field->enum_type(), is_descriptor) + "::class");
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  |        printer->Print(");\n");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 | 
	
		
			
				|  |  |      printer->Print(
 | 
	
		
			
				|  |  |          "GPBUtil::checkMessage($var, \\^class_name^::class);\n",
 | 
	
		
			
				|  |  | -        "class_name", MessageName(field->message_type(), is_descriptor));
 | 
	
		
			
				|  |  | +        "class_name", FullClassName(field->message_type(), is_descriptor));
 | 
	
		
			
				|  |  |    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
 | 
	
		
			
				|  |  |      printer->Print(
 | 
	
		
			
				|  |  |          "GPBUtil::checkEnum($var, \\^class_name^::class);\n",
 | 
	
		
			
				|  |  | -        "class_name", EnumName(field->enum_type(), is_descriptor));
 | 
	
		
			
				|  |  | +        "class_name", FullClassName(field->enum_type(), is_descriptor));
 | 
	
		
			
				|  |  |    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
 | 
	
		
			
				|  |  |      printer->Print(
 | 
	
		
			
				|  |  |          "GPBUtil::checkString($var, ^utf8^);\n",
 |