cuelang.org/go@v0.10.1/encoding/protobuf/pbinternal/attribute.go (about) 1 // Copyright 2021 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 pbinternal 16 17 import ( 18 "strings" 19 "unicode" 20 "unicode/utf8" 21 22 "cuelang.org/go/cue" 23 ) 24 25 type CompositeType int 26 27 const ( 28 Normal CompositeType = iota 29 List 30 Map 31 ) 32 33 type ValueType int 34 35 const ( 36 Unknown ValueType = iota 37 Message 38 Int 39 Float 40 String 41 Bytes 42 Bool 43 ) 44 45 type Info struct { 46 Name string 47 CUEName string 48 Attr cue.Attribute 49 Value cue.Value 50 51 CompositeType CompositeType 52 ValueType ValueType 53 Type string 54 55 IsEnum bool 56 57 // For maps only 58 KeyType ValueType // only for maps 59 KeyTypeString string 60 } 61 62 func FromIter(i *cue.Iterator) (info Info, err error) { 63 return FromValue(i.Label(), i.Value()) 64 } 65 66 func FromValue(name string, v cue.Value) (info Info, err error) { 67 a := v.Attribute("protobuf") 68 69 info.Name = name 70 info.CUEName = name 71 72 if a.Err() == nil { 73 info.Attr = a 74 75 s, ok, err := a.Lookup(1, "name") 76 if err != nil { 77 return info, err 78 } 79 if ok { 80 info.Name = strings.TrimSpace(s) 81 } 82 83 info.Type, err = a.String(1) 84 if err != nil { 85 return info, err 86 } 87 } 88 89 switch v.IncompleteKind() { 90 case cue.ListKind: 91 info.CompositeType = List 92 e, _ := v.Elem() 93 if e.Exists() { 94 v = e 95 } else { 96 for i, _ := v.List(); i.Next(); { 97 v = i.Value() 98 break 99 } 100 } 101 102 case cue.StructKind: 103 if strings.HasPrefix(info.Type, "map[") { 104 a := strings.SplitN(info.Type[len("map["):], "]", 2) 105 info.KeyTypeString = strings.TrimSpace(a[0]) 106 switch info.KeyTypeString { 107 case "string": 108 info.KeyType = String 109 case "bytes": 110 info.KeyType = Bytes 111 case "double", "float": 112 info.KeyType = Float 113 case "bool": 114 info.KeyType = Bool 115 default: 116 info.KeyType = Int // Assuming 117 } 118 info.CompositeType = Map 119 v, _ = v.Elem() 120 } 121 } 122 123 info.Value = v 124 125 switch v.IncompleteKind() { 126 case cue.StructKind: 127 info.ValueType = Message 128 129 case cue.StringKind: 130 info.ValueType = String 131 132 case cue.BytesKind: 133 info.ValueType = Bytes 134 135 case cue.BoolKind: 136 info.ValueType = Bool 137 138 case cue.IntKind: 139 info.ValueType = Int 140 r, _ := utf8.DecodeRuneInString(info.Type) 141 info.IsEnum = unicode.In(r, unicode.Upper) 142 143 case cue.FloatKind, cue.NumberKind: 144 info.ValueType = Float 145 } 146 147 return info, nil 148 }