Skip to content
This repository has been archived by the owner on Jan 17, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1 from ipld/feat/upgrade-ipld-prime
Browse files Browse the repository at this point in the history
feat(deps): upgrade to new IPLD prime
  • Loading branch information
hannahhoward authored Apr 28, 2020
2 parents 8cf97d9 + e736762 commit 935c972
Show file tree
Hide file tree
Showing 13 changed files with 596 additions and 1,102 deletions.
25 changes: 11 additions & 14 deletions coding.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,27 @@ import (

"github.com/ipfs/go-cid"
merkledag_pb "github.com/ipfs/go-merkledag/pb"
ipld "github.com/ipld/go-ipld-prime"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/ipld/go-ipld-prime/schema"
)

// DecodeDagProto is a fast path decoding to protobuf
// from PBNode__NodeBuilders
func (nb _PBNode__NodeBuilder) DecodeDagProto(r io.Reader) (ipld.Node, error) {
func (nb _PBNode__NodeBuilder) DecodeDagProto(r io.Reader) error {
var pbn merkledag_pb.PBNode
encoded, err := ioutil.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("io error during unmarshal. %v", err)
return fmt.Errorf("io error during unmarshal. %v", err)
}
if err := pbn.Unmarshal(encoded); err != nil {
return nil, fmt.Errorf("unmarshal failed. %v", err)
return fmt.Errorf("unmarshal failed. %v", err)
}
pbLinks := make([]PBLink, 0, len(pbn.Links))
for _, link := range pbn.Links {
hash, err := cid.Cast(link.GetHash())

if err != nil {
return nil, fmt.Errorf("unmarshal failed. %v", err)
return fmt.Errorf("unmarshal failed. %v", err)
}
pbLinks = append(pbLinks, PBLink{
d: PBLink__Content{
Expand All @@ -47,12 +46,9 @@ func (nb _PBNode__NodeBuilder) DecodeDagProto(r io.Reader) (ipld.Node, error) {
},
})
}
pbData := Bytes{pbn.GetData()}
return PBNode{d: PBNode__Content{
Links: PBLinks{x: pbLinks},
Data: pbData,
},
}, nil
nb.nd.d.Links.x = pbLinks
nb.nd.d.Data.x = pbn.GetData()
return nil
}

// EncodeDagProto is a fast path encoding to protobuf
Expand Down Expand Up @@ -97,12 +93,13 @@ func (nd PBNode) EncodeDagProto(w io.Writer) error {

// DecodeDagRaw is a fast path decoding to protobuf
// from RawNode__NodeBuilders
func (nb _RawNode__NodeBuilder) DecodeDagRaw(r io.Reader) (ipld.Node, error) {
func (nb _RawNode__NodeBuilder) DecodeDagRaw(r io.Reader) error {
data, err := ioutil.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("io error during unmarshal. %v", err)
return fmt.Errorf("io error during unmarshal. %v", err)
}
return RawNode{data}, nil
nb.nd.x = data
return nil
}

// EncodeDagRaw is a fast path encoding to protobuf
Expand Down
14 changes: 9 additions & 5 deletions common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package dagpb_test
import (
"bytes"

blocks "github.com/ipfs/go-block-format"
ipld "github.com/ipld/go-ipld-prime"
dagpb "github.com/ipld/go-ipld-prime-proto"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/jbenet/go-random"
)

Expand All @@ -20,12 +18,17 @@ func randomBytes(n int64) []byte {
}

func makeRawNode(randBytes []byte) (ipld.Node, error) {
raw_nb := dagpb.RawNode__NodeBuilder()
return raw_nb.CreateBytes(randBytes)
raw_nb := dagpb.Style.Raw.NewBuilder()
err := raw_nb.AssignBytes(randBytes)
if err != nil {
return nil, err
}
return raw_nb.Build(), nil
}

/*
func makeProtoNode(linkedNodes map[string]ipld.Node) (ipld.Node, error) {
dagpb_nb := dagpb.PBNode__NodeBuilder()
dag_ns := dagpb.PBNode__NodeBuilder()
dagpb_mb, err := dagpb_nb.CreateMap()
if err != nil {
return nil, err
Expand Down Expand Up @@ -120,3 +123,4 @@ func makeProtoNode(linkedNodes map[string]ipld.Node) (ipld.Node, error) {
}
return dagpb_mb.Build()
}
*/
141 changes: 133 additions & 8 deletions gen/main.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,106 @@
package main

import (
"io"
"io/ioutil"
"os"
"regexp"

"github.com/ipld/go-ipld-prime/schema"
gengo "github.com/ipld/go-ipld-prime/schema/gen/go"
)

type typedNodeGenerator interface {

// -- the natively-typed apis -->
// (might be more readable to group these in another interface and have it
// return a `typedNodeGenerator` with the rest? but structurally same.)

EmitNativeType(io.Writer)
EmitNativeAccessors(io.Writer) // depends on the kind -- field accessors for struct, typed iterators for map, etc.
EmitNativeBuilder(io.Writer) // typically emits some kind of struct that has a Build method.
EmitNativeMaybe(io.Writer) // a pointer-free 'maybe' mechanism is generated for all types.

// -- the schema.TypedNode.Type method and vars -->

EmitTypedNodeMethodType(io.Writer) // these emit dummies for now

// -- all node methods -->
// (and note that the nodeBuilder for this one should be the "semantic" one,
// e.g. it *always* acts like a map for structs, even if the repr is different.)

nodeGenerator

// -- and the representation and its node and nodebuilder -->

EmitTypedNodeMethodRepresentation(io.Writer)
}

type typedLinkNodeGenerator interface {
// all methods in typedNodeGenerator
typedNodeGenerator

// as typed.LinkNode.ReferencedNodeBuilder generator
EmitTypedLinkNodeMethodReferencedNodeBuilder(io.Writer)
}

type nodeGenerator interface {
EmitNodeType(io.Writer)
EmitNodeMethodReprKind(io.Writer)
EmitNodeMethodLookupString(io.Writer)
EmitNodeMethodLookup(io.Writer)
EmitNodeMethodLookupIndex(io.Writer)
EmitNodeMethodLookupSegment(io.Writer)
EmitNodeMethodMapIterator(io.Writer) // also iterator itself
EmitNodeMethodListIterator(io.Writer) // also iterator itself
EmitNodeMethodLength(io.Writer)
EmitNodeMethodIsUndefined(io.Writer)
EmitNodeMethodIsNull(io.Writer)
EmitNodeMethodAsBool(io.Writer)
EmitNodeMethodAsInt(io.Writer)
EmitNodeMethodAsFloat(io.Writer)
EmitNodeMethodAsString(io.Writer)
EmitNodeMethodAsBytes(io.Writer)
EmitNodeMethodAsLink(io.Writer)
}

func emitEntireType(ng nodeGenerator, w io.Writer) {
if ng == nil {
return
}
ng.EmitNodeType(w)
ng.EmitNodeMethodReprKind(w)
ng.EmitNodeMethodLookupString(w)
ng.EmitNodeMethodLookup(w)
ng.EmitNodeMethodLookupIndex(w)
ng.EmitNodeMethodLookupSegment(w)
ng.EmitNodeMethodMapIterator(w)
ng.EmitNodeMethodListIterator(w)
ng.EmitNodeMethodLength(w)
ng.EmitNodeMethodIsUndefined(w)
ng.EmitNodeMethodIsNull(w)
ng.EmitNodeMethodAsBool(w)
ng.EmitNodeMethodAsInt(w)
ng.EmitNodeMethodAsFloat(w)
ng.EmitNodeMethodAsString(w)
ng.EmitNodeMethodAsBytes(w)
ng.EmitNodeMethodAsLink(w)

tg, ok := ng.(typedNodeGenerator)
if ok {
tg.EmitNativeType(w)
tg.EmitNativeAccessors(w)
tg.EmitNativeBuilder(w)
tg.EmitNativeMaybe(w)
tg.EmitTypedNodeMethodType(w)
tg.EmitTypedNodeMethodRepresentation(w)
}
tlg, ok := ng.(typedLinkNodeGenerator)
if ok {
tlg.EmitTypedLinkNodeMethodReferencedNodeBuilder(w)
}
}

func main() {
openOrPanic := func(filename string) *os.File {
y, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
Expand Down Expand Up @@ -47,15 +141,46 @@ func main() {

f = openOrPanic("pb_node_gen.go")
gengo.EmitFileHeader("dagpb", f)
gengo.EmitEntireType(gengo.NewGeneratorForKindString(tString), f)
gengo.EmitEntireType(gengo.NewGeneratorForKindInt(tInt), f)
gengo.EmitEntireType(gengo.NewGeneratorForKindBytes(tBytes), f)
gengo.EmitEntireType(gengo.NewGeneratorForKindLink(tLink), f)
gengo.EmitEntireType(gengo.NewGeneratorForKindStruct(tPBLink), f)
gengo.EmitEntireType(gengo.NewGeneratorForKindList(tPBLinks), f)
gengo.EmitEntireType(gengo.NewGeneratorForKindStruct(tPBNode), f)
tg := gengo.NewGeneratorForKindString(tString)
emitEntireType(tg, f)
emitEntireType(tg.GetRepresentationNodeGen(), f)
tg = gengo.NewGeneratorForKindInt(tInt)
emitEntireType(tg, f)
emitEntireType(tg.GetRepresentationNodeGen(), f)
tg = gengo.NewGeneratorForKindBytes(tBytes)
emitEntireType(tg, f)
emitEntireType(tg.GetRepresentationNodeGen(), f)
tg = gengo.NewGeneratorForKindLink(tLink)
emitEntireType(tg, f)
emitEntireType(tg.GetRepresentationNodeGen(), f)
tg = gengo.NewGeneratorForKindStruct(tPBLink)
emitEntireType(tg, f)
emitEntireType(tg.GetRepresentationNodeGen(), f)
tg = gengo.NewGeneratorForKindList(tPBLinks)
emitEntireType(tg, f)
emitEntireType(tg.GetRepresentationNodeGen(), f)
tg = gengo.NewGeneratorForKindStruct(tPBNode)
emitEntireType(tg, f)
emitEntireType(tg.GetRepresentationNodeGen(), f)
if err := f.Close(); err != nil {
panic(err)
}
read, err := ioutil.ReadFile("pb_node_gen.go")
if err != nil {
panic(err)
}

re := regexp.MustCompile("ipld\\.ErrInvalidKey\\{[^}]*\\}")
newContents := re.ReplaceAll(read, []byte("err"))

err = ioutil.WriteFile("pb_node_gen.go", []byte(newContents), 0)
if err != nil {
panic(err)
}

f = openOrPanic("raw_node_gen.go")
gengo.EmitFileHeader("dagpb", f)
gengo.EmitEntireType(gengo.NewGeneratorForKindBytes(tRaw), f)
tg = gengo.NewGeneratorForKindBytes(tRaw)
emitEntireType(tg, f)
emitEntireType(tg.GetRepresentationNodeGen(), f)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/ipfs/go-ipld-format v0.2.0
github.com/ipfs/go-merkledag v0.3.1
github.com/ipfs/go-unixfs v0.2.4
github.com/ipld/go-ipld-prime v0.0.2-0.20200229094926-eb71617f4aeb
github.com/ipld/go-ipld-prime v0.0.2-0.20200327122045-fc80c2b0149d
github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c
github.com/multiformats/go-multihash v0.0.13
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ github.com/ipfs/go-unixfs v0.2.4 h1:6NwppOXefWIyysZ4LR/qUBPvXd5//8J3jiMdvpbw6Lo=
github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw=
github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E=
github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0=
github.com/ipld/go-ipld-prime v0.0.2-0.20200229094926-eb71617f4aeb h1:uvoZ2aTjsTt/6W5hkzj3JkPMY3oHvcla4WA29k4Jk0I=
github.com/ipld/go-ipld-prime v0.0.2-0.20200229094926-eb71617f4aeb/go.mod h1:uVIwe/u0H4VdKv3kaN1ck7uCb6yD9cFLS9/ELyXbsw8=
github.com/ipld/go-ipld-prime v0.0.2-0.20191108012745-28a82f04c785 h1:fASnkvtR+SmB2y453RxmDD3Uvd4LonVUgFGk9JoDaZs=
github.com/ipld/go-ipld-prime v0.0.2-0.20191108012745-28a82f04c785/go.mod h1:bDDSvVz7vaK12FNvMeRYnpRFkSUPNQOiCYQezMD/P3w=
github.com/ipld/go-ipld-prime v0.0.2-0.20200327122045-fc80c2b0149d h1:0WIVGCHabeWlI/Zn0bfXdGUcHzcbOSe38ehBgIRdSck=
github.com/ipld/go-ipld-prime v0.0.2-0.20200327122045-fc80c2b0149d/go.mod h1:uVIwe/u0H4VdKv3kaN1ck7uCb6yD9cFLS9/ELyXbsw8=
github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc=
github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
Expand Down
12 changes: 6 additions & 6 deletions multicodec.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ func init() {
}

// PBDecoder is a decoder function for Dag Protobuf nodes
func PBDecoder(nb ipld.NodeBuilder, r io.Reader) (ipld.Node, error) {
func PBDecoder(nb ipld.NodeAssembler, r io.Reader) error {
// Probe for a builtin fast path. Shortcut to that if possible.
// (ipldcbor.NodeBuilder supports this, for example.)
type detectFastPath interface {
DecodeDagProto(io.Reader) (ipld.Node, error)
DecodeDagProto(io.Reader) error
}
if nb2, ok := nb.(detectFastPath); ok {
return nb2.DecodeDagProto(r)
}
// Okay, generic builder path.
return nil, ErrNoAutomaticDecoding
return ErrNoAutomaticDecoding
}

// PBEncoder is a encoder function that encodes to Dag Protobuf
Expand All @@ -55,17 +55,17 @@ func PBEncoder(n ipld.Node, w io.Writer) error {
}

// RawDecoder is a decoder function for raw coded nodes
func RawDecoder(nb ipld.NodeBuilder, r io.Reader) (ipld.Node, error) {
func RawDecoder(nb ipld.NodeAssembler, r io.Reader) error {
// Probe for a builtin fast path. Shortcut to that if possible.
// (ipldcbor.NodeBuilder supports this, for example.)
type detectFastPath interface {
DecodeDagRaw(io.Reader) (ipld.Node, error)
DecodeDagRaw(io.Reader) error
}
if nb2, ok := nb.(detectFastPath); ok {
return nb2.DecodeDagRaw(r)
}
// Okay, generic builder path.
return nil, ErrNoAutomaticDecoding
return ErrNoAutomaticDecoding
}

// RawEncoder encodes a node to a raw block structure
Expand Down
40 changes: 27 additions & 13 deletions multicodec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"bytes"
"testing"

ipld "github.com/ipld/go-ipld-prime"
dag "github.com/ipfs/go-merkledag"
dagpb "github.com/ipld/go-ipld-prime-proto"
. "github.com/warpfork/go-wish"
)
Expand All @@ -21,29 +21,43 @@ func TestRoundTripRaw(t *testing.T) {
})
t.Run("decoding", func(t *testing.T) {
buf := bytes.NewBuffer(randBytes)
rawNode2, err := dagpb.RawDecoder(dagpb.RawNode__NodeBuilder(), buf)
nb := dagpb.Style.Raw.NewBuilder()
err := dagpb.RawDecoder(nb, buf)
Wish(t, err, ShouldEqual, nil)
rawNode2 := nb.Build()
Wish(t, rawNode2, ShouldEqual, rawNode)
})
}

func TestRoundTripProtbuf(t *testing.T) {
randBytes1 := randomBytes(256)
rawNode1, err := makeRawNode(randBytes1)
Wish(t, err, ShouldEqual, nil)
randBytes2 := randomBytes(256)
rawNode2, err := makeRawNode(randBytes2)
Wish(t, err, ShouldEqual, nil)
pbNode, err := makeProtoNode(map[string]ipld.Node{
"applesuace": rawNode1,
"oranges": rawNode2,
})
a := dag.NewRawNode([]byte("aaaa"))
b := dag.NewRawNode([]byte("bbbb"))
c := dag.NewRawNode([]byte("cccc"))

nd1 := &dag.ProtoNode{}
nd1.AddNodeLink("cat", a)

nd2 := &dag.ProtoNode{}
nd2.AddNodeLink("first", nd1)
nd2.AddNodeLink("dog", b)

nd3 := &dag.ProtoNode{}
nd3.AddNodeLink("second", nd2)
nd3.AddNodeLink("bear", c)

data := nd3.RawData()
ibuf := bytes.NewBuffer(data)
nb := dagpb.Style.Protobuf.NewBuilder()
err := dagpb.PBDecoder(nb, ibuf)
Wish(t, err, ShouldEqual, nil)
pbNode := nb.Build()
t.Run("encode/decode equivalency", func(t *testing.T) {
var buf bytes.Buffer
err := dagpb.PBEncoder(pbNode, &buf)
Wish(t, err, ShouldEqual, nil)
pbNode2, err := dagpb.PBDecoder(dagpb.PBNode__NodeBuilder(), &buf)
nb = dagpb.Style.Protobuf.NewBuilder()
err = dagpb.PBDecoder(nb, &buf)
pbNode2 := nb.Build()
Wish(t, err, ShouldEqual, nil)
Wish(t, pbNode2, ShouldEqual, pbNode)
})
Expand Down
Loading

0 comments on commit 935c972

Please sign in to comment.