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
) },
202 // postDecode takes the unexported fields populated by decode (with
203 // suffix X) and populates the corresponding exported fields.
204 // The unexported fields are cleared up to facilitate testing.
205 func (p
*Profile
) postDecode() error
{
208 mappings
:= make(map[uint64]*Mapping
)
209 for _
, m
:= range p
.Mapping
{
210 m
.File
, err
= getString(p
.stringTable
, &m
.fileX
, err
)
211 m
.BuildID
, err
= getString(p
.stringTable
, &m
.buildIDX
, err
)
215 functions
:= make(map[uint64]*Function
)
216 for _
, f
:= range p
.Function
{
217 f
.Name
, err
= getString(p
.stringTable
, &f
.nameX
, err
)
218 f
.SystemName
, err
= getString(p
.stringTable
, &f
.systemNameX
, err
)
219 f
.Filename
, err
= getString(p
.stringTable
, &f
.filenameX
, err
)
223 locations
:= make(map[uint64]*Location
)
224 for _
, l
:= range p
.Location
{
225 l
.Mapping
= mappings
[l
.mappingIDX
]
227 for i
, ln
:= range l
.Line
{
228 if id
:= ln
.functionIDX
; id
!= 0 {
229 l
.Line
[i
].Function
= functions
[id
]
230 if l
.Line
[i
].Function
== nil {
231 return fmt
.Errorf("Function ID %d not found", id
)
233 l
.Line
[i
].functionIDX
= 0
239 for _
, st
:= range p
.SampleType
{
240 st
.Type
, err
= getString(p
.stringTable
, &st
.typeX
, err
)
241 st
.Unit
, err
= getString(p
.stringTable
, &st
.unitX
, err
)
244 for _
, s
:= range p
.Sample
{
245 labels
:= make(map[string][]string)
246 numLabels
:= make(map[string][]int64)
247 for _
, l
:= range s
.labelX
{
248 var key
, value
string
249 key
, err
= getString(p
.stringTable
, &l
.keyX
, err
)
251 value
, err
= getString(p
.stringTable
, &l
.strX
, err
)
252 labels
[key
] = append(labels
[key
], value
)
254 numLabels
[key
] = append(numLabels
[key
], l
.numX
)
260 if len(numLabels
) > 0 {
261 s
.NumLabel
= numLabels
264 for _
, lid
:= range s
.locationIDX
{
265 s
.Location
= append(s
.Location
, locations
[lid
])
270 p
.DropFrames
, err
= getString(p
.stringTable
, &p
.dropFramesX
, err
)
271 p
.KeepFrames
, err
= getString(p
.stringTable
, &p
.keepFramesX
, err
)
273 if pt
:= p
.PeriodType
; pt
== nil {
274 p
.PeriodType
= &ValueType
{}
277 if pt
:= p
.PeriodType
; pt
!= nil {
278 pt
.Type
, err
= getString(p
.stringTable
, &pt
.typeX
, err
)
279 pt
.Unit
, err
= getString(p
.stringTable
, &pt
.unitX
, err
)
285 func (p
*ValueType
) decoder() []decoder
{
286 return valueTypeDecoder
289 func (p
*ValueType
) encode(b
*buffer
) {
290 encodeInt64Opt(b
, 1, p
.typeX
)
291 encodeInt64Opt(b
, 2, p
.unitX
)
294 var valueTypeDecoder
= []decoder
{
296 // optional int64 type = 1
297 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*ValueType
).typeX
) },
298 // optional int64 unit = 2
299 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*ValueType
).unitX
) },
302 func (p
*Sample
) decoder() []decoder
{
306 func (p
*Sample
) encode(b
*buffer
) {
307 encodeUint64s(b
, 1, p
.locationIDX
)
308 for _
, x
:= range p
.Value
{
311 for _
, x
:= range p
.labelX
{
312 encodeMessage(b
, 3, x
)
316 var sampleDecoder
= []decoder
{
318 // repeated uint64 location = 1
319 func(b
*buffer
, m message
) error
{ return decodeUint64s(b
, &m
.(*Sample
).locationIDX
) },
320 // repeated int64 value = 2
321 func(b
*buffer
, m message
) error
{ return decodeInt64s(b
, &m
.(*Sample
).Value
) },
322 // repeated Label label = 3
323 func(b
*buffer
, m message
) error
{
326 s
.labelX
= append(s
.labelX
, Label
{})
327 return decodeMessage(b
, &s
.labelX
[n
])
331 func (p Label
) decoder() []decoder
{
335 func (p Label
) encode(b
*buffer
) {
336 encodeInt64Opt(b
, 1, p
.keyX
)
337 encodeInt64Opt(b
, 2, p
.strX
)
338 encodeInt64Opt(b
, 3, p
.numX
)
341 var labelDecoder
= []decoder
{
343 // optional int64 key = 1
344 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Label
).keyX
) },
345 // optional int64 str = 2
346 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Label
).strX
) },
347 // optional int64 num = 3
348 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Label
).numX
) },
351 func (p
*Mapping
) decoder() []decoder
{
352 return mappingDecoder
355 func (p
*Mapping
) encode(b
*buffer
) {
356 encodeUint64Opt(b
, 1, p
.ID
)
357 encodeUint64Opt(b
, 2, p
.Start
)
358 encodeUint64Opt(b
, 3, p
.Limit
)
359 encodeUint64Opt(b
, 4, p
.Offset
)
360 encodeInt64Opt(b
, 5, p
.fileX
)
361 encodeInt64Opt(b
, 6, p
.buildIDX
)
362 encodeBoolOpt(b
, 7, p
.HasFunctions
)
363 encodeBoolOpt(b
, 8, p
.HasFilenames
)
364 encodeBoolOpt(b
, 9, p
.HasLineNumbers
)
365 encodeBoolOpt(b
, 10, p
.HasInlineFrames
)
368 var mappingDecoder
= []decoder
{
370 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Mapping
).ID
) }, // optional uint64 id = 1
371 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Mapping
).Start
) }, // optional uint64 memory_offset = 2
372 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Mapping
).Limit
) }, // optional uint64 memory_limit = 3
373 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Mapping
).Offset
) }, // optional uint64 file_offset = 4
374 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Mapping
).fileX
) }, // optional int64 filename = 5
375 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Mapping
).buildIDX
) }, // optional int64 build_id = 6
376 func(b
*buffer
, m message
) error
{ return decodeBool(b
, &m
.(*Mapping
).HasFunctions
) }, // optional bool has_functions = 7
377 func(b
*buffer
, m message
) error
{ return decodeBool(b
, &m
.(*Mapping
).HasFilenames
) }, // optional bool has_filenames = 8
378 func(b
*buffer
, m message
) error
{ return decodeBool(b
, &m
.(*Mapping
).HasLineNumbers
) }, // optional bool has_line_numbers = 9
379 func(b
*buffer
, m message
) error
{ return decodeBool(b
, &m
.(*Mapping
).HasInlineFrames
) }, // optional bool has_inline_frames = 10
382 func (p
*Location
) decoder() []decoder
{
383 return locationDecoder
386 func (p
*Location
) encode(b
*buffer
) {
387 encodeUint64Opt(b
, 1, p
.ID
)
388 encodeUint64Opt(b
, 2, p
.mappingIDX
)
389 encodeUint64Opt(b
, 3, p
.Address
)
390 for i
:= range p
.Line
{
391 encodeMessage(b
, 4, &p
.Line
[i
])
395 var locationDecoder
= []decoder
{
397 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Location
).ID
) }, // optional uint64 id = 1;
398 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Location
).mappingIDX
) }, // optional uint64 mapping_id = 2;
399 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Location
).Address
) }, // optional uint64 address = 3;
400 func(b
*buffer
, m message
) error
{ // repeated Line line = 4
403 pp
.Line
= append(pp
.Line
, Line
{})
404 return decodeMessage(b
, &pp
.Line
[n
])
408 func (p
*Line
) decoder() []decoder
{
412 func (p
*Line
) encode(b
*buffer
) {
413 encodeUint64Opt(b
, 1, p
.functionIDX
)
414 encodeInt64Opt(b
, 2, p
.Line
)
417 var lineDecoder
= []decoder
{
419 // optional uint64 function_id = 1
420 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Line
).functionIDX
) },
421 // optional int64 line = 2
422 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Line
).Line
) },
425 func (p
*Function
) decoder() []decoder
{
426 return functionDecoder
429 func (p
*Function
) encode(b
*buffer
) {
430 encodeUint64Opt(b
, 1, p
.ID
)
431 encodeInt64Opt(b
, 2, p
.nameX
)
432 encodeInt64Opt(b
, 3, p
.systemNameX
)
433 encodeInt64Opt(b
, 4, p
.filenameX
)
434 encodeInt64Opt(b
, 5, p
.StartLine
)
437 var functionDecoder
= []decoder
{
439 // optional uint64 id = 1
440 func(b
*buffer
, m message
) error
{ return decodeUint64(b
, &m
.(*Function
).ID
) },
441 // optional int64 function_name = 2
442 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Function
).nameX
) },
443 // optional int64 function_system_name = 3
444 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Function
).systemNameX
) },
445 // repeated int64 filename = 4
446 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Function
).filenameX
) },
447 // optional int64 start_line = 5
448 func(b
*buffer
, m message
) error
{ return decodeInt64(b
, &m
.(*Function
).StartLine
) },
451 func addString(strings
map[string]int, s
string) int64 {
460 func getString(strings
[]string, strng
*int64, err error
) (string, error
) {
465 if s
< 0 || s
>= len(strings
) {
466 return "", errMalformed
469 return strings
[s
], nil