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
{
212 mappings
:= make(map[uint64]*Mapping
)
213 for _
, m
:= range p
.Mapping
{
214 m
.File
, err
= getString(p
.stringTable
, &m
.fileX
, err
)
215 m
.BuildID
, err
= getString(p
.stringTable
, &m
.buildIDX
, err
)
219 functions
:= make(map[uint64]*Function
)
220 for _
, f
:= range p
.Function
{
221 f
.Name
, err
= getString(p
.stringTable
, &f
.nameX
, err
)
222 f
.SystemName
, err
= getString(p
.stringTable
, &f
.systemNameX
, err
)
223 f
.Filename
, err
= getString(p
.stringTable
, &f
.filenameX
, err
)
227 locations
:= make(map[uint64]*Location
)
228 for _
, l
:= range p
.Location
{
229 l
.Mapping
= mappings
[l
.mappingIDX
]
231 for i
, ln
:= range l
.Line
{
232 if id
:= ln
.functionIDX
; id
!= 0 {
233 l
.Line
[i
].Function
= functions
[id
]
234 if l
.Line
[i
].Function
== nil {
235 return fmt
.Errorf("Function ID %d not found", id
)
237 l
.Line
[i
].functionIDX
= 0
243 for _
, st
:= range p
.SampleType
{
244 st
.Type
, err
= getString(p
.stringTable
, &st
.typeX
, err
)
245 st
.Unit
, err
= getString(p
.stringTable
, &st
.unitX
, err
)
248 for _
, s
:= range p
.Sample
{
249 labels
:= make(map[string][]string)
250 numLabels
:= make(map[string][]int64)
251 for _
, l
:= range s
.labelX
{
252 var key
, value
string
253 key
, err
= getString(p
.stringTable
, &l
.keyX
, err
)
255 value
, err
= getString(p
.stringTable
, &l
.strX
, err
)
256 labels
[key
] = append(labels
[key
], value
)
258 numLabels
[key
] = append(numLabels
[key
], l
.numX
)
264 if len(numLabels
) > 0 {
265 s
.NumLabel
= numLabels
268 for _
, lid
:= range s
.locationIDX
{
269 s
.Location
= append(s
.Location
, locations
[lid
])
274 p
.DropFrames
, err
= getString(p
.stringTable
, &p
.dropFramesX
, err
)
275 p
.KeepFrames
, err
= getString(p
.stringTable
, &p
.keepFramesX
, err
)
277 if pt
:= p
.PeriodType
; pt
== nil {
278 p
.PeriodType
= &ValueType
{}
281 if pt
:= p
.PeriodType
; pt
!= nil {
282 pt
.Type
, err
= getString(p
.stringTable
, &pt
.typeX
, err
)
283 pt
.Unit
, err
= getString(p
.stringTable
, &pt
.unitX
, err
)
285 for _
, i
:= range p
.commentX
{
287 c
, err
= getString(p
.stringTable
, &i
, err
)
288 p
.Comments
= append(p
.Comments
, c
)
292 p
.DefaultSampleType
, err
= getString(p
.stringTable
, &p
.defaultSampleTypeX
, err
)
297 func (p
*ValueType
) decoder() []decoder
{
298 return valueTypeDecoder
301 func (p
*ValueType
) encode(b
*buffer
) {
302 encodeInt64Opt(b
, 1, p
.typeX
)
303 encodeInt64Opt(b
, 2, p
.unitX
)
306 var valueTypeDecoder
= []decoder
{
308 // optional int64 type = 1
309 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*ValueType
).typeX
) },
310 // optional int64 unit = 2
311 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*ValueType
).unitX
) },
314 func (p
*Sample
) decoder() []decoder
{
318 func (p
*Sample
) encode(b
*buffer
) {
319 encodeUint64s(b
, 1, p
.locationIDX
)
320 for _
, x
:= range p
.Value
{
323 for _
, x
:= range p
.labelX
{
324 encodeMessage(b
, 3, x
)
328 var sampleDecoder
= []decoder
{
330 // repeated uint64 location = 1
331 func(b
*buffer
, m message
) error
{ return decodeUint64s(b
, &m
.(*Sample
).locationIDX
) },
332 // repeated int64 value = 2
333 func(b
*buffer
, m message
) error
{ return decodeInt64s(b
, &m
.(*Sample
).Value
) },
334 // repeated Label label = 3
335 func(b
*buffer
, m message
) error
{
338 s
.labelX
= append(s
.labelX
, Label
{})
339 return decodeMessage(b
, &s
.labelX
[n
])
343 func (p Label
) decoder() []decoder
{
347 func (p Label
) encode(b
*buffer
) {
348 encodeInt64Opt(b
, 1, p
.keyX
)
349 encodeInt64Opt(b
, 2, p
.strX
)
350 encodeInt64Opt(b
, 3, p
.numX
)
353 var labelDecoder
= []decoder
{
355 // optional int64 key = 1
356 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Label
).keyX
) },
357 // optional int64 str = 2
358 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Label
).strX
) },
359 // optional int64 num = 3
360 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Label
).numX
) },
363 func (p
*Mapping
) decoder() []decoder
{
364 return mappingDecoder
367 func (p
*Mapping
) encode(b
*buffer
) {
368 encodeUint64Opt(b
, 1, p
.ID
)
369 encodeUint64Opt(b
, 2, p
.Start
)
370 encodeUint64Opt(b
, 3, p
.Limit
)
371 encodeUint64Opt(b
, 4, p
.Offset
)
372 encodeInt64Opt(b
, 5, p
.fileX
)
373 encodeInt64Opt(b
, 6, p
.buildIDX
)
374 encodeBoolOpt(b
, 7, p
.HasFunctions
)
375 encodeBoolOpt(b
, 8, p
.HasFilenames
)
376 encodeBoolOpt(b
, 9, p
.HasLineNumbers
)
377 encodeBoolOpt(b
, 10, p
.HasInlineFrames
)
380 var mappingDecoder
= []decoder
{
382 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Mapping
).ID
) }, // optional uint64 id = 1
383 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Mapping
).Start
) }, // optional uint64 memory_offset = 2
384 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Mapping
).Limit
) }, // optional uint64 memory_limit = 3
385 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Mapping
).Offset
) }, // optional uint64 file_offset = 4
386 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Mapping
).fileX
) }, // optional int64 filename = 5
387 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Mapping
).buildIDX
) }, // optional int64 build_id = 6
388 func(b
*buffer
, m message
) error
{ return decodeBool(b
, &m
.(*Mapping
).HasFunctions
) }, // optional bool has_functions = 7
389 func(b
*buffer
, m message
) error
{ return decodeBool(b
, &m
.(*Mapping
).HasFilenames
) }, // optional bool has_filenames = 8
390 func(b
*buffer
, m message
) error
{ return decodeBool(b
, &m
.(*Mapping
).HasLineNumbers
) }, // optional bool has_line_numbers = 9
391 func(b
*buffer
, m message
) error
{ return decodeBool(b
, &m
.(*Mapping
).HasInlineFrames
) }, // optional bool has_inline_frames = 10
394 func (p
*Location
) decoder() []decoder
{
395 return locationDecoder
398 func (p
*Location
) encode(b
*buffer
) {
399 encodeUint64Opt(b
, 1, p
.ID
)
400 encodeUint64Opt(b
, 2, p
.mappingIDX
)
401 encodeUint64Opt(b
, 3, p
.Address
)
402 for i
:= range p
.Line
{
403 encodeMessage(b
, 4, &p
.Line
[i
])
407 var locationDecoder
= []decoder
{
409 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Location
).ID
) }, // optional uint64 id = 1;
410 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Location
).mappingIDX
) }, // optional uint64 mapping_id = 2;
411 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Location
).Address
) }, // optional uint64 address = 3;
412 func(b
*buffer
, m message
) error
{ // repeated Line line = 4
415 pp
.Line
= append(pp
.Line
, Line
{})
416 return decodeMessage(b
, &pp
.Line
[n
])
420 func (p
*Line
) decoder() []decoder
{
424 func (p
*Line
) encode(b
*buffer
) {
425 encodeUint64Opt(b
, 1, p
.functionIDX
)
426 encodeInt64Opt(b
, 2, p
.Line
)
429 var lineDecoder
= []decoder
{
431 // optional uint64 function_id = 1
432 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Line
).functionIDX
) },
433 // optional int64 line = 2
434 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Line
).Line
) },
437 func (p
*Function
) decoder() []decoder
{
438 return functionDecoder
441 func (p
*Function
) encode(b
*buffer
) {
442 encodeUint64Opt(b
, 1, p
.ID
)
443 encodeInt64Opt(b
, 2, p
.nameX
)
444 encodeInt64Opt(b
, 3, p
.systemNameX
)
445 encodeInt64Opt(b
, 4, p
.filenameX
)
446 encodeInt64Opt(b
, 5, p
.StartLine
)
449 var functionDecoder
= []decoder
{
451 // optional uint64 id = 1
452 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Function
).ID
) },
453 // optional int64 function_name = 2
454 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Function
).nameX
) },
455 // optional int64 function_system_name = 3
456 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Function
).systemNameX
) },
457 // repeated int64 filename = 4
458 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Function
).filenameX
) },
459 // optional int64 start_line = 5
460 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Function
).StartLine
) },
463 func addString(strings
map[string]int, s
string) int64 {
472 func getString(strings
[]string, strng
*int64, err error
) (string, error
) {
477 if s
< 0 || s
>= len(strings
) {
478 return "", errMalformed
481 return strings
[s
], nil