Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 

180 řádky
5.0 KiB

  1. // Copyright 2016 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. package ptypes
  5. import (
  6. "fmt"
  7. "strings"
  8. "github.com/golang/protobuf/proto"
  9. "google.golang.org/protobuf/reflect/protoreflect"
  10. "google.golang.org/protobuf/reflect/protoregistry"
  11. anypb "github.com/golang/protobuf/ptypes/any"
  12. )
  13. const urlPrefix = "type.googleapis.com/"
  14. // AnyMessageName returns the message name contained in an anypb.Any message.
  15. // Most type assertions should use the Is function instead.
  16. //
  17. // Deprecated: Call the any.MessageName method instead.
  18. func AnyMessageName(any *anypb.Any) (string, error) {
  19. name, err := anyMessageName(any)
  20. return string(name), err
  21. }
  22. func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) {
  23. if any == nil {
  24. return "", fmt.Errorf("message is nil")
  25. }
  26. name := protoreflect.FullName(any.TypeUrl)
  27. if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 {
  28. name = name[i+len("/"):]
  29. }
  30. if !name.IsValid() {
  31. return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
  32. }
  33. return name, nil
  34. }
  35. // MarshalAny marshals the given message m into an anypb.Any message.
  36. //
  37. // Deprecated: Call the anypb.New function instead.
  38. func MarshalAny(m proto.Message) (*anypb.Any, error) {
  39. switch dm := m.(type) {
  40. case DynamicAny:
  41. m = dm.Message
  42. case *DynamicAny:
  43. if dm == nil {
  44. return nil, proto.ErrNil
  45. }
  46. m = dm.Message
  47. }
  48. b, err := proto.Marshal(m)
  49. if err != nil {
  50. return nil, err
  51. }
  52. return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil
  53. }
  54. // Empty returns a new message of the type specified in an anypb.Any message.
  55. // It returns protoregistry.NotFound if the corresponding message type could not
  56. // be resolved in the global registry.
  57. //
  58. // Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead
  59. // to resolve the message name and create a new instance of it.
  60. func Empty(any *anypb.Any) (proto.Message, error) {
  61. name, err := anyMessageName(any)
  62. if err != nil {
  63. return nil, err
  64. }
  65. mt, err := protoregistry.GlobalTypes.FindMessageByName(name)
  66. if err != nil {
  67. return nil, err
  68. }
  69. return proto.MessageV1(mt.New().Interface()), nil
  70. }
  71. // UnmarshalAny unmarshals the encoded value contained in the anypb.Any message
  72. // into the provided message m. It returns an error if the target message
  73. // does not match the type in the Any message or if an unmarshal error occurs.
  74. //
  75. // The target message m may be a *DynamicAny message. If the underlying message
  76. // type could not be resolved, then this returns protoregistry.NotFound.
  77. //
  78. // Deprecated: Call the any.UnmarshalTo method instead.
  79. func UnmarshalAny(any *anypb.Any, m proto.Message) error {
  80. if dm, ok := m.(*DynamicAny); ok {
  81. if dm.Message == nil {
  82. var err error
  83. dm.Message, err = Empty(any)
  84. if err != nil {
  85. return err
  86. }
  87. }
  88. m = dm.Message
  89. }
  90. anyName, err := AnyMessageName(any)
  91. if err != nil {
  92. return err
  93. }
  94. msgName := proto.MessageName(m)
  95. if anyName != msgName {
  96. return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName)
  97. }
  98. return proto.Unmarshal(any.Value, m)
  99. }
  100. // Is reports whether the Any message contains a message of the specified type.
  101. //
  102. // Deprecated: Call the any.MessageIs method instead.
  103. func Is(any *anypb.Any, m proto.Message) bool {
  104. if any == nil || m == nil {
  105. return false
  106. }
  107. name := proto.MessageName(m)
  108. if !strings.HasSuffix(any.TypeUrl, name) {
  109. return false
  110. }
  111. return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/'
  112. }
  113. // DynamicAny is a value that can be passed to UnmarshalAny to automatically
  114. // allocate a proto.Message for the type specified in an anypb.Any message.
  115. // The allocated message is stored in the embedded proto.Message.
  116. //
  117. // Example:
  118. // var x ptypes.DynamicAny
  119. // if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
  120. // fmt.Printf("unmarshaled message: %v", x.Message)
  121. //
  122. // Deprecated: Use the any.UnmarshalNew method instead to unmarshal
  123. // the any message contents into a new instance of the underlying message.
  124. type DynamicAny struct{ proto.Message }
  125. func (m DynamicAny) String() string {
  126. if m.Message == nil {
  127. return "<nil>"
  128. }
  129. return m.Message.String()
  130. }
  131. func (m DynamicAny) Reset() {
  132. if m.Message == nil {
  133. return
  134. }
  135. m.Message.Reset()
  136. }
  137. func (m DynamicAny) ProtoMessage() {
  138. return
  139. }
  140. func (m DynamicAny) ProtoReflect() protoreflect.Message {
  141. if m.Message == nil {
  142. return nil
  143. }
  144. return dynamicAny{proto.MessageReflect(m.Message)}
  145. }
  146. type dynamicAny struct{ protoreflect.Message }
  147. func (m dynamicAny) Type() protoreflect.MessageType {
  148. return dynamicAnyType{m.Message.Type()}
  149. }
  150. func (m dynamicAny) New() protoreflect.Message {
  151. return dynamicAnyType{m.Message.Type()}.New()
  152. }
  153. func (m dynamicAny) Interface() protoreflect.ProtoMessage {
  154. return DynamicAny{proto.MessageV1(m.Message.Interface())}
  155. }
  156. type dynamicAnyType struct{ protoreflect.MessageType }
  157. func (t dynamicAnyType) New() protoreflect.Message {
  158. return dynamicAny{t.MessageType.New()}
  159. }
  160. func (t dynamicAnyType) Zero() protoreflect.Message {
  161. return dynamicAny{t.MessageType.Zero()}
  162. }