func (s *messagingServerImpl) ListBlurbs(ctx context.Context, in *pb.ListBlurbsRequest) (*pb.ListBlurbsResponse, error) {
	passFilter := func(_ *pb.Blurb) bool { return true }
	return s.FilteredListBlurbs(ctx, in, passFilter)
}
Lists blurbs for a specific chat room or user profile depending on the
parent resource name.
package services
import (
	"context"
	"encoding/base64"
	"fmt"
	"io"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/googleapis/gapic-showcase/server"
	pb "github.com/googleapis/gapic-showcase/server/genproto"
	"google.golang.org/genproto/googleapis/longrunning"
	errdetails "google.golang.org/genproto/googleapis/rpc/errdetails"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)
func NewMessagingServer(identityServer ReadOnlyIdentityServer) MessagingServer {
	return &messagingServerImpl{
		identityServer: identityServer,
		nowF:           time.Now,
		token:          server.NewTokenGenerator(),
		roomKeys:       map[string]int{},
		blurbKeys:      map[string]blurbIndex{},
		blurbs:         map[string][]blurbEntry{},
		parentUids:     map[string]*server.UniqID{},
		observers:      map[string]map[string]blurbObserver{},
	}
}
type MessagingServer interface {
	FilteredListBlurbs(context.Context, *pb.ListBlurbsRequest, func(*pb.Blurb) bool) (*pb.ListBlurbsResponse, error)
	pb.MessagingServer
}
type messagingServerImpl struct {
	nowF           func() time.Time
	token          server.TokenGenerator
	identityServer ReadOnlyIdentityServer
	roomUID  server.UniqID
	roomMu   sync.Mutex
	roomKeys map[string]int
	rooms    []roomEntry
	blurbMu    sync.Mutex
	blurbKeys  map[string]blurbIndex
	blurbs     map[string][]blurbEntry
	parentUids map[string]*server.UniqID
	obsMu     sync.Mutex
	obsUID    server.UniqID
	observers map[string]map[string]blurbObserver
}
type roomEntry struct {
	room    *pb.Room
	deleted bool
}
type blurbIndex struct {
	row string
	col int
}
type blurbEntry struct {
	blurb   *pb.Blurb
	deleted bool
}
type blurbObserver interface {
	OnCreate(b *pb.Blurb)
	OnUpdate(b *pb.Blurb)
	OnDelete(b *pb.Blurb)
}
func (s *messagingServerImpl) CreateRoom(ctx context.Context, in *pb.CreateRoomRequest) (*pb.Room, error) {
	s.roomMu.Lock()
	defer s.roomMu.Unlock()
	r := in.GetRoom()
	err := validateRoom(r)
	if err != nil {
		return nil, err
	}
	uniqName := func(x *pb.Room) bool {
		return (r.GetDisplayName() == x.GetDisplayName())
	}
	if s.anyRoom(uniqName) {
		return nil, status.Errorf(
			codes.AlreadyExists,
			"A room with display_name %s already exists.",
			r.GetDisplayName())
	}
	id := s.roomUID.Next()
	name := fmt.Sprintf("rooms/%d", id)
	now := ptypes.TimestampNow()
	r.Name = name
	r.CreateTime = now
	r.UpdateTime = now
	index := len(s.rooms)
	s.rooms = append(s.rooms, roomEntry{room: r})
	s.roomKeys[name] = index
	return r, nil
}
func (s *messagingServerImpl) GetRoom(ctx context.Context, in *pb.GetRoomRequest) (*pb.Room, error) {
	s.roomMu.Lock()
	defer s.roomMu.Unlock()
	name := in.GetName()
	if i, ok := s.roomKeys[name]; ok {
		entry := s.rooms[i]
		if !entry.deleted {
			return entry.room, nil
		}
	}
	return nil, status.Errorf(
		codes.NotFound, "A room with name %s not found.",
		name)
}
func (s *messagingServerImpl) UpdateRoom(ctx context.Context, in *pb.UpdateRoomRequest) (*pb.Room, error) {
	f := in.GetUpdateMask()
	r := in.GetRoom()
	if f != nil && len(f.GetPaths()) > 0 {
		return nil, status.Error(
			codes.Unimplemented,
			"Field masks are currently not supported.")
	}
	s.roomMu.Lock()
	defer s.roomMu.Unlock()
	err := validateRoom(r)
	if err != nil {
		return nil, err
	}
	i, ok := s.roomKeys[r.GetName()]
	if !ok || s.rooms[i].deleted {
		return nil, status.Errorf(
			codes.NotFound,
			"A room with name %s not found.", r.GetName())
	}
	entry := s.rooms[i]
	uniqName := func(x *pb.Room) bool {
		return x != entry.room && (r.GetDisplayName() == x.GetDisplayName())
	}
	if s.anyRoom(uniqName) {
		return nil, status.Errorf(
			codes.AlreadyExists,
			"A room with either display_name, %s already exists.",
			r.GetDisplayName())
	}
	updated := &pb.Room{
		Name:        r.GetName(),
		DisplayName: r.GetDisplayName(),
		Description: r.GetDescription(),
		CreateTime:  entry.room.GetCreateTime(),
		UpdateTime:  ptypes.TimestampNow(),
	}
	s.rooms[i] = roomEntry{room: updated}
	return updated, nil
}
func (s *messagingServerImpl) DeleteRoom(ctx context.Context, in *pb.DeleteRoomRequest) (*empty.Empty, error) {
	s.roomMu.Lock()
	defer s.roomMu.Unlock()
	i, ok := s.roomKeys[in.GetName()]
	if !ok {
		return nil, status.Errorf(
			codes.NotFound,
			"A room with name %s not found.", in.GetName())
	}
	entry := s.rooms[i]
	s.rooms[i] = roomEntry{room: entry.room, deleted: true}
	return &empty.Empty{}, nil
}
func (s *messagingServerImpl) ListRooms(ctx context.Context, in *pb.ListRoomsRequest) (*pb.ListRoomsResponse, error) {
	start, err := s.token.GetIndex(in.GetPageToken())
	if err != nil {
		return nil, err
	}
	offset := 0
	rooms := []*pb.Room{}
	for _, entry := range s.rooms[start:] {
		offset++
		if entry.deleted {
			continue
		}
		rooms = append(rooms, entry.room)
		if len(rooms) >= int(in.GetPageSize()) {
			break
		}
	}
	nextToken := ""
	if start+offset < len(s.rooms) {
		nextToken = s.token.ForIndex(start + offset)
	}
	return &pb.ListRoomsResponse{Rooms: rooms, NextPageToken: nextToken}, nil
}
func (s *messagingServerImpl) anyRoom(f func(*pb.Room) bool) bool {
	for _, entry := range s.rooms {
		if !entry.deleted && f(entry.room) {
			return true
		}
	}
	return false
}
func validateRoom(r *pb.Room) error {
	if r.GetDisplayName() == "" {
		return status.Errorf(
			codes.InvalidArgument,
			"The field `display_name` is required.")
	}
	return nil
}
func (s *messagingServerImpl) CreateBlurb(ctx context.Context, in *pb.CreateBlurbRequest) (*pb.Blurb, error) {
	parent := in.GetParent()
	if err := s.validateParent(parent); err != nil {
		return nil, err
	}
	s.blurbMu.Lock()
	defer s.blurbMu.Unlock()
	b := in.GetBlurb()
	if err := validateBlurb(b); err != nil {
		return nil, err
	}
	parentBs, ok := s.blurbs[parent]
	if !ok {
		parentBs = []blurbEntry{}
	}
	puid, ok := s.parentUids[parent]
	if !ok {
		puid = &server.UniqID{}
		s.parentUids[parent] = puid
	}
	id := puid.Next()
	name := fmt.Sprintf("%s/blurbs/%d", parent, id)
	now := ptypes.TimestampNow()
	switch legacyID := b.LegacyId.(type) {
	case *pb.Blurb_LegacyRoomId:
		name = fmt.Sprintf("%s/blurbs/legacy/%s.%d", parent, legacyID.LegacyRoomId, id)
	case *pb.Blurb_LegacyUserId:
		name = fmt.Sprintf("%s/blurbs/legacy/%s~%d", parent, legacyID.LegacyUserId, id)
	}
	b.Name = name
	b.CreateTime = now
	b.UpdateTime = now
	index := len(parentBs)
	s.blurbs[parent] = append(parentBs, blurbEntry{blurb: b})
	s.blurbKeys[name] = blurbIndex{row: parent, col: index}
	s.obsMu.Lock()
	defer s.obsMu.Unlock()
	if parentObservers, ok := s.observers[parent]; ok {
		for _, o := range parentObservers {
			o.OnCreate(b)
		}
	}
	return b, nil
}
func (s *messagingServerImpl) GetBlurb(ctx context.Context, in *pb.GetBlurbRequest) (*pb.Blurb, error) {
	s.blurbMu.Lock()
	defer s.blurbMu.Unlock()
	if i, ok := s.blurbKeys[in.GetName()]; ok {
		entry := s.blurbs[i.row][i.col]
		if !entry.deleted {
			return entry.blurb, nil
		}
	}
	return nil, status.Errorf(
		codes.NotFound,
		"A blurb with name %s not found.",
		in.GetName())
}
func (s *messagingServerImpl) UpdateBlurb(ctx context.Context, in *pb.UpdateBlurbRequest) (*pb.Blurb, error) {
	if in.GetUpdateMask() != nil && len(in.GetUpdateMask().GetPaths()) > 0 {
		return nil, status.Error(
			codes.Unimplemented,
			"Field masks are currently not supported.")
	}
	s.blurbMu.Lock()
	defer s.blurbMu.Unlock()
	b := in.GetBlurb()
	i, ok := s.blurbKeys[b.GetName()]
	if !ok || s.blurbs[i.row][i.col].deleted {
		return nil, status.Errorf(
			codes.NotFound,
			"A blurb with name %s not found.", b.GetName())
	}
	if err := validateBlurb(b); err != nil {
		return nil, err
	}
	updated := proto.Clone(b).(*pb.Blurb)
	updated.UpdateTime = ptypes.TimestampNow()
	s.blurbs[i.row][i.col] = blurbEntry{blurb: updated}
	s.obsMu.Lock()
	defer s.obsMu.Unlock()
	if parentObservers, ok := s.observers[i.row]; ok {
		for _, o := range parentObservers {
			o.OnUpdate(updated)
		}
	}
	return updated, nil
}
func (s *messagingServerImpl) DeleteBlurb(ctx context.Context, in *pb.DeleteBlurbRequest) (*empty.Empty, error) {
	s.blurbMu.Lock()
	defer s.blurbMu.Unlock()
	i, ok := s.blurbKeys[in.GetName()]
	if !ok {
		return nil, status.Errorf(
			codes.NotFound,
			"A blurb with name %s not found.", in.GetName())
	}
	entry := s.blurbs[i.row][i.col]
	s.blurbs[i.row][i.col] = blurbEntry{blurb: entry.blurb, deleted: true}
	s.obsMu.Lock()
	defer s.obsMu.Unlock()
	if parentObservers, ok := s.observers[i.row]; ok {
		for _, o := range parentObservers {
			o.OnDelete(entry.blurb)
		}
	}
	return &empty.Empty{}, nil
}