cuelang.org/go@v0.10.1/internal/core/runtime/index.go (about) 1 // Copyright 2020 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runtime 16 17 import ( 18 "sync" 19 20 "cuelang.org/go/internal" 21 "cuelang.org/go/internal/core/adt" 22 ) 23 24 func (r *Runtime) IndexToString(i int64) string { 25 return r.index.IndexToString(i) 26 } 27 28 func (r *Runtime) StringToIndex(s string) int64 { 29 return getKey(s) 30 } 31 32 func (r *Runtime) NextUniqueID() uint64 { 33 return r.index.getNextUniqueID() 34 } 35 36 func (r *Runtime) LabelStr(l adt.Feature) string { 37 return l.IdentString(r) 38 } 39 40 func (r *Runtime) StrLabel(str string) adt.Feature { 41 return r.Label(str, false) 42 } 43 44 func (r *Runtime) Label(s string, isIdent bool) adt.Feature { 45 index := r.StringToIndex(s) 46 typ := adt.StringLabel 47 if isIdent { 48 switch { 49 case internal.IsDef(s) && internal.IsHidden(s): 50 typ = adt.HiddenDefinitionLabel 51 case internal.IsDef(s): 52 typ = adt.DefinitionLabel 53 case internal.IsHidden(s): 54 typ = adt.HiddenLabel 55 } 56 } 57 f, _ := adt.MakeLabel(nil, index, typ) 58 return f 59 } 60 61 // TODO: move to Runtime as fields. 62 var ( 63 labelMap = map[string]int{} 64 labels = make([]string, 0, 1000) 65 mutex sync.RWMutex 66 ) 67 68 func init() { 69 // Ensure label 0 is assigned to _. 70 getKey("_") 71 } 72 73 func getKey(s string) int64 { 74 mutex.RLock() 75 p, ok := labelMap[s] 76 mutex.RUnlock() 77 if ok { 78 return int64(p) 79 } 80 mutex.Lock() 81 defer mutex.Unlock() 82 p, ok = labelMap[s] 83 if ok { 84 return int64(p) 85 } 86 p = len(labels) 87 labels = append(labels, s) 88 labelMap[s] = p 89 return int64(p) 90 } 91 92 func (x *index) IndexToString(i int64) string { 93 mutex.RLock() 94 s := labels[i] 95 mutex.RUnlock() 96 return s 97 }