blob: 21ba412d1f3016998f83aedd6d8e0665fa9a1b40 [file] [log] [blame]
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package prototype provides builders to construct protobuf types that
// implement the interfaces defined in the protoreflect package.
//
// Protobuf types can either be constructed as standalone types
// (e.g., StandaloneMessage), or together as a batch of types in a single
// proto file (e.g., File). When creating standalone types, additional
// information must be provided such as the full type name and the proto syntax.
// When creating an entire file, the syntax and full name is derived from
// the parent type.
package prototype
import (
"github.com/golang/protobuf/v2/reflect/protoreflect"
)
// Every struct has a "meta" struct embedded within it as a pointer.
// The meta type provides additional data structures for efficient lookup on
// certain methods (e.g., ByName) or derived information that can be
// derived from the parent (e.g., FullName). The meta type is lazily allocated
// and initialized. This architectural approach keeps the literal representation
// smaller, which then keeps the generated code size smaller.
// TODO: Instead of a top-down construction approach where internal references
// to message types use placeholder types, we could add a Reference method
// on Message and Enum that creates a MessageDescriptor or EnumDescriptor
// reference that only becomes valid after NewFile.
// However, that API approach is more error prone, as it causes more memory
// aliasing and provides more opportunity for misuse.
// Also, it requires that NewFile at least eagerly initialize all
// messages and enums list types. We can always add that API in the future.
// File is a constructor for protoreflect.FileDescriptor.
type File struct {
Syntax protoreflect.Syntax
Path string
Package protoreflect.FullName
Imports []protoreflect.FileImport
Messages []Message
Enums []Enum
Extensions []Extension
Services []Service
*fileMeta
}
// NewFile creates a new protoreflect.FileDescriptor from the provided value.
// The file must represent a valid proto file according to protobuf semantics.
//
// Fields that reference an enum or message that is being declared within the
// same File can be represented using a placeholder descriptor. NewFile will
// automatically resolve the placeholder to point to the concrete type.
//
// The caller must relinquish full ownership of the input t and must not
// access or mutate any fields. The input must not contain slices that are
// sub-slices of each other.
func NewFile(t *File) (protoreflect.FileDescriptor, error) {
// TODO: Provide an unverified make that avoids validating the file.
// This is useful for generated code since we know that protoc-gen-go
// already validated the protobuf types.
ft := newFile(t)
if err := validateFile(ft); err != nil {
return nil, err
}
return ft, nil
}
// Message is a constructor for protoreflect.MessageDescriptor.
type Message struct {
Name protoreflect.Name
IsMapEntry bool
Fields []Field
Oneofs []Oneof
ExtensionRanges [][2]protoreflect.FieldNumber
Messages []Message
Enums []Enum
Extensions []Extension
*messageMeta
}
// Field is a constructor for protoreflect.FieldDescriptor.
type Field struct {
Name protoreflect.Name
Number protoreflect.FieldNumber
Cardinality protoreflect.Cardinality
Kind protoreflect.Kind
JSONName string
IsPacked bool
IsWeak bool
Default protoreflect.Value
OneofName protoreflect.Name
MessageType protoreflect.MessageDescriptor
EnumType protoreflect.EnumDescriptor
*fieldMeta
}
// Oneof is a constructor for protoreflect.OneofDescriptor.
type Oneof struct {
Name protoreflect.Name
*oneofMeta
}
// Extension is a constructor for protoreflect.ExtensionDescriptor.
type Extension struct {
Name protoreflect.Name
Number protoreflect.FieldNumber
Cardinality protoreflect.Cardinality
Kind protoreflect.Kind
IsPacked bool
Default protoreflect.Value
MessageType protoreflect.MessageDescriptor
EnumType protoreflect.EnumDescriptor
ExtendedType protoreflect.MessageDescriptor
*extensionMeta
}
// Enum is a constructor for protoreflect.EnumDescriptor.
type Enum struct {
Name protoreflect.Name
Values []EnumValue
*enumMeta
}
// EnumValue is a constructor for protoreflect.EnumValueDescriptor.
type EnumValue struct {
Name protoreflect.Name
Number protoreflect.EnumNumber
*enumValueMeta
}
// Service is a constructor for protoreflect.ServiceDescriptor.
type Service struct {
Name protoreflect.Name
Methods []Method
*serviceMeta
}
// Method is a constructor for protoreflect.MethodDescriptor.
type Method struct {
Name protoreflect.Name
InputType protoreflect.MessageDescriptor
OutputType protoreflect.MessageDescriptor
IsStreamingClient bool
IsStreamingServer bool
*methodMeta
}