// Copyright 2014 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 profile

import (
	
	
	
)

func ( *Profile) () []decoder {
	return profileDecoder
}

// preEncode populates the unexported fields to be used by encode
// (with suffix X) from the corresponding exported fields. The
// exported fields are cleared up to facilitate testing.
func ( *Profile) () {
	 := make(map[string]int)
	addString(, "")

	for ,  := range .SampleType {
		.typeX = addString(, .Type)
		.unitX = addString(, .Unit)
	}

	for ,  := range .Sample {
		.labelX = nil
		var  []string
		for  := range .Label {
			 = append(, )
		}
		sort.Strings()
		for ,  := range  {
			 := .Label[]
			for ,  := range  {
				.labelX = append(.labelX,
					Label{
						keyX: addString(, ),
						strX: addString(, ),
					},
				)
			}
		}
		var  []string
		for  := range .NumLabel {
			 = append(, )
		}
		sort.Strings()
		for ,  := range  {
			 := .NumLabel[]
			for ,  := range  {
				.labelX = append(.labelX,
					Label{
						keyX: addString(, ),
						numX: ,
					},
				)
			}
		}
		.locationIDX = nil
		for ,  := range .Location {
			.locationIDX = append(.locationIDX, .ID)
		}
	}

	for ,  := range .Mapping {
		.fileX = addString(, .File)
		.buildIDX = addString(, .BuildID)
	}

	for ,  := range .Location {
		for ,  := range .Line {
			if .Function != nil {
				.Line[].functionIDX = .Function.ID
			} else {
				.Line[].functionIDX = 0
			}
		}
		if .Mapping != nil {
			.mappingIDX = .Mapping.ID
		} else {
			.mappingIDX = 0
		}
	}
	for ,  := range .Function {
		.nameX = addString(, .Name)
		.systemNameX = addString(, .SystemName)
		.filenameX = addString(, .Filename)
	}

	.dropFramesX = addString(, .DropFrames)
	.keepFramesX = addString(, .KeepFrames)

	if  := .PeriodType;  != nil {
		.typeX = addString(, .Type)
		.unitX = addString(, .Unit)
	}

	.stringTable = make([]string, len())
	for ,  := range  {
		.stringTable[] = 
	}
}

func ( *Profile) ( *buffer) {
	for ,  := range .SampleType {
		encodeMessage(, 1, )
	}
	for ,  := range .Sample {
		encodeMessage(, 2, )
	}
	for ,  := range .Mapping {
		encodeMessage(, 3, )
	}
	for ,  := range .Location {
		encodeMessage(, 4, )
	}
	for ,  := range .Function {
		encodeMessage(, 5, )
	}
	encodeStrings(, 6, .stringTable)
	encodeInt64Opt(, 7, .dropFramesX)
	encodeInt64Opt(, 8, .keepFramesX)
	encodeInt64Opt(, 9, .TimeNanos)
	encodeInt64Opt(, 10, .DurationNanos)
	if  := .PeriodType;  != nil && (.typeX != 0 || .unitX != 0) {
		encodeMessage(, 11, .PeriodType)
	}
	encodeInt64Opt(, 12, .Period)
}

var profileDecoder = []decoder{
	nil, // 0
	// repeated ValueType sample_type = 1
	func( *buffer,  message) error {
		 := new(ValueType)
		 := .(*Profile)
		.SampleType = append(.SampleType, )
		return decodeMessage(, )
	},
	// repeated Sample sample = 2
	func( *buffer,  message) error {
		 := new(Sample)
		 := .(*Profile)
		.Sample = append(.Sample, )
		return decodeMessage(, )
	},
	// repeated Mapping mapping = 3
	func( *buffer,  message) error {
		 := new(Mapping)
		 := .(*Profile)
		.Mapping = append(.Mapping, )
		return decodeMessage(, )
	},
	// repeated Location location = 4
	func( *buffer,  message) error {
		 := new(Location)
		 := .(*Profile)
		.Location = append(.Location, )
		return decodeMessage(, )
	},
	// repeated Function function = 5
	func( *buffer,  message) error {
		 := new(Function)
		 := .(*Profile)
		.Function = append(.Function, )
		return decodeMessage(, )
	},
	// repeated string string_table = 6
	func( *buffer,  message) error {
		 := decodeStrings(, &.(*Profile).stringTable)
		if  != nil {
			return 
		}
		if *&.(*Profile).stringTable[0] != "" {
			return errors.New("string_table[0] must be ''")
		}
		return nil
	},
	// repeated int64 drop_frames = 7
	func( *buffer,  message) error { return decodeInt64(, &.(*Profile).dropFramesX) },
	// repeated int64 keep_frames = 8
	func( *buffer,  message) error { return decodeInt64(, &.(*Profile).keepFramesX) },
	// repeated int64 time_nanos = 9
	func( *buffer,  message) error { return decodeInt64(, &.(*Profile).TimeNanos) },
	// repeated int64 duration_nanos = 10
	func( *buffer,  message) error { return decodeInt64(, &.(*Profile).DurationNanos) },
	// optional string period_type = 11
	func( *buffer,  message) error {
		 := new(ValueType)
		 := .(*Profile)
		.PeriodType = 
		return decodeMessage(, )
	},
	// repeated int64 period = 12
	func( *buffer,  message) error { return decodeInt64(, &.(*Profile).Period) },
	// repeated int64 comment = 13
	func( *buffer,  message) error { return decodeInt64s(, &.(*Profile).commentX) },
	// int64 defaultSampleType = 14
	func( *buffer,  message) error { return decodeInt64(, &.(*Profile).defaultSampleTypeX) },
}

// postDecode takes the unexported fields populated by decode (with
// suffix X) and populates the corresponding exported fields.
// The unexported fields are cleared up to facilitate testing.
func ( *Profile) () error {
	var  error

	 := make(map[uint64]*Mapping)
	for ,  := range .Mapping {
		.File,  = getString(.stringTable, &.fileX, )
		.BuildID,  = getString(.stringTable, &.buildIDX, )
		[.ID] = 
	}

	 := make(map[uint64]*Function)
	for ,  := range .Function {
		.Name,  = getString(.stringTable, &.nameX, )
		.SystemName,  = getString(.stringTable, &.systemNameX, )
		.Filename,  = getString(.stringTable, &.filenameX, )
		[.ID] = 
	}

	 := make(map[uint64]*Location)
	for ,  := range .Location {
		.Mapping = [.mappingIDX]
		.mappingIDX = 0
		for ,  := range .Line {
			if  := .functionIDX;  != 0 {
				.Line[].Function = []
				if .Line[].Function == nil {
					return fmt.Errorf("Function ID %d not found", )
				}
				.Line[].functionIDX = 0
			}
		}
		[.ID] = 
	}

	for ,  := range .SampleType {
		.Type,  = getString(.stringTable, &.typeX, )
		.Unit,  = getString(.stringTable, &.unitX, )
	}

	for ,  := range .Sample {
		 := make(map[string][]string)
		 := make(map[string][]int64)
		for ,  := range .labelX {
			var ,  string
			,  = getString(.stringTable, &.keyX, )
			if .strX != 0 {
				,  = getString(.stringTable, &.strX, )
				[] = append([], )
			} else {
				[] = append([], .numX)
			}
		}
		if len() > 0 {
			.Label = 
		}
		if len() > 0 {
			.NumLabel = 
		}
		.Location = nil
		for ,  := range .locationIDX {
			.Location = append(.Location, [])
		}
		.locationIDX = nil
	}

	.DropFrames,  = getString(.stringTable, &.dropFramesX, )
	.KeepFrames,  = getString(.stringTable, &.keepFramesX, )

	if  := .PeriodType;  == nil {
		.PeriodType = &ValueType{}
	}

	if  := .PeriodType;  != nil {
		.Type,  = getString(.stringTable, &.typeX, )
		.Unit,  = getString(.stringTable, &.unitX, )
	}
	for ,  := range .commentX {
		var  string
		,  = getString(.stringTable, &, )
		.Comments = append(.Comments, )
	}

	.commentX = nil
	.DefaultSampleType,  = getString(.stringTable, &.defaultSampleTypeX, )
	.stringTable = nil
	return nil
}

func ( *ValueType) () []decoder {
	return valueTypeDecoder
}

func ( *ValueType) ( *buffer) {
	encodeInt64Opt(, 1, .typeX)
	encodeInt64Opt(, 2, .unitX)
}

var valueTypeDecoder = []decoder{
	nil, // 0
	// optional int64 type = 1
	func( *buffer,  message) error { return decodeInt64(, &.(*ValueType).typeX) },
	// optional int64 unit = 2
	func( *buffer,  message) error { return decodeInt64(, &.(*ValueType).unitX) },
}

func ( *Sample) () []decoder {
	return sampleDecoder
}

func ( *Sample) ( *buffer) {
	encodeUint64s(, 1, .locationIDX)
	for ,  := range .Value {
		encodeInt64(, 2, )
	}
	for ,  := range .labelX {
		encodeMessage(, 3, )
	}
}

var sampleDecoder = []decoder{
	nil, // 0
	// repeated uint64 location = 1
	func( *buffer,  message) error { return decodeUint64s(, &.(*Sample).locationIDX) },
	// repeated int64 value = 2
	func( *buffer,  message) error { return decodeInt64s(, &.(*Sample).Value) },
	// repeated Label label = 3
	func( *buffer,  message) error {
		 := .(*Sample)
		 := len(.labelX)
		.labelX = append(.labelX, Label{})
		return decodeMessage(, &.labelX[])
	},
}

func ( Label) () []decoder {
	return labelDecoder
}

func ( Label) ( *buffer) {
	encodeInt64Opt(, 1, .keyX)
	encodeInt64Opt(, 2, .strX)
	encodeInt64Opt(, 3, .numX)
}

var labelDecoder = []decoder{
	nil, // 0
	// optional int64 key = 1
	func( *buffer,  message) error { return decodeInt64(, &.(*Label).keyX) },
	// optional int64 str = 2
	func( *buffer,  message) error { return decodeInt64(, &.(*Label).strX) },
	// optional int64 num = 3
	func( *buffer,  message) error { return decodeInt64(, &.(*Label).numX) },
}

func ( *Mapping) () []decoder {
	return mappingDecoder
}

func ( *Mapping) ( *buffer) {
	encodeUint64Opt(, 1, .ID)
	encodeUint64Opt(, 2, .Start)
	encodeUint64Opt(, 3, .Limit)
	encodeUint64Opt(, 4, .Offset)
	encodeInt64Opt(, 5, .fileX)
	encodeInt64Opt(, 6, .buildIDX)
	encodeBoolOpt(, 7, .HasFunctions)
	encodeBoolOpt(, 8, .HasFilenames)
	encodeBoolOpt(, 9, .HasLineNumbers)
	encodeBoolOpt(, 10, .HasInlineFrames)
}

var mappingDecoder = []decoder{
	nil, // 0
	func( *buffer,  message) error { return decodeUint64(, &.(*Mapping).ID) },            // optional uint64 id = 1
	func( *buffer,  message) error { return decodeUint64(, &.(*Mapping).Start) },         // optional uint64 memory_offset = 2
	func( *buffer,  message) error { return decodeUint64(, &.(*Mapping).Limit) },         // optional uint64 memory_limit = 3
	func( *buffer,  message) error { return decodeUint64(, &.(*Mapping).Offset) },        // optional uint64 file_offset = 4
	func( *buffer,  message) error { return decodeInt64(, &.(*Mapping).fileX) },          // optional int64 filename = 5
	func( *buffer,  message) error { return decodeInt64(, &.(*Mapping).buildIDX) },       // optional int64 build_id = 6
	func( *buffer,  message) error { return decodeBool(, &.(*Mapping).HasFunctions) },    // optional bool has_functions = 7
	func( *buffer,  message) error { return decodeBool(, &.(*Mapping).HasFilenames) },    // optional bool has_filenames = 8
	func( *buffer,  message) error { return decodeBool(, &.(*Mapping).HasLineNumbers) },  // optional bool has_line_numbers = 9
	func( *buffer,  message) error { return decodeBool(, &.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10
}

func ( *Location) () []decoder {
	return locationDecoder
}

func ( *Location) ( *buffer) {
	encodeUint64Opt(, 1, .ID)
	encodeUint64Opt(, 2, .mappingIDX)
	encodeUint64Opt(, 3, .Address)
	for  := range .Line {
		encodeMessage(, 4, &.Line[])
	}
}

var locationDecoder = []decoder{
	nil, // 0
	func( *buffer,  message) error { return decodeUint64(, &.(*Location).ID) },         // optional uint64 id = 1;
	func( *buffer,  message) error { return decodeUint64(, &.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2;
	func( *buffer,  message) error { return decodeUint64(, &.(*Location).Address) },    // optional uint64 address = 3;
	func( *buffer,  message) error { // repeated Line line = 4
		 := .(*Location)
		 := len(.Line)
		.Line = append(.Line, Line{})
		return decodeMessage(, &.Line[])
	},
}

func ( *Line) () []decoder {
	return lineDecoder
}

func ( *Line) ( *buffer) {
	encodeUint64Opt(, 1, .functionIDX)
	encodeInt64Opt(, 2, .Line)
}

var lineDecoder = []decoder{
	nil, // 0
	// optional uint64 function_id = 1
	func( *buffer,  message) error { return decodeUint64(, &.(*Line).functionIDX) },
	// optional int64 line = 2
	func( *buffer,  message) error { return decodeInt64(, &.(*Line).Line) },
}

func ( *Function) () []decoder {
	return functionDecoder
}

func ( *Function) ( *buffer) {
	encodeUint64Opt(, 1, .ID)
	encodeInt64Opt(, 2, .nameX)
	encodeInt64Opt(, 3, .systemNameX)
	encodeInt64Opt(, 4, .filenameX)
	encodeInt64Opt(, 5, .StartLine)
}

var functionDecoder = []decoder{
	nil, // 0
	// optional uint64 id = 1
	func( *buffer,  message) error { return decodeUint64(, &.(*Function).ID) },
	// optional int64 function_name = 2
	func( *buffer,  message) error { return decodeInt64(, &.(*Function).nameX) },
	// optional int64 function_system_name = 3
	func( *buffer,  message) error { return decodeInt64(, &.(*Function).systemNameX) },
	// repeated int64 filename = 4
	func( *buffer,  message) error { return decodeInt64(, &.(*Function).filenameX) },
	// optional int64 start_line = 5
	func( *buffer,  message) error { return decodeInt64(, &.(*Function).StartLine) },
}

func addString( map[string]int,  string) int64 {
	,  := []
	if ! {
		 = len()
		[] = 
	}
	return int64()
}

func getString( []string,  *int64,  error) (string, error) {
	if  != nil {
		return "", 
	}
	 := int(*)
	if  < 0 ||  >= len() {
		return "", errMalformed
	}
	* = 0
	return [], nil
}