blob: d031d17a197542335506e25a914c74e9fecaab55 [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 impl
6
7import (
Joe Tsai0fc49f82019-05-01 12:29:25 -07008 "reflect"
Joe Tsai8e506a82019-03-16 00:05:34 -07009 "strconv"
10
Damien Neil5c5b5312019-05-14 12:44:37 -070011 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070012 pref "google.golang.org/protobuf/reflect/protoreflect"
Joe Tsaib2f66be2019-05-22 00:42:45 -040013 "google.golang.org/protobuf/reflect/prototype"
Joe Tsai21ade492019-05-22 13:42:54 -040014 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 Tsai0fc49f82019-05-01 12:29:25 -070021// enum is any enum type generated by protoc-gen-go
22// and must be a named int32 type.
23type enum = interface{}
24
Joe Tsai08e00302018-11-26 22:32:06 -080025// EnumOf returns the protoreflect.Enum interface over e.
Joe Tsai0fc49f82019-05-01 12:29:25 -070026func (Export) EnumOf(e enum) pref.Enum {
Damien Neila8593ba2019-01-08 16:18:07 -080027 if ev, ok := e.(pref.Enum); ok {
28 return ev
Joe Tsai08e00302018-11-26 22:32:06 -080029 }
Joe Tsai21ade492019-05-22 13:42:54 -040030 return legacyWrapEnum(reflect.ValueOf(e))
Joe Tsai08e00302018-11-26 22:32:06 -080031}
32
33// EnumTypeOf returns the protoreflect.EnumType for e.
Joe Tsai0fc49f82019-05-01 12:29:25 -070034func (Export) EnumTypeOf(e enum) pref.EnumType {
Damien Neila8593ba2019-01-08 16:18:07 -080035 if ev, ok := e.(pref.Enum); ok {
Joe Tsaib2f66be2019-05-22 00:42:45 -040036 return &prototype.Enum{
37 EnumDescriptor: ev.Descriptor(),
38 NewEnum: func(n pref.EnumNumber) pref.Enum {
39 return reflect.ValueOf(n).Convert(reflect.TypeOf(e)).Interface().(pref.Enum)
40 },
41 }
Joe Tsai08e00302018-11-26 22:32:06 -080042 }
Joe Tsai21ade492019-05-22 13:42:54 -040043 return legacyLoadEnumType(reflect.TypeOf(e))
Joe Tsai08e00302018-11-26 22:32:06 -080044}
45
Joe Tsai0fc49f82019-05-01 12:29:25 -070046// EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
47func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor {
48 if ev, ok := e.(pref.Enum); ok {
49 return ev.Descriptor()
50 }
Joe Tsai21ade492019-05-22 13:42:54 -040051 return LegacyLoadEnumDesc(reflect.TypeOf(e))
Joe Tsai0fc49f82019-05-01 12:29:25 -070052}
53
Joe Tsai8e506a82019-03-16 00:05:34 -070054// EnumStringOf returns the enum value as a string, either as the name if
55// the number is resolvable, or the number formatted as a string.
56func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string {
57 ev := ed.Values().ByNumber(n)
58 if ev != nil {
59 return string(ev.Name())
60 }
61 return strconv.Itoa(int(n))
62}
63
Joe Tsai0fc49f82019-05-01 12:29:25 -070064// message is any message type generated by protoc-gen-go
65// and must be a pointer to a named struct type.
66type message = interface{}
67
Joe Tsai08e00302018-11-26 22:32:06 -080068// MessageOf returns the protoreflect.Message interface over m.
Joe Tsai0fc49f82019-05-01 12:29:25 -070069func (Export) MessageOf(m message) pref.Message {
Joe Tsai08e00302018-11-26 22:32:06 -080070 if mv, ok := m.(pref.ProtoMessage); ok {
71 return mv.ProtoReflect()
72 }
Joe Tsai21ade492019-05-22 13:42:54 -040073 return legacyWrapMessage(reflect.ValueOf(m)).ProtoReflect()
Joe Tsai08e00302018-11-26 22:32:06 -080074}
75
76// MessageTypeOf returns the protoreflect.MessageType for m.
Joe Tsai0fc49f82019-05-01 12:29:25 -070077func (Export) MessageTypeOf(m message) pref.MessageType {
Joe Tsai08e00302018-11-26 22:32:06 -080078 if mv, ok := m.(pref.ProtoMessage); ok {
Joe Tsaib2f66be2019-05-22 00:42:45 -040079 return &prototype.Message{
80 MessageDescriptor: mv.ProtoReflect().Descriptor(),
81 NewMessage: func() pref.Message {
82 return reflect.New(reflect.TypeOf(m).Elem()).Interface().(pref.ProtoMessage).ProtoReflect()
83 },
84 }
Joe Tsai08e00302018-11-26 22:32:06 -080085 }
Joe Tsai21ade492019-05-22 13:42:54 -040086 return legacyLoadMessageInfo(reflect.TypeOf(m)).PBType
Joe Tsai08e00302018-11-26 22:32:06 -080087}
88
Joe Tsai0fc49f82019-05-01 12:29:25 -070089// MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
90func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor {
91 if mv, ok := m.(pref.ProtoMessage); ok {
92 return mv.ProtoReflect().Descriptor()
Joe Tsai08e00302018-11-26 22:32:06 -080093 }
Joe Tsai21ade492019-05-22 13:42:54 -040094 return LegacyLoadMessageDesc(reflect.TypeOf(m))
Joe Tsai08e00302018-11-26 22:32:06 -080095}
Joe Tsai1321a0e2019-03-20 09:46:22 -070096
97// MessageStringOf returns the message value as a string,
98// which is the message serialized in the protobuf text format.
99func (Export) MessageStringOf(m pref.ProtoMessage) string {
Damien Neil5c5b5312019-05-14 12:44:37 -0700100 b, _ := prototext.MarshalOptions{AllowPartial: true}.Marshal(m)
Joe Tsai1321a0e2019-03-20 09:46:22 -0700101 return string(b)
102}
Joe Tsai21ade492019-05-22 13:42:54 -0400103
104// ExtensionDescFromType returns the legacy protoiface.ExtensionDescV1 for t.
105func (Export) ExtensionDescFromType(t pref.ExtensionType) *piface.ExtensionDescV1 {
106 return legacyExtensionDescFromType(t)
107}
108
109// ExtensionTypeFromDesc returns the v2 protoreflect.ExtensionType for d.
110func (Export) ExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
111 return legacyExtensionTypeFromDesc(d)
112}