| Index: third_party/protobuf/examples/add_person.go
|
| diff --git a/third_party/protobuf/examples/add_person.go b/third_party/protobuf/examples/add_person.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4f2e7f7418274a12cd2b798a6816827753cb2514
|
| --- /dev/null
|
| +++ b/third_party/protobuf/examples/add_person.go
|
| @@ -0,0 +1,133 @@
|
| +package main
|
| +
|
| +import (
|
| + "bufio"
|
| + "fmt"
|
| + "io"
|
| + "io/ioutil"
|
| + "log"
|
| + "os"
|
| + "strings"
|
| +
|
| + "github.com/golang/protobuf/proto"
|
| + pb "github.com/google/protobuf/examples/tutorial"
|
| +)
|
| +
|
| +func promptForAddress(r io.Reader) (*pb.Person, error) {
|
| + // A protocol buffer can be created like any struct.
|
| + p := &pb.Person{}
|
| +
|
| + rd := bufio.NewReader(r)
|
| + fmt.Print("Enter person ID number: ")
|
| + // An int32 field in the .proto file is represented as an int32 field
|
| + // in the generated Go struct.
|
| + if _, err := fmt.Fscanf(rd, "%d\n", &p.Id); err != nil {
|
| + return p, err
|
| + }
|
| +
|
| + fmt.Print("Enter name: ")
|
| + name, err := rd.ReadString('\n')
|
| + if err != nil {
|
| + return p, err
|
| + }
|
| + // A string field in the .proto file results in a string field in Go.
|
| + // We trim the whitespace because rd.ReadString includes the trailing
|
| + // newline character in its output.
|
| + p.Name = strings.TrimSpace(name)
|
| +
|
| + fmt.Print("Enter email address (blank for none): ")
|
| + email, err := rd.ReadString('\n')
|
| + if err != nil {
|
| + return p, err
|
| + }
|
| + p.Email = strings.TrimSpace(email)
|
| +
|
| + for {
|
| + fmt.Print("Enter a phone number (or leave blank to finish): ")
|
| + phone, err := rd.ReadString('\n')
|
| + if err != nil {
|
| + return p, err
|
| + }
|
| + phone = strings.TrimSpace(phone)
|
| + if phone == "" {
|
| + break
|
| + }
|
| + // The PhoneNumber message type is nested within the Person
|
| + // message in the .proto file. This results in a Go struct
|
| + // named using the name of the parent prefixed to the name of
|
| + // the nested message. Just as with pb.Person, it can be
|
| + // created like any other struct.
|
| + pn := &pb.Person_PhoneNumber{
|
| + Number: phone,
|
| + }
|
| +
|
| + fmt.Print("Is this a mobile, home, or work phone? ")
|
| + ptype, err := rd.ReadString('\n')
|
| + if err != nil {
|
| + return p, err
|
| + }
|
| + ptype = strings.TrimSpace(ptype)
|
| +
|
| + // A proto enum results in a Go constant for each enum value.
|
| + switch ptype {
|
| + case "mobile":
|
| + pn.Type = pb.Person_MOBILE
|
| + case "home":
|
| + pn.Type = pb.Person_HOME
|
| + case "work":
|
| + pn.Type = pb.Person_WORK
|
| + default:
|
| + fmt.Printf("Unknown phone type %q. Using default.\n", ptype)
|
| + }
|
| +
|
| + // A repeated proto field maps to a slice field in Go. We can
|
| + // append to it like any other slice.
|
| + p.Phones = append(p.Phones, pn)
|
| + }
|
| +
|
| + return p, nil
|
| +}
|
| +
|
| +// Main reads the entire address book from a file, adds one person based on
|
| +// user input, then writes it back out to the same file.
|
| +func main() {
|
| + if len(os.Args) != 2 {
|
| + log.Fatalf("Usage: %s ADDRESS_BOOK_FILE\n", os.Args[0])
|
| + }
|
| + fname := os.Args[1]
|
| +
|
| + // Read the existing address book.
|
| + in, err := ioutil.ReadFile(fname)
|
| + if err != nil {
|
| + if os.IsNotExist(err) {
|
| + fmt.Printf("%s: File not found. Creating new file.\n", fname)
|
| + } else {
|
| + log.Fatalln("Error reading file:", err)
|
| + }
|
| + }
|
| +
|
| + // [START marshal_proto]
|
| + book := &pb.AddressBook{}
|
| + // [START_EXCLUDE]
|
| + if err := proto.Unmarshal(in, book); err != nil {
|
| + log.Fatalln("Failed to parse address book:", err)
|
| + }
|
| +
|
| + // Add an address.
|
| + addr, err := promptForAddress(os.Stdin)
|
| + if err != nil {
|
| + log.Fatalln("Error with address:", err)
|
| + }
|
| + book.People = append(book.People, addr)
|
| + // [END_EXCLUDE]
|
| +
|
| + // Write the new address book back to disk.
|
| + out, err := proto.Marshal(book)
|
| + if err != nil {
|
| + log.Fatalln("Failed to encode address book:", err)
|
| + }
|
| + if err := ioutil.WriteFile(fname, out, 0644); err != nil {
|
| + log.Fatalln("Failed to write address book:", err)
|
| + }
|
| + // [END marshal_proto]
|
| +}
|
|
|