// Copyright 2018 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.

// Code generated by generate-types. DO NOT EDIT.

package impl

import (
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/runtime/protoiface"
)

func (m *messageState) Descriptor() protoreflect.MessageDescriptor {
	return m.mi.PBType.Descriptor()
}
func (m *messageState) Type() protoreflect.MessageType {
	return m.mi.PBType
}
func (m *messageState) New() protoreflect.Message {
	return m.mi.PBType.New()
}
func (m *messageState) Interface() protoreflect.ProtoMessage {
	return m.ProtoUnwrap().(protoreflect.ProtoMessage)
}
func (m *messageState) ProtoUnwrap() interface{} {
	return m.pointer().AsIfaceOf(m.mi.GoType.Elem())
}
func (m *messageState) ProtoMethods() *protoiface.Methods {
	m.mi.init()
	return &m.mi.methods
}

func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
	m.mi.init()
	for _, fi := range m.mi.fields {
		if fi.has(m.pointer()) {
			if !f(fi.fieldDesc, fi.get(m.pointer())) {
				return
			}
		}
	}
	m.mi.extensionMap(m.pointer()).Range(f)
}
func (m *messageState) Has(fd protoreflect.FieldDescriptor) bool {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		return fi.has(m.pointer())
	} else {
		return m.mi.extensionMap(m.pointer()).Has(xt)
	}
}
func (m *messageState) Clear(fd protoreflect.FieldDescriptor) {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		fi.clear(m.pointer())
	} else {
		m.mi.extensionMap(m.pointer()).Clear(xt)
	}
}
func (m *messageState) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		return fi.get(m.pointer())
	} else {
		return m.mi.extensionMap(m.pointer()).Get(xt)
	}
}
func (m *messageState) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		fi.set(m.pointer(), v)
	} else {
		m.mi.extensionMap(m.pointer()).Set(xt, v)
	}
}
func (m *messageState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		return fi.mutable(m.pointer())
	} else {
		return m.mi.extensionMap(m.pointer()).Mutable(xt)
	}
}
func (m *messageState) NewMessage(fd protoreflect.FieldDescriptor) protoreflect.Message {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		return fi.newMessage()
	} else {
		return xt.New().Message()
	}
}
func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
	m.mi.init()
	if oi := m.mi.oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
		return od.Fields().ByNumber(oi.which(m.pointer()))
	}
	panic("invalid oneof descriptor")
}
func (m *messageState) GetUnknown() protoreflect.RawFields {
	m.mi.init()
	return m.mi.getUnknown(m.pointer())
}
func (m *messageState) SetUnknown(b protoreflect.RawFields) {
	m.mi.init()
	m.mi.setUnknown(m.pointer(), b)
}

func (m *messageReflectWrapper) Descriptor() protoreflect.MessageDescriptor {
	return m.mi.PBType.Descriptor()
}
func (m *messageReflectWrapper) Type() protoreflect.MessageType {
	return m.mi.PBType
}
func (m *messageReflectWrapper) New() protoreflect.Message {
	return m.mi.PBType.New()
}
func (m *messageReflectWrapper) Interface() protoreflect.ProtoMessage {
	if m, ok := m.ProtoUnwrap().(protoreflect.ProtoMessage); ok {
		return m
	}
	return (*messageIfaceWrapper)(m)
}
func (m *messageReflectWrapper) ProtoUnwrap() interface{} {
	return m.pointer().AsIfaceOf(m.mi.GoType.Elem())
}
func (m *messageReflectWrapper) ProtoMethods() *protoiface.Methods {
	m.mi.init()
	return &m.mi.methods
}

func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
	m.mi.init()
	for _, fi := range m.mi.fields {
		if fi.has(m.pointer()) {
			if !f(fi.fieldDesc, fi.get(m.pointer())) {
				return
			}
		}
	}
	m.mi.extensionMap(m.pointer()).Range(f)
}
func (m *messageReflectWrapper) Has(fd protoreflect.FieldDescriptor) bool {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		return fi.has(m.pointer())
	} else {
		return m.mi.extensionMap(m.pointer()).Has(xt)
	}
}
func (m *messageReflectWrapper) Clear(fd protoreflect.FieldDescriptor) {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		fi.clear(m.pointer())
	} else {
		m.mi.extensionMap(m.pointer()).Clear(xt)
	}
}
func (m *messageReflectWrapper) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		return fi.get(m.pointer())
	} else {
		return m.mi.extensionMap(m.pointer()).Get(xt)
	}
}
func (m *messageReflectWrapper) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		fi.set(m.pointer(), v)
	} else {
		m.mi.extensionMap(m.pointer()).Set(xt, v)
	}
}
func (m *messageReflectWrapper) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		return fi.mutable(m.pointer())
	} else {
		return m.mi.extensionMap(m.pointer()).Mutable(xt)
	}
}
func (m *messageReflectWrapper) NewMessage(fd protoreflect.FieldDescriptor) protoreflect.Message {
	m.mi.init()
	if fi, xt := m.mi.checkField(fd); fi != nil {
		return fi.newMessage()
	} else {
		return xt.New().Message()
	}
}
func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
	m.mi.init()
	if oi := m.mi.oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
		return od.Fields().ByNumber(oi.which(m.pointer()))
	}
	panic("invalid oneof descriptor")
}
func (m *messageReflectWrapper) GetUnknown() protoreflect.RawFields {
	m.mi.init()
	return m.mi.getUnknown(m.pointer())
}
func (m *messageReflectWrapper) SetUnknown(b protoreflect.RawFields) {
	m.mi.init()
	m.mi.setUnknown(m.pointer(), b)
}
