protofile.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. "google.golang.org/proto/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: Support initializing File from a google.protobuf.FileDescriptor?
  24. // TODO: Instead of a top-down construction approach where internal references
  25. // to message types use placeholder types, we could add a Reference method
  26. // on Message and Enum that creates a MessageDescriptor or EnumDescriptor
  27. // reference that only becomes valid after NewFile.
  28. // However, that API approach is more error prone, as it causes more memory
  29. // aliasing and provides more opportunity for misuse.
  30. // Also, it requires that NewFile at least eagerly initialize all
  31. // messages and enums list types. We can always add that API in the future.
  32. // File is a constructor for protoreflect.FileDescriptor.
  33. type File struct {
  34. Syntax protoreflect.Syntax
  35. Path string
  36. Package protoreflect.FullName
  37. Imports []protoreflect.FileImport
  38. Messages []Message
  39. Enums []Enum
  40. Extensions []Extension
  41. Services []Service
  42. *fileMeta
  43. }
  44. // NewFile creates a new protoreflect.FileDescriptor from the provided value.
  45. // The file must represent a valid proto file according to protobuf semantics.
  46. //
  47. // Fields that reference an enum or message that is being declared within the
  48. // same File can be represented using a placeholder descriptor. NewFile will
  49. // automatically resolve the placeholder to point to the concrete type.
  50. //
  51. // The caller must relinquish full ownership of the input t and must not
  52. // access or mutate any fields. The input must not contain slices that are
  53. // sub-slices of each other.
  54. func NewFile(t *File) (protoreflect.FileDescriptor, error) {
  55. // TODO: Provide an unverified make that avoids validating the file.
  56. // This is useful for generated code since we know that protoc-gen-go
  57. // already validated the protobuf types.
  58. ft := newFile(t)
  59. if err := validateFile(ft); err != nil {
  60. return nil, err
  61. }
  62. return ft, nil
  63. }
  64. // Message is a constructor for protoreflect.MessageDescriptor.
  65. type Message struct {
  66. Name protoreflect.Name
  67. IsMapEntry bool
  68. Fields []Field
  69. Oneofs []Oneof
  70. ExtensionRanges [][2]protoreflect.FieldNumber
  71. Messages []Message
  72. Enums []Enum
  73. Extensions []Extension
  74. *messageMeta
  75. }
  76. // Field is a constructor for protoreflect.FieldDescriptor.
  77. type Field struct {
  78. Name protoreflect.Name
  79. Number protoreflect.FieldNumber
  80. Cardinality protoreflect.Cardinality
  81. Kind protoreflect.Kind
  82. JSONName string
  83. IsPacked bool
  84. IsWeak bool
  85. Default protoreflect.Value
  86. OneofName protoreflect.Name
  87. MessageType protoreflect.MessageDescriptor
  88. EnumType protoreflect.EnumDescriptor
  89. *fieldMeta
  90. }
  91. // Oneof is a constructor for protoreflect.OneofDescriptor.
  92. type Oneof struct {
  93. Name protoreflect.Name
  94. *oneofMeta
  95. }
  96. // Extension is a constructor for protoreflect.ExtensionDescriptor.
  97. type Extension struct {
  98. Name protoreflect.Name
  99. Number protoreflect.FieldNumber
  100. Cardinality protoreflect.Cardinality
  101. Kind protoreflect.Kind
  102. IsPacked bool
  103. Default protoreflect.Value
  104. MessageType protoreflect.MessageDescriptor
  105. EnumType protoreflect.EnumDescriptor
  106. ExtendedType protoreflect.MessageDescriptor
  107. *extensionMeta
  108. }
  109. // Enum is a constructor for protoreflect.EnumDescriptor.
  110. type Enum struct {
  111. Name protoreflect.Name
  112. Values []EnumValue
  113. *enumMeta
  114. }
  115. // EnumValue is a constructor for protoreflect.EnumValueDescriptor.
  116. type EnumValue struct {
  117. Name protoreflect.Name
  118. Number protoreflect.EnumNumber
  119. *enumValueMeta
  120. }
  121. // Service is a constructor for protoreflect.ServiceDescriptor.
  122. type Service struct {
  123. Name protoreflect.Name
  124. Methods []Method
  125. *serviceMeta
  126. }
  127. // Method is a constructor for protoreflect.MethodDescriptor.
  128. type Method struct {
  129. Name protoreflect.Name
  130. InputType protoreflect.MessageDescriptor
  131. OutputType protoreflect.MessageDescriptor
  132. IsStreamingClient bool
  133. IsStreamingServer bool
  134. *methodMeta
  135. }