public static byte[] serialize(Descriptors.Descriptor descriptor) {
        byte[] schemaDataBytes;
        try {
            Map<String, FileDescriptorProto> fileDescriptorProtoCache = new HashMap<>();
            //recursively cache all FileDescriptorProto
            serializeFileDescriptor(descriptor.getFile(), fileDescriptorProtoCache);

            //extract root message path
            String rootMessageTypeName = descriptor.getFullName();
            String rootFileDescriptorName = descriptor.getFile().getFullName();
            //build FileDescriptorSet, this is equal to < protoc --include_imports --descriptor_set_out >
            byte[] fileDescriptorSet = FileDescriptorSet.newBuilder().addAllFile(fileDescriptorProtoCache.values())
                    .build().toByteArray();

            //serialize to bytes
            ProtobufNativeSchemaData schemaData = ProtobufNativeSchemaData.builder()
                    .fileDescriptorSet(fileDescriptorSet)
                    .rootFileDescriptorName(rootFileDescriptorName).rootMessageTypeName(rootMessageTypeName).build();
            schemaDataBytes = ObjectMapperFactory.getMapperWithIncludeAlways().writer().writeValueAsBytes(schemaData);
            logger.debug("descriptor '{}' serialized to '{}'.", descriptor.getFullName(), schemaDataBytes);
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchemaSerializationException(e);
        }
        return schemaDataBytes;
    }
@Test
    public static void testSerialize() {
        byte[] data =  ProtobufNativeSchemaUtils.serialize(org.apache.pulsar.client.schema.proto.Test.TestMessage.getDescriptor());
        Descriptors.Descriptor descriptor =  ProtobufNativeSchemaUtils.deserialize(data);
        Assert.assertNotNull(descriptor);
        Assert.assertNotNull(descriptor.findFieldByName("nestedField").getMessageType());
        Assert.assertNotNull(descriptor.findFieldByName("externalMessage").getMessageType());
    }