// Copyright 2021 CUE Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pbinternal import ( "strings" "unicode" "unicode/utf8" "cuelang.org/go/cue" ) type CompositeType int const ( Normal CompositeType = iota List Map ) type ValueType int const ( Unknown ValueType = iota Message Int Float String Bytes Bool ) type Info struct { Name string CUEName string Attr cue.Attribute Value cue.Value CompositeType CompositeType ValueType ValueType Type string IsEnum bool // For maps only KeyType ValueType // only for maps KeyTypeString string } func FromIter(i *cue.Iterator) (info Info, err error) { return FromValue(i.Label(), i.Value()) } func FromValue(name string, v cue.Value) (info Info, err error) { a := v.Attribute("protobuf") info.Name = name info.CUEName = name if a.Err() == nil { info.Attr = a s, ok, err := a.Lookup(1, "name") if err != nil { return info, err } if ok { info.Name = strings.TrimSpace(s) } info.Type, err = a.String(1) if err != nil { return info, err } } switch v.IncompleteKind() { case cue.ListKind: info.CompositeType = List e, _ := v.Elem() if e.Exists() { v = e } else { for i, _ := v.List(); i.Next(); { v = i.Value() break } } case cue.StructKind: if strings.HasPrefix(info.Type, "map[") { a := strings.SplitN(info.Type[len("map["):], "]", 2) info.KeyTypeString = strings.TrimSpace(a[0]) switch info.KeyTypeString { case "string": info.KeyType = String case "bytes": info.KeyType = Bytes case "double", "float": info.KeyType = Float case "bool": info.KeyType = Bool default: info.KeyType = Int // Assuming } info.CompositeType = Map v, _ = v.Elem() } } info.Value = v switch v.IncompleteKind() { case cue.StructKind: info.ValueType = Message case cue.StringKind: info.ValueType = String case cue.BytesKind: info.ValueType = Bytes case cue.BoolKind: info.ValueType = Bool case cue.IntKind: info.ValueType = Int r, _ := utf8.DecodeRuneInString(info.Type) info.IsEnum = unicode.In(r, unicode.Upper) case cue.FloatKind, cue.NumberKind: info.ValueType = Float } return info, nil }