.examples
.github
alerting
client
config
controller
core
docs
jsonpath
metrics
pattern
security
storage
test
util
vendor
github.com
golang.org
google.golang.org
appengine
protobuf
encoding
internal
descfmt
descopts
detrand
encoding
errors
filedesc
filetype
flags
genid
impl
api_export.go
checkinit.go
codec_extension.go
codec_field.go
codec_gen.go
codec_map.go
codec_map_go111.go
codec_map_go112.go
codec_message.go
codec_messageset.go
codec_reflect.go
codec_tables.go
codec_unsafe.go
convert.go
convert_list.go
convert_map.go
decode.go
encode.go
enum.go
extension.go
legacy_enum.go
legacy_export.go
legacy_extension.go
legacy_file.go
legacy_message.go
merge.go
merge_gen.go
message.go
message_reflect.go
message_reflect_field.go
message_reflect_gen.go
pointer_reflect.go
pointer_unsafe.go
validate.go
weak.go
order
pragma
set
strs
version
proto
reflect
runtime
types
LICENSE
PATENTS
gopkg.in
lukechampine.com
modernc.org
modules.txt
watchdog
web
.dockerignore
.gitattributes
.gitignore
Dockerfile
LICENSE
Makefile
README.md
config.yaml
go.mod
go.sum
main.go
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.11.0 to 1.13.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.11.0...v1.13.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
142 lines
3.5 KiB
Go
142 lines
3.5 KiB
Go
// Copyright 2019 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 impl
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"google.golang.org/protobuf/internal/errors"
|
|
"google.golang.org/protobuf/reflect/protoreflect"
|
|
"google.golang.org/protobuf/runtime/protoiface"
|
|
)
|
|
|
|
func (mi *MessageInfo) checkInitialized(in protoiface.CheckInitializedInput) (protoiface.CheckInitializedOutput, error) {
|
|
var p pointer
|
|
if ms, ok := in.Message.(*messageState); ok {
|
|
p = ms.pointer()
|
|
} else {
|
|
p = in.Message.(*messageReflectWrapper).pointer()
|
|
}
|
|
return protoiface.CheckInitializedOutput{}, mi.checkInitializedPointer(p)
|
|
}
|
|
|
|
func (mi *MessageInfo) checkInitializedPointer(p pointer) error {
|
|
mi.init()
|
|
if !mi.needsInitCheck {
|
|
return nil
|
|
}
|
|
if p.IsNil() {
|
|
for _, f := range mi.orderedCoderFields {
|
|
if f.isRequired {
|
|
return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
if mi.extensionOffset.IsValid() {
|
|
e := p.Apply(mi.extensionOffset).Extensions()
|
|
if err := mi.isInitExtensions(e); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
for _, f := range mi.orderedCoderFields {
|
|
if !f.isRequired && f.funcs.isInit == nil {
|
|
continue
|
|
}
|
|
fptr := p.Apply(f.offset)
|
|
if f.isPointer && fptr.Elem().IsNil() {
|
|
if f.isRequired {
|
|
return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
|
|
}
|
|
continue
|
|
}
|
|
if f.funcs.isInit == nil {
|
|
continue
|
|
}
|
|
if err := f.funcs.isInit(fptr, f); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (mi *MessageInfo) isInitExtensions(ext *map[int32]ExtensionField) error {
|
|
if ext == nil {
|
|
return nil
|
|
}
|
|
for _, x := range *ext {
|
|
ei := getExtensionFieldInfo(x.Type())
|
|
if ei.funcs.isInit == nil {
|
|
continue
|
|
}
|
|
v := x.Value()
|
|
if !v.IsValid() {
|
|
continue
|
|
}
|
|
if err := ei.funcs.isInit(v); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
needsInitCheckMu sync.Mutex
|
|
needsInitCheckMap sync.Map
|
|
)
|
|
|
|
// needsInitCheck reports whether a message needs to be checked for partial initialization.
|
|
//
|
|
// It returns true if the message transitively includes any required or extension fields.
|
|
func needsInitCheck(md protoreflect.MessageDescriptor) bool {
|
|
if v, ok := needsInitCheckMap.Load(md); ok {
|
|
if has, ok := v.(bool); ok {
|
|
return has
|
|
}
|
|
}
|
|
needsInitCheckMu.Lock()
|
|
defer needsInitCheckMu.Unlock()
|
|
return needsInitCheckLocked(md)
|
|
}
|
|
|
|
func needsInitCheckLocked(md protoreflect.MessageDescriptor) (has bool) {
|
|
if v, ok := needsInitCheckMap.Load(md); ok {
|
|
// If has is true, we've previously determined that this message
|
|
// needs init checks.
|
|
//
|
|
// If has is false, we've previously determined that it can never
|
|
// be uninitialized.
|
|
//
|
|
// If has is not a bool, we've just encountered a cycle in the
|
|
// message graph. In this case, it is safe to return false: If
|
|
// the message does have required fields, we'll detect them later
|
|
// in the graph traversal.
|
|
has, ok := v.(bool)
|
|
return ok && has
|
|
}
|
|
needsInitCheckMap.Store(md, struct{}{}) // avoid cycles while descending into this message
|
|
defer func() {
|
|
needsInitCheckMap.Store(md, has)
|
|
}()
|
|
if md.RequiredNumbers().Len() > 0 {
|
|
return true
|
|
}
|
|
if md.ExtensionRanges().Len() > 0 {
|
|
return true
|
|
}
|
|
for i := 0; i < md.Fields().Len(); i++ {
|
|
fd := md.Fields().Get(i)
|
|
// Map keys are never messages, so just consider the map value.
|
|
if fd.IsMap() {
|
|
fd = fd.MapValue()
|
|
}
|
|
fmd := fd.Message()
|
|
if fmd != nil && needsInitCheckLocked(fmd) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|