├── .gitignore ├── ChatRoom_V0.go ├── OnetoMoreChatRoom_V2 ├── README.md ├── client1_demo.png ├── client2_demo.png ├── client3_demo.png ├── morechatroom_client.go ├── morechatroom_server.go └── sever_demo.png ├── OnetooneChatRoom_V1 ├── README.md ├── chatroomclient.go └── chatroomsever.go ├── ProtobufChatRoom_V2.5 ├── ProtoChatClient.go ├── ProtoChatServer.go ├── README.md ├── demo │ ├── client.png │ └── server.png ├── github.com │ └── golang │ │ └── protobuf │ │ ├── LICENSE │ │ └── proto │ │ ├── clone.go │ │ ├── decode.go │ │ ├── discard.go │ │ ├── encode.go │ │ ├── equal.go │ │ ├── extensions.go │ │ ├── lib.go │ │ ├── message_set.go │ │ ├── pointer_reflect.go │ │ ├── pointer_unsafe.go │ │ ├── properties.go │ │ ├── table_marshal.go │ │ ├── table_merge.go │ │ ├── table_unmarshal.go │ │ ├── text.go │ │ └── text_parser.go └── protocol │ ├── conn.pb.go │ └── message │ ├── conn.proto │ ├── protoc-gen-go.exe │ └── protoc.exe └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /ChatRoom_V0.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net" 5 | "log" 6 | "fmt" 7 | "bufio" 8 | ) 9 | 10 | //主、广播、连接处理、客户写入 11 | 12 | type clients chan<- string //设置广播器,客户对外发送信息的通道 13 | // chan<- T 只能向此类通道发送元素值,而不能从它那里接收元素值 14 | 15 | var( 16 | entering = make(chan string,10) //建立客户进入房间的通道 17 | leaving = make(chan string,10) //建立客户离开房间的通道 18 | messages = make(chan string,100) //建立发送客户消息的通道 19 | ) 20 | func broadcaster{ 21 | clients := make(map[clients]bool) //将map中的客户信息值返回给 clients 22 | for { 23 | select { //选择发送消息的通道 24 | case information := <-entering //接收客户进入房间的信号 25 | clients[clients] = true 26 | 27 | case information := <-leaving //接收客户离开房间的信号 28 | delete(clients,information) //删除用户的名字和发送的消息 29 | close(information) //关闭 30 | 31 | case clients := <-messages //接收客户发送消息的信号 32 | for information := range clients{ //把消息中的所有内容广播给所有客户 33 | //迭代出一个数组或切片值中的每个元素、一个字符串中的每个字符 34 | imformation <- msg 35 | } 36 | 37 | } 38 | } 39 | } 40 | 41 | func handleConn(conn net.Conn){ 42 | ch := make(chan string) //创建对外发送客户消息的通道,返回的字符串存入ch中 43 | go clientWriter() //创建客户写入的goroutine 44 | 45 | human := conn.RemoteAddr().String() //写入客户的名字 46 | ch <- "Your name is " + human //“你的名字是...”写入ch 47 | messages <- human + "has arrived room" //加入房间前显示 “...已经加入房间 48 | entering <- ch //打开进入房间的通道 49 | 50 | input := bufio.NewScanner(conn) //读取客户输入的内容,并更新 51 | for input.Scan(){ 52 | messages <- human + ": " + input.Text() //在说的每句话之前加上客户的名字 53 | } 54 | 55 | leaving <- ch //打开离开房间的通道 56 | messages <- who + "has left room" //离开房间后显示 “...已经离开房间” 57 | conn.Close() //客户离开房间后通道关闭 58 | 59 | 60 | } 61 | 62 | func clientWriter(conn net.Conn,ch <- chan string){ 63 | for msg := range ch{ 64 | fmt.Fprintln(conn,msg) //将客户写入的所有内容记录在msg中并输出 65 | } 66 | } 67 | 68 | func main() { 69 | listener,err := net.Listen("tcp","127.0.0.1:8085") //构建TCP协议 服务端程序的第一步 70 | if err != nil{ //判断error类型的值是否为nil 71 | log.Fatal(err) 72 | return 73 | } 74 | 75 | go broadcaster() //并发执行广播的goroutine 76 | for{ 77 | conn,err := listener.Accept() //等待客户端的连接请求 78 | if err != nil{ 79 | log.Print(err) 80 | continue 81 | } 82 | go handleConn(conn) //对客户的连接进行处理的goroutine 83 | } 84 | 85 | 86 | } 87 | -------------------------------------------------------------------------------- /OnetoMoreChatRoom_V2/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/OnetoMoreChatRoom_V2/README.md -------------------------------------------------------------------------------- /OnetoMoreChatRoom_V2/client1_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/OnetoMoreChatRoom_V2/client1_demo.png -------------------------------------------------------------------------------- /OnetoMoreChatRoom_V2/client2_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/OnetoMoreChatRoom_V2/client2_demo.png -------------------------------------------------------------------------------- /OnetoMoreChatRoom_V2/client3_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/OnetoMoreChatRoom_V2/client3_demo.png -------------------------------------------------------------------------------- /OnetoMoreChatRoom_V2/morechatroom_client.go: -------------------------------------------------------------------------------- 1 | // one sever to more client chat room 2 | //This is chat client 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "net" 8 | ) 9 | 10 | var nick string = "" //声明聊天室的昵称 11 | 12 | func main() { 13 | conn, err := net.Dial("tcp", "127.0.0.1:8000") //打开监听端口 14 | if err != nil { 15 | fmt.Println("conn fail...") 16 | } 17 | defer conn.Close() 18 | fmt.Println("client connect server successed \n") 19 | 20 | //给自己取一个聊天室的昵称 21 | fmt.Printf("Make a nickname:") 22 | fmt.Scanf("%s", &nick) //输入昵称 23 | fmt.Println("hello : ", nick) //客户端输出 24 | conn.Write([]byte("nick|" + nick)) //将信息发送给服务器端 25 | 26 | go Handle(conn) //创建线程 27 | 28 | var msg string 29 | for { 30 | msg = "" //声明一个空的消息 31 | fmt.Scan(&msg) //输入消息 32 | conn.Write([]byte("say|" + nick + "|" + msg)) //三段字节流 say | 昵称 | 发送的消息 33 | if msg == "quit" { //如果消息为quit 34 | conn.Write([]byte("quit|" + nick)) //将quit字节流发送给服务器端 35 | break //程序结束运行 36 | } 37 | } 38 | } 39 | 40 | func Handle(conn net.Conn) { 41 | 42 | for { 43 | 44 | data := make([]byte, 255) //创建一个字节流 45 | msg_read, err := conn.Read(data) //将读取的字节流赋值给msg_read和err 46 | if msg_read == 0 || err != nil { //如果字节流为0或者有错误 47 | break 48 | } 49 | 50 | fmt.Println(string(data[0:msg_read])) //把字节流转换成字符串 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /OnetoMoreChatRoom_V2/morechatroom_server.go: -------------------------------------------------------------------------------- 1 | // one sever to more client chat room 2 | //This is chat sever 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "net" 8 | "strings" 9 | ) 10 | 11 | var ConnMap map[string]net.Conn = make(map[string]net.Conn) //声明一个集合 12 | 13 | //ConnMap := make(map[string]net.Conn) 14 | 15 | func main() { 16 | listen_socket, err := net.Listen("tcp", "127.0.0.1:8000") //打开监听接口 17 | if err != nil { 18 | fmt.Println("server start error") 19 | } 20 | 21 | defer listen_socket.Close() 22 | fmt.Println("server is wating ....") 23 | 24 | for { 25 | conn, err := listen_socket.Accept() //收到来自客户端发来的消息 26 | if err != nil { 27 | fmt.Println("conn fail ...") 28 | } 29 | fmt.Println(conn.RemoteAddr(), "connect successed") 30 | 31 | go handle(conn) //创建线程 32 | } 33 | } 34 | 35 | func handle(conn net.Conn) { 36 | for { 37 | data := make([]byte, 255) //创建字节流 (此处同 一对一 通信) 38 | msg_read, err := conn.Read(data) //声明并将从客户端读取的消息赋给msg_read 和err 39 | if msg_read == 0 || err != nil { 40 | continue 41 | } 42 | 43 | //解析协议 44 | msg_str := strings.Split(string(data[0:msg_read]), "|") //将从客户端收到的字节流分段保存到msg_str这个数组中 45 | 46 | switch msg_str[0] { 47 | case "nick": //加入聊天室 48 | fmt.Println(conn.RemoteAddr(), "-->", msg_str[1]) //nick占在数组下标0上,客户端上写的昵称占在数组下标1上 49 | for k, v := range ConnMap { //遍历集合中存储的客户端消息 50 | if k != msg_str[1] { 51 | v.Write([]byte("[" + msg_str[1] + "]: join...")) 52 | } 53 | } 54 | ConnMap[msg_str[1]] = conn 55 | case "say": //转发消息 56 | for k, v := range ConnMap { //k指客户端昵称 v指客户端连接服务器端后的地址 57 | if k != msg_str[1] { //判断是不是给自己发,如果不是 58 | fmt.Println("Send "+msg_str[2]+" to ", k) //服务器端将消息转发给集合中的每一个客户端 59 | v.Write([]byte("[" + msg_str[1] + "]: " + msg_str[2])) //给除了自己的每一个客户端发送自己之前要发送的消息 60 | } 61 | } 62 | case "quit": //退出 63 | for k, v := range ConnMap { //遍历集合中的客户端昵称 64 | if k != msg_str[1] { //如果昵称不是自己 65 | v.Write([]byte("[" + msg_str[1] + "]: quit")) //给除了自己的其他客户端昵称发送退出的消息,并使Write方法阻塞 66 | } 67 | } 68 | delete(ConnMap, msg_str[1]) //退出聊天室 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /OnetoMoreChatRoom_V2/sever_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/OnetoMoreChatRoom_V2/sever_demo.png -------------------------------------------------------------------------------- /OnetooneChatRoom_V1/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/OnetooneChatRoom_V1/README.md -------------------------------------------------------------------------------- /OnetooneChatRoom_V1/chatroomclient.go: -------------------------------------------------------------------------------- 1 | // One-to-one ChatRoom Client 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | "net" 7 | ) 8 | 9 | func main() { 10 | conn, err := net.Dial("tcp", "127.0.0.1:8000") 11 | if err != nil { 12 | fmt.Println("conn fail...") 13 | } 14 | defer conn.Close() 15 | fmt.Println("connect sever successed") 16 | 17 | var msg string //声明msg为字符串变量 18 | 19 | for { 20 | msg = "" //初始化msg为空值 21 | fmt.Printf("say to sever: ") 22 | fmt.Scan(&msg) //输入客户端向服务器端要发送的消息 23 | //fmt.Println(msg) 24 | //msg_write := []byte(msg) 25 | //conn.Write(msg_write) 26 | conn.Write([]byte(msg)) //信息转化成字节流形式并向服务器端发送 27 | //此处造成客户端程序端口堵塞 28 | //fmt.Println([]byte(msg)) 29 | 30 | //等待服务器端发送信息回来 31 | data := make([]byte, 255) 32 | msg_read, err := conn.Read(data) 33 | if msg_read == 0 || err != nil { 34 | fmt.Println("err") 35 | } 36 | msg_read_str := string(data[0:msg_read]) 37 | if msg_read_str == "close" { 38 | conn.Write([]byte("close")) 39 | break 40 | } 41 | 42 | fmt.Println("sever say:", msg_read_str) 43 | } 44 | conn.Close() 45 | } 46 | -------------------------------------------------------------------------------- /OnetooneChatRoom_V1/chatroomsever.go: -------------------------------------------------------------------------------- 1 | // One-to-one ChatRoom Sever 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | "net" 7 | ) 8 | 9 | //var ConnMap map[string]*net.TCPConn 10 | 11 | func main() { 12 | listen_socket, err := net.Listen("tcp", "127.0.0.1:8000") //打开监听接口 13 | if err != nil { //如果有错误 14 | fmt.Println("sever error") 15 | } 16 | 17 | defer listen_socket.Close() //延迟服务器端关闭 18 | fmt.Println("sever is wating ....") 19 | 20 | for { 21 | conn, err := listen_socket.Accept() //监听客户端的端口 22 | if err != nil { 23 | fmt.Println("conn fail ...") 24 | } 25 | fmt.Println("connect client successed") //显示服务器端连接成功 26 | 27 | var msg string //声明msg为字符串变量 28 | 29 | for { 30 | //开始接收客户端发过来的消息 31 | msg = "" //字符串msg初始为空 32 | data := make([]byte, 255) //创建并声明数据变量,为255位 33 | msg_read, err := conn.Read(data) //接收由客户端发来的消息,字节赋值给msg_read,err为错误 34 | if msg_read == 0 || err != nil { //如果读取的消息为0字节或者有错误 35 | fmt.Println("err") 36 | } 37 | 38 | msg_read_str := string(data[0:msg_read]) //将msg_read_str的字节格式转化成字符串形式 39 | if msg_read_str == "close" { //如果接收到的客户端消息为close 40 | conn.Write([]byte("close")) 41 | break 42 | } 43 | //fmt.Println(string(data[0:msg_read])) 44 | fmt.Println("client say: ", msg_read_str) //接收客户端发来的信息 45 | 46 | fmt.Printf("say to client: ") //提示向客户端要说的话 47 | fmt.Scan(&msg) //输入服务器端要对客户端说的话 48 | //conn.Write([]byte("hello client\n")) 49 | //msg_write := []byte(msg) 50 | conn.Write([]byte(msg)) //把消息发送给客户端 51 | //此处造成服务器端的端口堵塞 52 | } 53 | fmt.Println("client Close\n") 54 | conn.Close() //关闭连接 55 | } 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/ProtoChatClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net" 5 | "fmt" 6 | "Golang-OnlineChatRoom/ProtobufChatRoom_V2.5/protocol" 7 | "Golang-OnlineChatRoom/ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto" 8 | "log" 9 | ) 10 | 11 | func main() { 12 | conn, err := net.Dial("tcp", "127.0.0.1:8000") //打开监听端口 13 | if err != nil { 14 | fmt.Println("conn fail...") 15 | } 16 | defer conn.Close() 17 | fmt.Println("client connect server successed \n") 18 | 19 | var nickname string 20 | fmt.Println("请输入您在聊天室中要显示的昵称:") 21 | fmt.Scan(&nickname) 22 | fmt.Println("hello,welcome to online chat room :",nickname) 23 | go CliHandle(conn) 24 | 25 | for{ 26 | var datamsg string 27 | fmt.Println("请输入你要群发的消息:") 28 | fmt.Scan(&datamsg) 29 | 30 | testmsg := &protocol.Conn_ToS{ 31 | Nickname:proto.String(nickname), 32 | Msg:proto.String(datamsg), 33 | } 34 | data,err := proto.Marshal(testmsg) //对要发送的数据进行编码 35 | if err != nil{ 36 | log.Fatal("marshaling error:",err) 37 | } 38 | 39 | conn.Write(data) //拼接两个字节格式的数据 40 | 41 | if datamsg == "quit"{ 42 | conn.Write([]byte(datamsg + nickname)) 43 | break 44 | } 45 | } 46 | } 47 | 48 | //客户端接收消息 49 | func CliHandle(conn net.Conn){ 50 | for{ 51 | msgdata := make([]byte,255) 52 | msgdata_read,err := conn.Read(msgdata) 53 | if msgdata_read == 0 || err != nil{ 54 | break 55 | } 56 | //对接收到的数据进行解码 57 | newTest := &protocol.Conn_ToS{} 58 | err = proto.Unmarshal(msgdata[0:msgdata_read],newTest) 59 | if err != nil{ 60 | log.Fatal("unmarshaling error:",err) 61 | } 62 | 63 | fmt.Println(newTest.GetNickname(),newTest.GetMsg()) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/ProtoChatServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net" 5 | "fmt" 6 | ) 7 | 8 | var ConnMap map[int]net.Conn = make(map[int]net.Conn) 9 | 10 | func main() { 11 | listen_socket, err := net.Listen("tcp", "127.0.0.1:8000") //打开监听接口 12 | if err != nil { 13 | fmt.Println("server start error") 14 | } 15 | 16 | defer listen_socket.Close() 17 | fmt.Println("server is wating ....") 18 | var key int = 1 19 | for{ 20 | conn,err := listen_socket.Accept() 21 | if err != nil{ 22 | fmt.Println("connect failed ...") 23 | } 24 | fmt.Println(conn.RemoteAddr(),"connect successed !") 25 | ConnMap[key] = conn 26 | key++ 27 | 28 | go ServHandle(conn) 29 | } 30 | 31 | } 32 | 33 | func ServHandle(conn net.Conn){ 34 | 35 | 36 | for{ 37 | datamsg := make([]byte,255) 38 | datamsg_read ,err := conn.Read(datamsg) 39 | 40 | if datamsg_read == 0 || err != nil{ 41 | continue 42 | } 43 | fmt.Println(datamsg[0:datamsg_read]) 44 | for _,v := range ConnMap{ 45 | v.Write(datamsg[0:datamsg_read]) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/ProtobufChatRoom_V2.5/README.md -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/demo/client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/ProtobufChatRoom_V2.5/demo/client.png -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/demo/server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/ProtobufChatRoom_V2.5/demo/server.png -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/clone.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2011 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | // Protocol buffer deep copy and merge. 33 | // TODO: RawMessage. 34 | 35 | package proto 36 | 37 | import ( 38 | "fmt" 39 | "log" 40 | "reflect" 41 | "strings" 42 | ) 43 | 44 | // Clone returns a deep copy of a protocol buffer. 45 | func Clone(src Message) Message { 46 | in := reflect.ValueOf(src) 47 | if in.IsNil() { 48 | return src 49 | } 50 | out := reflect.New(in.Type().Elem()) 51 | dst := out.Interface().(Message) 52 | Merge(dst, src) 53 | return dst 54 | } 55 | 56 | // Merger is the interface representing objects that can merge messages of the same type. 57 | type Merger interface { 58 | // Merge merges src into this message. 59 | // Required and optional fields that are set in src will be set to that value in dst. 60 | // Elements of repeated fields will be appended. 61 | // 62 | // Merge may panic if called with a different argument type than the receiver. 63 | Merge(src Message) 64 | } 65 | 66 | // generatedMerger is the custom merge method that generated protos will have. 67 | // We must add this method since a generate Merge method will conflict with 68 | // many existing protos that have a Merge data field already defined. 69 | type generatedMerger interface { 70 | XXX_Merge(src Message) 71 | } 72 | 73 | // Merge merges src into dst. 74 | // Required and optional fields that are set in src will be set to that value in dst. 75 | // Elements of repeated fields will be appended. 76 | // Merge panics if src and dst are not the same type, or if dst is nil. 77 | func Merge(dst, src Message) { 78 | if m, ok := dst.(Merger); ok { 79 | m.Merge(src) 80 | return 81 | } 82 | 83 | in := reflect.ValueOf(src) 84 | out := reflect.ValueOf(dst) 85 | if out.IsNil() { 86 | panic("proto: nil destination") 87 | } 88 | if in.Type() != out.Type() { 89 | panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src)) 90 | } 91 | if in.IsNil() { 92 | return // Merge from nil src is a noop 93 | } 94 | if m, ok := dst.(generatedMerger); ok { 95 | m.XXX_Merge(src) 96 | return 97 | } 98 | mergeStruct(out.Elem(), in.Elem()) 99 | } 100 | 101 | func mergeStruct(out, in reflect.Value) { 102 | sprop := GetProperties(in.Type()) 103 | for i := 0; i < in.NumField(); i++ { 104 | f := in.Type().Field(i) 105 | if strings.HasPrefix(f.Name, "XXX_") { 106 | continue 107 | } 108 | mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) 109 | } 110 | 111 | if emIn, err := extendable(in.Addr().Interface()); err == nil { 112 | emOut, _ := extendable(out.Addr().Interface()) 113 | mIn, muIn := emIn.extensionsRead() 114 | if mIn != nil { 115 | mOut := emOut.extensionsWrite() 116 | muIn.Lock() 117 | mergeExtension(mOut, mIn) 118 | muIn.Unlock() 119 | } 120 | } 121 | 122 | uf := in.FieldByName("XXX_unrecognized") 123 | if !uf.IsValid() { 124 | return 125 | } 126 | uin := uf.Bytes() 127 | if len(uin) > 0 { 128 | out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) 129 | } 130 | } 131 | 132 | // mergeAny performs a merge between two values of the same type. 133 | // viaPtr indicates whether the values were indirected through a pointer (implying proto2). 134 | // prop is set if this is a struct field (it may be nil). 135 | func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { 136 | if in.Type() == protoMessageType { 137 | if !in.IsNil() { 138 | if out.IsNil() { 139 | out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) 140 | } else { 141 | Merge(out.Interface().(Message), in.Interface().(Message)) 142 | } 143 | } 144 | return 145 | } 146 | switch in.Kind() { 147 | case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, 148 | reflect.String, reflect.Uint32, reflect.Uint64: 149 | if !viaPtr && isProto3Zero(in) { 150 | return 151 | } 152 | out.Set(in) 153 | case reflect.Interface: 154 | // Probably a oneof field; copy non-nil values. 155 | if in.IsNil() { 156 | return 157 | } 158 | // Allocate destination if it is not set, or set to a different type. 159 | // Otherwise we will merge as normal. 160 | if out.IsNil() || out.Elem().Type() != in.Elem().Type() { 161 | out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) 162 | } 163 | mergeAny(out.Elem(), in.Elem(), false, nil) 164 | case reflect.Map: 165 | if in.Len() == 0 { 166 | return 167 | } 168 | if out.IsNil() { 169 | out.Set(reflect.MakeMap(in.Type())) 170 | } 171 | // For maps with value types of *T or []byte we need to deep copy each value. 172 | elemKind := in.Type().Elem().Kind() 173 | for _, key := range in.MapKeys() { 174 | var val reflect.Value 175 | switch elemKind { 176 | case reflect.Ptr: 177 | val = reflect.New(in.Type().Elem().Elem()) 178 | mergeAny(val, in.MapIndex(key), false, nil) 179 | case reflect.Slice: 180 | val = in.MapIndex(key) 181 | val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) 182 | default: 183 | val = in.MapIndex(key) 184 | } 185 | out.SetMapIndex(key, val) 186 | } 187 | case reflect.Ptr: 188 | if in.IsNil() { 189 | return 190 | } 191 | if out.IsNil() { 192 | out.Set(reflect.New(in.Elem().Type())) 193 | } 194 | mergeAny(out.Elem(), in.Elem(), true, nil) 195 | case reflect.Slice: 196 | if in.IsNil() { 197 | return 198 | } 199 | if in.Type().Elem().Kind() == reflect.Uint8 { 200 | // []byte is a scalar bytes field, not a repeated field. 201 | 202 | // Edge case: if this is in a proto3 message, a zero length 203 | // bytes field is considered the zero value, and should not 204 | // be merged. 205 | if prop != nil && prop.proto3 && in.Len() == 0 { 206 | return 207 | } 208 | 209 | // Make a deep copy. 210 | // Append to []byte{} instead of []byte(nil) so that we never end up 211 | // with a nil result. 212 | out.SetBytes(append([]byte{}, in.Bytes()...)) 213 | return 214 | } 215 | n := in.Len() 216 | if out.IsNil() { 217 | out.Set(reflect.MakeSlice(in.Type(), 0, n)) 218 | } 219 | switch in.Type().Elem().Kind() { 220 | case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, 221 | reflect.String, reflect.Uint32, reflect.Uint64: 222 | out.Set(reflect.AppendSlice(out, in)) 223 | default: 224 | for i := 0; i < n; i++ { 225 | x := reflect.Indirect(reflect.New(in.Type().Elem())) 226 | mergeAny(x, in.Index(i), false, nil) 227 | out.Set(reflect.Append(out, x)) 228 | } 229 | } 230 | case reflect.Struct: 231 | mergeStruct(out, in) 232 | default: 233 | // unknown type, so not a protocol buffer 234 | log.Printf("proto: don't know how to copy %v", in) 235 | } 236 | } 237 | 238 | func mergeExtension(out, in map[int32]Extension) { 239 | for extNum, eIn := range in { 240 | eOut := Extension{desc: eIn.desc} 241 | if eIn.value != nil { 242 | v := reflect.New(reflect.TypeOf(eIn.value)).Elem() 243 | mergeAny(v, reflect.ValueOf(eIn.value), false, nil) 244 | eOut.value = v.Interface() 245 | } 246 | if eIn.enc != nil { 247 | eOut.enc = make([]byte, len(eIn.enc)) 248 | copy(eOut.enc, eIn.enc) 249 | } 250 | 251 | out[extNum] = eOut 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/decode.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | /* 35 | * Routines for decoding protocol buffer data to construct in-memory representations. 36 | */ 37 | 38 | import ( 39 | "errors" 40 | "fmt" 41 | "io" 42 | ) 43 | 44 | // errOverflow is returned when an integer is too large to be represented. 45 | var errOverflow = errors.New("proto: integer overflow") 46 | 47 | // ErrInternalBadWireType is returned by generated code when an incorrect 48 | // wire type is encountered. It does not get returned to user code. 49 | var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") 50 | 51 | // DecodeVarint reads a varint-encoded integer from the slice. 52 | // It returns the integer and the number of bytes consumed, or 53 | // zero if there is not enough. 54 | // This is the format for the 55 | // int32, int64, uint32, uint64, bool, and enum 56 | // protocol buffer types. 57 | func DecodeVarint(buf []byte) (x uint64, n int) { 58 | for shift := uint(0); shift < 64; shift += 7 { 59 | if n >= len(buf) { 60 | return 0, 0 61 | } 62 | b := uint64(buf[n]) 63 | n++ 64 | x |= (b & 0x7F) << shift 65 | if (b & 0x80) == 0 { 66 | return x, n 67 | } 68 | } 69 | 70 | // The number is too large to represent in a 64-bit value. 71 | return 0, 0 72 | } 73 | 74 | func (p *Buffer) decodeVarintSlow() (x uint64, err error) { 75 | i := p.index 76 | l := len(p.buf) 77 | 78 | for shift := uint(0); shift < 64; shift += 7 { 79 | if i >= l { 80 | err = io.ErrUnexpectedEOF 81 | return 82 | } 83 | b := p.buf[i] 84 | i++ 85 | x |= (uint64(b) & 0x7F) << shift 86 | if b < 0x80 { 87 | p.index = i 88 | return 89 | } 90 | } 91 | 92 | // The number is too large to represent in a 64-bit value. 93 | err = errOverflow 94 | return 95 | } 96 | 97 | // DecodeVarint reads a varint-encoded integer from the Buffer. 98 | // This is the format for the 99 | // int32, int64, uint32, uint64, bool, and enum 100 | // protocol buffer types. 101 | func (p *Buffer) DecodeVarint() (x uint64, err error) { 102 | i := p.index 103 | buf := p.buf 104 | 105 | if i >= len(buf) { 106 | return 0, io.ErrUnexpectedEOF 107 | } else if buf[i] < 0x80 { 108 | p.index++ 109 | return uint64(buf[i]), nil 110 | } else if len(buf)-i < 10 { 111 | return p.decodeVarintSlow() 112 | } 113 | 114 | var b uint64 115 | // we already checked the first byte 116 | x = uint64(buf[i]) - 0x80 117 | i++ 118 | 119 | b = uint64(buf[i]) 120 | i++ 121 | x += b << 7 122 | if b&0x80 == 0 { 123 | goto done 124 | } 125 | x -= 0x80 << 7 126 | 127 | b = uint64(buf[i]) 128 | i++ 129 | x += b << 14 130 | if b&0x80 == 0 { 131 | goto done 132 | } 133 | x -= 0x80 << 14 134 | 135 | b = uint64(buf[i]) 136 | i++ 137 | x += b << 21 138 | if b&0x80 == 0 { 139 | goto done 140 | } 141 | x -= 0x80 << 21 142 | 143 | b = uint64(buf[i]) 144 | i++ 145 | x += b << 28 146 | if b&0x80 == 0 { 147 | goto done 148 | } 149 | x -= 0x80 << 28 150 | 151 | b = uint64(buf[i]) 152 | i++ 153 | x += b << 35 154 | if b&0x80 == 0 { 155 | goto done 156 | } 157 | x -= 0x80 << 35 158 | 159 | b = uint64(buf[i]) 160 | i++ 161 | x += b << 42 162 | if b&0x80 == 0 { 163 | goto done 164 | } 165 | x -= 0x80 << 42 166 | 167 | b = uint64(buf[i]) 168 | i++ 169 | x += b << 49 170 | if b&0x80 == 0 { 171 | goto done 172 | } 173 | x -= 0x80 << 49 174 | 175 | b = uint64(buf[i]) 176 | i++ 177 | x += b << 56 178 | if b&0x80 == 0 { 179 | goto done 180 | } 181 | x -= 0x80 << 56 182 | 183 | b = uint64(buf[i]) 184 | i++ 185 | x += b << 63 186 | if b&0x80 == 0 { 187 | goto done 188 | } 189 | // x -= 0x80 << 63 // Always zero. 190 | 191 | return 0, errOverflow 192 | 193 | done: 194 | p.index = i 195 | return x, nil 196 | } 197 | 198 | // DecodeFixed64 reads a 64-bit integer from the Buffer. 199 | // This is the format for the 200 | // fixed64, sfixed64, and double protocol buffer types. 201 | func (p *Buffer) DecodeFixed64() (x uint64, err error) { 202 | // x, err already 0 203 | i := p.index + 8 204 | if i < 0 || i > len(p.buf) { 205 | err = io.ErrUnexpectedEOF 206 | return 207 | } 208 | p.index = i 209 | 210 | x = uint64(p.buf[i-8]) 211 | x |= uint64(p.buf[i-7]) << 8 212 | x |= uint64(p.buf[i-6]) << 16 213 | x |= uint64(p.buf[i-5]) << 24 214 | x |= uint64(p.buf[i-4]) << 32 215 | x |= uint64(p.buf[i-3]) << 40 216 | x |= uint64(p.buf[i-2]) << 48 217 | x |= uint64(p.buf[i-1]) << 56 218 | return 219 | } 220 | 221 | // DecodeFixed32 reads a 32-bit integer from the Buffer. 222 | // This is the format for the 223 | // fixed32, sfixed32, and float protocol buffer types. 224 | func (p *Buffer) DecodeFixed32() (x uint64, err error) { 225 | // x, err already 0 226 | i := p.index + 4 227 | if i < 0 || i > len(p.buf) { 228 | err = io.ErrUnexpectedEOF 229 | return 230 | } 231 | p.index = i 232 | 233 | x = uint64(p.buf[i-4]) 234 | x |= uint64(p.buf[i-3]) << 8 235 | x |= uint64(p.buf[i-2]) << 16 236 | x |= uint64(p.buf[i-1]) << 24 237 | return 238 | } 239 | 240 | // DecodeZigzag64 reads a zigzag-encoded 64-bit integer 241 | // from the Buffer. 242 | // This is the format used for the sint64 protocol buffer type. 243 | func (p *Buffer) DecodeZigzag64() (x uint64, err error) { 244 | x, err = p.DecodeVarint() 245 | if err != nil { 246 | return 247 | } 248 | x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) 249 | return 250 | } 251 | 252 | // DecodeZigzag32 reads a zigzag-encoded 32-bit integer 253 | // from the Buffer. 254 | // This is the format used for the sint32 protocol buffer type. 255 | func (p *Buffer) DecodeZigzag32() (x uint64, err error) { 256 | x, err = p.DecodeVarint() 257 | if err != nil { 258 | return 259 | } 260 | x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) 261 | return 262 | } 263 | 264 | // DecodeRawBytes reads a count-delimited byte buffer from the Buffer. 265 | // This is the format used for the bytes protocol buffer 266 | // type and for embedded messages. 267 | func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { 268 | n, err := p.DecodeVarint() 269 | if err != nil { 270 | return nil, err 271 | } 272 | 273 | nb := int(n) 274 | if nb < 0 { 275 | return nil, fmt.Errorf("proto: bad byte length %d", nb) 276 | } 277 | end := p.index + nb 278 | if end < p.index || end > len(p.buf) { 279 | return nil, io.ErrUnexpectedEOF 280 | } 281 | 282 | if !alloc { 283 | // todo: check if can get more uses of alloc=false 284 | buf = p.buf[p.index:end] 285 | p.index += nb 286 | return 287 | } 288 | 289 | buf = make([]byte, nb) 290 | copy(buf, p.buf[p.index:]) 291 | p.index += nb 292 | return 293 | } 294 | 295 | // DecodeStringBytes reads an encoded string from the Buffer. 296 | // This is the format used for the proto2 string type. 297 | func (p *Buffer) DecodeStringBytes() (s string, err error) { 298 | buf, err := p.DecodeRawBytes(false) 299 | if err != nil { 300 | return 301 | } 302 | return string(buf), nil 303 | } 304 | 305 | // Unmarshaler is the interface representing objects that can 306 | // unmarshal themselves. The argument points to data that may be 307 | // overwritten, so implementations should not keep references to the 308 | // buffer. 309 | // Unmarshal implementations should not clear the receiver. 310 | // Any unmarshaled data should be merged into the receiver. 311 | // Callers of Unmarshal that do not want to retain existing data 312 | // should Reset the receiver before calling Unmarshal. 313 | type Unmarshaler interface { 314 | Unmarshal([]byte) error 315 | } 316 | 317 | // newUnmarshaler is the interface representing objects that can 318 | // unmarshal themselves. The semantics are identical to Unmarshaler. 319 | // 320 | // This exists to support protoc-gen-go generated messages. 321 | // The proto package will stop type-asserting to this interface in the future. 322 | // 323 | // DO NOT DEPEND ON THIS. 324 | type newUnmarshaler interface { 325 | XXX_Unmarshal([]byte) error 326 | } 327 | 328 | // Unmarshal parses the protocol buffer representation in buf and places the 329 | // decoded result in pb. If the struct underlying pb does not match 330 | // the data in buf, the results can be unpredictable. 331 | // 332 | // Unmarshal resets pb before starting to unmarshal, so any 333 | // existing data in pb is always removed. Use UnmarshalMerge 334 | // to preserve and append to existing data. 335 | func Unmarshal(buf []byte, pb Message) error { 336 | pb.Reset() 337 | if u, ok := pb.(newUnmarshaler); ok { 338 | return u.XXX_Unmarshal(buf) 339 | } 340 | if u, ok := pb.(Unmarshaler); ok { 341 | return u.Unmarshal(buf) 342 | } 343 | return NewBuffer(buf).Unmarshal(pb) 344 | } 345 | 346 | // UnmarshalMerge parses the protocol buffer representation in buf and 347 | // writes the decoded result to pb. If the struct underlying pb does not match 348 | // the data in buf, the results can be unpredictable. 349 | // 350 | // UnmarshalMerge merges into existing data in pb. 351 | // Most code should use Unmarshal instead. 352 | func UnmarshalMerge(buf []byte, pb Message) error { 353 | if u, ok := pb.(newUnmarshaler); ok { 354 | return u.XXX_Unmarshal(buf) 355 | } 356 | if u, ok := pb.(Unmarshaler); ok { 357 | // NOTE: The history of proto have unfortunately been inconsistent 358 | // whether Unmarshaler should or should not implicitly clear itself. 359 | // Some implementations do, most do not. 360 | // Thus, calling this here may or may not do what people want. 361 | // 362 | // See https://github.com/golang/protobuf/issues/424 363 | return u.Unmarshal(buf) 364 | } 365 | return NewBuffer(buf).Unmarshal(pb) 366 | } 367 | 368 | // DecodeMessage reads a count-delimited message from the Buffer. 369 | func (p *Buffer) DecodeMessage(pb Message) error { 370 | enc, err := p.DecodeRawBytes(false) 371 | if err != nil { 372 | return err 373 | } 374 | return NewBuffer(enc).Unmarshal(pb) 375 | } 376 | 377 | // DecodeGroup reads a tag-delimited group from the Buffer. 378 | // StartGroup tag is already consumed. This function consumes 379 | // EndGroup tag. 380 | func (p *Buffer) DecodeGroup(pb Message) error { 381 | b := p.buf[p.index:] 382 | x, y := findEndGroup(b) 383 | if x < 0 { 384 | return io.ErrUnexpectedEOF 385 | } 386 | err := Unmarshal(b[:x], pb) 387 | p.index += y 388 | return err 389 | } 390 | 391 | // Unmarshal parses the protocol buffer representation in the 392 | // Buffer and places the decoded result in pb. If the struct 393 | // underlying pb does not match the data in the buffer, the results can be 394 | // unpredictable. 395 | // 396 | // Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. 397 | func (p *Buffer) Unmarshal(pb Message) error { 398 | // If the object can unmarshal itself, let it. 399 | if u, ok := pb.(newUnmarshaler); ok { 400 | err := u.XXX_Unmarshal(p.buf[p.index:]) 401 | p.index = len(p.buf) 402 | return err 403 | } 404 | if u, ok := pb.(Unmarshaler); ok { 405 | // NOTE: The history of proto have unfortunately been inconsistent 406 | // whether Unmarshaler should or should not implicitly clear itself. 407 | // Some implementations do, most do not. 408 | // Thus, calling this here may or may not do what people want. 409 | // 410 | // See https://github.com/golang/protobuf/issues/424 411 | err := u.Unmarshal(p.buf[p.index:]) 412 | p.index = len(p.buf) 413 | return err 414 | } 415 | 416 | // Slow workaround for messages that aren't Unmarshalers. 417 | // This includes some hand-coded .pb.go files and 418 | // bootstrap protos. 419 | // TODO: fix all of those and then add Unmarshal to 420 | // the Message interface. Then: 421 | // The cast above and code below can be deleted. 422 | // The old unmarshaler can be deleted. 423 | // Clients can call Unmarshal directly (can already do that, actually). 424 | var info InternalMessageInfo 425 | err := info.Unmarshal(pb, p.buf[p.index:]) 426 | p.index = len(p.buf) 427 | return err 428 | } 429 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/discard.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2017 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | import ( 35 | "fmt" 36 | "reflect" 37 | "strings" 38 | "sync" 39 | "sync/atomic" 40 | ) 41 | 42 | type generatedDiscarder interface { 43 | XXX_DiscardUnknown() 44 | } 45 | 46 | // DiscardUnknown recursively discards all unknown fields from this message 47 | // and all embedded messages. 48 | // 49 | // When unmarshaling a message with unrecognized fields, the tags and values 50 | // of such fields are preserved in the Message. This allows a later call to 51 | // marshal to be able to produce a message that continues to have those 52 | // unrecognized fields. To avoid this, DiscardUnknown is used to 53 | // explicitly clear the unknown fields after unmarshaling. 54 | // 55 | // For proto2 messages, the unknown fields of message extensions are only 56 | // discarded from messages that have been accessed via GetExtension. 57 | func DiscardUnknown(m Message) { 58 | if m, ok := m.(generatedDiscarder); ok { 59 | m.XXX_DiscardUnknown() 60 | return 61 | } 62 | // TODO: Dynamically populate a InternalMessageInfo for legacy messages, 63 | // but the master branch has no implementation for InternalMessageInfo, 64 | // so it would be more work to replicate that approach. 65 | discardLegacy(m) 66 | } 67 | 68 | // DiscardUnknown recursively discards all unknown fields. 69 | func (a *InternalMessageInfo) DiscardUnknown(m Message) { 70 | di := atomicLoadDiscardInfo(&a.discard) 71 | if di == nil { 72 | di = getDiscardInfo(reflect.TypeOf(m).Elem()) 73 | atomicStoreDiscardInfo(&a.discard, di) 74 | } 75 | di.discard(toPointer(&m)) 76 | } 77 | 78 | type discardInfo struct { 79 | typ reflect.Type 80 | 81 | initialized int32 // 0: only typ is valid, 1: everything is valid 82 | lock sync.Mutex 83 | 84 | fields []discardFieldInfo 85 | unrecognized field 86 | } 87 | 88 | type discardFieldInfo struct { 89 | field field // Offset of field, guaranteed to be valid 90 | discard func(src pointer) 91 | } 92 | 93 | var ( 94 | discardInfoMap = map[reflect.Type]*discardInfo{} 95 | discardInfoLock sync.Mutex 96 | ) 97 | 98 | func getDiscardInfo(t reflect.Type) *discardInfo { 99 | discardInfoLock.Lock() 100 | defer discardInfoLock.Unlock() 101 | di := discardInfoMap[t] 102 | if di == nil { 103 | di = &discardInfo{typ: t} 104 | discardInfoMap[t] = di 105 | } 106 | return di 107 | } 108 | 109 | func (di *discardInfo) discard(src pointer) { 110 | if src.isNil() { 111 | return // Nothing to do. 112 | } 113 | 114 | if atomic.LoadInt32(&di.initialized) == 0 { 115 | di.computeDiscardInfo() 116 | } 117 | 118 | for _, fi := range di.fields { 119 | sfp := src.offset(fi.field) 120 | fi.discard(sfp) 121 | } 122 | 123 | // For proto2 messages, only discard unknown fields in message extensions 124 | // that have been accessed via GetExtension. 125 | if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil { 126 | // Ignore lock since DiscardUnknown is not concurrency safe. 127 | emm, _ := em.extensionsRead() 128 | for _, mx := range emm { 129 | if m, ok := mx.value.(Message); ok { 130 | DiscardUnknown(m) 131 | } 132 | } 133 | } 134 | 135 | if di.unrecognized.IsValid() { 136 | *src.offset(di.unrecognized).toBytes() = nil 137 | } 138 | } 139 | 140 | func (di *discardInfo) computeDiscardInfo() { 141 | di.lock.Lock() 142 | defer di.lock.Unlock() 143 | if di.initialized != 0 { 144 | return 145 | } 146 | t := di.typ 147 | n := t.NumField() 148 | 149 | for i := 0; i < n; i++ { 150 | f := t.Field(i) 151 | if strings.HasPrefix(f.Name, "XXX_") { 152 | continue 153 | } 154 | 155 | dfi := discardFieldInfo{field: toField(&f)} 156 | tf := f.Type 157 | 158 | // Unwrap tf to get its most basic type. 159 | var isPointer, isSlice bool 160 | if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { 161 | isSlice = true 162 | tf = tf.Elem() 163 | } 164 | if tf.Kind() == reflect.Ptr { 165 | isPointer = true 166 | tf = tf.Elem() 167 | } 168 | if isPointer && isSlice && tf.Kind() != reflect.Struct { 169 | panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name)) 170 | } 171 | 172 | switch tf.Kind() { 173 | case reflect.Struct: 174 | switch { 175 | case !isPointer: 176 | panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name)) 177 | case isSlice: // E.g., []*pb.T 178 | di := getDiscardInfo(tf) 179 | dfi.discard = func(src pointer) { 180 | sps := src.getPointerSlice() 181 | for _, sp := range sps { 182 | if !sp.isNil() { 183 | di.discard(sp) 184 | } 185 | } 186 | } 187 | default: // E.g., *pb.T 188 | di := getDiscardInfo(tf) 189 | dfi.discard = func(src pointer) { 190 | sp := src.getPointer() 191 | if !sp.isNil() { 192 | di.discard(sp) 193 | } 194 | } 195 | } 196 | case reflect.Map: 197 | switch { 198 | case isPointer || isSlice: 199 | panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name)) 200 | default: // E.g., map[K]V 201 | if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T) 202 | dfi.discard = func(src pointer) { 203 | sm := src.asPointerTo(tf).Elem() 204 | if sm.Len() == 0 { 205 | return 206 | } 207 | for _, key := range sm.MapKeys() { 208 | val := sm.MapIndex(key) 209 | DiscardUnknown(val.Interface().(Message)) 210 | } 211 | } 212 | } else { 213 | dfi.discard = func(pointer) {} // Noop 214 | } 215 | } 216 | case reflect.Interface: 217 | // Must be oneof field. 218 | switch { 219 | case isPointer || isSlice: 220 | panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name)) 221 | default: // E.g., interface{} 222 | // TODO: Make this faster? 223 | dfi.discard = func(src pointer) { 224 | su := src.asPointerTo(tf).Elem() 225 | if !su.IsNil() { 226 | sv := su.Elem().Elem().Field(0) 227 | if sv.Kind() == reflect.Ptr && sv.IsNil() { 228 | return 229 | } 230 | switch sv.Type().Kind() { 231 | case reflect.Ptr: // Proto struct (e.g., *T) 232 | DiscardUnknown(sv.Interface().(Message)) 233 | } 234 | } 235 | } 236 | } 237 | default: 238 | continue 239 | } 240 | di.fields = append(di.fields, dfi) 241 | } 242 | 243 | di.unrecognized = invalidField 244 | if f, ok := t.FieldByName("XXX_unrecognized"); ok { 245 | if f.Type != reflect.TypeOf([]byte{}) { 246 | panic("expected XXX_unrecognized to be of type []byte") 247 | } 248 | di.unrecognized = toField(&f) 249 | } 250 | 251 | atomic.StoreInt32(&di.initialized, 1) 252 | } 253 | 254 | func discardLegacy(m Message) { 255 | v := reflect.ValueOf(m) 256 | if v.Kind() != reflect.Ptr || v.IsNil() { 257 | return 258 | } 259 | v = v.Elem() 260 | if v.Kind() != reflect.Struct { 261 | return 262 | } 263 | t := v.Type() 264 | 265 | for i := 0; i < v.NumField(); i++ { 266 | f := t.Field(i) 267 | if strings.HasPrefix(f.Name, "XXX_") { 268 | continue 269 | } 270 | vf := v.Field(i) 271 | tf := f.Type 272 | 273 | // Unwrap tf to get its most basic type. 274 | var isPointer, isSlice bool 275 | if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { 276 | isSlice = true 277 | tf = tf.Elem() 278 | } 279 | if tf.Kind() == reflect.Ptr { 280 | isPointer = true 281 | tf = tf.Elem() 282 | } 283 | if isPointer && isSlice && tf.Kind() != reflect.Struct { 284 | panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name)) 285 | } 286 | 287 | switch tf.Kind() { 288 | case reflect.Struct: 289 | switch { 290 | case !isPointer: 291 | panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name)) 292 | case isSlice: // E.g., []*pb.T 293 | for j := 0; j < vf.Len(); j++ { 294 | discardLegacy(vf.Index(j).Interface().(Message)) 295 | } 296 | default: // E.g., *pb.T 297 | discardLegacy(vf.Interface().(Message)) 298 | } 299 | case reflect.Map: 300 | switch { 301 | case isPointer || isSlice: 302 | panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name)) 303 | default: // E.g., map[K]V 304 | tv := vf.Type().Elem() 305 | if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T) 306 | for _, key := range vf.MapKeys() { 307 | val := vf.MapIndex(key) 308 | discardLegacy(val.Interface().(Message)) 309 | } 310 | } 311 | } 312 | case reflect.Interface: 313 | // Must be oneof field. 314 | switch { 315 | case isPointer || isSlice: 316 | panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name)) 317 | default: // E.g., test_proto.isCommunique_Union interface 318 | if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" { 319 | vf = vf.Elem() // E.g., *test_proto.Communique_Msg 320 | if !vf.IsNil() { 321 | vf = vf.Elem() // E.g., test_proto.Communique_Msg 322 | vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value 323 | if vf.Kind() == reflect.Ptr { 324 | discardLegacy(vf.Interface().(Message)) 325 | } 326 | } 327 | } 328 | } 329 | } 330 | } 331 | 332 | if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() { 333 | if vf.Type() != reflect.TypeOf([]byte{}) { 334 | panic("expected XXX_unrecognized to be of type []byte") 335 | } 336 | vf.Set(reflect.ValueOf([]byte(nil))) 337 | } 338 | 339 | // For proto2 messages, only discard unknown fields in message extensions 340 | // that have been accessed via GetExtension. 341 | if em, err := extendable(m); err == nil { 342 | // Ignore lock since discardLegacy is not concurrency safe. 343 | emm, _ := em.extensionsRead() 344 | for _, mx := range emm { 345 | if m, ok := mx.value.(Message); ok { 346 | discardLegacy(m) 347 | } 348 | } 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/encode.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | /* 35 | * Routines for encoding data into the wire format for protocol buffers. 36 | */ 37 | 38 | import ( 39 | "errors" 40 | "fmt" 41 | "reflect" 42 | ) 43 | 44 | // RequiredNotSetError is an error type returned by either Marshal or Unmarshal. 45 | // Marshal reports this when a required field is not initialized. 46 | // Unmarshal reports this when a required field is missing from the wire data. 47 | type RequiredNotSetError struct { 48 | field string 49 | } 50 | 51 | func (e *RequiredNotSetError) Error() string { 52 | if e.field == "" { 53 | return fmt.Sprintf("proto: required field not set") 54 | } 55 | return fmt.Sprintf("proto: required field %q not set", e.field) 56 | } 57 | 58 | var ( 59 | // errRepeatedHasNil is the error returned if Marshal is called with 60 | // a struct with a repeated field containing a nil element. 61 | errRepeatedHasNil = errors.New("proto: repeated field has nil element") 62 | 63 | // errOneofHasNil is the error returned if Marshal is called with 64 | // a struct with a oneof field containing a nil element. 65 | errOneofHasNil = errors.New("proto: oneof field has nil value") 66 | 67 | // ErrNil is the error returned if Marshal is called with nil. 68 | ErrNil = errors.New("proto: Marshal called with nil") 69 | 70 | // ErrTooLarge is the error returned if Marshal is called with a 71 | // message that encodes to >2GB. 72 | ErrTooLarge = errors.New("proto: message encodes to over 2 GB") 73 | ) 74 | 75 | // The fundamental encoders that put bytes on the wire. 76 | // Those that take integer types all accept uint64 and are 77 | // therefore of type valueEncoder. 78 | 79 | const maxVarintBytes = 10 // maximum length of a varint 80 | 81 | // EncodeVarint returns the varint encoding of x. 82 | // This is the format for the 83 | // int32, int64, uint32, uint64, bool, and enum 84 | // protocol buffer types. 85 | // Not used by the package itself, but helpful to clients 86 | // wishing to use the same encoding. 87 | func EncodeVarint(x uint64) []byte { 88 | var buf [maxVarintBytes]byte 89 | var n int 90 | for n = 0; x > 127; n++ { 91 | buf[n] = 0x80 | uint8(x&0x7F) 92 | x >>= 7 93 | } 94 | buf[n] = uint8(x) 95 | n++ 96 | return buf[0:n] 97 | } 98 | 99 | // EncodeVarint writes a varint-encoded integer to the Buffer. 100 | // This is the format for the 101 | // int32, int64, uint32, uint64, bool, and enum 102 | // protocol buffer types. 103 | func (p *Buffer) EncodeVarint(x uint64) error { 104 | for x >= 1<<7 { 105 | p.buf = append(p.buf, uint8(x&0x7f|0x80)) 106 | x >>= 7 107 | } 108 | p.buf = append(p.buf, uint8(x)) 109 | return nil 110 | } 111 | 112 | // SizeVarint returns the varint encoding size of an integer. 113 | func SizeVarint(x uint64) int { 114 | switch { 115 | case x < 1<<7: 116 | return 1 117 | case x < 1<<14: 118 | return 2 119 | case x < 1<<21: 120 | return 3 121 | case x < 1<<28: 122 | return 4 123 | case x < 1<<35: 124 | return 5 125 | case x < 1<<42: 126 | return 6 127 | case x < 1<<49: 128 | return 7 129 | case x < 1<<56: 130 | return 8 131 | case x < 1<<63: 132 | return 9 133 | } 134 | return 10 135 | } 136 | 137 | // EncodeFixed64 writes a 64-bit integer to the Buffer. 138 | // This is the format for the 139 | // fixed64, sfixed64, and double protocol buffer types. 140 | func (p *Buffer) EncodeFixed64(x uint64) error { 141 | p.buf = append(p.buf, 142 | uint8(x), 143 | uint8(x>>8), 144 | uint8(x>>16), 145 | uint8(x>>24), 146 | uint8(x>>32), 147 | uint8(x>>40), 148 | uint8(x>>48), 149 | uint8(x>>56)) 150 | return nil 151 | } 152 | 153 | // EncodeFixed32 writes a 32-bit integer to the Buffer. 154 | // This is the format for the 155 | // fixed32, sfixed32, and float protocol buffer types. 156 | func (p *Buffer) EncodeFixed32(x uint64) error { 157 | p.buf = append(p.buf, 158 | uint8(x), 159 | uint8(x>>8), 160 | uint8(x>>16), 161 | uint8(x>>24)) 162 | return nil 163 | } 164 | 165 | // EncodeZigzag64 writes a zigzag-encoded 64-bit integer 166 | // to the Buffer. 167 | // This is the format used for the sint64 protocol buffer type. 168 | func (p *Buffer) EncodeZigzag64(x uint64) error { 169 | // use signed number to get arithmetic right shift. 170 | return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) 171 | } 172 | 173 | // EncodeZigzag32 writes a zigzag-encoded 32-bit integer 174 | // to the Buffer. 175 | // This is the format used for the sint32 protocol buffer type. 176 | func (p *Buffer) EncodeZigzag32(x uint64) error { 177 | // use signed number to get arithmetic right shift. 178 | return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) 179 | } 180 | 181 | // EncodeRawBytes writes a count-delimited byte buffer to the Buffer. 182 | // This is the format used for the bytes protocol buffer 183 | // type and for embedded messages. 184 | func (p *Buffer) EncodeRawBytes(b []byte) error { 185 | p.EncodeVarint(uint64(len(b))) 186 | p.buf = append(p.buf, b...) 187 | return nil 188 | } 189 | 190 | // EncodeStringBytes writes an encoded string to the Buffer. 191 | // This is the format used for the proto2 string type. 192 | func (p *Buffer) EncodeStringBytes(s string) error { 193 | p.EncodeVarint(uint64(len(s))) 194 | p.buf = append(p.buf, s...) 195 | return nil 196 | } 197 | 198 | // Marshaler is the interface representing objects that can marshal themselves. 199 | type Marshaler interface { 200 | Marshal() ([]byte, error) 201 | } 202 | 203 | // EncodeMessage writes the protocol buffer to the Buffer, 204 | // prefixed by a varint-encoded length. 205 | func (p *Buffer) EncodeMessage(pb Message) error { 206 | siz := Size(pb) 207 | p.EncodeVarint(uint64(siz)) 208 | return p.Marshal(pb) 209 | } 210 | 211 | // All protocol buffer fields are nillable, but be careful. 212 | func isNil(v reflect.Value) bool { 213 | switch v.Kind() { 214 | case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: 215 | return v.IsNil() 216 | } 217 | return false 218 | } 219 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/equal.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2011 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | // Protocol buffer comparison. 33 | 34 | package proto 35 | 36 | import ( 37 | "bytes" 38 | "log" 39 | "reflect" 40 | "strings" 41 | ) 42 | 43 | /* 44 | Equal returns true iff protocol buffers a and b are equal. 45 | The arguments must both be pointers to protocol buffer structs. 46 | 47 | Equality is defined in this way: 48 | - Two messages are equal iff they are the same type, 49 | corresponding fields are equal, unknown field sets 50 | are equal, and extensions sets are equal. 51 | - Two set scalar fields are equal iff their values are equal. 52 | If the fields are of a floating-point type, remember that 53 | NaN != x for all x, including NaN. If the message is defined 54 | in a proto3 .proto file, fields are not "set"; specifically, 55 | zero length proto3 "bytes" fields are equal (nil == {}). 56 | - Two repeated fields are equal iff their lengths are the same, 57 | and their corresponding elements are equal. Note a "bytes" field, 58 | although represented by []byte, is not a repeated field and the 59 | rule for the scalar fields described above applies. 60 | - Two unset fields are equal. 61 | - Two unknown field sets are equal if their current 62 | encoded state is equal. 63 | - Two extension sets are equal iff they have corresponding 64 | elements that are pairwise equal. 65 | - Two map fields are equal iff their lengths are the same, 66 | and they contain the same set of elements. Zero-length map 67 | fields are equal. 68 | - Every other combination of things are not equal. 69 | 70 | The return value is undefined if a and b are not protocol buffers. 71 | */ 72 | func Equal(a, b Message) bool { 73 | if a == nil || b == nil { 74 | return a == b 75 | } 76 | v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) 77 | if v1.Type() != v2.Type() { 78 | return false 79 | } 80 | if v1.Kind() == reflect.Ptr { 81 | if v1.IsNil() { 82 | return v2.IsNil() 83 | } 84 | if v2.IsNil() { 85 | return false 86 | } 87 | v1, v2 = v1.Elem(), v2.Elem() 88 | } 89 | if v1.Kind() != reflect.Struct { 90 | return false 91 | } 92 | return equalStruct(v1, v2) 93 | } 94 | 95 | // v1 and v2 are known to have the same type. 96 | func equalStruct(v1, v2 reflect.Value) bool { 97 | sprop := GetProperties(v1.Type()) 98 | for i := 0; i < v1.NumField(); i++ { 99 | f := v1.Type().Field(i) 100 | if strings.HasPrefix(f.Name, "XXX_") { 101 | continue 102 | } 103 | f1, f2 := v1.Field(i), v2.Field(i) 104 | if f.Type.Kind() == reflect.Ptr { 105 | if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { 106 | // both unset 107 | continue 108 | } else if n1 != n2 { 109 | // set/unset mismatch 110 | return false 111 | } 112 | f1, f2 = f1.Elem(), f2.Elem() 113 | } 114 | if !equalAny(f1, f2, sprop.Prop[i]) { 115 | return false 116 | } 117 | } 118 | 119 | if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { 120 | em2 := v2.FieldByName("XXX_InternalExtensions") 121 | if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { 122 | return false 123 | } 124 | } 125 | 126 | if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { 127 | em2 := v2.FieldByName("XXX_extensions") 128 | if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { 129 | return false 130 | } 131 | } 132 | 133 | uf := v1.FieldByName("XXX_unrecognized") 134 | if !uf.IsValid() { 135 | return true 136 | } 137 | 138 | u1 := uf.Bytes() 139 | u2 := v2.FieldByName("XXX_unrecognized").Bytes() 140 | return bytes.Equal(u1, u2) 141 | } 142 | 143 | // v1 and v2 are known to have the same type. 144 | // prop may be nil. 145 | func equalAny(v1, v2 reflect.Value, prop *Properties) bool { 146 | if v1.Type() == protoMessageType { 147 | m1, _ := v1.Interface().(Message) 148 | m2, _ := v2.Interface().(Message) 149 | return Equal(m1, m2) 150 | } 151 | switch v1.Kind() { 152 | case reflect.Bool: 153 | return v1.Bool() == v2.Bool() 154 | case reflect.Float32, reflect.Float64: 155 | return v1.Float() == v2.Float() 156 | case reflect.Int32, reflect.Int64: 157 | return v1.Int() == v2.Int() 158 | case reflect.Interface: 159 | // Probably a oneof field; compare the inner values. 160 | n1, n2 := v1.IsNil(), v2.IsNil() 161 | if n1 || n2 { 162 | return n1 == n2 163 | } 164 | e1, e2 := v1.Elem(), v2.Elem() 165 | if e1.Type() != e2.Type() { 166 | return false 167 | } 168 | return equalAny(e1, e2, nil) 169 | case reflect.Map: 170 | if v1.Len() != v2.Len() { 171 | return false 172 | } 173 | for _, key := range v1.MapKeys() { 174 | val2 := v2.MapIndex(key) 175 | if !val2.IsValid() { 176 | // This key was not found in the second map. 177 | return false 178 | } 179 | if !equalAny(v1.MapIndex(key), val2, nil) { 180 | return false 181 | } 182 | } 183 | return true 184 | case reflect.Ptr: 185 | // Maps may have nil values in them, so check for nil. 186 | if v1.IsNil() && v2.IsNil() { 187 | return true 188 | } 189 | if v1.IsNil() != v2.IsNil() { 190 | return false 191 | } 192 | return equalAny(v1.Elem(), v2.Elem(), prop) 193 | case reflect.Slice: 194 | if v1.Type().Elem().Kind() == reflect.Uint8 { 195 | // short circuit: []byte 196 | 197 | // Edge case: if this is in a proto3 message, a zero length 198 | // bytes field is considered the zero value. 199 | if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { 200 | return true 201 | } 202 | if v1.IsNil() != v2.IsNil() { 203 | return false 204 | } 205 | return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) 206 | } 207 | 208 | if v1.Len() != v2.Len() { 209 | return false 210 | } 211 | for i := 0; i < v1.Len(); i++ { 212 | if !equalAny(v1.Index(i), v2.Index(i), prop) { 213 | return false 214 | } 215 | } 216 | return true 217 | case reflect.String: 218 | return v1.Interface().(string) == v2.Interface().(string) 219 | case reflect.Struct: 220 | return equalStruct(v1, v2) 221 | case reflect.Uint32, reflect.Uint64: 222 | return v1.Uint() == v2.Uint() 223 | } 224 | 225 | // unknown type, so not a protocol buffer 226 | log.Printf("proto: don't know how to compare %v", v1) 227 | return false 228 | } 229 | 230 | // base is the struct type that the extensions are based on. 231 | // x1 and x2 are InternalExtensions. 232 | func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { 233 | em1, _ := x1.extensionsRead() 234 | em2, _ := x2.extensionsRead() 235 | return equalExtMap(base, em1, em2) 236 | } 237 | 238 | func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { 239 | if len(em1) != len(em2) { 240 | return false 241 | } 242 | 243 | for extNum, e1 := range em1 { 244 | e2, ok := em2[extNum] 245 | if !ok { 246 | return false 247 | } 248 | 249 | m1, m2 := e1.value, e2.value 250 | 251 | if m1 == nil && m2 == nil { 252 | // Both have only encoded form. 253 | if bytes.Equal(e1.enc, e2.enc) { 254 | continue 255 | } 256 | // The bytes are different, but the extensions might still be 257 | // equal. We need to decode them to compare. 258 | } 259 | 260 | if m1 != nil && m2 != nil { 261 | // Both are unencoded. 262 | if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { 263 | return false 264 | } 265 | continue 266 | } 267 | 268 | // At least one is encoded. To do a semantically correct comparison 269 | // we need to unmarshal them first. 270 | var desc *ExtensionDesc 271 | if m := extensionMaps[base]; m != nil { 272 | desc = m[extNum] 273 | } 274 | if desc == nil { 275 | // If both have only encoded form and the bytes are the same, 276 | // it is handled above. We get here when the bytes are different. 277 | // We don't know how to decode it, so just compare them as byte 278 | // slices. 279 | log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) 280 | return false 281 | } 282 | var err error 283 | if m1 == nil { 284 | m1, err = decodeExtension(e1.enc, desc) 285 | } 286 | if m2 == nil && err == nil { 287 | m2, err = decodeExtension(e2.enc, desc) 288 | } 289 | if err != nil { 290 | // The encoded form is invalid. 291 | log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) 292 | return false 293 | } 294 | if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { 295 | return false 296 | } 297 | } 298 | 299 | return true 300 | } 301 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/extensions.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | /* 35 | * Types and routines for supporting protocol buffer extensions. 36 | */ 37 | 38 | import ( 39 | "errors" 40 | "fmt" 41 | "io" 42 | "reflect" 43 | "strconv" 44 | "sync" 45 | ) 46 | 47 | // ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. 48 | var ErrMissingExtension = errors.New("proto: missing extension") 49 | 50 | // ExtensionRange represents a range of message extensions for a protocol buffer. 51 | // Used in code generated by the protocol compiler. 52 | type ExtensionRange struct { 53 | Start, End int32 // both inclusive 54 | } 55 | 56 | // extendableProto is an interface implemented by any protocol buffer generated by the current 57 | // proto compiler that may be extended. 58 | type extendableProto interface { 59 | Message 60 | ExtensionRangeArray() []ExtensionRange 61 | extensionsWrite() map[int32]Extension 62 | extensionsRead() (map[int32]Extension, sync.Locker) 63 | } 64 | 65 | // extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous 66 | // version of the proto compiler that may be extended. 67 | type extendableProtoV1 interface { 68 | Message 69 | ExtensionRangeArray() []ExtensionRange 70 | ExtensionMap() map[int32]Extension 71 | } 72 | 73 | // extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. 74 | type extensionAdapter struct { 75 | extendableProtoV1 76 | } 77 | 78 | func (e extensionAdapter) extensionsWrite() map[int32]Extension { 79 | return e.ExtensionMap() 80 | } 81 | 82 | func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { 83 | return e.ExtensionMap(), notLocker{} 84 | } 85 | 86 | // notLocker is a sync.Locker whose Lock and Unlock methods are nops. 87 | type notLocker struct{} 88 | 89 | func (n notLocker) Lock() {} 90 | func (n notLocker) Unlock() {} 91 | 92 | // extendable returns the extendableProto interface for the given generated proto message. 93 | // If the proto message has the old extension format, it returns a wrapper that implements 94 | // the extendableProto interface. 95 | func extendable(p interface{}) (extendableProto, error) { 96 | switch p := p.(type) { 97 | case extendableProto: 98 | if isNilPtr(p) { 99 | return nil, fmt.Errorf("proto: nil %T is not extendable", p) 100 | } 101 | return p, nil 102 | case extendableProtoV1: 103 | if isNilPtr(p) { 104 | return nil, fmt.Errorf("proto: nil %T is not extendable", p) 105 | } 106 | return extensionAdapter{p}, nil 107 | } 108 | // Don't allocate a specific error containing %T: 109 | // this is the hot path for Clone and MarshalText. 110 | return nil, errNotExtendable 111 | } 112 | 113 | var errNotExtendable = errors.New("proto: not an extendable proto.Message") 114 | 115 | func isNilPtr(x interface{}) bool { 116 | v := reflect.ValueOf(x) 117 | return v.Kind() == reflect.Ptr && v.IsNil() 118 | } 119 | 120 | // XXX_InternalExtensions is an internal representation of proto extensions. 121 | // 122 | // Each generated message struct type embeds an anonymous XXX_InternalExtensions field, 123 | // thus gaining the unexported 'extensions' method, which can be called only from the proto package. 124 | // 125 | // The methods of XXX_InternalExtensions are not concurrency safe in general, 126 | // but calls to logically read-only methods such as has and get may be executed concurrently. 127 | type XXX_InternalExtensions struct { 128 | // The struct must be indirect so that if a user inadvertently copies a 129 | // generated message and its embedded XXX_InternalExtensions, they 130 | // avoid the mayhem of a copied mutex. 131 | // 132 | // The mutex serializes all logically read-only operations to p.extensionMap. 133 | // It is up to the client to ensure that write operations to p.extensionMap are 134 | // mutually exclusive with other accesses. 135 | p *struct { 136 | mu sync.Mutex 137 | extensionMap map[int32]Extension 138 | } 139 | } 140 | 141 | // extensionsWrite returns the extension map, creating it on first use. 142 | func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { 143 | if e.p == nil { 144 | e.p = new(struct { 145 | mu sync.Mutex 146 | extensionMap map[int32]Extension 147 | }) 148 | e.p.extensionMap = make(map[int32]Extension) 149 | } 150 | return e.p.extensionMap 151 | } 152 | 153 | // extensionsRead returns the extensions map for read-only use. It may be nil. 154 | // The caller must hold the returned mutex's lock when accessing Elements within the map. 155 | func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { 156 | if e.p == nil { 157 | return nil, nil 158 | } 159 | return e.p.extensionMap, &e.p.mu 160 | } 161 | 162 | // ExtensionDesc represents an extension specification. 163 | // Used in generated code from the protocol compiler. 164 | type ExtensionDesc struct { 165 | ExtendedType Message // nil pointer to the type that is being extended 166 | ExtensionType interface{} // nil pointer to the extension type 167 | Field int32 // field number 168 | Name string // fully-qualified name of extension, for text formatting 169 | Tag string // protobuf tag style 170 | Filename string // name of the file in which the extension is defined 171 | } 172 | 173 | func (ed *ExtensionDesc) repeated() bool { 174 | t := reflect.TypeOf(ed.ExtensionType) 175 | return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 176 | } 177 | 178 | // Extension represents an extension in a message. 179 | type Extension struct { 180 | // When an extension is stored in a message using SetExtension 181 | // only desc and value are set. When the message is marshaled 182 | // enc will be set to the encoded form of the message. 183 | // 184 | // When a message is unmarshaled and contains extensions, each 185 | // extension will have only enc set. When such an extension is 186 | // accessed using GetExtension (or GetExtensions) desc and value 187 | // will be set. 188 | desc *ExtensionDesc 189 | value interface{} 190 | enc []byte 191 | } 192 | 193 | // SetRawExtension is for testing only. 194 | func SetRawExtension(base Message, id int32, b []byte) { 195 | epb, err := extendable(base) 196 | if err != nil { 197 | return 198 | } 199 | extmap := epb.extensionsWrite() 200 | extmap[id] = Extension{enc: b} 201 | } 202 | 203 | // isExtensionField returns true iff the given field number is in an extension range. 204 | func isExtensionField(pb extendableProto, field int32) bool { 205 | for _, er := range pb.ExtensionRangeArray() { 206 | if er.Start <= field && field <= er.End { 207 | return true 208 | } 209 | } 210 | return false 211 | } 212 | 213 | // checkExtensionTypes checks that the given extension is valid for pb. 214 | func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { 215 | var pbi interface{} = pb 216 | // Check the extended type. 217 | if ea, ok := pbi.(extensionAdapter); ok { 218 | pbi = ea.extendableProtoV1 219 | } 220 | if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { 221 | return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a) 222 | } 223 | // Check the range. 224 | if !isExtensionField(pb, extension.Field) { 225 | return errors.New("proto: bad extension number; not in declared ranges") 226 | } 227 | return nil 228 | } 229 | 230 | // extPropKey is sufficient to uniquely identify an extension. 231 | type extPropKey struct { 232 | base reflect.Type 233 | field int32 234 | } 235 | 236 | var extProp = struct { 237 | sync.RWMutex 238 | m map[extPropKey]*Properties 239 | }{ 240 | m: make(map[extPropKey]*Properties), 241 | } 242 | 243 | func extensionProperties(ed *ExtensionDesc) *Properties { 244 | key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} 245 | 246 | extProp.RLock() 247 | if prop, ok := extProp.m[key]; ok { 248 | extProp.RUnlock() 249 | return prop 250 | } 251 | extProp.RUnlock() 252 | 253 | extProp.Lock() 254 | defer extProp.Unlock() 255 | // Check again. 256 | if prop, ok := extProp.m[key]; ok { 257 | return prop 258 | } 259 | 260 | prop := new(Properties) 261 | prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) 262 | extProp.m[key] = prop 263 | return prop 264 | } 265 | 266 | // HasExtension returns whether the given extension is present in pb. 267 | func HasExtension(pb Message, extension *ExtensionDesc) bool { 268 | // TODO: Check types, field numbers, etc.? 269 | epb, err := extendable(pb) 270 | if err != nil { 271 | return false 272 | } 273 | extmap, mu := epb.extensionsRead() 274 | if extmap == nil { 275 | return false 276 | } 277 | mu.Lock() 278 | _, ok := extmap[extension.Field] 279 | mu.Unlock() 280 | return ok 281 | } 282 | 283 | // ClearExtension removes the given extension from pb. 284 | func ClearExtension(pb Message, extension *ExtensionDesc) { 285 | epb, err := extendable(pb) 286 | if err != nil { 287 | return 288 | } 289 | // TODO: Check types, field numbers, etc.? 290 | extmap := epb.extensionsWrite() 291 | delete(extmap, extension.Field) 292 | } 293 | 294 | // GetExtension retrieves a proto2 extended field from pb. 295 | // 296 | // If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), 297 | // then GetExtension parses the encoded field and returns a Go value of the specified type. 298 | // If the field is not present, then the default value is returned (if one is specified), 299 | // otherwise ErrMissingExtension is reported. 300 | // 301 | // If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil), 302 | // then GetExtension returns the raw encoded bytes of the field extension. 303 | func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { 304 | epb, err := extendable(pb) 305 | if err != nil { 306 | return nil, err 307 | } 308 | 309 | if extension.ExtendedType != nil { 310 | // can only check type if this is a complete descriptor 311 | if err := checkExtensionTypes(epb, extension); err != nil { 312 | return nil, err 313 | } 314 | } 315 | 316 | emap, mu := epb.extensionsRead() 317 | if emap == nil { 318 | return defaultExtensionValue(extension) 319 | } 320 | mu.Lock() 321 | defer mu.Unlock() 322 | e, ok := emap[extension.Field] 323 | if !ok { 324 | // defaultExtensionValue returns the default value or 325 | // ErrMissingExtension if there is no default. 326 | return defaultExtensionValue(extension) 327 | } 328 | 329 | if e.value != nil { 330 | // Already decoded. Check the descriptor, though. 331 | if e.desc != extension { 332 | // This shouldn't happen. If it does, it means that 333 | // GetExtension was called twice with two different 334 | // descriptors with the same field number. 335 | return nil, errors.New("proto: descriptor conflict") 336 | } 337 | return e.value, nil 338 | } 339 | 340 | if extension.ExtensionType == nil { 341 | // incomplete descriptor 342 | return e.enc, nil 343 | } 344 | 345 | v, err := decodeExtension(e.enc, extension) 346 | if err != nil { 347 | return nil, err 348 | } 349 | 350 | // Remember the decoded version and drop the encoded version. 351 | // That way it is safe to mutate what we return. 352 | e.value = v 353 | e.desc = extension 354 | e.enc = nil 355 | emap[extension.Field] = e 356 | return e.value, nil 357 | } 358 | 359 | // defaultExtensionValue returns the default value for extension. 360 | // If no default for an extension is defined ErrMissingExtension is returned. 361 | func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { 362 | if extension.ExtensionType == nil { 363 | // incomplete descriptor, so no default 364 | return nil, ErrMissingExtension 365 | } 366 | 367 | t := reflect.TypeOf(extension.ExtensionType) 368 | props := extensionProperties(extension) 369 | 370 | sf, _, err := fieldDefault(t, props) 371 | if err != nil { 372 | return nil, err 373 | } 374 | 375 | if sf == nil || sf.value == nil { 376 | // There is no default value. 377 | return nil, ErrMissingExtension 378 | } 379 | 380 | if t.Kind() != reflect.Ptr { 381 | // We do not need to return a Ptr, we can directly return sf.value. 382 | return sf.value, nil 383 | } 384 | 385 | // We need to return an interface{} that is a pointer to sf.value. 386 | value := reflect.New(t).Elem() 387 | value.Set(reflect.New(value.Type().Elem())) 388 | if sf.kind == reflect.Int32 { 389 | // We may have an int32 or an enum, but the underlying data is int32. 390 | // Since we can't set an int32 into a non int32 reflect.value directly 391 | // set it as a int32. 392 | value.Elem().SetInt(int64(sf.value.(int32))) 393 | } else { 394 | value.Elem().Set(reflect.ValueOf(sf.value)) 395 | } 396 | return value.Interface(), nil 397 | } 398 | 399 | // decodeExtension decodes an extension encoded in b. 400 | func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { 401 | t := reflect.TypeOf(extension.ExtensionType) 402 | unmarshal := typeUnmarshaler(t, extension.Tag) 403 | 404 | // t is a pointer to a struct, pointer to basic type or a slice. 405 | // Allocate space to store the pointer/slice. 406 | value := reflect.New(t).Elem() 407 | 408 | var err error 409 | for { 410 | x, n := decodeVarint(b) 411 | if n == 0 { 412 | return nil, io.ErrUnexpectedEOF 413 | } 414 | b = b[n:] 415 | wire := int(x) & 7 416 | 417 | b, err = unmarshal(b, valToPointer(value.Addr()), wire) 418 | if err != nil { 419 | return nil, err 420 | } 421 | 422 | if len(b) == 0 { 423 | break 424 | } 425 | } 426 | return value.Interface(), nil 427 | } 428 | 429 | // GetExtensions returns a slice of the extensions present in pb that are also listed in es. 430 | // The returned slice has the same length as es; missing extensions will appear as nil elements. 431 | func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { 432 | epb, err := extendable(pb) 433 | if err != nil { 434 | return nil, err 435 | } 436 | extensions = make([]interface{}, len(es)) 437 | for i, e := range es { 438 | extensions[i], err = GetExtension(epb, e) 439 | if err == ErrMissingExtension { 440 | err = nil 441 | } 442 | if err != nil { 443 | return 444 | } 445 | } 446 | return 447 | } 448 | 449 | // ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. 450 | // For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing 451 | // just the Field field, which defines the extension's field number. 452 | func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { 453 | epb, err := extendable(pb) 454 | if err != nil { 455 | return nil, err 456 | } 457 | registeredExtensions := RegisteredExtensions(pb) 458 | 459 | emap, mu := epb.extensionsRead() 460 | if emap == nil { 461 | return nil, nil 462 | } 463 | mu.Lock() 464 | defer mu.Unlock() 465 | extensions := make([]*ExtensionDesc, 0, len(emap)) 466 | for extid, e := range emap { 467 | desc := e.desc 468 | if desc == nil { 469 | desc = registeredExtensions[extid] 470 | if desc == nil { 471 | desc = &ExtensionDesc{Field: extid} 472 | } 473 | } 474 | 475 | extensions = append(extensions, desc) 476 | } 477 | return extensions, nil 478 | } 479 | 480 | // SetExtension sets the specified extension of pb to the specified value. 481 | func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { 482 | epb, err := extendable(pb) 483 | if err != nil { 484 | return err 485 | } 486 | if err := checkExtensionTypes(epb, extension); err != nil { 487 | return err 488 | } 489 | typ := reflect.TypeOf(extension.ExtensionType) 490 | if typ != reflect.TypeOf(value) { 491 | return errors.New("proto: bad extension value type") 492 | } 493 | // nil extension values need to be caught early, because the 494 | // encoder can't distinguish an ErrNil due to a nil extension 495 | // from an ErrNil due to a missing field. Extensions are 496 | // always optional, so the encoder would just swallow the error 497 | // and drop all the extensions from the encoded message. 498 | if reflect.ValueOf(value).IsNil() { 499 | return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) 500 | } 501 | 502 | extmap := epb.extensionsWrite() 503 | extmap[extension.Field] = Extension{desc: extension, value: value} 504 | return nil 505 | } 506 | 507 | // ClearAllExtensions clears all extensions from pb. 508 | func ClearAllExtensions(pb Message) { 509 | epb, err := extendable(pb) 510 | if err != nil { 511 | return 512 | } 513 | m := epb.extensionsWrite() 514 | for k := range m { 515 | delete(m, k) 516 | } 517 | } 518 | 519 | // A global registry of extensions. 520 | // The generated code will register the generated descriptors by calling RegisterExtension. 521 | 522 | var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) 523 | 524 | // RegisterExtension is called from the generated code. 525 | func RegisterExtension(desc *ExtensionDesc) { 526 | st := reflect.TypeOf(desc.ExtendedType).Elem() 527 | m := extensionMaps[st] 528 | if m == nil { 529 | m = make(map[int32]*ExtensionDesc) 530 | extensionMaps[st] = m 531 | } 532 | if _, ok := m[desc.Field]; ok { 533 | panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) 534 | } 535 | m[desc.Field] = desc 536 | } 537 | 538 | // RegisteredExtensions returns a map of the registered extensions of a 539 | // protocol buffer struct, indexed by the extension number. 540 | // The argument pb should be a nil pointer to the struct type. 541 | func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { 542 | return extensionMaps[reflect.TypeOf(pb).Elem()] 543 | } 544 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/message_set.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | /* 35 | * Support for message sets. 36 | */ 37 | 38 | import ( 39 | "bytes" 40 | "encoding/json" 41 | "errors" 42 | "fmt" 43 | "reflect" 44 | "sort" 45 | "sync" 46 | ) 47 | 48 | // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. 49 | // A message type ID is required for storing a protocol buffer in a message set. 50 | var errNoMessageTypeID = errors.New("proto does not have a message type ID") 51 | 52 | // The first two types (_MessageSet_Item and messageSet) 53 | // model what the protocol compiler produces for the following protocol message: 54 | // message MessageSet { 55 | // repeated group Item = 1 { 56 | // required int32 type_id = 2; 57 | // required string message = 3; 58 | // }; 59 | // } 60 | // That is the MessageSet wire format. We can't use a proto to generate these 61 | // because that would introduce a circular dependency between it and this package. 62 | 63 | type _MessageSet_Item struct { 64 | TypeId *int32 `protobuf:"varint,2,req,name=type_id"` 65 | Message []byte `protobuf:"bytes,3,req,name=message"` 66 | } 67 | 68 | type messageSet struct { 69 | Item []*_MessageSet_Item `protobuf:"group,1,rep"` 70 | XXX_unrecognized []byte 71 | // TODO: caching? 72 | } 73 | 74 | // Make sure messageSet is a Message. 75 | var _ Message = (*messageSet)(nil) 76 | 77 | // messageTypeIder is an interface satisfied by a protocol buffer type 78 | // that may be stored in a MessageSet. 79 | type messageTypeIder interface { 80 | MessageTypeId() int32 81 | } 82 | 83 | func (ms *messageSet) find(pb Message) *_MessageSet_Item { 84 | mti, ok := pb.(messageTypeIder) 85 | if !ok { 86 | return nil 87 | } 88 | id := mti.MessageTypeId() 89 | for _, item := range ms.Item { 90 | if *item.TypeId == id { 91 | return item 92 | } 93 | } 94 | return nil 95 | } 96 | 97 | func (ms *messageSet) Has(pb Message) bool { 98 | return ms.find(pb) != nil 99 | } 100 | 101 | func (ms *messageSet) Unmarshal(pb Message) error { 102 | if item := ms.find(pb); item != nil { 103 | return Unmarshal(item.Message, pb) 104 | } 105 | if _, ok := pb.(messageTypeIder); !ok { 106 | return errNoMessageTypeID 107 | } 108 | return nil // TODO: return error instead? 109 | } 110 | 111 | func (ms *messageSet) Marshal(pb Message) error { 112 | msg, err := Marshal(pb) 113 | if err != nil { 114 | return err 115 | } 116 | if item := ms.find(pb); item != nil { 117 | // reuse existing item 118 | item.Message = msg 119 | return nil 120 | } 121 | 122 | mti, ok := pb.(messageTypeIder) 123 | if !ok { 124 | return errNoMessageTypeID 125 | } 126 | 127 | mtid := mti.MessageTypeId() 128 | ms.Item = append(ms.Item, &_MessageSet_Item{ 129 | TypeId: &mtid, 130 | Message: msg, 131 | }) 132 | return nil 133 | } 134 | 135 | func (ms *messageSet) Reset() { *ms = messageSet{} } 136 | func (ms *messageSet) String() string { return CompactTextString(ms) } 137 | func (*messageSet) ProtoMessage() {} 138 | 139 | // Support for the message_set_wire_format message option. 140 | 141 | func skipVarint(buf []byte) []byte { 142 | i := 0 143 | for ; buf[i]&0x80 != 0; i++ { 144 | } 145 | return buf[i+1:] 146 | } 147 | 148 | // MarshalMessageSet encodes the extension map represented by m in the message set wire format. 149 | // It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. 150 | func MarshalMessageSet(exts interface{}) ([]byte, error) { 151 | return marshalMessageSet(exts, false) 152 | } 153 | 154 | // marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal. 155 | func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) { 156 | switch exts := exts.(type) { 157 | case *XXX_InternalExtensions: 158 | var u marshalInfo 159 | siz := u.sizeMessageSet(exts) 160 | b := make([]byte, 0, siz) 161 | return u.appendMessageSet(b, exts, deterministic) 162 | 163 | case map[int32]Extension: 164 | // This is an old-style extension map. 165 | // Wrap it in a new-style XXX_InternalExtensions. 166 | ie := XXX_InternalExtensions{ 167 | p: &struct { 168 | mu sync.Mutex 169 | extensionMap map[int32]Extension 170 | }{ 171 | extensionMap: exts, 172 | }, 173 | } 174 | 175 | var u marshalInfo 176 | siz := u.sizeMessageSet(&ie) 177 | b := make([]byte, 0, siz) 178 | return u.appendMessageSet(b, &ie, deterministic) 179 | 180 | default: 181 | return nil, errors.New("proto: not an extension map") 182 | } 183 | } 184 | 185 | // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. 186 | // It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. 187 | func UnmarshalMessageSet(buf []byte, exts interface{}) error { 188 | var m map[int32]Extension 189 | switch exts := exts.(type) { 190 | case *XXX_InternalExtensions: 191 | m = exts.extensionsWrite() 192 | case map[int32]Extension: 193 | m = exts 194 | default: 195 | return errors.New("proto: not an extension map") 196 | } 197 | 198 | ms := new(messageSet) 199 | if err := Unmarshal(buf, ms); err != nil { 200 | return err 201 | } 202 | for _, item := range ms.Item { 203 | id := *item.TypeId 204 | msg := item.Message 205 | 206 | // Restore wire type and field number varint, plus length varint. 207 | // Be careful to preserve duplicate items. 208 | b := EncodeVarint(uint64(id)<<3 | WireBytes) 209 | if ext, ok := m[id]; ok { 210 | // Existing data; rip off the tag and length varint 211 | // so we join the new data correctly. 212 | // We can assume that ext.enc is set because we are unmarshaling. 213 | o := ext.enc[len(b):] // skip wire type and field number 214 | _, n := DecodeVarint(o) // calculate length of length varint 215 | o = o[n:] // skip length varint 216 | msg = append(o, msg...) // join old data and new data 217 | } 218 | b = append(b, EncodeVarint(uint64(len(msg)))...) 219 | b = append(b, msg...) 220 | 221 | m[id] = Extension{enc: b} 222 | } 223 | return nil 224 | } 225 | 226 | // MarshalMessageSetJSON encodes the extension map represented by m in JSON format. 227 | // It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. 228 | func MarshalMessageSetJSON(exts interface{}) ([]byte, error) { 229 | var m map[int32]Extension 230 | switch exts := exts.(type) { 231 | case *XXX_InternalExtensions: 232 | var mu sync.Locker 233 | m, mu = exts.extensionsRead() 234 | if m != nil { 235 | // Keep the extensions map locked until we're done marshaling to prevent 236 | // races between marshaling and unmarshaling the lazily-{en,de}coded 237 | // values. 238 | mu.Lock() 239 | defer mu.Unlock() 240 | } 241 | case map[int32]Extension: 242 | m = exts 243 | default: 244 | return nil, errors.New("proto: not an extension map") 245 | } 246 | var b bytes.Buffer 247 | b.WriteByte('{') 248 | 249 | // Process the map in key order for deterministic output. 250 | ids := make([]int32, 0, len(m)) 251 | for id := range m { 252 | ids = append(ids, id) 253 | } 254 | sort.Sort(int32Slice(ids)) // int32Slice defined in text.go 255 | 256 | for i, id := range ids { 257 | ext := m[id] 258 | msd, ok := messageSetMap[id] 259 | if !ok { 260 | // Unknown type; we can't render it, so skip it. 261 | continue 262 | } 263 | 264 | if i > 0 && b.Len() > 1 { 265 | b.WriteByte(',') 266 | } 267 | 268 | fmt.Fprintf(&b, `"[%s]":`, msd.name) 269 | 270 | x := ext.value 271 | if x == nil { 272 | x = reflect.New(msd.t.Elem()).Interface() 273 | if err := Unmarshal(ext.enc, x.(Message)); err != nil { 274 | return nil, err 275 | } 276 | } 277 | d, err := json.Marshal(x) 278 | if err != nil { 279 | return nil, err 280 | } 281 | b.Write(d) 282 | } 283 | b.WriteByte('}') 284 | return b.Bytes(), nil 285 | } 286 | 287 | // UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. 288 | // It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. 289 | func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error { 290 | // Common-case fast path. 291 | if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { 292 | return nil 293 | } 294 | 295 | // This is fairly tricky, and it's not clear that it is needed. 296 | return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") 297 | } 298 | 299 | // A global registry of types that can be used in a MessageSet. 300 | 301 | var messageSetMap = make(map[int32]messageSetDesc) 302 | 303 | type messageSetDesc struct { 304 | t reflect.Type // pointer to struct 305 | name string 306 | } 307 | 308 | // RegisterMessageSetType is called from the generated code. 309 | func RegisterMessageSetType(m Message, fieldNum int32, name string) { 310 | messageSetMap[fieldNum] = messageSetDesc{ 311 | t: reflect.TypeOf(m), 312 | name: name, 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/pointer_reflect.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2012 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | // +build purego appengine js 33 | 34 | // This file contains an implementation of proto field accesses using package reflect. 35 | // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can 36 | // be used on App Engine. 37 | 38 | package proto 39 | 40 | import ( 41 | "reflect" 42 | "sync" 43 | ) 44 | 45 | const unsafeAllowed = false 46 | 47 | // A field identifies a field in a struct, accessible from a pointer. 48 | // In this implementation, a field is identified by the sequence of field indices 49 | // passed to reflect's FieldByIndex. 50 | type field []int 51 | 52 | // toField returns a field equivalent to the given reflect field. 53 | func toField(f *reflect.StructField) field { 54 | return f.Index 55 | } 56 | 57 | // invalidField is an invalid field identifier. 58 | var invalidField = field(nil) 59 | 60 | // zeroField is a noop when calling pointer.offset. 61 | var zeroField = field([]int{}) 62 | 63 | // IsValid reports whether the field identifier is valid. 64 | func (f field) IsValid() bool { return f != nil } 65 | 66 | // The pointer type is for the table-driven decoder. 67 | // The implementation here uses a reflect.Value of pointer type to 68 | // create a generic pointer. In pointer_unsafe.go we use unsafe 69 | // instead of reflect to implement the same (but faster) interface. 70 | type pointer struct { 71 | v reflect.Value 72 | } 73 | 74 | // toPointer converts an interface of pointer type to a pointer 75 | // that points to the same target. 76 | func toPointer(i *Message) pointer { 77 | return pointer{v: reflect.ValueOf(*i)} 78 | } 79 | 80 | // toAddrPointer converts an interface to a pointer that points to 81 | // the interface data. 82 | func toAddrPointer(i *interface{}, isptr bool) pointer { 83 | v := reflect.ValueOf(*i) 84 | u := reflect.New(v.Type()) 85 | u.Elem().Set(v) 86 | return pointer{v: u} 87 | } 88 | 89 | // valToPointer converts v to a pointer. v must be of pointer type. 90 | func valToPointer(v reflect.Value) pointer { 91 | return pointer{v: v} 92 | } 93 | 94 | // offset converts from a pointer to a structure to a pointer to 95 | // one of its fields. 96 | func (p pointer) offset(f field) pointer { 97 | return pointer{v: p.v.Elem().FieldByIndex(f).Addr()} 98 | } 99 | 100 | func (p pointer) isNil() bool { 101 | return p.v.IsNil() 102 | } 103 | 104 | // grow updates the slice s in place to make it one element longer. 105 | // s must be addressable. 106 | // Returns the (addressable) new element. 107 | func grow(s reflect.Value) reflect.Value { 108 | n, m := s.Len(), s.Cap() 109 | if n < m { 110 | s.SetLen(n + 1) 111 | } else { 112 | s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem()))) 113 | } 114 | return s.Index(n) 115 | } 116 | 117 | func (p pointer) toInt64() *int64 { 118 | return p.v.Interface().(*int64) 119 | } 120 | func (p pointer) toInt64Ptr() **int64 { 121 | return p.v.Interface().(**int64) 122 | } 123 | func (p pointer) toInt64Slice() *[]int64 { 124 | return p.v.Interface().(*[]int64) 125 | } 126 | 127 | var int32ptr = reflect.TypeOf((*int32)(nil)) 128 | 129 | func (p pointer) toInt32() *int32 { 130 | return p.v.Convert(int32ptr).Interface().(*int32) 131 | } 132 | 133 | // The toInt32Ptr/Slice methods don't work because of enums. 134 | // Instead, we must use set/get methods for the int32ptr/slice case. 135 | /* 136 | func (p pointer) toInt32Ptr() **int32 { 137 | return p.v.Interface().(**int32) 138 | } 139 | func (p pointer) toInt32Slice() *[]int32 { 140 | return p.v.Interface().(*[]int32) 141 | } 142 | */ 143 | func (p pointer) getInt32Ptr() *int32 { 144 | if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { 145 | // raw int32 type 146 | return p.v.Elem().Interface().(*int32) 147 | } 148 | // an enum 149 | return p.v.Elem().Convert(int32PtrType).Interface().(*int32) 150 | } 151 | func (p pointer) setInt32Ptr(v int32) { 152 | // Allocate value in a *int32. Possibly convert that to a *enum. 153 | // Then assign it to a **int32 or **enum. 154 | // Note: we can convert *int32 to *enum, but we can't convert 155 | // **int32 to **enum! 156 | p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem())) 157 | } 158 | 159 | // getInt32Slice copies []int32 from p as a new slice. 160 | // This behavior differs from the implementation in pointer_unsafe.go. 161 | func (p pointer) getInt32Slice() []int32 { 162 | if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { 163 | // raw int32 type 164 | return p.v.Elem().Interface().([]int32) 165 | } 166 | // an enum 167 | // Allocate a []int32, then assign []enum's values into it. 168 | // Note: we can't convert []enum to []int32. 169 | slice := p.v.Elem() 170 | s := make([]int32, slice.Len()) 171 | for i := 0; i < slice.Len(); i++ { 172 | s[i] = int32(slice.Index(i).Int()) 173 | } 174 | return s 175 | } 176 | 177 | // setInt32Slice copies []int32 into p as a new slice. 178 | // This behavior differs from the implementation in pointer_unsafe.go. 179 | func (p pointer) setInt32Slice(v []int32) { 180 | if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { 181 | // raw int32 type 182 | p.v.Elem().Set(reflect.ValueOf(v)) 183 | return 184 | } 185 | // an enum 186 | // Allocate a []enum, then assign []int32's values into it. 187 | // Note: we can't convert []enum to []int32. 188 | slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v)) 189 | for i, x := range v { 190 | slice.Index(i).SetInt(int64(x)) 191 | } 192 | p.v.Elem().Set(slice) 193 | } 194 | func (p pointer) appendInt32Slice(v int32) { 195 | grow(p.v.Elem()).SetInt(int64(v)) 196 | } 197 | 198 | func (p pointer) toUint64() *uint64 { 199 | return p.v.Interface().(*uint64) 200 | } 201 | func (p pointer) toUint64Ptr() **uint64 { 202 | return p.v.Interface().(**uint64) 203 | } 204 | func (p pointer) toUint64Slice() *[]uint64 { 205 | return p.v.Interface().(*[]uint64) 206 | } 207 | func (p pointer) toUint32() *uint32 { 208 | return p.v.Interface().(*uint32) 209 | } 210 | func (p pointer) toUint32Ptr() **uint32 { 211 | return p.v.Interface().(**uint32) 212 | } 213 | func (p pointer) toUint32Slice() *[]uint32 { 214 | return p.v.Interface().(*[]uint32) 215 | } 216 | func (p pointer) toBool() *bool { 217 | return p.v.Interface().(*bool) 218 | } 219 | func (p pointer) toBoolPtr() **bool { 220 | return p.v.Interface().(**bool) 221 | } 222 | func (p pointer) toBoolSlice() *[]bool { 223 | return p.v.Interface().(*[]bool) 224 | } 225 | func (p pointer) toFloat64() *float64 { 226 | return p.v.Interface().(*float64) 227 | } 228 | func (p pointer) toFloat64Ptr() **float64 { 229 | return p.v.Interface().(**float64) 230 | } 231 | func (p pointer) toFloat64Slice() *[]float64 { 232 | return p.v.Interface().(*[]float64) 233 | } 234 | func (p pointer) toFloat32() *float32 { 235 | return p.v.Interface().(*float32) 236 | } 237 | func (p pointer) toFloat32Ptr() **float32 { 238 | return p.v.Interface().(**float32) 239 | } 240 | func (p pointer) toFloat32Slice() *[]float32 { 241 | return p.v.Interface().(*[]float32) 242 | } 243 | func (p pointer) toString() *string { 244 | return p.v.Interface().(*string) 245 | } 246 | func (p pointer) toStringPtr() **string { 247 | return p.v.Interface().(**string) 248 | } 249 | func (p pointer) toStringSlice() *[]string { 250 | return p.v.Interface().(*[]string) 251 | } 252 | func (p pointer) toBytes() *[]byte { 253 | return p.v.Interface().(*[]byte) 254 | } 255 | func (p pointer) toBytesSlice() *[][]byte { 256 | return p.v.Interface().(*[][]byte) 257 | } 258 | func (p pointer) toExtensions() *XXX_InternalExtensions { 259 | return p.v.Interface().(*XXX_InternalExtensions) 260 | } 261 | func (p pointer) toOldExtensions() *map[int32]Extension { 262 | return p.v.Interface().(*map[int32]Extension) 263 | } 264 | func (p pointer) getPointer() pointer { 265 | return pointer{v: p.v.Elem()} 266 | } 267 | func (p pointer) setPointer(q pointer) { 268 | p.v.Elem().Set(q.v) 269 | } 270 | func (p pointer) appendPointer(q pointer) { 271 | grow(p.v.Elem()).Set(q.v) 272 | } 273 | 274 | // getPointerSlice copies []*T from p as a new []pointer. 275 | // This behavior differs from the implementation in pointer_unsafe.go. 276 | func (p pointer) getPointerSlice() []pointer { 277 | if p.v.IsNil() { 278 | return nil 279 | } 280 | n := p.v.Elem().Len() 281 | s := make([]pointer, n) 282 | for i := 0; i < n; i++ { 283 | s[i] = pointer{v: p.v.Elem().Index(i)} 284 | } 285 | return s 286 | } 287 | 288 | // setPointerSlice copies []pointer into p as a new []*T. 289 | // This behavior differs from the implementation in pointer_unsafe.go. 290 | func (p pointer) setPointerSlice(v []pointer) { 291 | if v == nil { 292 | p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem()) 293 | return 294 | } 295 | s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v)) 296 | for _, p := range v { 297 | s = reflect.Append(s, p.v) 298 | } 299 | p.v.Elem().Set(s) 300 | } 301 | 302 | // getInterfacePointer returns a pointer that points to the 303 | // interface data of the interface pointed by p. 304 | func (p pointer) getInterfacePointer() pointer { 305 | if p.v.Elem().IsNil() { 306 | return pointer{v: p.v.Elem()} 307 | } 308 | return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct 309 | } 310 | 311 | func (p pointer) asPointerTo(t reflect.Type) reflect.Value { 312 | // TODO: check that p.v.Type().Elem() == t? 313 | return p.v 314 | } 315 | 316 | func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { 317 | atomicLock.Lock() 318 | defer atomicLock.Unlock() 319 | return *p 320 | } 321 | func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { 322 | atomicLock.Lock() 323 | defer atomicLock.Unlock() 324 | *p = v 325 | } 326 | func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { 327 | atomicLock.Lock() 328 | defer atomicLock.Unlock() 329 | return *p 330 | } 331 | func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { 332 | atomicLock.Lock() 333 | defer atomicLock.Unlock() 334 | *p = v 335 | } 336 | func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { 337 | atomicLock.Lock() 338 | defer atomicLock.Unlock() 339 | return *p 340 | } 341 | func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { 342 | atomicLock.Lock() 343 | defer atomicLock.Unlock() 344 | *p = v 345 | } 346 | func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { 347 | atomicLock.Lock() 348 | defer atomicLock.Unlock() 349 | return *p 350 | } 351 | func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { 352 | atomicLock.Lock() 353 | defer atomicLock.Unlock() 354 | *p = v 355 | } 356 | 357 | var atomicLock sync.Mutex 358 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/pointer_unsafe.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2012 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | // +build !purego,!appengine,!js 33 | 34 | // This file contains the implementation of the proto field accesses using package unsafe. 35 | 36 | package proto 37 | 38 | import ( 39 | "reflect" 40 | "sync/atomic" 41 | "unsafe" 42 | ) 43 | 44 | const unsafeAllowed = true 45 | 46 | // A field identifies a field in a struct, accessible from a pointer. 47 | // In this implementation, a field is identified by its byte offset from the start of the struct. 48 | type field uintptr 49 | 50 | // toField returns a field equivalent to the given reflect field. 51 | func toField(f *reflect.StructField) field { 52 | return field(f.Offset) 53 | } 54 | 55 | // invalidField is an invalid field identifier. 56 | const invalidField = ^field(0) 57 | 58 | // zeroField is a noop when calling pointer.offset. 59 | const zeroField = field(0) 60 | 61 | // IsValid reports whether the field identifier is valid. 62 | func (f field) IsValid() bool { 63 | return f != invalidField 64 | } 65 | 66 | // The pointer type below is for the new table-driven encoder/decoder. 67 | // The implementation here uses unsafe.Pointer to create a generic pointer. 68 | // In pointer_reflect.go we use reflect instead of unsafe to implement 69 | // the same (but slower) interface. 70 | type pointer struct { 71 | p unsafe.Pointer 72 | } 73 | 74 | // size of pointer 75 | var ptrSize = unsafe.Sizeof(uintptr(0)) 76 | 77 | // toPointer converts an interface of pointer type to a pointer 78 | // that points to the same target. 79 | func toPointer(i *Message) pointer { 80 | // Super-tricky - read pointer out of data word of interface value. 81 | // Saves ~25ns over the equivalent: 82 | // return valToPointer(reflect.ValueOf(*i)) 83 | return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} 84 | } 85 | 86 | // toAddrPointer converts an interface to a pointer that points to 87 | // the interface data. 88 | func toAddrPointer(i *interface{}, isptr bool) pointer { 89 | // Super-tricky - read or get the address of data word of interface value. 90 | if isptr { 91 | // The interface is of pointer type, thus it is a direct interface. 92 | // The data word is the pointer data itself. We take its address. 93 | return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} 94 | } 95 | // The interface is not of pointer type. The data word is the pointer 96 | // to the data. 97 | return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} 98 | } 99 | 100 | // valToPointer converts v to a pointer. v must be of pointer type. 101 | func valToPointer(v reflect.Value) pointer { 102 | return pointer{p: unsafe.Pointer(v.Pointer())} 103 | } 104 | 105 | // offset converts from a pointer to a structure to a pointer to 106 | // one of its fields. 107 | func (p pointer) offset(f field) pointer { 108 | // For safety, we should panic if !f.IsValid, however calling panic causes 109 | // this to no longer be inlineable, which is a serious performance cost. 110 | /* 111 | if !f.IsValid() { 112 | panic("invalid field") 113 | } 114 | */ 115 | return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))} 116 | } 117 | 118 | func (p pointer) isNil() bool { 119 | return p.p == nil 120 | } 121 | 122 | func (p pointer) toInt64() *int64 { 123 | return (*int64)(p.p) 124 | } 125 | func (p pointer) toInt64Ptr() **int64 { 126 | return (**int64)(p.p) 127 | } 128 | func (p pointer) toInt64Slice() *[]int64 { 129 | return (*[]int64)(p.p) 130 | } 131 | func (p pointer) toInt32() *int32 { 132 | return (*int32)(p.p) 133 | } 134 | 135 | // See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist. 136 | /* 137 | func (p pointer) toInt32Ptr() **int32 { 138 | return (**int32)(p.p) 139 | } 140 | func (p pointer) toInt32Slice() *[]int32 { 141 | return (*[]int32)(p.p) 142 | } 143 | */ 144 | func (p pointer) getInt32Ptr() *int32 { 145 | return *(**int32)(p.p) 146 | } 147 | func (p pointer) setInt32Ptr(v int32) { 148 | *(**int32)(p.p) = &v 149 | } 150 | 151 | // getInt32Slice loads a []int32 from p. 152 | // The value returned is aliased with the original slice. 153 | // This behavior differs from the implementation in pointer_reflect.go. 154 | func (p pointer) getInt32Slice() []int32 { 155 | return *(*[]int32)(p.p) 156 | } 157 | 158 | // setInt32Slice stores a []int32 to p. 159 | // The value set is aliased with the input slice. 160 | // This behavior differs from the implementation in pointer_reflect.go. 161 | func (p pointer) setInt32Slice(v []int32) { 162 | *(*[]int32)(p.p) = v 163 | } 164 | 165 | // TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead? 166 | func (p pointer) appendInt32Slice(v int32) { 167 | s := (*[]int32)(p.p) 168 | *s = append(*s, v) 169 | } 170 | 171 | func (p pointer) toUint64() *uint64 { 172 | return (*uint64)(p.p) 173 | } 174 | func (p pointer) toUint64Ptr() **uint64 { 175 | return (**uint64)(p.p) 176 | } 177 | func (p pointer) toUint64Slice() *[]uint64 { 178 | return (*[]uint64)(p.p) 179 | } 180 | func (p pointer) toUint32() *uint32 { 181 | return (*uint32)(p.p) 182 | } 183 | func (p pointer) toUint32Ptr() **uint32 { 184 | return (**uint32)(p.p) 185 | } 186 | func (p pointer) toUint32Slice() *[]uint32 { 187 | return (*[]uint32)(p.p) 188 | } 189 | func (p pointer) toBool() *bool { 190 | return (*bool)(p.p) 191 | } 192 | func (p pointer) toBoolPtr() **bool { 193 | return (**bool)(p.p) 194 | } 195 | func (p pointer) toBoolSlice() *[]bool { 196 | return (*[]bool)(p.p) 197 | } 198 | func (p pointer) toFloat64() *float64 { 199 | return (*float64)(p.p) 200 | } 201 | func (p pointer) toFloat64Ptr() **float64 { 202 | return (**float64)(p.p) 203 | } 204 | func (p pointer) toFloat64Slice() *[]float64 { 205 | return (*[]float64)(p.p) 206 | } 207 | func (p pointer) toFloat32() *float32 { 208 | return (*float32)(p.p) 209 | } 210 | func (p pointer) toFloat32Ptr() **float32 { 211 | return (**float32)(p.p) 212 | } 213 | func (p pointer) toFloat32Slice() *[]float32 { 214 | return (*[]float32)(p.p) 215 | } 216 | func (p pointer) toString() *string { 217 | return (*string)(p.p) 218 | } 219 | func (p pointer) toStringPtr() **string { 220 | return (**string)(p.p) 221 | } 222 | func (p pointer) toStringSlice() *[]string { 223 | return (*[]string)(p.p) 224 | } 225 | func (p pointer) toBytes() *[]byte { 226 | return (*[]byte)(p.p) 227 | } 228 | func (p pointer) toBytesSlice() *[][]byte { 229 | return (*[][]byte)(p.p) 230 | } 231 | func (p pointer) toExtensions() *XXX_InternalExtensions { 232 | return (*XXX_InternalExtensions)(p.p) 233 | } 234 | func (p pointer) toOldExtensions() *map[int32]Extension { 235 | return (*map[int32]Extension)(p.p) 236 | } 237 | 238 | // getPointerSlice loads []*T from p as a []pointer. 239 | // The value returned is aliased with the original slice. 240 | // This behavior differs from the implementation in pointer_reflect.go. 241 | func (p pointer) getPointerSlice() []pointer { 242 | // Super-tricky - p should point to a []*T where T is a 243 | // message type. We load it as []pointer. 244 | return *(*[]pointer)(p.p) 245 | } 246 | 247 | // setPointerSlice stores []pointer into p as a []*T. 248 | // The value set is aliased with the input slice. 249 | // This behavior differs from the implementation in pointer_reflect.go. 250 | func (p pointer) setPointerSlice(v []pointer) { 251 | // Super-tricky - p should point to a []*T where T is a 252 | // message type. We store it as []pointer. 253 | *(*[]pointer)(p.p) = v 254 | } 255 | 256 | // getPointer loads the pointer at p and returns it. 257 | func (p pointer) getPointer() pointer { 258 | return pointer{p: *(*unsafe.Pointer)(p.p)} 259 | } 260 | 261 | // setPointer stores the pointer q at p. 262 | func (p pointer) setPointer(q pointer) { 263 | *(*unsafe.Pointer)(p.p) = q.p 264 | } 265 | 266 | // append q to the slice pointed to by p. 267 | func (p pointer) appendPointer(q pointer) { 268 | s := (*[]unsafe.Pointer)(p.p) 269 | *s = append(*s, q.p) 270 | } 271 | 272 | // getInterfacePointer returns a pointer that points to the 273 | // interface data of the interface pointed by p. 274 | func (p pointer) getInterfacePointer() pointer { 275 | // Super-tricky - read pointer out of data word of interface value. 276 | return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]} 277 | } 278 | 279 | // asPointerTo returns a reflect.Value that is a pointer to an 280 | // object of type t stored at p. 281 | func (p pointer) asPointerTo(t reflect.Type) reflect.Value { 282 | return reflect.NewAt(t, p.p) 283 | } 284 | 285 | func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { 286 | return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) 287 | } 288 | func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { 289 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) 290 | } 291 | func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { 292 | return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) 293 | } 294 | func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { 295 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) 296 | } 297 | func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { 298 | return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) 299 | } 300 | func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { 301 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) 302 | } 303 | func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { 304 | return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) 305 | } 306 | func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { 307 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) 308 | } 309 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/properties.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | /* 35 | * Routines for encoding data into the wire format for protocol buffers. 36 | */ 37 | 38 | import ( 39 | "fmt" 40 | "log" 41 | "os" 42 | "reflect" 43 | "sort" 44 | "strconv" 45 | "strings" 46 | "sync" 47 | ) 48 | 49 | const debug bool = false 50 | 51 | // Constants that identify the encoding of a value on the wire. 52 | const ( 53 | WireVarint = 0 54 | WireFixed64 = 1 55 | WireBytes = 2 56 | WireStartGroup = 3 57 | WireEndGroup = 4 58 | WireFixed32 = 5 59 | ) 60 | 61 | // tagMap is an optimization over map[int]int for typical protocol buffer 62 | // use-cases. Encoded protocol buffers are often in tag order with small tag 63 | // numbers. 64 | type tagMap struct { 65 | fastTags []int 66 | slowTags map[int]int 67 | } 68 | 69 | // tagMapFastLimit is the upper bound on the tag number that will be stored in 70 | // the tagMap slice rather than its map. 71 | const tagMapFastLimit = 1024 72 | 73 | func (p *tagMap) get(t int) (int, bool) { 74 | if t > 0 && t < tagMapFastLimit { 75 | if t >= len(p.fastTags) { 76 | return 0, false 77 | } 78 | fi := p.fastTags[t] 79 | return fi, fi >= 0 80 | } 81 | fi, ok := p.slowTags[t] 82 | return fi, ok 83 | } 84 | 85 | func (p *tagMap) put(t int, fi int) { 86 | if t > 0 && t < tagMapFastLimit { 87 | for len(p.fastTags) < t+1 { 88 | p.fastTags = append(p.fastTags, -1) 89 | } 90 | p.fastTags[t] = fi 91 | return 92 | } 93 | if p.slowTags == nil { 94 | p.slowTags = make(map[int]int) 95 | } 96 | p.slowTags[t] = fi 97 | } 98 | 99 | // StructProperties represents properties for all the fields of a struct. 100 | // decoderTags and decoderOrigNames should only be used by the decoder. 101 | type StructProperties struct { 102 | Prop []*Properties // properties for each field 103 | reqCount int // required count 104 | decoderTags tagMap // map from proto tag to struct field number 105 | decoderOrigNames map[string]int // map from original name to struct field number 106 | order []int // list of struct field numbers in tag order 107 | 108 | // OneofTypes contains information about the oneof fields in this message. 109 | // It is keyed by the original name of a field. 110 | OneofTypes map[string]*OneofProperties 111 | } 112 | 113 | // OneofProperties represents information about a specific field in a oneof. 114 | type OneofProperties struct { 115 | Type reflect.Type // pointer to generated struct type for this oneof field 116 | Field int // struct field number of the containing oneof in the message 117 | Prop *Properties 118 | } 119 | 120 | // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. 121 | // See encode.go, (*Buffer).enc_struct. 122 | 123 | func (sp *StructProperties) Len() int { return len(sp.order) } 124 | func (sp *StructProperties) Less(i, j int) bool { 125 | return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag 126 | } 127 | func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } 128 | 129 | // Properties represents the protocol-specific behavior of a single struct field. 130 | type Properties struct { 131 | Name string // name of the field, for error messages 132 | OrigName string // original name before protocol compiler (always set) 133 | JSONName string // name to use for JSON; determined by protoc 134 | Wire string 135 | WireType int 136 | Tag int 137 | Required bool 138 | Optional bool 139 | Repeated bool 140 | Packed bool // relevant for repeated primitives only 141 | Enum string // set for enum types only 142 | proto3 bool // whether this is known to be a proto3 field 143 | oneof bool // whether this is a oneof field 144 | 145 | Default string // default value 146 | HasDefault bool // whether an explicit default was provided 147 | 148 | stype reflect.Type // set for struct types only 149 | sprop *StructProperties // set for struct types only 150 | 151 | mtype reflect.Type // set for map types only 152 | MapKeyProp *Properties // set for map types only 153 | MapValProp *Properties // set for map types only 154 | } 155 | 156 | // String formats the properties in the protobuf struct field tag style. 157 | func (p *Properties) String() string { 158 | s := p.Wire 159 | s += "," 160 | s += strconv.Itoa(p.Tag) 161 | if p.Required { 162 | s += ",req" 163 | } 164 | if p.Optional { 165 | s += ",opt" 166 | } 167 | if p.Repeated { 168 | s += ",rep" 169 | } 170 | if p.Packed { 171 | s += ",packed" 172 | } 173 | s += ",name=" + p.OrigName 174 | if p.JSONName != p.OrigName { 175 | s += ",json=" + p.JSONName 176 | } 177 | if p.proto3 { 178 | s += ",proto3" 179 | } 180 | if p.oneof { 181 | s += ",oneof" 182 | } 183 | if len(p.Enum) > 0 { 184 | s += ",enum=" + p.Enum 185 | } 186 | if p.HasDefault { 187 | s += ",def=" + p.Default 188 | } 189 | return s 190 | } 191 | 192 | // Parse populates p by parsing a string in the protobuf struct field tag style. 193 | func (p *Properties) Parse(s string) { 194 | // "bytes,49,opt,name=foo,def=hello!" 195 | fields := strings.Split(s, ",") // breaks def=, but handled below. 196 | if len(fields) < 2 { 197 | fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) 198 | return 199 | } 200 | 201 | p.Wire = fields[0] 202 | switch p.Wire { 203 | case "varint": 204 | p.WireType = WireVarint 205 | case "fixed32": 206 | p.WireType = WireFixed32 207 | case "fixed64": 208 | p.WireType = WireFixed64 209 | case "zigzag32": 210 | p.WireType = WireVarint 211 | case "zigzag64": 212 | p.WireType = WireVarint 213 | case "bytes", "group": 214 | p.WireType = WireBytes 215 | // no numeric converter for non-numeric types 216 | default: 217 | fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) 218 | return 219 | } 220 | 221 | var err error 222 | p.Tag, err = strconv.Atoi(fields[1]) 223 | if err != nil { 224 | return 225 | } 226 | 227 | outer: 228 | for i := 2; i < len(fields); i++ { 229 | f := fields[i] 230 | switch { 231 | case f == "req": 232 | p.Required = true 233 | case f == "opt": 234 | p.Optional = true 235 | case f == "rep": 236 | p.Repeated = true 237 | case f == "packed": 238 | p.Packed = true 239 | case strings.HasPrefix(f, "name="): 240 | p.OrigName = f[5:] 241 | case strings.HasPrefix(f, "json="): 242 | p.JSONName = f[5:] 243 | case strings.HasPrefix(f, "enum="): 244 | p.Enum = f[5:] 245 | case f == "proto3": 246 | p.proto3 = true 247 | case f == "oneof": 248 | p.oneof = true 249 | case strings.HasPrefix(f, "def="): 250 | p.HasDefault = true 251 | p.Default = f[4:] // rest of string 252 | if i+1 < len(fields) { 253 | // Commas aren't escaped, and def is always last. 254 | p.Default += "," + strings.Join(fields[i+1:], ",") 255 | break outer 256 | } 257 | } 258 | } 259 | } 260 | 261 | var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() 262 | 263 | // setFieldProps initializes the field properties for submessages and maps. 264 | func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { 265 | switch t1 := typ; t1.Kind() { 266 | case reflect.Ptr: 267 | if t1.Elem().Kind() == reflect.Struct { 268 | p.stype = t1.Elem() 269 | } 270 | 271 | case reflect.Slice: 272 | if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct { 273 | p.stype = t2.Elem() 274 | } 275 | 276 | case reflect.Map: 277 | p.mtype = t1 278 | p.MapKeyProp = &Properties{} 279 | p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) 280 | p.MapValProp = &Properties{} 281 | vtype := p.mtype.Elem() 282 | if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { 283 | // The value type is not a message (*T) or bytes ([]byte), 284 | // so we need encoders for the pointer to this type. 285 | vtype = reflect.PtrTo(vtype) 286 | } 287 | p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) 288 | } 289 | 290 | if p.stype != nil { 291 | if lockGetProp { 292 | p.sprop = GetProperties(p.stype) 293 | } else { 294 | p.sprop = getPropertiesLocked(p.stype) 295 | } 296 | } 297 | } 298 | 299 | var ( 300 | marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() 301 | ) 302 | 303 | // Init populates the properties from a protocol buffer struct tag. 304 | func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { 305 | p.init(typ, name, tag, f, true) 306 | } 307 | 308 | func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { 309 | // "bytes,49,opt,def=hello!" 310 | p.Name = name 311 | p.OrigName = name 312 | if tag == "" { 313 | return 314 | } 315 | p.Parse(tag) 316 | p.setFieldProps(typ, f, lockGetProp) 317 | } 318 | 319 | var ( 320 | propertiesMu sync.RWMutex 321 | propertiesMap = make(map[reflect.Type]*StructProperties) 322 | ) 323 | 324 | // GetProperties returns the list of properties for the type represented by t. 325 | // t must represent a generated struct type of a protocol message. 326 | func GetProperties(t reflect.Type) *StructProperties { 327 | if t.Kind() != reflect.Struct { 328 | panic("proto: type must have kind struct") 329 | } 330 | 331 | // Most calls to GetProperties in a long-running program will be 332 | // retrieving details for types we have seen before. 333 | propertiesMu.RLock() 334 | sprop, ok := propertiesMap[t] 335 | propertiesMu.RUnlock() 336 | if ok { 337 | if collectStats { 338 | stats.Chit++ 339 | } 340 | return sprop 341 | } 342 | 343 | propertiesMu.Lock() 344 | sprop = getPropertiesLocked(t) 345 | propertiesMu.Unlock() 346 | return sprop 347 | } 348 | 349 | // getPropertiesLocked requires that propertiesMu is held. 350 | func getPropertiesLocked(t reflect.Type) *StructProperties { 351 | if prop, ok := propertiesMap[t]; ok { 352 | if collectStats { 353 | stats.Chit++ 354 | } 355 | return prop 356 | } 357 | if collectStats { 358 | stats.Cmiss++ 359 | } 360 | 361 | prop := new(StructProperties) 362 | // in case of recursive protos, fill this in now. 363 | propertiesMap[t] = prop 364 | 365 | // build properties 366 | prop.Prop = make([]*Properties, t.NumField()) 367 | prop.order = make([]int, t.NumField()) 368 | 369 | for i := 0; i < t.NumField(); i++ { 370 | f := t.Field(i) 371 | p := new(Properties) 372 | name := f.Name 373 | p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) 374 | 375 | oneof := f.Tag.Get("protobuf_oneof") // special case 376 | if oneof != "" { 377 | // Oneof fields don't use the traditional protobuf tag. 378 | p.OrigName = oneof 379 | } 380 | prop.Prop[i] = p 381 | prop.order[i] = i 382 | if debug { 383 | print(i, " ", f.Name, " ", t.String(), " ") 384 | if p.Tag > 0 { 385 | print(p.String()) 386 | } 387 | print("\n") 388 | } 389 | } 390 | 391 | // Re-order prop.order. 392 | sort.Sort(prop) 393 | 394 | type oneofMessage interface { 395 | XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) 396 | } 397 | if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { 398 | var oots []interface{} 399 | _, _, _, oots = om.XXX_OneofFuncs() 400 | 401 | // Interpret oneof metadata. 402 | prop.OneofTypes = make(map[string]*OneofProperties) 403 | for _, oot := range oots { 404 | oop := &OneofProperties{ 405 | Type: reflect.ValueOf(oot).Type(), // *T 406 | Prop: new(Properties), 407 | } 408 | sft := oop.Type.Elem().Field(0) 409 | oop.Prop.Name = sft.Name 410 | oop.Prop.Parse(sft.Tag.Get("protobuf")) 411 | // There will be exactly one interface field that 412 | // this new value is assignable to. 413 | for i := 0; i < t.NumField(); i++ { 414 | f := t.Field(i) 415 | if f.Type.Kind() != reflect.Interface { 416 | continue 417 | } 418 | if !oop.Type.AssignableTo(f.Type) { 419 | continue 420 | } 421 | oop.Field = i 422 | break 423 | } 424 | prop.OneofTypes[oop.Prop.OrigName] = oop 425 | } 426 | } 427 | 428 | // build required counts 429 | // build tags 430 | reqCount := 0 431 | prop.decoderOrigNames = make(map[string]int) 432 | for i, p := range prop.Prop { 433 | if strings.HasPrefix(p.Name, "XXX_") { 434 | // Internal fields should not appear in tags/origNames maps. 435 | // They are handled specially when encoding and decoding. 436 | continue 437 | } 438 | if p.Required { 439 | reqCount++ 440 | } 441 | prop.decoderTags.put(p.Tag, i) 442 | prop.decoderOrigNames[p.OrigName] = i 443 | } 444 | prop.reqCount = reqCount 445 | 446 | return prop 447 | } 448 | 449 | // A global registry of enum types. 450 | // The generated code will register the generated maps by calling RegisterEnum. 451 | 452 | var enumValueMaps = make(map[string]map[string]int32) 453 | 454 | // RegisterEnum is called from the generated code to install the enum descriptor 455 | // maps into the global table to aid parsing text format protocol buffers. 456 | func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { 457 | if _, ok := enumValueMaps[typeName]; ok { 458 | panic("proto: duplicate enum registered: " + typeName) 459 | } 460 | enumValueMaps[typeName] = valueMap 461 | } 462 | 463 | // EnumValueMap returns the mapping from names to integers of the 464 | // enum type enumType, or a nil if not found. 465 | func EnumValueMap(enumType string) map[string]int32 { 466 | return enumValueMaps[enumType] 467 | } 468 | 469 | // A registry of all linked message types. 470 | // The string is a fully-qualified proto name ("pkg.Message"). 471 | var ( 472 | protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers 473 | protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types 474 | revProtoTypes = make(map[reflect.Type]string) 475 | ) 476 | 477 | // RegisterType is called from generated code and maps from the fully qualified 478 | // proto name to the type (pointer to struct) of the protocol buffer. 479 | func RegisterType(x Message, name string) { 480 | if _, ok := protoTypedNils[name]; ok { 481 | // TODO: Some day, make this a panic. 482 | log.Printf("proto: duplicate proto type registered: %s", name) 483 | return 484 | } 485 | t := reflect.TypeOf(x) 486 | if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { 487 | // Generated code always calls RegisterType with nil x. 488 | // This check is just for extra safety. 489 | protoTypedNils[name] = x 490 | } else { 491 | protoTypedNils[name] = reflect.Zero(t).Interface().(Message) 492 | } 493 | revProtoTypes[t] = name 494 | } 495 | 496 | // RegisterMapType is called from generated code and maps from the fully qualified 497 | // proto name to the native map type of the proto map definition. 498 | func RegisterMapType(x interface{}, name string) { 499 | if reflect.TypeOf(x).Kind() != reflect.Map { 500 | panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) 501 | } 502 | if _, ok := protoMapTypes[name]; ok { 503 | log.Printf("proto: duplicate proto type registered: %s", name) 504 | return 505 | } 506 | t := reflect.TypeOf(x) 507 | protoMapTypes[name] = t 508 | revProtoTypes[t] = name 509 | } 510 | 511 | // MessageName returns the fully-qualified proto name for the given message type. 512 | func MessageName(x Message) string { 513 | type xname interface { 514 | XXX_MessageName() string 515 | } 516 | if m, ok := x.(xname); ok { 517 | return m.XXX_MessageName() 518 | } 519 | return revProtoTypes[reflect.TypeOf(x)] 520 | } 521 | 522 | // MessageType returns the message type (pointer to struct) for a named message. 523 | // The type is not guaranteed to implement proto.Message if the name refers to a 524 | // map entry. 525 | func MessageType(name string) reflect.Type { 526 | if t, ok := protoTypedNils[name]; ok { 527 | return reflect.TypeOf(t) 528 | } 529 | return protoMapTypes[name] 530 | } 531 | 532 | // A registry of all linked proto files. 533 | var ( 534 | protoFiles = make(map[string][]byte) // file name => fileDescriptor 535 | ) 536 | 537 | // RegisterFile is called from generated code and maps from the 538 | // full file name of a .proto file to its compressed FileDescriptorProto. 539 | func RegisterFile(filename string, fileDescriptor []byte) { 540 | protoFiles[filename] = fileDescriptor 541 | } 542 | 543 | // FileDescriptor returns the compressed FileDescriptorProto for a .proto file. 544 | func FileDescriptor(filename string) []byte { return protoFiles[filename] } 545 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/table_merge.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2016 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | import ( 35 | "fmt" 36 | "reflect" 37 | "strings" 38 | "sync" 39 | "sync/atomic" 40 | ) 41 | 42 | // Merge merges the src message into dst. 43 | // This assumes that dst and src of the same type and are non-nil. 44 | func (a *InternalMessageInfo) Merge(dst, src Message) { 45 | mi := atomicLoadMergeInfo(&a.merge) 46 | if mi == nil { 47 | mi = getMergeInfo(reflect.TypeOf(dst).Elem()) 48 | atomicStoreMergeInfo(&a.merge, mi) 49 | } 50 | mi.merge(toPointer(&dst), toPointer(&src)) 51 | } 52 | 53 | type mergeInfo struct { 54 | typ reflect.Type 55 | 56 | initialized int32 // 0: only typ is valid, 1: everything is valid 57 | lock sync.Mutex 58 | 59 | fields []mergeFieldInfo 60 | unrecognized field // Offset of XXX_unrecognized 61 | } 62 | 63 | type mergeFieldInfo struct { 64 | field field // Offset of field, guaranteed to be valid 65 | 66 | // isPointer reports whether the value in the field is a pointer. 67 | // This is true for the following situations: 68 | // * Pointer to struct 69 | // * Pointer to basic type (proto2 only) 70 | // * Slice (first value in slice header is a pointer) 71 | // * String (first value in string header is a pointer) 72 | isPointer bool 73 | 74 | // basicWidth reports the width of the field assuming that it is directly 75 | // embedded in the struct (as is the case for basic types in proto3). 76 | // The possible values are: 77 | // 0: invalid 78 | // 1: bool 79 | // 4: int32, uint32, float32 80 | // 8: int64, uint64, float64 81 | basicWidth int 82 | 83 | // Where dst and src are pointers to the types being merged. 84 | merge func(dst, src pointer) 85 | } 86 | 87 | var ( 88 | mergeInfoMap = map[reflect.Type]*mergeInfo{} 89 | mergeInfoLock sync.Mutex 90 | ) 91 | 92 | func getMergeInfo(t reflect.Type) *mergeInfo { 93 | mergeInfoLock.Lock() 94 | defer mergeInfoLock.Unlock() 95 | mi := mergeInfoMap[t] 96 | if mi == nil { 97 | mi = &mergeInfo{typ: t} 98 | mergeInfoMap[t] = mi 99 | } 100 | return mi 101 | } 102 | 103 | // merge merges src into dst assuming they are both of type *mi.typ. 104 | func (mi *mergeInfo) merge(dst, src pointer) { 105 | if dst.isNil() { 106 | panic("proto: nil destination") 107 | } 108 | if src.isNil() { 109 | return // Nothing to do. 110 | } 111 | 112 | if atomic.LoadInt32(&mi.initialized) == 0 { 113 | mi.computeMergeInfo() 114 | } 115 | 116 | for _, fi := range mi.fields { 117 | sfp := src.offset(fi.field) 118 | 119 | // As an optimization, we can avoid the merge function call cost 120 | // if we know for sure that the source will have no effect 121 | // by checking if it is the zero value. 122 | if unsafeAllowed { 123 | if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string 124 | continue 125 | } 126 | if fi.basicWidth > 0 { 127 | switch { 128 | case fi.basicWidth == 1 && !*sfp.toBool(): 129 | continue 130 | case fi.basicWidth == 4 && *sfp.toUint32() == 0: 131 | continue 132 | case fi.basicWidth == 8 && *sfp.toUint64() == 0: 133 | continue 134 | } 135 | } 136 | } 137 | 138 | dfp := dst.offset(fi.field) 139 | fi.merge(dfp, sfp) 140 | } 141 | 142 | // TODO: Make this faster? 143 | out := dst.asPointerTo(mi.typ).Elem() 144 | in := src.asPointerTo(mi.typ).Elem() 145 | if emIn, err := extendable(in.Addr().Interface()); err == nil { 146 | emOut, _ := extendable(out.Addr().Interface()) 147 | mIn, muIn := emIn.extensionsRead() 148 | if mIn != nil { 149 | mOut := emOut.extensionsWrite() 150 | muIn.Lock() 151 | mergeExtension(mOut, mIn) 152 | muIn.Unlock() 153 | } 154 | } 155 | 156 | if mi.unrecognized.IsValid() { 157 | if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 { 158 | *dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...) 159 | } 160 | } 161 | } 162 | 163 | func (mi *mergeInfo) computeMergeInfo() { 164 | mi.lock.Lock() 165 | defer mi.lock.Unlock() 166 | if mi.initialized != 0 { 167 | return 168 | } 169 | t := mi.typ 170 | n := t.NumField() 171 | 172 | props := GetProperties(t) 173 | for i := 0; i < n; i++ { 174 | f := t.Field(i) 175 | if strings.HasPrefix(f.Name, "XXX_") { 176 | continue 177 | } 178 | 179 | mfi := mergeFieldInfo{field: toField(&f)} 180 | tf := f.Type 181 | 182 | // As an optimization, we can avoid the merge function call cost 183 | // if we know for sure that the source will have no effect 184 | // by checking if it is the zero value. 185 | if unsafeAllowed { 186 | switch tf.Kind() { 187 | case reflect.Ptr, reflect.Slice, reflect.String: 188 | // As a special case, we assume slices and strings are pointers 189 | // since we know that the first field in the SliceSlice or 190 | // StringHeader is a data pointer. 191 | mfi.isPointer = true 192 | case reflect.Bool: 193 | mfi.basicWidth = 1 194 | case reflect.Int32, reflect.Uint32, reflect.Float32: 195 | mfi.basicWidth = 4 196 | case reflect.Int64, reflect.Uint64, reflect.Float64: 197 | mfi.basicWidth = 8 198 | } 199 | } 200 | 201 | // Unwrap tf to get at its most basic type. 202 | var isPointer, isSlice bool 203 | if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { 204 | isSlice = true 205 | tf = tf.Elem() 206 | } 207 | if tf.Kind() == reflect.Ptr { 208 | isPointer = true 209 | tf = tf.Elem() 210 | } 211 | if isPointer && isSlice && tf.Kind() != reflect.Struct { 212 | panic("both pointer and slice for basic type in " + tf.Name()) 213 | } 214 | 215 | switch tf.Kind() { 216 | case reflect.Int32: 217 | switch { 218 | case isSlice: // E.g., []int32 219 | mfi.merge = func(dst, src pointer) { 220 | // NOTE: toInt32Slice is not defined (see pointer_reflect.go). 221 | /* 222 | sfsp := src.toInt32Slice() 223 | if *sfsp != nil { 224 | dfsp := dst.toInt32Slice() 225 | *dfsp = append(*dfsp, *sfsp...) 226 | if *dfsp == nil { 227 | *dfsp = []int64{} 228 | } 229 | } 230 | */ 231 | sfs := src.getInt32Slice() 232 | if sfs != nil { 233 | dfs := dst.getInt32Slice() 234 | dfs = append(dfs, sfs...) 235 | if dfs == nil { 236 | dfs = []int32{} 237 | } 238 | dst.setInt32Slice(dfs) 239 | } 240 | } 241 | case isPointer: // E.g., *int32 242 | mfi.merge = func(dst, src pointer) { 243 | // NOTE: toInt32Ptr is not defined (see pointer_reflect.go). 244 | /* 245 | sfpp := src.toInt32Ptr() 246 | if *sfpp != nil { 247 | dfpp := dst.toInt32Ptr() 248 | if *dfpp == nil { 249 | *dfpp = Int32(**sfpp) 250 | } else { 251 | **dfpp = **sfpp 252 | } 253 | } 254 | */ 255 | sfp := src.getInt32Ptr() 256 | if sfp != nil { 257 | dfp := dst.getInt32Ptr() 258 | if dfp == nil { 259 | dst.setInt32Ptr(*sfp) 260 | } else { 261 | *dfp = *sfp 262 | } 263 | } 264 | } 265 | default: // E.g., int32 266 | mfi.merge = func(dst, src pointer) { 267 | if v := *src.toInt32(); v != 0 { 268 | *dst.toInt32() = v 269 | } 270 | } 271 | } 272 | case reflect.Int64: 273 | switch { 274 | case isSlice: // E.g., []int64 275 | mfi.merge = func(dst, src pointer) { 276 | sfsp := src.toInt64Slice() 277 | if *sfsp != nil { 278 | dfsp := dst.toInt64Slice() 279 | *dfsp = append(*dfsp, *sfsp...) 280 | if *dfsp == nil { 281 | *dfsp = []int64{} 282 | } 283 | } 284 | } 285 | case isPointer: // E.g., *int64 286 | mfi.merge = func(dst, src pointer) { 287 | sfpp := src.toInt64Ptr() 288 | if *sfpp != nil { 289 | dfpp := dst.toInt64Ptr() 290 | if *dfpp == nil { 291 | *dfpp = Int64(**sfpp) 292 | } else { 293 | **dfpp = **sfpp 294 | } 295 | } 296 | } 297 | default: // E.g., int64 298 | mfi.merge = func(dst, src pointer) { 299 | if v := *src.toInt64(); v != 0 { 300 | *dst.toInt64() = v 301 | } 302 | } 303 | } 304 | case reflect.Uint32: 305 | switch { 306 | case isSlice: // E.g., []uint32 307 | mfi.merge = func(dst, src pointer) { 308 | sfsp := src.toUint32Slice() 309 | if *sfsp != nil { 310 | dfsp := dst.toUint32Slice() 311 | *dfsp = append(*dfsp, *sfsp...) 312 | if *dfsp == nil { 313 | *dfsp = []uint32{} 314 | } 315 | } 316 | } 317 | case isPointer: // E.g., *uint32 318 | mfi.merge = func(dst, src pointer) { 319 | sfpp := src.toUint32Ptr() 320 | if *sfpp != nil { 321 | dfpp := dst.toUint32Ptr() 322 | if *dfpp == nil { 323 | *dfpp = Uint32(**sfpp) 324 | } else { 325 | **dfpp = **sfpp 326 | } 327 | } 328 | } 329 | default: // E.g., uint32 330 | mfi.merge = func(dst, src pointer) { 331 | if v := *src.toUint32(); v != 0 { 332 | *dst.toUint32() = v 333 | } 334 | } 335 | } 336 | case reflect.Uint64: 337 | switch { 338 | case isSlice: // E.g., []uint64 339 | mfi.merge = func(dst, src pointer) { 340 | sfsp := src.toUint64Slice() 341 | if *sfsp != nil { 342 | dfsp := dst.toUint64Slice() 343 | *dfsp = append(*dfsp, *sfsp...) 344 | if *dfsp == nil { 345 | *dfsp = []uint64{} 346 | } 347 | } 348 | } 349 | case isPointer: // E.g., *uint64 350 | mfi.merge = func(dst, src pointer) { 351 | sfpp := src.toUint64Ptr() 352 | if *sfpp != nil { 353 | dfpp := dst.toUint64Ptr() 354 | if *dfpp == nil { 355 | *dfpp = Uint64(**sfpp) 356 | } else { 357 | **dfpp = **sfpp 358 | } 359 | } 360 | } 361 | default: // E.g., uint64 362 | mfi.merge = func(dst, src pointer) { 363 | if v := *src.toUint64(); v != 0 { 364 | *dst.toUint64() = v 365 | } 366 | } 367 | } 368 | case reflect.Float32: 369 | switch { 370 | case isSlice: // E.g., []float32 371 | mfi.merge = func(dst, src pointer) { 372 | sfsp := src.toFloat32Slice() 373 | if *sfsp != nil { 374 | dfsp := dst.toFloat32Slice() 375 | *dfsp = append(*dfsp, *sfsp...) 376 | if *dfsp == nil { 377 | *dfsp = []float32{} 378 | } 379 | } 380 | } 381 | case isPointer: // E.g., *float32 382 | mfi.merge = func(dst, src pointer) { 383 | sfpp := src.toFloat32Ptr() 384 | if *sfpp != nil { 385 | dfpp := dst.toFloat32Ptr() 386 | if *dfpp == nil { 387 | *dfpp = Float32(**sfpp) 388 | } else { 389 | **dfpp = **sfpp 390 | } 391 | } 392 | } 393 | default: // E.g., float32 394 | mfi.merge = func(dst, src pointer) { 395 | if v := *src.toFloat32(); v != 0 { 396 | *dst.toFloat32() = v 397 | } 398 | } 399 | } 400 | case reflect.Float64: 401 | switch { 402 | case isSlice: // E.g., []float64 403 | mfi.merge = func(dst, src pointer) { 404 | sfsp := src.toFloat64Slice() 405 | if *sfsp != nil { 406 | dfsp := dst.toFloat64Slice() 407 | *dfsp = append(*dfsp, *sfsp...) 408 | if *dfsp == nil { 409 | *dfsp = []float64{} 410 | } 411 | } 412 | } 413 | case isPointer: // E.g., *float64 414 | mfi.merge = func(dst, src pointer) { 415 | sfpp := src.toFloat64Ptr() 416 | if *sfpp != nil { 417 | dfpp := dst.toFloat64Ptr() 418 | if *dfpp == nil { 419 | *dfpp = Float64(**sfpp) 420 | } else { 421 | **dfpp = **sfpp 422 | } 423 | } 424 | } 425 | default: // E.g., float64 426 | mfi.merge = func(dst, src pointer) { 427 | if v := *src.toFloat64(); v != 0 { 428 | *dst.toFloat64() = v 429 | } 430 | } 431 | } 432 | case reflect.Bool: 433 | switch { 434 | case isSlice: // E.g., []bool 435 | mfi.merge = func(dst, src pointer) { 436 | sfsp := src.toBoolSlice() 437 | if *sfsp != nil { 438 | dfsp := dst.toBoolSlice() 439 | *dfsp = append(*dfsp, *sfsp...) 440 | if *dfsp == nil { 441 | *dfsp = []bool{} 442 | } 443 | } 444 | } 445 | case isPointer: // E.g., *bool 446 | mfi.merge = func(dst, src pointer) { 447 | sfpp := src.toBoolPtr() 448 | if *sfpp != nil { 449 | dfpp := dst.toBoolPtr() 450 | if *dfpp == nil { 451 | *dfpp = Bool(**sfpp) 452 | } else { 453 | **dfpp = **sfpp 454 | } 455 | } 456 | } 457 | default: // E.g., bool 458 | mfi.merge = func(dst, src pointer) { 459 | if v := *src.toBool(); v { 460 | *dst.toBool() = v 461 | } 462 | } 463 | } 464 | case reflect.String: 465 | switch { 466 | case isSlice: // E.g., []string 467 | mfi.merge = func(dst, src pointer) { 468 | sfsp := src.toStringSlice() 469 | if *sfsp != nil { 470 | dfsp := dst.toStringSlice() 471 | *dfsp = append(*dfsp, *sfsp...) 472 | if *dfsp == nil { 473 | *dfsp = []string{} 474 | } 475 | } 476 | } 477 | case isPointer: // E.g., *string 478 | mfi.merge = func(dst, src pointer) { 479 | sfpp := src.toStringPtr() 480 | if *sfpp != nil { 481 | dfpp := dst.toStringPtr() 482 | if *dfpp == nil { 483 | *dfpp = String(**sfpp) 484 | } else { 485 | **dfpp = **sfpp 486 | } 487 | } 488 | } 489 | default: // E.g., string 490 | mfi.merge = func(dst, src pointer) { 491 | if v := *src.toString(); v != "" { 492 | *dst.toString() = v 493 | } 494 | } 495 | } 496 | case reflect.Slice: 497 | isProto3 := props.Prop[i].proto3 498 | switch { 499 | case isPointer: 500 | panic("bad pointer in byte slice case in " + tf.Name()) 501 | case tf.Elem().Kind() != reflect.Uint8: 502 | panic("bad element kind in byte slice case in " + tf.Name()) 503 | case isSlice: // E.g., [][]byte 504 | mfi.merge = func(dst, src pointer) { 505 | sbsp := src.toBytesSlice() 506 | if *sbsp != nil { 507 | dbsp := dst.toBytesSlice() 508 | for _, sb := range *sbsp { 509 | if sb == nil { 510 | *dbsp = append(*dbsp, nil) 511 | } else { 512 | *dbsp = append(*dbsp, append([]byte{}, sb...)) 513 | } 514 | } 515 | if *dbsp == nil { 516 | *dbsp = [][]byte{} 517 | } 518 | } 519 | } 520 | default: // E.g., []byte 521 | mfi.merge = func(dst, src pointer) { 522 | sbp := src.toBytes() 523 | if *sbp != nil { 524 | dbp := dst.toBytes() 525 | if !isProto3 || len(*sbp) > 0 { 526 | *dbp = append([]byte{}, *sbp...) 527 | } 528 | } 529 | } 530 | } 531 | case reflect.Struct: 532 | switch { 533 | case !isPointer: 534 | panic(fmt.Sprintf("message field %s without pointer", tf)) 535 | case isSlice: // E.g., []*pb.T 536 | mi := getMergeInfo(tf) 537 | mfi.merge = func(dst, src pointer) { 538 | sps := src.getPointerSlice() 539 | if sps != nil { 540 | dps := dst.getPointerSlice() 541 | for _, sp := range sps { 542 | var dp pointer 543 | if !sp.isNil() { 544 | dp = valToPointer(reflect.New(tf)) 545 | mi.merge(dp, sp) 546 | } 547 | dps = append(dps, dp) 548 | } 549 | if dps == nil { 550 | dps = []pointer{} 551 | } 552 | dst.setPointerSlice(dps) 553 | } 554 | } 555 | default: // E.g., *pb.T 556 | mi := getMergeInfo(tf) 557 | mfi.merge = func(dst, src pointer) { 558 | sp := src.getPointer() 559 | if !sp.isNil() { 560 | dp := dst.getPointer() 561 | if dp.isNil() { 562 | dp = valToPointer(reflect.New(tf)) 563 | dst.setPointer(dp) 564 | } 565 | mi.merge(dp, sp) 566 | } 567 | } 568 | } 569 | case reflect.Map: 570 | switch { 571 | case isPointer || isSlice: 572 | panic("bad pointer or slice in map case in " + tf.Name()) 573 | default: // E.g., map[K]V 574 | mfi.merge = func(dst, src pointer) { 575 | sm := src.asPointerTo(tf).Elem() 576 | if sm.Len() == 0 { 577 | return 578 | } 579 | dm := dst.asPointerTo(tf).Elem() 580 | if dm.IsNil() { 581 | dm.Set(reflect.MakeMap(tf)) 582 | } 583 | 584 | switch tf.Elem().Kind() { 585 | case reflect.Ptr: // Proto struct (e.g., *T) 586 | for _, key := range sm.MapKeys() { 587 | val := sm.MapIndex(key) 588 | val = reflect.ValueOf(Clone(val.Interface().(Message))) 589 | dm.SetMapIndex(key, val) 590 | } 591 | case reflect.Slice: // E.g. Bytes type (e.g., []byte) 592 | for _, key := range sm.MapKeys() { 593 | val := sm.MapIndex(key) 594 | val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) 595 | dm.SetMapIndex(key, val) 596 | } 597 | default: // Basic type (e.g., string) 598 | for _, key := range sm.MapKeys() { 599 | val := sm.MapIndex(key) 600 | dm.SetMapIndex(key, val) 601 | } 602 | } 603 | } 604 | } 605 | case reflect.Interface: 606 | // Must be oneof field. 607 | switch { 608 | case isPointer || isSlice: 609 | panic("bad pointer or slice in interface case in " + tf.Name()) 610 | default: // E.g., interface{} 611 | // TODO: Make this faster? 612 | mfi.merge = func(dst, src pointer) { 613 | su := src.asPointerTo(tf).Elem() 614 | if !su.IsNil() { 615 | du := dst.asPointerTo(tf).Elem() 616 | typ := su.Elem().Type() 617 | if du.IsNil() || du.Elem().Type() != typ { 618 | du.Set(reflect.New(typ.Elem())) // Initialize interface if empty 619 | } 620 | sv := su.Elem().Elem().Field(0) 621 | if sv.Kind() == reflect.Ptr && sv.IsNil() { 622 | return 623 | } 624 | dv := du.Elem().Elem().Field(0) 625 | if dv.Kind() == reflect.Ptr && dv.IsNil() { 626 | dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty 627 | } 628 | switch sv.Type().Kind() { 629 | case reflect.Ptr: // Proto struct (e.g., *T) 630 | Merge(dv.Interface().(Message), sv.Interface().(Message)) 631 | case reflect.Slice: // E.g. Bytes type (e.g., []byte) 632 | dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...))) 633 | default: // Basic type (e.g., string) 634 | dv.Set(sv) 635 | } 636 | } 637 | } 638 | } 639 | default: 640 | panic(fmt.Sprintf("merger not found for type:%s", tf)) 641 | } 642 | mi.fields = append(mi.fields, mfi) 643 | } 644 | 645 | mi.unrecognized = invalidField 646 | if f, ok := t.FieldByName("XXX_unrecognized"); ok { 647 | if f.Type != reflect.TypeOf([]byte{}) { 648 | panic("expected XXX_unrecognized to be of type []byte") 649 | } 650 | mi.unrecognized = toField(&f) 651 | } 652 | 653 | atomic.StoreInt32(&mi.initialized, 1) 654 | } 655 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/text.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | // Functions for writing the text protocol buffer format. 35 | 36 | import ( 37 | "bufio" 38 | "bytes" 39 | "encoding" 40 | "errors" 41 | "fmt" 42 | "io" 43 | "log" 44 | "math" 45 | "reflect" 46 | "sort" 47 | "strings" 48 | ) 49 | 50 | var ( 51 | newline = []byte("\n") 52 | spaces = []byte(" ") 53 | endBraceNewline = []byte("}\n") 54 | backslashN = []byte{'\\', 'n'} 55 | backslashR = []byte{'\\', 'r'} 56 | backslashT = []byte{'\\', 't'} 57 | backslashDQ = []byte{'\\', '"'} 58 | backslashBS = []byte{'\\', '\\'} 59 | posInf = []byte("inf") 60 | negInf = []byte("-inf") 61 | nan = []byte("nan") 62 | ) 63 | 64 | type writer interface { 65 | io.Writer 66 | WriteByte(byte) error 67 | } 68 | 69 | // textWriter is an io.Writer that tracks its indentation level. 70 | type textWriter struct { 71 | ind int 72 | complete bool // if the current position is a complete line 73 | compact bool // whether to write out as a one-liner 74 | w writer 75 | } 76 | 77 | func (w *textWriter) WriteString(s string) (n int, err error) { 78 | if !strings.Contains(s, "\n") { 79 | if !w.compact && w.complete { 80 | w.writeIndent() 81 | } 82 | w.complete = false 83 | return io.WriteString(w.w, s) 84 | } 85 | // WriteString is typically called without newlines, so this 86 | // codepath and its copy are rare. We copy to avoid 87 | // duplicating all of Write's logic here. 88 | return w.Write([]byte(s)) 89 | } 90 | 91 | func (w *textWriter) Write(p []byte) (n int, err error) { 92 | newlines := bytes.Count(p, newline) 93 | if newlines == 0 { 94 | if !w.compact && w.complete { 95 | w.writeIndent() 96 | } 97 | n, err = w.w.Write(p) 98 | w.complete = false 99 | return n, err 100 | } 101 | 102 | frags := bytes.SplitN(p, newline, newlines+1) 103 | if w.compact { 104 | for i, frag := range frags { 105 | if i > 0 { 106 | if err := w.w.WriteByte(' '); err != nil { 107 | return n, err 108 | } 109 | n++ 110 | } 111 | nn, err := w.w.Write(frag) 112 | n += nn 113 | if err != nil { 114 | return n, err 115 | } 116 | } 117 | return n, nil 118 | } 119 | 120 | for i, frag := range frags { 121 | if w.complete { 122 | w.writeIndent() 123 | } 124 | nn, err := w.w.Write(frag) 125 | n += nn 126 | if err != nil { 127 | return n, err 128 | } 129 | if i+1 < len(frags) { 130 | if err := w.w.WriteByte('\n'); err != nil { 131 | return n, err 132 | } 133 | n++ 134 | } 135 | } 136 | w.complete = len(frags[len(frags)-1]) == 0 137 | return n, nil 138 | } 139 | 140 | func (w *textWriter) WriteByte(c byte) error { 141 | if w.compact && c == '\n' { 142 | c = ' ' 143 | } 144 | if !w.compact && w.complete { 145 | w.writeIndent() 146 | } 147 | err := w.w.WriteByte(c) 148 | w.complete = c == '\n' 149 | return err 150 | } 151 | 152 | func (w *textWriter) indent() { w.ind++ } 153 | 154 | func (w *textWriter) unindent() { 155 | if w.ind == 0 { 156 | log.Print("proto: textWriter unindented too far") 157 | return 158 | } 159 | w.ind-- 160 | } 161 | 162 | func writeName(w *textWriter, props *Properties) error { 163 | if _, err := w.WriteString(props.OrigName); err != nil { 164 | return err 165 | } 166 | if props.Wire != "group" { 167 | return w.WriteByte(':') 168 | } 169 | return nil 170 | } 171 | 172 | func requiresQuotes(u string) bool { 173 | // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. 174 | for _, ch := range u { 175 | switch { 176 | case ch == '.' || ch == '/' || ch == '_': 177 | continue 178 | case '0' <= ch && ch <= '9': 179 | continue 180 | case 'A' <= ch && ch <= 'Z': 181 | continue 182 | case 'a' <= ch && ch <= 'z': 183 | continue 184 | default: 185 | return true 186 | } 187 | } 188 | return false 189 | } 190 | 191 | // isAny reports whether sv is a google.protobuf.Any message 192 | func isAny(sv reflect.Value) bool { 193 | type wkt interface { 194 | XXX_WellKnownType() string 195 | } 196 | t, ok := sv.Addr().Interface().(wkt) 197 | return ok && t.XXX_WellKnownType() == "Any" 198 | } 199 | 200 | // writeProto3Any writes an expanded google.protobuf.Any message. 201 | // 202 | // It returns (false, nil) if sv value can't be unmarshaled (e.g. because 203 | // required messages are not linked in). 204 | // 205 | // It returns (true, error) when sv was written in expanded format or an error 206 | // was encountered. 207 | func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { 208 | turl := sv.FieldByName("TypeUrl") 209 | val := sv.FieldByName("Value") 210 | if !turl.IsValid() || !val.IsValid() { 211 | return true, errors.New("proto: invalid google.protobuf.Any message") 212 | } 213 | 214 | b, ok := val.Interface().([]byte) 215 | if !ok { 216 | return true, errors.New("proto: invalid google.protobuf.Any message") 217 | } 218 | 219 | parts := strings.Split(turl.String(), "/") 220 | mt := MessageType(parts[len(parts)-1]) 221 | if mt == nil { 222 | return false, nil 223 | } 224 | m := reflect.New(mt.Elem()) 225 | if err := Unmarshal(b, m.Interface().(Message)); err != nil { 226 | return false, nil 227 | } 228 | w.Write([]byte("[")) 229 | u := turl.String() 230 | if requiresQuotes(u) { 231 | writeString(w, u) 232 | } else { 233 | w.Write([]byte(u)) 234 | } 235 | if w.compact { 236 | w.Write([]byte("]:<")) 237 | } else { 238 | w.Write([]byte("]: <\n")) 239 | w.ind++ 240 | } 241 | if err := tm.writeStruct(w, m.Elem()); err != nil { 242 | return true, err 243 | } 244 | if w.compact { 245 | w.Write([]byte("> ")) 246 | } else { 247 | w.ind-- 248 | w.Write([]byte(">\n")) 249 | } 250 | return true, nil 251 | } 252 | 253 | func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { 254 | if tm.ExpandAny && isAny(sv) { 255 | if canExpand, err := tm.writeProto3Any(w, sv); canExpand { 256 | return err 257 | } 258 | } 259 | st := sv.Type() 260 | sprops := GetProperties(st) 261 | for i := 0; i < sv.NumField(); i++ { 262 | fv := sv.Field(i) 263 | props := sprops.Prop[i] 264 | name := st.Field(i).Name 265 | 266 | if name == "XXX_NoUnkeyedLiteral" { 267 | continue 268 | } 269 | 270 | if strings.HasPrefix(name, "XXX_") { 271 | // There are two XXX_ fields: 272 | // XXX_unrecognized []byte 273 | // XXX_extensions map[int32]proto.Extension 274 | // The first is handled here; 275 | // the second is handled at the bottom of this function. 276 | if name == "XXX_unrecognized" && !fv.IsNil() { 277 | if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { 278 | return err 279 | } 280 | } 281 | continue 282 | } 283 | if fv.Kind() == reflect.Ptr && fv.IsNil() { 284 | // Field not filled in. This could be an optional field or 285 | // a required field that wasn't filled in. Either way, there 286 | // isn't anything we can show for it. 287 | continue 288 | } 289 | if fv.Kind() == reflect.Slice && fv.IsNil() { 290 | // Repeated field that is empty, or a bytes field that is unused. 291 | continue 292 | } 293 | 294 | if props.Repeated && fv.Kind() == reflect.Slice { 295 | // Repeated field. 296 | for j := 0; j < fv.Len(); j++ { 297 | if err := writeName(w, props); err != nil { 298 | return err 299 | } 300 | if !w.compact { 301 | if err := w.WriteByte(' '); err != nil { 302 | return err 303 | } 304 | } 305 | v := fv.Index(j) 306 | if v.Kind() == reflect.Ptr && v.IsNil() { 307 | // A nil message in a repeated field is not valid, 308 | // but we can handle that more gracefully than panicking. 309 | if _, err := w.Write([]byte("\n")); err != nil { 310 | return err 311 | } 312 | continue 313 | } 314 | if err := tm.writeAny(w, v, props); err != nil { 315 | return err 316 | } 317 | if err := w.WriteByte('\n'); err != nil { 318 | return err 319 | } 320 | } 321 | continue 322 | } 323 | if fv.Kind() == reflect.Map { 324 | // Map fields are rendered as a repeated struct with key/value fields. 325 | keys := fv.MapKeys() 326 | sort.Sort(mapKeys(keys)) 327 | for _, key := range keys { 328 | val := fv.MapIndex(key) 329 | if err := writeName(w, props); err != nil { 330 | return err 331 | } 332 | if !w.compact { 333 | if err := w.WriteByte(' '); err != nil { 334 | return err 335 | } 336 | } 337 | // open struct 338 | if err := w.WriteByte('<'); err != nil { 339 | return err 340 | } 341 | if !w.compact { 342 | if err := w.WriteByte('\n'); err != nil { 343 | return err 344 | } 345 | } 346 | w.indent() 347 | // key 348 | if _, err := w.WriteString("key:"); err != nil { 349 | return err 350 | } 351 | if !w.compact { 352 | if err := w.WriteByte(' '); err != nil { 353 | return err 354 | } 355 | } 356 | if err := tm.writeAny(w, key, props.MapKeyProp); err != nil { 357 | return err 358 | } 359 | if err := w.WriteByte('\n'); err != nil { 360 | return err 361 | } 362 | // nil values aren't legal, but we can avoid panicking because of them. 363 | if val.Kind() != reflect.Ptr || !val.IsNil() { 364 | // value 365 | if _, err := w.WriteString("value:"); err != nil { 366 | return err 367 | } 368 | if !w.compact { 369 | if err := w.WriteByte(' '); err != nil { 370 | return err 371 | } 372 | } 373 | if err := tm.writeAny(w, val, props.MapValProp); err != nil { 374 | return err 375 | } 376 | if err := w.WriteByte('\n'); err != nil { 377 | return err 378 | } 379 | } 380 | // close struct 381 | w.unindent() 382 | if err := w.WriteByte('>'); err != nil { 383 | return err 384 | } 385 | if err := w.WriteByte('\n'); err != nil { 386 | return err 387 | } 388 | } 389 | continue 390 | } 391 | if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { 392 | // empty bytes field 393 | continue 394 | } 395 | if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { 396 | // proto3 non-repeated scalar field; skip if zero value 397 | if isProto3Zero(fv) { 398 | continue 399 | } 400 | } 401 | 402 | if fv.Kind() == reflect.Interface { 403 | // Check if it is a oneof. 404 | if st.Field(i).Tag.Get("protobuf_oneof") != "" { 405 | // fv is nil, or holds a pointer to generated struct. 406 | // That generated struct has exactly one field, 407 | // which has a protobuf struct tag. 408 | if fv.IsNil() { 409 | continue 410 | } 411 | inner := fv.Elem().Elem() // interface -> *T -> T 412 | tag := inner.Type().Field(0).Tag.Get("protobuf") 413 | props = new(Properties) // Overwrite the outer props var, but not its pointee. 414 | props.Parse(tag) 415 | // Write the value in the oneof, not the oneof itself. 416 | fv = inner.Field(0) 417 | 418 | // Special case to cope with malformed messages gracefully: 419 | // If the value in the oneof is a nil pointer, don't panic 420 | // in writeAny. 421 | if fv.Kind() == reflect.Ptr && fv.IsNil() { 422 | // Use errors.New so writeAny won't render quotes. 423 | msg := errors.New("/* nil */") 424 | fv = reflect.ValueOf(&msg).Elem() 425 | } 426 | } 427 | } 428 | 429 | if err := writeName(w, props); err != nil { 430 | return err 431 | } 432 | if !w.compact { 433 | if err := w.WriteByte(' '); err != nil { 434 | return err 435 | } 436 | } 437 | 438 | // Enums have a String method, so writeAny will work fine. 439 | if err := tm.writeAny(w, fv, props); err != nil { 440 | return err 441 | } 442 | 443 | if err := w.WriteByte('\n'); err != nil { 444 | return err 445 | } 446 | } 447 | 448 | // Extensions (the XXX_extensions field). 449 | pv := sv.Addr() 450 | if _, err := extendable(pv.Interface()); err == nil { 451 | if err := tm.writeExtensions(w, pv); err != nil { 452 | return err 453 | } 454 | } 455 | 456 | return nil 457 | } 458 | 459 | // writeAny writes an arbitrary field. 460 | func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { 461 | v = reflect.Indirect(v) 462 | 463 | // Floats have special cases. 464 | if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { 465 | x := v.Float() 466 | var b []byte 467 | switch { 468 | case math.IsInf(x, 1): 469 | b = posInf 470 | case math.IsInf(x, -1): 471 | b = negInf 472 | case math.IsNaN(x): 473 | b = nan 474 | } 475 | if b != nil { 476 | _, err := w.Write(b) 477 | return err 478 | } 479 | // Other values are handled below. 480 | } 481 | 482 | // We don't attempt to serialise every possible value type; only those 483 | // that can occur in protocol buffers. 484 | switch v.Kind() { 485 | case reflect.Slice: 486 | // Should only be a []byte; repeated fields are handled in writeStruct. 487 | if err := writeString(w, string(v.Bytes())); err != nil { 488 | return err 489 | } 490 | case reflect.String: 491 | if err := writeString(w, v.String()); err != nil { 492 | return err 493 | } 494 | case reflect.Struct: 495 | // Required/optional group/message. 496 | var bra, ket byte = '<', '>' 497 | if props != nil && props.Wire == "group" { 498 | bra, ket = '{', '}' 499 | } 500 | if err := w.WriteByte(bra); err != nil { 501 | return err 502 | } 503 | if !w.compact { 504 | if err := w.WriteByte('\n'); err != nil { 505 | return err 506 | } 507 | } 508 | w.indent() 509 | if v.CanAddr() { 510 | // Calling v.Interface on a struct causes the reflect package to 511 | // copy the entire struct. This is racy with the new Marshaler 512 | // since we atomically update the XXX_sizecache. 513 | // 514 | // Thus, we retrieve a pointer to the struct if possible to avoid 515 | // a race since v.Interface on the pointer doesn't copy the struct. 516 | // 517 | // If v is not addressable, then we are not worried about a race 518 | // since it implies that the binary Marshaler cannot possibly be 519 | // mutating this value. 520 | v = v.Addr() 521 | } 522 | if etm, ok := v.Interface().(encoding.TextMarshaler); ok { 523 | text, err := etm.MarshalText() 524 | if err != nil { 525 | return err 526 | } 527 | if _, err = w.Write(text); err != nil { 528 | return err 529 | } 530 | } else { 531 | if v.Kind() == reflect.Ptr { 532 | v = v.Elem() 533 | } 534 | if err := tm.writeStruct(w, v); err != nil { 535 | return err 536 | } 537 | } 538 | w.unindent() 539 | if err := w.WriteByte(ket); err != nil { 540 | return err 541 | } 542 | default: 543 | _, err := fmt.Fprint(w, v.Interface()) 544 | return err 545 | } 546 | return nil 547 | } 548 | 549 | // equivalent to C's isprint. 550 | func isprint(c byte) bool { 551 | return c >= 0x20 && c < 0x7f 552 | } 553 | 554 | // writeString writes a string in the protocol buffer text format. 555 | // It is similar to strconv.Quote except we don't use Go escape sequences, 556 | // we treat the string as a byte sequence, and we use octal escapes. 557 | // These differences are to maintain interoperability with the other 558 | // languages' implementations of the text format. 559 | func writeString(w *textWriter, s string) error { 560 | // use WriteByte here to get any needed indent 561 | if err := w.WriteByte('"'); err != nil { 562 | return err 563 | } 564 | // Loop over the bytes, not the runes. 565 | for i := 0; i < len(s); i++ { 566 | var err error 567 | // Divergence from C++: we don't escape apostrophes. 568 | // There's no need to escape them, and the C++ parser 569 | // copes with a naked apostrophe. 570 | switch c := s[i]; c { 571 | case '\n': 572 | _, err = w.w.Write(backslashN) 573 | case '\r': 574 | _, err = w.w.Write(backslashR) 575 | case '\t': 576 | _, err = w.w.Write(backslashT) 577 | case '"': 578 | _, err = w.w.Write(backslashDQ) 579 | case '\\': 580 | _, err = w.w.Write(backslashBS) 581 | default: 582 | if isprint(c) { 583 | err = w.w.WriteByte(c) 584 | } else { 585 | _, err = fmt.Fprintf(w.w, "\\%03o", c) 586 | } 587 | } 588 | if err != nil { 589 | return err 590 | } 591 | } 592 | return w.WriteByte('"') 593 | } 594 | 595 | func writeUnknownStruct(w *textWriter, data []byte) (err error) { 596 | if !w.compact { 597 | if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { 598 | return err 599 | } 600 | } 601 | b := NewBuffer(data) 602 | for b.index < len(b.buf) { 603 | x, err := b.DecodeVarint() 604 | if err != nil { 605 | _, err := fmt.Fprintf(w, "/* %v */\n", err) 606 | return err 607 | } 608 | wire, tag := x&7, x>>3 609 | if wire == WireEndGroup { 610 | w.unindent() 611 | if _, err := w.Write(endBraceNewline); err != nil { 612 | return err 613 | } 614 | continue 615 | } 616 | if _, err := fmt.Fprint(w, tag); err != nil { 617 | return err 618 | } 619 | if wire != WireStartGroup { 620 | if err := w.WriteByte(':'); err != nil { 621 | return err 622 | } 623 | } 624 | if !w.compact || wire == WireStartGroup { 625 | if err := w.WriteByte(' '); err != nil { 626 | return err 627 | } 628 | } 629 | switch wire { 630 | case WireBytes: 631 | buf, e := b.DecodeRawBytes(false) 632 | if e == nil { 633 | _, err = fmt.Fprintf(w, "%q", buf) 634 | } else { 635 | _, err = fmt.Fprintf(w, "/* %v */", e) 636 | } 637 | case WireFixed32: 638 | x, err = b.DecodeFixed32() 639 | err = writeUnknownInt(w, x, err) 640 | case WireFixed64: 641 | x, err = b.DecodeFixed64() 642 | err = writeUnknownInt(w, x, err) 643 | case WireStartGroup: 644 | err = w.WriteByte('{') 645 | w.indent() 646 | case WireVarint: 647 | x, err = b.DecodeVarint() 648 | err = writeUnknownInt(w, x, err) 649 | default: 650 | _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) 651 | } 652 | if err != nil { 653 | return err 654 | } 655 | if err = w.WriteByte('\n'); err != nil { 656 | return err 657 | } 658 | } 659 | return nil 660 | } 661 | 662 | func writeUnknownInt(w *textWriter, x uint64, err error) error { 663 | if err == nil { 664 | _, err = fmt.Fprint(w, x) 665 | } else { 666 | _, err = fmt.Fprintf(w, "/* %v */", err) 667 | } 668 | return err 669 | } 670 | 671 | type int32Slice []int32 672 | 673 | func (s int32Slice) Len() int { return len(s) } 674 | func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } 675 | func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 676 | 677 | // writeExtensions writes all the extensions in pv. 678 | // pv is assumed to be a pointer to a protocol message struct that is extendable. 679 | func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { 680 | emap := extensionMaps[pv.Type().Elem()] 681 | ep, _ := extendable(pv.Interface()) 682 | 683 | // Order the extensions by ID. 684 | // This isn't strictly necessary, but it will give us 685 | // canonical output, which will also make testing easier. 686 | m, mu := ep.extensionsRead() 687 | if m == nil { 688 | return nil 689 | } 690 | mu.Lock() 691 | ids := make([]int32, 0, len(m)) 692 | for id := range m { 693 | ids = append(ids, id) 694 | } 695 | sort.Sort(int32Slice(ids)) 696 | mu.Unlock() 697 | 698 | for _, extNum := range ids { 699 | ext := m[extNum] 700 | var desc *ExtensionDesc 701 | if emap != nil { 702 | desc = emap[extNum] 703 | } 704 | if desc == nil { 705 | // Unknown extension. 706 | if err := writeUnknownStruct(w, ext.enc); err != nil { 707 | return err 708 | } 709 | continue 710 | } 711 | 712 | pb, err := GetExtension(ep, desc) 713 | if err != nil { 714 | return fmt.Errorf("failed getting extension: %v", err) 715 | } 716 | 717 | // Repeated extensions will appear as a slice. 718 | if !desc.repeated() { 719 | if err := tm.writeExtension(w, desc.Name, pb); err != nil { 720 | return err 721 | } 722 | } else { 723 | v := reflect.ValueOf(pb) 724 | for i := 0; i < v.Len(); i++ { 725 | if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { 726 | return err 727 | } 728 | } 729 | } 730 | } 731 | return nil 732 | } 733 | 734 | func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { 735 | if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { 736 | return err 737 | } 738 | if !w.compact { 739 | if err := w.WriteByte(' '); err != nil { 740 | return err 741 | } 742 | } 743 | if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { 744 | return err 745 | } 746 | if err := w.WriteByte('\n'); err != nil { 747 | return err 748 | } 749 | return nil 750 | } 751 | 752 | func (w *textWriter) writeIndent() { 753 | if !w.complete { 754 | return 755 | } 756 | remain := w.ind * 2 757 | for remain > 0 { 758 | n := remain 759 | if n > len(spaces) { 760 | n = len(spaces) 761 | } 762 | w.w.Write(spaces[:n]) 763 | remain -= n 764 | } 765 | w.complete = false 766 | } 767 | 768 | // TextMarshaler is a configurable text format marshaler. 769 | type TextMarshaler struct { 770 | Compact bool // use compact text format (one line). 771 | ExpandAny bool // expand google.protobuf.Any messages of known types 772 | } 773 | 774 | // Marshal writes a given protocol buffer in text format. 775 | // The only errors returned are from w. 776 | func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { 777 | val := reflect.ValueOf(pb) 778 | if pb == nil || val.IsNil() { 779 | w.Write([]byte("")) 780 | return nil 781 | } 782 | var bw *bufio.Writer 783 | ww, ok := w.(writer) 784 | if !ok { 785 | bw = bufio.NewWriter(w) 786 | ww = bw 787 | } 788 | aw := &textWriter{ 789 | w: ww, 790 | complete: true, 791 | compact: tm.Compact, 792 | } 793 | 794 | if etm, ok := pb.(encoding.TextMarshaler); ok { 795 | text, err := etm.MarshalText() 796 | if err != nil { 797 | return err 798 | } 799 | if _, err = aw.Write(text); err != nil { 800 | return err 801 | } 802 | if bw != nil { 803 | return bw.Flush() 804 | } 805 | return nil 806 | } 807 | // Dereference the received pointer so we don't have outer < and >. 808 | v := reflect.Indirect(val) 809 | if err := tm.writeStruct(aw, v); err != nil { 810 | return err 811 | } 812 | if bw != nil { 813 | return bw.Flush() 814 | } 815 | return nil 816 | } 817 | 818 | // Text is the same as Marshal, but returns the string directly. 819 | func (tm *TextMarshaler) Text(pb Message) string { 820 | var buf bytes.Buffer 821 | tm.Marshal(&buf, pb) 822 | return buf.String() 823 | } 824 | 825 | var ( 826 | defaultTextMarshaler = TextMarshaler{} 827 | compactTextMarshaler = TextMarshaler{Compact: true} 828 | ) 829 | 830 | // TODO: consider removing some of the Marshal functions below. 831 | 832 | // MarshalText writes a given protocol buffer in text format. 833 | // The only errors returned are from w. 834 | func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } 835 | 836 | // MarshalTextString is the same as MarshalText, but returns the string directly. 837 | func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } 838 | 839 | // CompactText writes a given protocol buffer in compact text format (one line). 840 | func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } 841 | 842 | // CompactTextString is the same as CompactText, but returns the string directly. 843 | func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } 844 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/github.com/golang/protobuf/proto/text_parser.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | // Functions for parsing the Text protocol buffer format. 35 | // TODO: message sets. 36 | 37 | import ( 38 | "encoding" 39 | "errors" 40 | "fmt" 41 | "reflect" 42 | "strconv" 43 | "strings" 44 | "unicode/utf8" 45 | ) 46 | 47 | // Error string emitted when deserializing Any and fields are already set 48 | const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" 49 | 50 | type ParseError struct { 51 | Message string 52 | Line int // 1-based line number 53 | Offset int // 0-based byte offset from start of input 54 | } 55 | 56 | func (p *ParseError) Error() string { 57 | if p.Line == 1 { 58 | // show offset only for first line 59 | return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) 60 | } 61 | return fmt.Sprintf("line %d: %v", p.Line, p.Message) 62 | } 63 | 64 | type token struct { 65 | value string 66 | err *ParseError 67 | line int // line number 68 | offset int // byte number from start of input, not start of line 69 | unquoted string // the unquoted version of value, if it was a quoted string 70 | } 71 | 72 | func (t *token) String() string { 73 | if t.err == nil { 74 | return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) 75 | } 76 | return fmt.Sprintf("parse error: %v", t.err) 77 | } 78 | 79 | type textParser struct { 80 | s string // remaining input 81 | done bool // whether the parsing is finished (success or error) 82 | backed bool // whether back() was called 83 | offset, line int 84 | cur token 85 | } 86 | 87 | func newTextParser(s string) *textParser { 88 | p := new(textParser) 89 | p.s = s 90 | p.line = 1 91 | p.cur.line = 1 92 | return p 93 | } 94 | 95 | func (p *textParser) errorf(format string, a ...interface{}) *ParseError { 96 | pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} 97 | p.cur.err = pe 98 | p.done = true 99 | return pe 100 | } 101 | 102 | // Numbers and identifiers are matched by [-+._A-Za-z0-9] 103 | func isIdentOrNumberChar(c byte) bool { 104 | switch { 105 | case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': 106 | return true 107 | case '0' <= c && c <= '9': 108 | return true 109 | } 110 | switch c { 111 | case '-', '+', '.', '_': 112 | return true 113 | } 114 | return false 115 | } 116 | 117 | func isWhitespace(c byte) bool { 118 | switch c { 119 | case ' ', '\t', '\n', '\r': 120 | return true 121 | } 122 | return false 123 | } 124 | 125 | func isQuote(c byte) bool { 126 | switch c { 127 | case '"', '\'': 128 | return true 129 | } 130 | return false 131 | } 132 | 133 | func (p *textParser) skipWhitespace() { 134 | i := 0 135 | for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { 136 | if p.s[i] == '#' { 137 | // comment; skip to end of line or input 138 | for i < len(p.s) && p.s[i] != '\n' { 139 | i++ 140 | } 141 | if i == len(p.s) { 142 | break 143 | } 144 | } 145 | if p.s[i] == '\n' { 146 | p.line++ 147 | } 148 | i++ 149 | } 150 | p.offset += i 151 | p.s = p.s[i:len(p.s)] 152 | if len(p.s) == 0 { 153 | p.done = true 154 | } 155 | } 156 | 157 | func (p *textParser) advance() { 158 | // Skip whitespace 159 | p.skipWhitespace() 160 | if p.done { 161 | return 162 | } 163 | 164 | // Start of non-whitespace 165 | p.cur.err = nil 166 | p.cur.offset, p.cur.line = p.offset, p.line 167 | p.cur.unquoted = "" 168 | switch p.s[0] { 169 | case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': 170 | // Single symbol 171 | p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] 172 | case '"', '\'': 173 | // Quoted string 174 | i := 1 175 | for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { 176 | if p.s[i] == '\\' && i+1 < len(p.s) { 177 | // skip escaped char 178 | i++ 179 | } 180 | i++ 181 | } 182 | if i >= len(p.s) || p.s[i] != p.s[0] { 183 | p.errorf("unmatched quote") 184 | return 185 | } 186 | unq, err := unquoteC(p.s[1:i], rune(p.s[0])) 187 | if err != nil { 188 | p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) 189 | return 190 | } 191 | p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] 192 | p.cur.unquoted = unq 193 | default: 194 | i := 0 195 | for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { 196 | i++ 197 | } 198 | if i == 0 { 199 | p.errorf("unexpected byte %#x", p.s[0]) 200 | return 201 | } 202 | p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] 203 | } 204 | p.offset += len(p.cur.value) 205 | } 206 | 207 | var ( 208 | errBadUTF8 = errors.New("proto: bad UTF-8") 209 | ) 210 | 211 | func unquoteC(s string, quote rune) (string, error) { 212 | // This is based on C++'s tokenizer.cc. 213 | // Despite its name, this is *not* parsing C syntax. 214 | // For instance, "\0" is an invalid quoted string. 215 | 216 | // Avoid allocation in trivial cases. 217 | simple := true 218 | for _, r := range s { 219 | if r == '\\' || r == quote { 220 | simple = false 221 | break 222 | } 223 | } 224 | if simple { 225 | return s, nil 226 | } 227 | 228 | buf := make([]byte, 0, 3*len(s)/2) 229 | for len(s) > 0 { 230 | r, n := utf8.DecodeRuneInString(s) 231 | if r == utf8.RuneError && n == 1 { 232 | return "", errBadUTF8 233 | } 234 | s = s[n:] 235 | if r != '\\' { 236 | if r < utf8.RuneSelf { 237 | buf = append(buf, byte(r)) 238 | } else { 239 | buf = append(buf, string(r)...) 240 | } 241 | continue 242 | } 243 | 244 | ch, tail, err := unescape(s) 245 | if err != nil { 246 | return "", err 247 | } 248 | buf = append(buf, ch...) 249 | s = tail 250 | } 251 | return string(buf), nil 252 | } 253 | 254 | func unescape(s string) (ch string, tail string, err error) { 255 | r, n := utf8.DecodeRuneInString(s) 256 | if r == utf8.RuneError && n == 1 { 257 | return "", "", errBadUTF8 258 | } 259 | s = s[n:] 260 | switch r { 261 | case 'a': 262 | return "\a", s, nil 263 | case 'b': 264 | return "\b", s, nil 265 | case 'f': 266 | return "\f", s, nil 267 | case 'n': 268 | return "\n", s, nil 269 | case 'r': 270 | return "\r", s, nil 271 | case 't': 272 | return "\t", s, nil 273 | case 'v': 274 | return "\v", s, nil 275 | case '?': 276 | return "?", s, nil // trigraph workaround 277 | case '\'', '"', '\\': 278 | return string(r), s, nil 279 | case '0', '1', '2', '3', '4', '5', '6', '7': 280 | if len(s) < 2 { 281 | return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) 282 | } 283 | ss := string(r) + s[:2] 284 | s = s[2:] 285 | i, err := strconv.ParseUint(ss, 8, 8) 286 | if err != nil { 287 | return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) 288 | } 289 | return string([]byte{byte(i)}), s, nil 290 | case 'x', 'X', 'u', 'U': 291 | var n int 292 | switch r { 293 | case 'x', 'X': 294 | n = 2 295 | case 'u': 296 | n = 4 297 | case 'U': 298 | n = 8 299 | } 300 | if len(s) < n { 301 | return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) 302 | } 303 | ss := s[:n] 304 | s = s[n:] 305 | i, err := strconv.ParseUint(ss, 16, 64) 306 | if err != nil { 307 | return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) 308 | } 309 | if r == 'x' || r == 'X' { 310 | return string([]byte{byte(i)}), s, nil 311 | } 312 | if i > utf8.MaxRune { 313 | return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) 314 | } 315 | return string(i), s, nil 316 | } 317 | return "", "", fmt.Errorf(`unknown escape \%c`, r) 318 | } 319 | 320 | // Back off the parser by one token. Can only be done between calls to next(). 321 | // It makes the next advance() a no-op. 322 | func (p *textParser) back() { p.backed = true } 323 | 324 | // Advances the parser and returns the new current token. 325 | func (p *textParser) next() *token { 326 | if p.backed || p.done { 327 | p.backed = false 328 | return &p.cur 329 | } 330 | p.advance() 331 | if p.done { 332 | p.cur.value = "" 333 | } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { 334 | // Look for multiple quoted strings separated by whitespace, 335 | // and concatenate them. 336 | cat := p.cur 337 | for { 338 | p.skipWhitespace() 339 | if p.done || !isQuote(p.s[0]) { 340 | break 341 | } 342 | p.advance() 343 | if p.cur.err != nil { 344 | return &p.cur 345 | } 346 | cat.value += " " + p.cur.value 347 | cat.unquoted += p.cur.unquoted 348 | } 349 | p.done = false // parser may have seen EOF, but we want to return cat 350 | p.cur = cat 351 | } 352 | return &p.cur 353 | } 354 | 355 | func (p *textParser) consumeToken(s string) error { 356 | tok := p.next() 357 | if tok.err != nil { 358 | return tok.err 359 | } 360 | if tok.value != s { 361 | p.back() 362 | return p.errorf("expected %q, found %q", s, tok.value) 363 | } 364 | return nil 365 | } 366 | 367 | // Return a RequiredNotSetError indicating which required field was not set. 368 | func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { 369 | st := sv.Type() 370 | sprops := GetProperties(st) 371 | for i := 0; i < st.NumField(); i++ { 372 | if !isNil(sv.Field(i)) { 373 | continue 374 | } 375 | 376 | props := sprops.Prop[i] 377 | if props.Required { 378 | return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} 379 | } 380 | } 381 | return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen 382 | } 383 | 384 | // Returns the index in the struct for the named field, as well as the parsed tag properties. 385 | func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { 386 | i, ok := sprops.decoderOrigNames[name] 387 | if ok { 388 | return i, sprops.Prop[i], true 389 | } 390 | return -1, nil, false 391 | } 392 | 393 | // Consume a ':' from the input stream (if the next token is a colon), 394 | // returning an error if a colon is needed but not present. 395 | func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { 396 | tok := p.next() 397 | if tok.err != nil { 398 | return tok.err 399 | } 400 | if tok.value != ":" { 401 | // Colon is optional when the field is a group or message. 402 | needColon := true 403 | switch props.Wire { 404 | case "group": 405 | needColon = false 406 | case "bytes": 407 | // A "bytes" field is either a message, a string, or a repeated field; 408 | // those three become *T, *string and []T respectively, so we can check for 409 | // this field being a pointer to a non-string. 410 | if typ.Kind() == reflect.Ptr { 411 | // *T or *string 412 | if typ.Elem().Kind() == reflect.String { 413 | break 414 | } 415 | } else if typ.Kind() == reflect.Slice { 416 | // []T or []*T 417 | if typ.Elem().Kind() != reflect.Ptr { 418 | break 419 | } 420 | } else if typ.Kind() == reflect.String { 421 | // The proto3 exception is for a string field, 422 | // which requires a colon. 423 | break 424 | } 425 | needColon = false 426 | } 427 | if needColon { 428 | return p.errorf("expected ':', found %q", tok.value) 429 | } 430 | p.back() 431 | } 432 | return nil 433 | } 434 | 435 | func (p *textParser) readStruct(sv reflect.Value, terminator string) error { 436 | st := sv.Type() 437 | sprops := GetProperties(st) 438 | reqCount := sprops.reqCount 439 | var reqFieldErr error 440 | fieldSet := make(map[string]bool) 441 | // A struct is a sequence of "name: value", terminated by one of 442 | // '>' or '}', or the end of the input. A name may also be 443 | // "[extension]" or "[type/url]". 444 | // 445 | // The whole struct can also be an expanded Any message, like: 446 | // [type/url] < ... struct contents ... > 447 | for { 448 | tok := p.next() 449 | if tok.err != nil { 450 | return tok.err 451 | } 452 | if tok.value == terminator { 453 | break 454 | } 455 | if tok.value == "[" { 456 | // Looks like an extension or an Any. 457 | // 458 | // TODO: Check whether we need to handle 459 | // namespace rooted names (e.g. ".something.Foo"). 460 | extName, err := p.consumeExtName() 461 | if err != nil { 462 | return err 463 | } 464 | 465 | if s := strings.LastIndex(extName, "/"); s >= 0 { 466 | // If it contains a slash, it's an Any type URL. 467 | messageName := extName[s+1:] 468 | mt := MessageType(messageName) 469 | if mt == nil { 470 | return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) 471 | } 472 | tok = p.next() 473 | if tok.err != nil { 474 | return tok.err 475 | } 476 | // consume an optional colon 477 | if tok.value == ":" { 478 | tok = p.next() 479 | if tok.err != nil { 480 | return tok.err 481 | } 482 | } 483 | var terminator string 484 | switch tok.value { 485 | case "<": 486 | terminator = ">" 487 | case "{": 488 | terminator = "}" 489 | default: 490 | return p.errorf("expected '{' or '<', found %q", tok.value) 491 | } 492 | v := reflect.New(mt.Elem()) 493 | if pe := p.readStruct(v.Elem(), terminator); pe != nil { 494 | return pe 495 | } 496 | b, err := Marshal(v.Interface().(Message)) 497 | if err != nil { 498 | return p.errorf("failed to marshal message of type %q: %v", messageName, err) 499 | } 500 | if fieldSet["type_url"] { 501 | return p.errorf(anyRepeatedlyUnpacked, "type_url") 502 | } 503 | if fieldSet["value"] { 504 | return p.errorf(anyRepeatedlyUnpacked, "value") 505 | } 506 | sv.FieldByName("TypeUrl").SetString(extName) 507 | sv.FieldByName("Value").SetBytes(b) 508 | fieldSet["type_url"] = true 509 | fieldSet["value"] = true 510 | continue 511 | } 512 | 513 | var desc *ExtensionDesc 514 | // This could be faster, but it's functional. 515 | // TODO: Do something smarter than a linear scan. 516 | for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { 517 | if d.Name == extName { 518 | desc = d 519 | break 520 | } 521 | } 522 | if desc == nil { 523 | return p.errorf("unrecognized extension %q", extName) 524 | } 525 | 526 | props := &Properties{} 527 | props.Parse(desc.Tag) 528 | 529 | typ := reflect.TypeOf(desc.ExtensionType) 530 | if err := p.checkForColon(props, typ); err != nil { 531 | return err 532 | } 533 | 534 | rep := desc.repeated() 535 | 536 | // Read the extension structure, and set it in 537 | // the value we're constructing. 538 | var ext reflect.Value 539 | if !rep { 540 | ext = reflect.New(typ).Elem() 541 | } else { 542 | ext = reflect.New(typ.Elem()).Elem() 543 | } 544 | if err := p.readAny(ext, props); err != nil { 545 | if _, ok := err.(*RequiredNotSetError); !ok { 546 | return err 547 | } 548 | reqFieldErr = err 549 | } 550 | ep := sv.Addr().Interface().(Message) 551 | if !rep { 552 | SetExtension(ep, desc, ext.Interface()) 553 | } else { 554 | old, err := GetExtension(ep, desc) 555 | var sl reflect.Value 556 | if err == nil { 557 | sl = reflect.ValueOf(old) // existing slice 558 | } else { 559 | sl = reflect.MakeSlice(typ, 0, 1) 560 | } 561 | sl = reflect.Append(sl, ext) 562 | SetExtension(ep, desc, sl.Interface()) 563 | } 564 | if err := p.consumeOptionalSeparator(); err != nil { 565 | return err 566 | } 567 | continue 568 | } 569 | 570 | // This is a normal, non-extension field. 571 | name := tok.value 572 | var dst reflect.Value 573 | fi, props, ok := structFieldByName(sprops, name) 574 | if ok { 575 | dst = sv.Field(fi) 576 | } else if oop, ok := sprops.OneofTypes[name]; ok { 577 | // It is a oneof. 578 | props = oop.Prop 579 | nv := reflect.New(oop.Type.Elem()) 580 | dst = nv.Elem().Field(0) 581 | field := sv.Field(oop.Field) 582 | if !field.IsNil() { 583 | return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) 584 | } 585 | field.Set(nv) 586 | } 587 | if !dst.IsValid() { 588 | return p.errorf("unknown field name %q in %v", name, st) 589 | } 590 | 591 | if dst.Kind() == reflect.Map { 592 | // Consume any colon. 593 | if err := p.checkForColon(props, dst.Type()); err != nil { 594 | return err 595 | } 596 | 597 | // Construct the map if it doesn't already exist. 598 | if dst.IsNil() { 599 | dst.Set(reflect.MakeMap(dst.Type())) 600 | } 601 | key := reflect.New(dst.Type().Key()).Elem() 602 | val := reflect.New(dst.Type().Elem()).Elem() 603 | 604 | // The map entry should be this sequence of tokens: 605 | // < key : KEY value : VALUE > 606 | // However, implementations may omit key or value, and technically 607 | // we should support them in any order. See b/28924776 for a time 608 | // this went wrong. 609 | 610 | tok := p.next() 611 | var terminator string 612 | switch tok.value { 613 | case "<": 614 | terminator = ">" 615 | case "{": 616 | terminator = "}" 617 | default: 618 | return p.errorf("expected '{' or '<', found %q", tok.value) 619 | } 620 | for { 621 | tok := p.next() 622 | if tok.err != nil { 623 | return tok.err 624 | } 625 | if tok.value == terminator { 626 | break 627 | } 628 | switch tok.value { 629 | case "key": 630 | if err := p.consumeToken(":"); err != nil { 631 | return err 632 | } 633 | if err := p.readAny(key, props.MapKeyProp); err != nil { 634 | return err 635 | } 636 | if err := p.consumeOptionalSeparator(); err != nil { 637 | return err 638 | } 639 | case "value": 640 | if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil { 641 | return err 642 | } 643 | if err := p.readAny(val, props.MapValProp); err != nil { 644 | return err 645 | } 646 | if err := p.consumeOptionalSeparator(); err != nil { 647 | return err 648 | } 649 | default: 650 | p.back() 651 | return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) 652 | } 653 | } 654 | 655 | dst.SetMapIndex(key, val) 656 | continue 657 | } 658 | 659 | // Check that it's not already set if it's not a repeated field. 660 | if !props.Repeated && fieldSet[name] { 661 | return p.errorf("non-repeated field %q was repeated", name) 662 | } 663 | 664 | if err := p.checkForColon(props, dst.Type()); err != nil { 665 | return err 666 | } 667 | 668 | // Parse into the field. 669 | fieldSet[name] = true 670 | if err := p.readAny(dst, props); err != nil { 671 | if _, ok := err.(*RequiredNotSetError); !ok { 672 | return err 673 | } 674 | reqFieldErr = err 675 | } 676 | if props.Required { 677 | reqCount-- 678 | } 679 | 680 | if err := p.consumeOptionalSeparator(); err != nil { 681 | return err 682 | } 683 | 684 | } 685 | 686 | if reqCount > 0 { 687 | return p.missingRequiredFieldError(sv) 688 | } 689 | return reqFieldErr 690 | } 691 | 692 | // consumeExtName consumes extension name or expanded Any type URL and the 693 | // following ']'. It returns the name or URL consumed. 694 | func (p *textParser) consumeExtName() (string, error) { 695 | tok := p.next() 696 | if tok.err != nil { 697 | return "", tok.err 698 | } 699 | 700 | // If extension name or type url is quoted, it's a single token. 701 | if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { 702 | name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) 703 | if err != nil { 704 | return "", err 705 | } 706 | return name, p.consumeToken("]") 707 | } 708 | 709 | // Consume everything up to "]" 710 | var parts []string 711 | for tok.value != "]" { 712 | parts = append(parts, tok.value) 713 | tok = p.next() 714 | if tok.err != nil { 715 | return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) 716 | } 717 | if p.done && tok.value != "]" { 718 | return "", p.errorf("unclosed type_url or extension name") 719 | } 720 | } 721 | return strings.Join(parts, ""), nil 722 | } 723 | 724 | // consumeOptionalSeparator consumes an optional semicolon or comma. 725 | // It is used in readStruct to provide backward compatibility. 726 | func (p *textParser) consumeOptionalSeparator() error { 727 | tok := p.next() 728 | if tok.err != nil { 729 | return tok.err 730 | } 731 | if tok.value != ";" && tok.value != "," { 732 | p.back() 733 | } 734 | return nil 735 | } 736 | 737 | func (p *textParser) readAny(v reflect.Value, props *Properties) error { 738 | tok := p.next() 739 | if tok.err != nil { 740 | return tok.err 741 | } 742 | if tok.value == "" { 743 | return p.errorf("unexpected EOF") 744 | } 745 | 746 | switch fv := v; fv.Kind() { 747 | case reflect.Slice: 748 | at := v.Type() 749 | if at.Elem().Kind() == reflect.Uint8 { 750 | // Special case for []byte 751 | if tok.value[0] != '"' && tok.value[0] != '\'' { 752 | // Deliberately written out here, as the error after 753 | // this switch statement would write "invalid []byte: ...", 754 | // which is not as user-friendly. 755 | return p.errorf("invalid string: %v", tok.value) 756 | } 757 | bytes := []byte(tok.unquoted) 758 | fv.Set(reflect.ValueOf(bytes)) 759 | return nil 760 | } 761 | // Repeated field. 762 | if tok.value == "[" { 763 | // Repeated field with list notation, like [1,2,3]. 764 | for { 765 | fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) 766 | err := p.readAny(fv.Index(fv.Len()-1), props) 767 | if err != nil { 768 | return err 769 | } 770 | tok := p.next() 771 | if tok.err != nil { 772 | return tok.err 773 | } 774 | if tok.value == "]" { 775 | break 776 | } 777 | if tok.value != "," { 778 | return p.errorf("Expected ']' or ',' found %q", tok.value) 779 | } 780 | } 781 | return nil 782 | } 783 | // One value of the repeated field. 784 | p.back() 785 | fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) 786 | return p.readAny(fv.Index(fv.Len()-1), props) 787 | case reflect.Bool: 788 | // true/1/t/True or false/f/0/False. 789 | switch tok.value { 790 | case "true", "1", "t", "True": 791 | fv.SetBool(true) 792 | return nil 793 | case "false", "0", "f", "False": 794 | fv.SetBool(false) 795 | return nil 796 | } 797 | case reflect.Float32, reflect.Float64: 798 | v := tok.value 799 | // Ignore 'f' for compatibility with output generated by C++, but don't 800 | // remove 'f' when the value is "-inf" or "inf". 801 | if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { 802 | v = v[:len(v)-1] 803 | } 804 | if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { 805 | fv.SetFloat(f) 806 | return nil 807 | } 808 | case reflect.Int32: 809 | if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { 810 | fv.SetInt(x) 811 | return nil 812 | } 813 | 814 | if len(props.Enum) == 0 { 815 | break 816 | } 817 | m, ok := enumValueMaps[props.Enum] 818 | if !ok { 819 | break 820 | } 821 | x, ok := m[tok.value] 822 | if !ok { 823 | break 824 | } 825 | fv.SetInt(int64(x)) 826 | return nil 827 | case reflect.Int64: 828 | if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { 829 | fv.SetInt(x) 830 | return nil 831 | } 832 | 833 | case reflect.Ptr: 834 | // A basic field (indirected through pointer), or a repeated message/group 835 | p.back() 836 | fv.Set(reflect.New(fv.Type().Elem())) 837 | return p.readAny(fv.Elem(), props) 838 | case reflect.String: 839 | if tok.value[0] == '"' || tok.value[0] == '\'' { 840 | fv.SetString(tok.unquoted) 841 | return nil 842 | } 843 | case reflect.Struct: 844 | var terminator string 845 | switch tok.value { 846 | case "{": 847 | terminator = "}" 848 | case "<": 849 | terminator = ">" 850 | default: 851 | return p.errorf("expected '{' or '<', found %q", tok.value) 852 | } 853 | // TODO: Handle nested messages which implement encoding.TextUnmarshaler. 854 | return p.readStruct(fv, terminator) 855 | case reflect.Uint32: 856 | if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { 857 | fv.SetUint(uint64(x)) 858 | return nil 859 | } 860 | case reflect.Uint64: 861 | if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { 862 | fv.SetUint(x) 863 | return nil 864 | } 865 | } 866 | return p.errorf("invalid %v: %v", v.Type(), tok.value) 867 | } 868 | 869 | // UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb 870 | // before starting to unmarshal, so any existing data in pb is always removed. 871 | // If a required field is not set and no other error occurs, 872 | // UnmarshalText returns *RequiredNotSetError. 873 | func UnmarshalText(s string, pb Message) error { 874 | if um, ok := pb.(encoding.TextUnmarshaler); ok { 875 | return um.UnmarshalText([]byte(s)) 876 | } 877 | pb.Reset() 878 | v := reflect.ValueOf(pb) 879 | return newTextParser(s).readStruct(v.Elem(), "") 880 | } 881 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/protocol/conn.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: conn.proto 3 | 4 | /* 5 | Package protocol is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | conn.proto 9 | 10 | It has these top-level messages: 11 | Conn_ToS 12 | Conn_ToC 13 | */ 14 | package protocol 15 | 16 | import proto "Golang-OnlineChatRoom/ProtobufChatRoom/github.com/golang/protobuf/proto" 17 | import fmt "fmt" 18 | import math "math" 19 | 20 | // Reference imports to suppress errors if they are not otherwise used. 21 | var _ = proto.Marshal 22 | var _ = fmt.Errorf 23 | var _ = math.Inf 24 | 25 | // This is a compile-time assertion to ensure that this generated file 26 | // is compatible with the proto package it is being compiled against. 27 | // A compilation error at this line likely means your copy of the 28 | // proto package needs to be updated. 29 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 30 | 31 | type Conn_ToS struct { 32 | Nickname *string `protobuf:"bytes,1,req,name=nickname" json:"nickname,omitempty"` 33 | Msg *string `protobuf:"bytes,2,req,name=msg" json:"msg,omitempty"` 34 | XXX_unrecognized []byte `json:"-"` 35 | } 36 | 37 | func (m *Conn_ToS) Reset() { *m = Conn_ToS{} } 38 | func (m *Conn_ToS) String() string { return proto.CompactTextString(m) } 39 | func (*Conn_ToS) ProtoMessage() {} 40 | func (*Conn_ToS) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } 41 | 42 | func (m *Conn_ToS) GetNickname() string { 43 | if m != nil && m.Nickname != nil { 44 | return *m.Nickname 45 | } 46 | return "" 47 | } 48 | 49 | func (m *Conn_ToS) GetMsg() string { 50 | if m != nil && m.Msg != nil { 51 | return *m.Msg 52 | } 53 | return "" 54 | } 55 | 56 | type Conn_ToC struct { 57 | Nickname *string `protobuf:"bytes,1,req,name=nickname" json:"nickname,omitempty"` 58 | Msg *string `protobuf:"bytes,2,req,name=msg" json:"msg,omitempty"` 59 | XXX_unrecognized []byte `json:"-"` 60 | } 61 | 62 | func (m *Conn_ToC) Reset() { *m = Conn_ToC{} } 63 | func (m *Conn_ToC) String() string { return proto.CompactTextString(m) } 64 | func (*Conn_ToC) ProtoMessage() {} 65 | func (*Conn_ToC) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } 66 | 67 | func (m *Conn_ToC) GetNickname() string { 68 | if m != nil && m.Nickname != nil { 69 | return *m.Nickname 70 | } 71 | return "" 72 | } 73 | 74 | func (m *Conn_ToC) GetMsg() string { 75 | if m != nil && m.Msg != nil { 76 | return *m.Msg 77 | } 78 | return "" 79 | } 80 | 81 | func init() { 82 | proto.RegisterType((*Conn_ToS)(nil), "protocol.conn_ToS") 83 | proto.RegisterType((*Conn_ToC)(nil), "protocol.conn_ToC") 84 | } 85 | 86 | func init() { proto.RegisterFile("conn.proto", fileDescriptor0) } 87 | 88 | var fileDescriptor0 = []byte{ 89 | // 91 bytes of a gzipped FileDescriptorProto 90 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0xce, 0xcf, 0xcb, 91 | 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x00, 0x53, 0xc9, 0xf9, 0x39, 0x4a, 0x16, 0x5c, 92 | 0x1c, 0x20, 0xf1, 0xf8, 0x90, 0xfc, 0x60, 0x21, 0x29, 0x2e, 0x8e, 0xbc, 0xcc, 0xe4, 0xec, 0xbc, 93 | 0xc4, 0xdc, 0x54, 0x09, 0x46, 0x05, 0x26, 0x0d, 0xce, 0x20, 0x38, 0x5f, 0x48, 0x80, 0x8b, 0x39, 94 | 0xb7, 0x38, 0x5d, 0x82, 0x09, 0x2c, 0x0c, 0x62, 0x22, 0xe9, 0x74, 0x26, 0x4d, 0x27, 0x20, 0x00, 95 | 0x00, 0xff, 0xff, 0x33, 0xfa, 0x35, 0x53, 0x8a, 0x00, 0x00, 0x00, 96 | } 97 | -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/protocol/message/conn.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | package protocol; 3 | 4 | message conn_ToS{ 5 | required string nickname = 1; 6 | required string msg = 2; 7 | } 8 | 9 | message conn_ToC{ 10 | required string nickname = 1; 11 | required string msg = 2; 12 | } -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/protocol/message/protoc-gen-go.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/ProtobufChatRoom_V2.5/protocol/message/protoc-gen-go.exe -------------------------------------------------------------------------------- /ProtobufChatRoom_V2.5/protocol/message/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/ProtobufChatRoom_V2.5/protocol/message/protoc.exe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OctopusLian/Golang-OnlineChatRoom/dedaadb719ec287b4e5f9721431c34169f71ebc5/README.md --------------------------------------------------------------------------------