diff options
Diffstat (limited to 'reflect/protorange/example_test.go')
-rw-r--r-- | reflect/protorange/example_test.go | 307 |
1 files changed, 0 insertions, 307 deletions
diff --git a/reflect/protorange/example_test.go b/reflect/protorange/example_test.go deleted file mode 100644 index 90ceec6c..00000000 --- a/reflect/protorange/example_test.go +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package protorange_test - -import ( - "fmt" - "strings" - "time" - - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/internal/detrand" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protopath" - "google.golang.org/protobuf/reflect/protorange" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/testing/protopack" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/timestamppb" - - newspb "google.golang.org/protobuf/internal/testprotos/news" -) - -func init() { - detrand.Disable() -} - -func mustMarshal(m proto.Message) []byte { - b, err := proto.Marshal(m) - if err != nil { - panic(err) - } - return b -} - -// Range through every message and clear the unknown fields. -func Example_discardUnknown() { - // Populate the article with unknown fields. - m := &newspb.Article{} - m.ProtoReflect().SetUnknown(protopack.Message{ - protopack.Tag{1000, protopack.BytesType}, protopack.String("Hello, world!"), - }.Marshal()) - fmt.Println("has unknown fields?", len(m.ProtoReflect().GetUnknown()) > 0) - - // Range through the message and clear all unknown fields. - fmt.Println("clear unknown fields") - protorange.Range(m.ProtoReflect(), func(proto protopath.Values) error { - m, ok := proto.Index(-1).Value.Interface().(protoreflect.Message) - if ok && len(m.GetUnknown()) > 0 { - m.SetUnknown(nil) - } - return nil - }) - fmt.Println("has unknown fields?", len(m.ProtoReflect().GetUnknown()) > 0) - - // Output: - // has unknown fields? true - // clear unknown fields - // has unknown fields? false -} - -// Print the relative paths as Range iterates through a message -// in a depth-first order. -func Example_printPaths() { - m := &newspb.Article{ - Author: "Russ Cox", - Date: timestamppb.New(time.Date(2019, time.November, 8, 0, 0, 0, 0, time.UTC)), - Title: "Go Turns 10", - Content: "Happy birthday, Go! This weekend we celebrate the 10th anniversary of the Go release...", - Status: newspb.Article_PUBLISHED, - Tags: []string{"community", "birthday"}, - Attachments: []*anypb.Any{{ - TypeUrl: "google.golang.org.BinaryAttachment", - Value: mustMarshal(&newspb.BinaryAttachment{ - Name: "gopher-birthday.png", - Data: []byte("<binary data>"), - }), - }}, - } - - // Traverse over all reachable values and print the path. - protorange.Range(m.ProtoReflect(), func(p protopath.Values) error { - fmt.Println(p.Path[1:]) - return nil - }) - - // Output: - // .author - // .date - // .date.seconds - // .title - // .content - // .status - // .tags - // .tags[0] - // .tags[1] - // .attachments - // .attachments[0] - // .attachments[0].(google.golang.org.BinaryAttachment) - // .attachments[0].(google.golang.org.BinaryAttachment).name - // .attachments[0].(google.golang.org.BinaryAttachment).data -} - -// Implement a basic text formatter by ranging through all populated values -// in a message in depth-first order. -func Example_formatText() { - m := &newspb.Article{ - Author: "Brad Fitzpatrick", - Date: timestamppb.New(time.Date(2018, time.February, 16, 0, 0, 0, 0, time.UTC)), - Title: "Go 1.10 is released", - Content: "Happy Friday, happy weekend! Today the Go team is happy to announce the release of Go 1.10...", - Status: newspb.Article_PUBLISHED, - Tags: []string{"go1.10", "release"}, - Attachments: []*anypb.Any{{ - TypeUrl: "google.golang.org.KeyValueAttachment", - Value: mustMarshal(&newspb.KeyValueAttachment{ - Name: "checksums.txt", - Data: map[string]string{ - "go1.10.src.tar.gz": "07cbb9d0091b846c6aea40bf5bc0cea7", - "go1.10.darwin-amd64.pkg": "cbb38bb6ff6ea86279e01745984445bf", - "go1.10.linux-amd64.tar.gz": "6b3d0e4a5c77352cf4275573817f7566", - "go1.10.windows-amd64.msi": "57bda02030f58f5d2bf71943e1390123", - }, - }), - }}, - } - - // Print a message in a humanly readable format. - var indent []byte - protorange.Options{ - Stable: true, - }.Range(m.ProtoReflect(), - func(p protopath.Values) error { - // Print the key. - var fd protoreflect.FieldDescriptor - last := p.Index(-1) - beforeLast := p.Index(-2) - switch last.Step.Kind() { - case protopath.FieldAccessStep: - fd = last.Step.FieldDescriptor() - fmt.Printf("%s%s: ", indent, fd.Name()) - case protopath.ListIndexStep: - fd = beforeLast.Step.FieldDescriptor() // lists always appear in the context of a repeated field - fmt.Printf("%s%d: ", indent, last.Step.ListIndex()) - case protopath.MapIndexStep: - fd = beforeLast.Step.FieldDescriptor() // maps always appear in the context of a repeated field - fmt.Printf("%s%v: ", indent, last.Step.MapIndex().Interface()) - case protopath.AnyExpandStep: - fmt.Printf("%s[%v]: ", indent, last.Value.Message().Descriptor().FullName()) - case protopath.UnknownAccessStep: - fmt.Printf("%s?: ", indent) - } - - // Starting printing the value. - switch v := last.Value.Interface().(type) { - case protoreflect.Message: - fmt.Printf("{\n") - indent = append(indent, '\t') - case protoreflect.List: - fmt.Printf("[\n") - indent = append(indent, '\t') - case protoreflect.Map: - fmt.Printf("{\n") - indent = append(indent, '\t') - case protoreflect.EnumNumber: - var ev protoreflect.EnumValueDescriptor - if fd != nil { - ev = fd.Enum().Values().ByNumber(v) - } - if ev != nil { - fmt.Printf("%v\n", ev.Name()) - } else { - fmt.Printf("%v\n", v) - } - case string, []byte: - fmt.Printf("%q\n", v) - default: - fmt.Printf("%v\n", v) - } - return nil - }, - func(p protopath.Values) error { - // Finish printing the value. - last := p.Index(-1) - switch last.Value.Interface().(type) { - case protoreflect.Message: - indent = indent[:len(indent)-1] - fmt.Printf("%s}\n", indent) - case protoreflect.List: - indent = indent[:len(indent)-1] - fmt.Printf("%s]\n", indent) - case protoreflect.Map: - indent = indent[:len(indent)-1] - fmt.Printf("%s}\n", indent) - } - return nil - }, - ) - - // Output: - // { - // author: "Brad Fitzpatrick" - // date: { - // seconds: 1518739200 - // } - // title: "Go 1.10 is released" - // content: "Happy Friday, happy weekend! Today the Go team is happy to announce the release of Go 1.10..." - // attachments: [ - // 0: { - // [google.golang.org.KeyValueAttachment]: { - // name: "checksums.txt" - // data: { - // go1.10.darwin-amd64.pkg: "cbb38bb6ff6ea86279e01745984445bf" - // go1.10.linux-amd64.tar.gz: "6b3d0e4a5c77352cf4275573817f7566" - // go1.10.src.tar.gz: "07cbb9d0091b846c6aea40bf5bc0cea7" - // go1.10.windows-amd64.msi: "57bda02030f58f5d2bf71943e1390123" - // } - // } - // } - // ] - // tags: [ - // 0: "go1.10" - // 1: "release" - // ] - // status: PUBLISHED - // } -} - -// Scan all protobuf string values for a sensitive word and replace it with -// a suitable alternative. -func Example_sanitizeStrings() { - m := &newspb.Article{ - Author: "Hermione Granger", - Date: timestamppb.New(time.Date(1998, time.May, 2, 0, 0, 0, 0, time.UTC)), - Title: "Harry Potter vanquishes Voldemort once and for all!", - Content: "In a final duel between Harry Potter and Lord Voldemort earlier this evening...", - Tags: []string{"HarryPotter", "LordVoldemort"}, - Attachments: []*anypb.Any{{ - TypeUrl: "google.golang.org.KeyValueAttachment", - Value: mustMarshal(&newspb.KeyValueAttachment{ - Name: "aliases.txt", - Data: map[string]string{ - "Harry Potter": "The Boy Who Lived", - "Tom Riddle": "Lord Voldemort", - }, - }), - }}, - } - - protorange.Range(m.ProtoReflect(), func(p protopath.Values) error { - const ( - sensitive = "Voldemort" - alternative = "[He-Who-Must-Not-Be-Named]" - ) - - // Check if there is a sensitive word to redact. - last := p.Index(-1) - s, ok := last.Value.Interface().(string) - if !ok || !strings.Contains(s, sensitive) { - return nil - } - s = strings.Replace(s, sensitive, alternative, -1) - - // Store the redacted string back into the message. - beforeLast := p.Index(-2) - switch last.Step.Kind() { - case protopath.FieldAccessStep: - m := beforeLast.Value.Message() - fd := last.Step.FieldDescriptor() - m.Set(fd, protoreflect.ValueOfString(s)) - case protopath.ListIndexStep: - ls := beforeLast.Value.List() - i := last.Step.ListIndex() - ls.Set(i, protoreflect.ValueOfString(s)) - case protopath.MapIndexStep: - ms := beforeLast.Value.Map() - k := last.Step.MapIndex() - ms.Set(k, protoreflect.ValueOfString(s)) - } - return nil - }) - - fmt.Println(protojson.Format(m)) - - // Output: - // { - // "author": "Hermione Granger", - // "date": "1998-05-02T00:00:00Z", - // "title": "Harry Potter vanquishes [He-Who-Must-Not-Be-Named] once and for all!", - // "content": "In a final duel between Harry Potter and Lord [He-Who-Must-Not-Be-Named] earlier this evening...", - // "tags": [ - // "HarryPotter", - // "Lord[He-Who-Must-Not-Be-Named]" - // ], - // "attachments": [ - // { - // "@type": "google.golang.org.KeyValueAttachment", - // "name": "aliases.txt", - // "data": { - // "Harry Potter": "The Boy Who Lived", - // "Tom Riddle": "Lord [He-Who-Must-Not-Be-Named]" - // } - // } - // ] - // } -} |