// Code generated by gotdgen, DO NOT EDIT.

package tg

import (
	"context"
	"errors"
	"fmt"
	"sort"
	"strings"

	"go.uber.org/multierr"

	"github.com/gotd/td/bin"
	"github.com/gotd/td/tdjson"
	"github.com/gotd/td/tdp"
	"github.com/gotd/td/tgerr"
)

// No-op definition for keeping imports.
var (
	_ = bin.Buffer{}
	_ = context.Background()
	_ = fmt.Stringer(nil)
	_ = strings.Builder{}
	_ = errors.Is
	_ = multierr.AppendInto
	_ = sort.Ints
	_ = tdp.Format
	_ = tgerr.Error{}
	_ = tdjson.Encoder{}
)

// DocumentAttributeImageSize represents TL type `documentAttributeImageSize#6c37c15c`.
// Defines the width and height of an image uploaded as document
//
// See https://core.telegram.org/constructor/documentAttributeImageSize for reference.
type DocumentAttributeImageSize struct {
	// Width of image
	W int
	// Height of image
	H int
}

// DocumentAttributeImageSizeTypeID is TL type id of DocumentAttributeImageSize.
const DocumentAttributeImageSizeTypeID = 0x6c37c15c

// construct implements constructor of DocumentAttributeClass.
func (d DocumentAttributeImageSize) construct() DocumentAttributeClass { return &d }

// Ensuring interfaces in compile-time for DocumentAttributeImageSize.
var (
	_ bin.Encoder     = &DocumentAttributeImageSize{}
	_ bin.Decoder     = &DocumentAttributeImageSize{}
	_ bin.BareEncoder = &DocumentAttributeImageSize{}
	_ bin.BareDecoder = &DocumentAttributeImageSize{}

	_ DocumentAttributeClass = &DocumentAttributeImageSize{}
)

func (d *DocumentAttributeImageSize) Zero() bool {
	if d == nil {
		return true
	}
	if !(d.W == 0) {
		return false
	}
	if !(d.H == 0) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (d *DocumentAttributeImageSize) String() string {
	if d == nil {
		return "DocumentAttributeImageSize(nil)"
	}
	type Alias DocumentAttributeImageSize
	return fmt.Sprintf("DocumentAttributeImageSize%+v", Alias(*d))
}

// FillFrom fills DocumentAttributeImageSize from given interface.
func (d *DocumentAttributeImageSize) FillFrom(from interface {
	GetW() (value int)
	GetH() (value int)
}) {
	d.W = from.GetW()
	d.H = from.GetH()
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*DocumentAttributeImageSize) TypeID() uint32 {
	return DocumentAttributeImageSizeTypeID
}

// TypeName returns name of type in TL schema.
func (*DocumentAttributeImageSize) TypeName() string {
	return "documentAttributeImageSize"
}

// TypeInfo returns info about TL type.
func (d *DocumentAttributeImageSize) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "documentAttributeImageSize",
		ID:   DocumentAttributeImageSizeTypeID,
	}
	if d == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "W",
			SchemaName: "w",
		},
		{
			Name:       "H",
			SchemaName: "h",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (d *DocumentAttributeImageSize) Encode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeImageSize#6c37c15c as nil")
	}
	b.PutID(DocumentAttributeImageSizeTypeID)
	return d.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (d *DocumentAttributeImageSize) EncodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeImageSize#6c37c15c as nil")
	}
	b.PutInt(d.W)
	b.PutInt(d.H)
	return nil
}

// Decode implements bin.Decoder.
func (d *DocumentAttributeImageSize) Decode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeImageSize#6c37c15c to nil")
	}
	if err := b.ConsumeID(DocumentAttributeImageSizeTypeID); err != nil {
		return fmt.Errorf("unable to decode documentAttributeImageSize#6c37c15c: %w", err)
	}
	return d.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (d *DocumentAttributeImageSize) DecodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeImageSize#6c37c15c to nil")
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeImageSize#6c37c15c: field w: %w", err)
		}
		d.W = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeImageSize#6c37c15c: field h: %w", err)
		}
		d.H = value
	}
	return nil
}

// GetW returns value of W field.
func (d *DocumentAttributeImageSize) GetW() (value int) {
	if d == nil {
		return
	}
	return d.W
}

// GetH returns value of H field.
func (d *DocumentAttributeImageSize) GetH() (value int) {
	if d == nil {
		return
	}
	return d.H
}

// DocumentAttributeAnimated represents TL type `documentAttributeAnimated#11b58939`.
// Defines an animated GIF
//
// See https://core.telegram.org/constructor/documentAttributeAnimated for reference.
type DocumentAttributeAnimated struct {
}

// DocumentAttributeAnimatedTypeID is TL type id of DocumentAttributeAnimated.
const DocumentAttributeAnimatedTypeID = 0x11b58939

// construct implements constructor of DocumentAttributeClass.
func (d DocumentAttributeAnimated) construct() DocumentAttributeClass { return &d }

// Ensuring interfaces in compile-time for DocumentAttributeAnimated.
var (
	_ bin.Encoder     = &DocumentAttributeAnimated{}
	_ bin.Decoder     = &DocumentAttributeAnimated{}
	_ bin.BareEncoder = &DocumentAttributeAnimated{}
	_ bin.BareDecoder = &DocumentAttributeAnimated{}

	_ DocumentAttributeClass = &DocumentAttributeAnimated{}
)

func (d *DocumentAttributeAnimated) Zero() bool {
	if d == nil {
		return true
	}

	return true
}

// String implements fmt.Stringer.
func (d *DocumentAttributeAnimated) String() string {
	if d == nil {
		return "DocumentAttributeAnimated(nil)"
	}
	type Alias DocumentAttributeAnimated
	return fmt.Sprintf("DocumentAttributeAnimated%+v", Alias(*d))
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*DocumentAttributeAnimated) TypeID() uint32 {
	return DocumentAttributeAnimatedTypeID
}

// TypeName returns name of type in TL schema.
func (*DocumentAttributeAnimated) TypeName() string {
	return "documentAttributeAnimated"
}

// TypeInfo returns info about TL type.
func (d *DocumentAttributeAnimated) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "documentAttributeAnimated",
		ID:   DocumentAttributeAnimatedTypeID,
	}
	if d == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (d *DocumentAttributeAnimated) Encode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeAnimated#11b58939 as nil")
	}
	b.PutID(DocumentAttributeAnimatedTypeID)
	return d.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (d *DocumentAttributeAnimated) EncodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeAnimated#11b58939 as nil")
	}
	return nil
}

// Decode implements bin.Decoder.
func (d *DocumentAttributeAnimated) Decode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeAnimated#11b58939 to nil")
	}
	if err := b.ConsumeID(DocumentAttributeAnimatedTypeID); err != nil {
		return fmt.Errorf("unable to decode documentAttributeAnimated#11b58939: %w", err)
	}
	return d.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (d *DocumentAttributeAnimated) DecodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeAnimated#11b58939 to nil")
	}
	return nil
}

// DocumentAttributeSticker represents TL type `documentAttributeSticker#6319d612`.
// Defines a sticker
//
// See https://core.telegram.org/constructor/documentAttributeSticker for reference.
type DocumentAttributeSticker struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Whether this is a mask sticker
	Mask bool
	// Alternative emoji representation of sticker
	Alt string
	// Associated stickerset
	Stickerset InputStickerSetClass
	// Mask coordinates (if this is a mask sticker, attached to a photo)
	//
	// Use SetMaskCoords and GetMaskCoords helpers.
	MaskCoords MaskCoords
}

// DocumentAttributeStickerTypeID is TL type id of DocumentAttributeSticker.
const DocumentAttributeStickerTypeID = 0x6319d612

// construct implements constructor of DocumentAttributeClass.
func (d DocumentAttributeSticker) construct() DocumentAttributeClass { return &d }

// Ensuring interfaces in compile-time for DocumentAttributeSticker.
var (
	_ bin.Encoder     = &DocumentAttributeSticker{}
	_ bin.Decoder     = &DocumentAttributeSticker{}
	_ bin.BareEncoder = &DocumentAttributeSticker{}
	_ bin.BareDecoder = &DocumentAttributeSticker{}

	_ DocumentAttributeClass = &DocumentAttributeSticker{}
)

func (d *DocumentAttributeSticker) Zero() bool {
	if d == nil {
		return true
	}
	if !(d.Flags.Zero()) {
		return false
	}
	if !(d.Mask == false) {
		return false
	}
	if !(d.Alt == "") {
		return false
	}
	if !(d.Stickerset == nil) {
		return false
	}
	if !(d.MaskCoords.Zero()) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (d *DocumentAttributeSticker) String() string {
	if d == nil {
		return "DocumentAttributeSticker(nil)"
	}
	type Alias DocumentAttributeSticker
	return fmt.Sprintf("DocumentAttributeSticker%+v", Alias(*d))
}

// FillFrom fills DocumentAttributeSticker from given interface.
func (d *DocumentAttributeSticker) FillFrom(from interface {
	GetMask() (value bool)
	GetAlt() (value string)
	GetStickerset() (value InputStickerSetClass)
	GetMaskCoords() (value MaskCoords, ok bool)
}) {
	d.Mask = from.GetMask()
	d.Alt = from.GetAlt()
	d.Stickerset = from.GetStickerset()
	if val, ok := from.GetMaskCoords(); ok {
		d.MaskCoords = val
	}

}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*DocumentAttributeSticker) TypeID() uint32 {
	return DocumentAttributeStickerTypeID
}

// TypeName returns name of type in TL schema.
func (*DocumentAttributeSticker) TypeName() string {
	return "documentAttributeSticker"
}

// TypeInfo returns info about TL type.
func (d *DocumentAttributeSticker) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "documentAttributeSticker",
		ID:   DocumentAttributeStickerTypeID,
	}
	if d == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Mask",
			SchemaName: "mask",
			Null:       !d.Flags.Has(1),
		},
		{
			Name:       "Alt",
			SchemaName: "alt",
		},
		{
			Name:       "Stickerset",
			SchemaName: "stickerset",
		},
		{
			Name:       "MaskCoords",
			SchemaName: "mask_coords",
			Null:       !d.Flags.Has(0),
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (d *DocumentAttributeSticker) SetFlags() {
	if !(d.Mask == false) {
		d.Flags.Set(1)
	}
	if !(d.MaskCoords.Zero()) {
		d.Flags.Set(0)
	}
}

// Encode implements bin.Encoder.
func (d *DocumentAttributeSticker) Encode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeSticker#6319d612 as nil")
	}
	b.PutID(DocumentAttributeStickerTypeID)
	return d.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (d *DocumentAttributeSticker) EncodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeSticker#6319d612 as nil")
	}
	d.SetFlags()
	if err := d.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode documentAttributeSticker#6319d612: field flags: %w", err)
	}
	b.PutString(d.Alt)
	if d.Stickerset == nil {
		return fmt.Errorf("unable to encode documentAttributeSticker#6319d612: field stickerset is nil")
	}
	if err := d.Stickerset.Encode(b); err != nil {
		return fmt.Errorf("unable to encode documentAttributeSticker#6319d612: field stickerset: %w", err)
	}
	if d.Flags.Has(0) {
		if err := d.MaskCoords.Encode(b); err != nil {
			return fmt.Errorf("unable to encode documentAttributeSticker#6319d612: field mask_coords: %w", err)
		}
	}
	return nil
}

// Decode implements bin.Decoder.
func (d *DocumentAttributeSticker) Decode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeSticker#6319d612 to nil")
	}
	if err := b.ConsumeID(DocumentAttributeStickerTypeID); err != nil {
		return fmt.Errorf("unable to decode documentAttributeSticker#6319d612: %w", err)
	}
	return d.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (d *DocumentAttributeSticker) DecodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeSticker#6319d612 to nil")
	}
	{
		if err := d.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode documentAttributeSticker#6319d612: field flags: %w", err)
		}
	}
	d.Mask = d.Flags.Has(1)
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeSticker#6319d612: field alt: %w", err)
		}
		d.Alt = value
	}
	{
		value, err := DecodeInputStickerSet(b)
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeSticker#6319d612: field stickerset: %w", err)
		}
		d.Stickerset = value
	}
	if d.Flags.Has(0) {
		if err := d.MaskCoords.Decode(b); err != nil {
			return fmt.Errorf("unable to decode documentAttributeSticker#6319d612: field mask_coords: %w", err)
		}
	}
	return nil
}

// SetMask sets value of Mask conditional field.
func (d *DocumentAttributeSticker) SetMask(value bool) {
	if value {
		d.Flags.Set(1)
		d.Mask = true
	} else {
		d.Flags.Unset(1)
		d.Mask = false
	}
}

// GetMask returns value of Mask conditional field.
func (d *DocumentAttributeSticker) GetMask() (value bool) {
	if d == nil {
		return
	}
	return d.Flags.Has(1)
}

// GetAlt returns value of Alt field.
func (d *DocumentAttributeSticker) GetAlt() (value string) {
	if d == nil {
		return
	}
	return d.Alt
}

// GetStickerset returns value of Stickerset field.
func (d *DocumentAttributeSticker) GetStickerset() (value InputStickerSetClass) {
	if d == nil {
		return
	}
	return d.Stickerset
}

// SetMaskCoords sets value of MaskCoords conditional field.
func (d *DocumentAttributeSticker) SetMaskCoords(value MaskCoords) {
	d.Flags.Set(0)
	d.MaskCoords = value
}

// GetMaskCoords returns value of MaskCoords conditional field and
// boolean which is true if field was set.
func (d *DocumentAttributeSticker) GetMaskCoords() (value MaskCoords, ok bool) {
	if d == nil {
		return
	}
	if !d.Flags.Has(0) {
		return value, false
	}
	return d.MaskCoords, true
}

// DocumentAttributeVideo represents TL type `documentAttributeVideo#ef02ce6`.
// Defines a video
//
// See https://core.telegram.org/constructor/documentAttributeVideo for reference.
type DocumentAttributeVideo struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Whether this is a round video
	RoundMessage bool
	// Whether the video supports streaming
	SupportsStreaming bool
	// Duration in seconds
	Duration int
	// Video width
	W int
	// Video height
	H int
}

// DocumentAttributeVideoTypeID is TL type id of DocumentAttributeVideo.
const DocumentAttributeVideoTypeID = 0xef02ce6

// construct implements constructor of DocumentAttributeClass.
func (d DocumentAttributeVideo) construct() DocumentAttributeClass { return &d }

// Ensuring interfaces in compile-time for DocumentAttributeVideo.
var (
	_ bin.Encoder     = &DocumentAttributeVideo{}
	_ bin.Decoder     = &DocumentAttributeVideo{}
	_ bin.BareEncoder = &DocumentAttributeVideo{}
	_ bin.BareDecoder = &DocumentAttributeVideo{}

	_ DocumentAttributeClass = &DocumentAttributeVideo{}
)

func (d *DocumentAttributeVideo) Zero() bool {
	if d == nil {
		return true
	}
	if !(d.Flags.Zero()) {
		return false
	}
	if !(d.RoundMessage == false) {
		return false
	}
	if !(d.SupportsStreaming == false) {
		return false
	}
	if !(d.Duration == 0) {
		return false
	}
	if !(d.W == 0) {
		return false
	}
	if !(d.H == 0) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (d *DocumentAttributeVideo) String() string {
	if d == nil {
		return "DocumentAttributeVideo(nil)"
	}
	type Alias DocumentAttributeVideo
	return fmt.Sprintf("DocumentAttributeVideo%+v", Alias(*d))
}

// FillFrom fills DocumentAttributeVideo from given interface.
func (d *DocumentAttributeVideo) FillFrom(from interface {
	GetRoundMessage() (value bool)
	GetSupportsStreaming() (value bool)
	GetDuration() (value int)
	GetW() (value int)
	GetH() (value int)
}) {
	d.RoundMessage = from.GetRoundMessage()
	d.SupportsStreaming = from.GetSupportsStreaming()
	d.Duration = from.GetDuration()
	d.W = from.GetW()
	d.H = from.GetH()
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*DocumentAttributeVideo) TypeID() uint32 {
	return DocumentAttributeVideoTypeID
}

// TypeName returns name of type in TL schema.
func (*DocumentAttributeVideo) TypeName() string {
	return "documentAttributeVideo"
}

// TypeInfo returns info about TL type.
func (d *DocumentAttributeVideo) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "documentAttributeVideo",
		ID:   DocumentAttributeVideoTypeID,
	}
	if d == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "RoundMessage",
			SchemaName: "round_message",
			Null:       !d.Flags.Has(0),
		},
		{
			Name:       "SupportsStreaming",
			SchemaName: "supports_streaming",
			Null:       !d.Flags.Has(1),
		},
		{
			Name:       "Duration",
			SchemaName: "duration",
		},
		{
			Name:       "W",
			SchemaName: "w",
		},
		{
			Name:       "H",
			SchemaName: "h",
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (d *DocumentAttributeVideo) SetFlags() {
	if !(d.RoundMessage == false) {
		d.Flags.Set(0)
	}
	if !(d.SupportsStreaming == false) {
		d.Flags.Set(1)
	}
}

// Encode implements bin.Encoder.
func (d *DocumentAttributeVideo) Encode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeVideo#ef02ce6 as nil")
	}
	b.PutID(DocumentAttributeVideoTypeID)
	return d.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (d *DocumentAttributeVideo) EncodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeVideo#ef02ce6 as nil")
	}
	d.SetFlags()
	if err := d.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode documentAttributeVideo#ef02ce6: field flags: %w", err)
	}
	b.PutInt(d.Duration)
	b.PutInt(d.W)
	b.PutInt(d.H)
	return nil
}

// Decode implements bin.Decoder.
func (d *DocumentAttributeVideo) Decode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeVideo#ef02ce6 to nil")
	}
	if err := b.ConsumeID(DocumentAttributeVideoTypeID); err != nil {
		return fmt.Errorf("unable to decode documentAttributeVideo#ef02ce6: %w", err)
	}
	return d.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (d *DocumentAttributeVideo) DecodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeVideo#ef02ce6 to nil")
	}
	{
		if err := d.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode documentAttributeVideo#ef02ce6: field flags: %w", err)
		}
	}
	d.RoundMessage = d.Flags.Has(0)
	d.SupportsStreaming = d.Flags.Has(1)
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeVideo#ef02ce6: field duration: %w", err)
		}
		d.Duration = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeVideo#ef02ce6: field w: %w", err)
		}
		d.W = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeVideo#ef02ce6: field h: %w", err)
		}
		d.H = value
	}
	return nil
}

// SetRoundMessage sets value of RoundMessage conditional field.
func (d *DocumentAttributeVideo) SetRoundMessage(value bool) {
	if value {
		d.Flags.Set(0)
		d.RoundMessage = true
	} else {
		d.Flags.Unset(0)
		d.RoundMessage = false
	}
}

// GetRoundMessage returns value of RoundMessage conditional field.
func (d *DocumentAttributeVideo) GetRoundMessage() (value bool) {
	if d == nil {
		return
	}
	return d.Flags.Has(0)
}

// SetSupportsStreaming sets value of SupportsStreaming conditional field.
func (d *DocumentAttributeVideo) SetSupportsStreaming(value bool) {
	if value {
		d.Flags.Set(1)
		d.SupportsStreaming = true
	} else {
		d.Flags.Unset(1)
		d.SupportsStreaming = false
	}
}

// GetSupportsStreaming returns value of SupportsStreaming conditional field.
func (d *DocumentAttributeVideo) GetSupportsStreaming() (value bool) {
	if d == nil {
		return
	}
	return d.Flags.Has(1)
}

// GetDuration returns value of Duration field.
func (d *DocumentAttributeVideo) GetDuration() (value int) {
	if d == nil {
		return
	}
	return d.Duration
}

// GetW returns value of W field.
func (d *DocumentAttributeVideo) GetW() (value int) {
	if d == nil {
		return
	}
	return d.W
}

// GetH returns value of H field.
func (d *DocumentAttributeVideo) GetH() (value int) {
	if d == nil {
		return
	}
	return d.H
}

// DocumentAttributeAudio represents TL type `documentAttributeAudio#9852f9c6`.
// Represents an audio file
//
// See https://core.telegram.org/constructor/documentAttributeAudio for reference.
type DocumentAttributeAudio struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Whether this is a voice message
	Voice bool
	// Duration in seconds
	Duration int
	// Name of song
	//
	// Use SetTitle and GetTitle helpers.
	Title string
	// Performer
	//
	// Use SetPerformer and GetPerformer helpers.
	Performer string
	// Waveform: consists in a series of bitpacked 5-bit values. Example implementation:
	// android¹.
	//
	// Links:
	//  1) https://github.com/DrKLO/Telegram/blob/96dce2c9aabc33b87db61d830aa087b6b03fe397/TMessagesProj/jni/audio.c#L546
	//
	// Use SetWaveform and GetWaveform helpers.
	Waveform []byte
}

// DocumentAttributeAudioTypeID is TL type id of DocumentAttributeAudio.
const DocumentAttributeAudioTypeID = 0x9852f9c6

// construct implements constructor of DocumentAttributeClass.
func (d DocumentAttributeAudio) construct() DocumentAttributeClass { return &d }

// Ensuring interfaces in compile-time for DocumentAttributeAudio.
var (
	_ bin.Encoder     = &DocumentAttributeAudio{}
	_ bin.Decoder     = &DocumentAttributeAudio{}
	_ bin.BareEncoder = &DocumentAttributeAudio{}
	_ bin.BareDecoder = &DocumentAttributeAudio{}

	_ DocumentAttributeClass = &DocumentAttributeAudio{}
)

func (d *DocumentAttributeAudio) Zero() bool {
	if d == nil {
		return true
	}
	if !(d.Flags.Zero()) {
		return false
	}
	if !(d.Voice == false) {
		return false
	}
	if !(d.Duration == 0) {
		return false
	}
	if !(d.Title == "") {
		return false
	}
	if !(d.Performer == "") {
		return false
	}
	if !(d.Waveform == nil) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (d *DocumentAttributeAudio) String() string {
	if d == nil {
		return "DocumentAttributeAudio(nil)"
	}
	type Alias DocumentAttributeAudio
	return fmt.Sprintf("DocumentAttributeAudio%+v", Alias(*d))
}

// FillFrom fills DocumentAttributeAudio from given interface.
func (d *DocumentAttributeAudio) FillFrom(from interface {
	GetVoice() (value bool)
	GetDuration() (value int)
	GetTitle() (value string, ok bool)
	GetPerformer() (value string, ok bool)
	GetWaveform() (value []byte, ok bool)
}) {
	d.Voice = from.GetVoice()
	d.Duration = from.GetDuration()
	if val, ok := from.GetTitle(); ok {
		d.Title = val
	}

	if val, ok := from.GetPerformer(); ok {
		d.Performer = val
	}

	if val, ok := from.GetWaveform(); ok {
		d.Waveform = val
	}

}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*DocumentAttributeAudio) TypeID() uint32 {
	return DocumentAttributeAudioTypeID
}

// TypeName returns name of type in TL schema.
func (*DocumentAttributeAudio) TypeName() string {
	return "documentAttributeAudio"
}

// TypeInfo returns info about TL type.
func (d *DocumentAttributeAudio) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "documentAttributeAudio",
		ID:   DocumentAttributeAudioTypeID,
	}
	if d == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Voice",
			SchemaName: "voice",
			Null:       !d.Flags.Has(10),
		},
		{
			Name:       "Duration",
			SchemaName: "duration",
		},
		{
			Name:       "Title",
			SchemaName: "title",
			Null:       !d.Flags.Has(0),
		},
		{
			Name:       "Performer",
			SchemaName: "performer",
			Null:       !d.Flags.Has(1),
		},
		{
			Name:       "Waveform",
			SchemaName: "waveform",
			Null:       !d.Flags.Has(2),
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (d *DocumentAttributeAudio) SetFlags() {
	if !(d.Voice == false) {
		d.Flags.Set(10)
	}
	if !(d.Title == "") {
		d.Flags.Set(0)
	}
	if !(d.Performer == "") {
		d.Flags.Set(1)
	}
	if !(d.Waveform == nil) {
		d.Flags.Set(2)
	}
}

// Encode implements bin.Encoder.
func (d *DocumentAttributeAudio) Encode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeAudio#9852f9c6 as nil")
	}
	b.PutID(DocumentAttributeAudioTypeID)
	return d.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (d *DocumentAttributeAudio) EncodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeAudio#9852f9c6 as nil")
	}
	d.SetFlags()
	if err := d.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode documentAttributeAudio#9852f9c6: field flags: %w", err)
	}
	b.PutInt(d.Duration)
	if d.Flags.Has(0) {
		b.PutString(d.Title)
	}
	if d.Flags.Has(1) {
		b.PutString(d.Performer)
	}
	if d.Flags.Has(2) {
		b.PutBytes(d.Waveform)
	}
	return nil
}

// Decode implements bin.Decoder.
func (d *DocumentAttributeAudio) Decode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeAudio#9852f9c6 to nil")
	}
	if err := b.ConsumeID(DocumentAttributeAudioTypeID); err != nil {
		return fmt.Errorf("unable to decode documentAttributeAudio#9852f9c6: %w", err)
	}
	return d.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (d *DocumentAttributeAudio) DecodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeAudio#9852f9c6 to nil")
	}
	{
		if err := d.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode documentAttributeAudio#9852f9c6: field flags: %w", err)
		}
	}
	d.Voice = d.Flags.Has(10)
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeAudio#9852f9c6: field duration: %w", err)
		}
		d.Duration = value
	}
	if d.Flags.Has(0) {
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeAudio#9852f9c6: field title: %w", err)
		}
		d.Title = value
	}
	if d.Flags.Has(1) {
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeAudio#9852f9c6: field performer: %w", err)
		}
		d.Performer = value
	}
	if d.Flags.Has(2) {
		value, err := b.Bytes()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeAudio#9852f9c6: field waveform: %w", err)
		}
		d.Waveform = value
	}
	return nil
}

// SetVoice sets value of Voice conditional field.
func (d *DocumentAttributeAudio) SetVoice(value bool) {
	if value {
		d.Flags.Set(10)
		d.Voice = true
	} else {
		d.Flags.Unset(10)
		d.Voice = false
	}
}

// GetVoice returns value of Voice conditional field.
func (d *DocumentAttributeAudio) GetVoice() (value bool) {
	if d == nil {
		return
	}
	return d.Flags.Has(10)
}

// GetDuration returns value of Duration field.
func (d *DocumentAttributeAudio) GetDuration() (value int) {
	if d == nil {
		return
	}
	return d.Duration
}

// SetTitle sets value of Title conditional field.
func (d *DocumentAttributeAudio) SetTitle(value string) {
	d.Flags.Set(0)
	d.Title = value
}

// GetTitle returns value of Title conditional field and
// boolean which is true if field was set.
func (d *DocumentAttributeAudio) GetTitle() (value string, ok bool) {
	if d == nil {
		return
	}
	if !d.Flags.Has(0) {
		return value, false
	}
	return d.Title, true
}

// SetPerformer sets value of Performer conditional field.
func (d *DocumentAttributeAudio) SetPerformer(value string) {
	d.Flags.Set(1)
	d.Performer = value
}

// GetPerformer returns value of Performer conditional field and
// boolean which is true if field was set.
func (d *DocumentAttributeAudio) GetPerformer() (value string, ok bool) {
	if d == nil {
		return
	}
	if !d.Flags.Has(1) {
		return value, false
	}
	return d.Performer, true
}

// SetWaveform sets value of Waveform conditional field.
func (d *DocumentAttributeAudio) SetWaveform(value []byte) {
	d.Flags.Set(2)
	d.Waveform = value
}

// GetWaveform returns value of Waveform conditional field and
// boolean which is true if field was set.
func (d *DocumentAttributeAudio) GetWaveform() (value []byte, ok bool) {
	if d == nil {
		return
	}
	if !d.Flags.Has(2) {
		return value, false
	}
	return d.Waveform, true
}

// DocumentAttributeFilename represents TL type `documentAttributeFilename#15590068`.
// A simple document with a file name
//
// See https://core.telegram.org/constructor/documentAttributeFilename for reference.
type DocumentAttributeFilename struct {
	// The file name
	FileName string
}

// DocumentAttributeFilenameTypeID is TL type id of DocumentAttributeFilename.
const DocumentAttributeFilenameTypeID = 0x15590068

// construct implements constructor of DocumentAttributeClass.
func (d DocumentAttributeFilename) construct() DocumentAttributeClass { return &d }

// Ensuring interfaces in compile-time for DocumentAttributeFilename.
var (
	_ bin.Encoder     = &DocumentAttributeFilename{}
	_ bin.Decoder     = &DocumentAttributeFilename{}
	_ bin.BareEncoder = &DocumentAttributeFilename{}
	_ bin.BareDecoder = &DocumentAttributeFilename{}

	_ DocumentAttributeClass = &DocumentAttributeFilename{}
)

func (d *DocumentAttributeFilename) Zero() bool {
	if d == nil {
		return true
	}
	if !(d.FileName == "") {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (d *DocumentAttributeFilename) String() string {
	if d == nil {
		return "DocumentAttributeFilename(nil)"
	}
	type Alias DocumentAttributeFilename
	return fmt.Sprintf("DocumentAttributeFilename%+v", Alias(*d))
}

// FillFrom fills DocumentAttributeFilename from given interface.
func (d *DocumentAttributeFilename) FillFrom(from interface {
	GetFileName() (value string)
}) {
	d.FileName = from.GetFileName()
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*DocumentAttributeFilename) TypeID() uint32 {
	return DocumentAttributeFilenameTypeID
}

// TypeName returns name of type in TL schema.
func (*DocumentAttributeFilename) TypeName() string {
	return "documentAttributeFilename"
}

// TypeInfo returns info about TL type.
func (d *DocumentAttributeFilename) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "documentAttributeFilename",
		ID:   DocumentAttributeFilenameTypeID,
	}
	if d == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "FileName",
			SchemaName: "file_name",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (d *DocumentAttributeFilename) Encode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeFilename#15590068 as nil")
	}
	b.PutID(DocumentAttributeFilenameTypeID)
	return d.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (d *DocumentAttributeFilename) EncodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeFilename#15590068 as nil")
	}
	b.PutString(d.FileName)
	return nil
}

// Decode implements bin.Decoder.
func (d *DocumentAttributeFilename) Decode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeFilename#15590068 to nil")
	}
	if err := b.ConsumeID(DocumentAttributeFilenameTypeID); err != nil {
		return fmt.Errorf("unable to decode documentAttributeFilename#15590068: %w", err)
	}
	return d.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (d *DocumentAttributeFilename) DecodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeFilename#15590068 to nil")
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeFilename#15590068: field file_name: %w", err)
		}
		d.FileName = value
	}
	return nil
}

// GetFileName returns value of FileName field.
func (d *DocumentAttributeFilename) GetFileName() (value string) {
	if d == nil {
		return
	}
	return d.FileName
}

// DocumentAttributeHasStickers represents TL type `documentAttributeHasStickers#9801d2f7`.
// Whether the current document has stickers attached
//
// See https://core.telegram.org/constructor/documentAttributeHasStickers for reference.
type DocumentAttributeHasStickers struct {
}

// DocumentAttributeHasStickersTypeID is TL type id of DocumentAttributeHasStickers.
const DocumentAttributeHasStickersTypeID = 0x9801d2f7

// construct implements constructor of DocumentAttributeClass.
func (d DocumentAttributeHasStickers) construct() DocumentAttributeClass { return &d }

// Ensuring interfaces in compile-time for DocumentAttributeHasStickers.
var (
	_ bin.Encoder     = &DocumentAttributeHasStickers{}
	_ bin.Decoder     = &DocumentAttributeHasStickers{}
	_ bin.BareEncoder = &DocumentAttributeHasStickers{}
	_ bin.BareDecoder = &DocumentAttributeHasStickers{}

	_ DocumentAttributeClass = &DocumentAttributeHasStickers{}
)

func (d *DocumentAttributeHasStickers) Zero() bool {
	if d == nil {
		return true
	}

	return true
}

// String implements fmt.Stringer.
func (d *DocumentAttributeHasStickers) String() string {
	if d == nil {
		return "DocumentAttributeHasStickers(nil)"
	}
	type Alias DocumentAttributeHasStickers
	return fmt.Sprintf("DocumentAttributeHasStickers%+v", Alias(*d))
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*DocumentAttributeHasStickers) TypeID() uint32 {
	return DocumentAttributeHasStickersTypeID
}

// TypeName returns name of type in TL schema.
func (*DocumentAttributeHasStickers) TypeName() string {
	return "documentAttributeHasStickers"
}

// TypeInfo returns info about TL type.
func (d *DocumentAttributeHasStickers) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "documentAttributeHasStickers",
		ID:   DocumentAttributeHasStickersTypeID,
	}
	if d == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (d *DocumentAttributeHasStickers) Encode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeHasStickers#9801d2f7 as nil")
	}
	b.PutID(DocumentAttributeHasStickersTypeID)
	return d.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (d *DocumentAttributeHasStickers) EncodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeHasStickers#9801d2f7 as nil")
	}
	return nil
}

// Decode implements bin.Decoder.
func (d *DocumentAttributeHasStickers) Decode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeHasStickers#9801d2f7 to nil")
	}
	if err := b.ConsumeID(DocumentAttributeHasStickersTypeID); err != nil {
		return fmt.Errorf("unable to decode documentAttributeHasStickers#9801d2f7: %w", err)
	}
	return d.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (d *DocumentAttributeHasStickers) DecodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeHasStickers#9801d2f7 to nil")
	}
	return nil
}

// DocumentAttributeCustomEmoji represents TL type `documentAttributeCustomEmoji#fd149899`.
// Info about a custom emoji
//
// See https://core.telegram.org/constructor/documentAttributeCustomEmoji for reference.
type DocumentAttributeCustomEmoji struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Whether this custom emoji can be sent by non-Premium users
	Free bool
	// Whether the color of this TGS custom emoji should be changed to the text color when
	// used in messages, the accent color if used as emoji status, white on chat photos, or
	// another appropriate color based on context.
	TextColor bool
	// The actual emoji
	Alt string
	// The emoji stickerset to which this emoji belongs.
	Stickerset InputStickerSetClass
}

// DocumentAttributeCustomEmojiTypeID is TL type id of DocumentAttributeCustomEmoji.
const DocumentAttributeCustomEmojiTypeID = 0xfd149899

// construct implements constructor of DocumentAttributeClass.
func (d DocumentAttributeCustomEmoji) construct() DocumentAttributeClass { return &d }

// Ensuring interfaces in compile-time for DocumentAttributeCustomEmoji.
var (
	_ bin.Encoder     = &DocumentAttributeCustomEmoji{}
	_ bin.Decoder     = &DocumentAttributeCustomEmoji{}
	_ bin.BareEncoder = &DocumentAttributeCustomEmoji{}
	_ bin.BareDecoder = &DocumentAttributeCustomEmoji{}

	_ DocumentAttributeClass = &DocumentAttributeCustomEmoji{}
)

func (d *DocumentAttributeCustomEmoji) Zero() bool {
	if d == nil {
		return true
	}
	if !(d.Flags.Zero()) {
		return false
	}
	if !(d.Free == false) {
		return false
	}
	if !(d.TextColor == false) {
		return false
	}
	if !(d.Alt == "") {
		return false
	}
	if !(d.Stickerset == nil) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (d *DocumentAttributeCustomEmoji) String() string {
	if d == nil {
		return "DocumentAttributeCustomEmoji(nil)"
	}
	type Alias DocumentAttributeCustomEmoji
	return fmt.Sprintf("DocumentAttributeCustomEmoji%+v", Alias(*d))
}

// FillFrom fills DocumentAttributeCustomEmoji from given interface.
func (d *DocumentAttributeCustomEmoji) FillFrom(from interface {
	GetFree() (value bool)
	GetTextColor() (value bool)
	GetAlt() (value string)
	GetStickerset() (value InputStickerSetClass)
}) {
	d.Free = from.GetFree()
	d.TextColor = from.GetTextColor()
	d.Alt = from.GetAlt()
	d.Stickerset = from.GetStickerset()
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*DocumentAttributeCustomEmoji) TypeID() uint32 {
	return DocumentAttributeCustomEmojiTypeID
}

// TypeName returns name of type in TL schema.
func (*DocumentAttributeCustomEmoji) TypeName() string {
	return "documentAttributeCustomEmoji"
}

// TypeInfo returns info about TL type.
func (d *DocumentAttributeCustomEmoji) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "documentAttributeCustomEmoji",
		ID:   DocumentAttributeCustomEmojiTypeID,
	}
	if d == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Free",
			SchemaName: "free",
			Null:       !d.Flags.Has(0),
		},
		{
			Name:       "TextColor",
			SchemaName: "text_color",
			Null:       !d.Flags.Has(1),
		},
		{
			Name:       "Alt",
			SchemaName: "alt",
		},
		{
			Name:       "Stickerset",
			SchemaName: "stickerset",
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (d *DocumentAttributeCustomEmoji) SetFlags() {
	if !(d.Free == false) {
		d.Flags.Set(0)
	}
	if !(d.TextColor == false) {
		d.Flags.Set(1)
	}
}

// Encode implements bin.Encoder.
func (d *DocumentAttributeCustomEmoji) Encode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeCustomEmoji#fd149899 as nil")
	}
	b.PutID(DocumentAttributeCustomEmojiTypeID)
	return d.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (d *DocumentAttributeCustomEmoji) EncodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't encode documentAttributeCustomEmoji#fd149899 as nil")
	}
	d.SetFlags()
	if err := d.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode documentAttributeCustomEmoji#fd149899: field flags: %w", err)
	}
	b.PutString(d.Alt)
	if d.Stickerset == nil {
		return fmt.Errorf("unable to encode documentAttributeCustomEmoji#fd149899: field stickerset is nil")
	}
	if err := d.Stickerset.Encode(b); err != nil {
		return fmt.Errorf("unable to encode documentAttributeCustomEmoji#fd149899: field stickerset: %w", err)
	}
	return nil
}

// Decode implements bin.Decoder.
func (d *DocumentAttributeCustomEmoji) Decode(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeCustomEmoji#fd149899 to nil")
	}
	if err := b.ConsumeID(DocumentAttributeCustomEmojiTypeID); err != nil {
		return fmt.Errorf("unable to decode documentAttributeCustomEmoji#fd149899: %w", err)
	}
	return d.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (d *DocumentAttributeCustomEmoji) DecodeBare(b *bin.Buffer) error {
	if d == nil {
		return fmt.Errorf("can't decode documentAttributeCustomEmoji#fd149899 to nil")
	}
	{
		if err := d.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode documentAttributeCustomEmoji#fd149899: field flags: %w", err)
		}
	}
	d.Free = d.Flags.Has(0)
	d.TextColor = d.Flags.Has(1)
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeCustomEmoji#fd149899: field alt: %w", err)
		}
		d.Alt = value
	}
	{
		value, err := DecodeInputStickerSet(b)
		if err != nil {
			return fmt.Errorf("unable to decode documentAttributeCustomEmoji#fd149899: field stickerset: %w", err)
		}
		d.Stickerset = value
	}
	return nil
}

// SetFree sets value of Free conditional field.
func (d *DocumentAttributeCustomEmoji) SetFree(value bool) {
	if value {
		d.Flags.Set(0)
		d.Free = true
	} else {
		d.Flags.Unset(0)
		d.Free = false
	}
}

// GetFree returns value of Free conditional field.
func (d *DocumentAttributeCustomEmoji) GetFree() (value bool) {
	if d == nil {
		return
	}
	return d.Flags.Has(0)
}

// SetTextColor sets value of TextColor conditional field.
func (d *DocumentAttributeCustomEmoji) SetTextColor(value bool) {
	if value {
		d.Flags.Set(1)
		d.TextColor = true
	} else {
		d.Flags.Unset(1)
		d.TextColor = false
	}
}

// GetTextColor returns value of TextColor conditional field.
func (d *DocumentAttributeCustomEmoji) GetTextColor() (value bool) {
	if d == nil {
		return
	}
	return d.Flags.Has(1)
}

// GetAlt returns value of Alt field.
func (d *DocumentAttributeCustomEmoji) GetAlt() (value string) {
	if d == nil {
		return
	}
	return d.Alt
}

// GetStickerset returns value of Stickerset field.
func (d *DocumentAttributeCustomEmoji) GetStickerset() (value InputStickerSetClass) {
	if d == nil {
		return
	}
	return d.Stickerset
}

// DocumentAttributeClassName is schema name of DocumentAttributeClass.
const DocumentAttributeClassName = "DocumentAttribute"

// DocumentAttributeClass represents DocumentAttribute generic type.
//
// See https://core.telegram.org/type/DocumentAttribute for reference.
//
// Example:
//
//	g, err := tg.DecodeDocumentAttribute(buf)
//	if err != nil {
//	    panic(err)
//	}
//	switch v := g.(type) {
//	case *tg.DocumentAttributeImageSize: // documentAttributeImageSize#6c37c15c
//	case *tg.DocumentAttributeAnimated: // documentAttributeAnimated#11b58939
//	case *tg.DocumentAttributeSticker: // documentAttributeSticker#6319d612
//	case *tg.DocumentAttributeVideo: // documentAttributeVideo#ef02ce6
//	case *tg.DocumentAttributeAudio: // documentAttributeAudio#9852f9c6
//	case *tg.DocumentAttributeFilename: // documentAttributeFilename#15590068
//	case *tg.DocumentAttributeHasStickers: // documentAttributeHasStickers#9801d2f7
//	case *tg.DocumentAttributeCustomEmoji: // documentAttributeCustomEmoji#fd149899
//	default: panic(v)
//	}
type DocumentAttributeClass interface {
	bin.Encoder
	bin.Decoder
	bin.BareEncoder
	bin.BareDecoder
	construct() DocumentAttributeClass

	// TypeID returns type id in TL schema.
	//
	// See https://core.telegram.org/mtproto/TL-tl#remarks.
	TypeID() uint32
	// TypeName returns name of type in TL schema.
	TypeName() string
	// String implements fmt.Stringer.
	String() string
	// Zero returns true if current object has a zero value.
	Zero() bool
}

// DecodeDocumentAttribute implements binary de-serialization for DocumentAttributeClass.
func DecodeDocumentAttribute(buf *bin.Buffer) (DocumentAttributeClass, error) {
	id, err := buf.PeekID()
	if err != nil {
		return nil, err
	}
	switch id {
	case DocumentAttributeImageSizeTypeID:
		// Decoding documentAttributeImageSize#6c37c15c.
		v := DocumentAttributeImageSize{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", err)
		}
		return &v, nil
	case DocumentAttributeAnimatedTypeID:
		// Decoding documentAttributeAnimated#11b58939.
		v := DocumentAttributeAnimated{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", err)
		}
		return &v, nil
	case DocumentAttributeStickerTypeID:
		// Decoding documentAttributeSticker#6319d612.
		v := DocumentAttributeSticker{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", err)
		}
		return &v, nil
	case DocumentAttributeVideoTypeID:
		// Decoding documentAttributeVideo#ef02ce6.
		v := DocumentAttributeVideo{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", err)
		}
		return &v, nil
	case DocumentAttributeAudioTypeID:
		// Decoding documentAttributeAudio#9852f9c6.
		v := DocumentAttributeAudio{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", err)
		}
		return &v, nil
	case DocumentAttributeFilenameTypeID:
		// Decoding documentAttributeFilename#15590068.
		v := DocumentAttributeFilename{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", err)
		}
		return &v, nil
	case DocumentAttributeHasStickersTypeID:
		// Decoding documentAttributeHasStickers#9801d2f7.
		v := DocumentAttributeHasStickers{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", err)
		}
		return &v, nil
	case DocumentAttributeCustomEmojiTypeID:
		// Decoding documentAttributeCustomEmoji#fd149899.
		v := DocumentAttributeCustomEmoji{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode DocumentAttributeClass: %w", bin.NewUnexpectedID(id))
	}
}

// DocumentAttribute boxes the DocumentAttributeClass providing a helper.
type DocumentAttributeBox struct {
	DocumentAttribute DocumentAttributeClass
}

// Decode implements bin.Decoder for DocumentAttributeBox.
func (b *DocumentAttributeBox) Decode(buf *bin.Buffer) error {
	if b == nil {
		return fmt.Errorf("unable to decode DocumentAttributeBox to nil")
	}
	v, err := DecodeDocumentAttribute(buf)
	if err != nil {
		return fmt.Errorf("unable to decode boxed value: %w", err)
	}
	b.DocumentAttribute = v
	return nil
}

// Encode implements bin.Encode for DocumentAttributeBox.
func (b *DocumentAttributeBox) Encode(buf *bin.Buffer) error {
	if b == nil || b.DocumentAttribute == nil {
		return fmt.Errorf("unable to encode DocumentAttributeClass as nil")
	}
	return b.DocumentAttribute.Encode(buf)
}
