func ToDocEvent(docEvent sync.DocEvent) (*api.DocEvent, error) {
	eventType, err := ToDocEventType(docEvent.Type)
	if err != nil {
		return nil, err
	}
	return &api.DocEvent{
		Type:         eventType,
		Publisher:    ToClient(docEvent.Publisher),
		DocumentKeys: ToDocumentKeys(docEvent.DocumentKeys),
	}, nil
}
ToDocEvent converts the given model to Protobuf format.
package converter
import (
	"fmt"
	"reflect"
	"github.com/yorkie-team/yorkie/api"
	"github.com/yorkie-team/yorkie/pkg/document/change"
	"github.com/yorkie-team/yorkie/pkg/document/checkpoint"
	"github.com/yorkie-team/yorkie/pkg/document/json"
	"github.com/yorkie-team/yorkie/pkg/document/key"
	"github.com/yorkie-team/yorkie/pkg/document/operation"
	"github.com/yorkie-team/yorkie/pkg/document/time"
	"github.com/yorkie-team/yorkie/pkg/types"
	"github.com/yorkie-team/yorkie/yorkie/backend/sync"
)
func ToClient(client types.Client) *api.Client {
	return &api.Client{
		Id:       client.ID.Bytes(),
		Metadata: ToMetadataInfo(client.MetadataInfo),
	}
}
func ToMetadataInfo(metadata types.MetadataInfo) *api.Metadata {
	return &api.Metadata{
		Clock: metadata.Clock,
		Data:  metadata.Data,
	}
}
func ToChangePack(pack *change.Pack) (*api.ChangePack, error) {
	pbChanges, err := toChanges(pack.Changes)
	if err != nil {
		return nil, err
	}
	return &api.ChangePack{
		DocumentKey:     toDocumentKey(pack.DocumentKey),
		Checkpoint:      toCheckpoint(pack.Checkpoint),
		Changes:         pbChanges,
		Snapshot:        pack.Snapshot,
		MinSyncedTicket: toTimeTicket(pack.MinSyncedTicket),
	}, nil
}
func toDocumentKey(key *key.Key) *api.DocumentKey {
	return &api.DocumentKey{
		Collection: key.Collection,
		Document:   key.Document,
	}
}
func toCheckpoint(cp *checkpoint.Checkpoint) *api.Checkpoint {
	return &api.Checkpoint{
		ServerSeq: cp.ServerSeq,
		ClientSeq: cp.ClientSeq,
	}
}
func toChanges(changes []*change.Change) ([]*api.Change, error) {
	var pbChanges []*api.Change
	for _, c := range changes {
		pbOperations, err := ToOperations(c.Operations())
		if err != nil {
			return nil, err
		}
		pbChanges = append(pbChanges, &api.Change{
			Id:         toChangeID(c.ID()),
			Message:    c.Message(),
			Operations: pbOperations,
		})
	}
	return pbChanges, nil
}
func toChangeID(id *change.ID) *api.ChangeID {
	return &api.ChangeID{
		ClientSeq: id.ClientSeq(),
		Lamport:   id.Lamport(),
		ActorId:   id.Actor().Bytes(),
	}
}
func ToDocumentKeys(keys []*key.Key) []*api.DocumentKey {
	var pbKeys []*api.DocumentKey
	for _, k := range keys {
		pbKeys = append(pbKeys, toDocumentKey(k))
	}
	return pbKeys
}
func ToClientsMap(clientsMap map[string][]types.Client) map[string]*api.Clients {
	pbClientsMap := make(map[string]*api.Clients)
	for k, clients := range clientsMap {
		var pbClients []*api.Client
		for _, client := range clients {
			pbClients = append(pbClients, ToClient(client))
		}
		pbClientsMap[k] = &api.Clients{
			Clients: pbClients,
		}
	}
	return pbClientsMap
}
func ToDocEventType(eventType types.DocEventType) (api.DocEventType, error) {
	switch eventType {
	case types.DocumentsChangedEvent:
		return api.DocEventType_DOCUMENTS_CHANGED, nil
	case types.DocumentsWatchedEvent:
		return api.DocEventType_DOCUMENTS_WATCHED, nil
	case types.DocumentsUnwatchedEvent:
		return api.DocEventType_DOCUMENTS_UNWATCHED, nil
	case types.MetadataChangedEvent:
		return api.DocEventType_METADATA_CHANGED, nil
	default:
		return 0, fmt.Errorf("%s: %w", eventType, ErrUnsupportedEventType)
	}
}