protofile.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Copyright 2018 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 prototype provides builders to construct protobuf types that
  5. // implement the interfaces defined in the protoreflect package.
  6. //
  7. // Protobuf types can either be constructed as standalone types
  8. // (e.g., StandaloneMessage), or together as a batch of types in a single
  9. // proto file (e.g., File). When creating standalone types, additional
  10. // information must be provided such as the full type name and the proto syntax.
  11. // When creating an entire file, the syntax and full name is derived from
  12. // the parent type.
  13. package prototype
  14. import (
  15. "github.com/golang/protobuf/v2/reflect/protoreflect"
  16. )
  17. // Every struct has a "meta" struct embedded within it as a pointer.
  18. // The meta type provides additional data structures for efficient lookup on
  19. // certain methods (e.g., ByName) or derived information that can be
  20. // derived from the parent (e.g., FullName). The meta type is lazily allocated
  21. // and initialized. This architectural approach keeps the literal representation
  22. // smaller, which then keeps the generated code size smaller.
  23. // TODO: Instead of a top-down construction approach where internal references
  24. // to message types use placeholder types, we could add a Reference method
  25. // on Message and Enum that creates a MessageDescriptor or EnumDescriptor
  26. // reference that only becomes valid after NewFile.
  27. // However, that API approach is more error prone, as it causes more memory
  28. // aliasing and provides more opportunity for misuse.
  29. // Also, it requires that NewFile at least eagerly initialize all
  30. // messages and enums list types. We can always add that API in the future.
  31. // File is a constructor for protoreflect.FileDescriptor.
  32. type File struct {
  33. Syntax protoreflect.Syntax
  34. Path string
  35. Package protoreflect.FullName
  36. Imports []protoreflect.FileImport
  37. Messages []Message
  38. Enums []Enum
  39. Extensions []Extension
  40. Services []Service
  41. *fileMeta
  42. }
  43. // NewFile creates a new protoreflect.FileDescriptor from the provided value.
  44. // The file must represent a valid proto file according to protobuf semantics.
  45. //
  46. // Fields that reference an enum or message that is being declared within the
  47. // same File can be represented using a placeholder descriptor. NewFile will
  48. // automatically resolve the placeholder to point to the concrete type.
  49. //
  50. // The caller must relinquish full ownership of the input t and must not
  51. // access or mutate any fields. The input must not contain slices that are
  52. // sub-slices of each other.
  53. func NewFile(t *File) (protoreflect.FileDescriptor, error) {
  54. // TODO: Provide an unverified make that avoids validating the file.
  55. // This is useful for generated code since we know that protoc-gen-go
  56. // already validated the protobuf types.
  57. ft := newFile(t)
  58. if err := validateFile(ft); err != nil {
  59. return nil, err
  60. }
  61. return ft, nil
  62. }
  63. // Message is a constructor for protoreflect.MessageDescriptor.
  64. type Message struct {
  65. Name protoreflect.Name
  66. IsMapEntry bool
  67. Fields []Field
  68. Oneofs []Oneof
  69. ExtensionRanges [][2]protoreflect.FieldNumber
  70. Messages []Message
  71. Enums []Enum
  72. Extensions []Extension
  73. *messageMeta
  74. }
  75. // Field is a constructor for protoreflect.FieldDescriptor.
  76. type Field struct {
  77. Name protoreflect.Name
  78. Number protoreflect.FieldNumber
  79. Cardinality protoreflect.Cardinality
  80. Kind protoreflect.Kind
  81. JSONName string
  82. IsPacked bool
  83. IsWeak bool
  84. Default protoreflect.Value
  85. OneofName protoreflect.Name
  86. MessageType protoreflect.MessageDescriptor
  87. EnumType protoreflect.EnumDescriptor
  88. *fieldMeta
  89. }
  90. // Oneof is a constructor for protoreflect.OneofDescriptor.
  91. type Oneof struct {
  92. Name protoreflect.Name
  93. *oneofMeta
  94. }
  95. // Extension is a constructor for protoreflect.ExtensionDescriptor.
  96. type Extension struct {
  97. Name protoreflect.Name
  98. Number protoreflect.FieldNumber
  99. Cardinality protoreflect.Cardinality
  100. Kind protoreflect.Kind
  101. IsPacked bool
  102. Default protoreflect.Value
  103. MessageType protoreflect.MessageDescriptor
  104. EnumType protoreflect.EnumDescriptor
  105. ExtendedType protoreflect.MessageDescriptor
  106. *extensionMeta
  107. }
  108. // Enum is a constructor for protoreflect.EnumDescriptor.
  109. type Enum struct {
  110. Name protoreflect.Name
  111. Values []EnumValue
  112. *enumMeta
  113. }
  114. // EnumValue is a constructor for protoreflect.EnumValueDescriptor.
  115. type EnumValue struct {
  116. Name protoreflect.Name
  117. Number protoreflect.EnumNumber
  118. *enumValueMeta
  119. }
  120. // Service is a constructor for protoreflect.ServiceDescriptor.
  121. type Service struct {
  122. Name protoreflect.Name
  123. Methods []Method
  124. *serviceMeta
  125. }
  126. // Method is a constructor for protoreflect.MethodDescriptor.
  127. type Method struct {
  128. Name protoreflect.Name
  129. InputType protoreflect.MessageDescriptor
  130. OutputType protoreflect.MessageDescriptor
  131. IsStreamingClient bool
  132. IsStreamingServer bool
  133. *methodMeta
  134. }