github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/gopkg.in/sourcemap.v1/consumer.go (about) 1 package sourcemap 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/url" 7 "path" 8 "sort" 9 "strconv" 10 ) 11 12 type Consumer struct { 13 sourceRootURL *url.URL 14 smap *sourceMap 15 mappings []mapping 16 } 17 18 func Parse(mapURL string, b []byte) (*Consumer, error) { 19 smap := new(sourceMap) 20 err := json.Unmarshal(b, smap) 21 if err != nil { 22 return nil, err 23 } 24 25 if smap.Version != 3 { 26 return nil, fmt.Errorf( 27 "sourcemap: got version=%d, but only 3rd version is supported", 28 smap.Version, 29 ) 30 } 31 32 var sourceRootURL *url.URL 33 if smap.SourceRoot != "" { 34 u, err := url.Parse(smap.SourceRoot) 35 if err != nil { 36 return nil, err 37 } 38 if u.IsAbs() { 39 sourceRootURL = u 40 } 41 } else if mapURL != "" { 42 u, err := url.Parse(mapURL) 43 if err != nil { 44 return nil, err 45 } 46 if u.IsAbs() { 47 u.Path = path.Dir(u.Path) 48 sourceRootURL = u 49 } 50 } 51 52 mappings, err := parseMappings(smap.Mappings) 53 if err != nil { 54 return nil, err 55 } 56 // Free memory. 57 smap.Mappings = "" 58 59 return &Consumer{ 60 sourceRootURL: sourceRootURL, 61 smap: smap, 62 mappings: mappings, 63 }, nil 64 } 65 66 func (c *Consumer) File() string { 67 return c.smap.File 68 } 69 70 func (c *Consumer) Source(genLine, genCol int) (source, name string, line, col int, ok bool) { 71 i := sort.Search(len(c.mappings), func(i int) bool { 72 m := &c.mappings[i] 73 if m.genLine == genLine { 74 return m.genCol >= genCol 75 } 76 return m.genLine >= genLine 77 }) 78 79 // Mapping not found. 80 if i == len(c.mappings) { 81 return 82 } 83 84 match := &c.mappings[i] 85 86 // Fuzzy match. 87 if match.genLine > genLine || match.genCol > genCol { 88 if i == 0 { 89 return 90 } 91 match = &c.mappings[i-1] 92 } 93 94 if match.sourcesInd >= 0 { 95 source = c.absSource(c.smap.Sources[match.sourcesInd]) 96 } 97 if match.namesInd >= 0 { 98 v := c.smap.Names[match.namesInd] 99 switch v := v.(type) { 100 case string: 101 name = v 102 case float64: 103 name = strconv.FormatFloat(v, 'f', -1, 64) 104 default: 105 name = fmt.Sprint(v) 106 } 107 } 108 line = match.sourceLine 109 col = match.sourceCol 110 ok = true 111 return 112 } 113 114 func (c *Consumer) absSource(source string) string { 115 if path.IsAbs(source) { 116 return source 117 } 118 119 if u, err := url.Parse(source); err == nil && u.IsAbs() { 120 return source 121 } 122 123 if c.sourceRootURL != nil { 124 u := *c.sourceRootURL 125 u.Path = path.Join(c.sourceRootURL.Path, source) 126 return u.String() 127 } 128 129 if c.smap.SourceRoot != "" { 130 return path.Join(c.smap.SourceRoot, source) 131 } 132 133 return source 134 }