blob: 55c5481f41d1ad7234b3a56b4c93df43f1ee4395 [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 Tsai6663f3a2019-09-03 15:33:00 -07008 "fmt"
Joe Tsai0fc49f82019-05-01 12:29:25 -07009 "reflect"
Joe Tsai8e506a82019-03-16 00:05:34 -070010 "strconv"
11
Damien Neil5c5b5312019-05-14 12:44:37 -070012 "google.golang.org/protobuf/encoding/prototext"
Joe Tsai6663f3a2019-09-03 15:33:00 -070013 "google.golang.org/protobuf/proto"
14 "google.golang.org/protobuf/reflect/protoreflect"
Damien Neile89e6242019-05-13 23:55:40 -070015 pref "google.golang.org/protobuf/reflect/protoreflect"
Joe Tsai6663f3a2019-09-03 15:33:00 -070016 piface "google.golang.org/protobuf/runtime/protoiface"
Joe Tsai08e00302018-11-26 22:32:06 -080017)
18
19// Export is a zero-length named type that exists only to export a set of
20// functions that we do not want to appear in godoc.
21type Export struct{}
22
Joe Tsai0fc49f82019-05-01 12:29:25 -070023// enum is any enum type generated by protoc-gen-go
24// and must be a named int32 type.
25type enum = interface{}
26
Joe Tsai08e00302018-11-26 22:32:06 -080027// EnumOf returns the protoreflect.Enum interface over e.
Joe Tsai0fc49f82019-05-01 12:29:25 -070028func (Export) EnumOf(e enum) pref.Enum {
Damien Neila8593ba2019-01-08 16:18:07 -080029 if ev, ok := e.(pref.Enum); ok {
30 return ev
Joe Tsai08e00302018-11-26 22:32:06 -080031 }
Joe Tsai21ade492019-05-22 13:42:54 -040032 return legacyWrapEnum(reflect.ValueOf(e))
Joe Tsai08e00302018-11-26 22:32:06 -080033}
34
Joe Tsai0fc49f82019-05-01 12:29:25 -070035// EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
36func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor {
37 if ev, ok := e.(pref.Enum); ok {
38 return ev.Descriptor()
39 }
Joe Tsai21ade492019-05-22 13:42:54 -040040 return LegacyLoadEnumDesc(reflect.TypeOf(e))
Joe Tsai0fc49f82019-05-01 12:29:25 -070041}
42
Joe Tsai6663f3a2019-09-03 15:33:00 -070043// EnumTypeOf returns the protoreflect.EnumType for e.
44func (Export) EnumTypeOf(e enum) pref.EnumType {
45 if ev, ok := e.(pref.Enum); ok {
46 return ev.Type()
47 }
48 return legacyLoadEnumType(reflect.TypeOf(e))
49}
50
Joe Tsai8e506a82019-03-16 00:05:34 -070051// EnumStringOf returns the enum value as a string, either as the name if
52// the number is resolvable, or the number formatted as a string.
53func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string {
54 ev := ed.Values().ByNumber(n)
55 if ev != nil {
56 return string(ev.Name())
57 }
58 return strconv.Itoa(int(n))
59}
60
Joe Tsai0fc49f82019-05-01 12:29:25 -070061// message is any message type generated by protoc-gen-go
62// and must be a pointer to a named struct type.
63type message = interface{}
64
Joe Tsai6663f3a2019-09-03 15:33:00 -070065// legacyMessageWrapper wraps a v2 message as a v1 message.
66type legacyMessageWrapper struct{ m protoreflect.ProtoMessage }
67
68func (m legacyMessageWrapper) Reset() { proto.Reset(m.m) }
69func (m legacyMessageWrapper) String() string { return Export{}.MessageStringOf(m.m) }
70func (m legacyMessageWrapper) ProtoMessage() {}
71
72// ProtoMessageV1Of converts either a v1 or v2 message to a v1 message.
73func (Export) ProtoMessageV1Of(m message) piface.MessageV1 {
74 switch mv := m.(type) {
75 case piface.MessageV1:
76 return mv
77 case Unwrapper:
78 return Export{}.ProtoMessageV1Of(mv.ProtoUnwrap())
79 case protoreflect.ProtoMessage:
80 return legacyMessageWrapper{mv}
81 default:
82 panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
Joe Tsai08e00302018-11-26 22:32:06 -080083 }
Joe Tsai08e00302018-11-26 22:32:06 -080084}
85
Joe Tsai6663f3a2019-09-03 15:33:00 -070086// ProtoMessageV2Of converts either a v1 or v2 message to a v2 message.
87func (Export) ProtoMessageV2Of(m message) pref.ProtoMessage {
88 switch mv := m.(type) {
89 case protoreflect.ProtoMessage:
90 return mv
91 case legacyMessageWrapper:
92 return mv.m
93 case piface.MessageV1:
94 return legacyWrapMessage(reflect.ValueOf(mv))
95 default:
96 panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
Joe Tsai08e00302018-11-26 22:32:06 -080097 }
Joe Tsai6663f3a2019-09-03 15:33:00 -070098}
99
100// MessageOf returns the protoreflect.Message interface over m.
101func (Export) MessageOf(m message) pref.Message {
102 switch mv := m.(type) {
103 case pref.ProtoMessage:
104 return mv.ProtoReflect()
105 case legacyMessageWrapper:
106 return mv.m.ProtoReflect()
107 case piface.MessageV1:
108 return legacyWrapMessage(reflect.ValueOf(mv)).ProtoReflect()
109 default:
110 panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
111 }
Joe Tsai08e00302018-11-26 22:32:06 -0800112}
113
Joe Tsai0fc49f82019-05-01 12:29:25 -0700114// MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
115func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor {
Joe Tsai6663f3a2019-09-03 15:33:00 -0700116 switch mv := m.(type) {
117 case pref.ProtoMessage:
Joe Tsai0fc49f82019-05-01 12:29:25 -0700118 return mv.ProtoReflect().Descriptor()
Joe Tsai6663f3a2019-09-03 15:33:00 -0700119 case legacyMessageWrapper:
120 return mv.m.ProtoReflect().Descriptor()
121 case piface.MessageV1:
122 return LegacyLoadMessageDesc(reflect.TypeOf(mv))
123 default:
124 panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
Joe Tsai08e00302018-11-26 22:32:06 -0800125 }
Joe Tsai6663f3a2019-09-03 15:33:00 -0700126}
127
128// MessageTypeOf returns the protoreflect.MessageType for m.
129func (Export) MessageTypeOf(m message) pref.MessageType {
130 switch mv := m.(type) {
131 case pref.ProtoMessage:
132 return mv.ProtoReflect().Type()
133 case legacyMessageWrapper:
134 return mv.m.ProtoReflect().Type()
135 case piface.MessageV1:
136 return legacyLoadMessageInfo(reflect.TypeOf(mv))
137 default:
138 panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m))
139 }
Joe Tsai08e00302018-11-26 22:32:06 -0800140}
Joe Tsai1321a0e2019-03-20 09:46:22 -0700141
142// MessageStringOf returns the message value as a string,
143// which is the message serialized in the protobuf text format.
144func (Export) MessageStringOf(m pref.ProtoMessage) string {
Damien Neil5c5b5312019-05-14 12:44:37 -0700145 b, _ := prototext.MarshalOptions{AllowPartial: true}.Marshal(m)
Joe Tsai1321a0e2019-03-20 09:46:22 -0700146 return string(b)
147}
Joe Tsai21ade492019-05-22 13:42:54 -0400148
Damien Neilf1e905b2019-08-08 15:45:59 -0700149// ExtensionDescFromType returns the legacy protoV1.ExtensionDesc for t.
150func (Export) ExtensionDescFromType(t pref.ExtensionType) *ExtensionInfo {
Joe Tsai21ade492019-05-22 13:42:54 -0400151 return legacyExtensionDescFromType(t)
152}