hunk.code_window: 	}
   	AddStatusCache(status)
   	return nil
   }
   func UpdateChannelLastViewedAt(channelIds []string, userId string) *model.AppError {
  
hunk.labels: keep keep keep add keep keep keep keep
hunk.after_edit: 	if status.Status != oldStatus {
   		BroadcastStatus(status)
   	}
  
hunk.file_path: app/channel.go
hunk.type: add
file: // Go support for Protocol Buffers - Google's data interchange format
  //
  // Copyright 2010 The Go Authors.  All rights reserved.
  // https://github.com/golang/protobuf
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are
  // met:
  //
  //     * Redistributions of source code must retain the above copyright
  // notice, this list of conditions and the following disclaimer.
  //     * Redistributions in binary form must reproduce the above
  // copyright notice, this list of conditions and the following disclaimer
  // in the documentation and/or other materials provided with the
  // distribution.
  //     * Neither the name of Google Inc. nor the names of its
  // contributors may be used to endorse or promote products derived from
  // this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
  package proto_test
  
  import (
  	"bytes"
  	"errors"
  	"io/ioutil"
  	"math"
  	"strings"
  	"testing"
  
  	"github.com/golang/protobuf/proto"
  
  	proto3pb "github.com/golang/protobuf/proto/proto3_proto"
  	pb "github.com/golang/protobuf/proto/testdata"
  )
  
  // textMessage implements the methods that allow it to marshal and unmarshal
  // itself as text.
  type textMessage struct {
  }
  
  func (*textMessage) MarshalText() ([]byte, error) {
  	return []byte("custom"), nil
  }
  
  func (*textMessage) UnmarshalText(bytes []byte) error {
  	if string(bytes) != "custom" {
  		return errors.New("expected 'custom'")
  	}
  	return nil
  }
  
  func (*textMessage) Reset()         {}
  func (*textMessage) String() string { return "" }
  func (*textMessage) ProtoMessage()  {}
  
  func newTestMessage() *pb.MyMessage {
  	msg := &pb.MyMessage{
  		Count: proto.Int32(42),
  		Name:  proto.String("Dave"),
  		Quote: proto.String(`"I didn't want to go."`),
  		Pet:   []string{"bunny", "kitty", "horsey"},
  		Inner: &pb.InnerMessage{
  			Host:      proto.String("footrest.syd"),
  			Port:      proto.Int32(7001),
  			Connected: proto.Bool(true),
  		},
  		Others: []*pb.OtherMessage{
  			{
  				Key:   proto.Int64(0xdeadbeef),
  				Value: []byte{1, 65, 7, 12},
  			},
  			{
  				Weight: proto.Float32(6.022),
  				Inner: &pb.InnerMessage{
  					Host: proto.String("lesha.mtv"),
  					Port: proto.Int32(8002),
  				},
  			},
  		},
  		Bikeshed: pb.MyMessage_BLUE.Enum(),
  		Somegroup: &pb.MyMessage_SomeGroup{
  			GroupField: proto.Int32(8),
  		},
  		// One normally wouldn't do this.
  		// This is an undeclared tag 13, as a varint (wire type 0) with value 4.
  		XXX_unrecognized: []byte{13<<3 | 0, 4},
  	}
  	ext := &pb.Ext{
  		Data: proto.String("Big gobs for big rats"),
  	}
  	if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil {
  		panic(err)
  	}
  	greetings := []string{"adg", "easy", "cow"}
  	if err := proto.SetExtension(msg, pb.E_Greeting, greetings); err != nil {
  		panic(err)
  	}
  
  	// Add an unknown extension. We marshal a pb.Ext, and fake the ID.
  	b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")})
  	if err != nil {
  		panic(err)
  	}
  	b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...)
  	proto.SetRawExtension(msg, 201, b)
  
  	// Extensions can be plain fields, too, so let's test that.
  	b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19)
  	proto.SetRawExtension(msg, 202, b)
  
  	return msg
  }
  
  const text = `count: 42
  name: "Dave"
  quote: "\"I didn't want to go.\""
  pet: "bunny"
  pet: "kitty"
  pet: "horsey"
  inner: <
    host: "footrest.syd"
    port: 7001
    connected: true
  >
  others: <
    key: 3735928559
    value: "\001A\007\014"
  >
  others: <
    weight: 6.022
    inner: <
      host: "lesha.mtv"
      port: 8002
    >
  >
  bikeshed: BLUE
  SomeGroup {
    group_field: 8
  }
  /* 2 unknown bytes */
  13: 4
  [testdata.Ext.more]: <
    data: "Big gobs for big rats"
  >
  [testdata.greeting]: "adg"
  [testdata.greeting]: "easy"
  [testdata.greeting]: "cow"
  /* 13 unknown bytes */
  201: "\t3G skiing"
  /* 3 unknown bytes */
  202: 19
  `
  
  func TestMarshalText(t *testing.T) {
  	buf := new(bytes.Buffer)
  	if err := proto.MarshalText(buf, newTestMessage()); err != nil {
  		t.Fatalf("proto.MarshalText: %v", err)
  	}
  	s := buf.String()
  	if s != text {
  		t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, text)
  	}
  }
  
  func TestMarshalTextCustomMessage(t *testing.T) {
  	buf := new(bytes.Buffer)
  	if err := proto.MarshalText(buf, &textMessage{}); err != nil {
  		t.Fatalf("proto.MarshalText: %v", err)
  	}
  	s := buf.String()
  	if s != "custom" {
  		t.Errorf("Got %q, expected %q", s, "custom")
  	}
  }
  func TestMarshalTextNil(t *testing.T) {
  	want := "<nil>"
  	tests := []proto.Message{nil, (*pb.MyMessage)(nil)}
  	for i, test := range tests {
  		buf := new(bytes.Buffer)
  		if err := proto.MarshalText(buf, test); err != nil {
  			t.Fatal(err)
  		}
  		if got := buf.String(); got != want {
  			t.Errorf("%d: got %q want %q", i, got, want)
  		}
  	}
  }
  
  func TestMarshalTextUnknownEnum(t *testing.T) {
  	// The Color enum only specifies values 0-2.
  	m := &pb.MyMessage{Bikeshed: pb.MyMessage_Color(3).Enum()}
  	got := m.String()
  	const want = `bikeshed:3 `
  	if got != want {
  		t.Errorf("\n got %q\nwant %q", got, want)
  	}
  }
  
  func TestTextOneof(t *testing.T) {
  	tests := []struct {
  		m    proto.Message
  		want string
  	}{
  		// zero message
  		{&pb.Communique{}, ``},
  		// scalar field
  		{&pb.Communique{Union: &pb.Communique_Number{4}}, `number:4`},
  		// message field
  		{&pb.Communique{Union: &pb.Communique_Msg{
  			&pb.Strings{StringField: proto.String("why hello!")},
  		}}, `msg:<string_field:"why hello!" >`},
  		// bad oneof (should not panic)
  		{&pb.Communique{Union: &pb.Communique_Msg{nil}}, `msg:/* nil */`},
  	}
  	for _, test := range tests {
  		got := strings.TrimSpace(test.m.String())
  		if got != test.want {
  			t.Errorf("\n got %s\nwant %s", got, test.want)
  		}
  	}
  }
  
  func BenchmarkMarshalTextBuffered(b *testing.B) {
  	buf := new(bytes.Buffer)
  	m := newTestMessage()
  	for i := 0; i < b.N; i++ {
  		buf.Reset()
  		proto.MarshalText(buf, m)
  	}
  }
  
  func BenchmarkMarshalTextUnbuffered(b *testing.B) {
  	w := ioutil.Discard
  	m := newTestMessage()
  	for i := 0; i < b.N; i++ {
  		proto.MarshalText(w, m)
  	}
  }
  
  func compact(src string) string {
  	// s/[ \n]+/ /g; s/ $//;
  	dst := make([]byte, len(src))
  	space, comment := false, false
  	j := 0
  	for i := 0; i < len(src); i++ {
  		if strings.HasPrefix(src[i:], "/*") {
  			comment = true
  			i++
  			continue
  		}
  		if comment && strings.HasPrefix(src[i:], "*/") {
  			comment = false
  			i++
  			continue
  		}
  		if comment {
  			continue
  		}
  		c := src[i]
  		if c == ' ' || c == '\n' {
  			space = true
  			continue
  		}
  		if j > 0 && (dst[j-1] == ':' || dst[j-1] == '<' || dst[j-1] == '{') {
  			space = false
  		}
  		if c == '{' {
  			space = false
  		}
  		if space {
  			dst[j] = ' '
  			j++
  			space = false
  		}
  		dst[j] = c
  		j++
  	}
  	if space {
  		dst[j] = ' '
  		j++
  	}
  	return string(dst[0:j])
  }
  
  var compactText = compact(text)
  
  func TestCompactText(t *testing.T) {
  	s := proto.CompactTextString(newTestMessage())
  	if s != compactText {
  		t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v\n===\n", s, compactText)
  	}
  }
  
  func TestStringEscaping(t *testing.T) {
  	testCases := []struct {
  		in  *pb.Strings
  		out string
  	}{
  		{
  			// Test data from C++ test (TextFormatTest.StringEscape).
  			// Single divergence: we don't escape apostrophes.
  			&pb.Strings{StringField: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and  multiple   spaces")},
  			"string_field: \"\\\"A string with ' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and  multiple   spaces\"\n",
  		},
  		{
  			// Test data from the same C++ test.
  			&pb.Strings{StringField: proto.String("\350\260\267\346\255\214")},
  			"string_field: \"\\350\\260\\267\\346\\255\\214\"\n",
  		},
  		{
  			// Some UTF-8.
  			&pb.Strings{StringField: proto.String("\x00\x01\xff\x81")},
  			`string_field: "\000\001\377\201"` + "\n",
  		},
  	}
  
  	for i, tc := range testCases {
  		var buf bytes.Buffer
  		if err := proto.MarshalText(&buf, tc.in); err != nil {
  			t.Errorf("proto.MarsalText: %v", err)
  			continue
  		}
  		s := buf.String()
  		if s != tc.out {
  			t.Errorf("#%d: Got:\n%s\nExpected:\n%s\n", i, s, tc.out)
  			continue
  		}
  
  		// Check round-trip.
  		pb := new(pb.Strings)
  		if err := proto.UnmarshalText(s, pb); err != nil {
  			t.Errorf("#%d: UnmarshalText: %v", i, err)
  			continue
  		}
  		if !proto.Equal(pb, tc.in) {
  			t.Errorf("#%d: Round-trip failed:\nstart: %v\n  end: %v", i, tc.in, pb)
  		}
  	}
  }
  
  // A limitedWriter accepts some output before it fails.
  // This is a proxy for something like a nearly-full or imminently-failing disk,
  // or a network connection that is about to die.
  type limitedWriter struct {
  	b     bytes.Buffer
  	limit int
  }
  
  var outOfSpace = errors.New("proto: insufficient space")
  
  func (w *limitedWriter) Write(p []byte) (n int, err error) {
  	var avail = w.limit - w.b.Len()
  	if avail <= 0 {
  		return 0, outOfSpace
  	}
  	if len(p) <= avail {
  		return w.b.Write(p)
  	}
  	n, _ = w.b.Write(p[:avail])
  	return n, outOfSpace
  }
  
  func TestMarshalTextFailing(t *testing.T) {
  	// Try lots of different sizes to exercise more error code-paths.
  	for lim := 0; lim < len(text); lim++ {
  		buf := new(limitedWriter)
  		buf.limit = lim
  		err := proto.MarshalText(buf, newTestMessage())
  		// We expect a certain error, but also some partial results in the buffer.
  		if err != outOfSpace {
  			t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", err, outOfSpace)
  		}
  		s := buf.b.String()
  		x := text[:buf.limit]
  		if s != x {
  			t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, x)
  		}
  	}
  }
  
  func TestFloats(t *testing.T) {
  	tests := []struct {
  		f    float64
  		want string
  	}{
  		{0, "0"},
  		{4.7, "4.7"},
  		{math.Inf(1), "inf"},
  		{math.Inf(-1), "-inf"},
  		{math.NaN(), "nan"},
  	}
  	for _, test := range tests {
  		msg := &pb.FloatingPoint{F: &test.f}
  		got := strings.TrimSpace(msg.String())
  		want := `f:` + test.want
  		if got != want {
  			t.Errorf("f=%f: got %q, want %q", test.f, got, want)
  		}
  	}
  }
  
  func TestRepeatedNilText(t *testing.T) {
  	m := &pb.MessageList{
  		Message: []*pb.MessageList_Message{
  			nil,
  			&pb.MessageList_Message{
  				Name: proto.String("Horse"),
  			},
  			nil,
  		},
  	}
  	want := `Message <nil>
  Message {
    name: "Horse"
  }
  Message <nil>
  `
  	if s := proto.MarshalTextString(m); s != want {
  		t.Errorf(" got: %s\nwant: %s", s, want)
  	}
  }
  
  func TestProto3Text(t *testing.T) {
  	tests := []struct {
  		m    proto.Message
  		want string
  	}{
  		// zero message
  		{&proto3pb.Message{}, ``},
  		// zero message except for an empty byte slice
  		{&proto3pb.Message{Data: []byte{}}, ``},
  		// trivial case
  		{&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`},
  		// empty map
  		{&pb.MessageWithMap{}, ``},
  		// non-empty map; map format is the same as a repeated struct,
  		// and they are sorted by key (numerically for numeric keys).
  		{
  			&pb.MessageWithMap{NameMapping: map[int32]string{
  				-1:      "Negatory",
  				7:       "Lucky",
  				1234:    "Feist",
  				6345789: "Otis",
  			}},
  			`name_mapping:<key:-1 value:"Negatory" > ` +
  				`name_mapping:<key:7 value:"Lucky" > ` +
  				`name_mapping:<key:1234 value:"Feist" > ` +
  				`name_mapping:<key:6345789 value:"Otis" >`,
  		},
  		// map with nil value; not well-defined, but we shouldn't crash
  		{
  			&pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{7: nil}},
  			`msg_mapping:<key:7 >`,
  		},
  	}
  	for _, test := range tests {
  		got := strings.TrimSpace(test.m.String())
  		if got != test.want {
  			t.Errorf("\n got %s\nwant %s", got, test.want)
  		}
  	}
  }
  