vendor/google.golang.org/protobuf/internal/filetype/build.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
     8 
     8 
     9 import (
     9 import (
    10 	"reflect"
    10 	"reflect"
    11 
    11 
    12 	"google.golang.org/protobuf/internal/descopts"
    12 	"google.golang.org/protobuf/internal/descopts"
    13 	fdesc "google.golang.org/protobuf/internal/filedesc"
    13 	"google.golang.org/protobuf/internal/filedesc"
    14 	pimpl "google.golang.org/protobuf/internal/impl"
    14 	pimpl "google.golang.org/protobuf/internal/impl"
    15 	pref "google.golang.org/protobuf/reflect/protoreflect"
    15 	"google.golang.org/protobuf/reflect/protoreflect"
    16 	preg "google.golang.org/protobuf/reflect/protoregistry"
    16 	"google.golang.org/protobuf/reflect/protoregistry"
    17 )
    17 )
    18 
    18 
    19 // Builder constructs type descriptors from a raw file descriptor
    19 // Builder constructs type descriptors from a raw file descriptor
    20 // and associated Go types for each enum and message declaration.
    20 // and associated Go types for each enum and message declaration.
    21 //
    21 //
    22 //
    22 // # Flattened Ordering
    23 // Flattened Ordering
       
    24 //
    23 //
    25 // The protobuf type system represents declarations as a tree. Certain nodes in
    24 // The protobuf type system represents declarations as a tree. Certain nodes in
    26 // the tree require us to either associate it with a concrete Go type or to
    25 // the tree require us to either associate it with a concrete Go type or to
    27 // resolve a dependency, which is information that must be provided separately
    26 // resolve a dependency, which is information that must be provided separately
    28 // since it cannot be derived from the file descriptor alone.
    27 // since it cannot be derived from the file descriptor alone.
    50 // The traversal starts at the root file descriptor and yields each direct
    49 // The traversal starts at the root file descriptor and yields each direct
    51 // declaration within each node before traversing into sub-declarations
    50 // declaration within each node before traversing into sub-declarations
    52 // that children themselves may have.
    51 // that children themselves may have.
    53 type Builder struct {
    52 type Builder struct {
    54 	// File is the underlying file descriptor builder.
    53 	// File is the underlying file descriptor builder.
    55 	File fdesc.Builder
    54 	File filedesc.Builder
    56 
    55 
    57 	// GoTypes is a unique set of the Go types for all declarations and
    56 	// GoTypes is a unique set of the Go types for all declarations and
    58 	// dependencies. Each type is represented as a zero value of the Go type.
    57 	// dependencies. Each type is represented as a zero value of the Go type.
    59 	//
    58 	//
    60 	// Declarations are Go types generated for enums and messages directly
    59 	// Declarations are Go types generated for enums and messages directly
   106 	ExtensionInfos []pimpl.ExtensionInfo
   105 	ExtensionInfos []pimpl.ExtensionInfo
   107 
   106 
   108 	// TypeRegistry is the registry to register each type descriptor.
   107 	// TypeRegistry is the registry to register each type descriptor.
   109 	// If nil, it uses protoregistry.GlobalTypes.
   108 	// If nil, it uses protoregistry.GlobalTypes.
   110 	TypeRegistry interface {
   109 	TypeRegistry interface {
   111 		RegisterMessage(pref.MessageType) error
   110 		RegisterMessage(protoreflect.MessageType) error
   112 		RegisterEnum(pref.EnumType) error
   111 		RegisterEnum(protoreflect.EnumType) error
   113 		RegisterExtension(pref.ExtensionType) error
   112 		RegisterExtension(protoreflect.ExtensionType) error
   114 	}
   113 	}
   115 }
   114 }
   116 
   115 
   117 // Out is the output of the builder.
   116 // Out is the output of the builder.
   118 type Out struct {
   117 type Out struct {
   119 	File pref.FileDescriptor
   118 	File protoreflect.FileDescriptor
   120 }
   119 }
   121 
   120 
   122 func (tb Builder) Build() (out Out) {
   121 func (tb Builder) Build() (out Out) {
   123 	// Replace the resolver with one that resolves dependencies by index,
   122 	// Replace the resolver with one that resolves dependencies by index,
   124 	// which is faster and more reliable than relying on the global registry.
   123 	// which is faster and more reliable than relying on the global registry.
   125 	if tb.File.FileRegistry == nil {
   124 	if tb.File.FileRegistry == nil {
   126 		tb.File.FileRegistry = preg.GlobalFiles
   125 		tb.File.FileRegistry = protoregistry.GlobalFiles
   127 	}
   126 	}
   128 	tb.File.FileRegistry = &resolverByIndex{
   127 	tb.File.FileRegistry = &resolverByIndex{
   129 		goTypes:      tb.GoTypes,
   128 		goTypes:      tb.GoTypes,
   130 		depIdxs:      tb.DependencyIndexes,
   129 		depIdxs:      tb.DependencyIndexes,
   131 		fileRegistry: tb.File.FileRegistry,
   130 		fileRegistry: tb.File.FileRegistry,
   132 	}
   131 	}
   133 
   132 
   134 	// Initialize registry if unpopulated.
   133 	// Initialize registry if unpopulated.
   135 	if tb.TypeRegistry == nil {
   134 	if tb.TypeRegistry == nil {
   136 		tb.TypeRegistry = preg.GlobalTypes
   135 		tb.TypeRegistry = protoregistry.GlobalTypes
   137 	}
   136 	}
   138 
   137 
   139 	fbOut := tb.File.Build()
   138 	fbOut := tb.File.Build()
   140 	out.File = fbOut.File
   139 	out.File = fbOut.File
   141 
   140 
   181 		// locally register concrete message type for the options.
   180 		// locally register concrete message type for the options.
   182 		if out.File.Path() == "google/protobuf/descriptor.proto" && out.File.Package() == "google.protobuf" {
   181 		if out.File.Path() == "google/protobuf/descriptor.proto" && out.File.Package() == "google.protobuf" {
   183 			for i := range fbOut.Messages {
   182 			for i := range fbOut.Messages {
   184 				switch fbOut.Messages[i].Name() {
   183 				switch fbOut.Messages[i].Name() {
   185 				case "FileOptions":
   184 				case "FileOptions":
   186 					descopts.File = messageGoTypes[i].(pref.ProtoMessage)
   185 					descopts.File = messageGoTypes[i].(protoreflect.ProtoMessage)
   187 				case "EnumOptions":
   186 				case "EnumOptions":
   188 					descopts.Enum = messageGoTypes[i].(pref.ProtoMessage)
   187 					descopts.Enum = messageGoTypes[i].(protoreflect.ProtoMessage)
   189 				case "EnumValueOptions":
   188 				case "EnumValueOptions":
   190 					descopts.EnumValue = messageGoTypes[i].(pref.ProtoMessage)
   189 					descopts.EnumValue = messageGoTypes[i].(protoreflect.ProtoMessage)
   191 				case "MessageOptions":
   190 				case "MessageOptions":
   192 					descopts.Message = messageGoTypes[i].(pref.ProtoMessage)
   191 					descopts.Message = messageGoTypes[i].(protoreflect.ProtoMessage)
   193 				case "FieldOptions":
   192 				case "FieldOptions":
   194 					descopts.Field = messageGoTypes[i].(pref.ProtoMessage)
   193 					descopts.Field = messageGoTypes[i].(protoreflect.ProtoMessage)
   195 				case "OneofOptions":
   194 				case "OneofOptions":
   196 					descopts.Oneof = messageGoTypes[i].(pref.ProtoMessage)
   195 					descopts.Oneof = messageGoTypes[i].(protoreflect.ProtoMessage)
   197 				case "ExtensionRangeOptions":
   196 				case "ExtensionRangeOptions":
   198 					descopts.ExtensionRange = messageGoTypes[i].(pref.ProtoMessage)
   197 					descopts.ExtensionRange = messageGoTypes[i].(protoreflect.ProtoMessage)
   199 				case "ServiceOptions":
   198 				case "ServiceOptions":
   200 					descopts.Service = messageGoTypes[i].(pref.ProtoMessage)
   199 					descopts.Service = messageGoTypes[i].(protoreflect.ProtoMessage)
   201 				case "MethodOptions":
   200 				case "MethodOptions":
   202 					descopts.Method = messageGoTypes[i].(pref.ProtoMessage)
   201 					descopts.Method = messageGoTypes[i].(protoreflect.ProtoMessage)
   203 				}
   202 				}
   204 			}
   203 			}
   205 		}
   204 		}
   206 	}
   205 	}
   207 
   206 
   214 		// For enum and message kinds, determine the referent Go type so
   213 		// For enum and message kinds, determine the referent Go type so
   215 		// that we can construct their constructors.
   214 		// that we can construct their constructors.
   216 		const listExtDeps = 2
   215 		const listExtDeps = 2
   217 		var goType reflect.Type
   216 		var goType reflect.Type
   218 		switch fbOut.Extensions[i].L1.Kind {
   217 		switch fbOut.Extensions[i].L1.Kind {
   219 		case pref.EnumKind:
   218 		case protoreflect.EnumKind:
   220 			j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
   219 			j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
   221 			goType = reflect.TypeOf(tb.GoTypes[j])
   220 			goType = reflect.TypeOf(tb.GoTypes[j])
   222 			depIdx++
   221 			depIdx++
   223 		case pref.MessageKind, pref.GroupKind:
   222 		case protoreflect.MessageKind, protoreflect.GroupKind:
   224 			j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
   223 			j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx)
   225 			goType = reflect.TypeOf(tb.GoTypes[j])
   224 			goType = reflect.TypeOf(tb.GoTypes[j])
   226 			depIdx++
   225 			depIdx++
   227 		default:
   226 		default:
   228 			goType = goTypeForPBKind[fbOut.Extensions[i].L1.Kind]
   227 			goType = goTypeForPBKind[fbOut.Extensions[i].L1.Kind]
   240 	}
   239 	}
   241 
   240 
   242 	return out
   241 	return out
   243 }
   242 }
   244 
   243 
   245 var goTypeForPBKind = map[pref.Kind]reflect.Type{
   244 var goTypeForPBKind = map[protoreflect.Kind]reflect.Type{
   246 	pref.BoolKind:     reflect.TypeOf(bool(false)),
   245 	protoreflect.BoolKind:     reflect.TypeOf(bool(false)),
   247 	pref.Int32Kind:    reflect.TypeOf(int32(0)),
   246 	protoreflect.Int32Kind:    reflect.TypeOf(int32(0)),
   248 	pref.Sint32Kind:   reflect.TypeOf(int32(0)),
   247 	protoreflect.Sint32Kind:   reflect.TypeOf(int32(0)),
   249 	pref.Sfixed32Kind: reflect.TypeOf(int32(0)),
   248 	protoreflect.Sfixed32Kind: reflect.TypeOf(int32(0)),
   250 	pref.Int64Kind:    reflect.TypeOf(int64(0)),
   249 	protoreflect.Int64Kind:    reflect.TypeOf(int64(0)),
   251 	pref.Sint64Kind:   reflect.TypeOf(int64(0)),
   250 	protoreflect.Sint64Kind:   reflect.TypeOf(int64(0)),
   252 	pref.Sfixed64Kind: reflect.TypeOf(int64(0)),
   251 	protoreflect.Sfixed64Kind: reflect.TypeOf(int64(0)),
   253 	pref.Uint32Kind:   reflect.TypeOf(uint32(0)),
   252 	protoreflect.Uint32Kind:   reflect.TypeOf(uint32(0)),
   254 	pref.Fixed32Kind:  reflect.TypeOf(uint32(0)),
   253 	protoreflect.Fixed32Kind:  reflect.TypeOf(uint32(0)),
   255 	pref.Uint64Kind:   reflect.TypeOf(uint64(0)),
   254 	protoreflect.Uint64Kind:   reflect.TypeOf(uint64(0)),
   256 	pref.Fixed64Kind:  reflect.TypeOf(uint64(0)),
   255 	protoreflect.Fixed64Kind:  reflect.TypeOf(uint64(0)),
   257 	pref.FloatKind:    reflect.TypeOf(float32(0)),
   256 	protoreflect.FloatKind:    reflect.TypeOf(float32(0)),
   258 	pref.DoubleKind:   reflect.TypeOf(float64(0)),
   257 	protoreflect.DoubleKind:   reflect.TypeOf(float64(0)),
   259 	pref.StringKind:   reflect.TypeOf(string("")),
   258 	protoreflect.StringKind:   reflect.TypeOf(string("")),
   260 	pref.BytesKind:    reflect.TypeOf([]byte(nil)),
   259 	protoreflect.BytesKind:    reflect.TypeOf([]byte(nil)),
   261 }
   260 }
   262 
   261 
   263 type depIdxs []int32
   262 type depIdxs []int32
   264 
   263 
   265 // Get retrieves the jth element of the ith sub-list.
   264 // Get retrieves the jth element of the ith sub-list.
   272 		goTypes []interface{}
   271 		goTypes []interface{}
   273 		depIdxs depIdxs
   272 		depIdxs depIdxs
   274 		fileRegistry
   273 		fileRegistry
   275 	}
   274 	}
   276 	fileRegistry interface {
   275 	fileRegistry interface {
   277 		FindFileByPath(string) (pref.FileDescriptor, error)
   276 		FindFileByPath(string) (protoreflect.FileDescriptor, error)
   278 		FindDescriptorByName(pref.FullName) (pref.Descriptor, error)
   277 		FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
   279 		RegisterFile(pref.FileDescriptor) error
   278 		RegisterFile(protoreflect.FileDescriptor) error
   280 	}
   279 	}
   281 )
   280 )
   282 
   281 
   283 func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []fdesc.Enum, ms []fdesc.Message) pref.EnumDescriptor {
   282 func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []filedesc.Enum, ms []filedesc.Message) protoreflect.EnumDescriptor {
   284 	if depIdx := int(r.depIdxs.Get(i, j)); int(depIdx) < len(es)+len(ms) {
   283 	if depIdx := int(r.depIdxs.Get(i, j)); int(depIdx) < len(es)+len(ms) {
   285 		return &es[depIdx]
   284 		return &es[depIdx]
   286 	} else {
   285 	} else {
   287 		return pimpl.Export{}.EnumDescriptorOf(r.goTypes[depIdx])
   286 		return pimpl.Export{}.EnumDescriptorOf(r.goTypes[depIdx])
   288 	}
   287 	}
   289 }
   288 }
   290 
   289 
   291 func (r *resolverByIndex) FindMessageByIndex(i, j int32, es []fdesc.Enum, ms []fdesc.Message) pref.MessageDescriptor {
   290 func (r *resolverByIndex) FindMessageByIndex(i, j int32, es []filedesc.Enum, ms []filedesc.Message) protoreflect.MessageDescriptor {
   292 	if depIdx := int(r.depIdxs.Get(i, j)); depIdx < len(es)+len(ms) {
   291 	if depIdx := int(r.depIdxs.Get(i, j)); depIdx < len(es)+len(ms) {
   293 		return &ms[depIdx-len(es)]
   292 		return &ms[depIdx-len(es)]
   294 	} else {
   293 	} else {
   295 		return pimpl.Export{}.MessageDescriptorOf(r.goTypes[depIdx])
   294 		return pimpl.Export{}.MessageDescriptorOf(r.goTypes[depIdx])
   296 	}
   295 	}