// Autogenerated by Thrift Compiler (0.9.3)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING

package sampling

import (
	"bytes"
	"fmt"
	"github.com/uber/jaeger-client-go/thrift"
)

// (needed to ensure safety because of naive import list construction.)
var _ = thrift.ZERO
var _ = fmt.Printf
var _ = bytes.Equal

var GoUnusedProtection__ int

type SamplingStrategyType int64

const (
	SamplingStrategyType_PROBABILISTIC SamplingStrategyType = 0
	SamplingStrategyType_RATE_LIMITING SamplingStrategyType = 1
)

func (p SamplingStrategyType) String() string {
	switch p {
	case SamplingStrategyType_PROBABILISTIC:
		return "PROBABILISTIC"
	case SamplingStrategyType_RATE_LIMITING:
		return "RATE_LIMITING"
	}
	return "<UNSET>"
}

func SamplingStrategyTypeFromString(s string) (SamplingStrategyType, error) {
	switch s {
	case "PROBABILISTIC":
		return SamplingStrategyType_PROBABILISTIC, nil
	case "RATE_LIMITING":
		return SamplingStrategyType_RATE_LIMITING, nil
	}
	return SamplingStrategyType(0), fmt.Errorf("not a valid SamplingStrategyType string")
}

func SamplingStrategyTypePtr(v SamplingStrategyType) *SamplingStrategyType { return &v }

func (p SamplingStrategyType) MarshalText() ([]byte, error) {
	return []byte(p.String()), nil
}

func (p *SamplingStrategyType) UnmarshalText(text []byte) error {
	q, err := SamplingStrategyTypeFromString(string(text))
	if err != nil {
		return err
	}
	*p = q
	return nil
}

// Attributes:
//  - SamplingRate
type ProbabilisticSamplingStrategy struct {
	SamplingRate float64 `thrift:"samplingRate,1,required" json:"samplingRate"`
}

func NewProbabilisticSamplingStrategy() *ProbabilisticSamplingStrategy {
	return &ProbabilisticSamplingStrategy{}
}

func (p *ProbabilisticSamplingStrategy) GetSamplingRate() float64 {
	return p.SamplingRate
}
func (p *ProbabilisticSamplingStrategy) Read(iprot thrift.TProtocol) error {
	if _, err := iprot.ReadStructBegin(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
	}

	var issetSamplingRate bool = false

	for {
		_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
		if err != nil {
			return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
		}
		if fieldTypeId == thrift.STOP {
			break
		}
		switch fieldId {
		case 1:
			if err := p.readField1(iprot); err != nil {
				return err
			}
			issetSamplingRate = true
		default:
			if err := iprot.Skip(fieldTypeId); err != nil {
				return err
			}
		}
		if err := iprot.ReadFieldEnd(); err != nil {
			return err
		}
	}
	if err := iprot.ReadStructEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
	}
	if !issetSamplingRate {
		return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field SamplingRate is not set"))
	}
	return nil
}

func (p *ProbabilisticSamplingStrategy) readField1(iprot thrift.TProtocol) error {
	if v, err := iprot.ReadDouble(); err != nil {
		return thrift.PrependError("error reading field 1: ", err)
	} else {
		p.SamplingRate = v
	}
	return nil
}

func (p *ProbabilisticSamplingStrategy) Write(oprot thrift.TProtocol) error {
	if err := oprot.WriteStructBegin("ProbabilisticSamplingStrategy"); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
	}
	if err := p.writeField1(oprot); err != nil {
		return err
	}
	if err := oprot.WriteFieldStop(); err != nil {
		return thrift.PrependError("write field stop error: ", err)
	}
	if err := oprot.WriteStructEnd(); err != nil {
		return thrift.PrependError("write struct stop error: ", err)
	}
	return nil
}

func (p *ProbabilisticSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) {
	if err := oprot.WriteFieldBegin("samplingRate", thrift.DOUBLE, 1); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:samplingRate: ", p), err)
	}
	if err := oprot.WriteDouble(float64(p.SamplingRate)); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T.samplingRate (1) field write error: ", p), err)
	}
	if err := oprot.WriteFieldEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field end error 1:samplingRate: ", p), err)
	}
	return err
}

func (p *ProbabilisticSamplingStrategy) String() string {
	if p == nil {
		return "<nil>"
	}
	return fmt.Sprintf("ProbabilisticSamplingStrategy(%+v)", *p)
}

// Attributes:
//  - MaxTracesPerSecond
type RateLimitingSamplingStrategy struct {
	MaxTracesPerSecond int16 `thrift:"maxTracesPerSecond,1,required" json:"maxTracesPerSecond"`
}

func NewRateLimitingSamplingStrategy() *RateLimitingSamplingStrategy {
	return &RateLimitingSamplingStrategy{}
}

func (p *RateLimitingSamplingStrategy) GetMaxTracesPerSecond() int16 {
	return p.MaxTracesPerSecond
}
func (p *RateLimitingSamplingStrategy) Read(iprot thrift.TProtocol) error {
	if _, err := iprot.ReadStructBegin(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
	}

	var issetMaxTracesPerSecond bool = false

	for {
		_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
		if err != nil {
			return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
		}
		if fieldTypeId == thrift.STOP {
			break
		}
		switch fieldId {
		case 1:
			if err := p.readField1(iprot); err != nil {
				return err
			}
			issetMaxTracesPerSecond = true
		default:
			if err := iprot.Skip(fieldTypeId); err != nil {
				return err
			}
		}
		if err := iprot.ReadFieldEnd(); err != nil {
			return err
		}
	}
	if err := iprot.ReadStructEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
	}
	if !issetMaxTracesPerSecond {
		return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field MaxTracesPerSecond is not set"))
	}
	return nil
}

func (p *RateLimitingSamplingStrategy) readField1(iprot thrift.TProtocol) error {
	if v, err := iprot.ReadI16(); err != nil {
		return thrift.PrependError("error reading field 1: ", err)
	} else {
		p.MaxTracesPerSecond = v
	}
	return nil
}

func (p *RateLimitingSamplingStrategy) Write(oprot thrift.TProtocol) error {
	if err := oprot.WriteStructBegin("RateLimitingSamplingStrategy"); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
	}
	if err := p.writeField1(oprot); err != nil {
		return err
	}
	if err := oprot.WriteFieldStop(); err != nil {
		return thrift.PrependError("write field stop error: ", err)
	}
	if err := oprot.WriteStructEnd(); err != nil {
		return thrift.PrependError("write struct stop error: ", err)
	}
	return nil
}

func (p *RateLimitingSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) {
	if err := oprot.WriteFieldBegin("maxTracesPerSecond", thrift.I16, 1); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:maxTracesPerSecond: ", p), err)
	}
	if err := oprot.WriteI16(int16(p.MaxTracesPerSecond)); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T.maxTracesPerSecond (1) field write error: ", p), err)
	}
	if err := oprot.WriteFieldEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field end error 1:maxTracesPerSecond: ", p), err)
	}
	return err
}

func (p *RateLimitingSamplingStrategy) String() string {
	if p == nil {
		return "<nil>"
	}
	return fmt.Sprintf("RateLimitingSamplingStrategy(%+v)", *p)
}

// Attributes:
//  - Operation
//  - ProbabilisticSampling
type OperationSamplingStrategy struct {
	Operation             string                         `thrift:"operation,1,required" json:"operation"`
	ProbabilisticSampling *ProbabilisticSamplingStrategy `thrift:"probabilisticSampling,2,required" json:"probabilisticSampling"`
}

func NewOperationSamplingStrategy() *OperationSamplingStrategy {
	return &OperationSamplingStrategy{}
}

func (p *OperationSamplingStrategy) GetOperation() string {
	return p.Operation
}

var OperationSamplingStrategy_ProbabilisticSampling_DEFAULT *ProbabilisticSamplingStrategy

func (p *OperationSamplingStrategy) GetProbabilisticSampling() *ProbabilisticSamplingStrategy {
	if !p.IsSetProbabilisticSampling() {
		return OperationSamplingStrategy_ProbabilisticSampling_DEFAULT
	}
	return p.ProbabilisticSampling
}
func (p *OperationSamplingStrategy) IsSetProbabilisticSampling() bool {
	return p.ProbabilisticSampling != nil
}

func (p *OperationSamplingStrategy) Read(iprot thrift.TProtocol) error {
	if _, err := iprot.ReadStructBegin(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
	}

	var issetOperation bool = false
	var issetProbabilisticSampling bool = false

	for {
		_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
		if err != nil {
			return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
		}
		if fieldTypeId == thrift.STOP {
			break
		}
		switch fieldId {
		case 1:
			if err := p.readField1(iprot); err != nil {
				return err
			}
			issetOperation = true
		case 2:
			if err := p.readField2(iprot); err != nil {
				return err
			}
			issetProbabilisticSampling = true
		default:
			if err := iprot.Skip(fieldTypeId); err != nil {
				return err
			}
		}
		if err := iprot.ReadFieldEnd(); err != nil {
			return err
		}
	}
	if err := iprot.ReadStructEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
	}
	if !issetOperation {
		return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Operation is not set"))
	}
	if !issetProbabilisticSampling {
		return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field ProbabilisticSampling is not set"))
	}
	return nil
}

func (p *OperationSamplingStrategy) readField1(iprot thrift.TProtocol) error {
	if v, err := iprot.ReadString(); err != nil {
		return thrift.PrependError("error reading field 1: ", err)
	} else {
		p.Operation = v
	}
	return nil
}

func (p *OperationSamplingStrategy) readField2(iprot thrift.TProtocol) error {
	p.ProbabilisticSampling = &ProbabilisticSamplingStrategy{}
	if err := p.ProbabilisticSampling.Read(iprot); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.ProbabilisticSampling), err)
	}
	return nil
}

func (p *OperationSamplingStrategy) Write(oprot thrift.TProtocol) error {
	if err := oprot.WriteStructBegin("OperationSamplingStrategy"); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
	}
	if err := p.writeField1(oprot); err != nil {
		return err
	}
	if err := p.writeField2(oprot); err != nil {
		return err
	}
	if err := oprot.WriteFieldStop(); err != nil {
		return thrift.PrependError("write field stop error: ", err)
	}
	if err := oprot.WriteStructEnd(); err != nil {
		return thrift.PrependError("write struct stop error: ", err)
	}
	return nil
}

func (p *OperationSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) {
	if err := oprot.WriteFieldBegin("operation", thrift.STRING, 1); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:operation: ", p), err)
	}
	if err := oprot.WriteString(string(p.Operation)); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T.operation (1) field write error: ", p), err)
	}
	if err := oprot.WriteFieldEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field end error 1:operation: ", p), err)
	}
	return err
}

func (p *OperationSamplingStrategy) writeField2(oprot thrift.TProtocol) (err error) {
	if err := oprot.WriteFieldBegin("probabilisticSampling", thrift.STRUCT, 2); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:probabilisticSampling: ", p), err)
	}
	if err := p.ProbabilisticSampling.Write(oprot); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.ProbabilisticSampling), err)
	}
	if err := oprot.WriteFieldEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field end error 2:probabilisticSampling: ", p), err)
	}
	return err
}

func (p *OperationSamplingStrategy) String() string {
	if p == nil {
		return "<nil>"
	}
	return fmt.Sprintf("OperationSamplingStrategy(%+v)", *p)
}

// Attributes:
//  - DefaultSamplingProbability
//  - DefaultLowerBoundTracesPerSecond
//  - PerOperationStrategies
//  - DefaultUpperBoundTracesPerSecond
type PerOperationSamplingStrategies struct {
	DefaultSamplingProbability       float64                      `thrift:"defaultSamplingProbability,1,required" json:"defaultSamplingProbability"`
	DefaultLowerBoundTracesPerSecond float64                      `thrift:"defaultLowerBoundTracesPerSecond,2,required" json:"defaultLowerBoundTracesPerSecond"`
	PerOperationStrategies           []*OperationSamplingStrategy `thrift:"perOperationStrategies,3,required" json:"perOperationStrategies"`
	DefaultUpperBoundTracesPerSecond *float64                     `thrift:"defaultUpperBoundTracesPerSecond,4" json:"defaultUpperBoundTracesPerSecond,omitempty"`
}

func NewPerOperationSamplingStrategies() *PerOperationSamplingStrategies {
	return &PerOperationSamplingStrategies{}
}

func (p *PerOperationSamplingStrategies) GetDefaultSamplingProbability() float64 {
	return p.DefaultSamplingProbability
}

func (p *PerOperationSamplingStrategies) GetDefaultLowerBoundTracesPerSecond() float64 {
	return p.DefaultLowerBoundTracesPerSecond
}

func (p *PerOperationSamplingStrategies) GetPerOperationStrategies() []*OperationSamplingStrategy {
	return p.PerOperationStrategies
}

var PerOperationSamplingStrategies_DefaultUpperBoundTracesPerSecond_DEFAULT float64

func (p *PerOperationSamplingStrategies) GetDefaultUpperBoundTracesPerSecond() float64 {
	if !p.IsSetDefaultUpperBoundTracesPerSecond() {
		return PerOperationSamplingStrategies_DefaultUpperBoundTracesPerSecond_DEFAULT
	}
	return *p.DefaultUpperBoundTracesPerSecond
}
func (p *PerOperationSamplingStrategies) IsSetDefaultUpperBoundTracesPerSecond() bool {
	return p.DefaultUpperBoundTracesPerSecond != nil
}

func (p *PerOperationSamplingStrategies) Read(iprot thrift.TProtocol) error {
	if _, err := iprot.ReadStructBegin(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
	}

	var issetDefaultSamplingProbability bool = false
	var issetDefaultLowerBoundTracesPerSecond bool = false
	var issetPerOperationStrategies bool = false

	for {
		_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
		if err != nil {
			return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
		}
		if fieldTypeId == thrift.STOP {
			break
		}
		switch fieldId {
		case 1:
			if err := p.readField1(iprot); err != nil {
				return err
			}
			issetDefaultSamplingProbability = true
		case 2:
			if err := p.readField2(iprot); err != nil {
				return err
			}
			issetDefaultLowerBoundTracesPerSecond = true
		case 3:
			if err := p.readField3(iprot); err != nil {
				return err
			}
			issetPerOperationStrategies = true
		case 4:
			if err := p.readField4(iprot); err != nil {
				return err
			}
		default:
			if err := iprot.Skip(fieldTypeId); err != nil {
				return err
			}
		}
		if err := iprot.ReadFieldEnd(); err != nil {
			return err
		}
	}
	if err := iprot.ReadStructEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
	}
	if !issetDefaultSamplingProbability {
		return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field DefaultSamplingProbability is not set"))
	}
	if !issetDefaultLowerBoundTracesPerSecond {
		return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field DefaultLowerBoundTracesPerSecond is not set"))
	}
	if !issetPerOperationStrategies {
		return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field PerOperationStrategies is not set"))
	}
	return nil
}

func (p *PerOperationSamplingStrategies) readField1(iprot thrift.TProtocol) error {
	if v, err := iprot.ReadDouble(); err != nil {
		return thrift.PrependError("error reading field 1: ", err)
	} else {
		p.DefaultSamplingProbability = v
	}
	return nil
}

func (p *PerOperationSamplingStrategies) readField2(iprot thrift.TProtocol) error {
	if v, err := iprot.ReadDouble(); err != nil {
		return thrift.PrependError("error reading field 2: ", err)
	} else {
		p.DefaultLowerBoundTracesPerSecond = v
	}
	return nil
}

func (p *PerOperationSamplingStrategies) readField3(iprot thrift.TProtocol) error {
	_, size, err := iprot.ReadListBegin()
	if err != nil {
		return thrift.PrependError("error reading list begin: ", err)
	}
	tSlice := make([]*OperationSamplingStrategy, 0, size)
	p.PerOperationStrategies = tSlice
	for i := 0; i < size; i++ {
		_elem0 := &OperationSamplingStrategy{}
		if err := _elem0.Read(iprot); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem0), err)
		}
		p.PerOperationStrategies = append(p.PerOperationStrategies, _elem0)
	}
	if err := iprot.ReadListEnd(); err != nil {
		return thrift.PrependError("error reading list end: ", err)
	}
	return nil
}

func (p *PerOperationSamplingStrategies) readField4(iprot thrift.TProtocol) error {
	if v, err := iprot.ReadDouble(); err != nil {
		return thrift.PrependError("error reading field 4: ", err)
	} else {
		p.DefaultUpperBoundTracesPerSecond = &v
	}
	return nil
}

func (p *PerOperationSamplingStrategies) Write(oprot thrift.TProtocol) error {
	if err := oprot.WriteStructBegin("PerOperationSamplingStrategies"); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
	}
	if err := p.writeField1(oprot); err != nil {
		return err
	}
	if err := p.writeField2(oprot); err != nil {
		return err
	}
	if err := p.writeField3(oprot); err != nil {
		return err
	}
	if err := p.writeField4(oprot); err != nil {
		return err
	}
	if err := oprot.WriteFieldStop(); err != nil {
		return thrift.PrependError("write field stop error: ", err)
	}
	if err := oprot.WriteStructEnd(); err != nil {
		return thrift.PrependError("write struct stop error: ", err)
	}
	return nil
}

func (p *PerOperationSamplingStrategies) writeField1(oprot thrift.TProtocol) (err error) {
	if err := oprot.WriteFieldBegin("defaultSamplingProbability", thrift.DOUBLE, 1); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:defaultSamplingProbability: ", p), err)
	}
	if err := oprot.WriteDouble(float64(p.DefaultSamplingProbability)); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T.defaultSamplingProbability (1) field write error: ", p), err)
	}
	if err := oprot.WriteFieldEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field end error 1:defaultSamplingProbability: ", p), err)
	}
	return err
}

func (p *PerOperationSamplingStrategies) writeField2(oprot thrift.TProtocol) (err error) {
	if err := oprot.WriteFieldBegin("defaultLowerBoundTracesPerSecond", thrift.DOUBLE, 2); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:defaultLowerBoundTracesPerSecond: ", p), err)
	}
	if err := oprot.WriteDouble(float64(p.DefaultLowerBoundTracesPerSecond)); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T.defaultLowerBoundTracesPerSecond (2) field write error: ", p), err)
	}
	if err := oprot.WriteFieldEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field end error 2:defaultLowerBoundTracesPerSecond: ", p), err)
	}
	return err
}

func (p *PerOperationSamplingStrategies) writeField3(oprot thrift.TProtocol) (err error) {
	if err := oprot.WriteFieldBegin("perOperationStrategies", thrift.LIST, 3); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:perOperationStrategies: ", p), err)
	}
	if err := oprot.WriteListBegin(thrift.STRUCT, len(p.PerOperationStrategies)); err != nil {
		return thrift.PrependError("error writing list begin: ", err)
	}
	for _, v := range p.PerOperationStrategies {
		if err := v.Write(oprot); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err)
		}
	}
	if err := oprot.WriteListEnd(); err != nil {
		return thrift.PrependError("error writing list end: ", err)
	}
	if err := oprot.WriteFieldEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field end error 3:perOperationStrategies: ", p), err)
	}
	return err
}

func (p *PerOperationSamplingStrategies) writeField4(oprot thrift.TProtocol) (err error) {
	if p.IsSetDefaultUpperBoundTracesPerSecond() {
		if err := oprot.WriteFieldBegin("defaultUpperBoundTracesPerSecond", thrift.DOUBLE, 4); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:defaultUpperBoundTracesPerSecond: ", p), err)
		}
		if err := oprot.WriteDouble(float64(*p.DefaultUpperBoundTracesPerSecond)); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T.defaultUpperBoundTracesPerSecond (4) field write error: ", p), err)
		}
		if err := oprot.WriteFieldEnd(); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T write field end error 4:defaultUpperBoundTracesPerSecond: ", p), err)
		}
	}
	return err
}

func (p *PerOperationSamplingStrategies) String() string {
	if p == nil {
		return "<nil>"
	}
	return fmt.Sprintf("PerOperationSamplingStrategies(%+v)", *p)
}

// Attributes:
//  - StrategyType
//  - ProbabilisticSampling
//  - RateLimitingSampling
//  - OperationSampling
type SamplingStrategyResponse struct {
	StrategyType          SamplingStrategyType            `thrift:"strategyType,1,required" json:"strategyType"`
	ProbabilisticSampling *ProbabilisticSamplingStrategy  `thrift:"probabilisticSampling,2" json:"probabilisticSampling,omitempty"`
	RateLimitingSampling  *RateLimitingSamplingStrategy   `thrift:"rateLimitingSampling,3" json:"rateLimitingSampling,omitempty"`
	OperationSampling     *PerOperationSamplingStrategies `thrift:"operationSampling,4" json:"operationSampling,omitempty"`
}

func NewSamplingStrategyResponse() *SamplingStrategyResponse {
	return &SamplingStrategyResponse{}
}

func (p *SamplingStrategyResponse) GetStrategyType() SamplingStrategyType {
	return p.StrategyType
}

var SamplingStrategyResponse_ProbabilisticSampling_DEFAULT *ProbabilisticSamplingStrategy

func (p *SamplingStrategyResponse) GetProbabilisticSampling() *ProbabilisticSamplingStrategy {
	if !p.IsSetProbabilisticSampling() {
		return SamplingStrategyResponse_ProbabilisticSampling_DEFAULT
	}
	return p.ProbabilisticSampling
}

var SamplingStrategyResponse_RateLimitingSampling_DEFAULT *RateLimitingSamplingStrategy

func (p *SamplingStrategyResponse) GetRateLimitingSampling() *RateLimitingSamplingStrategy {
	if !p.IsSetRateLimitingSampling() {
		return SamplingStrategyResponse_RateLimitingSampling_DEFAULT
	}
	return p.RateLimitingSampling
}

var SamplingStrategyResponse_OperationSampling_DEFAULT *PerOperationSamplingStrategies

func (p *SamplingStrategyResponse) GetOperationSampling() *PerOperationSamplingStrategies {
	if !p.IsSetOperationSampling() {
		return SamplingStrategyResponse_OperationSampling_DEFAULT
	}
	return p.OperationSampling
}
func (p *SamplingStrategyResponse) IsSetProbabilisticSampling() bool {
	return p.ProbabilisticSampling != nil
}

func (p *SamplingStrategyResponse) IsSetRateLimitingSampling() bool {
	return p.RateLimitingSampling != nil
}

func (p *SamplingStrategyResponse) IsSetOperationSampling() bool {
	return p.OperationSampling != nil
}

func (p *SamplingStrategyResponse) Read(iprot thrift.TProtocol) error {
	if _, err := iprot.ReadStructBegin(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
	}

	var issetStrategyType bool = false

	for {
		_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
		if err != nil {
			return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
		}
		if fieldTypeId == thrift.STOP {
			break
		}
		switch fieldId {
		case 1:
			if err := p.readField1(iprot); err != nil {
				return err
			}
			issetStrategyType = true
		case 2:
			if err := p.readField2(iprot); err != nil {
				return err
			}
		case 3:
			if err := p.readField3(iprot); err != nil {
				return err
			}
		case 4:
			if err := p.readField4(iprot); err != nil {
				return err
			}
		default:
			if err := iprot.Skip(fieldTypeId); err != nil {
				return err
			}
		}
		if err := iprot.ReadFieldEnd(); err != nil {
			return err
		}
	}
	if err := iprot.ReadStructEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
	}
	if !issetStrategyType {
		return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field StrategyType is not set"))
	}
	return nil
}

func (p *SamplingStrategyResponse) readField1(iprot thrift.TProtocol) error {
	if v, err := iprot.ReadI32(); err != nil {
		return thrift.PrependError("error reading field 1: ", err)
	} else {
		temp := SamplingStrategyType(v)
		p.StrategyType = temp
	}
	return nil
}

func (p *SamplingStrategyResponse) readField2(iprot thrift.TProtocol) error {
	p.ProbabilisticSampling = &ProbabilisticSamplingStrategy{}
	if err := p.ProbabilisticSampling.Read(iprot); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.ProbabilisticSampling), err)
	}
	return nil
}

func (p *SamplingStrategyResponse) readField3(iprot thrift.TProtocol) error {
	p.RateLimitingSampling = &RateLimitingSamplingStrategy{}
	if err := p.RateLimitingSampling.Read(iprot); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.RateLimitingSampling), err)
	}
	return nil
}

func (p *SamplingStrategyResponse) readField4(iprot thrift.TProtocol) error {
	p.OperationSampling = &PerOperationSamplingStrategies{}
	if err := p.OperationSampling.Read(iprot); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.OperationSampling), err)
	}
	return nil
}

func (p *SamplingStrategyResponse) Write(oprot thrift.TProtocol) error {
	if err := oprot.WriteStructBegin("SamplingStrategyResponse"); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
	}
	if err := p.writeField1(oprot); err != nil {
		return err
	}
	if err := p.writeField2(oprot); err != nil {
		return err
	}
	if err := p.writeField3(oprot); err != nil {
		return err
	}
	if err := p.writeField4(oprot); err != nil {
		return err
	}
	if err := oprot.WriteFieldStop(); err != nil {
		return thrift.PrependError("write field stop error: ", err)
	}
	if err := oprot.WriteStructEnd(); err != nil {
		return thrift.PrependError("write struct stop error: ", err)
	}
	return nil
}

func (p *SamplingStrategyResponse) writeField1(oprot thrift.TProtocol) (err error) {
	if err := oprot.WriteFieldBegin("strategyType", thrift.I32, 1); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:strategyType: ", p), err)
	}
	if err := oprot.WriteI32(int32(p.StrategyType)); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T.strategyType (1) field write error: ", p), err)
	}
	if err := oprot.WriteFieldEnd(); err != nil {
		return thrift.PrependError(fmt.Sprintf("%T write field end error 1:strategyType: ", p), err)
	}
	return err
}

func (p *SamplingStrategyResponse) writeField2(oprot thrift.TProtocol) (err error) {
	if p.IsSetProbabilisticSampling() {
		if err := oprot.WriteFieldBegin("probabilisticSampling", thrift.STRUCT, 2); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:probabilisticSampling: ", p), err)
		}
		if err := p.ProbabilisticSampling.Write(oprot); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.ProbabilisticSampling), err)
		}
		if err := oprot.WriteFieldEnd(); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T write field end error 2:probabilisticSampling: ", p), err)
		}
	}
	return err
}

func (p *SamplingStrategyResponse) writeField3(oprot thrift.TProtocol) (err error) {
	if p.IsSetRateLimitingSampling() {
		if err := oprot.WriteFieldBegin("rateLimitingSampling", thrift.STRUCT, 3); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:rateLimitingSampling: ", p), err)
		}
		if err := p.RateLimitingSampling.Write(oprot); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.RateLimitingSampling), err)
		}
		if err := oprot.WriteFieldEnd(); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T write field end error 3:rateLimitingSampling: ", p), err)
		}
	}
	return err
}

func (p *SamplingStrategyResponse) writeField4(oprot thrift.TProtocol) (err error) {
	if p.IsSetOperationSampling() {
		if err := oprot.WriteFieldBegin("operationSampling", thrift.STRUCT, 4); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:operationSampling: ", p), err)
		}
		if err := p.OperationSampling.Write(oprot); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.OperationSampling), err)
		}
		if err := oprot.WriteFieldEnd(); err != nil {
			return thrift.PrependError(fmt.Sprintf("%T write field end error 4:operationSampling: ", p), err)
		}
	}
	return err
}

func (p *SamplingStrategyResponse) String() string {
	if p == nil {
		return "<nil>"
	}
	return fmt.Sprintf("SamplingStrategyResponse(%+v)", *p)
}
