vendor/google.golang.org/protobuf/proto/decode.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
    17 )
    17 )
    18 
    18 
    19 // UnmarshalOptions configures the unmarshaler.
    19 // UnmarshalOptions configures the unmarshaler.
    20 //
    20 //
    21 // Example usage:
    21 // Example usage:
    22 //   err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)
    22 //
       
    23 //	err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)
    23 type UnmarshalOptions struct {
    24 type UnmarshalOptions struct {
    24 	pragma.NoUnkeyedLiterals
    25 	pragma.NoUnkeyedLiterals
    25 
    26 
    26 	// Merge merges the input into the destination message.
    27 	// Merge merges the input into the destination message.
    27 	// The default behavior is to always reset the message before unmarshaling,
    28 	// The default behavior is to always reset the message before unmarshaling,
    40 	// If nil, this defaults to using protoregistry.GlobalTypes.
    41 	// If nil, this defaults to using protoregistry.GlobalTypes.
    41 	Resolver interface {
    42 	Resolver interface {
    42 		FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
    43 		FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
    43 		FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
    44 		FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
    44 	}
    45 	}
       
    46 
       
    47 	// RecursionLimit limits how deeply messages may be nested.
       
    48 	// If zero, a default limit is applied.
       
    49 	RecursionLimit int
    45 }
    50 }
    46 
    51 
    47 // Unmarshal parses the wire-format message in b and places the result in m.
    52 // Unmarshal parses the wire-format message in b and places the result in m.
    48 // The provided message must be mutable (e.g., a non-nil pointer to a message).
    53 // The provided message must be mutable (e.g., a non-nil pointer to a message).
    49 func Unmarshal(b []byte, m Message) error {
    54 func Unmarshal(b []byte, m Message) error {
    50 	_, err := UnmarshalOptions{}.unmarshal(b, m.ProtoReflect())
    55 	_, err := UnmarshalOptions{RecursionLimit: protowire.DefaultRecursionLimit}.unmarshal(b, m.ProtoReflect())
    51 	return err
    56 	return err
    52 }
    57 }
    53 
    58 
    54 // Unmarshal parses the wire-format message in b and places the result in m.
    59 // Unmarshal parses the wire-format message in b and places the result in m.
    55 // The provided message must be mutable (e.g., a non-nil pointer to a message).
    60 // The provided message must be mutable (e.g., a non-nil pointer to a message).
    56 func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
    61 func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
       
    62 	if o.RecursionLimit == 0 {
       
    63 		o.RecursionLimit = protowire.DefaultRecursionLimit
       
    64 	}
    57 	_, err := o.unmarshal(b, m.ProtoReflect())
    65 	_, err := o.unmarshal(b, m.ProtoReflect())
    58 	return err
    66 	return err
    59 }
    67 }
    60 
    68 
    61 // UnmarshalState parses a wire-format message and places the result in m.
    69 // UnmarshalState parses a wire-format message and places the result in m.
    62 //
    70 //
    63 // This method permits fine-grained control over the unmarshaler.
    71 // This method permits fine-grained control over the unmarshaler.
    64 // Most users should use Unmarshal instead.
    72 // Most users should use Unmarshal instead.
    65 func (o UnmarshalOptions) UnmarshalState(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
    73 func (o UnmarshalOptions) UnmarshalState(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
       
    74 	if o.RecursionLimit == 0 {
       
    75 		o.RecursionLimit = protowire.DefaultRecursionLimit
       
    76 	}
    66 	return o.unmarshal(in.Buf, in.Message)
    77 	return o.unmarshal(in.Buf, in.Message)
    67 }
    78 }
    68 
    79 
    69 // unmarshal is a centralized function that all unmarshal operations go through.
    80 // unmarshal is a centralized function that all unmarshal operations go through.
    70 // For profiling purposes, avoid changing the name of this function or
    81 // For profiling purposes, avoid changing the name of this function or
    84 		!(o.DiscardUnknown && methods.Flags&protoiface.SupportUnmarshalDiscardUnknown == 0) {
    95 		!(o.DiscardUnknown && methods.Flags&protoiface.SupportUnmarshalDiscardUnknown == 0) {
    85 		in := protoiface.UnmarshalInput{
    96 		in := protoiface.UnmarshalInput{
    86 			Message:  m,
    97 			Message:  m,
    87 			Buf:      b,
    98 			Buf:      b,
    88 			Resolver: o.Resolver,
    99 			Resolver: o.Resolver,
       
   100 			Depth:    o.RecursionLimit,
    89 		}
   101 		}
    90 		if o.DiscardUnknown {
   102 		if o.DiscardUnknown {
    91 			in.Flags |= protoiface.UnmarshalDiscardUnknown
   103 			in.Flags |= protoiface.UnmarshalDiscardUnknown
    92 		}
   104 		}
    93 		out, err = methods.Unmarshal(in)
   105 		out, err = methods.Unmarshal(in)
    94 	} else {
   106 	} else {
       
   107 		o.RecursionLimit--
       
   108 		if o.RecursionLimit < 0 {
       
   109 			return out, errors.New("exceeded max recursion depth")
       
   110 		}
    95 		err = o.unmarshalMessageSlow(b, m)
   111 		err = o.unmarshalMessageSlow(b, m)
    96 	}
   112 	}
    97 	if err != nil {
   113 	if err != nil {
    98 		return out, err
   114 		return out, err
    99 	}
   115 	}