xref: /aosp_15_r20/external/golang-protobuf/internal/order/order.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
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