this repo has no description
at master 147 lines 2.8 kB view raw
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 15package pbinternal 16 17import ( 18 "strings" 19 "unicode" 20 "unicode/utf8" 21 22 "cuelang.org/go/cue" 23) 24 25type CompositeType int 26 27const ( 28 Normal CompositeType = iota 29 List 30 Map 31) 32 33type ValueType int 34 35const ( 36 Unknown ValueType = iota 37 Message 38 Int 39 Float 40 String 41 Bytes 42 Bool 43) 44 45type 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 62func FromIter(i *cue.Iterator) (info Info, err error) { 63 return FromValue(i.Selector().Unquoted(), i.Value()) 64} 65 66func 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 if e := v.LookupPath(cue.MakePath(cue.AnyIndex)); e.Exists() { 93 v = e 94 } else { 95 for i, _ := v.List(); i.Next(); { 96 v = i.Value() 97 break 98 } 99 } 100 101 case cue.StructKind: 102 if strings.HasPrefix(info.Type, "map[") { 103 a := strings.SplitN(info.Type[len("map["):], "]", 2) 104 info.KeyTypeString = strings.TrimSpace(a[0]) 105 switch info.KeyTypeString { 106 case "string": 107 info.KeyType = String 108 case "bytes": 109 info.KeyType = Bytes 110 case "double", "float": 111 info.KeyType = Float 112 case "bool": 113 info.KeyType = Bool 114 default: 115 info.KeyType = Int // Assuming 116 } 117 info.CompositeType = Map 118 v = v.LookupPath(cue.MakePath(cue.AnyString)) 119 } 120 } 121 122 info.Value = v 123 124 switch v.IncompleteKind() { 125 case cue.StructKind: 126 info.ValueType = Message 127 128 case cue.StringKind: 129 info.ValueType = String 130 131 case cue.BytesKind: 132 info.ValueType = Bytes 133 134 case cue.BoolKind: 135 info.ValueType = Bool 136 137 case cue.IntKind: 138 info.ValueType = Int 139 r, _ := utf8.DecodeRuneInString(info.Type) 140 info.IsEnum = unicode.In(r, unicode.Upper) 141 142 case cue.FloatKind, cue.NumberKind: 143 info.ValueType = Float 144 } 145 146 return info, nil 147}