blob: 701b578d920d57e74a1d71047522fd4397bbaab0 [file] [log] [blame]
Joe Tsai08e00302018-11-26 22:32:06 -08001// 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
5package legacy
6
7import (
Joe Tsaib2f66be2019-05-22 00:42:45 -04008 "fmt"
Joe Tsai08e00302018-11-26 22:32:06 -08009 "reflect"
10
Damien Neile89e6242019-05-13 23:55:40 -070011 pimpl "google.golang.org/protobuf/internal/impl"
12 pvalue "google.golang.org/protobuf/internal/value"
13 pref "google.golang.org/protobuf/reflect/protoreflect"
14 piface "google.golang.org/protobuf/runtime/protoiface"
Joe Tsai08e00302018-11-26 22:32:06 -080015)
16
17// Export is a zero-length named type that exists only to export a set of
18// functions that we do not want to appear in godoc.
19type Export struct{}
20
Joe Tsaib2f66be2019-05-22 00:42:45 -040021func (Export) EnumOf(e interface{}) pref.Enum {
22 return wrapEnum(reflect.ValueOf(e))
Joe Tsai08e00302018-11-26 22:32:06 -080023}
24
25func (Export) EnumTypeOf(e interface{}) pref.EnumType {
Joe Tsai6dbffb72018-12-04 14:06:19 -080026 return loadEnumType(reflect.TypeOf(e))
Joe Tsai08e00302018-11-26 22:32:06 -080027}
28
Joe Tsai0fc49f82019-05-01 12:29:25 -070029func (Export) EnumDescriptorOf(e interface{}) pref.EnumDescriptor {
30 return LoadEnumDesc(reflect.TypeOf(e))
31}
32
Joe Tsaib2f66be2019-05-22 00:42:45 -040033func (Export) MessageOf(m interface{}) pref.Message {
34 return wrapMessage(reflect.ValueOf(m)).ProtoReflect()
Joe Tsai08e00302018-11-26 22:32:06 -080035}
36
37func (Export) MessageTypeOf(m interface{}) pref.MessageType {
Joe Tsai4fe96632019-05-22 05:12:36 -040038 return loadMessageInfo(reflect.TypeOf(m)).PBType
Joe Tsai08e00302018-11-26 22:32:06 -080039}
40
Joe Tsai0fc49f82019-05-01 12:29:25 -070041func (Export) MessageDescriptorOf(m interface{}) pref.MessageDescriptor {
42 return LoadMessageDesc(reflect.TypeOf(m))
Joe Tsai08e00302018-11-26 22:32:06 -080043}
44
Joe Tsai4fddeba2019-03-20 18:29:32 -070045func (Export) ExtensionDescFromType(t pref.ExtensionType) *piface.ExtensionDescV1 {
Joe Tsai6dbffb72018-12-04 14:06:19 -080046 return extensionDescFromType(t)
Joe Tsai08e00302018-11-26 22:32:06 -080047}
48
Joe Tsai4fddeba2019-03-20 18:29:32 -070049func (Export) ExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
Joe Tsai6dbffb72018-12-04 14:06:19 -080050 return extensionTypeFromDesc(d)
Joe Tsai08e00302018-11-26 22:32:06 -080051}
52
Joe Tsaib2f66be2019-05-22 00:42:45 -040053var (
54 enumIfaceV2 = reflect.TypeOf((*pref.Enum)(nil)).Elem()
55 messageIfaceV1 = reflect.TypeOf((*piface.MessageV1)(nil)).Elem()
56 messageIfaceV2 = reflect.TypeOf((*pref.ProtoMessage)(nil)).Elem()
57)
58
59func (Export) NewConverter(t reflect.Type, k pref.Kind) pvalue.Converter {
60 c, _ := newConverter(t, k)
61 return c
62}
63
64func newConverter(t reflect.Type, k pref.Kind) (pvalue.Converter, bool) {
65 switch k {
66 case pref.EnumKind:
67 if t.Kind() == reflect.Int32 && !t.Implements(enumIfaceV2) {
68 return pvalue.Converter{
69 PBValueOf: func(v reflect.Value) pref.Value {
70 if v.Type() != t {
71 panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
72 }
73 return pref.ValueOf(pref.EnumNumber(v.Int()))
74 },
75 GoValueOf: func(v pref.Value) reflect.Value {
76 return reflect.ValueOf(v.Enum()).Convert(t)
77 },
78 NewEnum: func(n pref.EnumNumber) pref.Enum {
79 return wrapEnum(reflect.ValueOf(n).Convert(t))
80 },
81 }, true
82 }
83 case pref.MessageKind, pref.GroupKind:
84 if t.Kind() == reflect.Ptr && t.Implements(messageIfaceV1) && !t.Implements(messageIfaceV2) {
85 return pvalue.Converter{
86 PBValueOf: func(v reflect.Value) pref.Value {
87 if v.Type() != t {
88 panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
89 }
90 return pref.ValueOf(Export{}.MessageOf(v.Interface()))
91 },
92 GoValueOf: func(v pref.Value) reflect.Value {
93 rv := reflect.ValueOf(v.Message().(pvalue.Unwrapper).ProtoUnwrap())
94 if rv.Type() != t {
95 panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), t))
96 }
97 return rv
98 },
99 NewMessage: func() pref.Message {
100 return wrapMessage(reflect.New(t.Elem())).ProtoReflect()
101 },
102 }, true
103 }
104 }
105 return pvalue.NewConverter(t, k), false
106}
107
Joe Tsai08e00302018-11-26 22:32:06 -0800108func init() {
109 pimpl.RegisterLegacyWrapper(Export{})
110}