func makeTypeRef(t schema.Type, rel *node, nodes nodeMap) (typeRef, error) { nodeRef := func(id uint64) (typeRef, error) { ni, err := nodes.mustFind(id) if err != nil { return typeRef{}, err } return makeNodeTypeRef(ni, rel) } if ref, ok := staticTypeRefs[t.Which()]; ok { return ref, nil } switch t.Which() { case schema.Type_Which_enum: return nodeRef(t.Enum().TypeId()) case schema.Type_Which_structType: return nodeRef(t.StructType().TypeId()) case schema.Type_Which_interface: return nodeRef(t.Interface().TypeId()) case schema.Type_Which_list: lt, _ := t.List().ElementType() if ref, ok := staticListTypeRefs[lt.Which()]; ok { return ref, nil } switch lt.Which() { case schema.Type_Which_enum: ref, err := nodeRef(lt.Enum().TypeId()) if err != nil { return ref, err } ref.name = ref.name + "_List" ref.newfunc = "New" + ref.name return ref, nil case schema.Type_Which_structType: ref, err := nodeRef(lt.StructType().TypeId()) if err != nil { return ref, err } ref.name = ref.name + "_List" ref.newfunc = "New" + ref.name return ref, nil case schema.Type_Which_anyPointer, schema.Type_Which_list, schema.Type_Which_interface: return typeRef{name: "PointerList", newfunc: "NewPointerList", imp: capnpImportSpec}, nil } } return typeRef{}, fmt.Errorf("unable to reference type %v", t.Which()) }
func (enc *Encoder) marshalList(elem schema.Type, l capnp.List) error { enc.w.WriteByte('[') switch elem.Which() { case schema.Type_Which_void: for i := 0; i < l.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.w.WriteString(voidMarker) } case schema.Type_Which_bool: bl := capnp.BitList{List: l} for i := 0; i < bl.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalBool(bl.At(i)) } case schema.Type_Which_int8: il := capnp.Int8List{List: l} for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalInt(int64(il.At(i))) } case schema.Type_Which_int16: il := capnp.Int16List{List: l} for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalInt(int64(il.At(i))) } case schema.Type_Which_int32: il := capnp.Int32List{List: l} for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalInt(int64(il.At(i))) } case schema.Type_Which_int64: il := capnp.Int64List{List: l} for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalInt(il.At(i)) } case schema.Type_Which_uint8: il := capnp.UInt8List{List: l} for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalUint(uint64(il.At(i))) } case schema.Type_Which_uint16: il := capnp.UInt16List{List: l} for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalUint(uint64(il.At(i))) } case schema.Type_Which_uint32: il := capnp.UInt32List{List: l} for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalUint(uint64(il.At(i))) } case schema.Type_Which_uint64: il := capnp.UInt64List{List: l} for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalUint(il.At(i)) } case schema.Type_Which_float32: fl := capnp.Float32List{List: l} for i := 0; i < fl.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalFloat32(fl.At(i)) } case schema.Type_Which_float64: fl := capnp.Float64List{List: l} for i := 0; i < fl.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalFloat64(fl.At(i)) } case schema.Type_Which_data: dl := capnp.DataList{List: l} for i := 0; i < dl.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } d, err := dl.At(i) if err != nil { return err } enc.marshalText(d) } case schema.Type_Which_text: tl := capnp.TextList{List: l} for i := 0; i < tl.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } t, err := tl.BytesAt(i) if err != nil { return err } enc.marshalText(t) } case schema.Type_Which_structType: for i := 0; i < l.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } err := enc.marshalStruct(elem.StructType().TypeId(), l.Struct(i)) if err != nil { return err } } case schema.Type_Which_list: ee, err := elem.List().ElementType() if err != nil { return err } for i := 0; i < l.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } p, err := capnp.PointerList{List: l}.PtrAt(i) if err != nil { return err } err = enc.marshalList(ee, p.List()) if err != nil { return err } } case schema.Type_Which_enum: il := capnp.UInt16List{List: l} typ := elem.Enum().TypeId() // TODO(light): only search for node once for i := 0; i < il.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.marshalEnum(typ, il.At(i)) } case schema.Type_Which_interface: for i := 0; i < l.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.w.WriteString(interfaceMarker) } case schema.Type_Which_anyPointer: for i := 0; i < l.Len(); i++ { if i > 0 { enc.w.WriteString(", ") } enc.w.WriteString(anyPointerMarker) } default: return fmt.Errorf("unknown list type %v", elem.Which()) } enc.w.WriteByte(']') return nil }
// Value formats a value from a schema (like a field default) as Go source. func (g *generator) Value(rel *node, t schema.Type, v schema.Value) (string, error) { if !isValueOfType(v, t) { return "", fmt.Errorf("value type is %v, but found %v value", t.Which(), v.Which()) } switch t.Which() { case schema.Type_Which_void: return "struct{}{}", nil case schema.Type_Which_interface: // The only statically representable interface value is null. return g.imports.Capnp() + ".Client(nil)", nil case schema.Type_Which_bool: if v.Bool() { return "true", nil } else { return "false", nil } case schema.Type_Which_uint8, schema.Type_Which_uint16, schema.Type_Which_uint32, schema.Type_Which_uint64: return fmt.Sprintf("uint%d(%d)", intbits(t.Which()), uintValue(v)), nil case schema.Type_Which_int8, schema.Type_Which_int16, schema.Type_Which_int32, schema.Type_Which_int64: return fmt.Sprintf("int%d(%d)", intbits(t.Which()), intValue(v)), nil case schema.Type_Which_float32: return fmt.Sprintf("%s.Float32frombits(0x%x)", g.imports.Math(), math.Float32bits(v.Float32())), nil case schema.Type_Which_float64: return fmt.Sprintf("%s.Float64frombits(0x%x)", g.imports.Math(), math.Float64bits(v.Float64())), nil case schema.Type_Which_text: text, _ := v.Text() return strconv.Quote(text), nil case schema.Type_Which_data: buf := make([]byte, 0, 1024) buf = append(buf, "[]byte{"...) data, _ := v.Data() for i, b := range data { if i > 0 { buf = append(buf, ',', ' ') } buf = strconv.AppendUint(buf, uint64(b), 10) } buf = append(buf, '}') return string(buf), nil case schema.Type_Which_enum: en := g.nodes[t.Enum().TypeId()] if en == nil || !en.IsValid() || en.Which() != schema.Node_Which_enum { return "", errors.New("expected enum type") } enums, _ := en.Enum().Enumerants() val := int(v.Enum()) if val >= enums.Len() { rn, err := g.RemoteNodeName(en, rel) if err != nil { return "", err } return fmt.Sprintf("%s(%d)", rn, val), nil } ev := makeEnumval(en, val, enums.At(val)) imp, err := importForNode(en, rel) if err != nil { return "", err } if imp.path == "" { return ev.FullName(), nil } qname := g.imports.add(imp) return qname + "." + ev.FullName(), nil case schema.Type_Which_structType: data, _ := v.StructValuePtr() var buf bytes.Buffer tn, err := g.nodes.mustFind(t.StructType().TypeId()) if err != nil { return "", err } sd, err := g.data.copyData(data) if err != nil { return "", err } err = templates.ExecuteTemplate(&buf, "structValue", structValueParams{ G: g, Node: rel, Typ: tn, Value: sd, }) return buf.String(), err case schema.Type_Which_anyPointer: data, _ := v.AnyPointerPtr() var buf bytes.Buffer sd, err := g.data.copyData(data) if err != nil { return "", err } err = templates.ExecuteTemplate(&buf, "pointerValue", pointerValueParams{ G: g, Value: sd, }) return buf.String(), err case schema.Type_Which_list: data, _ := v.ListPtr() var buf bytes.Buffer ftyp, err := g.RemoteTypeName(t, rel) if err != nil { return "", err } sd, err := g.data.copyData(data) if err != nil { return "", err } err = templates.ExecuteTemplate(&buf, "listValue", listValueParams{ G: g, Typ: ftyp, Value: sd, }) return buf.String(), err default: return "", fmt.Errorf("unhandled value type %v", t.Which()) } }