Joe Tsai | eeca8bb | 2018-12-04 16:24:22 -0800 | [diff] [blame] | 1 | // Copyright 2010 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | package protoV1 |
| 6 | |
| 7 | import ( |
| 8 | "fmt" |
| 9 | |
| 10 | "github.com/golang/protobuf/protoapi" |
| 11 | ) |
| 12 | |
| 13 | // RequiredNotSetError is an error type returned by either Marshal or Unmarshal. |
| 14 | // Marshal reports this when a required field is not initialized. |
| 15 | // Unmarshal reports this when a required field is missing from the wire data. |
| 16 | type RequiredNotSetError struct{ field string } |
| 17 | |
| 18 | func (e *RequiredNotSetError) Error() string { |
| 19 | if e.field == "" { |
| 20 | return fmt.Sprintf("proto: required field not set") |
| 21 | } |
| 22 | return fmt.Sprintf("proto: required field %q not set", e.field) |
| 23 | } |
| 24 | func (e *RequiredNotSetError) RequiredNotSet() bool { |
| 25 | return true |
| 26 | } |
| 27 | |
| 28 | type invalidUTF8Error struct{ field string } |
| 29 | |
| 30 | func (e *invalidUTF8Error) Error() string { |
| 31 | if e.field == "" { |
| 32 | return "proto: invalid UTF-8 detected" |
| 33 | } |
| 34 | return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field) |
| 35 | } |
| 36 | func (e *invalidUTF8Error) InvalidUTF8() bool { |
| 37 | return true |
| 38 | } |
| 39 | |
| 40 | // errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8. |
| 41 | // This error should not be exposed to the external API as such errors should |
| 42 | // be recreated with the field information. |
| 43 | var errInvalidUTF8 = &invalidUTF8Error{} |
| 44 | |
| 45 | // isNonFatal reports whether the error is either a RequiredNotSet error |
| 46 | // or a InvalidUTF8 error. |
| 47 | func isNonFatal(err error) bool { |
| 48 | if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() { |
| 49 | return true |
| 50 | } |
| 51 | if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() { |
| 52 | return true |
| 53 | } |
| 54 | return false |
| 55 | } |
| 56 | |
| 57 | type nonFatal struct{ E error } |
| 58 | |
| 59 | // Merge merges err into nf and reports whether it was successful. |
| 60 | // Otherwise it returns false for any fatal non-nil errors. |
| 61 | func (nf *nonFatal) Merge(err error) (ok bool) { |
| 62 | if err == nil { |
| 63 | return true // not an error |
| 64 | } |
| 65 | if !isNonFatal(err) { |
| 66 | return false // fatal error |
| 67 | } |
| 68 | if nf.E == nil { |
| 69 | nf.E = err // store first instance of non-fatal error |
| 70 | } |
| 71 | return true |
| 72 | } |
| 73 | |
| 74 | type ( |
| 75 | Message = protoapi.Message |
| 76 | Extension = protoapi.ExtensionField |
| 77 | ExtensionRange = protoapi.ExtensionRange |
| 78 | XXX_InternalExtensions = protoapi.XXX_InternalExtensions |
| 79 | ) |
| 80 | |
| 81 | // A Buffer is a buffer manager for marshaling and unmarshaling |
| 82 | // protocol buffers. It may be reused between invocations to |
| 83 | // reduce memory usage. It is not necessary to use a Buffer; |
| 84 | // the global functions Marshal and Unmarshal create a |
| 85 | // temporary Buffer and are fine for most applications. |
| 86 | type Buffer struct { |
| 87 | buf []byte // encode/decode byte stream |
| 88 | index int // read point |
| 89 | } |
| 90 | |
| 91 | // NewBuffer allocates a new Buffer and initializes its internal data to |
| 92 | // the contents of the argument slice. |
| 93 | func NewBuffer(e []byte) *Buffer { |
| 94 | return &Buffer{buf: e} |
| 95 | } |
| 96 | |
| 97 | // InternalMessageInfo is a type used internally by generated .pb.go files. |
| 98 | // This type is not intended to be used by non-generated code. |
| 99 | // This type is not subject to any compatibility guarantee. |
| 100 | type InternalMessageInfo struct { |
| 101 | unmarshal *unmarshalInfo |
| 102 | } |