...

Source file src/google.golang.org/protobuf/testing/protocmp/reflect.go

Documentation: google.golang.org/protobuf/testing/protocmp

     1  // Copyright 2020 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  
     5  package protocmp
     6  
     7  import (
     8  	"reflect"
     9  	"sort"
    10  	"strconv"
    11  	"strings"
    12  
    13  	"google.golang.org/protobuf/internal/genid"
    14  	"google.golang.org/protobuf/proto"
    15  	"google.golang.org/protobuf/reflect/protoreflect"
    16  	"google.golang.org/protobuf/runtime/protoiface"
    17  )
    18  
    19  func reflectValueOf(v interface{}) protoreflect.Value {
    20  	switch v := v.(type) {
    21  	case Enum:
    22  		return protoreflect.ValueOfEnum(v.Number())
    23  	case Message:
    24  		return protoreflect.ValueOfMessage(v.ProtoReflect())
    25  	case []byte:
    26  		return protoreflect.ValueOfBytes(v) // avoid overlap with reflect.Slice check below
    27  	default:
    28  		switch rv := reflect.ValueOf(v); {
    29  		case rv.Kind() == reflect.Slice:
    30  			return protoreflect.ValueOfList(reflectList{rv})
    31  		case rv.Kind() == reflect.Map:
    32  			return protoreflect.ValueOfMap(reflectMap{rv})
    33  		default:
    34  			return protoreflect.ValueOf(v)
    35  		}
    36  	}
    37  }
    38  
    39  type reflectMessage Message
    40  
    41  func (m reflectMessage) stringKey(fd protoreflect.FieldDescriptor) string {
    42  	if m.Descriptor() != fd.ContainingMessage() {
    43  		panic("mismatching containing message")
    44  	}
    45  	return fd.TextName()
    46  }
    47  
    48  func (m reflectMessage) Descriptor() protoreflect.MessageDescriptor {
    49  	return (Message)(m).Descriptor()
    50  }
    51  func (m reflectMessage) Type() protoreflect.MessageType {
    52  	return reflectMessageType{m.Descriptor()}
    53  }
    54  func (m reflectMessage) New() protoreflect.Message {
    55  	return m.Type().New()
    56  }
    57  func (m reflectMessage) Interface() protoreflect.ProtoMessage {
    58  	return Message(m)
    59  }
    60  func (m reflectMessage) Range(f func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool) {
    61  	// Range over populated known fields.
    62  	fds := m.Descriptor().Fields()
    63  	for i := 0; i < fds.Len(); i++ {
    64  		fd := fds.Get(i)
    65  		if m.Has(fd) && !f(fd, m.Get(fd)) {
    66  			return
    67  		}
    68  	}
    69  
    70  	// Range over populated extension fields.
    71  	for _, xd := range m[messageTypeKey].(messageMeta).xds {
    72  		if m.Has(xd) && !f(xd, m.Get(xd)) {
    73  			return
    74  		}
    75  	}
    76  }
    77  func (m reflectMessage) Has(fd protoreflect.FieldDescriptor) bool {
    78  	_, ok := m[m.stringKey(fd)]
    79  	return ok
    80  }
    81  func (m reflectMessage) Clear(protoreflect.FieldDescriptor) {
    82  	panic("invalid mutation of read-only message")
    83  }
    84  func (m reflectMessage) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
    85  	v, ok := m[m.stringKey(fd)]
    86  	if !ok {
    87  		switch {
    88  		case fd.IsList():
    89  			return protoreflect.ValueOfList(reflectList{})
    90  		case fd.IsMap():
    91  			return protoreflect.ValueOfMap(reflectMap{})
    92  		case fd.Message() != nil:
    93  			return protoreflect.ValueOfMessage(reflectMessage{
    94  				messageTypeKey: messageMeta{md: fd.Message()},
    95  			})
    96  		default:
    97  			return fd.Default()
    98  		}
    99  	}
   100  
   101  	// The transformation may leave Any messages in structured form.
   102  	// If so, convert them back to a raw-encoded form.
   103  	if fd.FullName() == genid.Any_Value_field_fullname {
   104  		if m, ok := v.(Message); ok {
   105  			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
   106  			if err != nil {
   107  				panic("BUG: " + err.Error())
   108  			}
   109  			return protoreflect.ValueOfBytes(b)
   110  		}
   111  	}
   112  
   113  	return reflectValueOf(v)
   114  }
   115  func (m reflectMessage) Set(protoreflect.FieldDescriptor, protoreflect.Value) {
   116  	panic("invalid mutation of read-only message")
   117  }
   118  func (m reflectMessage) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
   119  	panic("invalid mutation of read-only message")
   120  }
   121  func (m reflectMessage) NewField(protoreflect.FieldDescriptor) protoreflect.Value {
   122  	panic("not implemented")
   123  }
   124  func (m reflectMessage) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
   125  	if m.Descriptor().Oneofs().ByName(od.Name()) != od {
   126  		panic("oneof descriptor does not belong to this message")
   127  	}
   128  	fds := od.Fields()
   129  	for i := 0; i < fds.Len(); i++ {
   130  		fd := fds.Get(i)
   131  		if _, ok := m[m.stringKey(fd)]; ok {
   132  			return fd
   133  		}
   134  	}
   135  	return nil
   136  }
   137  func (m reflectMessage) GetUnknown() protoreflect.RawFields {
   138  	var nums []protoreflect.FieldNumber
   139  	for k := range m {
   140  		if len(strings.Trim(k, "0123456789")) == 0 {
   141  			n, _ := strconv.ParseUint(k, 10, 32)
   142  			nums = append(nums, protoreflect.FieldNumber(n))
   143  		}
   144  	}
   145  	sort.Slice(nums, func(i, j int) bool { return nums[i] < nums[j] })
   146  
   147  	var raw protoreflect.RawFields
   148  	for _, num := range nums {
   149  		b, _ := m[strconv.FormatUint(uint64(num), 10)].(protoreflect.RawFields)
   150  		raw = append(raw, b...)
   151  	}
   152  	return raw
   153  }
   154  func (m reflectMessage) SetUnknown(protoreflect.RawFields) {
   155  	panic("invalid mutation of read-only message")
   156  }
   157  func (m reflectMessage) IsValid() bool {
   158  	invalid, _ := m[messageInvalidKey].(bool)
   159  	return !invalid
   160  }
   161  func (m reflectMessage) ProtoMethods() *protoiface.Methods {
   162  	return nil
   163  }
   164  
   165  type reflectMessageType struct{ protoreflect.MessageDescriptor }
   166  
   167  func (t reflectMessageType) New() protoreflect.Message {
   168  	panic("not implemented")
   169  }
   170  func (t reflectMessageType) Zero() protoreflect.Message {
   171  	panic("not implemented")
   172  }
   173  func (t reflectMessageType) Descriptor() protoreflect.MessageDescriptor {
   174  	return t.MessageDescriptor
   175  }
   176  
   177  type reflectList struct{ v reflect.Value }
   178  
   179  func (ls reflectList) Len() int {
   180  	if !ls.IsValid() {
   181  		return 0
   182  	}
   183  	return ls.v.Len()
   184  }
   185  func (ls reflectList) Get(i int) protoreflect.Value {
   186  	return reflectValueOf(ls.v.Index(i).Interface())
   187  }
   188  func (ls reflectList) Set(int, protoreflect.Value) {
   189  	panic("invalid mutation of read-only list")
   190  }
   191  func (ls reflectList) Append(protoreflect.Value) {
   192  	panic("invalid mutation of read-only list")
   193  }
   194  func (ls reflectList) AppendMutable() protoreflect.Value {
   195  	panic("invalid mutation of read-only list")
   196  }
   197  func (ls reflectList) Truncate(int) {
   198  	panic("invalid mutation of read-only list")
   199  }
   200  func (ls reflectList) NewElement() protoreflect.Value {
   201  	panic("not implemented")
   202  }
   203  func (ls reflectList) IsValid() bool {
   204  	return ls.v.IsValid()
   205  }
   206  
   207  type reflectMap struct{ v reflect.Value }
   208  
   209  func (ms reflectMap) Len() int {
   210  	if !ms.IsValid() {
   211  		return 0
   212  	}
   213  	return ms.v.Len()
   214  }
   215  func (ms reflectMap) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) {
   216  	if !ms.IsValid() {
   217  		return
   218  	}
   219  	ks := ms.v.MapKeys()
   220  	for _, k := range ks {
   221  		pk := reflectValueOf(k.Interface()).MapKey()
   222  		pv := reflectValueOf(ms.v.MapIndex(k).Interface())
   223  		if !f(pk, pv) {
   224  			return
   225  		}
   226  	}
   227  }
   228  func (ms reflectMap) Has(k protoreflect.MapKey) bool {
   229  	if !ms.IsValid() {
   230  		return false
   231  	}
   232  	return ms.v.MapIndex(reflect.ValueOf(k.Interface())).IsValid()
   233  }
   234  func (ms reflectMap) Clear(protoreflect.MapKey) {
   235  	panic("invalid mutation of read-only list")
   236  }
   237  func (ms reflectMap) Get(k protoreflect.MapKey) protoreflect.Value {
   238  	if !ms.IsValid() {
   239  		return protoreflect.Value{}
   240  	}
   241  	v := ms.v.MapIndex(reflect.ValueOf(k.Interface()))
   242  	if !v.IsValid() {
   243  		return protoreflect.Value{}
   244  	}
   245  	return reflectValueOf(v.Interface())
   246  }
   247  func (ms reflectMap) Set(protoreflect.MapKey, protoreflect.Value) {
   248  	panic("invalid mutation of read-only list")
   249  }
   250  func (ms reflectMap) Mutable(k protoreflect.MapKey) protoreflect.Value {
   251  	panic("invalid mutation of read-only list")
   252  }
   253  func (ms reflectMap) NewValue() protoreflect.Value {
   254  	panic("not implemented")
   255  }
   256  func (ms reflectMap) IsValid() bool {
   257  	return ms.v.IsValid()
   258  }
   259  

View as plain text