1*1c12ee1eSDan Willemsen// Copyright 2020 The Go Authors. All rights reserved. 2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style 3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file. 4*1c12ee1eSDan Willemsen 5*1c12ee1eSDan Willemsenpackage order 6*1c12ee1eSDan Willemsen 7*1c12ee1eSDan Willemsenimport ( 8*1c12ee1eSDan Willemsen "google.golang.org/protobuf/reflect/protoreflect" 9*1c12ee1eSDan Willemsen) 10*1c12ee1eSDan Willemsen 11*1c12ee1eSDan Willemsen// FieldOrder specifies the ordering to visit message fields. 12*1c12ee1eSDan Willemsen// It is a function that reports whether x is ordered before y. 13*1c12ee1eSDan Willemsentype FieldOrder func(x, y protoreflect.FieldDescriptor) bool 14*1c12ee1eSDan Willemsen 15*1c12ee1eSDan Willemsenvar ( 16*1c12ee1eSDan Willemsen // AnyFieldOrder specifies no specific field ordering. 17*1c12ee1eSDan Willemsen AnyFieldOrder FieldOrder = nil 18*1c12ee1eSDan Willemsen 19*1c12ee1eSDan Willemsen // LegacyFieldOrder sorts fields in the same ordering as emitted by 20*1c12ee1eSDan Willemsen // wire serialization in the github.com/golang/protobuf implementation. 21*1c12ee1eSDan Willemsen LegacyFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool { 22*1c12ee1eSDan Willemsen ox, oy := x.ContainingOneof(), y.ContainingOneof() 23*1c12ee1eSDan Willemsen inOneof := func(od protoreflect.OneofDescriptor) bool { 24*1c12ee1eSDan Willemsen return od != nil && !od.IsSynthetic() 25*1c12ee1eSDan Willemsen } 26*1c12ee1eSDan Willemsen 27*1c12ee1eSDan Willemsen // Extension fields sort before non-extension fields. 28*1c12ee1eSDan Willemsen if x.IsExtension() != y.IsExtension() { 29*1c12ee1eSDan Willemsen return x.IsExtension() && !y.IsExtension() 30*1c12ee1eSDan Willemsen } 31*1c12ee1eSDan Willemsen // Fields not within a oneof sort before those within a oneof. 32*1c12ee1eSDan Willemsen if inOneof(ox) != inOneof(oy) { 33*1c12ee1eSDan Willemsen return !inOneof(ox) && inOneof(oy) 34*1c12ee1eSDan Willemsen } 35*1c12ee1eSDan Willemsen // Fields in disjoint oneof sets are sorted by declaration index. 36*1c12ee1eSDan Willemsen if ox != nil && oy != nil && ox != oy { 37*1c12ee1eSDan Willemsen return ox.Index() < oy.Index() 38*1c12ee1eSDan Willemsen } 39*1c12ee1eSDan Willemsen // Fields sorted by field number. 40*1c12ee1eSDan Willemsen return x.Number() < y.Number() 41*1c12ee1eSDan Willemsen } 42*1c12ee1eSDan Willemsen 43*1c12ee1eSDan Willemsen // NumberFieldOrder sorts fields by their field number. 44*1c12ee1eSDan Willemsen NumberFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool { 45*1c12ee1eSDan Willemsen return x.Number() < y.Number() 46*1c12ee1eSDan Willemsen } 47*1c12ee1eSDan Willemsen 48*1c12ee1eSDan Willemsen // IndexNameFieldOrder sorts non-extension fields before extension fields. 49*1c12ee1eSDan Willemsen // Non-extensions are sorted according to their declaration index. 50*1c12ee1eSDan Willemsen // Extensions are sorted according to their full name. 51*1c12ee1eSDan Willemsen IndexNameFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool { 52*1c12ee1eSDan Willemsen // Non-extension fields sort before extension fields. 53*1c12ee1eSDan Willemsen if x.IsExtension() != y.IsExtension() { 54*1c12ee1eSDan Willemsen return !x.IsExtension() && y.IsExtension() 55*1c12ee1eSDan Willemsen } 56*1c12ee1eSDan Willemsen // Extensions sorted by fullname. 57*1c12ee1eSDan Willemsen if x.IsExtension() && y.IsExtension() { 58*1c12ee1eSDan Willemsen return x.FullName() < y.FullName() 59*1c12ee1eSDan Willemsen } 60*1c12ee1eSDan Willemsen // Non-extensions sorted by declaration index. 61*1c12ee1eSDan Willemsen return x.Index() < y.Index() 62*1c12ee1eSDan Willemsen } 63*1c12ee1eSDan Willemsen) 64*1c12ee1eSDan Willemsen 65*1c12ee1eSDan Willemsen// KeyOrder specifies the ordering to visit map entries. 66*1c12ee1eSDan Willemsen// It is a function that reports whether x is ordered before y. 67*1c12ee1eSDan Willemsentype KeyOrder func(x, y protoreflect.MapKey) bool 68*1c12ee1eSDan Willemsen 69*1c12ee1eSDan Willemsenvar ( 70*1c12ee1eSDan Willemsen // AnyKeyOrder specifies no specific key ordering. 71*1c12ee1eSDan Willemsen AnyKeyOrder KeyOrder = nil 72*1c12ee1eSDan Willemsen 73*1c12ee1eSDan Willemsen // GenericKeyOrder sorts false before true, numeric keys in ascending order, 74*1c12ee1eSDan Willemsen // and strings in lexicographical ordering according to UTF-8 codepoints. 75*1c12ee1eSDan Willemsen GenericKeyOrder KeyOrder = func(x, y protoreflect.MapKey) bool { 76*1c12ee1eSDan Willemsen switch x.Interface().(type) { 77*1c12ee1eSDan Willemsen case bool: 78*1c12ee1eSDan Willemsen return !x.Bool() && y.Bool() 79*1c12ee1eSDan Willemsen case int32, int64: 80*1c12ee1eSDan Willemsen return x.Int() < y.Int() 81*1c12ee1eSDan Willemsen case uint32, uint64: 82*1c12ee1eSDan Willemsen return x.Uint() < y.Uint() 83*1c12ee1eSDan Willemsen case string: 84*1c12ee1eSDan Willemsen return x.String() < y.String() 85*1c12ee1eSDan Willemsen default: 86*1c12ee1eSDan Willemsen panic("invalid map key type") 87*1c12ee1eSDan Willemsen } 88*1c12ee1eSDan Willemsen } 89*1c12ee1eSDan Willemsen) 90