First implementation
This commit is contained in:
		
							
								
								
									
										89
									
								
								vendor/google.golang.org/protobuf/internal/order/order.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								vendor/google.golang.org/protobuf/internal/order/order.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
// Copyright 2020 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package order
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	pref "google.golang.org/protobuf/reflect/protoreflect"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// FieldOrder specifies the ordering to visit message fields.
 | 
			
		||||
// It is a function that reports whether x is ordered before y.
 | 
			
		||||
type FieldOrder func(x, y pref.FieldDescriptor) bool
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// AnyFieldOrder specifies no specific field ordering.
 | 
			
		||||
	AnyFieldOrder FieldOrder = nil
 | 
			
		||||
 | 
			
		||||
	// LegacyFieldOrder sorts fields in the same ordering as emitted by
 | 
			
		||||
	// wire serialization in the github.com/golang/protobuf implementation.
 | 
			
		||||
	LegacyFieldOrder FieldOrder = func(x, y pref.FieldDescriptor) bool {
 | 
			
		||||
		ox, oy := x.ContainingOneof(), y.ContainingOneof()
 | 
			
		||||
		inOneof := func(od pref.OneofDescriptor) bool {
 | 
			
		||||
			return od != nil && !od.IsSynthetic()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Extension fields sort before non-extension fields.
 | 
			
		||||
		if x.IsExtension() != y.IsExtension() {
 | 
			
		||||
			return x.IsExtension() && !y.IsExtension()
 | 
			
		||||
		}
 | 
			
		||||
		// Fields not within a oneof sort before those within a oneof.
 | 
			
		||||
		if inOneof(ox) != inOneof(oy) {
 | 
			
		||||
			return !inOneof(ox) && inOneof(oy)
 | 
			
		||||
		}
 | 
			
		||||
		// Fields in disjoint oneof sets are sorted by declaration index.
 | 
			
		||||
		if ox != nil && oy != nil && ox != oy {
 | 
			
		||||
			return ox.Index() < oy.Index()
 | 
			
		||||
		}
 | 
			
		||||
		// Fields sorted by field number.
 | 
			
		||||
		return x.Number() < y.Number()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// NumberFieldOrder sorts fields by their field number.
 | 
			
		||||
	NumberFieldOrder FieldOrder = func(x, y pref.FieldDescriptor) bool {
 | 
			
		||||
		return x.Number() < y.Number()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// IndexNameFieldOrder sorts non-extension fields before extension fields.
 | 
			
		||||
	// Non-extensions are sorted according to their declaration index.
 | 
			
		||||
	// Extensions are sorted according to their full name.
 | 
			
		||||
	IndexNameFieldOrder FieldOrder = func(x, y pref.FieldDescriptor) bool {
 | 
			
		||||
		// Non-extension fields sort before extension fields.
 | 
			
		||||
		if x.IsExtension() != y.IsExtension() {
 | 
			
		||||
			return !x.IsExtension() && y.IsExtension()
 | 
			
		||||
		}
 | 
			
		||||
		// Extensions sorted by fullname.
 | 
			
		||||
		if x.IsExtension() && y.IsExtension() {
 | 
			
		||||
			return x.FullName() < y.FullName()
 | 
			
		||||
		}
 | 
			
		||||
		// Non-extensions sorted by declaration index.
 | 
			
		||||
		return x.Index() < y.Index()
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// KeyOrder specifies the ordering to visit map entries.
 | 
			
		||||
// It is a function that reports whether x is ordered before y.
 | 
			
		||||
type KeyOrder func(x, y pref.MapKey) bool
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// AnyKeyOrder specifies no specific key ordering.
 | 
			
		||||
	AnyKeyOrder KeyOrder = nil
 | 
			
		||||
 | 
			
		||||
	// GenericKeyOrder sorts false before true, numeric keys in ascending order,
 | 
			
		||||
	// and strings in lexicographical ordering according to UTF-8 codepoints.
 | 
			
		||||
	GenericKeyOrder KeyOrder = func(x, y pref.MapKey) bool {
 | 
			
		||||
		switch x.Interface().(type) {
 | 
			
		||||
		case bool:
 | 
			
		||||
			return !x.Bool() && y.Bool()
 | 
			
		||||
		case int32, int64:
 | 
			
		||||
			return x.Int() < y.Int()
 | 
			
		||||
		case uint32, uint64:
 | 
			
		||||
			return x.Uint() < y.Uint()
 | 
			
		||||
		case string:
 | 
			
		||||
			return x.String() < y.String()
 | 
			
		||||
		default:
 | 
			
		||||
			panic("invalid map key type")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										115
									
								
								vendor/google.golang.org/protobuf/internal/order/range.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								vendor/google.golang.org/protobuf/internal/order/range.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
// Copyright 2020 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package order provides ordered access to messages and maps.
 | 
			
		||||
package order
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	pref "google.golang.org/protobuf/reflect/protoreflect"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type messageField struct {
 | 
			
		||||
	fd pref.FieldDescriptor
 | 
			
		||||
	v  pref.Value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var messageFieldPool = sync.Pool{
 | 
			
		||||
	New: func() interface{} { return new([]messageField) },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// FieldRnger is an interface for visiting all fields in a message.
 | 
			
		||||
	// The protoreflect.Message type implements this interface.
 | 
			
		||||
	FieldRanger interface{ Range(VisitField) }
 | 
			
		||||
	// VisitField is called everytime a message field is visited.
 | 
			
		||||
	VisitField = func(pref.FieldDescriptor, pref.Value) bool
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// RangeFields iterates over the fields of fs according to the specified order.
 | 
			
		||||
func RangeFields(fs FieldRanger, less FieldOrder, fn VisitField) {
 | 
			
		||||
	if less == nil {
 | 
			
		||||
		fs.Range(fn)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Obtain a pre-allocated scratch buffer.
 | 
			
		||||
	p := messageFieldPool.Get().(*[]messageField)
 | 
			
		||||
	fields := (*p)[:0]
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if cap(fields) < 1024 {
 | 
			
		||||
			*p = fields
 | 
			
		||||
			messageFieldPool.Put(p)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	// Collect all fields in the message and sort them.
 | 
			
		||||
	fs.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
 | 
			
		||||
		fields = append(fields, messageField{fd, v})
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
	sort.Slice(fields, func(i, j int) bool {
 | 
			
		||||
		return less(fields[i].fd, fields[j].fd)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// Visit the fields in the specified ordering.
 | 
			
		||||
	for _, f := range fields {
 | 
			
		||||
		if !fn(f.fd, f.v) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mapEntry struct {
 | 
			
		||||
	k pref.MapKey
 | 
			
		||||
	v pref.Value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var mapEntryPool = sync.Pool{
 | 
			
		||||
	New: func() interface{} { return new([]mapEntry) },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// EntryRanger is an interface for visiting all fields in a message.
 | 
			
		||||
	// The protoreflect.Map type implements this interface.
 | 
			
		||||
	EntryRanger interface{ Range(VisitEntry) }
 | 
			
		||||
	// VisitEntry is called everytime a map entry is visited.
 | 
			
		||||
	VisitEntry = func(pref.MapKey, pref.Value) bool
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// RangeEntries iterates over the entries of es according to the specified order.
 | 
			
		||||
func RangeEntries(es EntryRanger, less KeyOrder, fn VisitEntry) {
 | 
			
		||||
	if less == nil {
 | 
			
		||||
		es.Range(fn)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Obtain a pre-allocated scratch buffer.
 | 
			
		||||
	p := mapEntryPool.Get().(*[]mapEntry)
 | 
			
		||||
	entries := (*p)[:0]
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if cap(entries) < 1024 {
 | 
			
		||||
			*p = entries
 | 
			
		||||
			mapEntryPool.Put(p)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	// Collect all entries in the map and sort them.
 | 
			
		||||
	es.Range(func(k pref.MapKey, v pref.Value) bool {
 | 
			
		||||
		entries = append(entries, mapEntry{k, v})
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
	sort.Slice(entries, func(i, j int) bool {
 | 
			
		||||
		return less(entries[i].k, entries[j].k)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// Visit the entries in the specified ordering.
 | 
			
		||||
	for _, e := range entries {
 | 
			
		||||
		if !fn(e.k, e.v) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user