1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 func (p *Profile) decoder() []decoder {
17 // preEncode populates the unexported fields to be used by encode
18 // (with suffix X) from the corresponding exported fields. The
19 // exported fields are cleared up to facilitate testing.
20 func (p *Profile) preEncode() {
21 strings := make(map[string]int)
22 addString(strings, "")
24 for _, st := range p.SampleType {
25 st.typeX = addString(strings, st.Type)
26 st.unitX = addString(strings, st.Unit)
29 for _, s := range p.Sample {
32 for k := range s.Label {
33 keys = append(keys, k)
36 for _, k := range keys {
38 for _, v := range vs {
39 s.labelX = append(s.labelX,
41 keyX: addString(strings, k),
42 strX: addString(strings, v),
48 for k := range s.NumLabel {
49 numKeys = append(numKeys, k)
52 for _, k := range numKeys {
54 for _, v := range vs {
55 s.labelX = append(s.labelX,
57 keyX: addString(strings, k),
64 for _, l := range s.Location {
65 s.locationIDX = append(s.locationIDX, l.ID)
69 for _, m := range p.Mapping {
70 m.fileX = addString(strings, m.File)
71 m.buildIDX = addString(strings, m.BuildID)
74 for _, l := range p.Location {
75 for i, ln := range l.Line {
76 if ln.Function != nil {
77 l.Line[i].functionIDX = ln.Function.ID
79 l.Line[i].functionIDX = 0
83 l.mappingIDX = l.Mapping.ID
88 for _, f := range p.Function {
89 f.nameX = addString(strings, f.Name)
90 f.systemNameX = addString(strings, f.SystemName)
91 f.filenameX = addString(strings, f.Filename)
94 p.dropFramesX = addString(strings, p.DropFrames)
95 p.keepFramesX = addString(strings, p.KeepFrames)
97 if pt := p.PeriodType; pt != nil {
98 pt.typeX = addString(strings, pt.Type)
99 pt.unitX = addString(strings, pt.Unit)
102 p.stringTable = make([]string, len(strings))
103 for s, i := range strings {
108 func (p *Profile) encode(b *buffer) {
109 for _, x := range p.SampleType {
110 encodeMessage(b, 1, x)
112 for _, x := range p.Sample {
113 encodeMessage(b, 2, x)
115 for _, x := range p.Mapping {
116 encodeMessage(b, 3, x)
118 for _, x := range p.Location {
119 encodeMessage(b, 4, x)
121 for _, x := range p.Function {
122 encodeMessage(b, 5, x)
124 encodeStrings(b, 6, p.stringTable)
125 encodeInt64Opt(b, 7, p.dropFramesX)
126 encodeInt64Opt(b, 8, p.keepFramesX)
127 encodeInt64Opt(b, 9, p.TimeNanos)
128 encodeInt64Opt(b, 10, p.DurationNanos)
129 if pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) {
130 encodeMessage(b, 11, p.PeriodType)
132 encodeInt64Opt(b, 12, p.Period)
135 var profileDecoder = []decoder{
137 // repeated ValueType sample_type = 1
138 func(b *buffer, m message) error {
141 pp.SampleType = append(pp.SampleType, x)
142 return decodeMessage(b, x)
144 // repeated Sample sample = 2
145 func(b *buffer, m message) error {
148 pp.Sample = append(pp.Sample, x)
149 return decodeMessage(b, x)
151 // repeated Mapping mapping = 3
152 func(b *buffer, m message) error {
155 pp.Mapping = append(pp.Mapping, x)
156 return decodeMessage(b, x)
158 // repeated Location location = 4
159 func(b *buffer, m message) error {
162 pp.Location = append(pp.Location, x)
163 return decodeMessage(b, x)
165 // repeated Function function = 5
166 func(b *buffer, m message) error {
169 pp.Function = append(pp.Function, x)
170 return decodeMessage(b, x)
172 // repeated string string_table = 6
173 func(b *buffer, m message) error {
174 err := decodeStrings(b, &m.(*Profile).stringTable)
178 if m.(*Profile).stringTable[0] != "" {
179 return errors.New("string_table[0] must be ''")
183 // repeated int64 drop_frames = 7
184 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) },
185 // repeated int64 keep_frames = 8
186 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) },
187 // repeated int64 time_nanos = 9
188 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).TimeNanos) },
189 // repeated int64 duration_nanos = 10
190 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) },
191 // optional string period_type = 11
192 func(b *buffer, m message) error {
196 return decodeMessage(b, x)
198 // repeated int64 period = 12
199 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) },
200 // repeated int64 comment = 13
201 func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) },
202 // int64 defaultSampleType = 14
203 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) },
206 // postDecode takes the unexported fields populated by decode (with
207 // suffix X) and populates the corresponding exported fields.
208 // The unexported fields are cleared up to facilitate testing.
209 func (p *Profile) postDecode() error {
215 mappings := make(map[uint64]*Mapping)
216 for _, m := range p.Mapping {
217 m.File, err = getString(p.stringTable, &m.fileX, err)
218 m.BuildID, err = getString(p.stringTable, &m.buildIDX, err)
222 functions := make(map[uint64]*Function)
223 for _, f := range p.Function {
224 f.Name, err = getString(p.stringTable, &f.nameX, err)
225 f.SystemName, err = getString(p.stringTable, &f.systemNameX, err)
226 f.Filename, err = getString(p.stringTable, &f.filenameX, err)
230 locations := make(map[uint64]*Location)
231 for _, l := range p.Location {
232 l.Mapping = mappings[l.mappingIDX]
234 for i, ln := range l.Line {
235 if id := ln.functionIDX; id != 0 {
236 l.Line[i].Function = functions[id]
237 if l.Line[i].Function == nil {
238 return fmt.Errorf("Function ID %d not found", id)
240 l.Line[i].functionIDX = 0
246 for _, st := range p.SampleType {
247 st.Type, err = getString(p.stringTable, &st.typeX, err)
248 st.Unit, err = getString(p.stringTable, &st.unitX, err)
251 for _, s := range p.Sample {
252 labels := make(map[string][]string)
253 numLabels := make(map[string][]int64)
254 for _, l := range s.labelX {
255 var key, value string
256 key, err = getString(p.stringTable, &l.keyX, err)
258 value, err = getString(p.stringTable, &l.strX, err)
259 labels[key] = append(labels[key], value)
261 numLabels[key] = append(numLabels[key], l.numX)
267 if len(numLabels) > 0 {
268 s.NumLabel = numLabels
271 for _, lid := range s.locationIDX {
272 s.Location = append(s.Location, locations[lid])
277 p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err)
278 p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err)
280 if pt := p.PeriodType; pt == nil {
281 p.PeriodType = &ValueType{}
284 if pt := p.PeriodType; pt != nil {
285 pt.Type, err = getString(p.stringTable, &pt.typeX, err)
286 pt.Unit, err = getString(p.stringTable, &pt.unitX, err)
288 for _, i := range p.commentX {
290 c, err = getString(p.stringTable, &i, err)
291 p.Comments = append(p.Comments, c)
295 p.DefaultSampleType, err = getString(p.stringTable, &p.defaultSampleTypeX, err)
300 func (p *ValueType) decoder() []decoder {
301 return valueTypeDecoder
304 func (p *ValueType) encode(b *buffer) {
305 encodeInt64Opt(b, 1, p.typeX)
306 encodeInt64Opt(b, 2, p.unitX)
309 var valueTypeDecoder = []decoder{
311 // optional int64 type = 1
312 func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) },
313 // optional int64 unit = 2
314 func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) },
317 func (p *Sample) decoder() []decoder {
321 func (p *Sample) encode(b *buffer) {
322 encodeUint64s(b, 1, p.locationIDX)
323 for _, x := range p.Value {
326 for _, x := range p.labelX {
327 encodeMessage(b, 3, x)
331 var sampleDecoder = []decoder{
333 // repeated uint64 location = 1
334 func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) },
335 // repeated int64 value = 2
336 func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) },
337 // repeated Label label = 3
338 func(b *buffer, m message) error {
341 s.labelX = append(s.labelX, Label{})
342 return decodeMessage(b, &s.labelX[n])
346 func (p Label) decoder() []decoder {
350 func (p Label) encode(b *buffer) {
351 encodeInt64Opt(b, 1, p.keyX)
352 encodeInt64Opt(b, 2, p.strX)
353 encodeInt64Opt(b, 3, p.numX)
356 var labelDecoder = []decoder{
358 // optional int64 key = 1
359 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).keyX) },
360 // optional int64 str = 2
361 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).strX) },
362 // optional int64 num = 3
363 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).numX) },
366 func (p *Mapping) decoder() []decoder {
367 return mappingDecoder
370 func (p *Mapping) encode(b *buffer) {
371 encodeUint64Opt(b, 1, p.ID)
372 encodeUint64Opt(b, 2, p.Start)
373 encodeUint64Opt(b, 3, p.Limit)
374 encodeUint64Opt(b, 4, p.Offset)
375 encodeInt64Opt(b, 5, p.fileX)
376 encodeInt64Opt(b, 6, p.buildIDX)
377 encodeBoolOpt(b, 7, p.HasFunctions)
378 encodeBoolOpt(b, 8, p.HasFilenames)
379 encodeBoolOpt(b, 9, p.HasLineNumbers)
380 encodeBoolOpt(b, 10, p.HasInlineFrames)
383 var mappingDecoder = []decoder{
385 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) }, // optional uint64 id = 1
386 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) }, // optional uint64 memory_offset = 2
387 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) }, // optional uint64 memory_limit = 3
388 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) }, // optional uint64 file_offset = 4
389 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) }, // optional int64 filename = 5
390 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) }, // optional int64 build_id = 6
391 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) }, // optional bool has_functions = 7
392 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) }, // optional bool has_filenames = 8
393 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) }, // optional bool has_line_numbers = 9
394 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10
397 func (p *Location) decoder() []decoder {
398 return locationDecoder
401 func (p *Location) encode(b *buffer) {
402 encodeUint64Opt(b, 1, p.ID)
403 encodeUint64Opt(b, 2, p.mappingIDX)
404 encodeUint64Opt(b, 3, p.Address)
405 for i := range p.Line {
406 encodeMessage(b, 4, &p.Line[i])
410 var locationDecoder = []decoder{
412 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) }, // optional uint64 id = 1;
413 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2;
414 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) }, // optional uint64 address = 3;
415 func(b *buffer, m message) error { // repeated Line line = 4
418 pp.Line = append(pp.Line, Line{})
419 return decodeMessage(b, &pp.Line[n])
423 func (p *Line) decoder() []decoder {
427 func (p *Line) encode(b *buffer) {
428 encodeUint64Opt(b, 1, p.functionIDX)
429 encodeInt64Opt(b, 2, p.Line)
432 var lineDecoder = []decoder{
434 // optional uint64 function_id = 1
435 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },
436 // optional int64 line = 2
437 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) },
440 func (p *Function) decoder() []decoder {
441 return functionDecoder
444 func (p *Function) encode(b *buffer) {
445 encodeUint64Opt(b, 1, p.ID)
446 encodeInt64Opt(b, 2, p.nameX)
447 encodeInt64Opt(b, 3, p.systemNameX)
448 encodeInt64Opt(b, 4, p.filenameX)
449 encodeInt64Opt(b, 5, p.StartLine)
452 var functionDecoder = []decoder{
454 // optional uint64 id = 1
455 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) },
456 // optional int64 function_name = 2
457 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) },
458 // optional int64 function_system_name = 3
459 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) },
460 // repeated int64 filename = 4
461 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) },
462 // optional int64 start_line = 5
463 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) },
466 func addString(strings map[string]int, s string) int64 {
475 func getString(strings []string, strng *int64, err error) (string, error) {
480 if s < 0 || s >= len(strings) {
481 return "", errMalformed
484 return strings[s], nil