diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a642ac92..a37b89bd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,8 @@ jobs: pkg install -y sudo gmake bash git go golangci-lint curl wget fakeroot libffi rubygem-fpm git config --global --add safe.directory /home/runner/work/cloudflared/cloudflared run: | + gmake install-go go mod download go mod tidy go install golang.org/x/tools/cmd/goimports@latest - gmake install-go cloudflared cleanup-go + gmake cloudflared cleanup-go diff --git a/vendor/zombiezen.com/go/capnproto2/.gitignore b/vendor/zombiezen.com/go/capnproto2/.gitignore new file mode 100644 index 00000000..413ca091 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/.gitignore @@ -0,0 +1,12 @@ +/capnpc-go/capnpc-go +/internal/cmd/mktemplates/mktemplates +TAGS +*~ +*.swp + +# Bazel +/bazel-bin +/bazel-capnproto2 +/bazel-genfiles +/bazel-out +/bazel-testlogs diff --git a/vendor/zombiezen.com/go/capnproto2/.travis.yml b/vendor/zombiezen.com/go/capnproto2/.travis.yml new file mode 100644 index 00000000..b332d165 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/.travis.yml @@ -0,0 +1,9 @@ +language: go +go_import_path: zombiezen.com/go/capnproto2 +go: +- 1.x +install: _travis/install.bash +script: _travis/build.bash +env: +- USE_BAZEL=0 +- USE_BAZEL=1 diff --git a/vendor/zombiezen.com/go/capnproto2/AUTHORS b/vendor/zombiezen.com/go/capnproto2/AUTHORS new file mode 100644 index 00000000..3ea1e9c7 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/AUTHORS @@ -0,0 +1,32 @@ +# This is the official list of go-capnproto authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as one of +# Organization's name +# Individual's name +# Individual's name +# See CONTRIBUTORS for the meaning of multiple email addresses. + +# Please keep the list sorted. + +Anapaya Systems AG +CloudFlare Inc. +Daniel Darabos +Dominik Roos +Eran Duchan +Evan Shaw +Google Inc. +Ian Denhardt +James McKaskill +Jason E. Aten +Johan Hernandez +Joonsung Lee +Kiwi.com s.r.o. +Lev Radomislensky +Peter Waldschmidt +Tiit Pikma +Tom Thorogood +TJ Holowaychuk +William Laffin +Colin Arnott diff --git a/vendor/zombiezen.com/go/capnproto2/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/BUILD.bazel new file mode 100644 index 00000000..323aa5f2 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/BUILD.bazel @@ -0,0 +1,62 @@ +load("@bazel_gazelle//:def.bzl", "gazelle") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +# gazelle:prefix zombiezen.com/go/capnproto2 +gazelle( + name = "gazelle", + command = "fix", +) + +go_library( + name = "go_default_library", + srcs = [ + "address.go", + "canonical.go", + "capability.go", + "capn.go", + "doc.go", + "go.capnp.go", + "list.go", + "mem.go", + "mem_18.go", + "mem_other.go", + "pointer.go", + "rawpointer.go", + "readlimit.go", + "strings.go", + "struct.go", + ], + importpath = "zombiezen.com/go/capnproto2", + visibility = ["//visibility:public"], + deps = [ + "//internal/packed:go_default_library", + "//internal/strquote:go_default_library", + "//schemas:go_default_library", + "@org_golang_x_net//context:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = [ + "address_test.go", + "canonical_test.go", + "capability_test.go", + "capn_test.go", + "example_test.go", + "integration_test.go", + "integrationutil_test.go", + "list_test.go", + "mem_test.go", + "rawpointer_test.go", + "readlimit_test.go", + ], + data = [ + "//internal/aircraftlib:schema", + ], + embed = [":go_default_library"], + deps = [ + "//internal/aircraftlib:go_default_library", + "//internal/capnptool:go_default_library", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/CHANGELOG.md b/vendor/zombiezen.com/go/capnproto2/CHANGELOG.md new file mode 100644 index 00000000..c3f67286 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/CHANGELOG.md @@ -0,0 +1,199 @@ +# Go Cap'n Proto Release Notes + +## 2.17.3 + +- Clear read limits for `const` messages in schemas. + ([#131](https://github.com/capnproto/go-capnproto2/pull/131)) + +## 2.17.0 + +- Add `capnp.Canonicalize` function that implements the + [canonicalization](https://capnproto.org/encoding.html#canonicalization) + algorithm. ([#92](https://github.com/capnproto/go-capnproto2/issues/92)) +- Zero-sized struct pointers are now written with an offset of + -1 to distinguish them from a null pointer. + ([#92](https://github.com/capnproto/go-capnproto2/issues/92)) +- Better support for alternate `Arena` implementations + - [Document `Arena` contract](https://godoc.org/zombiezen.com/go/capnproto2#Arena) + in more detail + - Permit an `Arena` to have a single empty segment in `NewMessage` +- `Arena` allocation optimizations: both `SingleSegment` and + `MultiSegment` now gradually ramp up the amount of space allocated in + a single allocation as the message grows. This is similar to how + built-in Go `append` function works. Workloads with medium to large + messages should expect a decrease in number of allocations, while + small message workloads should remain about the same. Please file an + issue if you encounter any performance regressions. + ([#96](https://github.com/capnproto/go-capnproto2/issues/96)) +- Fix double-far pointer logic. ([#97](https://github.com/capnproto/go-capnproto2/issues/97)) + This is a long-standing bug with reading and writing multi-segment + messages. I've added broader test coverage for multi-segment messages + and far pointers, so it's unlikely that such a failure will persist in + the future. +- Accessing a field in a union when that field is not the one set now + results in a panic. ([#56](https://github.com/capnproto/go-capnproto2/issues/56)) + This is intended to help uncover programming mistakes where a union + field is accessed without checking `Which()`. Prior to this change, + unset union field accessors would silently return garbage. +- `Struct.Address()` and `List.Address()` are now deprecated. + Especially for `List`, where the address is at the beginning of the + data, not the composite literal, the return value is not well-defined + and its not clear how to use it. Use `capnp.SamePtr` if you need to + check for pointer reference equality. File an issue if you're using + `Address()` for something else. + +## 2.16.0 + +- Add BUILD.bazel files ([#88](https://github.com/capnproto/go-capnproto2/issues/88)) + +## 2.15.0 + +- capnpc-go now fails when a file does not include an import annotation. + ([#41](https://github.com/capnproto/go-capnproto2/issues/41)) +- Remove rbtree dependency ([#80](https://github.com/capnproto/go-capnproto2/issues/80)) +- Add option to reduce allocations in `capnp.Decoder` + ([#79](https://github.com/capnproto/go-capnproto2/issues/79)) +- Add `String()` methods for lists + ([#85](https://github.com/capnproto/go-capnproto2/issues/85)) +- Add `String()` methods to schema.capnp.go + ([#83](https://github.com/capnproto/go-capnproto2/issues/83)) + +## 2.14.1 + +- Use [new Go generated code convention](https://golang.org/s/generatedcode) in + capnpc-go output ([#78](https://github.com/capnproto/go-capnproto2/issues/78)) + +## Retroactive Releases + +go-capnproto2 was originally a "build from HEAD" sort of library, as was +convention for most Go libraries at the time. Before 2.14.1, Semantic +Versioning tags were retroactively added so that it would be clear what the +differences were since original release, since marking it as "2.0.0" would seem +awkward. + +The general process was: any significant new feature was given a minor release, +and then any bugfixes before the next minor release were given a "2.X.1" +release. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VersionDescription
2.14.0Add support to pogs for interface types (#66 and #74)
2.13.1Fix bug with far far pointers (#71), use writev system call to encode multi-segment messages efficiently in Go 1.8+ (#70), and add GitHub-Linguist-compatible code generation comment
2.13.0Add Conn.Done and Conn.Err methods
2.12.4Fix size of created List(Float32)
2.12.3Fix bugs from fuzz tests: mismatched element size on list access causing crashes (#59) and miscellaneous packed reader issues
2.12.2Fix another shutdown race condition (#54)
2.12.1Fix ownership bug with receiver-hosted capabilities, add discriminant check to HasField (#55), fix multi-segment bug for data/text lists, and use nulls for setting empty data/text
2.12.0Add rpc.ConnLog option and fix race conditions and edge cases in RPC implementation
2.11.1Fix packed reader behavior on certain readers (#49), add capnp.UnmarshalPacked function that performs faster, and reduce locking overhead of segment maps
2.11.0Fix shutdown deadlock in RPC shutdown (#45)
2.10.1Work around lack of support for RPC-level promise capabilities (#2)
2.10.0Add pogs package (#33)
2.9.1Fix not-found behavior in schemas and add missing group IDs in generated embedded schemas
2.9.0Add encoding/text package (#20)
2.8.0Reduce generated code size for text fields and correct NUL check
2.7.0Insert compressed schema data into generated code
2.6.1Strip NUL byte from TextList.BytesAt and fix capnpc-go output for struct groups
2.6.0Add packages for predefined Cap'n Proto schemas
2.5.1Fix capnpc-go regression (#29) and strip trailing NUL byte in TextBytes accessor
2.5.0Add NewFoo method for list fields in generated structs (#7)
2.4.0Add maximum segment limit (#25)
2.3.0Add depth and traversal limit security checks
2.2.1Fix data race in reading Message from multiple goroutines
2.2.0Add HasFoo pointer field methods to generated code (#24)
2.1.0Introduce Ptr type and reduce allocations in single-segment cases
2.0.2Allow allocation-less string field access via TextList.BytesAt() and StringBytes() (#17)
2.0.1Allow nil params in client wrappers (#9) and fix integer underflow on compare function (#12)
2.0.0First release under zombiezen.com/go/capnproto2
diff --git a/vendor/zombiezen.com/go/capnproto2/CONTRIBUTING.md b/vendor/zombiezen.com/go/capnproto2/CONTRIBUTING.md new file mode 100644 index 00000000..f13501d6 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/CONTRIBUTING.md @@ -0,0 +1,22 @@ +# How to contribute + +We'd love to accept your patches and contributions to this project. There are a +just a few small guidelines you need to follow. + +## Code contributions + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult [GitHub Help][] for more +information on using pull requests. + +When you make your first submission to this repository, please add your name to +the AUTHORS and CONTRIBUTORS file as part of your first pull request. + +As a policy, go-capnproto2 should always build cleanly and pass tests on every +commit. We run a [Travis build][] that checks before and after merges to +enforce this policy. However, as a courtesy to other contributors, please run +`go test ./...` before sending a pull request (this is what the Travis +build does). + +[GitHub Help]: https://help.github.com/articles/about-pull-requests/ +[Travis build]: https://travis-ci.org/capnproto/go-capnproto2 diff --git a/vendor/zombiezen.com/go/capnproto2/CONTRIBUTORS b/vendor/zombiezen.com/go/capnproto2/CONTRIBUTORS new file mode 100644 index 00000000..9a1aa311 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/CONTRIBUTORS @@ -0,0 +1,39 @@ +# This is the official list of people who can contribute +# (and typically have contributed) code to the go-capnproto repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# copyright belongs to the individual or the corporation. + +# Names should be added to this file like so: +# Individual's name +# Individual's name + +# Please keep the list sorted. + +Alan Braithwaite +Albert Strasheim +Daniel Darabos +Dominik Roos +Eran Duchan +Evan Shaw +Ian Denhardt +James McKaskill +Jason E. Aten +Johan Hernandez +Joonsung Lee +Lev Radomislensky +Lukas Vogel +Martin Sucha +Peter Waldschmidt +Ross Light +Stephen Shirley +Tiit Pikma +Tom Thorogood +TJ Holowaychuk +William Laffin +Colin Arnott diff --git a/vendor/zombiezen.com/go/capnproto2/LICENSE b/vendor/zombiezen.com/go/capnproto2/LICENSE new file mode 100644 index 00000000..3e590a19 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/LICENSE @@ -0,0 +1,25 @@ +go-capnproto is licensed under the terms of the MIT license reproduced below. + +=============================================================================== + +Copyright (C) 2014 the go-capnproto authors and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +=============================================================================== diff --git a/vendor/zombiezen.com/go/capnproto2/README.md b/vendor/zombiezen.com/go/capnproto2/README.md new file mode 100644 index 00000000..47d072b3 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/README.md @@ -0,0 +1,68 @@ +# Cap'n Proto bindings for Go + +[![GoDoc](https://godoc.org/zombiezen.com/go/capnproto2?status.svg)][godoc] +[![Build Status](https://travis-ci.org/capnproto/go-capnproto2.svg?branch=master)][travis] + +go-capnproto consists of: +- a Go code generator for [Cap'n Proto](https://capnproto.org/) +- a Go package that provides runtime support +- a Go package that implements Level 1 of the RPC protocol + +[godoc]: https://godoc.org/zombiezen.com/go/capnproto2 +[travis]: https://travis-ci.org/capnproto/go-capnproto2 + +## Getting started + +You will need the `capnp` tool to compile schemas into Go. +This package has been tested with Cap'n Proto 0.5.0. + +``` +$ go get -u -t zombiezen.com/go/capnproto2/... +$ go test -v zombiezen.com/go/capnproto2/... +``` + +This library uses [SemVer tags][] to indicate stable releases. +While the goal is that master should always be passing all known tests, tagged releases are vetted more. +When possible, use the [latest release tag](https://github.com/capnproto/go-capnproto2/releases). + +``` +$ cd $GOPATH/src/zombiezen.com/go/capnproto2 +$ git fetch +$ git checkout v2.16.0 # check the releases page for the latest +``` + +Then read the [Getting Started guide][]. + +[SemVer tags]: http://semver.org/ +[Getting Started guide]: https://github.com/capnproto/go-capnproto2/wiki/Getting-Started + +## API Compatibility + +Consider this package's API as beta software, since the Cap'n Proto spec is not final. +In the spirit of the [Go 1 compatibility guarantee][gocompat], I will make every effort to avoid making breaking API changes. +The major cases where I reserve the right to make breaking changes are: + +- Security. +- Changes in the Cap'n Proto specification. +- Bugs. + +The `pogs` package is relatively new and may change over time. +However, its functionality has been well-tested and will probably only relax restrictions. + +[gocompat]: https://golang.org/doc/go1compat + +## Documentation + +See the docs on [godoc.org][godoc]. + +## What is Cap'n Proto? + +The best cerealization... + +https://capnproto.org/ + +## License + +MIT - see [LICENSE][] file + +[LICENSE]: https://github.com/capnproto/go-capnproto2/blob/master/LICENSE diff --git a/vendor/zombiezen.com/go/capnproto2/WORKSPACE b/vendor/zombiezen.com/go/capnproto2/WORKSPACE new file mode 100644 index 00000000..7d3d0a61 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/WORKSPACE @@ -0,0 +1,45 @@ +workspace(name = "com_zombiezen_go_capnproto2") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "io_bazel_rules_go", + sha256 = "86ae934bd4c43b99893fc64be9d9fc684b81461581df7ea8fc291c816f5ee8c5", + urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.18.3/rules_go-0.18.3.tar.gz"], +) + +http_archive( + name = "bazel_gazelle", + sha256 = "3c681998538231a2d24d0c07ed5a7658cb72bfb5fd4bf9911157c0e9ac6a2687", + urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.17.0/bazel-gazelle-0.17.0.tar.gz"], +) + +load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") + +go_rules_dependencies() + +go_register_toolchains() + +load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") + +gazelle_dependencies() + +go_repository( + name = "com_github_kylelemons_godebug", + importpath = "github.com/kylelemons/godebug", + sha256 = "4415b09bae90e41695bc17e4d00d0708e1f6bbb6e21cc22ce0146a26ddc243a7", + strip_prefix = "godebug-a616ab194758ae0a11290d87ca46ee8c440117b0", + urls = [ + "https://github.com/kylelemons/godebug/archive/a616ab194758ae0a11290d87ca46ee8c440117b0.zip", + ], +) + +go_repository( + name = "org_golang_x_net", + importpath = "golang.org/x/net", + sha256 = "880dc04d0af397dce6875ee2349bbb4295fe5a47352f7a4da4270456f726edd4", + strip_prefix = "net-f5079bd7f6f74e23c4d65efa0f4ce14cbd6a3c0f", + urls = [ + "https://github.com/golang/net/archive/f5079bd7f6f74e23c4d65efa0f4ce14cbd6a3c0f.zip", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/address.go b/vendor/zombiezen.com/go/capnproto2/address.go new file mode 100644 index 00000000..0e06dc49 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/address.go @@ -0,0 +1,116 @@ +package capnp + +// An Address is an index inside a segment's data (in bytes). +type Address uint32 + +// addSize returns the address a+sz. +func (a Address) addSize(sz Size) (b Address, ok bool) { + x := int64(a) + int64(sz) + if x > int64(maxSize) { + return 0, false + } + return Address(x), true +} + +// element returns the address a+i*sz. +func (a Address) element(i int32, sz Size) (b Address, ok bool) { + x := int64(i) * int64(sz) + if x > int64(maxSize) { + return 0, false + } + x += int64(a) + if x > int64(maxSize) { + return 0, false + } + return Address(x), true +} + +// addOffset returns the address a+o. +func (a Address) addOffset(o DataOffset) Address { + return a + Address(o) +} + +// A Size is a size (in bytes). +type Size uint32 + +// wordSize is the number of bytes in a Cap'n Proto word. +const wordSize Size = 8 + +// maxSize is the maximum representable size. +const maxSize Size = 1<<32 - 1 + +// times returns the size sz*n. +func (sz Size) times(n int32) (ns Size, ok bool) { + x := int64(sz) * int64(n) + if x > int64(maxSize) { + return 0, false + } + return Size(x), true +} + +// padToWord adds padding to sz to make it divisible by wordSize. +func (sz Size) padToWord() Size { + n := Size(wordSize - 1) + return (sz + n) &^ n +} + +// DataOffset is an offset in bytes from the beginning of a struct's data section. +type DataOffset uint32 + +// ObjectSize records section sizes for a struct or list. +type ObjectSize struct { + DataSize Size + PointerCount uint16 +} + +// isZero reports whether sz is the zero size. +func (sz ObjectSize) isZero() bool { + return sz.DataSize == 0 && sz.PointerCount == 0 +} + +// isOneByte reports whether the object size is one byte (for Text/Data element sizes). +func (sz ObjectSize) isOneByte() bool { + return sz.DataSize == 1 && sz.PointerCount == 0 +} + +// isValid reports whether sz's fields are in range. +func (sz ObjectSize) isValid() bool { + return sz.DataSize <= 0xffff*wordSize +} + +// pointerSize returns the number of bytes the pointer section occupies. +func (sz ObjectSize) pointerSize() Size { + // Guaranteed not to overflow + return wordSize * Size(sz.PointerCount) +} + +// totalSize returns the number of bytes that the object occupies. +func (sz ObjectSize) totalSize() Size { + return sz.DataSize + sz.pointerSize() +} + +// dataWordCount returns the number of words in the data section. +func (sz ObjectSize) dataWordCount() int32 { + if sz.DataSize%wordSize != 0 { + panic("data size not aligned by word") + } + return int32(sz.DataSize / wordSize) +} + +// totalWordCount returns the number of words that the object occupies. +func (sz ObjectSize) totalWordCount() int32 { + return sz.dataWordCount() + int32(sz.PointerCount) +} + +// BitOffset is an offset in bits from the beginning of a struct's data section. +type BitOffset uint32 + +// offset returns the equivalent byte offset. +func (bit BitOffset) offset() DataOffset { + return DataOffset(bit / 8) +} + +// mask returns the bitmask for the bit. +func (bit BitOffset) mask() byte { + return byte(1 << (bit % 8)) +} diff --git a/vendor/zombiezen.com/go/capnproto2/canonical.go b/vendor/zombiezen.com/go/capnproto2/canonical.go new file mode 100644 index 00000000..40e5f2ba --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/canonical.go @@ -0,0 +1,161 @@ +package capnp + +import ( + "errors" + "fmt" +) + +// Canonicalize encodes a struct into its canonical form: a single- +// segment blob without a segment table. The result will be identical +// for equivalent structs, even as the schema evolves. The blob is +// suitable for hashing or signing. +func Canonicalize(s Struct) ([]byte, error) { + msg, seg, _ := NewMessage(SingleSegment(nil)) + if !s.IsValid() { + return seg.Data(), nil + } + root, err := NewRootStruct(seg, canonicalStructSize(s)) + if err != nil { + return nil, fmt.Errorf("canonicalize: %v", err) + } + if err := msg.SetRootPtr(root.ToPtr()); err != nil { + return nil, fmt.Errorf("canonicalize: %v", err) + } + if err := fillCanonicalStruct(root, s); err != nil { + return nil, fmt.Errorf("canonicalize: %v", err) + } + return seg.Data(), nil +} + +func canonicalPtr(dst *Segment, p Ptr) (Ptr, error) { + if !p.IsValid() { + return Ptr{}, nil + } + switch p.flags.ptrType() { + case structPtrType: + ss, err := NewStruct(dst, canonicalStructSize(p.Struct())) + if err != nil { + return Ptr{}, err + } + if err := fillCanonicalStruct(ss, p.Struct()); err != nil { + return Ptr{}, err + } + return ss.ToPtr(), nil + case listPtrType: + ll, err := canonicalList(dst, p.List()) + if err != nil { + return Ptr{}, err + } + return ll.ToPtr(), nil + case interfacePtrType: + return Ptr{}, errors.New("cannot canonicalize interface") + default: + panic("unreachable") + } +} + +func fillCanonicalStruct(dst, s Struct) error { + copy(dst.seg.slice(dst.off, dst.size.DataSize), s.seg.slice(s.off, s.size.DataSize)) + for i := uint16(0); i < dst.size.PointerCount; i++ { + p, err := s.Ptr(i) + if err != nil { + return fmt.Errorf("pointer %d: %v", i, err) + } + cp, err := canonicalPtr(dst.seg, p) + if err != nil { + return fmt.Errorf("pointer %d: %v", i, err) + } + if err := dst.SetPtr(i, cp); err != nil { + return fmt.Errorf("pointer %d: %v", i, err) + } + } + return nil +} + +func canonicalStructSize(s Struct) ObjectSize { + if !s.IsValid() { + return ObjectSize{} + } + var sz ObjectSize + // int32 will not overflow because max struct data size is 2^16 words. + for off := int32(s.size.DataSize &^ (wordSize - 1)); off >= 0; off -= int32(wordSize) { + if s.Uint64(DataOffset(off)) != 0 { + sz.DataSize = Size(off) + wordSize + break + } + } + for i := int32(s.size.PointerCount) - 1; i >= 0; i-- { + if s.seg.readRawPointer(s.pointerAddress(uint16(i))) != 0 { + sz.PointerCount = uint16(i + 1) + break + } + } + return sz +} + +func canonicalList(dst *Segment, l List) (List, error) { + if !l.IsValid() { + return List{}, nil + } + if l.size.PointerCount == 0 { + // Data only, just copy over. + sz := l.allocSize() + _, newAddr, err := alloc(dst, sz) + if err != nil { + return List{}, err + } + cl := List{ + seg: dst, + off: newAddr, + length: l.length, + size: l.size, + flags: l.flags, + depthLimit: maxDepth, + } + end, _ := l.off.addSize(sz) // list was already validated + copy(dst.data[newAddr:], l.seg.data[l.off:end]) + return cl, nil + } + if l.flags&isCompositeList == 0 { + cl, err := NewPointerList(dst, l.length) + if err != nil { + return List{}, err + } + for i := 0; i < l.Len(); i++ { + p, err := PointerList{l}.PtrAt(i) + if err != nil { + return List{}, fmt.Errorf("element %d: %v", i, err) + } + cp, err := canonicalPtr(dst, p) + if err != nil { + return List{}, fmt.Errorf("element %d: %v", i, err) + } + if err := cl.SetPtr(i, cp); err != nil { + return List{}, fmt.Errorf("element %d: %v", i, err) + } + } + return cl.List, nil + } + + // Struct/composite list + var elemSize ObjectSize + for i := 0; i < l.Len(); i++ { + sz := canonicalStructSize(l.Struct(i)) + if sz.DataSize > elemSize.DataSize { + elemSize.DataSize = sz.DataSize + } + if sz.PointerCount > elemSize.PointerCount { + elemSize.PointerCount = sz.PointerCount + } + } + cl, err := NewCompositeList(dst, elemSize, l.length) + if err != nil { + return List{}, err + } + for i := 0; i < cl.Len(); i++ { + if err := fillCanonicalStruct(cl.Struct(i), l.Struct(i)); err != nil { + return List{}, fmt.Errorf("element %d: %v", i, err) + } + } + return cl, nil +} diff --git a/vendor/zombiezen.com/go/capnproto2/capability.go b/vendor/zombiezen.com/go/capnproto2/capability.go new file mode 100644 index 00000000..d11c680d --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/capability.go @@ -0,0 +1,541 @@ +package capnp + +import ( + "errors" + "strconv" + + "golang.org/x/net/context" +) + +// An Interface is a reference to a client in a message's capability table. +type Interface struct { + seg *Segment + cap CapabilityID +} + +// NewInterface creates a new interface pointer. No allocation is +// performed; s is only used for Segment()'s return value. +func NewInterface(s *Segment, cap CapabilityID) Interface { + return Interface{ + seg: s, + cap: cap, + } +} + +// ToInterface converts p to an Interface. +// +// Deprecated: Use Ptr.Interface. +func ToInterface(p Pointer) Interface { + if !IsValid(p) { + return Interface{} + } + i, ok := p.underlying().(Interface) + if !ok { + return Interface{} + } + return i +} + +// ToPtr converts the interface to a generic pointer. +func (p Interface) ToPtr() Ptr { + return Ptr{ + seg: p.seg, + lenOrCap: uint32(p.cap), + flags: interfacePtrFlag, + } +} + +// Segment returns the segment this pointer came from. +func (i Interface) Segment() *Segment { + return i.seg +} + +// IsValid returns whether the interface is valid. +func (i Interface) IsValid() bool { + return i.seg != nil +} + +// HasData is always true. +func (i Interface) HasData() bool { + return true +} + +// Capability returns the capability ID of the interface. +func (i Interface) Capability() CapabilityID { + return i.cap +} + +// value returns a raw interface pointer with the capability ID. +func (i Interface) value(paddr Address) rawPointer { + if i.seg == nil { + return 0 + } + return rawInterfacePointer(i.cap) +} + +func (i Interface) underlying() Pointer { + return i +} + +// Client returns the client stored in the message's capability table +// or nil if the pointer is invalid. +func (i Interface) Client() Client { + if i.seg == nil { + return nil + } + tab := i.seg.msg.CapTable + if int64(i.cap) >= int64(len(tab)) { + return nil + } + return tab[i.cap] +} + +// ErrNullClient is returned from a call made on a null client pointer. +var ErrNullClient = errors.New("capnp: call on null client") + +// A CapabilityID is an index into a message's capability table. +type CapabilityID uint32 + +// A Client represents an Cap'n Proto interface type. It is safe to use +// from multiple goroutines. +// +// Generally, only RPC protocol implementers should provide types that +// implement Client: call ordering guarantees, promises, and +// synchronization are tricky to get right. Prefer creating a server +// that wraps another interface than trying to implement Client. +type Client interface { + // Call starts executing a method and returns an answer that will hold + // the resulting struct. The call's parameters must be placed before + // Call() returns. + // + // Calls are delivered to the capability in the order they are made. + // This guarantee is based on the concept of a capability + // acknowledging delivery of a call: this is specific to an + // implementation of Client. A type that implements Client must + // guarantee that if foo() then bar() is called on a client, that + // acknowledging foo() happens before acknowledging bar(). + Call(call *Call) Answer + + // Close releases any resources associated with this client. + // No further calls to the client should be made after calling Close. + Close() error +} + +// The Call type holds the record for an outgoing interface call. +type Call struct { + // Ctx is the context of the call. + Ctx context.Context + + // Method is the interface ID and method ID, along with the optional name, + // of the method to call. + Method Method + + // Params is a struct containing parameters for the call. + // This should be set when the RPC system receives a call for an + // exported interface. It is mutually exclusive with ParamsFunc + // and ParamsSize. + Params Struct + // ParamsFunc is a function that populates an allocated struct with + // the parameters for the call. ParamsSize determines the size of the + // struct to allocate. This is used when application code is using a + // client. These settings should be set together; they are mutually + // exclusive with Params. + ParamsFunc func(Struct) error + ParamsSize ObjectSize + + // Options passes RPC-specific options for the call. + Options CallOptions +} + +// Copy clones a call, ensuring that its Params are placed. +// If Call.ParamsFunc is nil, then the same Call will be returned. +func (call *Call) Copy(s *Segment) (*Call, error) { + if call.ParamsFunc == nil { + return call, nil + } + p, err := call.PlaceParams(s) + if err != nil { + return nil, err + } + return &Call{ + Ctx: call.Ctx, + Method: call.Method, + Params: p, + Options: call.Options, + }, nil +} + +// PlaceParams returns the parameters struct, allocating it inside +// segment s as necessary. If s is nil, a new single-segment message +// is allocated. +func (call *Call) PlaceParams(s *Segment) (Struct, error) { + if call.ParamsFunc == nil { + return call.Params, nil + } + if s == nil { + var err error + _, s, err = NewMessage(SingleSegment(nil)) + if err != nil { + return Struct{}, err + } + } + p, err := NewStruct(s, call.ParamsSize) + if err != nil { + return Struct{}, nil + } + err = call.ParamsFunc(p) + return p, err +} + +// CallOptions holds RPC-specific options for an interface call. +// Its usage is similar to the values in context.Context, but is only +// used for a single call: its values are not intended to propagate to +// other callees. An example of an option would be the +// Call.sendResultsTo field in rpc.capnp. +type CallOptions struct { + m map[interface{}]interface{} +} + +// NewCallOptions builds a CallOptions value from a list of individual options. +func NewCallOptions(opts []CallOption) CallOptions { + co := CallOptions{make(map[interface{}]interface{})} + for _, o := range opts { + o.f(co) + } + return co +} + +// Value retrieves the value associated with the options for this key, +// or nil if no value is associated with this key. +func (co CallOptions) Value(key interface{}) interface{} { + return co.m[key] +} + +// With creates a copy of the CallOptions value with other options applied. +func (co CallOptions) With(opts []CallOption) CallOptions { + newopts := CallOptions{make(map[interface{}]interface{})} + for k, v := range co.m { + newopts.m[k] = v + } + for _, o := range opts { + o.f(newopts) + } + return newopts +} + +// A CallOption is a function that modifies options on an interface call. +type CallOption struct { + f func(CallOptions) +} + +// SetOptionValue returns a call option that associates a value to an +// option key. This can be retrieved later with CallOptions.Value. +func SetOptionValue(key, value interface{}) CallOption { + return CallOption{func(co CallOptions) { + co.m[key] = value + }} +} + +// An Answer is the deferred result of a client call, which is usually wrapped by a Pipeline. +type Answer interface { + // Struct waits until the call is finished and returns the result. + Struct() (Struct, error) + + // The following methods are the same as in Client except with + // an added transform parameter -- a path to the interface to use. + + PipelineCall(transform []PipelineOp, call *Call) Answer + PipelineClose(transform []PipelineOp) error +} + +// A Pipeline is a generic wrapper for an answer. +type Pipeline struct { + answer Answer + parent *Pipeline + op PipelineOp +} + +// NewPipeline returns a new pipeline based on an answer. +func NewPipeline(ans Answer) *Pipeline { + return &Pipeline{answer: ans} +} + +// Answer returns the answer the pipeline is derived from. +func (p *Pipeline) Answer() Answer { + return p.answer +} + +// Transform returns the operations needed to transform the root answer +// into the value p represents. +func (p *Pipeline) Transform() []PipelineOp { + n := 0 + for q := p; q.parent != nil; q = q.parent { + n++ + } + xform := make([]PipelineOp, n) + for i, q := n-1, p; q.parent != nil; i, q = i-1, q.parent { + xform[i] = q.op + } + return xform +} + +// Struct waits until the answer is resolved and returns the struct +// this pipeline represents. +func (p *Pipeline) Struct() (Struct, error) { + s, err := p.answer.Struct() + if err != nil { + return Struct{}, err + } + ptr, err := TransformPtr(s.ToPtr(), p.Transform()) + if err != nil { + return Struct{}, err + } + return ptr.Struct(), nil +} + +// Client returns the client version of p. +func (p *Pipeline) Client() *PipelineClient { + return (*PipelineClient)(p) +} + +// GetPipeline returns a derived pipeline which yields the pointer field given. +func (p *Pipeline) GetPipeline(off uint16) *Pipeline { + return p.GetPipelineDefault(off, nil) +} + +// GetPipelineDefault returns a derived pipeline which yields the pointer field given, +// defaulting to the value given. +func (p *Pipeline) GetPipelineDefault(off uint16, def []byte) *Pipeline { + return &Pipeline{ + answer: p.answer, + parent: p, + op: PipelineOp{ + Field: off, + DefaultValue: def, + }, + } +} + +// PipelineClient implements Client by calling to the pipeline's answer. +type PipelineClient Pipeline + +func (pc *PipelineClient) transform() []PipelineOp { + return (*Pipeline)(pc).Transform() +} + +// Call calls Answer.PipelineCall with the pipeline's transform. +func (pc *PipelineClient) Call(call *Call) Answer { + return pc.answer.PipelineCall(pc.transform(), call) +} + +// Close calls Answer.PipelineClose with the pipeline's transform. +func (pc *PipelineClient) Close() error { + return pc.answer.PipelineClose(pc.transform()) +} + +// A PipelineOp describes a step in transforming a pipeline. +// It maps closely with the PromisedAnswer.Op struct in rpc.capnp. +type PipelineOp struct { + Field uint16 + DefaultValue []byte +} + +// String returns a human-readable description of op. +func (op PipelineOp) String() string { + s := make([]byte, 0, 32) + s = append(s, "get field "...) + s = strconv.AppendInt(s, int64(op.Field), 10) + if op.DefaultValue == nil { + return string(s) + } + s = append(s, " with default"...) + return string(s) +} + +// A Method identifies a method along with an optional human-readable +// description of the method. +type Method struct { + InterfaceID uint64 + MethodID uint16 + + // Canonical name of the interface. May be empty. + InterfaceName string + // Method name as it appears in the schema. May be empty. + MethodName string +} + +// String returns a formatted string containing the interface name or +// the method name if present, otherwise it uses the raw IDs. +// This is suitable for use in error messages and logs. +func (m *Method) String() string { + buf := make([]byte, 0, 128) + if m.InterfaceName == "" { + buf = append(buf, '@', '0', 'x') + buf = strconv.AppendUint(buf, m.InterfaceID, 16) + } else { + buf = append(buf, m.InterfaceName...) + } + buf = append(buf, '.') + if m.MethodName == "" { + buf = append(buf, '@') + buf = strconv.AppendUint(buf, uint64(m.MethodID), 10) + } else { + buf = append(buf, m.MethodName...) + } + return string(buf) +} + +// Transform applies a sequence of pipeline operations to a pointer +// and returns the result. +// +// Deprecated: Use TransformPtr. +func Transform(p Pointer, transform []PipelineOp) (Pointer, error) { + pp, err := TransformPtr(toPtr(p), transform) + return pp.toPointer(), err +} + +// TransformPtr applies a sequence of pipeline operations to a pointer +// and returns the result. +func TransformPtr(p Ptr, transform []PipelineOp) (Ptr, error) { + n := len(transform) + if n == 0 { + return p, nil + } + s := p.Struct() + for _, op := range transform[:n-1] { + field, err := s.Ptr(op.Field) + if err != nil { + return Ptr{}, err + } + s, err = field.StructDefault(op.DefaultValue) + if err != nil { + return Ptr{}, err + } + } + op := transform[n-1] + p, err := s.Ptr(op.Field) + if err != nil { + return Ptr{}, err + } + if op.DefaultValue != nil { + p, err = p.Default(op.DefaultValue) + } + return p, err +} + +type immediateAnswer struct { + s Struct +} + +// ImmediateAnswer returns an Answer that accesses s. +func ImmediateAnswer(s Struct) Answer { + return immediateAnswer{s} +} + +func (ans immediateAnswer) Struct() (Struct, error) { + return ans.s, nil +} + +func (ans immediateAnswer) findClient(transform []PipelineOp) Client { + p, err := TransformPtr(ans.s.ToPtr(), transform) + if err != nil { + return ErrorClient(err) + } + return p.Interface().Client() +} + +func (ans immediateAnswer) PipelineCall(transform []PipelineOp, call *Call) Answer { + c := ans.findClient(transform) + if c == nil { + return ErrorAnswer(ErrNullClient) + } + return c.Call(call) +} + +func (ans immediateAnswer) PipelineClose(transform []PipelineOp) error { + c := ans.findClient(transform) + if c == nil { + return ErrNullClient + } + return c.Close() +} + +type errorAnswer struct { + e error +} + +// ErrorAnswer returns a Answer that always returns error e. +func ErrorAnswer(e error) Answer { + return errorAnswer{e} +} + +func (ans errorAnswer) Struct() (Struct, error) { + return Struct{}, ans.e +} + +func (ans errorAnswer) PipelineCall([]PipelineOp, *Call) Answer { + return ans +} + +func (ans errorAnswer) PipelineClose([]PipelineOp) error { + return ans.e +} + +// IsFixedAnswer reports whether an answer was created by +// ImmediateAnswer or ErrorAnswer. +func IsFixedAnswer(ans Answer) bool { + switch ans.(type) { + case immediateAnswer: + return true + case errorAnswer: + return true + default: + return false + } +} + +type errorClient struct { + e error +} + +// ErrorClient returns a Client that always returns error e. +func ErrorClient(e error) Client { + return errorClient{e} +} + +func (ec errorClient) Call(*Call) Answer { + return ErrorAnswer(ec.e) +} + +func (ec errorClient) Close() error { + return nil +} + +// IsErrorClient reports whether c was created with ErrorClient. +func IsErrorClient(c Client) bool { + _, ok := c.(errorClient) + return ok +} + +// MethodError is an error on an associated method. +type MethodError struct { + Method *Method + Err error +} + +// Error returns the method name concatenated with the error string. +func (e *MethodError) Error() string { + return e.Method.String() + ": " + e.Err.Error() +} + +// ErrUnimplemented is the error returned when a method is called on +// a server that does not implement the method. +var ErrUnimplemented = errors.New("capnp: method not implemented") + +// IsUnimplemented reports whether e indicates an unimplemented method error. +func IsUnimplemented(e error) bool { + if me, ok := e.(*MethodError); ok { + e = me.Err + } + return e == ErrUnimplemented +} diff --git a/vendor/zombiezen.com/go/capnproto2/capn.go b/vendor/zombiezen.com/go/capnproto2/capn.go new file mode 100644 index 00000000..c4701e6e --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/capn.go @@ -0,0 +1,434 @@ +package capnp + +import ( + "encoding/binary" + "errors" +) + +// A SegmentID is a numeric identifier for a Segment. +type SegmentID uint32 + +// A Segment is an allocation arena for Cap'n Proto objects. +// It is part of a Message, which can contain other segments that +// reference each other. +type Segment struct { + msg *Message + id SegmentID + data []byte +} + +// Message returns the message that contains s. +func (s *Segment) Message() *Message { + return s.msg +} + +// ID returns the segment's ID. +func (s *Segment) ID() SegmentID { + return s.id +} + +// Data returns the raw byte slice for the segment. +func (s *Segment) Data() []byte { + return s.data +} + +func (s *Segment) inBounds(addr Address) bool { + return addr < Address(len(s.data)) +} + +func (s *Segment) regionInBounds(base Address, sz Size) bool { + end, ok := base.addSize(sz) + if !ok { + return false + } + return end <= Address(len(s.data)) +} + +// slice returns the segment of data from base to base+sz. +func (s *Segment) slice(base Address, sz Size) []byte { + // Bounds check should have happened before calling slice. + return s.data[base : base+Address(sz)] +} + +func (s *Segment) readUint8(addr Address) uint8 { + return s.slice(addr, 1)[0] +} + +func (s *Segment) readUint16(addr Address) uint16 { + return binary.LittleEndian.Uint16(s.slice(addr, 2)) +} + +func (s *Segment) readUint32(addr Address) uint32 { + return binary.LittleEndian.Uint32(s.slice(addr, 4)) +} + +func (s *Segment) readUint64(addr Address) uint64 { + return binary.LittleEndian.Uint64(s.slice(addr, 8)) +} + +func (s *Segment) readRawPointer(addr Address) rawPointer { + return rawPointer(s.readUint64(addr)) +} + +func (s *Segment) writeUint8(addr Address, val uint8) { + s.slice(addr, 1)[0] = val +} + +func (s *Segment) writeUint16(addr Address, val uint16) { + binary.LittleEndian.PutUint16(s.slice(addr, 2), val) +} + +func (s *Segment) writeUint32(addr Address, val uint32) { + binary.LittleEndian.PutUint32(s.slice(addr, 4), val) +} + +func (s *Segment) writeUint64(addr Address, val uint64) { + binary.LittleEndian.PutUint64(s.slice(addr, 8), val) +} + +func (s *Segment) writeRawPointer(addr Address, val rawPointer) { + s.writeUint64(addr, uint64(val)) +} + +// root returns a 1-element pointer list that references the first word +// in the segment. This only makes sense to call on the first segment +// in a message. +func (s *Segment) root() PointerList { + sz := ObjectSize{PointerCount: 1} + if !s.regionInBounds(0, sz.totalSize()) { + return PointerList{} + } + return PointerList{List{ + seg: s, + length: 1, + size: sz, + depthLimit: s.msg.depthLimit(), + }} +} + +func (s *Segment) lookupSegment(id SegmentID) (*Segment, error) { + if s.id == id { + return s, nil + } + return s.msg.Segment(id) +} + +func (s *Segment) readPtr(paddr Address, depthLimit uint) (ptr Ptr, err error) { + s, base, val, err := s.resolveFarPointer(paddr) + if err != nil { + return Ptr{}, err + } + if val == 0 { + return Ptr{}, nil + } + if depthLimit == 0 { + return Ptr{}, errDepthLimit + } + switch val.pointerType() { + case structPointer: + sp, err := s.readStructPtr(base, val) + if err != nil { + return Ptr{}, err + } + if !s.msg.ReadLimiter().canRead(sp.readSize()) { + return Ptr{}, errReadLimit + } + sp.depthLimit = depthLimit - 1 + return sp.ToPtr(), nil + case listPointer: + lp, err := s.readListPtr(base, val) + if err != nil { + return Ptr{}, err + } + if !s.msg.ReadLimiter().canRead(lp.readSize()) { + return Ptr{}, errReadLimit + } + lp.depthLimit = depthLimit - 1 + return lp.ToPtr(), nil + case otherPointer: + if val.otherPointerType() != 0 { + return Ptr{}, errOtherPointer + } + return Interface{ + seg: s, + cap: val.capabilityIndex(), + }.ToPtr(), nil + default: + // Only other types are far pointers. + return Ptr{}, errBadLandingPad + } +} + +func (s *Segment) readStructPtr(base Address, val rawPointer) (Struct, error) { + addr, ok := val.offset().resolve(base) + if !ok { + return Struct{}, errPointerAddress + } + sz := val.structSize() + if !s.regionInBounds(addr, sz.totalSize()) { + return Struct{}, errPointerAddress + } + return Struct{ + seg: s, + off: addr, + size: sz, + }, nil +} + +func (s *Segment) readListPtr(base Address, val rawPointer) (List, error) { + addr, ok := val.offset().resolve(base) + if !ok { + return List{}, errPointerAddress + } + lsize, ok := val.totalListSize() + if !ok { + return List{}, errOverflow + } + if !s.regionInBounds(addr, lsize) { + return List{}, errPointerAddress + } + lt := val.listType() + if lt == compositeList { + hdr := s.readRawPointer(addr) + var ok bool + addr, ok = addr.addSize(wordSize) + if !ok { + return List{}, errOverflow + } + if hdr.pointerType() != structPointer { + return List{}, errBadTag + } + sz := hdr.structSize() + n := int32(hdr.offset()) + if n < 0 { + return List{}, errListSize + } + // TODO(light): check that this has the same end address + if tsize, ok := sz.totalSize().times(n); !ok { + return List{}, errOverflow + } else if !s.regionInBounds(addr, tsize) { + return List{}, errPointerAddress + } + return List{ + seg: s, + size: sz, + off: addr, + length: n, + flags: isCompositeList, + }, nil + } + n := val.numListElements() + if n < 0 { + return List{}, errListSize + } + if lt == bit1List { + return List{ + seg: s, + off: addr, + length: n, + flags: isBitList, + }, nil + } + return List{ + seg: s, + size: val.elementSize(), + off: addr, + length: n, + }, nil +} + +func (s *Segment) resolveFarPointer(paddr Address) (dst *Segment, base Address, resolved rawPointer, err error) { + // Encoding details at https://capnproto.org/encoding.html#inter-segment-pointers + + val := s.readRawPointer(paddr) + switch val.pointerType() { + case doubleFarPointer: + padSeg, err := s.lookupSegment(val.farSegment()) + if err != nil { + return nil, 0, 0, err + } + padAddr := val.farAddress() + if !padSeg.regionInBounds(padAddr, wordSize*2) { + return nil, 0, 0, errPointerAddress + } + far := padSeg.readRawPointer(padAddr) + if far.pointerType() != farPointer { + return nil, 0, 0, errBadLandingPad + } + tagAddr, ok := padAddr.addSize(wordSize) + if !ok { + return nil, 0, 0, errOverflow + } + tag := padSeg.readRawPointer(tagAddr) + if pt := tag.pointerType(); (pt != structPointer && pt != listPointer) || tag.offset() != 0 { + return nil, 0, 0, errBadLandingPad + } + if dst, err = s.lookupSegment(far.farSegment()); err != nil { + return nil, 0, 0, err + } + return dst, 0, landingPadNearPointer(far, tag), nil + case farPointer: + var err error + dst, err = s.lookupSegment(val.farSegment()) + if err != nil { + return nil, 0, 0, err + } + padAddr := val.farAddress() + if !dst.regionInBounds(padAddr, wordSize) { + return nil, 0, 0, errPointerAddress + } + var ok bool + base, ok = padAddr.addSize(wordSize) + if !ok { + return nil, 0, 0, errOverflow + } + return dst, base, dst.readRawPointer(padAddr), nil + default: + var ok bool + base, ok = paddr.addSize(wordSize) + if !ok { + return nil, 0, 0, errOverflow + } + return s, base, val, nil + } +} + +func (s *Segment) writePtr(off Address, src Ptr, forceCopy bool) error { + if !src.IsValid() { + s.writeRawPointer(off, 0) + return nil + } + + // Copy src, if needed, and process pointers where placement is + // irrelevant (capabilities and zero-sized structs). + var srcAddr Address + var srcRaw rawPointer + switch src.flags.ptrType() { + case structPtrType: + st := src.Struct() + if st.size.isZero() { + // Zero-sized structs should always be encoded with offset -1 in + // order to avoid conflating with null. No allocation needed. + s.writeRawPointer(off, rawStructPointer(-1, ObjectSize{})) + return nil + } + if forceCopy || src.seg.msg != s.msg || st.flags&isListMember != 0 { + newSeg, newAddr, err := alloc(s, st.size.totalSize()) + if err != nil { + return err + } + dst := Struct{ + seg: newSeg, + off: newAddr, + size: st.size, + depthLimit: maxDepth, + // clear flags + } + if err := copyStruct(dst, st); err != nil { + return err + } + st = dst + src = dst.ToPtr() + } + srcAddr = st.off + srcRaw = rawStructPointer(0, st.size) + case listPtrType: + l := src.List() + if forceCopy || src.seg.msg != s.msg { + sz := l.allocSize() + newSeg, newAddr, err := alloc(s, sz) + if err != nil { + return err + } + dst := List{ + seg: newSeg, + off: newAddr, + length: l.length, + size: l.size, + flags: l.flags, + depthLimit: maxDepth, + } + if dst.flags&isCompositeList != 0 { + // Copy tag word + newSeg.writeRawPointer(newAddr, l.seg.readRawPointer(l.off-Address(wordSize))) + var ok bool + dst.off, ok = dst.off.addSize(wordSize) + if !ok { + return errOverflow + } + sz -= wordSize + } + if dst.flags&isBitList != 0 || dst.size.PointerCount == 0 { + end, _ := l.off.addSize(sz) // list was already validated + copy(newSeg.data[dst.off:], l.seg.data[l.off:end]) + } else { + for i := 0; i < l.Len(); i++ { + err := copyStruct(dst.Struct(i), l.Struct(i)) + if err != nil { + return err + } + } + } + l = dst + src = dst.ToPtr() + } + srcAddr = l.off + if l.flags&isCompositeList != 0 { + srcAddr -= Address(wordSize) + } + srcRaw = l.raw() + case interfacePtrType: + i := src.Interface() + if src.seg.msg != s.msg { + c := s.msg.AddCap(i.Client()) + i = NewInterface(s, c) + } + s.writeRawPointer(off, i.value(off)) + return nil + default: + panic("unreachable") + } + + switch { + case src.seg == s: + // Common case: src is in same segment as pointer. + // Use a near pointer. + s.writeRawPointer(off, srcRaw.withOffset(nearPointerOffset(off, srcAddr))) + return nil + case hasCapacity(src.seg.data, wordSize): + // Enough room adjacent to src to write a far pointer landing pad. + _, padAddr, _ := alloc(src.seg, wordSize) + src.seg.writeRawPointer(padAddr, srcRaw.withOffset(nearPointerOffset(padAddr, srcAddr))) + s.writeRawPointer(off, rawFarPointer(src.seg.id, padAddr)) + return nil + default: + // Not enough room for a landing pad, need to use a double-far pointer. + padSeg, padAddr, err := alloc(s, wordSize*2) + if err != nil { + return err + } + padSeg.writeRawPointer(padAddr, rawFarPointer(src.seg.id, srcAddr)) + padSeg.writeRawPointer(padAddr+Address(wordSize), srcRaw) + s.writeRawPointer(off, rawDoubleFarPointer(padSeg.id, padAddr)) + return nil + } +} + +var ( + errPointerAddress = errors.New("capnp: invalid pointer address") + errBadLandingPad = errors.New("capnp: invalid far pointer landing pad") + errBadTag = errors.New("capnp: invalid tag word") + errOtherPointer = errors.New("capnp: unknown pointer type") + errObjectSize = errors.New("capnp: invalid object size") + errElementSize = errors.New("capnp: mismatched list element size") + errReadLimit = errors.New("capnp: read traversal limit reached") + errDepthLimit = errors.New("capnp: depth limit reached") +) + +var ( + errOverflow = errors.New("capnp: address or size overflow") + errOutOfBounds = errors.New("capnp: address out of bounds") + errCopyDepth = errors.New("capnp: copy depth too large") + errOverlap = errors.New("capnp: overlapping data on copy") + errListSize = errors.New("capnp: invalid list size") +) diff --git a/vendor/zombiezen.com/go/capnproto2/doc.go b/vendor/zombiezen.com/go/capnproto2/doc.go new file mode 100644 index 00000000..f4109f1a --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/doc.go @@ -0,0 +1,384 @@ +/* +Package capnp is a Cap'n Proto library for Go. +https://capnproto.org/ + +Read the Getting Started guide for a tutorial on how to use this +package. https://github.com/capnproto/go-capnproto2/wiki/Getting-Started + +Generating code + +capnpc-go provides the compiler backend for capnp. + + # First, install capnpc-go to $PATH. + go install zombiezen.com/go/capnproto2/capnpc-go + # Then, generate Go files. + capnp compile -I$GOPATH/src/zombiezen.com/go/capnproto2/std -ogo *.capnp + +capnpc-go requires two annotations for all files: package and import. +package is needed to know what package to place at the head of the +generated file and what identifier to use when referring to the type +from another package. import should be the fully qualified import path +and is used to generate import statement from other packages and to +detect when two types are in the same package. For example: + + using Go = import "/go.capnp"; + $Go.package("main"); + $Go.import("zombiezen.com/go/capnproto2/example"); + +For adding documentation comments to the generated code, there's the doc +annotation. This annotation adds the comment to a struct, enum or field so +that godoc will pick it up. For example: + + struct Zdate $Go.doc("Zdate represents a calendar date") { + year @0 :Int16; + month @1 :UInt8; + day @2 :UInt8 ; + } + +Messages and Segments + +In Cap'n Proto, the unit of communication is a message. A message +consists of one or more segments -- contiguous blocks of memory. This +allows large messages to be split up and loaded independently or lazily. +Typically you will use one segment per message. Logically, a message is +organized in a tree of objects, with the root always being a struct (as +opposed to a list or primitive). Messages can be read from and written +to a stream. + +The Message and Segment types are the main types that application code +will use from this package. The Message type has methods for marshaling +and unmarshaling its segments to the wire format. If the application +needs to read or write from a stream, it should use the Encoder and +Decoder types. + +Pointers + +The type for a generic reference to a Cap'n Proto object is Ptr. A Ptr +can refer to a struct, a list, or an interface. Ptr, Struct, List, and +Interface (the pointer types) have value semantics and refer to data in +a single segment. All of the pointer types have a notion of "valid". +An invalid pointer will return the default value from any accessor and +panic when any setter is called. + +In previous versions of this package, the Pointer interface was used +instead of the Ptr struct. This interface and functions that use it are +now deprecated. See https://github.com/capnproto/go-capnproto2/wiki/New-Ptr-Type +for details about this API change. + +Data accessors and setters (i.e. struct primitive fields and list +elements) do not return errors, but pointer accessors and setters do. +There are a few reasons that a read or write of a pointer can fail, but +the most common are bad pointers or allocation failures. For accessors, +an invalid object will be returned in case of an error. + +Since Go doesn't have generics, wrapper types provide type safety on +lists. This package provides lists of basic types, and capnpc-go +generates list wrappers for named types. However, if you need to use +deeper nesting of lists (e.g. List(List(UInt8))), you will need to use a +PointerList and wrap the elements. + +Structs + +For the following schema: + + struct Foo @0x8423424e9b01c0af { + num @0 :UInt32; + bar @1 :Foo; + } + +capnpc-go will generate: + + // Foo is a pointer to a Foo struct in a segment. + // Member functions are provided to get/set members in the + // struct. + type Foo struct{ capnp.Struct } + + // Foo_TypeID is the unique identifier for the type Foo. + // It remains the same across languages and schema changes. + const Foo_TypeID = 0x8423424e9b01c0af + + // NewFoo creates a new orphaned Foo struct, preferring placement in + // s. If there isn't enough space, then another segment in the + // message will be used or allocated. You can set a field of type Foo + // to this new message, but usually you will want to use the + // NewBar()-style method shown below. + func NewFoo(s *capnp.Segment) (Foo, error) + + // NewRootFoo creates a new Foo struct and sets the message's root to + // it. + func NewRootFoo(s *capnp.Segment) (Foo, error) + + // ReadRootFoo reads the message's root pointer and converts it to a + // Foo struct. + func ReadRootFoo(msg *capnp.Message) (Foo, error) + + // Num returns the value of the num field. + func (s Foo) Num() uint32 + + // SetNum sets the value of the num field to v. + func (s Foo) SetNum(v uint32) + + // Bar returns the value of the bar field. This can return an error + // if the pointer goes beyond the segment's range, the segment fails + // to load, or the pointer recursion limit has been reached. + func (s Foo) Bar() (Foo, error) + + // HasBar reports whether the bar field was initialized (non-null). + func (s Foo) HasBar() bool + + // SetBar sets the value of the bar field to v. + func (s Foo) SetBar(v Foo) error + + // NewBar sets the bar field to a newly allocated Foo struct, + // preferring placement in s's segment. + func (s Foo) NewBar() (Foo, error) + + // Foo_List is a value with pointer semantics. It is created for all + // structs, and is used for List(Foo) in the capnp file. + type Foo_List struct{ capnp.List } + + // NewFoo_List creates a new orphaned List(Foo), preferring placement + // in s. This can then be added to a message by using a Set function + // which takes a Foo_List. sz specifies the number of elements in the + // list. The list's size cannot be changed after creation. + func NewFoo_List(s *capnp.Segment, sz int32) Foo_List + + // Len returns the number of elements in the list. + func (s Foo_List) Len() int + + // At returns a pointer to the i'th element. If i is an invalid index, + // this will return an invalid Foo (all getters will return default + // values, setters will fail). + func (s Foo_List) At(i int) Foo + + // Foo_Promise is a promise for a Foo. Methods are provided to get + // promises of struct and interface fields. + type Foo_Promise struct{ *capnp.Pipeline } + + // Get waits until the promise is resolved and returns the result. + func (p Foo_Promise) Get() (Foo, error) + + // Bar returns a promise for that bar field. + func (p Foo_Promise) Bar() Foo_Promise + + +Groups + +For each group a typedef is created with a different method set for just the +groups fields: + + struct Foo { + group :Group { + field @0 :Bool; + } + } + +generates the following: + + type Foo struct{ capnp.Struct } + type Foo_group Foo + + func (s Foo) Group() Foo_group + func (s Foo_group) Field() bool + +That way the following may be used to access a field in a group: + + var f Foo + value := f.Group().Field() + +Note that group accessors just convert the type and so have no overhead. + +Unions + +Named unions are treated as a group with an inner unnamed union. Unnamed +unions generate an enum Type_Which and a corresponding Which() function: + + struct Foo { + union { + a @0 :Bool; + b @1 :Bool; + } + } + +generates the following: + + type Foo_Which uint16 + + const ( + Foo_Which_a Foo_Which = 0 + Foo_Which_b Foo_Which = 1 + ) + + func (s Foo) A() bool + func (s Foo) B() bool + func (s Foo) SetA(v bool) + func (s Foo) SetB(v bool) + func (s Foo) Which() Foo_Which + +Which() should be checked before using the getters, and the default case must +always be handled. + +Setters for single values will set the union discriminator as well as set the +value. + +For voids in unions, there is a void setter that just sets the discriminator. +For example: + + struct Foo { + union { + a @0 :Void; + b @1 :Void; + } + } + +generates the following: + + func (s Foo) SetA() // Set that we are using A + func (s Foo) SetB() // Set that we are using B + +Similarly, for groups in unions, there is a group setter that just sets +the discriminator. This must be called before the group getter can be +used to set values. For example: + + struct Foo { + union { + a :group { + v :Bool + } + b :group { + v :Bool + } + } + } + +and in usage: + + f.SetA() // Set that we are using group A + f.A().SetV(true) // then we can use the group A getter to set the inner values + +Enums + +capnpc-go generates enum values as constants. For example in the capnp file: + + enum ElementSize { + empty @0; + bit @1; + byte @2; + twoBytes @3; + fourBytes @4; + eightBytes @5; + pointer @6; + inlineComposite @7; + } + +In the generated capnp.go file: + + type ElementSize uint16 + + const ( + ElementSize_empty ElementSize = 0 + ElementSize_bit ElementSize = 1 + ElementSize_byte ElementSize = 2 + ElementSize_twoBytes ElementSize = 3 + ElementSize_fourBytes ElementSize = 4 + ElementSize_eightBytes ElementSize = 5 + ElementSize_pointer ElementSize = 6 + ElementSize_inlineComposite ElementSize = 7 + ) + +In addition an enum.String() function is generated that will convert the constants to a string +for debugging or logging purposes. By default, the enum name is used as the tag value, +but the tags can be customized with a $Go.tag or $Go.notag annotation. + +For example: + + enum ElementSize { + empty @0 $Go.tag("void"); + bit @1 $Go.tag("1 bit"); + byte @2 $Go.tag("8 bits"); + inlineComposite @7 $Go.notag; + } + +In the generated go file: + + func (c ElementSize) String() string { + switch c { + case ElementSize_empty: + return "void" + case ElementSize_bit: + return "1 bit" + case ElementSize_byte: + return "8 bits" + default: + return "" + } + } + +Interfaces + +capnpc-go generates type-safe Client wrappers for interfaces. For parameter +lists and result lists, structs are generated as described above with the names +Interface_method_Params and Interface_method_Results, unless a single struct +type is used. For example, for this interface: + + interface Calculator { + evaluate @0 (expression :Expression) -> (value :Value); + } + +capnpc-go generates the following Go code (along with the structs +Calculator_evaluate_Params and Calculator_evaluate_Results): + + // Calculator is a client to a Calculator interface. + type Calculator struct{ Client capnp.Client } + + // Evaluate calls `evaluate` on the client. params is called on a newly + // allocated Calculator_evaluate_Params struct to fill in the parameters. + func (c Calculator) Evaluate( + ctx context.Context, + params func(Calculator_evaluate_Params) error, + opts ...capnp.CallOption) *Calculator_evaluate_Results_Promise + +capnpc-go also generates code to implement the interface: + + // A Calculator_Server implements the Calculator interface. + type Calculator_Server interface { + Evaluate(Calculator_evaluate_Call) error + } + + // Calculator_evaluate_Call holds the arguments for a Calculator.evaluate server call. + type Calculator_evaluate_Call struct { + Ctx context.Context + Options capnp.CallOptions + Params Calculator_evaluate_Params + Results Calculator_evaluate_Results + } + + // Calculator_ServerToClient is equivalent to calling: + // NewCalculator(capnp.NewServer(Calculator_Methods(nil, s), s)) + // If s does not implement the Close method, then nil is used. + func Calculator_ServerToClient(s Calculator_Server) Calculator + + // Calculator_Methods appends methods from Calculator that call to server and + // returns the methods. If methods is nil or the capacity of the underlying + // slice is too small, a new slice is returned. + func Calculator_Methods(methods []server.Method, s Calculator_Server) []server.Method + +Since a single capability may want to implement many interfaces, you can +use multiple *_Methods functions to build a single slice to send to +NewServer. + +An example of combining the client/server code to communicate with a locally +implemented Calculator: + + var srv Calculator_Server + calc := Calculator_ServerToClient(srv) + result := calc.Evaluate(ctx, func(params Calculator_evaluate_Params) { + params.SetExpression(expr) + }) + val := result.Value().Get() + +A note about message ordering: when implementing a server method, you +are responsible for acknowledging delivery of a method call. Failure to +do so can cause deadlocks. See the server.Ack function for more details. +*/ +package capnp // import "zombiezen.com/go/capnproto2" diff --git a/vendor/zombiezen.com/go/capnproto2/encoding/text/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/encoding/text/BUILD.bazel new file mode 100644 index 00000000..d22f796d --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/encoding/text/BUILD.bazel @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["marshal.go"], + importpath = "zombiezen.com/go/capnproto2/encoding/text", + visibility = ["//visibility:public"], + deps = [ + "//:go_default_library", + "//internal/nodemap:go_default_library", + "//internal/schema:go_default_library", + "//internal/strquote:go_default_library", + "//schemas:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["marshal_test.go"], + data = glob(["testdata/**"]), + embed = [":go_default_library"], + deps = [ + "//:go_default_library", + "//internal/schema:go_default_library", + "//schemas:go_default_library", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/encoding/text/marshal.go b/vendor/zombiezen.com/go/capnproto2/encoding/text/marshal.go new file mode 100644 index 00000000..fde265c3 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/encoding/text/marshal.go @@ -0,0 +1,582 @@ +// Package text supports marshaling Cap'n Proto messages as text based on a schema. +package text + +import ( + "bytes" + "fmt" + "io" + "math" + "strconv" + + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/nodemap" + "zombiezen.com/go/capnproto2/internal/schema" + "zombiezen.com/go/capnproto2/internal/strquote" + "zombiezen.com/go/capnproto2/schemas" +) + +// Marker strings. +const ( + voidMarker = "void" + interfaceMarker = "" + anyPointerMarker = "" +) + +// Marshal returns the text representation of a struct. +func Marshal(typeID uint64, s capnp.Struct) (string, error) { + buf := new(bytes.Buffer) + if err := NewEncoder(buf).Encode(typeID, s); err != nil { + return "", err + } + return buf.String(), nil +} + +// MarshalList returns the text representation of a struct list. +func MarshalList(typeID uint64, l capnp.List) (string, error) { + buf := new(bytes.Buffer) + if err := NewEncoder(buf).EncodeList(typeID, l); err != nil { + return "", err + } + return buf.String(), nil +} + +// An Encoder writes the text format of Cap'n Proto messages to an output stream. +type Encoder struct { + w indentWriter + tmp []byte + nodes nodemap.Map +} + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + return &Encoder{w: indentWriter{w: w}} +} + +// UseRegistry changes the registry that the encoder consults for +// schemas from the default registry. +func (enc *Encoder) UseRegistry(reg *schemas.Registry) { + enc.nodes.UseRegistry(reg) +} + +// SetIndent sets string to indent each level with. +// An empty string disables indentation. +func (enc *Encoder) SetIndent(indent string) { + enc.w.indentPerLevel = indent +} + +// Encode writes the text representation of s to the stream. +func (enc *Encoder) Encode(typeID uint64, s capnp.Struct) error { + if enc.w.err != nil { + return enc.w.err + } + err := enc.marshalStruct(typeID, s) + if err != nil { + return err + } + return enc.w.err +} + +// EncodeList writes the text representation of struct list l to the stream. +func (enc *Encoder) EncodeList(typeID uint64, l capnp.List) error { + _, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil)) + typ, _ := schema.NewRootType(seg) + typ.SetStructType() + typ.StructType().SetTypeId(typeID) + return enc.marshalList(typ, l) +} + +func (enc *Encoder) marshalBool(v bool) { + if v { + enc.w.WriteString("true") + } else { + enc.w.WriteString("false") + } +} + +func (enc *Encoder) marshalInt(i int64) { + enc.tmp = strconv.AppendInt(enc.tmp[:0], i, 10) + enc.w.Write(enc.tmp) +} + +func (enc *Encoder) marshalUint(i uint64) { + enc.tmp = strconv.AppendUint(enc.tmp[:0], i, 10) + enc.w.Write(enc.tmp) +} + +func (enc *Encoder) marshalFloat32(f float32) { + enc.tmp = strconv.AppendFloat(enc.tmp[:0], float64(f), 'g', -1, 32) + enc.w.Write(enc.tmp) +} + +func (enc *Encoder) marshalFloat64(f float64) { + enc.tmp = strconv.AppendFloat(enc.tmp[:0], f, 'g', -1, 64) + enc.w.Write(enc.tmp) +} + +func (enc *Encoder) marshalText(t []byte) { + enc.tmp = strquote.Append(enc.tmp[:0], t) + enc.w.Write(enc.tmp) +} + +func needsEscape(b byte) bool { + return b < 0x20 || b >= 0x7f +} + +func hexDigit(b byte) byte { + const digits = "0123456789abcdef" + return digits[b] +} + +func (enc *Encoder) marshalStruct(typeID uint64, s capnp.Struct) error { + n, err := enc.nodes.Find(typeID) + if err != nil { + return err + } + if !n.IsValid() || n.Which() != schema.Node_Which_structNode { + return fmt.Errorf("cannot find struct type %#x", typeID) + } + var discriminant uint16 + if n.StructNode().DiscriminantCount() > 0 { + discriminant = s.Uint16(capnp.DataOffset(n.StructNode().DiscriminantOffset() * 2)) + } + fields := codeOrderFields(n.StructNode()) + if len(fields) == 0 { + enc.w.WriteString("()") + return nil + } + enc.w.WriteByte('(') + enc.w.Indent() + enc.w.NewLine() + first := true + for _, f := range fields { + if !(f.Which() == schema.Field_Which_slot || f.Which() == schema.Field_Which_group) { + continue + } + if dv := f.DiscriminantValue(); !(dv == schema.Field_noDiscriminant || dv == discriminant) { + continue + } + if !first { + enc.w.WriteByte(',') + enc.w.NewLineOrSpace() + } + first = false + name, err := f.NameBytes() + if err != nil { + return err + } + enc.w.Write(name) + enc.w.WriteString(" = ") + switch f.Which() { + case schema.Field_Which_slot: + if err := enc.marshalFieldValue(s, f); err != nil { + return err + } + case schema.Field_Which_group: + if err := enc.marshalStruct(f.Group().TypeId(), s); err != nil { + return err + } + } + } + enc.w.NewLine() + enc.w.Unindent() + enc.w.WriteByte(')') + return nil +} + +func (enc *Encoder) marshalFieldValue(s capnp.Struct, f schema.Field) error { + typ, err := f.Slot().Type() + if err != nil { + return err + } + dv, err := f.Slot().DefaultValue() + if err != nil { + return err + } + if dv.IsValid() && int(typ.Which()) != int(dv.Which()) { + name, _ := f.Name() + return fmt.Errorf("marshal field %s: default value is a %v, want %v", name, dv.Which(), typ.Which()) + } + switch typ.Which() { + case schema.Type_Which_void: + enc.w.WriteString(voidMarker) + case schema.Type_Which_bool: + v := s.Bit(capnp.BitOffset(f.Slot().Offset())) + d := dv.Bool() + enc.marshalBool(!d && v || d && !v) + case schema.Type_Which_int8: + v := s.Uint8(capnp.DataOffset(f.Slot().Offset())) + d := uint8(dv.Int8()) + enc.marshalInt(int64(int8(v ^ d))) + case schema.Type_Which_int16: + v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2)) + d := uint16(dv.Int16()) + enc.marshalInt(int64(int16(v ^ d))) + case schema.Type_Which_int32: + v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4)) + d := uint32(dv.Int32()) + enc.marshalInt(int64(int32(v ^ d))) + case schema.Type_Which_int64: + v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8)) + d := uint64(dv.Int64()) + enc.marshalInt(int64(v ^ d)) + case schema.Type_Which_uint8: + v := s.Uint8(capnp.DataOffset(f.Slot().Offset())) + d := dv.Uint8() + enc.marshalUint(uint64(v ^ d)) + case schema.Type_Which_uint16: + v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2)) + d := dv.Uint16() + enc.marshalUint(uint64(v ^ d)) + case schema.Type_Which_uint32: + v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4)) + d := dv.Uint32() + enc.marshalUint(uint64(v ^ d)) + case schema.Type_Which_uint64: + v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8)) + d := dv.Uint64() + enc.marshalUint(v ^ d) + case schema.Type_Which_float32: + v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4)) + d := math.Float32bits(dv.Float32()) + enc.marshalFloat32(math.Float32frombits(v ^ d)) + case schema.Type_Which_float64: + v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8)) + d := math.Float64bits(dv.Float64()) + enc.marshalFloat64(math.Float64frombits(v ^ d)) + case schema.Type_Which_structType: + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + if !p.IsValid() { + p, _ = dv.StructValuePtr() + } + return enc.marshalStruct(typ.StructType().TypeId(), p.Struct()) + case schema.Type_Which_data: + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + if !p.IsValid() { + b, _ := dv.Data() + enc.marshalText(b) + return nil + } + enc.marshalText(p.Data()) + case schema.Type_Which_text: + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + if !p.IsValid() { + b, _ := dv.TextBytes() + enc.marshalText(b) + return nil + } + enc.marshalText(p.TextBytes()) + case schema.Type_Which_list: + elem, err := typ.List().ElementType() + if err != nil { + return err + } + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + if !p.IsValid() { + p, _ = dv.ListPtr() + } + return enc.marshalList(elem, p.List()) + case schema.Type_Which_enum: + v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2)) + d := dv.Uint16() + return enc.marshalEnum(typ.Enum().TypeId(), v^d) + case schema.Type_Which_interface: + enc.w.WriteString(interfaceMarker) + case schema.Type_Which_anyPointer: + enc.w.WriteString(anyPointerMarker) + default: + return fmt.Errorf("unknown field type %v", typ.Which()) + } + return nil +} + +func codeOrderFields(s schema.Node_structNode) []schema.Field { + list, _ := s.Fields() + n := list.Len() + fields := make([]schema.Field, n) + for i := 0; i < n; i++ { + f := list.At(i) + fields[f.CodeOrder()] = f + } + return fields +} + +func (enc *Encoder) marshalList(elem schema.Type, l capnp.List) error { + writeListItems := func(writeItem func(i int) error) error { + if l.Len() == 0 { + _, err := enc.w.WriteString("[]") + return err + } + enc.w.WriteByte('[') + enc.w.Indent() + enc.w.NewLine() + for i := 0; i < l.Len(); i++ { + err := writeItem(i) + if err != nil { + return err + } + if i == l.Len()-1 { + enc.w.NewLine() + } else { + enc.w.WriteByte(',') + enc.w.NewLineOrSpace() + } + } + enc.w.Unindent() + enc.w.WriteByte(']') + return nil + } + writeListItemsN := func(writeItem func(i int) (int, error)) error { + return writeListItems(func(i int) error { + _, err := writeItem(i) + return err + }) + } + switch elem.Which() { + case schema.Type_Which_void: + return writeListItemsN(func(_ int) (int, error) { + return enc.w.WriteString("void") + }) + case schema.Type_Which_bool: + p := capnp.BitList{List: l} + return writeListItemsN(func(i int) (int, error) { + if p.At(i) { + return enc.w.WriteString("true") + } else { + return enc.w.WriteString("false") + } + }) + case schema.Type_Which_int8: + p := capnp.Int8List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatInt(int64(p.At(i)), 10)) + }) + case schema.Type_Which_int16: + p := capnp.Int16List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatInt(int64(p.At(i)), 10)) + }) + case schema.Type_Which_int32: + p := capnp.Int32List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatInt(int64(p.At(i)), 10)) + }) + case schema.Type_Which_int64: + p := capnp.Int64List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatInt(p.At(i), 10)) + }) + case schema.Type_Which_uint8: + p := capnp.UInt8List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatUint(uint64(p.At(i)), 10)) + }) + case schema.Type_Which_uint16: + p := capnp.UInt16List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatUint(uint64(p.At(i)), 10)) + }) + case schema.Type_Which_uint32: + p := capnp.UInt32List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatUint(uint64(p.At(i)), 10)) + }) + case schema.Type_Which_uint64: + p := capnp.UInt64List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatUint(p.At(i), 10)) + }) + case schema.Type_Which_float32: + p := capnp.Float32List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatFloat(float64(p.At(i)), 'g', -1, 32)) + }) + case schema.Type_Which_float64: + p := capnp.Float64List{List: l} + return writeListItemsN(func(i int) (int, error) { + return enc.w.WriteString(strconv.FormatFloat(p.At(i), 'g', -1, 64)) + }) + case schema.Type_Which_data: + p := capnp.DataList{List: l} + return writeListItemsN(func(i int) (int, error) { + s, err := p.At(i) + if err != nil { + return enc.w.WriteString("") + } + buf := strquote.Append(nil, s) + return enc.w.Write(buf) + }) + case schema.Type_Which_text: + p := capnp.TextList{List: l} + return writeListItemsN(func(i int) (int, error) { + s, err := p.BytesAt(i) + if err != nil { + return enc.w.WriteString("") + } + buf := strquote.Append(nil, s) + return enc.w.Write(buf) + }) + case schema.Type_Which_structType: + return writeListItems(func(i int) error { + return enc.marshalStruct(elem.StructType().TypeId(), l.Struct(i)) + }) + case schema.Type_Which_list: + ee, err := elem.List().ElementType() + if err != nil { + return err + } + return writeListItems(func(i int) error { + p, err := capnp.PointerList{List: l}.PtrAt(i) + if err != nil { + return err + } + return enc.marshalList(ee, p.List()) + }) + case schema.Type_Which_enum: + il := capnp.UInt16List{List: l} + typ := elem.Enum().TypeId() + // TODO(light): only search for node once + return writeListItems(func(i int) error { + return enc.marshalEnum(typ, il.At(i)) + }) + case schema.Type_Which_interface: + return writeListItemsN(func(_ int) (int, error) { + return enc.w.WriteString(interfaceMarker) + }) + case schema.Type_Which_anyPointer: + return writeListItemsN(func(_ int) (int, error) { + return enc.w.WriteString(anyPointerMarker) + }) + default: + return fmt.Errorf("unknown list type %v", elem.Which()) + } +} + +func (enc *Encoder) marshalEnum(typ uint64, val uint16) error { + n, err := enc.nodes.Find(typ) + if err != nil { + return err + } + if n.Which() != schema.Node_Which_enum { + return fmt.Errorf("marshaling enum of type @%#x: type is not an enum", typ) + } + enums, err := n.Enum().Enumerants() + if err != nil { + return err + } + if int(val) >= enums.Len() { + enc.marshalUint(uint64(val)) + return nil + } + name, err := enums.At(int(val)).NameBytes() + if err != nil { + return err + } + enc.w.Write(name) + return nil +} + +// indentWriter is helper for writing indented text +type indentWriter struct { + w io.Writer + err error + + // indentPerLevel is a string to prepend to a line for every level of indentation. + indentPerLevel string + + // current indent level + currentIndent int + + // hasLineContent is true when we have written something on the current line. + hasLineContent bool +} + +func (iw *indentWriter) beforeWrite() { + if iw.err != nil { + return + } + if len(iw.indentPerLevel) > 0 && !iw.hasLineContent { + iw.hasLineContent = true + for i := 0; i < iw.currentIndent; i++ { + _, err := iw.w.Write([]byte(iw.indentPerLevel)) + if err != nil { + iw.err = err + return + } + } + } +} + +func (iw *indentWriter) Write(p []byte) (int, error) { + iw.beforeWrite() + if iw.err != nil { + return 0, iw.err + } + var n int + n, iw.err = iw.w.Write(p) + return n, iw.err +} + +func (iw *indentWriter) WriteString(s string) (int, error) { + iw.beforeWrite() + if iw.err != nil { + return 0, iw.err + } + var n int + n, iw.err = io.WriteString(iw.w, s) + return n, iw.err +} + +func (iw *indentWriter) WriteByte(b byte) error { + iw.beforeWrite() + if iw.err != nil { + return iw.err + } + if bw, ok := iw.w.(io.ByteWriter); ok { + iw.err = bw.WriteByte(b) + } else { + _, iw.err = iw.w.Write([]byte{b}) + } + return iw.err +} + +func (iw *indentWriter) Indent() { + iw.currentIndent++ +} + +func (iw *indentWriter) Unindent() { + iw.currentIndent-- +} + +func (iw *indentWriter) NewLine() { + if len(iw.indentPerLevel) > 0 && iw.hasLineContent { + if iw.err != nil { + return + } + if bw, ok := iw.w.(io.ByteWriter); ok { + iw.err = bw.WriteByte('\n') + } else { + _, iw.err = iw.w.Write([]byte{'\n'}) + } + iw.hasLineContent = false + } +} + +func (iw *indentWriter) NewLineOrSpace() { + if len(iw.indentPerLevel) > 0 { + iw.NewLine() + } else { + iw.WriteByte(' ') + } +} diff --git a/vendor/zombiezen.com/go/capnproto2/go.capnp.go b/vendor/zombiezen.com/go/capnproto2/go.capnp.go new file mode 100644 index 00000000..28f18bab --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/go.capnp.go @@ -0,0 +1,45 @@ +// Code generated by capnpc-go. DO NOT EDIT. + +package capnp + +import ( + schemas "zombiezen.com/go/capnproto2/schemas" +) + +const Package = uint64(0xbea97f1023792be0) +const Import = uint64(0xe130b601260e44b5) +const Doc = uint64(0xc58ad6bd519f935e) +const Tag = uint64(0xa574b41924caefc7) +const Notag = uint64(0xc8768679ec52e012) +const Customtype = uint64(0xfa10659ae02f2093) +const Name = uint64(0xc2b96012172f8df1) +const schema_d12a1c51fedd6c88 = "x\xda\x12\x98\xe2\xc0d\xc8z\x9c\x89\x81!P\x81\x95" + + "\xed\xff\xf1\xf7\xa7T$\xb7\x94,e\x08\xe4e\xe5\xf8" + + "\xdf\x91s\xf7_\xa0\x8c\xd6E\x06\x06FaO\xc6." + + "\xe1@Fv\x06\x86`\x1fFfF\x06\xc6\xff\x0f\xb4" + + "+\x95\x05\xeaW\xee\x03)eDQj\xcb\xb8J\xd8" + + "\x15\xac\xd4\x01\xa2\xf4c\xaf\xbe\xb8P\xc2\xceC\x0c\x17" + + "yY\xff\xf1\xa3\xa85d\x9c$l\x09Vk\x02Q" + + "\x1b7y~\xe0\xdek]GA\xc6\x9a\xa0(Ue" + + "\xec\x12\xd6\x05+\xd5\x80(\x15z\x10\xf4\xa6\xb2\xad\xec" + + "\x04\xa6c%\x19g\x09+\x82\x95\xca@\x94nu\xe1" + + "Sc\xdcf\xf0\x10\xd3\xb1\xbc\x8c\x8b\x84E\xc1J\x05" + + " J'+\xe8?\x98\x95*\xf0\x0b\xa4T\x01E)" + + "#\xe3!aN\xb0R\x16\x90R\x9e\xff\xc5%)\xfa" + + "\xe9\xf9z\xc9\x8c\x89\x05y\x05V%\x89\xe9\x0c\x0c\x01" + + "\x8c\x8c\x8c<\x0cLhR\x05\x89\xc9\xfc\xd9\x89\xe9\xa9" + + "\xd8e\xf3\x12s\x19qH\xa5\xe4'\xe323/\xbf" + + "\x8491=\x80\x91\x91\x81\x19M&3\xb7\x80=\xbf" + + "\xa8\x04]\x1b\x13X2\xb9\xb4\xb8$?\xb7\xa4\xb2 " + + "\x15f. \x00\x00\xff\xff\x89\xff\x94\xdf" + +func init() { + schemas.Register(schema_d12a1c51fedd6c88, + 0xa574b41924caefc7, + 0xbea97f1023792be0, + 0xc2b96012172f8df1, + 0xc58ad6bd519f935e, + 0xc8768679ec52e012, + 0xe130b601260e44b5, + 0xfa10659ae02f2093) +} diff --git a/vendor/zombiezen.com/go/capnproto2/internal/fulfiller/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/internal/fulfiller/BUILD.bazel new file mode 100644 index 00000000..e630462a --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/fulfiller/BUILD.bazel @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["fulfiller.go"], + importpath = "zombiezen.com/go/capnproto2/internal/fulfiller", + visibility = ["//:__subpackages__"], + deps = [ + "//:go_default_library", + "//internal/queue:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["fulfiller_test.go"], + embed = [":go_default_library"], + deps = ["//:go_default_library"], +) diff --git a/vendor/zombiezen.com/go/capnproto2/internal/fulfiller/fulfiller.go b/vendor/zombiezen.com/go/capnproto2/internal/fulfiller/fulfiller.go new file mode 100644 index 00000000..a9c9d838 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/fulfiller/fulfiller.go @@ -0,0 +1,329 @@ +// Package fulfiller provides a type that implements capnp.Answer that +// resolves by calling setter methods. +package fulfiller + +import ( + "errors" + "sync" + + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/queue" +) + +// callQueueSize is the maximum number of pending calls. +const callQueueSize = 64 + +// Fulfiller is a promise for a Struct. The zero value is an unresolved +// answer. A Fulfiller is considered to be resolved once Fulfill or +// Reject is called. Calls to the Fulfiller will queue up until it is +// resolved. A Fulfiller is safe to use from multiple goroutines. +type Fulfiller struct { + once sync.Once + resolved chan struct{} // initialized by init() + + // Protected by mu + mu sync.RWMutex + answer capnp.Answer + queue []pcall // initialized by init() +} + +// init initializes the Fulfiller. It is idempotent. +// Should be called for each method on Fulfiller. +func (f *Fulfiller) init() { + f.once.Do(func() { + f.resolved = make(chan struct{}) + f.queue = make([]pcall, 0, callQueueSize) + }) +} + +// Fulfill sets the fulfiller's answer to s. If there are queued +// pipeline calls, the capabilities on the struct will be embargoed +// until the queued calls finish. Fulfill will panic if the fulfiller +// has already been resolved. +func (f *Fulfiller) Fulfill(s capnp.Struct) { + f.init() + f.mu.Lock() + if f.answer != nil { + f.mu.Unlock() + panic("Fulfiller.Fulfill called more than once") + } + f.answer = capnp.ImmediateAnswer(s) + queues := f.emptyQueue(s) + ctab := s.Segment().Message().CapTable + for capIdx, q := range queues { + ctab[capIdx] = newEmbargoClient(ctab[capIdx], q) + } + close(f.resolved) + f.mu.Unlock() +} + +// emptyQueue splits the queue by which capability it targets and +// drops any invalid calls. Once this function returns, f.queue will +// be nil. +func (f *Fulfiller) emptyQueue(s capnp.Struct) map[capnp.CapabilityID][]ecall { + qs := make(map[capnp.CapabilityID][]ecall, len(f.queue)) + for i, pc := range f.queue { + c, err := capnp.TransformPtr(s.ToPtr(), pc.transform) + if err != nil { + pc.f.Reject(err) + continue + } + in := c.Interface() + if !in.IsValid() { + pc.f.Reject(capnp.ErrNullClient) + continue + } + cn := in.Capability() + if qs[cn] == nil { + qs[cn] = make([]ecall, 0, len(f.queue)-i) + } + qs[cn] = append(qs[cn], pc.ecall) + } + f.queue = nil + return qs +} + +// Reject sets the fulfiller's answer to err. If there are queued +// pipeline calls, they will all return errors. Reject will panic if +// the error is nil or the fulfiller has already been resolved. +func (f *Fulfiller) Reject(err error) { + if err == nil { + panic("Fulfiller.Reject called with nil") + } + f.init() + f.mu.Lock() + if f.answer != nil { + f.mu.Unlock() + panic("Fulfiller.Reject called more than once") + } + f.answer = capnp.ErrorAnswer(err) + for i := range f.queue { + f.queue[i].f.Reject(err) + f.queue[i] = pcall{} + } + close(f.resolved) + f.mu.Unlock() +} + +// Done returns a channel that is closed once f is resolved. +func (f *Fulfiller) Done() <-chan struct{} { + f.init() + return f.resolved +} + +// Peek returns f's resolved answer or nil if f has not been resolved. +// The Struct method of an answer returned from Peek returns immediately. +func (f *Fulfiller) Peek() capnp.Answer { + f.init() + f.mu.RLock() + a := f.answer + f.mu.RUnlock() + return a +} + +// Struct waits until f is resolved and returns its struct if fulfilled +// or an error if rejected. +func (f *Fulfiller) Struct() (capnp.Struct, error) { + <-f.Done() + return f.Peek().Struct() +} + +// PipelineCall calls PipelineCall on the fulfilled answer or queues the +// call if f has not been fulfilled. +func (f *Fulfiller) PipelineCall(transform []capnp.PipelineOp, call *capnp.Call) capnp.Answer { + f.init() + + // Fast path: pass-through after fulfilled. + if a := f.Peek(); a != nil { + return a.PipelineCall(transform, call) + } + + f.mu.Lock() + // Make sure that f wasn't fulfilled. + if a := f.answer; a != nil { + f.mu.Unlock() + return a.PipelineCall(transform, call) + } + if len(f.queue) == cap(f.queue) { + f.mu.Unlock() + return capnp.ErrorAnswer(errCallQueueFull) + } + cc, err := call.Copy(nil) + if err != nil { + f.mu.Unlock() + return capnp.ErrorAnswer(err) + } + g := new(Fulfiller) + f.queue = append(f.queue, pcall{ + transform: transform, + ecall: ecall{ + call: cc, + f: g, + }, + }) + f.mu.Unlock() + return g +} + +// PipelineClose waits until f is resolved and then calls PipelineClose +// on the fulfilled answer. +func (f *Fulfiller) PipelineClose(transform []capnp.PipelineOp) error { + <-f.Done() + return f.Peek().PipelineClose(transform) +} + +// pcall is a queued pipeline call. +type pcall struct { + transform []capnp.PipelineOp + ecall +} + +// EmbargoClient is a client that flushes a queue of calls. +// Fulfiller will create these automatically when pipelined calls are +// made on unresolved answers. EmbargoClient is exported so that rpc +// can avoid making calls on its own Conn. +type EmbargoClient struct { + client capnp.Client + + mu sync.RWMutex + q queue.Queue + calls ecallList +} + +func newEmbargoClient(client capnp.Client, queue []ecall) capnp.Client { + ec := &EmbargoClient{ + client: client, + calls: make(ecallList, callQueueSize), + } + ec.q.Init(ec.calls, copy(ec.calls, queue)) + go ec.flushQueue() + return ec +} + +func (ec *EmbargoClient) push(cl *capnp.Call) capnp.Answer { + f := new(Fulfiller) + cl, err := cl.Copy(nil) + if err != nil { + return capnp.ErrorAnswer(err) + } + i := ec.q.Push() + if i == -1 { + return capnp.ErrorAnswer(errCallQueueFull) + } + ec.calls[i] = ecall{cl, f} + return f +} + +// flushQueue is run in its own goroutine. +func (ec *EmbargoClient) flushQueue() { + var c ecall + ec.mu.Lock() + if i := ec.q.Front(); i != -1 { + c = ec.calls[i] + } + ec.mu.Unlock() + for c.call != nil { + ans := ec.client.Call(c.call) + go func(f *Fulfiller, ans capnp.Answer) { + s, err := ans.Struct() + if err == nil { + f.Fulfill(s) + } else { + f.Reject(err) + } + }(c.f, ans) + ec.mu.Lock() + ec.q.Pop() + if i := ec.q.Front(); i != -1 { + c = ec.calls[i] + } else { + c = ecall{} + } + ec.mu.Unlock() + } +} + +// Client returns the underlying client if the embargo has been lifted +// and nil otherwise. +func (ec *EmbargoClient) Client() capnp.Client { + ec.mu.RLock() + ok := ec.isPassthrough() + ec.mu.RUnlock() + if !ok { + return nil + } + return ec.client +} + +func (ec *EmbargoClient) isPassthrough() bool { + return ec.q.Len() == 0 +} + +// Call either queues a call to the underlying client or starts a call +// if the embargo has been lifted. +func (ec *EmbargoClient) Call(cl *capnp.Call) capnp.Answer { + // Fast path: queue is flushed. + ec.mu.RLock() + ok := ec.isPassthrough() + ec.mu.RUnlock() + if ok { + return ec.client.Call(cl) + } + + // Add to queue. + ec.mu.Lock() + // Since we released the lock, check that the queue hasn't been flushed. + if ec.isPassthrough() { + ec.mu.Unlock() + return ec.client.Call(cl) + } + ans := ec.push(cl) + ec.mu.Unlock() + return ans +} + +// TryQueue will attempt to queue a call or return nil if the embargo +// has been lifted. +func (ec *EmbargoClient) TryQueue(cl *capnp.Call) capnp.Answer { + ec.mu.Lock() + if ec.isPassthrough() { + ec.mu.Unlock() + return nil + } + ans := ec.push(cl) + ec.mu.Unlock() + return ans +} + +// Close closes the underlying client, rejecting any queued calls. +func (ec *EmbargoClient) Close() error { + ec.mu.Lock() + // reject all queued calls + for ec.q.Len() > 0 { + ec.calls[ec.q.Front()].f.Reject(errQueueCallCancel) + ec.q.Pop() + } + ec.mu.Unlock() + return ec.client.Close() +} + +// ecall is an queued embargoed call. +type ecall struct { + call *capnp.Call + f *Fulfiller +} + +type ecallList []ecall + +func (el ecallList) Len() int { + return len(el) +} + +func (el ecallList) Clear(i int) { + el[i] = ecall{} +} + +var ( + errCallQueueFull = errors.New("capnp: promised answer call queue full") + errQueueCallCancel = errors.New("capnp: queued call canceled") +) diff --git a/vendor/zombiezen.com/go/capnproto2/internal/nodemap/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/internal/nodemap/BUILD.bazel new file mode 100644 index 00000000..45dda92f --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/nodemap/BUILD.bazel @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["nodemap.go"], + importpath = "zombiezen.com/go/capnproto2/internal/nodemap", + visibility = ["//:__subpackages__"], + deps = [ + "//:go_default_library", + "//internal/schema:go_default_library", + "//schemas:go_default_library", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/internal/nodemap/nodemap.go b/vendor/zombiezen.com/go/capnproto2/internal/nodemap/nodemap.go new file mode 100644 index 00000000..bcacffc7 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/nodemap/nodemap.go @@ -0,0 +1,58 @@ +// Package nodemap provides a schema registry index type. +package nodemap + +import ( + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/schema" + "zombiezen.com/go/capnproto2/schemas" +) + +// Map is a lazy index of a registry. +// The zero value is an index of the default registry. +type Map struct { + reg *schemas.Registry + nodes map[uint64]schema.Node +} + +func (m *Map) registry() *schemas.Registry { + if m.reg != nil { + return m.reg + } + return &schemas.DefaultRegistry +} + +func (m *Map) UseRegistry(reg *schemas.Registry) { + m.reg = reg + m.nodes = make(map[uint64]schema.Node) +} + +// Find returns the node for the given ID. +func (m *Map) Find(id uint64) (schema.Node, error) { + if n := m.nodes[id]; n.IsValid() { + return n, nil + } + data, err := m.registry().Find(id) + if err != nil { + return schema.Node{}, err + } + msg, err := capnp.Unmarshal(data) + if err != nil { + return schema.Node{}, err + } + req, err := schema.ReadRootCodeGeneratorRequest(msg) + if err != nil { + return schema.Node{}, err + } + nodes, err := req.Nodes() + if err != nil { + return schema.Node{}, err + } + if m.nodes == nil { + m.nodes = make(map[uint64]schema.Node) + } + for i := 0; i < nodes.Len(); i++ { + n := nodes.At(i) + m.nodes[n.Id()] = n + } + return m.nodes[id], nil +} diff --git a/vendor/zombiezen.com/go/capnproto2/internal/packed/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/internal/packed/BUILD.bazel new file mode 100644 index 00000000..08938408 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/packed/BUILD.bazel @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "discard.go", + "discard_go14.go", + "packed.go", + ], + importpath = "zombiezen.com/go/capnproto2/internal/packed", + visibility = ["//:__subpackages__"], +) + +go_test( + name = "go_default_test", + srcs = ["packed_test.go"], + data = glob(["testdata/**"]), + embed = [":go_default_library"], +) diff --git a/vendor/zombiezen.com/go/capnproto2/internal/packed/discard.go b/vendor/zombiezen.com/go/capnproto2/internal/packed/discard.go new file mode 100644 index 00000000..6bf54628 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/packed/discard.go @@ -0,0 +1,11 @@ +// +build go1.5 + +package packed + +import ( + "bufio" +) + +func discard(r *bufio.Reader, n int) { + r.Discard(n) +} diff --git a/vendor/zombiezen.com/go/capnproto2/internal/packed/discard_go14.go b/vendor/zombiezen.com/go/capnproto2/internal/packed/discard_go14.go new file mode 100644 index 00000000..a42c391f --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/packed/discard_go14.go @@ -0,0 +1,13 @@ +// +build !go1.5 + +package packed + +import ( + "bufio" + "io" + "io/ioutil" +) + +func discard(r *bufio.Reader, n int) { + io.CopyN(ioutil.Discard, r, int64(n)) +} diff --git a/vendor/zombiezen.com/go/capnproto2/internal/packed/fuzz.go b/vendor/zombiezen.com/go/capnproto2/internal/packed/fuzz.go new file mode 100644 index 00000000..8e10bf5b --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/packed/fuzz.go @@ -0,0 +1,65 @@ +// +build gofuzz + +// Fuzz test harness. To run: +// go-fuzz-build zombiezen.com/go/capnproto2/internal/packed +// go-fuzz -bin=packed-fuzz.zip -workdir=internal/packed/testdata + +package packed + +import ( + "bufio" + "bytes" + "io" + "io/ioutil" +) + +func Fuzz(data []byte) int { + result := 0 + + // Unpacked + if unpacked, err := Unpack(nil, data); err == nil { + checkRepack(unpacked) + result = 1 + } + + // Read + { + r := NewReader(bufio.NewReader(bytes.NewReader(data))) + if unpacked, err := ioutil.ReadAll(r); err == nil { + checkRepack(unpacked) + result = 1 + } + } + + // ReadWord + { + r := NewReader(bufio.NewReader(bytes.NewReader(data))) + var unpacked []byte + var err error + for { + n := len(unpacked) + unpacked = append(unpacked, 0, 0, 0, 0, 0, 0, 0, 0) + if err = r.ReadWord(unpacked[n:]); err != nil { + unpacked = unpacked[:n] + break + } + } + if err == io.EOF { + checkRepack(unpacked) + result = 1 + } + } + + return result +} + +func checkRepack(unpacked []byte) { + packed := Pack(nil, unpacked) + unpacked2, err := Unpack(nil, packed) + if err != nil { + panic("correctness: unpack, pack, unpack gives error: " + err.Error()) + } + if !bytes.Equal(unpacked, unpacked2) { + panic("correctness: unpack, pack, unpack gives different results") + } +} diff --git a/vendor/zombiezen.com/go/capnproto2/internal/packed/packed.go b/vendor/zombiezen.com/go/capnproto2/internal/packed/packed.go new file mode 100644 index 00000000..5cd2c120 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/packed/packed.go @@ -0,0 +1,337 @@ +// Package packed provides functions to read and write the "packed" +// compression scheme described at https://capnproto.org/encoding.html#packing. +package packed + +import ( + "bufio" + "errors" + "io" +) + +const wordSize = 8 + +// Special case tags. +const ( + zeroTag byte = 0x00 + unpackedTag byte = 0xff +) + +// Pack appends the packed version of src to dst and returns the +// resulting slice. len(src) must be a multiple of 8 or Pack panics. +func Pack(dst, src []byte) []byte { + if len(src)%wordSize != 0 { + panic("packed.Pack len(src) must be a multiple of 8") + } + var buf [wordSize]byte + for len(src) > 0 { + var hdr byte + n := 0 + for i := uint(0); i < wordSize; i++ { + if src[i] != 0 { + hdr |= 1 << i + buf[n] = src[i] + n++ + } + } + dst = append(dst, hdr) + dst = append(dst, buf[:n]...) + src = src[wordSize:] + + switch hdr { + case zeroTag: + z := min(numZeroWords(src), 0xff) + dst = append(dst, byte(z)) + src = src[z*wordSize:] + case unpackedTag: + i := 0 + end := min(len(src), 0xff*wordSize) + for i < end { + zeros := 0 + for _, b := range src[i : i+wordSize] { + if b == 0 { + zeros++ + } + } + + if zeros > 1 { + break + } + i += wordSize + } + + rawWords := byte(i / wordSize) + dst = append(dst, rawWords) + dst = append(dst, src[:i]...) + src = src[i:] + } + } + return dst +} + +// numZeroWords returns the number of leading zero words in b. +func numZeroWords(b []byte) int { + for i, bb := range b { + if bb != 0 { + return i / wordSize + } + } + return len(b) / wordSize +} + +// Unpack appends the unpacked version of src to dst and returns the +// resulting slice. +func Unpack(dst, src []byte) ([]byte, error) { + for len(src) > 0 { + tag := src[0] + src = src[1:] + + pstart := len(dst) + dst = allocWords(dst, 1) + p := dst[pstart : pstart+wordSize] + if len(src) >= wordSize { + i := 0 + nz := tag & 1 + p[0] = src[i] & -nz + i += int(nz) + nz = tag >> 1 & 1 + p[1] = src[i] & -nz + i += int(nz) + nz = tag >> 2 & 1 + p[2] = src[i] & -nz + i += int(nz) + nz = tag >> 3 & 1 + p[3] = src[i] & -nz + i += int(nz) + nz = tag >> 4 & 1 + p[4] = src[i] & -nz + i += int(nz) + nz = tag >> 5 & 1 + p[5] = src[i] & -nz + i += int(nz) + nz = tag >> 6 & 1 + p[6] = src[i] & -nz + i += int(nz) + nz = tag >> 7 & 1 + p[7] = src[i] & -nz + i += int(nz) + src = src[i:] + } else { + for i := uint(0); i < wordSize; i++ { + if tag&(1<= target { + pp := p[len(p):target] + for i := range pp { + pp[i] = 0 + } + return p[:target] + } + newcap := cap(p) + doublecap := newcap + newcap + if target > doublecap { + newcap = target + } else { + if len(p) < 1024 { + newcap = doublecap + } else { + for newcap < target { + newcap += newcap / 4 + } + } + } + pp := make([]byte, target, newcap) + copy(pp, p) + return pp +} + +// A Reader decompresses a packed byte stream. +type Reader struct { + // ReadWord state + rd *bufio.Reader + err error + zeroes int + literal int + + // Read state + word [wordSize]byte + wordIdx int +} + +// NewReader returns a reader that decompresses a packed stream from r. +func NewReader(r *bufio.Reader) *Reader { + return &Reader{rd: r, wordIdx: wordSize} +} + +func min(a, b int) int { + if b < a { + return b + } + return a +} + +// ReadWord decompresses the next word from the underlying stream. +func (r *Reader) ReadWord(p []byte) error { + if len(p) < wordSize { + return errors.New("packed: read word buffer too small") + } + r.wordIdx = wordSize // if the caller tries to call ReadWord and Read, don't give them partial words. + if r.err != nil { + err := r.err + r.err = nil + return err + } + p = p[:wordSize] + switch { + case r.zeroes > 0: + r.zeroes-- + for i := range p { + p[i] = 0 + } + return nil + case r.literal > 0: + r.literal-- + _, err := io.ReadFull(r.rd, p) + return err + } + + var tag byte + if r.rd.Buffered() < wordSize+1 { + var err error + tag, err = r.rd.ReadByte() + if err != nil { + return err + } + for i := range p { + p[i] = 0 + } + for i := uint(0); i < wordSize; i++ { + if tag&(1<> 1 & 1 + p[1] = b[i] & -nz + i += int(nz) + nz = tag >> 2 & 1 + p[2] = b[i] & -nz + i += int(nz) + nz = tag >> 3 & 1 + p[3] = b[i] & -nz + i += int(nz) + nz = tag >> 4 & 1 + p[4] = b[i] & -nz + i += int(nz) + nz = tag >> 5 & 1 + p[5] = b[i] & -nz + i += int(nz) + nz = tag >> 6 & 1 + p[6] = b[i] & -nz + i += int(nz) + nz = tag >> 7 & 1 + p[7] = b[i] & -nz + i += int(nz) + discard(r.rd, i) + } + switch tag { + case zeroTag: + z, err := r.rd.ReadByte() + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + r.err = err + return err + } + r.zeroes = int(z) + case unpackedTag: + l, err := r.rd.ReadByte() + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + r.err = err + return err + } + r.literal = int(l) + } + return nil +} + +// Read reads up to len(p) bytes into p. This will decompress whole +// words at a time, so mixing calls to Read and ReadWord may lead to +// bytes missing. +func (r *Reader) Read(p []byte) (n int, err error) { + if r.wordIdx < wordSize { + n = copy(p, r.word[r.wordIdx:]) + r.wordIdx += n + } + for n < len(p) { + if r.rd.Buffered() < wordSize+1 && n > 0 { + return n, nil + } + if len(p)-n >= wordSize { + err := r.ReadWord(p[n:]) + if err != nil { + return n, err + } + n += wordSize + } else { + err := r.ReadWord(r.word[:]) + if err != nil { + return n, err + } + r.wordIdx = copy(p[n:], r.word[:]) + n += r.wordIdx + } + } + return n, nil +} diff --git a/vendor/zombiezen.com/go/capnproto2/internal/queue/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/internal/queue/BUILD.bazel new file mode 100644 index 00000000..60ca4263 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/queue/BUILD.bazel @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["queue.go"], + importpath = "zombiezen.com/go/capnproto2/internal/queue", + visibility = ["//:__subpackages__"], +) + +go_test( + name = "go_default_test", + srcs = ["queue_test.go"], + embed = [":go_default_library"], +) diff --git a/vendor/zombiezen.com/go/capnproto2/internal/queue/queue.go b/vendor/zombiezen.com/go/capnproto2/internal/queue/queue.go new file mode 100644 index 00000000..3f0b95e4 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/queue/queue.go @@ -0,0 +1,70 @@ +// Package queue implements a generic queue using a ring buffer. +package queue + +// A Queue wraps an Interface to provide queue operations. +type Queue struct { + q Interface + start int + n int + cap int +} + +// New creates a new queue that starts with n elements. The interface's +// length must not change over the course of the queue's usage. +func New(q Interface, n int) *Queue { + qq := new(Queue) + qq.Init(q, n) + return qq +} + +// Init initializes a queue. The old queue is untouched. +func (q *Queue) Init(r Interface, n int) { + q.q = r + q.start = 0 + q.n = n + q.cap = r.Len() +} + +// Len returns the length of the queue. This is different from the +// underlying interface's length, which is the queue's capacity. +func (q *Queue) Len() int { + return q.n +} + +// Push reserves space for an element on the queue, returning its index. +// If the queue is full, Push returns -1. +func (q *Queue) Push() int { + if q.n >= q.cap { + return -1 + } + i := (q.start + q.n) % q.cap + q.n++ + return i +} + +// Front returns the index of the front of the queue, or -1 if the queue is empty. +func (q *Queue) Front() int { + if q.n == 0 { + return -1 + } + return q.start +} + +// Pop pops an element from the queue, returning whether it succeeded. +func (q *Queue) Pop() bool { + if q.n == 0 { + return false + } + q.q.Clear(q.start) + q.start = (q.start + 1) % q.cap + q.n-- + return true +} + +// A type implementing Interface can be used to store elements in a Queue. +type Interface interface { + // Len returns the number of elements available. + Len() int + // Clear removes the element at i. + Clear(i int) +} diff --git a/vendor/zombiezen.com/go/capnproto2/internal/schema/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/internal/schema/BUILD.bazel new file mode 100644 index 00000000..2f4eafcf --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/schema/BUILD.bazel @@ -0,0 +1,9 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["schema.capnp.go"], + importpath = "zombiezen.com/go/capnproto2/internal/schema", + visibility = ["//:__subpackages__"], + deps = ["//:go_default_library"], +) diff --git a/vendor/zombiezen.com/go/capnproto2/internal/schema/schema.capnp.go b/vendor/zombiezen.com/go/capnproto2/internal/schema/schema.capnp.go new file mode 100644 index 00000000..d2937278 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/schema/schema.capnp.go @@ -0,0 +1,3071 @@ +// Code generated by capnpc-go. DO NOT EDIT. + +package schema + +import ( + math "math" + strconv "strconv" + capnp "zombiezen.com/go/capnproto2" +) + +// Constants defined in schema.capnp. +const ( + Field_noDiscriminant = uint16(65535) +) + +type Node struct{ capnp.Struct } +type Node_structNode Node +type Node_enum Node +type Node_interface Node +type Node_const Node +type Node_annotation Node +type Node_Which uint16 + +const ( + Node_Which_file Node_Which = 0 + Node_Which_structNode Node_Which = 1 + Node_Which_enum Node_Which = 2 + Node_Which_interface Node_Which = 3 + Node_Which_const Node_Which = 4 + Node_Which_annotation Node_Which = 5 +) + +func (w Node_Which) String() string { + const s = "filestructNodeenuminterfaceconstannotation" + switch w { + case Node_Which_file: + return s[0:4] + case Node_Which_structNode: + return s[4:14] + case Node_Which_enum: + return s[14:18] + case Node_Which_interface: + return s[18:27] + case Node_Which_const: + return s[27:32] + case Node_Which_annotation: + return s[32:42] + + } + return "Node_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Node_TypeID is the unique identifier for the type Node. +const Node_TypeID = 0xe682ab4cf923a417 + +func NewNode(s *capnp.Segment) (Node, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 40, PointerCount: 6}) + return Node{st}, err +} + +func NewRootNode(s *capnp.Segment) (Node, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 40, PointerCount: 6}) + return Node{st}, err +} + +func ReadRootNode(msg *capnp.Message) (Node, error) { + root, err := msg.RootPtr() + return Node{root.Struct()}, err +} + +func (s Node) Which() Node_Which { + return Node_Which(s.Struct.Uint16(12)) +} +func (s Node) Id() uint64 { + return s.Struct.Uint64(0) +} + +func (s Node) SetId(v uint64) { + s.Struct.SetUint64(0, v) +} + +func (s Node) DisplayName() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s Node) HasDisplayName() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Node) DisplayNameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s Node) SetDisplayName(v string) error { + return s.Struct.SetText(0, v) +} + +func (s Node) DisplayNamePrefixLength() uint32 { + return s.Struct.Uint32(8) +} + +func (s Node) SetDisplayNamePrefixLength(v uint32) { + s.Struct.SetUint32(8, v) +} + +func (s Node) ScopeId() uint64 { + return s.Struct.Uint64(16) +} + +func (s Node) SetScopeId(v uint64) { + s.Struct.SetUint64(16, v) +} + +func (s Node) Parameters() (Node_Parameter_List, error) { + p, err := s.Struct.Ptr(5) + return Node_Parameter_List{List: p.List()}, err +} + +func (s Node) HasParameters() bool { + p, err := s.Struct.Ptr(5) + return p.IsValid() || err != nil +} + +func (s Node) SetParameters(v Node_Parameter_List) error { + return s.Struct.SetPtr(5, v.List.ToPtr()) +} + +// NewParameters sets the parameters field to a newly +// allocated Node_Parameter_List, preferring placement in s's segment. +func (s Node) NewParameters(n int32) (Node_Parameter_List, error) { + l, err := NewNode_Parameter_List(s.Struct.Segment(), n) + if err != nil { + return Node_Parameter_List{}, err + } + err = s.Struct.SetPtr(5, l.List.ToPtr()) + return l, err +} + +func (s Node) IsGeneric() bool { + return s.Struct.Bit(288) +} + +func (s Node) SetIsGeneric(v bool) { + s.Struct.SetBit(288, v) +} + +func (s Node) NestedNodes() (Node_NestedNode_List, error) { + p, err := s.Struct.Ptr(1) + return Node_NestedNode_List{List: p.List()}, err +} + +func (s Node) HasNestedNodes() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Node) SetNestedNodes(v Node_NestedNode_List) error { + return s.Struct.SetPtr(1, v.List.ToPtr()) +} + +// NewNestedNodes sets the nestedNodes field to a newly +// allocated Node_NestedNode_List, preferring placement in s's segment. +func (s Node) NewNestedNodes(n int32) (Node_NestedNode_List, error) { + l, err := NewNode_NestedNode_List(s.Struct.Segment(), n) + if err != nil { + return Node_NestedNode_List{}, err + } + err = s.Struct.SetPtr(1, l.List.ToPtr()) + return l, err +} + +func (s Node) Annotations() (Annotation_List, error) { + p, err := s.Struct.Ptr(2) + return Annotation_List{List: p.List()}, err +} + +func (s Node) HasAnnotations() bool { + p, err := s.Struct.Ptr(2) + return p.IsValid() || err != nil +} + +func (s Node) SetAnnotations(v Annotation_List) error { + return s.Struct.SetPtr(2, v.List.ToPtr()) +} + +// NewAnnotations sets the annotations field to a newly +// allocated Annotation_List, preferring placement in s's segment. +func (s Node) NewAnnotations(n int32) (Annotation_List, error) { + l, err := NewAnnotation_List(s.Struct.Segment(), n) + if err != nil { + return Annotation_List{}, err + } + err = s.Struct.SetPtr(2, l.List.ToPtr()) + return l, err +} + +func (s Node) SetFile() { + s.Struct.SetUint16(12, 0) + +} + +func (s Node) StructNode() Node_structNode { return Node_structNode(s) } + +func (s Node) SetStructNode() { + s.Struct.SetUint16(12, 1) +} + +func (s Node_structNode) DataWordCount() uint16 { + return s.Struct.Uint16(14) +} + +func (s Node_structNode) SetDataWordCount(v uint16) { + s.Struct.SetUint16(14, v) +} + +func (s Node_structNode) PointerCount() uint16 { + return s.Struct.Uint16(24) +} + +func (s Node_structNode) SetPointerCount(v uint16) { + s.Struct.SetUint16(24, v) +} + +func (s Node_structNode) PreferredListEncoding() ElementSize { + return ElementSize(s.Struct.Uint16(26)) +} + +func (s Node_structNode) SetPreferredListEncoding(v ElementSize) { + s.Struct.SetUint16(26, uint16(v)) +} + +func (s Node_structNode) IsGroup() bool { + return s.Struct.Bit(224) +} + +func (s Node_structNode) SetIsGroup(v bool) { + s.Struct.SetBit(224, v) +} + +func (s Node_structNode) DiscriminantCount() uint16 { + return s.Struct.Uint16(30) +} + +func (s Node_structNode) SetDiscriminantCount(v uint16) { + s.Struct.SetUint16(30, v) +} + +func (s Node_structNode) DiscriminantOffset() uint32 { + return s.Struct.Uint32(32) +} + +func (s Node_structNode) SetDiscriminantOffset(v uint32) { + s.Struct.SetUint32(32, v) +} + +func (s Node_structNode) Fields() (Field_List, error) { + p, err := s.Struct.Ptr(3) + return Field_List{List: p.List()}, err +} + +func (s Node_structNode) HasFields() bool { + p, err := s.Struct.Ptr(3) + return p.IsValid() || err != nil +} + +func (s Node_structNode) SetFields(v Field_List) error { + return s.Struct.SetPtr(3, v.List.ToPtr()) +} + +// NewFields sets the fields field to a newly +// allocated Field_List, preferring placement in s's segment. +func (s Node_structNode) NewFields(n int32) (Field_List, error) { + l, err := NewField_List(s.Struct.Segment(), n) + if err != nil { + return Field_List{}, err + } + err = s.Struct.SetPtr(3, l.List.ToPtr()) + return l, err +} + +func (s Node) Enum() Node_enum { return Node_enum(s) } + +func (s Node) SetEnum() { + s.Struct.SetUint16(12, 2) +} + +func (s Node_enum) Enumerants() (Enumerant_List, error) { + p, err := s.Struct.Ptr(3) + return Enumerant_List{List: p.List()}, err +} + +func (s Node_enum) HasEnumerants() bool { + p, err := s.Struct.Ptr(3) + return p.IsValid() || err != nil +} + +func (s Node_enum) SetEnumerants(v Enumerant_List) error { + return s.Struct.SetPtr(3, v.List.ToPtr()) +} + +// NewEnumerants sets the enumerants field to a newly +// allocated Enumerant_List, preferring placement in s's segment. +func (s Node_enum) NewEnumerants(n int32) (Enumerant_List, error) { + l, err := NewEnumerant_List(s.Struct.Segment(), n) + if err != nil { + return Enumerant_List{}, err + } + err = s.Struct.SetPtr(3, l.List.ToPtr()) + return l, err +} + +func (s Node) Interface() Node_interface { return Node_interface(s) } + +func (s Node) SetInterface() { + s.Struct.SetUint16(12, 3) +} + +func (s Node_interface) Methods() (Method_List, error) { + p, err := s.Struct.Ptr(3) + return Method_List{List: p.List()}, err +} + +func (s Node_interface) HasMethods() bool { + p, err := s.Struct.Ptr(3) + return p.IsValid() || err != nil +} + +func (s Node_interface) SetMethods(v Method_List) error { + return s.Struct.SetPtr(3, v.List.ToPtr()) +} + +// NewMethods sets the methods field to a newly +// allocated Method_List, preferring placement in s's segment. +func (s Node_interface) NewMethods(n int32) (Method_List, error) { + l, err := NewMethod_List(s.Struct.Segment(), n) + if err != nil { + return Method_List{}, err + } + err = s.Struct.SetPtr(3, l.List.ToPtr()) + return l, err +} + +func (s Node_interface) Superclasses() (Superclass_List, error) { + p, err := s.Struct.Ptr(4) + return Superclass_List{List: p.List()}, err +} + +func (s Node_interface) HasSuperclasses() bool { + p, err := s.Struct.Ptr(4) + return p.IsValid() || err != nil +} + +func (s Node_interface) SetSuperclasses(v Superclass_List) error { + return s.Struct.SetPtr(4, v.List.ToPtr()) +} + +// NewSuperclasses sets the superclasses field to a newly +// allocated Superclass_List, preferring placement in s's segment. +func (s Node_interface) NewSuperclasses(n int32) (Superclass_List, error) { + l, err := NewSuperclass_List(s.Struct.Segment(), n) + if err != nil { + return Superclass_List{}, err + } + err = s.Struct.SetPtr(4, l.List.ToPtr()) + return l, err +} + +func (s Node) Const() Node_const { return Node_const(s) } + +func (s Node) SetConst() { + s.Struct.SetUint16(12, 4) +} + +func (s Node_const) Type() (Type, error) { + p, err := s.Struct.Ptr(3) + return Type{Struct: p.Struct()}, err +} + +func (s Node_const) HasType() bool { + p, err := s.Struct.Ptr(3) + return p.IsValid() || err != nil +} + +func (s Node_const) SetType(v Type) error { + return s.Struct.SetPtr(3, v.Struct.ToPtr()) +} + +// NewType sets the type field to a newly +// allocated Type struct, preferring placement in s's segment. +func (s Node_const) NewType() (Type, error) { + ss, err := NewType(s.Struct.Segment()) + if err != nil { + return Type{}, err + } + err = s.Struct.SetPtr(3, ss.Struct.ToPtr()) + return ss, err +} + +func (s Node_const) Value() (Value, error) { + p, err := s.Struct.Ptr(4) + return Value{Struct: p.Struct()}, err +} + +func (s Node_const) HasValue() bool { + p, err := s.Struct.Ptr(4) + return p.IsValid() || err != nil +} + +func (s Node_const) SetValue(v Value) error { + return s.Struct.SetPtr(4, v.Struct.ToPtr()) +} + +// NewValue sets the value field to a newly +// allocated Value struct, preferring placement in s's segment. +func (s Node_const) NewValue() (Value, error) { + ss, err := NewValue(s.Struct.Segment()) + if err != nil { + return Value{}, err + } + err = s.Struct.SetPtr(4, ss.Struct.ToPtr()) + return ss, err +} + +func (s Node) Annotation() Node_annotation { return Node_annotation(s) } + +func (s Node) SetAnnotation() { + s.Struct.SetUint16(12, 5) +} + +func (s Node_annotation) Type() (Type, error) { + p, err := s.Struct.Ptr(3) + return Type{Struct: p.Struct()}, err +} + +func (s Node_annotation) HasType() bool { + p, err := s.Struct.Ptr(3) + return p.IsValid() || err != nil +} + +func (s Node_annotation) SetType(v Type) error { + return s.Struct.SetPtr(3, v.Struct.ToPtr()) +} + +// NewType sets the type field to a newly +// allocated Type struct, preferring placement in s's segment. +func (s Node_annotation) NewType() (Type, error) { + ss, err := NewType(s.Struct.Segment()) + if err != nil { + return Type{}, err + } + err = s.Struct.SetPtr(3, ss.Struct.ToPtr()) + return ss, err +} + +func (s Node_annotation) TargetsFile() bool { + return s.Struct.Bit(112) +} + +func (s Node_annotation) SetTargetsFile(v bool) { + s.Struct.SetBit(112, v) +} + +func (s Node_annotation) TargetsConst() bool { + return s.Struct.Bit(113) +} + +func (s Node_annotation) SetTargetsConst(v bool) { + s.Struct.SetBit(113, v) +} + +func (s Node_annotation) TargetsEnum() bool { + return s.Struct.Bit(114) +} + +func (s Node_annotation) SetTargetsEnum(v bool) { + s.Struct.SetBit(114, v) +} + +func (s Node_annotation) TargetsEnumerant() bool { + return s.Struct.Bit(115) +} + +func (s Node_annotation) SetTargetsEnumerant(v bool) { + s.Struct.SetBit(115, v) +} + +func (s Node_annotation) TargetsStruct() bool { + return s.Struct.Bit(116) +} + +func (s Node_annotation) SetTargetsStruct(v bool) { + s.Struct.SetBit(116, v) +} + +func (s Node_annotation) TargetsField() bool { + return s.Struct.Bit(117) +} + +func (s Node_annotation) SetTargetsField(v bool) { + s.Struct.SetBit(117, v) +} + +func (s Node_annotation) TargetsUnion() bool { + return s.Struct.Bit(118) +} + +func (s Node_annotation) SetTargetsUnion(v bool) { + s.Struct.SetBit(118, v) +} + +func (s Node_annotation) TargetsGroup() bool { + return s.Struct.Bit(119) +} + +func (s Node_annotation) SetTargetsGroup(v bool) { + s.Struct.SetBit(119, v) +} + +func (s Node_annotation) TargetsInterface() bool { + return s.Struct.Bit(120) +} + +func (s Node_annotation) SetTargetsInterface(v bool) { + s.Struct.SetBit(120, v) +} + +func (s Node_annotation) TargetsMethod() bool { + return s.Struct.Bit(121) +} + +func (s Node_annotation) SetTargetsMethod(v bool) { + s.Struct.SetBit(121, v) +} + +func (s Node_annotation) TargetsParam() bool { + return s.Struct.Bit(122) +} + +func (s Node_annotation) SetTargetsParam(v bool) { + s.Struct.SetBit(122, v) +} + +func (s Node_annotation) TargetsAnnotation() bool { + return s.Struct.Bit(123) +} + +func (s Node_annotation) SetTargetsAnnotation(v bool) { + s.Struct.SetBit(123, v) +} + +// Node_List is a list of Node. +type Node_List struct{ capnp.List } + +// NewNode creates a new list of Node. +func NewNode_List(s *capnp.Segment, sz int32) (Node_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 40, PointerCount: 6}, sz) + return Node_List{l}, err +} + +func (s Node_List) At(i int) Node { return Node{s.List.Struct(i)} } + +func (s Node_List) Set(i int, v Node) error { return s.List.SetStruct(i, v.Struct) } + +// Node_Promise is a wrapper for a Node promised by a client call. +type Node_Promise struct{ *capnp.Pipeline } + +func (p Node_Promise) Struct() (Node, error) { + s, err := p.Pipeline.Struct() + return Node{s}, err +} + +func (p Node_Promise) StructNode() Node_structNode_Promise { return Node_structNode_Promise{p.Pipeline} } + +// Node_structNode_Promise is a wrapper for a Node_structNode promised by a client call. +type Node_structNode_Promise struct{ *capnp.Pipeline } + +func (p Node_structNode_Promise) Struct() (Node_structNode, error) { + s, err := p.Pipeline.Struct() + return Node_structNode{s}, err +} + +func (p Node_Promise) Enum() Node_enum_Promise { return Node_enum_Promise{p.Pipeline} } + +// Node_enum_Promise is a wrapper for a Node_enum promised by a client call. +type Node_enum_Promise struct{ *capnp.Pipeline } + +func (p Node_enum_Promise) Struct() (Node_enum, error) { + s, err := p.Pipeline.Struct() + return Node_enum{s}, err +} + +func (p Node_Promise) Interface() Node_interface_Promise { return Node_interface_Promise{p.Pipeline} } + +// Node_interface_Promise is a wrapper for a Node_interface promised by a client call. +type Node_interface_Promise struct{ *capnp.Pipeline } + +func (p Node_interface_Promise) Struct() (Node_interface, error) { + s, err := p.Pipeline.Struct() + return Node_interface{s}, err +} + +func (p Node_Promise) Const() Node_const_Promise { return Node_const_Promise{p.Pipeline} } + +// Node_const_Promise is a wrapper for a Node_const promised by a client call. +type Node_const_Promise struct{ *capnp.Pipeline } + +func (p Node_const_Promise) Struct() (Node_const, error) { + s, err := p.Pipeline.Struct() + return Node_const{s}, err +} + +func (p Node_const_Promise) Type() Type_Promise { + return Type_Promise{Pipeline: p.Pipeline.GetPipeline(3)} +} + +func (p Node_const_Promise) Value() Value_Promise { + return Value_Promise{Pipeline: p.Pipeline.GetPipeline(4)} +} + +func (p Node_Promise) Annotation() Node_annotation_Promise { return Node_annotation_Promise{p.Pipeline} } + +// Node_annotation_Promise is a wrapper for a Node_annotation promised by a client call. +type Node_annotation_Promise struct{ *capnp.Pipeline } + +func (p Node_annotation_Promise) Struct() (Node_annotation, error) { + s, err := p.Pipeline.Struct() + return Node_annotation{s}, err +} + +func (p Node_annotation_Promise) Type() Type_Promise { + return Type_Promise{Pipeline: p.Pipeline.GetPipeline(3)} +} + +type Node_Parameter struct{ capnp.Struct } + +// Node_Parameter_TypeID is the unique identifier for the type Node_Parameter. +const Node_Parameter_TypeID = 0xb9521bccf10fa3b1 + +func NewNode_Parameter(s *capnp.Segment) (Node_Parameter, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) + return Node_Parameter{st}, err +} + +func NewRootNode_Parameter(s *capnp.Segment) (Node_Parameter, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) + return Node_Parameter{st}, err +} + +func ReadRootNode_Parameter(msg *capnp.Message) (Node_Parameter, error) { + root, err := msg.RootPtr() + return Node_Parameter{root.Struct()}, err +} + +func (s Node_Parameter) Name() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s Node_Parameter) HasName() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Node_Parameter) NameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s Node_Parameter) SetName(v string) error { + return s.Struct.SetText(0, v) +} + +// Node_Parameter_List is a list of Node_Parameter. +type Node_Parameter_List struct{ capnp.List } + +// NewNode_Parameter creates a new list of Node_Parameter. +func NewNode_Parameter_List(s *capnp.Segment, sz int32) (Node_Parameter_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz) + return Node_Parameter_List{l}, err +} + +func (s Node_Parameter_List) At(i int) Node_Parameter { return Node_Parameter{s.List.Struct(i)} } + +func (s Node_Parameter_List) Set(i int, v Node_Parameter) error { return s.List.SetStruct(i, v.Struct) } + +// Node_Parameter_Promise is a wrapper for a Node_Parameter promised by a client call. +type Node_Parameter_Promise struct{ *capnp.Pipeline } + +func (p Node_Parameter_Promise) Struct() (Node_Parameter, error) { + s, err := p.Pipeline.Struct() + return Node_Parameter{s}, err +} + +type Node_NestedNode struct{ capnp.Struct } + +// Node_NestedNode_TypeID is the unique identifier for the type Node_NestedNode. +const Node_NestedNode_TypeID = 0xdebf55bbfa0fc242 + +func NewNode_NestedNode(s *capnp.Segment) (Node_NestedNode, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Node_NestedNode{st}, err +} + +func NewRootNode_NestedNode(s *capnp.Segment) (Node_NestedNode, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Node_NestedNode{st}, err +} + +func ReadRootNode_NestedNode(msg *capnp.Message) (Node_NestedNode, error) { + root, err := msg.RootPtr() + return Node_NestedNode{root.Struct()}, err +} + +func (s Node_NestedNode) Name() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s Node_NestedNode) HasName() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Node_NestedNode) NameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s Node_NestedNode) SetName(v string) error { + return s.Struct.SetText(0, v) +} + +func (s Node_NestedNode) Id() uint64 { + return s.Struct.Uint64(0) +} + +func (s Node_NestedNode) SetId(v uint64) { + s.Struct.SetUint64(0, v) +} + +// Node_NestedNode_List is a list of Node_NestedNode. +type Node_NestedNode_List struct{ capnp.List } + +// NewNode_NestedNode creates a new list of Node_NestedNode. +func NewNode_NestedNode_List(s *capnp.Segment, sz int32) (Node_NestedNode_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Node_NestedNode_List{l}, err +} + +func (s Node_NestedNode_List) At(i int) Node_NestedNode { return Node_NestedNode{s.List.Struct(i)} } + +func (s Node_NestedNode_List) Set(i int, v Node_NestedNode) error { + return s.List.SetStruct(i, v.Struct) +} + +// Node_NestedNode_Promise is a wrapper for a Node_NestedNode promised by a client call. +type Node_NestedNode_Promise struct{ *capnp.Pipeline } + +func (p Node_NestedNode_Promise) Struct() (Node_NestedNode, error) { + s, err := p.Pipeline.Struct() + return Node_NestedNode{s}, err +} + +type Field struct{ capnp.Struct } +type Field_slot Field +type Field_group Field +type Field_ordinal Field +type Field_Which uint16 + +const ( + Field_Which_slot Field_Which = 0 + Field_Which_group Field_Which = 1 +) + +func (w Field_Which) String() string { + const s = "slotgroup" + switch w { + case Field_Which_slot: + return s[0:4] + case Field_Which_group: + return s[4:9] + + } + return "Field_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +type Field_ordinal_Which uint16 + +const ( + Field_ordinal_Which_implicit Field_ordinal_Which = 0 + Field_ordinal_Which_explicit Field_ordinal_Which = 1 +) + +func (w Field_ordinal_Which) String() string { + const s = "implicitexplicit" + switch w { + case Field_ordinal_Which_implicit: + return s[0:8] + case Field_ordinal_Which_explicit: + return s[8:16] + + } + return "Field_ordinal_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Field_TypeID is the unique identifier for the type Field. +const Field_TypeID = 0x9aad50a41f4af45f + +func NewField(s *capnp.Segment) (Field, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 24, PointerCount: 4}) + return Field{st}, err +} + +func NewRootField(s *capnp.Segment) (Field, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 24, PointerCount: 4}) + return Field{st}, err +} + +func ReadRootField(msg *capnp.Message) (Field, error) { + root, err := msg.RootPtr() + return Field{root.Struct()}, err +} + +func (s Field) Which() Field_Which { + return Field_Which(s.Struct.Uint16(8)) +} +func (s Field) Name() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s Field) HasName() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Field) NameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s Field) SetName(v string) error { + return s.Struct.SetText(0, v) +} + +func (s Field) CodeOrder() uint16 { + return s.Struct.Uint16(0) +} + +func (s Field) SetCodeOrder(v uint16) { + s.Struct.SetUint16(0, v) +} + +func (s Field) Annotations() (Annotation_List, error) { + p, err := s.Struct.Ptr(1) + return Annotation_List{List: p.List()}, err +} + +func (s Field) HasAnnotations() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Field) SetAnnotations(v Annotation_List) error { + return s.Struct.SetPtr(1, v.List.ToPtr()) +} + +// NewAnnotations sets the annotations field to a newly +// allocated Annotation_List, preferring placement in s's segment. +func (s Field) NewAnnotations(n int32) (Annotation_List, error) { + l, err := NewAnnotation_List(s.Struct.Segment(), n) + if err != nil { + return Annotation_List{}, err + } + err = s.Struct.SetPtr(1, l.List.ToPtr()) + return l, err +} + +func (s Field) DiscriminantValue() uint16 { + return s.Struct.Uint16(2) ^ 65535 +} + +func (s Field) SetDiscriminantValue(v uint16) { + s.Struct.SetUint16(2, v^65535) +} + +func (s Field) Slot() Field_slot { return Field_slot(s) } + +func (s Field) SetSlot() { + s.Struct.SetUint16(8, 0) +} + +func (s Field_slot) Offset() uint32 { + return s.Struct.Uint32(4) +} + +func (s Field_slot) SetOffset(v uint32) { + s.Struct.SetUint32(4, v) +} + +func (s Field_slot) Type() (Type, error) { + p, err := s.Struct.Ptr(2) + return Type{Struct: p.Struct()}, err +} + +func (s Field_slot) HasType() bool { + p, err := s.Struct.Ptr(2) + return p.IsValid() || err != nil +} + +func (s Field_slot) SetType(v Type) error { + return s.Struct.SetPtr(2, v.Struct.ToPtr()) +} + +// NewType sets the type field to a newly +// allocated Type struct, preferring placement in s's segment. +func (s Field_slot) NewType() (Type, error) { + ss, err := NewType(s.Struct.Segment()) + if err != nil { + return Type{}, err + } + err = s.Struct.SetPtr(2, ss.Struct.ToPtr()) + return ss, err +} + +func (s Field_slot) DefaultValue() (Value, error) { + p, err := s.Struct.Ptr(3) + return Value{Struct: p.Struct()}, err +} + +func (s Field_slot) HasDefaultValue() bool { + p, err := s.Struct.Ptr(3) + return p.IsValid() || err != nil +} + +func (s Field_slot) SetDefaultValue(v Value) error { + return s.Struct.SetPtr(3, v.Struct.ToPtr()) +} + +// NewDefaultValue sets the defaultValue field to a newly +// allocated Value struct, preferring placement in s's segment. +func (s Field_slot) NewDefaultValue() (Value, error) { + ss, err := NewValue(s.Struct.Segment()) + if err != nil { + return Value{}, err + } + err = s.Struct.SetPtr(3, ss.Struct.ToPtr()) + return ss, err +} + +func (s Field_slot) HadExplicitDefault() bool { + return s.Struct.Bit(128) +} + +func (s Field_slot) SetHadExplicitDefault(v bool) { + s.Struct.SetBit(128, v) +} + +func (s Field) Group() Field_group { return Field_group(s) } + +func (s Field) SetGroup() { + s.Struct.SetUint16(8, 1) +} + +func (s Field_group) TypeId() uint64 { + return s.Struct.Uint64(16) +} + +func (s Field_group) SetTypeId(v uint64) { + s.Struct.SetUint64(16, v) +} + +func (s Field) Ordinal() Field_ordinal { return Field_ordinal(s) } + +func (s Field_ordinal) Which() Field_ordinal_Which { + return Field_ordinal_Which(s.Struct.Uint16(10)) +} +func (s Field_ordinal) SetImplicit() { + s.Struct.SetUint16(10, 0) + +} + +func (s Field_ordinal) Explicit() uint16 { + return s.Struct.Uint16(12) +} + +func (s Field_ordinal) SetExplicit(v uint16) { + s.Struct.SetUint16(10, 1) + s.Struct.SetUint16(12, v) +} + +// Field_List is a list of Field. +type Field_List struct{ capnp.List } + +// NewField creates a new list of Field. +func NewField_List(s *capnp.Segment, sz int32) (Field_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 24, PointerCount: 4}, sz) + return Field_List{l}, err +} + +func (s Field_List) At(i int) Field { return Field{s.List.Struct(i)} } + +func (s Field_List) Set(i int, v Field) error { return s.List.SetStruct(i, v.Struct) } + +// Field_Promise is a wrapper for a Field promised by a client call. +type Field_Promise struct{ *capnp.Pipeline } + +func (p Field_Promise) Struct() (Field, error) { + s, err := p.Pipeline.Struct() + return Field{s}, err +} + +func (p Field_Promise) Slot() Field_slot_Promise { return Field_slot_Promise{p.Pipeline} } + +// Field_slot_Promise is a wrapper for a Field_slot promised by a client call. +type Field_slot_Promise struct{ *capnp.Pipeline } + +func (p Field_slot_Promise) Struct() (Field_slot, error) { + s, err := p.Pipeline.Struct() + return Field_slot{s}, err +} + +func (p Field_slot_Promise) Type() Type_Promise { + return Type_Promise{Pipeline: p.Pipeline.GetPipeline(2)} +} + +func (p Field_slot_Promise) DefaultValue() Value_Promise { + return Value_Promise{Pipeline: p.Pipeline.GetPipeline(3)} +} + +func (p Field_Promise) Group() Field_group_Promise { return Field_group_Promise{p.Pipeline} } + +// Field_group_Promise is a wrapper for a Field_group promised by a client call. +type Field_group_Promise struct{ *capnp.Pipeline } + +func (p Field_group_Promise) Struct() (Field_group, error) { + s, err := p.Pipeline.Struct() + return Field_group{s}, err +} + +func (p Field_Promise) Ordinal() Field_ordinal_Promise { return Field_ordinal_Promise{p.Pipeline} } + +// Field_ordinal_Promise is a wrapper for a Field_ordinal promised by a client call. +type Field_ordinal_Promise struct{ *capnp.Pipeline } + +func (p Field_ordinal_Promise) Struct() (Field_ordinal, error) { + s, err := p.Pipeline.Struct() + return Field_ordinal{s}, err +} + +type Enumerant struct{ capnp.Struct } + +// Enumerant_TypeID is the unique identifier for the type Enumerant. +const Enumerant_TypeID = 0x978a7cebdc549a4d + +func NewEnumerant(s *capnp.Segment) (Enumerant, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return Enumerant{st}, err +} + +func NewRootEnumerant(s *capnp.Segment) (Enumerant, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return Enumerant{st}, err +} + +func ReadRootEnumerant(msg *capnp.Message) (Enumerant, error) { + root, err := msg.RootPtr() + return Enumerant{root.Struct()}, err +} + +func (s Enumerant) Name() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s Enumerant) HasName() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Enumerant) NameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s Enumerant) SetName(v string) error { + return s.Struct.SetText(0, v) +} + +func (s Enumerant) CodeOrder() uint16 { + return s.Struct.Uint16(0) +} + +func (s Enumerant) SetCodeOrder(v uint16) { + s.Struct.SetUint16(0, v) +} + +func (s Enumerant) Annotations() (Annotation_List, error) { + p, err := s.Struct.Ptr(1) + return Annotation_List{List: p.List()}, err +} + +func (s Enumerant) HasAnnotations() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Enumerant) SetAnnotations(v Annotation_List) error { + return s.Struct.SetPtr(1, v.List.ToPtr()) +} + +// NewAnnotations sets the annotations field to a newly +// allocated Annotation_List, preferring placement in s's segment. +func (s Enumerant) NewAnnotations(n int32) (Annotation_List, error) { + l, err := NewAnnotation_List(s.Struct.Segment(), n) + if err != nil { + return Annotation_List{}, err + } + err = s.Struct.SetPtr(1, l.List.ToPtr()) + return l, err +} + +// Enumerant_List is a list of Enumerant. +type Enumerant_List struct{ capnp.List } + +// NewEnumerant creates a new list of Enumerant. +func NewEnumerant_List(s *capnp.Segment, sz int32) (Enumerant_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz) + return Enumerant_List{l}, err +} + +func (s Enumerant_List) At(i int) Enumerant { return Enumerant{s.List.Struct(i)} } + +func (s Enumerant_List) Set(i int, v Enumerant) error { return s.List.SetStruct(i, v.Struct) } + +// Enumerant_Promise is a wrapper for a Enumerant promised by a client call. +type Enumerant_Promise struct{ *capnp.Pipeline } + +func (p Enumerant_Promise) Struct() (Enumerant, error) { + s, err := p.Pipeline.Struct() + return Enumerant{s}, err +} + +type Superclass struct{ capnp.Struct } + +// Superclass_TypeID is the unique identifier for the type Superclass. +const Superclass_TypeID = 0xa9962a9ed0a4d7f8 + +func NewSuperclass(s *capnp.Segment) (Superclass, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Superclass{st}, err +} + +func NewRootSuperclass(s *capnp.Segment) (Superclass, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Superclass{st}, err +} + +func ReadRootSuperclass(msg *capnp.Message) (Superclass, error) { + root, err := msg.RootPtr() + return Superclass{root.Struct()}, err +} + +func (s Superclass) Id() uint64 { + return s.Struct.Uint64(0) +} + +func (s Superclass) SetId(v uint64) { + s.Struct.SetUint64(0, v) +} + +func (s Superclass) Brand() (Brand, error) { + p, err := s.Struct.Ptr(0) + return Brand{Struct: p.Struct()}, err +} + +func (s Superclass) HasBrand() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Superclass) SetBrand(v Brand) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewBrand sets the brand field to a newly +// allocated Brand struct, preferring placement in s's segment. +func (s Superclass) NewBrand() (Brand, error) { + ss, err := NewBrand(s.Struct.Segment()) + if err != nil { + return Brand{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +// Superclass_List is a list of Superclass. +type Superclass_List struct{ capnp.List } + +// NewSuperclass creates a new list of Superclass. +func NewSuperclass_List(s *capnp.Segment, sz int32) (Superclass_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Superclass_List{l}, err +} + +func (s Superclass_List) At(i int) Superclass { return Superclass{s.List.Struct(i)} } + +func (s Superclass_List) Set(i int, v Superclass) error { return s.List.SetStruct(i, v.Struct) } + +// Superclass_Promise is a wrapper for a Superclass promised by a client call. +type Superclass_Promise struct{ *capnp.Pipeline } + +func (p Superclass_Promise) Struct() (Superclass, error) { + s, err := p.Pipeline.Struct() + return Superclass{s}, err +} + +func (p Superclass_Promise) Brand() Brand_Promise { + return Brand_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +type Method struct{ capnp.Struct } + +// Method_TypeID is the unique identifier for the type Method. +const Method_TypeID = 0x9500cce23b334d80 + +func NewMethod(s *capnp.Segment) (Method, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 24, PointerCount: 5}) + return Method{st}, err +} + +func NewRootMethod(s *capnp.Segment) (Method, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 24, PointerCount: 5}) + return Method{st}, err +} + +func ReadRootMethod(msg *capnp.Message) (Method, error) { + root, err := msg.RootPtr() + return Method{root.Struct()}, err +} + +func (s Method) Name() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s Method) HasName() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Method) NameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s Method) SetName(v string) error { + return s.Struct.SetText(0, v) +} + +func (s Method) CodeOrder() uint16 { + return s.Struct.Uint16(0) +} + +func (s Method) SetCodeOrder(v uint16) { + s.Struct.SetUint16(0, v) +} + +func (s Method) ImplicitParameters() (Node_Parameter_List, error) { + p, err := s.Struct.Ptr(4) + return Node_Parameter_List{List: p.List()}, err +} + +func (s Method) HasImplicitParameters() bool { + p, err := s.Struct.Ptr(4) + return p.IsValid() || err != nil +} + +func (s Method) SetImplicitParameters(v Node_Parameter_List) error { + return s.Struct.SetPtr(4, v.List.ToPtr()) +} + +// NewImplicitParameters sets the implicitParameters field to a newly +// allocated Node_Parameter_List, preferring placement in s's segment. +func (s Method) NewImplicitParameters(n int32) (Node_Parameter_List, error) { + l, err := NewNode_Parameter_List(s.Struct.Segment(), n) + if err != nil { + return Node_Parameter_List{}, err + } + err = s.Struct.SetPtr(4, l.List.ToPtr()) + return l, err +} + +func (s Method) ParamStructType() uint64 { + return s.Struct.Uint64(8) +} + +func (s Method) SetParamStructType(v uint64) { + s.Struct.SetUint64(8, v) +} + +func (s Method) ParamBrand() (Brand, error) { + p, err := s.Struct.Ptr(2) + return Brand{Struct: p.Struct()}, err +} + +func (s Method) HasParamBrand() bool { + p, err := s.Struct.Ptr(2) + return p.IsValid() || err != nil +} + +func (s Method) SetParamBrand(v Brand) error { + return s.Struct.SetPtr(2, v.Struct.ToPtr()) +} + +// NewParamBrand sets the paramBrand field to a newly +// allocated Brand struct, preferring placement in s's segment. +func (s Method) NewParamBrand() (Brand, error) { + ss, err := NewBrand(s.Struct.Segment()) + if err != nil { + return Brand{}, err + } + err = s.Struct.SetPtr(2, ss.Struct.ToPtr()) + return ss, err +} + +func (s Method) ResultStructType() uint64 { + return s.Struct.Uint64(16) +} + +func (s Method) SetResultStructType(v uint64) { + s.Struct.SetUint64(16, v) +} + +func (s Method) ResultBrand() (Brand, error) { + p, err := s.Struct.Ptr(3) + return Brand{Struct: p.Struct()}, err +} + +func (s Method) HasResultBrand() bool { + p, err := s.Struct.Ptr(3) + return p.IsValid() || err != nil +} + +func (s Method) SetResultBrand(v Brand) error { + return s.Struct.SetPtr(3, v.Struct.ToPtr()) +} + +// NewResultBrand sets the resultBrand field to a newly +// allocated Brand struct, preferring placement in s's segment. +func (s Method) NewResultBrand() (Brand, error) { + ss, err := NewBrand(s.Struct.Segment()) + if err != nil { + return Brand{}, err + } + err = s.Struct.SetPtr(3, ss.Struct.ToPtr()) + return ss, err +} + +func (s Method) Annotations() (Annotation_List, error) { + p, err := s.Struct.Ptr(1) + return Annotation_List{List: p.List()}, err +} + +func (s Method) HasAnnotations() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Method) SetAnnotations(v Annotation_List) error { + return s.Struct.SetPtr(1, v.List.ToPtr()) +} + +// NewAnnotations sets the annotations field to a newly +// allocated Annotation_List, preferring placement in s's segment. +func (s Method) NewAnnotations(n int32) (Annotation_List, error) { + l, err := NewAnnotation_List(s.Struct.Segment(), n) + if err != nil { + return Annotation_List{}, err + } + err = s.Struct.SetPtr(1, l.List.ToPtr()) + return l, err +} + +// Method_List is a list of Method. +type Method_List struct{ capnp.List } + +// NewMethod creates a new list of Method. +func NewMethod_List(s *capnp.Segment, sz int32) (Method_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 24, PointerCount: 5}, sz) + return Method_List{l}, err +} + +func (s Method_List) At(i int) Method { return Method{s.List.Struct(i)} } + +func (s Method_List) Set(i int, v Method) error { return s.List.SetStruct(i, v.Struct) } + +// Method_Promise is a wrapper for a Method promised by a client call. +type Method_Promise struct{ *capnp.Pipeline } + +func (p Method_Promise) Struct() (Method, error) { + s, err := p.Pipeline.Struct() + return Method{s}, err +} + +func (p Method_Promise) ParamBrand() Brand_Promise { + return Brand_Promise{Pipeline: p.Pipeline.GetPipeline(2)} +} + +func (p Method_Promise) ResultBrand() Brand_Promise { + return Brand_Promise{Pipeline: p.Pipeline.GetPipeline(3)} +} + +type Type struct{ capnp.Struct } +type Type_list Type +type Type_enum Type +type Type_structType Type +type Type_interface Type +type Type_anyPointer Type +type Type_anyPointer_unconstrained Type +type Type_anyPointer_parameter Type +type Type_anyPointer_implicitMethodParameter Type +type Type_Which uint16 + +const ( + Type_Which_void Type_Which = 0 + Type_Which_bool Type_Which = 1 + Type_Which_int8 Type_Which = 2 + Type_Which_int16 Type_Which = 3 + Type_Which_int32 Type_Which = 4 + Type_Which_int64 Type_Which = 5 + Type_Which_uint8 Type_Which = 6 + Type_Which_uint16 Type_Which = 7 + Type_Which_uint32 Type_Which = 8 + Type_Which_uint64 Type_Which = 9 + Type_Which_float32 Type_Which = 10 + Type_Which_float64 Type_Which = 11 + Type_Which_text Type_Which = 12 + Type_Which_data Type_Which = 13 + Type_Which_list Type_Which = 14 + Type_Which_enum Type_Which = 15 + Type_Which_structType Type_Which = 16 + Type_Which_interface Type_Which = 17 + Type_Which_anyPointer Type_Which = 18 +) + +func (w Type_Which) String() string { + const s = "voidboolint8int16int32int64uint8uint16uint32uint64float32float64textdatalistenumstructTypeinterfaceanyPointer" + switch w { + case Type_Which_void: + return s[0:4] + case Type_Which_bool: + return s[4:8] + case Type_Which_int8: + return s[8:12] + case Type_Which_int16: + return s[12:17] + case Type_Which_int32: + return s[17:22] + case Type_Which_int64: + return s[22:27] + case Type_Which_uint8: + return s[27:32] + case Type_Which_uint16: + return s[32:38] + case Type_Which_uint32: + return s[38:44] + case Type_Which_uint64: + return s[44:50] + case Type_Which_float32: + return s[50:57] + case Type_Which_float64: + return s[57:64] + case Type_Which_text: + return s[64:68] + case Type_Which_data: + return s[68:72] + case Type_Which_list: + return s[72:76] + case Type_Which_enum: + return s[76:80] + case Type_Which_structType: + return s[80:90] + case Type_Which_interface: + return s[90:99] + case Type_Which_anyPointer: + return s[99:109] + + } + return "Type_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +type Type_anyPointer_Which uint16 + +const ( + Type_anyPointer_Which_unconstrained Type_anyPointer_Which = 0 + Type_anyPointer_Which_parameter Type_anyPointer_Which = 1 + Type_anyPointer_Which_implicitMethodParameter Type_anyPointer_Which = 2 +) + +func (w Type_anyPointer_Which) String() string { + const s = "unconstrainedparameterimplicitMethodParameter" + switch w { + case Type_anyPointer_Which_unconstrained: + return s[0:13] + case Type_anyPointer_Which_parameter: + return s[13:22] + case Type_anyPointer_Which_implicitMethodParameter: + return s[22:45] + + } + return "Type_anyPointer_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +type Type_anyPointer_unconstrained_Which uint16 + +const ( + Type_anyPointer_unconstrained_Which_anyKind Type_anyPointer_unconstrained_Which = 0 + Type_anyPointer_unconstrained_Which_struct Type_anyPointer_unconstrained_Which = 1 + Type_anyPointer_unconstrained_Which_list Type_anyPointer_unconstrained_Which = 2 + Type_anyPointer_unconstrained_Which_capability Type_anyPointer_unconstrained_Which = 3 +) + +func (w Type_anyPointer_unconstrained_Which) String() string { + const s = "anyKindstructlistcapability" + switch w { + case Type_anyPointer_unconstrained_Which_anyKind: + return s[0:7] + case Type_anyPointer_unconstrained_Which_struct: + return s[7:13] + case Type_anyPointer_unconstrained_Which_list: + return s[13:17] + case Type_anyPointer_unconstrained_Which_capability: + return s[17:27] + + } + return "Type_anyPointer_unconstrained_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Type_TypeID is the unique identifier for the type Type. +const Type_TypeID = 0xd07378ede1f9cc60 + +func NewType(s *capnp.Segment) (Type, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 24, PointerCount: 1}) + return Type{st}, err +} + +func NewRootType(s *capnp.Segment) (Type, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 24, PointerCount: 1}) + return Type{st}, err +} + +func ReadRootType(msg *capnp.Message) (Type, error) { + root, err := msg.RootPtr() + return Type{root.Struct()}, err +} + +func (s Type) Which() Type_Which { + return Type_Which(s.Struct.Uint16(0)) +} +func (s Type) SetVoid() { + s.Struct.SetUint16(0, 0) + +} + +func (s Type) SetBool() { + s.Struct.SetUint16(0, 1) + +} + +func (s Type) SetInt8() { + s.Struct.SetUint16(0, 2) + +} + +func (s Type) SetInt16() { + s.Struct.SetUint16(0, 3) + +} + +func (s Type) SetInt32() { + s.Struct.SetUint16(0, 4) + +} + +func (s Type) SetInt64() { + s.Struct.SetUint16(0, 5) + +} + +func (s Type) SetUint8() { + s.Struct.SetUint16(0, 6) + +} + +func (s Type) SetUint16() { + s.Struct.SetUint16(0, 7) + +} + +func (s Type) SetUint32() { + s.Struct.SetUint16(0, 8) + +} + +func (s Type) SetUint64() { + s.Struct.SetUint16(0, 9) + +} + +func (s Type) SetFloat32() { + s.Struct.SetUint16(0, 10) + +} + +func (s Type) SetFloat64() { + s.Struct.SetUint16(0, 11) + +} + +func (s Type) SetText() { + s.Struct.SetUint16(0, 12) + +} + +func (s Type) SetData() { + s.Struct.SetUint16(0, 13) + +} + +func (s Type) List() Type_list { return Type_list(s) } + +func (s Type) SetList() { + s.Struct.SetUint16(0, 14) +} + +func (s Type_list) ElementType() (Type, error) { + p, err := s.Struct.Ptr(0) + return Type{Struct: p.Struct()}, err +} + +func (s Type_list) HasElementType() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Type_list) SetElementType(v Type) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewElementType sets the elementType field to a newly +// allocated Type struct, preferring placement in s's segment. +func (s Type_list) NewElementType() (Type, error) { + ss, err := NewType(s.Struct.Segment()) + if err != nil { + return Type{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Type) Enum() Type_enum { return Type_enum(s) } + +func (s Type) SetEnum() { + s.Struct.SetUint16(0, 15) +} + +func (s Type_enum) TypeId() uint64 { + return s.Struct.Uint64(8) +} + +func (s Type_enum) SetTypeId(v uint64) { + s.Struct.SetUint64(8, v) +} + +func (s Type_enum) Brand() (Brand, error) { + p, err := s.Struct.Ptr(0) + return Brand{Struct: p.Struct()}, err +} + +func (s Type_enum) HasBrand() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Type_enum) SetBrand(v Brand) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewBrand sets the brand field to a newly +// allocated Brand struct, preferring placement in s's segment. +func (s Type_enum) NewBrand() (Brand, error) { + ss, err := NewBrand(s.Struct.Segment()) + if err != nil { + return Brand{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Type) StructType() Type_structType { return Type_structType(s) } + +func (s Type) SetStructType() { + s.Struct.SetUint16(0, 16) +} + +func (s Type_structType) TypeId() uint64 { + return s.Struct.Uint64(8) +} + +func (s Type_structType) SetTypeId(v uint64) { + s.Struct.SetUint64(8, v) +} + +func (s Type_structType) Brand() (Brand, error) { + p, err := s.Struct.Ptr(0) + return Brand{Struct: p.Struct()}, err +} + +func (s Type_structType) HasBrand() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Type_structType) SetBrand(v Brand) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewBrand sets the brand field to a newly +// allocated Brand struct, preferring placement in s's segment. +func (s Type_structType) NewBrand() (Brand, error) { + ss, err := NewBrand(s.Struct.Segment()) + if err != nil { + return Brand{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Type) Interface() Type_interface { return Type_interface(s) } + +func (s Type) SetInterface() { + s.Struct.SetUint16(0, 17) +} + +func (s Type_interface) TypeId() uint64 { + return s.Struct.Uint64(8) +} + +func (s Type_interface) SetTypeId(v uint64) { + s.Struct.SetUint64(8, v) +} + +func (s Type_interface) Brand() (Brand, error) { + p, err := s.Struct.Ptr(0) + return Brand{Struct: p.Struct()}, err +} + +func (s Type_interface) HasBrand() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Type_interface) SetBrand(v Brand) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewBrand sets the brand field to a newly +// allocated Brand struct, preferring placement in s's segment. +func (s Type_interface) NewBrand() (Brand, error) { + ss, err := NewBrand(s.Struct.Segment()) + if err != nil { + return Brand{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Type) AnyPointer() Type_anyPointer { return Type_anyPointer(s) } + +func (s Type) SetAnyPointer() { + s.Struct.SetUint16(0, 18) +} + +func (s Type_anyPointer) Which() Type_anyPointer_Which { + return Type_anyPointer_Which(s.Struct.Uint16(8)) +} +func (s Type_anyPointer) Unconstrained() Type_anyPointer_unconstrained { + return Type_anyPointer_unconstrained(s) +} + +func (s Type_anyPointer) SetUnconstrained() { + s.Struct.SetUint16(8, 0) +} + +func (s Type_anyPointer_unconstrained) Which() Type_anyPointer_unconstrained_Which { + return Type_anyPointer_unconstrained_Which(s.Struct.Uint16(10)) +} +func (s Type_anyPointer_unconstrained) SetAnyKind() { + s.Struct.SetUint16(10, 0) + +} + +func (s Type_anyPointer_unconstrained) SetStruct() { + s.Struct.SetUint16(10, 1) + +} + +func (s Type_anyPointer_unconstrained) SetList() { + s.Struct.SetUint16(10, 2) + +} + +func (s Type_anyPointer_unconstrained) SetCapability() { + s.Struct.SetUint16(10, 3) + +} + +func (s Type_anyPointer) Parameter() Type_anyPointer_parameter { return Type_anyPointer_parameter(s) } + +func (s Type_anyPointer) SetParameter() { + s.Struct.SetUint16(8, 1) +} + +func (s Type_anyPointer_parameter) ScopeId() uint64 { + return s.Struct.Uint64(16) +} + +func (s Type_anyPointer_parameter) SetScopeId(v uint64) { + s.Struct.SetUint64(16, v) +} + +func (s Type_anyPointer_parameter) ParameterIndex() uint16 { + return s.Struct.Uint16(10) +} + +func (s Type_anyPointer_parameter) SetParameterIndex(v uint16) { + s.Struct.SetUint16(10, v) +} + +func (s Type_anyPointer) ImplicitMethodParameter() Type_anyPointer_implicitMethodParameter { + return Type_anyPointer_implicitMethodParameter(s) +} + +func (s Type_anyPointer) SetImplicitMethodParameter() { + s.Struct.SetUint16(8, 2) +} + +func (s Type_anyPointer_implicitMethodParameter) ParameterIndex() uint16 { + return s.Struct.Uint16(10) +} + +func (s Type_anyPointer_implicitMethodParameter) SetParameterIndex(v uint16) { + s.Struct.SetUint16(10, v) +} + +// Type_List is a list of Type. +type Type_List struct{ capnp.List } + +// NewType creates a new list of Type. +func NewType_List(s *capnp.Segment, sz int32) (Type_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 24, PointerCount: 1}, sz) + return Type_List{l}, err +} + +func (s Type_List) At(i int) Type { return Type{s.List.Struct(i)} } + +func (s Type_List) Set(i int, v Type) error { return s.List.SetStruct(i, v.Struct) } + +// Type_Promise is a wrapper for a Type promised by a client call. +type Type_Promise struct{ *capnp.Pipeline } + +func (p Type_Promise) Struct() (Type, error) { + s, err := p.Pipeline.Struct() + return Type{s}, err +} + +func (p Type_Promise) List() Type_list_Promise { return Type_list_Promise{p.Pipeline} } + +// Type_list_Promise is a wrapper for a Type_list promised by a client call. +type Type_list_Promise struct{ *capnp.Pipeline } + +func (p Type_list_Promise) Struct() (Type_list, error) { + s, err := p.Pipeline.Struct() + return Type_list{s}, err +} + +func (p Type_list_Promise) ElementType() Type_Promise { + return Type_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Type_Promise) Enum() Type_enum_Promise { return Type_enum_Promise{p.Pipeline} } + +// Type_enum_Promise is a wrapper for a Type_enum promised by a client call. +type Type_enum_Promise struct{ *capnp.Pipeline } + +func (p Type_enum_Promise) Struct() (Type_enum, error) { + s, err := p.Pipeline.Struct() + return Type_enum{s}, err +} + +func (p Type_enum_Promise) Brand() Brand_Promise { + return Brand_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Type_Promise) StructType() Type_structType_Promise { return Type_structType_Promise{p.Pipeline} } + +// Type_structType_Promise is a wrapper for a Type_structType promised by a client call. +type Type_structType_Promise struct{ *capnp.Pipeline } + +func (p Type_structType_Promise) Struct() (Type_structType, error) { + s, err := p.Pipeline.Struct() + return Type_structType{s}, err +} + +func (p Type_structType_Promise) Brand() Brand_Promise { + return Brand_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Type_Promise) Interface() Type_interface_Promise { return Type_interface_Promise{p.Pipeline} } + +// Type_interface_Promise is a wrapper for a Type_interface promised by a client call. +type Type_interface_Promise struct{ *capnp.Pipeline } + +func (p Type_interface_Promise) Struct() (Type_interface, error) { + s, err := p.Pipeline.Struct() + return Type_interface{s}, err +} + +func (p Type_interface_Promise) Brand() Brand_Promise { + return Brand_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Type_Promise) AnyPointer() Type_anyPointer_Promise { return Type_anyPointer_Promise{p.Pipeline} } + +// Type_anyPointer_Promise is a wrapper for a Type_anyPointer promised by a client call. +type Type_anyPointer_Promise struct{ *capnp.Pipeline } + +func (p Type_anyPointer_Promise) Struct() (Type_anyPointer, error) { + s, err := p.Pipeline.Struct() + return Type_anyPointer{s}, err +} + +func (p Type_anyPointer_Promise) Unconstrained() Type_anyPointer_unconstrained_Promise { + return Type_anyPointer_unconstrained_Promise{p.Pipeline} +} + +// Type_anyPointer_unconstrained_Promise is a wrapper for a Type_anyPointer_unconstrained promised by a client call. +type Type_anyPointer_unconstrained_Promise struct{ *capnp.Pipeline } + +func (p Type_anyPointer_unconstrained_Promise) Struct() (Type_anyPointer_unconstrained, error) { + s, err := p.Pipeline.Struct() + return Type_anyPointer_unconstrained{s}, err +} + +func (p Type_anyPointer_Promise) Parameter() Type_anyPointer_parameter_Promise { + return Type_anyPointer_parameter_Promise{p.Pipeline} +} + +// Type_anyPointer_parameter_Promise is a wrapper for a Type_anyPointer_parameter promised by a client call. +type Type_anyPointer_parameter_Promise struct{ *capnp.Pipeline } + +func (p Type_anyPointer_parameter_Promise) Struct() (Type_anyPointer_parameter, error) { + s, err := p.Pipeline.Struct() + return Type_anyPointer_parameter{s}, err +} + +func (p Type_anyPointer_Promise) ImplicitMethodParameter() Type_anyPointer_implicitMethodParameter_Promise { + return Type_anyPointer_implicitMethodParameter_Promise{p.Pipeline} +} + +// Type_anyPointer_implicitMethodParameter_Promise is a wrapper for a Type_anyPointer_implicitMethodParameter promised by a client call. +type Type_anyPointer_implicitMethodParameter_Promise struct{ *capnp.Pipeline } + +func (p Type_anyPointer_implicitMethodParameter_Promise) Struct() (Type_anyPointer_implicitMethodParameter, error) { + s, err := p.Pipeline.Struct() + return Type_anyPointer_implicitMethodParameter{s}, err +} + +type Brand struct{ capnp.Struct } + +// Brand_TypeID is the unique identifier for the type Brand. +const Brand_TypeID = 0x903455f06065422b + +func NewBrand(s *capnp.Segment) (Brand, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) + return Brand{st}, err +} + +func NewRootBrand(s *capnp.Segment) (Brand, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}) + return Brand{st}, err +} + +func ReadRootBrand(msg *capnp.Message) (Brand, error) { + root, err := msg.RootPtr() + return Brand{root.Struct()}, err +} + +func (s Brand) Scopes() (Brand_Scope_List, error) { + p, err := s.Struct.Ptr(0) + return Brand_Scope_List{List: p.List()}, err +} + +func (s Brand) HasScopes() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Brand) SetScopes(v Brand_Scope_List) error { + return s.Struct.SetPtr(0, v.List.ToPtr()) +} + +// NewScopes sets the scopes field to a newly +// allocated Brand_Scope_List, preferring placement in s's segment. +func (s Brand) NewScopes(n int32) (Brand_Scope_List, error) { + l, err := NewBrand_Scope_List(s.Struct.Segment(), n) + if err != nil { + return Brand_Scope_List{}, err + } + err = s.Struct.SetPtr(0, l.List.ToPtr()) + return l, err +} + +// Brand_List is a list of Brand. +type Brand_List struct{ capnp.List } + +// NewBrand creates a new list of Brand. +func NewBrand_List(s *capnp.Segment, sz int32) (Brand_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz) + return Brand_List{l}, err +} + +func (s Brand_List) At(i int) Brand { return Brand{s.List.Struct(i)} } + +func (s Brand_List) Set(i int, v Brand) error { return s.List.SetStruct(i, v.Struct) } + +// Brand_Promise is a wrapper for a Brand promised by a client call. +type Brand_Promise struct{ *capnp.Pipeline } + +func (p Brand_Promise) Struct() (Brand, error) { + s, err := p.Pipeline.Struct() + return Brand{s}, err +} + +type Brand_Scope struct{ capnp.Struct } +type Brand_Scope_Which uint16 + +const ( + Brand_Scope_Which_bind Brand_Scope_Which = 0 + Brand_Scope_Which_inherit Brand_Scope_Which = 1 +) + +func (w Brand_Scope_Which) String() string { + const s = "bindinherit" + switch w { + case Brand_Scope_Which_bind: + return s[0:4] + case Brand_Scope_Which_inherit: + return s[4:11] + + } + return "Brand_Scope_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Brand_Scope_TypeID is the unique identifier for the type Brand_Scope. +const Brand_Scope_TypeID = 0xabd73485a9636bc9 + +func NewBrand_Scope(s *capnp.Segment) (Brand_Scope, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}) + return Brand_Scope{st}, err +} + +func NewRootBrand_Scope(s *capnp.Segment) (Brand_Scope, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}) + return Brand_Scope{st}, err +} + +func ReadRootBrand_Scope(msg *capnp.Message) (Brand_Scope, error) { + root, err := msg.RootPtr() + return Brand_Scope{root.Struct()}, err +} + +func (s Brand_Scope) Which() Brand_Scope_Which { + return Brand_Scope_Which(s.Struct.Uint16(8)) +} +func (s Brand_Scope) ScopeId() uint64 { + return s.Struct.Uint64(0) +} + +func (s Brand_Scope) SetScopeId(v uint64) { + s.Struct.SetUint64(0, v) +} + +func (s Brand_Scope) Bind() (Brand_Binding_List, error) { + p, err := s.Struct.Ptr(0) + return Brand_Binding_List{List: p.List()}, err +} + +func (s Brand_Scope) HasBind() bool { + if s.Struct.Uint16(8) != 0 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Brand_Scope) SetBind(v Brand_Binding_List) error { + s.Struct.SetUint16(8, 0) + return s.Struct.SetPtr(0, v.List.ToPtr()) +} + +// NewBind sets the bind field to a newly +// allocated Brand_Binding_List, preferring placement in s's segment. +func (s Brand_Scope) NewBind(n int32) (Brand_Binding_List, error) { + s.Struct.SetUint16(8, 0) + l, err := NewBrand_Binding_List(s.Struct.Segment(), n) + if err != nil { + return Brand_Binding_List{}, err + } + err = s.Struct.SetPtr(0, l.List.ToPtr()) + return l, err +} + +func (s Brand_Scope) SetInherit() { + s.Struct.SetUint16(8, 1) + +} + +// Brand_Scope_List is a list of Brand_Scope. +type Brand_Scope_List struct{ capnp.List } + +// NewBrand_Scope creates a new list of Brand_Scope. +func NewBrand_Scope_List(s *capnp.Segment, sz int32) (Brand_Scope_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}, sz) + return Brand_Scope_List{l}, err +} + +func (s Brand_Scope_List) At(i int) Brand_Scope { return Brand_Scope{s.List.Struct(i)} } + +func (s Brand_Scope_List) Set(i int, v Brand_Scope) error { return s.List.SetStruct(i, v.Struct) } + +// Brand_Scope_Promise is a wrapper for a Brand_Scope promised by a client call. +type Brand_Scope_Promise struct{ *capnp.Pipeline } + +func (p Brand_Scope_Promise) Struct() (Brand_Scope, error) { + s, err := p.Pipeline.Struct() + return Brand_Scope{s}, err +} + +type Brand_Binding struct{ capnp.Struct } +type Brand_Binding_Which uint16 + +const ( + Brand_Binding_Which_unbound Brand_Binding_Which = 0 + Brand_Binding_Which_type Brand_Binding_Which = 1 +) + +func (w Brand_Binding_Which) String() string { + const s = "unboundtype" + switch w { + case Brand_Binding_Which_unbound: + return s[0:7] + case Brand_Binding_Which_type: + return s[7:11] + + } + return "Brand_Binding_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Brand_Binding_TypeID is the unique identifier for the type Brand_Binding. +const Brand_Binding_TypeID = 0xc863cd16969ee7fc + +func NewBrand_Binding(s *capnp.Segment) (Brand_Binding, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Brand_Binding{st}, err +} + +func NewRootBrand_Binding(s *capnp.Segment) (Brand_Binding, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Brand_Binding{st}, err +} + +func ReadRootBrand_Binding(msg *capnp.Message) (Brand_Binding, error) { + root, err := msg.RootPtr() + return Brand_Binding{root.Struct()}, err +} + +func (s Brand_Binding) Which() Brand_Binding_Which { + return Brand_Binding_Which(s.Struct.Uint16(0)) +} +func (s Brand_Binding) SetUnbound() { + s.Struct.SetUint16(0, 0) + +} + +func (s Brand_Binding) Type() (Type, error) { + p, err := s.Struct.Ptr(0) + return Type{Struct: p.Struct()}, err +} + +func (s Brand_Binding) HasType() bool { + if s.Struct.Uint16(0) != 1 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Brand_Binding) SetType(v Type) error { + s.Struct.SetUint16(0, 1) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewType sets the type field to a newly +// allocated Type struct, preferring placement in s's segment. +func (s Brand_Binding) NewType() (Type, error) { + s.Struct.SetUint16(0, 1) + ss, err := NewType(s.Struct.Segment()) + if err != nil { + return Type{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +// Brand_Binding_List is a list of Brand_Binding. +type Brand_Binding_List struct{ capnp.List } + +// NewBrand_Binding creates a new list of Brand_Binding. +func NewBrand_Binding_List(s *capnp.Segment, sz int32) (Brand_Binding_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Brand_Binding_List{l}, err +} + +func (s Brand_Binding_List) At(i int) Brand_Binding { return Brand_Binding{s.List.Struct(i)} } + +func (s Brand_Binding_List) Set(i int, v Brand_Binding) error { return s.List.SetStruct(i, v.Struct) } + +// Brand_Binding_Promise is a wrapper for a Brand_Binding promised by a client call. +type Brand_Binding_Promise struct{ *capnp.Pipeline } + +func (p Brand_Binding_Promise) Struct() (Brand_Binding, error) { + s, err := p.Pipeline.Struct() + return Brand_Binding{s}, err +} + +func (p Brand_Binding_Promise) Type() Type_Promise { + return Type_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +type Value struct{ capnp.Struct } +type Value_Which uint16 + +const ( + Value_Which_void Value_Which = 0 + Value_Which_bool Value_Which = 1 + Value_Which_int8 Value_Which = 2 + Value_Which_int16 Value_Which = 3 + Value_Which_int32 Value_Which = 4 + Value_Which_int64 Value_Which = 5 + Value_Which_uint8 Value_Which = 6 + Value_Which_uint16 Value_Which = 7 + Value_Which_uint32 Value_Which = 8 + Value_Which_uint64 Value_Which = 9 + Value_Which_float32 Value_Which = 10 + Value_Which_float64 Value_Which = 11 + Value_Which_text Value_Which = 12 + Value_Which_data Value_Which = 13 + Value_Which_list Value_Which = 14 + Value_Which_enum Value_Which = 15 + Value_Which_structValue Value_Which = 16 + Value_Which_interface Value_Which = 17 + Value_Which_anyPointer Value_Which = 18 +) + +func (w Value_Which) String() string { + const s = "voidboolint8int16int32int64uint8uint16uint32uint64float32float64textdatalistenumstructValueinterfaceanyPointer" + switch w { + case Value_Which_void: + return s[0:4] + case Value_Which_bool: + return s[4:8] + case Value_Which_int8: + return s[8:12] + case Value_Which_int16: + return s[12:17] + case Value_Which_int32: + return s[17:22] + case Value_Which_int64: + return s[22:27] + case Value_Which_uint8: + return s[27:32] + case Value_Which_uint16: + return s[32:38] + case Value_Which_uint32: + return s[38:44] + case Value_Which_uint64: + return s[44:50] + case Value_Which_float32: + return s[50:57] + case Value_Which_float64: + return s[57:64] + case Value_Which_text: + return s[64:68] + case Value_Which_data: + return s[68:72] + case Value_Which_list: + return s[72:76] + case Value_Which_enum: + return s[76:80] + case Value_Which_structValue: + return s[80:91] + case Value_Which_interface: + return s[91:100] + case Value_Which_anyPointer: + return s[100:110] + + } + return "Value_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Value_TypeID is the unique identifier for the type Value. +const Value_TypeID = 0xce23dcd2d7b00c9b + +func NewValue(s *capnp.Segment) (Value, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}) + return Value{st}, err +} + +func NewRootValue(s *capnp.Segment) (Value, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}) + return Value{st}, err +} + +func ReadRootValue(msg *capnp.Message) (Value, error) { + root, err := msg.RootPtr() + return Value{root.Struct()}, err +} + +func (s Value) Which() Value_Which { + return Value_Which(s.Struct.Uint16(0)) +} +func (s Value) SetVoid() { + s.Struct.SetUint16(0, 0) + +} + +func (s Value) Bool() bool { + return s.Struct.Bit(16) +} + +func (s Value) SetBool(v bool) { + s.Struct.SetUint16(0, 1) + s.Struct.SetBit(16, v) +} + +func (s Value) Int8() int8 { + return int8(s.Struct.Uint8(2)) +} + +func (s Value) SetInt8(v int8) { + s.Struct.SetUint16(0, 2) + s.Struct.SetUint8(2, uint8(v)) +} + +func (s Value) Int16() int16 { + return int16(s.Struct.Uint16(2)) +} + +func (s Value) SetInt16(v int16) { + s.Struct.SetUint16(0, 3) + s.Struct.SetUint16(2, uint16(v)) +} + +func (s Value) Int32() int32 { + return int32(s.Struct.Uint32(4)) +} + +func (s Value) SetInt32(v int32) { + s.Struct.SetUint16(0, 4) + s.Struct.SetUint32(4, uint32(v)) +} + +func (s Value) Int64() int64 { + return int64(s.Struct.Uint64(8)) +} + +func (s Value) SetInt64(v int64) { + s.Struct.SetUint16(0, 5) + s.Struct.SetUint64(8, uint64(v)) +} + +func (s Value) Uint8() uint8 { + return s.Struct.Uint8(2) +} + +func (s Value) SetUint8(v uint8) { + s.Struct.SetUint16(0, 6) + s.Struct.SetUint8(2, v) +} + +func (s Value) Uint16() uint16 { + return s.Struct.Uint16(2) +} + +func (s Value) SetUint16(v uint16) { + s.Struct.SetUint16(0, 7) + s.Struct.SetUint16(2, v) +} + +func (s Value) Uint32() uint32 { + return s.Struct.Uint32(4) +} + +func (s Value) SetUint32(v uint32) { + s.Struct.SetUint16(0, 8) + s.Struct.SetUint32(4, v) +} + +func (s Value) Uint64() uint64 { + return s.Struct.Uint64(8) +} + +func (s Value) SetUint64(v uint64) { + s.Struct.SetUint16(0, 9) + s.Struct.SetUint64(8, v) +} + +func (s Value) Float32() float32 { + return math.Float32frombits(s.Struct.Uint32(4)) +} + +func (s Value) SetFloat32(v float32) { + s.Struct.SetUint16(0, 10) + s.Struct.SetUint32(4, math.Float32bits(v)) +} + +func (s Value) Float64() float64 { + return math.Float64frombits(s.Struct.Uint64(8)) +} + +func (s Value) SetFloat64(v float64) { + s.Struct.SetUint16(0, 11) + s.Struct.SetUint64(8, math.Float64bits(v)) +} + +func (s Value) Text() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s Value) HasText() bool { + if s.Struct.Uint16(0) != 12 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Value) TextBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s Value) SetText(v string) error { + s.Struct.SetUint16(0, 12) + return s.Struct.SetText(0, v) +} + +func (s Value) Data() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return []byte(p.Data()), err +} + +func (s Value) HasData() bool { + if s.Struct.Uint16(0) != 13 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Value) SetData(v []byte) error { + s.Struct.SetUint16(0, 13) + return s.Struct.SetData(0, v) +} + +func (s Value) List() (capnp.Pointer, error) { + return s.Struct.Pointer(0) +} + +func (s Value) HasList() bool { + if s.Struct.Uint16(0) != 14 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Value) ListPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Value) SetList(v capnp.Pointer) error { + s.Struct.SetUint16(0, 14) + return s.Struct.SetPointer(0, v) +} + +func (s Value) SetListPtr(v capnp.Ptr) error { + s.Struct.SetUint16(0, 14) + return s.Struct.SetPtr(0, v) +} + +func (s Value) Enum() uint16 { + return s.Struct.Uint16(2) +} + +func (s Value) SetEnum(v uint16) { + s.Struct.SetUint16(0, 15) + s.Struct.SetUint16(2, v) +} + +func (s Value) StructValue() (capnp.Pointer, error) { + return s.Struct.Pointer(0) +} + +func (s Value) HasStructValue() bool { + if s.Struct.Uint16(0) != 16 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Value) StructValuePtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Value) SetStructValue(v capnp.Pointer) error { + s.Struct.SetUint16(0, 16) + return s.Struct.SetPointer(0, v) +} + +func (s Value) SetStructValuePtr(v capnp.Ptr) error { + s.Struct.SetUint16(0, 16) + return s.Struct.SetPtr(0, v) +} + +func (s Value) SetInterface() { + s.Struct.SetUint16(0, 17) + +} + +func (s Value) AnyPointer() (capnp.Pointer, error) { + return s.Struct.Pointer(0) +} + +func (s Value) HasAnyPointer() bool { + if s.Struct.Uint16(0) != 18 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Value) AnyPointerPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Value) SetAnyPointer(v capnp.Pointer) error { + s.Struct.SetUint16(0, 18) + return s.Struct.SetPointer(0, v) +} + +func (s Value) SetAnyPointerPtr(v capnp.Ptr) error { + s.Struct.SetUint16(0, 18) + return s.Struct.SetPtr(0, v) +} + +// Value_List is a list of Value. +type Value_List struct{ capnp.List } + +// NewValue creates a new list of Value. +func NewValue_List(s *capnp.Segment, sz int32) (Value_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}, sz) + return Value_List{l}, err +} + +func (s Value_List) At(i int) Value { return Value{s.List.Struct(i)} } + +func (s Value_List) Set(i int, v Value) error { return s.List.SetStruct(i, v.Struct) } + +// Value_Promise is a wrapper for a Value promised by a client call. +type Value_Promise struct{ *capnp.Pipeline } + +func (p Value_Promise) Struct() (Value, error) { + s, err := p.Pipeline.Struct() + return Value{s}, err +} + +func (p Value_Promise) List() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +func (p Value_Promise) StructValue() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +func (p Value_Promise) AnyPointer() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +type Annotation struct{ capnp.Struct } + +// Annotation_TypeID is the unique identifier for the type Annotation. +const Annotation_TypeID = 0xf1c8950dab257542 + +func NewAnnotation(s *capnp.Segment) (Annotation, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return Annotation{st}, err +} + +func NewRootAnnotation(s *capnp.Segment) (Annotation, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return Annotation{st}, err +} + +func ReadRootAnnotation(msg *capnp.Message) (Annotation, error) { + root, err := msg.RootPtr() + return Annotation{root.Struct()}, err +} + +func (s Annotation) Id() uint64 { + return s.Struct.Uint64(0) +} + +func (s Annotation) SetId(v uint64) { + s.Struct.SetUint64(0, v) +} + +func (s Annotation) Brand() (Brand, error) { + p, err := s.Struct.Ptr(1) + return Brand{Struct: p.Struct()}, err +} + +func (s Annotation) HasBrand() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Annotation) SetBrand(v Brand) error { + return s.Struct.SetPtr(1, v.Struct.ToPtr()) +} + +// NewBrand sets the brand field to a newly +// allocated Brand struct, preferring placement in s's segment. +func (s Annotation) NewBrand() (Brand, error) { + ss, err := NewBrand(s.Struct.Segment()) + if err != nil { + return Brand{}, err + } + err = s.Struct.SetPtr(1, ss.Struct.ToPtr()) + return ss, err +} + +func (s Annotation) Value() (Value, error) { + p, err := s.Struct.Ptr(0) + return Value{Struct: p.Struct()}, err +} + +func (s Annotation) HasValue() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Annotation) SetValue(v Value) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewValue sets the value field to a newly +// allocated Value struct, preferring placement in s's segment. +func (s Annotation) NewValue() (Value, error) { + ss, err := NewValue(s.Struct.Segment()) + if err != nil { + return Value{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +// Annotation_List is a list of Annotation. +type Annotation_List struct{ capnp.List } + +// NewAnnotation creates a new list of Annotation. +func NewAnnotation_List(s *capnp.Segment, sz int32) (Annotation_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz) + return Annotation_List{l}, err +} + +func (s Annotation_List) At(i int) Annotation { return Annotation{s.List.Struct(i)} } + +func (s Annotation_List) Set(i int, v Annotation) error { return s.List.SetStruct(i, v.Struct) } + +// Annotation_Promise is a wrapper for a Annotation promised by a client call. +type Annotation_Promise struct{ *capnp.Pipeline } + +func (p Annotation_Promise) Struct() (Annotation, error) { + s, err := p.Pipeline.Struct() + return Annotation{s}, err +} + +func (p Annotation_Promise) Brand() Brand_Promise { + return Brand_Promise{Pipeline: p.Pipeline.GetPipeline(1)} +} + +func (p Annotation_Promise) Value() Value_Promise { + return Value_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +type ElementSize uint16 + +// ElementSize_TypeID is the unique identifier for the type ElementSize. +const ElementSize_TypeID = 0xd1958f7dba521926 + +// Values of ElementSize. +const ( + ElementSize_empty ElementSize = 0 + ElementSize_bit ElementSize = 1 + ElementSize_byte ElementSize = 2 + ElementSize_twoBytes ElementSize = 3 + ElementSize_fourBytes ElementSize = 4 + ElementSize_eightBytes ElementSize = 5 + ElementSize_pointer ElementSize = 6 + ElementSize_inlineComposite ElementSize = 7 +) + +// String returns the enum's constant name. +func (c ElementSize) String() string { + switch c { + case ElementSize_empty: + return "empty" + case ElementSize_bit: + return "bit" + case ElementSize_byte: + return "byte" + case ElementSize_twoBytes: + return "twoBytes" + case ElementSize_fourBytes: + return "fourBytes" + case ElementSize_eightBytes: + return "eightBytes" + case ElementSize_pointer: + return "pointer" + case ElementSize_inlineComposite: + return "inlineComposite" + + default: + return "" + } +} + +// ElementSizeFromString returns the enum value with a name, +// or the zero value if there's no such value. +func ElementSizeFromString(c string) ElementSize { + switch c { + case "empty": + return ElementSize_empty + case "bit": + return ElementSize_bit + case "byte": + return ElementSize_byte + case "twoBytes": + return ElementSize_twoBytes + case "fourBytes": + return ElementSize_fourBytes + case "eightBytes": + return ElementSize_eightBytes + case "pointer": + return ElementSize_pointer + case "inlineComposite": + return ElementSize_inlineComposite + + default: + return 0 + } +} + +type ElementSize_List struct{ capnp.List } + +func NewElementSize_List(s *capnp.Segment, sz int32) (ElementSize_List, error) { + l, err := capnp.NewUInt16List(s, sz) + return ElementSize_List{l.List}, err +} + +func (l ElementSize_List) At(i int) ElementSize { + ul := capnp.UInt16List{List: l.List} + return ElementSize(ul.At(i)) +} + +func (l ElementSize_List) Set(i int, v ElementSize) { + ul := capnp.UInt16List{List: l.List} + ul.Set(i, uint16(v)) +} + +type CodeGeneratorRequest struct{ capnp.Struct } + +// CodeGeneratorRequest_TypeID is the unique identifier for the type CodeGeneratorRequest. +const CodeGeneratorRequest_TypeID = 0xbfc546f6210ad7ce + +func NewCodeGeneratorRequest(s *capnp.Segment) (CodeGeneratorRequest, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) + return CodeGeneratorRequest{st}, err +} + +func NewRootCodeGeneratorRequest(s *capnp.Segment) (CodeGeneratorRequest, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) + return CodeGeneratorRequest{st}, err +} + +func ReadRootCodeGeneratorRequest(msg *capnp.Message) (CodeGeneratorRequest, error) { + root, err := msg.RootPtr() + return CodeGeneratorRequest{root.Struct()}, err +} + +func (s CodeGeneratorRequest) Nodes() (Node_List, error) { + p, err := s.Struct.Ptr(0) + return Node_List{List: p.List()}, err +} + +func (s CodeGeneratorRequest) HasNodes() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s CodeGeneratorRequest) SetNodes(v Node_List) error { + return s.Struct.SetPtr(0, v.List.ToPtr()) +} + +// NewNodes sets the nodes field to a newly +// allocated Node_List, preferring placement in s's segment. +func (s CodeGeneratorRequest) NewNodes(n int32) (Node_List, error) { + l, err := NewNode_List(s.Struct.Segment(), n) + if err != nil { + return Node_List{}, err + } + err = s.Struct.SetPtr(0, l.List.ToPtr()) + return l, err +} + +func (s CodeGeneratorRequest) RequestedFiles() (CodeGeneratorRequest_RequestedFile_List, error) { + p, err := s.Struct.Ptr(1) + return CodeGeneratorRequest_RequestedFile_List{List: p.List()}, err +} + +func (s CodeGeneratorRequest) HasRequestedFiles() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s CodeGeneratorRequest) SetRequestedFiles(v CodeGeneratorRequest_RequestedFile_List) error { + return s.Struct.SetPtr(1, v.List.ToPtr()) +} + +// NewRequestedFiles sets the requestedFiles field to a newly +// allocated CodeGeneratorRequest_RequestedFile_List, preferring placement in s's segment. +func (s CodeGeneratorRequest) NewRequestedFiles(n int32) (CodeGeneratorRequest_RequestedFile_List, error) { + l, err := NewCodeGeneratorRequest_RequestedFile_List(s.Struct.Segment(), n) + if err != nil { + return CodeGeneratorRequest_RequestedFile_List{}, err + } + err = s.Struct.SetPtr(1, l.List.ToPtr()) + return l, err +} + +// CodeGeneratorRequest_List is a list of CodeGeneratorRequest. +type CodeGeneratorRequest_List struct{ capnp.List } + +// NewCodeGeneratorRequest creates a new list of CodeGeneratorRequest. +func NewCodeGeneratorRequest_List(s *capnp.Segment, sz int32) (CodeGeneratorRequest_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz) + return CodeGeneratorRequest_List{l}, err +} + +func (s CodeGeneratorRequest_List) At(i int) CodeGeneratorRequest { + return CodeGeneratorRequest{s.List.Struct(i)} +} + +func (s CodeGeneratorRequest_List) Set(i int, v CodeGeneratorRequest) error { + return s.List.SetStruct(i, v.Struct) +} + +// CodeGeneratorRequest_Promise is a wrapper for a CodeGeneratorRequest promised by a client call. +type CodeGeneratorRequest_Promise struct{ *capnp.Pipeline } + +func (p CodeGeneratorRequest_Promise) Struct() (CodeGeneratorRequest, error) { + s, err := p.Pipeline.Struct() + return CodeGeneratorRequest{s}, err +} + +type CodeGeneratorRequest_RequestedFile struct{ capnp.Struct } + +// CodeGeneratorRequest_RequestedFile_TypeID is the unique identifier for the type CodeGeneratorRequest_RequestedFile. +const CodeGeneratorRequest_RequestedFile_TypeID = 0xcfea0eb02e810062 + +func NewCodeGeneratorRequest_RequestedFile(s *capnp.Segment) (CodeGeneratorRequest_RequestedFile, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return CodeGeneratorRequest_RequestedFile{st}, err +} + +func NewRootCodeGeneratorRequest_RequestedFile(s *capnp.Segment) (CodeGeneratorRequest_RequestedFile, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return CodeGeneratorRequest_RequestedFile{st}, err +} + +func ReadRootCodeGeneratorRequest_RequestedFile(msg *capnp.Message) (CodeGeneratorRequest_RequestedFile, error) { + root, err := msg.RootPtr() + return CodeGeneratorRequest_RequestedFile{root.Struct()}, err +} + +func (s CodeGeneratorRequest_RequestedFile) Id() uint64 { + return s.Struct.Uint64(0) +} + +func (s CodeGeneratorRequest_RequestedFile) SetId(v uint64) { + s.Struct.SetUint64(0, v) +} + +func (s CodeGeneratorRequest_RequestedFile) Filename() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s CodeGeneratorRequest_RequestedFile) HasFilename() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s CodeGeneratorRequest_RequestedFile) FilenameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s CodeGeneratorRequest_RequestedFile) SetFilename(v string) error { + return s.Struct.SetText(0, v) +} + +func (s CodeGeneratorRequest_RequestedFile) Imports() (CodeGeneratorRequest_RequestedFile_Import_List, error) { + p, err := s.Struct.Ptr(1) + return CodeGeneratorRequest_RequestedFile_Import_List{List: p.List()}, err +} + +func (s CodeGeneratorRequest_RequestedFile) HasImports() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s CodeGeneratorRequest_RequestedFile) SetImports(v CodeGeneratorRequest_RequestedFile_Import_List) error { + return s.Struct.SetPtr(1, v.List.ToPtr()) +} + +// NewImports sets the imports field to a newly +// allocated CodeGeneratorRequest_RequestedFile_Import_List, preferring placement in s's segment. +func (s CodeGeneratorRequest_RequestedFile) NewImports(n int32) (CodeGeneratorRequest_RequestedFile_Import_List, error) { + l, err := NewCodeGeneratorRequest_RequestedFile_Import_List(s.Struct.Segment(), n) + if err != nil { + return CodeGeneratorRequest_RequestedFile_Import_List{}, err + } + err = s.Struct.SetPtr(1, l.List.ToPtr()) + return l, err +} + +// CodeGeneratorRequest_RequestedFile_List is a list of CodeGeneratorRequest_RequestedFile. +type CodeGeneratorRequest_RequestedFile_List struct{ capnp.List } + +// NewCodeGeneratorRequest_RequestedFile creates a new list of CodeGeneratorRequest_RequestedFile. +func NewCodeGeneratorRequest_RequestedFile_List(s *capnp.Segment, sz int32) (CodeGeneratorRequest_RequestedFile_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz) + return CodeGeneratorRequest_RequestedFile_List{l}, err +} + +func (s CodeGeneratorRequest_RequestedFile_List) At(i int) CodeGeneratorRequest_RequestedFile { + return CodeGeneratorRequest_RequestedFile{s.List.Struct(i)} +} + +func (s CodeGeneratorRequest_RequestedFile_List) Set(i int, v CodeGeneratorRequest_RequestedFile) error { + return s.List.SetStruct(i, v.Struct) +} + +// CodeGeneratorRequest_RequestedFile_Promise is a wrapper for a CodeGeneratorRequest_RequestedFile promised by a client call. +type CodeGeneratorRequest_RequestedFile_Promise struct{ *capnp.Pipeline } + +func (p CodeGeneratorRequest_RequestedFile_Promise) Struct() (CodeGeneratorRequest_RequestedFile, error) { + s, err := p.Pipeline.Struct() + return CodeGeneratorRequest_RequestedFile{s}, err +} + +type CodeGeneratorRequest_RequestedFile_Import struct{ capnp.Struct } + +// CodeGeneratorRequest_RequestedFile_Import_TypeID is the unique identifier for the type CodeGeneratorRequest_RequestedFile_Import. +const CodeGeneratorRequest_RequestedFile_Import_TypeID = 0xae504193122357e5 + +func NewCodeGeneratorRequest_RequestedFile_Import(s *capnp.Segment) (CodeGeneratorRequest_RequestedFile_Import, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return CodeGeneratorRequest_RequestedFile_Import{st}, err +} + +func NewRootCodeGeneratorRequest_RequestedFile_Import(s *capnp.Segment) (CodeGeneratorRequest_RequestedFile_Import, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return CodeGeneratorRequest_RequestedFile_Import{st}, err +} + +func ReadRootCodeGeneratorRequest_RequestedFile_Import(msg *capnp.Message) (CodeGeneratorRequest_RequestedFile_Import, error) { + root, err := msg.RootPtr() + return CodeGeneratorRequest_RequestedFile_Import{root.Struct()}, err +} + +func (s CodeGeneratorRequest_RequestedFile_Import) Id() uint64 { + return s.Struct.Uint64(0) +} + +func (s CodeGeneratorRequest_RequestedFile_Import) SetId(v uint64) { + s.Struct.SetUint64(0, v) +} + +func (s CodeGeneratorRequest_RequestedFile_Import) Name() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s CodeGeneratorRequest_RequestedFile_Import) HasName() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s CodeGeneratorRequest_RequestedFile_Import) NameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s CodeGeneratorRequest_RequestedFile_Import) SetName(v string) error { + return s.Struct.SetText(0, v) +} + +// CodeGeneratorRequest_RequestedFile_Import_List is a list of CodeGeneratorRequest_RequestedFile_Import. +type CodeGeneratorRequest_RequestedFile_Import_List struct{ capnp.List } + +// NewCodeGeneratorRequest_RequestedFile_Import creates a new list of CodeGeneratorRequest_RequestedFile_Import. +func NewCodeGeneratorRequest_RequestedFile_Import_List(s *capnp.Segment, sz int32) (CodeGeneratorRequest_RequestedFile_Import_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return CodeGeneratorRequest_RequestedFile_Import_List{l}, err +} + +func (s CodeGeneratorRequest_RequestedFile_Import_List) At(i int) CodeGeneratorRequest_RequestedFile_Import { + return CodeGeneratorRequest_RequestedFile_Import{s.List.Struct(i)} +} + +func (s CodeGeneratorRequest_RequestedFile_Import_List) Set(i int, v CodeGeneratorRequest_RequestedFile_Import) error { + return s.List.SetStruct(i, v.Struct) +} + +// CodeGeneratorRequest_RequestedFile_Import_Promise is a wrapper for a CodeGeneratorRequest_RequestedFile_Import promised by a client call. +type CodeGeneratorRequest_RequestedFile_Import_Promise struct{ *capnp.Pipeline } + +func (p CodeGeneratorRequest_RequestedFile_Import_Promise) Struct() (CodeGeneratorRequest_RequestedFile_Import, error) { + s, err := p.Pipeline.Struct() + return CodeGeneratorRequest_RequestedFile_Import{s}, err +} diff --git a/vendor/zombiezen.com/go/capnproto2/internal/strquote/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/internal/strquote/BUILD.bazel new file mode 100644 index 00000000..f6efa985 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/strquote/BUILD.bazel @@ -0,0 +1,8 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["strquote.go"], + importpath = "zombiezen.com/go/capnproto2/internal/strquote", + visibility = ["//:__subpackages__"], +) diff --git a/vendor/zombiezen.com/go/capnproto2/internal/strquote/strquote.go b/vendor/zombiezen.com/go/capnproto2/internal/strquote/strquote.go new file mode 100644 index 00000000..f6af09b9 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/internal/strquote/strquote.go @@ -0,0 +1,52 @@ +// Package strquote provides a function for formatting a string as a +// Cap'n Proto string literal. +package strquote + +// Append appends a Cap'n Proto string literal of s to buf. +func Append(buf []byte, s []byte) []byte { + buf = append(buf, '"') + last := 0 + for i, b := range s { + if !needsEscape(b) { + continue + } + buf = append(buf, s[last:i]...) + switch b { + case '\a': + buf = append(buf, '\\', 'a') + case '\b': + buf = append(buf, '\\', 'b') + case '\f': + buf = append(buf, '\\', 'f') + case '\n': + buf = append(buf, '\\', 'n') + case '\r': + buf = append(buf, '\\', 'r') + case '\t': + buf = append(buf, '\\', 't') + case '\v': + buf = append(buf, '\\', 'v') + case '\'': + buf = append(buf, '\\', '\'') + case '"': + buf = append(buf, '\\', '"') + case '\\': + buf = append(buf, '\\', '\\') + default: + buf = append(buf, '\\', 'x', hexDigit(b/16), hexDigit(b%16)) + } + last = i + 1 + } + buf = append(buf, s[last:]...) + buf = append(buf, '"') + return buf +} + +func needsEscape(b byte) bool { + return b < 0x20 || b >= 0x7f +} + +func hexDigit(b byte) byte { + const digits = "0123456789abcdef" + return digits[b] +} diff --git a/vendor/zombiezen.com/go/capnproto2/list.go b/vendor/zombiezen.com/go/capnproto2/list.go new file mode 100644 index 00000000..95a09492 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/list.go @@ -0,0 +1,1044 @@ +package capnp + +import ( + "errors" + "math" + "strconv" + + "zombiezen.com/go/capnproto2/internal/strquote" +) + +// A List is a reference to an array of values. +type List struct { + seg *Segment + off Address // at beginning of elements (past composite list tag word) + length int32 + size ObjectSize + depthLimit uint + flags listFlags +} + +// newPrimitiveList allocates a new list of primitive values, preferring placement in s. +func newPrimitiveList(s *Segment, sz Size, n int32) (List, error) { + total, ok := sz.times(n) + if !ok { + return List{}, errOverflow + } + s, addr, err := alloc(s, total) + if err != nil { + return List{}, err + } + return List{ + seg: s, + off: addr, + length: n, + size: ObjectSize{DataSize: sz}, + depthLimit: maxDepth, + }, nil +} + +// NewCompositeList creates a new composite list, preferring placement +// in s. +func NewCompositeList(s *Segment, sz ObjectSize, n int32) (List, error) { + if !sz.isValid() { + return List{}, errObjectSize + } + sz.DataSize = sz.DataSize.padToWord() + total, ok := sz.totalSize().times(n) + if !ok || total > maxSize-wordSize { + return List{}, errOverflow + } + s, addr, err := alloc(s, wordSize+total) + if err != nil { + return List{}, err + } + // Add tag word + s.writeRawPointer(addr, rawStructPointer(pointerOffset(n), sz)) + return List{ + seg: s, + off: addr + Address(wordSize), + length: n, + size: sz, + flags: isCompositeList, + depthLimit: maxDepth, + }, nil +} + +// ToList converts p to a List. +// +// Deprecated: Use Ptr.List. +func ToList(p Pointer) List { + return toPtr(p).List() +} + +// ToListDefault attempts to convert p into a list, reading the default +// value from def if p is not a list. +// +// Deprecated: Use Ptr.ListDefault. +func ToListDefault(p Pointer, def []byte) (List, error) { + return toPtr(p).ListDefault(def) +} + +// ToPtr converts the list to a generic pointer. +func (p List) ToPtr() Ptr { + return Ptr{ + seg: p.seg, + off: p.off, + lenOrCap: uint32(p.length), + size: p.size, + depthLimit: p.depthLimit, + flags: listPtrFlag(p.flags), + } +} + +// Segment returns the segment this pointer references. +func (p List) Segment() *Segment { + return p.seg +} + +// IsValid returns whether the list is valid. +func (p List) IsValid() bool { + return p.seg != nil +} + +// HasData reports whether the list's total size is non-zero. +func (p List) HasData() bool { + sz, ok := p.size.totalSize().times(p.length) + if !ok { + return false + } + return sz > 0 +} + +// readSize returns the list's size for the purposes of read limit +// accounting. +func (p List) readSize() Size { + if p.seg == nil { + return 0 + } + e := p.size.totalSize() + if e == 0 { + e = wordSize + } + sz, ok := e.times(p.length) + if !ok { + return maxSize + } + return sz +} + +// allocSize returns the list's size for the purpose of copying the list +// to a different message. +func (p List) allocSize() Size { + if p.seg == nil { + return 0 + } + if p.flags&isBitList != 0 { + return Size((p.length + 7) / 8) + } + sz, _ := p.size.totalSize().times(p.length) // size has already been validated + if p.flags&isCompositeList == 0 { + return sz + } + return sz + wordSize +} + +// raw returns the equivalent raw list pointer with a zero offset. +func (p List) raw() rawPointer { + if p.seg == nil { + return 0 + } + if p.flags&isCompositeList != 0 { + return rawListPointer(0, compositeList, p.length*p.size.totalWordCount()) + } + if p.flags&isBitList != 0 { + return rawListPointer(0, bit1List, p.length) + } + if p.size.PointerCount == 1 && p.size.DataSize == 0 { + return rawListPointer(0, pointerList, p.length) + } + if p.size.PointerCount != 0 { + panic(errListSize) + } + switch p.size.DataSize { + case 0: + return rawListPointer(0, voidList, p.length) + case 1: + return rawListPointer(0, byte1List, p.length) + case 2: + return rawListPointer(0, byte2List, p.length) + case 4: + return rawListPointer(0, byte4List, p.length) + case 8: + return rawListPointer(0, byte8List, p.length) + default: + panic(errListSize) + } +} + +func (p List) underlying() Pointer { + return p +} + +// Address returns the address the pointer references. +// +// Deprecated: The return value is not well-defined. Use SamePtr if you +// need to check whether two pointers refer to the same object. +func (p List) Address() Address { + return p.off +} + +// Len returns the length of the list. +func (p List) Len() int { + if p.seg == nil { + return 0 + } + return int(p.length) +} + +// primitiveElem returns the address of the segment data for a list element. +// Calling this on a bit list returns an error. +func (p List) primitiveElem(i int, expectedSize ObjectSize) (Address, error) { + if p.seg == nil || i < 0 || i >= int(p.length) { + // This is programmer error, not input error. + panic(errOutOfBounds) + } + if p.flags&isBitList != 0 || p.flags&isCompositeList == 0 && p.size != expectedSize || p.flags&isCompositeList != 0 && (p.size.DataSize < expectedSize.DataSize || p.size.PointerCount < expectedSize.PointerCount) { + return 0, errElementSize + } + addr, ok := p.off.element(int32(i), p.size.totalSize()) + if !ok { + return 0, errOverflow + } + return addr, nil +} + +// Struct returns the i'th element as a struct. +func (p List) Struct(i int) Struct { + if p.seg == nil || i < 0 || i >= int(p.length) { + // This is programmer error, not input error. + panic(errOutOfBounds) + } + if p.flags&isBitList != 0 { + return Struct{} + } + addr, ok := p.off.element(int32(i), p.size.totalSize()) + if !ok { + return Struct{} + } + return Struct{ + seg: p.seg, + off: addr, + size: p.size, + flags: isListMember, + depthLimit: p.depthLimit - 1, + } +} + +// SetStruct set the i'th element to the value in s. +func (p List) SetStruct(i int, s Struct) error { + if p.flags&isBitList != 0 { + return errBitListStruct + } + return copyStruct(p.Struct(i), s) +} + +// A BitList is a reference to a list of booleans. +type BitList struct{ List } + +// NewBitList creates a new bit list, preferring placement in s. +func NewBitList(s *Segment, n int32) (BitList, error) { + s, addr, err := alloc(s, Size(int64(n+7)/8)) + if err != nil { + return BitList{}, err + } + return BitList{List{ + seg: s, + off: addr, + length: n, + flags: isBitList, + depthLimit: maxDepth, + }}, nil +} + +// At returns the i'th bit. +func (p BitList) At(i int) bool { + if p.seg == nil || i < 0 || i >= int(p.length) { + // This is programmer error, not input error. + panic(errOutOfBounds) + } + if p.flags&isBitList == 0 { + return false + } + bit := BitOffset(i) + addr := p.off.addOffset(bit.offset()) + return p.seg.readUint8(addr)&bit.mask() != 0 +} + +// Set sets the i'th bit to v. +func (p BitList) Set(i int, v bool) { + if p.seg == nil || i < 0 || i >= int(p.length) { + // This is programmer error, not input error. + panic(errOutOfBounds) + } + if p.flags&isBitList == 0 { + // Again, programmer error. Should have used NewBitList. + panic(errElementSize) + } + bit := BitOffset(i) + addr := p.off.addOffset(bit.offset()) + b := p.seg.slice(addr, 1) + if v { + b[0] |= bit.mask() + } else { + b[0] &^= bit.mask() + } +} + +// String returns the list in Cap'n Proto schema format (e.g. "[true, false]"). +func (p BitList) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < p.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + if p.At(i) { + buf = append(buf, "true"...) + } else { + buf = append(buf, "false"...) + } + } + buf = append(buf, ']') + return string(buf) +} + +// A PointerList is a reference to an array of pointers. +type PointerList struct{ List } + +// NewPointerList allocates a new list of pointers, preferring placement in s. +func NewPointerList(s *Segment, n int32) (PointerList, error) { + total, ok := wordSize.times(n) + if !ok { + return PointerList{}, errOverflow + } + s, addr, err := alloc(s, total) + if err != nil { + return PointerList{}, err + } + return PointerList{List{ + seg: s, + off: addr, + length: n, + size: ObjectSize{PointerCount: 1}, + depthLimit: maxDepth, + }}, nil +} + +// At returns the i'th pointer in the list. +// +// Deprecated: Use PtrAt. +func (p PointerList) At(i int) (Pointer, error) { + pi, err := p.PtrAt(i) + return pi.toPointer(), err +} + +// PtrAt returns the i'th pointer in the list. +func (p PointerList) PtrAt(i int) (Ptr, error) { + addr, err := p.primitiveElem(i, ObjectSize{PointerCount: 1}) + if err != nil { + return Ptr{}, err + } + return p.seg.readPtr(addr, p.depthLimit) +} + +// Set sets the i'th pointer in the list to v. +// +// Deprecated: Use SetPtr. +func (p PointerList) Set(i int, v Pointer) error { + return p.SetPtr(i, toPtr(v)) +} + +// SetPtr sets the i'th pointer in the list to v. +func (p PointerList) SetPtr(i int, v Ptr) error { + addr, err := p.primitiveElem(i, ObjectSize{PointerCount: 1}) + if err != nil { + return err + } + return p.seg.writePtr(addr, v, false) +} + +// TextList is an array of pointers to strings. +type TextList struct{ List } + +// NewTextList allocates a new list of text pointers, preferring placement in s. +func NewTextList(s *Segment, n int32) (TextList, error) { + pl, err := NewPointerList(s, n) + if err != nil { + return TextList{}, err + } + return TextList{pl.List}, nil +} + +// At returns the i'th string in the list. +func (l TextList) At(i int) (string, error) { + addr, err := l.primitiveElem(i, ObjectSize{PointerCount: 1}) + if err != nil { + return "", err + } + p, err := l.seg.readPtr(addr, l.depthLimit) + if err != nil { + return "", err + } + return p.Text(), nil +} + +// BytesAt returns the i'th element in the list as a byte slice. +// The underlying array of the slice is the segment data. +func (l TextList) BytesAt(i int) ([]byte, error) { + addr, err := l.primitiveElem(i, ObjectSize{PointerCount: 1}) + if err != nil { + return nil, err + } + p, err := l.seg.readPtr(addr, l.depthLimit) + if err != nil { + return nil, err + } + return p.TextBytes(), nil +} + +// Set sets the i'th string in the list to v. +func (l TextList) Set(i int, v string) error { + addr, err := l.primitiveElem(i, ObjectSize{PointerCount: 1}) + if err != nil { + return err + } + if v == "" { + return l.seg.writePtr(addr, Ptr{}, false) + } + p, err := NewText(l.seg, v) + if err != nil { + return err + } + return l.seg.writePtr(addr, p.List.ToPtr(), false) +} + +// String returns the list in Cap'n Proto schema format (e.g. `["foo", "bar"]`). +func (l TextList) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + s, err := l.BytesAt(i) + if err != nil { + buf = append(buf, ""...) + continue + } + buf = strquote.Append(buf, s) + } + buf = append(buf, ']') + return string(buf) +} + +// DataList is an array of pointers to data. +type DataList struct{ List } + +// NewDataList allocates a new list of data pointers, preferring placement in s. +func NewDataList(s *Segment, n int32) (DataList, error) { + pl, err := NewPointerList(s, n) + if err != nil { + return DataList{}, err + } + return DataList{pl.List}, nil +} + +// At returns the i'th data in the list. +func (l DataList) At(i int) ([]byte, error) { + addr, err := l.primitiveElem(i, ObjectSize{PointerCount: 1}) + if err != nil { + return nil, err + } + p, err := l.seg.readPtr(addr, l.depthLimit) + if err != nil { + return nil, err + } + return p.Data(), nil +} + +// Set sets the i'th data in the list to v. +func (l DataList) Set(i int, v []byte) error { + addr, err := l.primitiveElem(i, ObjectSize{PointerCount: 1}) + if err != nil { + return err + } + if len(v) == 0 { + return l.seg.writePtr(addr, Ptr{}, false) + } + p, err := NewData(l.seg, v) + if err != nil { + return err + } + return l.seg.writePtr(addr, p.List.ToPtr(), false) +} + +// String returns the list in Cap'n Proto schema format (e.g. `["foo", "bar"]`). +func (l DataList) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + s, err := l.At(i) + if err != nil { + buf = append(buf, ""...) + continue + } + buf = strquote.Append(buf, s) + } + buf = append(buf, ']') + return string(buf) +} + +// A VoidList is a list of zero-sized elements. +type VoidList struct{ List } + +// NewVoidList creates a list of voids. No allocation is performed; +// s is only used for Segment()'s return value. +func NewVoidList(s *Segment, n int32) VoidList { + return VoidList{List{ + seg: s, + length: n, + depthLimit: maxDepth, + }} +} + +// String returns the list in Cap'n Proto schema format (e.g. "[void, void, void]"). +func (l VoidList) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = append(buf, "void"...) + } + buf = append(buf, ']') + return string(buf) +} + +// A UInt8List is an array of UInt8 values. +type UInt8List struct{ List } + +// NewUInt8List creates a new list of UInt8, preferring placement in s. +func NewUInt8List(s *Segment, n int32) (UInt8List, error) { + l, err := newPrimitiveList(s, 1, n) + if err != nil { + return UInt8List{}, err + } + return UInt8List{l}, nil +} + +// NewText creates a new list of UInt8 from a string. +func NewText(s *Segment, v string) (UInt8List, error) { + // TODO(light): error if v is too long + l, err := NewUInt8List(s, int32(len(v)+1)) + if err != nil { + return UInt8List{}, err + } + copy(l.seg.slice(l.off, Size(len(v))), v) + return l, nil +} + +// NewTextFromBytes creates a NUL-terminated list of UInt8 from a byte slice. +func NewTextFromBytes(s *Segment, v []byte) (UInt8List, error) { + // TODO(light): error if v is too long + l, err := NewUInt8List(s, int32(len(v)+1)) + if err != nil { + return UInt8List{}, err + } + copy(l.seg.slice(l.off, Size(len(v))), v) + return l, nil +} + +// NewData creates a new list of UInt8 from a byte slice. +func NewData(s *Segment, v []byte) (UInt8List, error) { + // TODO(light): error if v is too long + l, err := NewUInt8List(s, int32(len(v))) + if err != nil { + return UInt8List{}, err + } + copy(l.seg.slice(l.off, Size(len(v))), v) + return l, nil +} + +// ToText attempts to convert p into Text. +// +// Deprecated: Use Ptr.Text. +func ToText(p Pointer) string { + return toPtr(p).TextDefault("") +} + +// ToTextDefault attempts to convert p into Text, returning def on failure. +// +// Deprecated: Use Ptr.TextDefault. +func ToTextDefault(p Pointer, def string) string { + return toPtr(p).TextDefault(def) +} + +// ToData attempts to convert p into Data. +// +// Deprecated: Use Ptr.Data. +func ToData(p Pointer) []byte { + return toPtr(p).DataDefault(nil) +} + +// ToDataDefault attempts to convert p into Data, returning def on failure. +// +// Deprecated: Use Ptr.DataDefault. +func ToDataDefault(p Pointer, def []byte) []byte { + return toPtr(p).DataDefault(def) +} + +func isOneByteList(p Ptr) bool { + return p.seg != nil && p.flags.ptrType() == listPtrType && p.size.isOneByte() && p.flags.listFlags()&isCompositeList == 0 +} + +// At returns the i'th element. +func (l UInt8List) At(i int) uint8 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 1}) + if err != nil { + return 0 + } + return l.seg.readUint8(addr) +} + +// Set sets the i'th element to v. +func (l UInt8List) Set(i int, v uint8) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 1}) + if err != nil { + panic(err) + } + l.seg.writeUint8(addr, v) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l UInt8List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendUint(buf, uint64(l.At(i)), 10) + } + buf = append(buf, ']') + return string(buf) +} + +// Int8List is an array of Int8 values. +type Int8List struct{ List } + +// NewInt8List creates a new list of Int8, preferring placement in s. +func NewInt8List(s *Segment, n int32) (Int8List, error) { + l, err := newPrimitiveList(s, 1, n) + if err != nil { + return Int8List{}, err + } + return Int8List{l}, nil +} + +// At returns the i'th element. +func (l Int8List) At(i int) int8 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 1}) + if err != nil { + return 0 + } + return int8(l.seg.readUint8(addr)) +} + +// Set sets the i'th element to v. +func (l Int8List) Set(i int, v int8) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 1}) + if err != nil { + panic(err) + } + l.seg.writeUint8(addr, uint8(v)) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l Int8List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendInt(buf, int64(l.At(i)), 10) + } + buf = append(buf, ']') + return string(buf) +} + +// A UInt16List is an array of UInt16 values. +type UInt16List struct{ List } + +// NewUInt16List creates a new list of UInt16, preferring placement in s. +func NewUInt16List(s *Segment, n int32) (UInt16List, error) { + l, err := newPrimitiveList(s, 2, n) + if err != nil { + return UInt16List{}, err + } + return UInt16List{l}, nil +} + +// At returns the i'th element. +func (l UInt16List) At(i int) uint16 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 2}) + if err != nil { + return 0 + } + return l.seg.readUint16(addr) +} + +// Set sets the i'th element to v. +func (l UInt16List) Set(i int, v uint16) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 2}) + if err != nil { + panic(err) + } + l.seg.writeUint16(addr, v) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l UInt16List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendUint(buf, uint64(l.At(i)), 10) + } + buf = append(buf, ']') + return string(buf) +} + +// Int16List is an array of Int16 values. +type Int16List struct{ List } + +// NewInt16List creates a new list of Int16, preferring placement in s. +func NewInt16List(s *Segment, n int32) (Int16List, error) { + l, err := newPrimitiveList(s, 2, n) + if err != nil { + return Int16List{}, err + } + return Int16List{l}, nil +} + +// At returns the i'th element. +func (l Int16List) At(i int) int16 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 2}) + if err != nil { + return 0 + } + return int16(l.seg.readUint16(addr)) +} + +// Set sets the i'th element to v. +func (l Int16List) Set(i int, v int16) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 2}) + if err != nil { + panic(err) + } + l.seg.writeUint16(addr, uint16(v)) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l Int16List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendInt(buf, int64(l.At(i)), 10) + } + buf = append(buf, ']') + return string(buf) +} + +// UInt32List is an array of UInt32 values. +type UInt32List struct{ List } + +// NewUInt32List creates a new list of UInt32, preferring placement in s. +func NewUInt32List(s *Segment, n int32) (UInt32List, error) { + l, err := newPrimitiveList(s, 4, n) + if err != nil { + return UInt32List{}, err + } + return UInt32List{l}, nil +} + +// At returns the i'th element. +func (l UInt32List) At(i int) uint32 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 4}) + if err != nil { + return 0 + } + return l.seg.readUint32(addr) +} + +// Set sets the i'th element to v. +func (l UInt32List) Set(i int, v uint32) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 4}) + if err != nil { + panic(err) + } + l.seg.writeUint32(addr, v) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l UInt32List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendUint(buf, uint64(l.At(i)), 10) + } + buf = append(buf, ']') + return string(buf) +} + +// Int32List is an array of Int32 values. +type Int32List struct{ List } + +// NewInt32List creates a new list of Int32, preferring placement in s. +func NewInt32List(s *Segment, n int32) (Int32List, error) { + l, err := newPrimitiveList(s, 4, n) + if err != nil { + return Int32List{}, err + } + return Int32List{l}, nil +} + +// At returns the i'th element. +func (l Int32List) At(i int) int32 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 4}) + if err != nil { + return 0 + } + return int32(l.seg.readUint32(addr)) +} + +// Set sets the i'th element to v. +func (l Int32List) Set(i int, v int32) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 4}) + if err != nil { + panic(err) + } + l.seg.writeUint32(addr, uint32(v)) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l Int32List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendInt(buf, int64(l.At(i)), 10) + } + buf = append(buf, ']') + return string(buf) +} + +// UInt64List is an array of UInt64 values. +type UInt64List struct{ List } + +// NewUInt64List creates a new list of UInt64, preferring placement in s. +func NewUInt64List(s *Segment, n int32) (UInt64List, error) { + l, err := newPrimitiveList(s, 8, n) + if err != nil { + return UInt64List{}, err + } + return UInt64List{l}, nil +} + +// At returns the i'th element. +func (l UInt64List) At(i int) uint64 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 8}) + if err != nil { + return 0 + } + return l.seg.readUint64(addr) +} + +// Set sets the i'th element to v. +func (l UInt64List) Set(i int, v uint64) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 8}) + if err != nil { + panic(err) + } + l.seg.writeUint64(addr, v) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l UInt64List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendUint(buf, l.At(i), 10) + } + buf = append(buf, ']') + return string(buf) +} + +// Int64List is an array of Int64 values. +type Int64List struct{ List } + +// NewInt64List creates a new list of Int64, preferring placement in s. +func NewInt64List(s *Segment, n int32) (Int64List, error) { + l, err := newPrimitiveList(s, 8, n) + if err != nil { + return Int64List{}, err + } + return Int64List{l}, nil +} + +// At returns the i'th element. +func (l Int64List) At(i int) int64 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 8}) + if err != nil { + return 0 + } + return int64(l.seg.readUint64(addr)) +} + +// Set sets the i'th element to v. +func (l Int64List) Set(i int, v int64) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 8}) + if err != nil { + panic(err) + } + l.seg.writeUint64(addr, uint64(v)) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l Int64List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendInt(buf, l.At(i), 10) + } + buf = append(buf, ']') + return string(buf) +} + +// Float32List is an array of Float32 values. +type Float32List struct{ List } + +// NewFloat32List creates a new list of Float32, preferring placement in s. +func NewFloat32List(s *Segment, n int32) (Float32List, error) { + l, err := newPrimitiveList(s, 4, n) + if err != nil { + return Float32List{}, err + } + return Float32List{l}, nil +} + +// At returns the i'th element. +func (l Float32List) At(i int) float32 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 4}) + if err != nil { + return 0 + } + return math.Float32frombits(l.seg.readUint32(addr)) +} + +// Set sets the i'th element to v. +func (l Float32List) Set(i int, v float32) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 4}) + if err != nil { + panic(err) + } + l.seg.writeUint32(addr, math.Float32bits(v)) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l Float32List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendFloat(buf, float64(l.At(i)), 'g', -1, 32) + } + buf = append(buf, ']') + return string(buf) +} + +// Float64List is an array of Float64 values. +type Float64List struct{ List } + +// NewFloat64List creates a new list of Float64, preferring placement in s. +func NewFloat64List(s *Segment, n int32) (Float64List, error) { + l, err := newPrimitiveList(s, 8, n) + if err != nil { + return Float64List{}, err + } + return Float64List{l}, nil +} + +// At returns the i'th element. +func (l Float64List) At(i int) float64 { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 8}) + if err != nil { + return 0 + } + return math.Float64frombits(l.seg.readUint64(addr)) +} + +// Set sets the i'th element to v. +func (l Float64List) Set(i int, v float64) { + addr, err := l.primitiveElem(i, ObjectSize{DataSize: 8}) + if err != nil { + panic(err) + } + l.seg.writeUint64(addr, math.Float64bits(v)) +} + +// String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]"). +func (l Float64List) String() string { + var buf []byte + buf = append(buf, '[') + for i := 0; i < l.Len(); i++ { + if i > 0 { + buf = append(buf, ", "...) + } + buf = strconv.AppendFloat(buf, l.At(i), 'g', -1, 64) + } + buf = append(buf, ']') + return string(buf) +} + +type listFlags uint8 + +const ( + isCompositeList listFlags = 1 << iota + isBitList +) + +var errBitListStruct = errors.New("capnp: SetStruct called on bit list") diff --git a/vendor/zombiezen.com/go/capnproto2/mem.go b/vendor/zombiezen.com/go/capnproto2/mem.go new file mode 100644 index 00000000..11f84be5 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/mem.go @@ -0,0 +1,913 @@ +package capnp + +import ( + "bufio" + "encoding/binary" + "errors" + "fmt" + "io" + "sync" + + "zombiezen.com/go/capnproto2/internal/packed" +) + +// Security limits. Matches C++ implementation. +const ( + defaultTraverseLimit = 64 << 20 // 64 MiB + defaultDepthLimit = 64 + + maxStreamSegments = 512 + + defaultDecodeLimit = 64 << 20 // 64 MiB +) + +const maxDepth = ^uint(0) + +// A Message is a tree of Cap'n Proto objects, split into one or more +// segments of contiguous memory. The only required field is Arena. +// A Message is safe to read from multiple goroutines. +type Message struct { + // rlimit must be first so that it is 64-bit aligned. + // See sync/atomic docs. + rlimit ReadLimiter + rlimitInit sync.Once + + Arena Arena + + // CapTable is the indexed list of the clients referenced in the + // message. Capability pointers inside the message will use this table + // to map pointers to Clients. The table is usually populated by the + // RPC system. + // + // See https://capnproto.org/encoding.html#capabilities-interfaces for + // more details on the capability table. + CapTable []Client + + // TraverseLimit limits how many total bytes of data are allowed to be + // traversed while reading. Traversal is counted when a Struct or + // List is obtained. This means that calling a getter for the same + // sub-struct multiple times will cause it to be double-counted. Once + // the traversal limit is reached, pointer accessors will report + // errors. See https://capnproto.org/encoding.html#amplification-attack + // for more details on this security measure. + // + // If not set, this defaults to 64 MiB. + TraverseLimit uint64 + + // DepthLimit limits how deeply-nested a message structure can be. + // If not set, this defaults to 64. + DepthLimit uint + + // mu protects the following fields: + mu sync.Mutex + segs map[SegmentID]*Segment + firstSeg Segment // Preallocated first segment. msg is non-nil once initialized. +} + +// NewMessage creates a message with a new root and returns the first +// segment. It is an error to call NewMessage on an arena with data in it. +func NewMessage(arena Arena) (msg *Message, first *Segment, err error) { + msg = &Message{Arena: arena} + switch arena.NumSegments() { + case 0: + first, err = msg.allocSegment(wordSize) + if err != nil { + return nil, nil, err + } + case 1: + first, err = msg.Segment(0) + if err != nil { + return nil, nil, err + } + if len(first.data) > 0 { + return nil, nil, errHasData + } + default: + return nil, nil, errHasData + } + if first.ID() != 0 { + return nil, nil, errors.New("capnp: arena allocated first segment with non-zero ID") + } + seg, _, err := alloc(first, wordSize) // allocate root + if err != nil { + return nil, nil, err + } + if seg != first { + return nil, nil, errors.New("capnp: arena didn't allocate first word in first segment") + } + return msg, first, nil +} + +// Reset resets a message to use a different arena, allowing a single +// Message to be reused for reading multiple messages. This invalidates +// any existing pointers in the Message, so use with caution. +func (m *Message) Reset(arena Arena) { + m.mu.Lock() + m.Arena = arena + m.CapTable = nil + m.segs = nil + m.firstSeg = Segment{} + m.mu.Unlock() + if m.TraverseLimit == 0 { + m.ReadLimiter().Reset(defaultTraverseLimit) + } else { + m.ReadLimiter().Reset(m.TraverseLimit) + } +} + +// Root returns the pointer to the message's root object. +// +// Deprecated: Use RootPtr. +func (m *Message) Root() (Pointer, error) { + p, err := m.RootPtr() + return p.toPointer(), err +} + +// RootPtr returns the pointer to the message's root object. +func (m *Message) RootPtr() (Ptr, error) { + s, err := m.Segment(0) + if err != nil { + return Ptr{}, err + } + return s.root().PtrAt(0) +} + +// SetRoot sets the message's root object to p. +// +// Deprecated: Use SetRootPtr. +func (m *Message) SetRoot(p Pointer) error { + return m.SetRootPtr(toPtr(p)) +} + +// SetRootPtr sets the message's root object to p. +func (m *Message) SetRootPtr(p Ptr) error { + s, err := m.Segment(0) + if err != nil { + return err + } + return s.root().SetPtr(0, p) +} + +// AddCap appends a capability to the message's capability table and +// returns its ID. +func (m *Message) AddCap(c Client) CapabilityID { + n := CapabilityID(len(m.CapTable)) + m.CapTable = append(m.CapTable, c) + return n +} + +// ReadLimiter returns the message's read limiter. Useful if you want +// to reset the traversal limit while reading. +func (m *Message) ReadLimiter() *ReadLimiter { + m.rlimitInit.Do(func() { + if m.TraverseLimit == 0 { + m.rlimit.limit = defaultTraverseLimit + } else { + m.rlimit.limit = m.TraverseLimit + } + }) + return &m.rlimit +} + +func (m *Message) depthLimit() uint { + if m.DepthLimit != 0 { + return m.DepthLimit + } + return defaultDepthLimit +} + +// NumSegments returns the number of segments in the message. +func (m *Message) NumSegments() int64 { + return int64(m.Arena.NumSegments()) +} + +// Segment returns the segment with the given ID. +func (m *Message) Segment(id SegmentID) (*Segment, error) { + if isInt32Bit && id > maxInt32 { + return nil, errSegment32Bit + } + if int64(id) >= m.Arena.NumSegments() { + return nil, errSegmentOutOfBounds + } + m.mu.Lock() + if seg := m.segment(id); seg != nil { + m.mu.Unlock() + return seg, nil + } + data, err := m.Arena.Data(id) + if err != nil { + m.mu.Unlock() + return nil, err + } + seg := m.setSegment(id, data) + m.mu.Unlock() + return seg, nil +} + +// segment returns the segment with the given ID. +// The caller must be holding m.mu. +func (m *Message) segment(id SegmentID) *Segment { + if m.segs == nil { + if id == 0 && m.firstSeg.msg != nil { + return &m.firstSeg + } + return nil + } + return m.segs[id] +} + +// setSegment creates or updates the Segment with the given ID. +// The caller must be holding m.mu. +func (m *Message) setSegment(id SegmentID, data []byte) *Segment { + if m.segs == nil { + if id == 0 { + m.firstSeg = Segment{ + id: id, + msg: m, + data: data, + } + return &m.firstSeg + } + m.segs = make(map[SegmentID]*Segment) + if m.firstSeg.msg != nil { + m.segs[0] = &m.firstSeg + } + } else if seg := m.segs[id]; seg != nil { + seg.data = data + return seg + } + seg := &Segment{ + id: id, + msg: m, + data: data, + } + m.segs[id] = seg + return seg +} + +// allocSegment creates or resizes an existing segment such that +// cap(seg.Data) - len(seg.Data) >= sz. +func (m *Message) allocSegment(sz Size) (*Segment, error) { + m.mu.Lock() + if m.segs == nil && m.firstSeg.msg != nil { + m.segs = make(map[SegmentID]*Segment) + m.segs[0] = &m.firstSeg + } + id, data, err := m.Arena.Allocate(sz, m.segs) + if err != nil { + m.mu.Unlock() + return nil, err + } + if isInt32Bit && id > maxInt32 { + m.mu.Unlock() + return nil, errSegment32Bit + } + seg := m.setSegment(id, data) + m.mu.Unlock() + return seg, nil +} + +// alloc allocates sz zero-filled bytes. It prefers using s, but may +// use a different segment in the same message if there's not sufficient +// capacity. +func alloc(s *Segment, sz Size) (*Segment, Address, error) { + sz = sz.padToWord() + if sz > maxSize-wordSize { + return nil, 0, errOverflow + } + + if !hasCapacity(s.data, sz) { + var err error + s, err = s.msg.allocSegment(sz) + if err != nil { + return nil, 0, err + } + } + + addr := Address(len(s.data)) + end, ok := addr.addSize(sz) + if !ok { + return nil, 0, errOverflow + } + space := s.data[len(s.data):end] + s.data = s.data[:end] + for i := range space { + space[i] = 0 + } + return s, addr, nil +} + +// An Arena loads and allocates segments for a Message. +type Arena interface { + // NumSegments returns the number of segments in the arena. + // This must not be larger than 1<<32. + NumSegments() int64 + + // Data loads the data for the segment with the given ID. IDs are in + // the range [0, NumSegments()). + // must be tightly packed in the range [0, NumSegments()). + Data(id SegmentID) ([]byte, error) + + // Allocate selects a segment to place a new object in, creating a + // segment or growing the capacity of a previously loaded segment if + // necessary. If Allocate does not return an error, then the + // difference of the capacity and the length of the returned slice + // must be at least minsz. segs is a map of segment slices returned + // by the Data method keyed by ID (although the length of these slices + // may have changed by previous allocations). Allocate must not + // modify segs. + // + // If Allocate creates a new segment, the ID must be one larger than + // the last segment's ID or zero if it is the first segment. + // + // If Allocate returns an previously loaded segment's ID, then the + // arena is responsible for preserving the existing data in the + // returned byte slice. + Allocate(minsz Size, segs map[SegmentID]*Segment) (SegmentID, []byte, error) +} + +type singleSegmentArena []byte + +// SingleSegment returns a new arena with an expanding single-segment +// buffer. b can be used to populate the segment for reading or to +// reserve memory of a specific size. A SingleSegment arena does not +// return errors unless you attempt to access another segment. +func SingleSegment(b []byte) Arena { + ssa := new(singleSegmentArena) + *ssa = b + return ssa +} + +func (ssa *singleSegmentArena) NumSegments() int64 { + return 1 +} + +func (ssa *singleSegmentArena) Data(id SegmentID) ([]byte, error) { + if id != 0 { + return nil, errSegmentOutOfBounds + } + return *ssa, nil +} + +func (ssa *singleSegmentArena) Allocate(sz Size, segs map[SegmentID]*Segment) (SegmentID, []byte, error) { + data := []byte(*ssa) + if segs[0] != nil { + data = segs[0].data + } + if len(data)%int(wordSize) != 0 { + return 0, nil, errors.New("capnp: segment size is not a multiple of word size") + } + if hasCapacity(data, sz) { + return 0, data, nil + } + inc, err := nextAlloc(int64(cap(data)), int64(maxSegmentSize()), sz) + if err != nil { + return 0, nil, fmt.Errorf("capnp: alloc %d bytes: %v", sz, err) + } + buf := make([]byte, len(data), cap(data)+inc) + copy(buf, data) + *ssa = buf + return 0, *ssa, nil +} + +type roSingleSegment []byte + +func (ss roSingleSegment) NumSegments() int64 { + return 1 +} + +func (ss roSingleSegment) Data(id SegmentID) ([]byte, error) { + if id != 0 { + return nil, errSegmentOutOfBounds + } + return ss, nil +} + +func (ss roSingleSegment) Allocate(sz Size, segs map[SegmentID]*Segment) (SegmentID, []byte, error) { + return 0, nil, errors.New("capnp: segment is read-only") +} + +type multiSegmentArena [][]byte + +// MultiSegment returns a new arena that allocates new segments when +// they are full. b can be used to populate the buffer for reading or +// to reserve memory of a specific size. +func MultiSegment(b [][]byte) Arena { + msa := new(multiSegmentArena) + *msa = b + return msa +} + +// demuxArena slices b into a multi-segment arena. +func demuxArena(hdr streamHeader, data []byte) (Arena, error) { + segs := make([][]byte, int(hdr.maxSegment())+1) + for i := range segs { + sz, err := hdr.segmentSize(uint32(i)) + if err != nil { + return nil, err + } + segs[i], data = data[:sz:sz], data[sz:] + } + return MultiSegment(segs), nil +} + +func (msa *multiSegmentArena) NumSegments() int64 { + return int64(len(*msa)) +} + +func (msa *multiSegmentArena) Data(id SegmentID) ([]byte, error) { + if int64(id) >= int64(len(*msa)) { + return nil, errSegmentOutOfBounds + } + return (*msa)[id], nil +} + +func (msa *multiSegmentArena) Allocate(sz Size, segs map[SegmentID]*Segment) (SegmentID, []byte, error) { + var total int64 + for i, data := range *msa { + id := SegmentID(i) + if s := segs[id]; s != nil { + data = s.data + } + if hasCapacity(data, sz) { + return id, data, nil + } + total += int64(cap(data)) + if total < 0 { + // Overflow. + return 0, nil, fmt.Errorf("capnp: alloc %d bytes: message too large", sz) + } + } + n, err := nextAlloc(total, 1<<63-1, sz) + if err != nil { + return 0, nil, fmt.Errorf("capnp: alloc %d bytes: %v", sz, err) + } + buf := make([]byte, 0, n) + id := SegmentID(len(*msa)) + *msa = append(*msa, buf) + return id, buf, nil +} + +// nextAlloc computes how much more space to allocate given the number +// of bytes allocated in the entire message and the requested number of +// bytes. It will always return a multiple of wordSize. max must be a +// multiple of wordSize. The sum of curr and the returned size will +// always be less than max. +func nextAlloc(curr, max int64, req Size) (int, error) { + if req == 0 { + return 0, nil + } + maxinc := int64(1<<32 - 8) // largest word-aligned Size + if isInt32Bit { + maxinc = 1<<31 - 8 // largest word-aligned int + } + if int64(req) > maxinc { + return 0, errors.New("allocation too large") + } + req = req.padToWord() + want := curr + int64(req) + if want <= curr || want > max { + return 0, errors.New("allocation overflows message size") + } + new := curr + double := new + new + switch { + case want < 1024: + next := (1024 - curr + 7) &^ 7 + if next < curr { + return int((curr + 7) &^ 7), nil + } + return int(next), nil + case want > double: + return int(req), nil + default: + for 0 < new && new < want { + new += new / 4 + } + if new <= 0 { + return int(req), nil + } + delta := new - curr + if delta > maxinc { + return int(maxinc), nil + } + return int((delta + 7) &^ 7), nil + } +} + +// A Decoder represents a framer that deserializes a particular Cap'n +// Proto input stream. +type Decoder struct { + r io.Reader + + segbuf [msgHeaderSize]byte + hdrbuf []byte + + reuse bool + buf []byte + msg Message + arena roSingleSegment + + // Maximum number of bytes that can be read per call to Decode. + // If not set, a reasonable default is used. + MaxMessageSize uint64 +} + +// NewDecoder creates a new Cap'n Proto framer that reads from r. +func NewDecoder(r io.Reader) *Decoder { + return &Decoder{r: r} +} + +// NewPackedDecoder creates a new Cap'n Proto framer that reads from a +// packed stream r. +func NewPackedDecoder(r io.Reader) *Decoder { + return NewDecoder(packed.NewReader(bufio.NewReader(r))) +} + +// Decode reads a message from the decoder stream. +func (d *Decoder) Decode() (*Message, error) { + maxSize := d.MaxMessageSize + if maxSize == 0 { + maxSize = defaultDecodeLimit + } + if _, err := io.ReadFull(d.r, d.segbuf[:]); err != nil { + return nil, err + } + maxSeg := binary.LittleEndian.Uint32(d.segbuf[:]) + if maxSeg > maxStreamSegments { + return nil, errTooManySegments + } + hdrSize := streamHeaderSize(maxSeg) + if hdrSize > maxSize || hdrSize > (1<<31-1) { + return nil, errDecodeLimit + } + d.hdrbuf = resizeSlice(d.hdrbuf, int(hdrSize)) + copy(d.hdrbuf, d.segbuf[:]) + if _, err := io.ReadFull(d.r, d.hdrbuf[msgHeaderSize:]); err != nil { + return nil, err + } + hdr, _, err := parseStreamHeader(d.hdrbuf) + if err != nil { + return nil, err + } + total, err := hdr.totalSize() + if err != nil { + return nil, err + } + // TODO(someday): if total size is greater than can fit in one buffer, + // attempt to allocate buffer per segment. + if total > maxSize-hdrSize || total > (1<<31-1) { + return nil, errDecodeLimit + } + if !d.reuse { + buf := make([]byte, int(total)) + if _, err := io.ReadFull(d.r, buf); err != nil { + return nil, err + } + arena, err := demuxArena(hdr, buf) + if err != nil { + return nil, err + } + return &Message{Arena: arena}, nil + } + d.buf = resizeSlice(d.buf, int(total)) + if _, err := io.ReadFull(d.r, d.buf); err != nil { + return nil, err + } + var arena Arena + if hdr.maxSegment() == 0 { + d.arena = d.buf[:len(d.buf):len(d.buf)] + arena = &d.arena + } else { + var err error + arena, err = demuxArena(hdr, d.buf) + if err != nil { + return nil, err + } + } + d.msg.Reset(arena) + return &d.msg, nil +} + +func resizeSlice(b []byte, size int) []byte { + if cap(b) < size { + return make([]byte, size) + } + return b[:size] +} + +// ReuseBuffer causes the decoder to reuse its buffer on subsequent decodes. +// The decoder may return messages that cannot handle allocations. +func (d *Decoder) ReuseBuffer() { + d.reuse = true +} + +// Unmarshal reads an unpacked serialized stream into a message. No +// copying is performed, so the objects in the returned message read +// directly from data. +func Unmarshal(data []byte) (*Message, error) { + if len(data) == 0 { + return nil, io.EOF + } + hdr, data, err := parseStreamHeader(data) + if err != nil { + return nil, err + } + if tot, err := hdr.totalSize(); err != nil { + return nil, err + } else if tot > uint64(len(data)) { + return nil, io.ErrUnexpectedEOF + } + arena, err := demuxArena(hdr, data) + if err != nil { + return nil, err + } + return &Message{Arena: arena}, nil +} + +// UnmarshalPacked reads a packed serialized stream into a message. +func UnmarshalPacked(data []byte) (*Message, error) { + if len(data) == 0 { + return nil, io.EOF + } + data, err := packed.Unpack(nil, data) + if err != nil { + return nil, err + } + return Unmarshal(data) +} + +// MustUnmarshalRoot reads an unpacked serialized stream and returns +// its root pointer. If there is any error, it panics. +// +// Deprecated: Use MustUnmarshalRootPtr. +func MustUnmarshalRoot(data []byte) Pointer { + msg, err := Unmarshal(data) + if err != nil { + panic(err) + } + p, err := msg.Root() + if err != nil { + panic(err) + } + return p +} + +// MustUnmarshalRootPtr reads an unpacked serialized stream and returns +// its root pointer. If there is any error, it panics. +func MustUnmarshalRootPtr(data []byte) Ptr { + msg, err := Unmarshal(data) + if err != nil { + panic(err) + } + p, err := msg.RootPtr() + if err != nil { + panic(err) + } + return p +} + +// An Encoder represents a framer for serializing a particular Cap'n +// Proto stream. +type Encoder struct { + w io.Writer + hdrbuf []byte + bufs [][]byte + + packed bool + packbuf []byte +} + +// NewEncoder creates a new Cap'n Proto framer that writes to w. +func NewEncoder(w io.Writer) *Encoder { + return &Encoder{w: w} +} + +// NewPackedEncoder creates a new Cap'n Proto framer that writes to a +// packed stream w. +func NewPackedEncoder(w io.Writer) *Encoder { + return &Encoder{w: w, packed: true} +} + +// Encode writes a message to the encoder stream. +func (e *Encoder) Encode(m *Message) error { + nsegs := m.NumSegments() + if nsegs == 0 { + return errMessageEmpty + } + e.bufs = append(e.bufs[:0], nil) // first element is placeholder for header + maxSeg := uint32(nsegs - 1) + hdrSize := streamHeaderSize(maxSeg) + if uint64(cap(e.hdrbuf)) < hdrSize { + e.hdrbuf = make([]byte, 0, hdrSize) + } + e.hdrbuf = appendUint32(e.hdrbuf[:0], maxSeg) + for i := int64(0); i < nsegs; i++ { + s, err := m.Segment(SegmentID(i)) + if err != nil { + return err + } + n := len(s.data) + if int64(n) > int64(maxSize) { + return errSegmentTooLarge + } + e.hdrbuf = appendUint32(e.hdrbuf, uint32(Size(n)/wordSize)) + e.bufs = append(e.bufs, s.data) + } + if len(e.hdrbuf)%int(wordSize) != 0 { + e.hdrbuf = appendUint32(e.hdrbuf, 0) + } + e.bufs[0] = e.hdrbuf + if e.packed { + return e.writePacked(e.bufs) + } + return e.write(e.bufs) +} + +func (e *Encoder) writePacked(bufs [][]byte) error { + for _, b := range bufs { + e.packbuf = packed.Pack(e.packbuf[:0], b) + if _, err := e.w.Write(e.packbuf); err != nil { + return err + } + } + return nil +} + +func (m *Message) segmentSizes() ([]Size, error) { + nsegs := m.NumSegments() + sizes := make([]Size, nsegs) + for i := int64(0); i < nsegs; i++ { + s, err := m.Segment(SegmentID(i)) + if err != nil { + return sizes[:i], err + } + n := len(s.data) + if int64(n) > int64(maxSize) { + return sizes[:i], errSegmentTooLarge + } + sizes[i] = Size(n) + } + return sizes, nil +} + +// Marshal concatenates the segments in the message into a single byte +// slice including framing. +func (m *Message) Marshal() ([]byte, error) { + // Compute buffer size. + // TODO(light): error out if too many segments + nsegs := m.NumSegments() + if nsegs == 0 { + return nil, errMessageEmpty + } + maxSeg := uint32(nsegs - 1) + hdrSize := streamHeaderSize(maxSeg) + sizes, err := m.segmentSizes() + if err != nil { + return nil, err + } + // TODO(light): error out if too large + total := uint64(hdrSize) + totalSize(sizes) + + // Fill in buffer. + buf := make([]byte, hdrSize, total) + // TODO: remove marshalStreamHeader and inline. + marshalStreamHeader(buf, sizes) + for i := int64(0); i < nsegs; i++ { + s, err := m.Segment(SegmentID(i)) + if err != nil { + return nil, err + } + buf = append(buf, s.data...) + } + return buf, nil +} + +// MarshalPacked marshals the message in packed form. +func (m *Message) MarshalPacked() ([]byte, error) { + data, err := m.Marshal() + if err != nil { + return nil, err + } + buf := make([]byte, 0, len(data)) + buf = packed.Pack(buf, data) + return buf, nil +} + +// Stream header sizes. +const ( + msgHeaderSize = 4 + segHeaderSize = 4 +) + +// streamHeaderSize returns the size of the header, given the +// first 32-bit number. +func streamHeaderSize(n uint32) uint64 { + return (msgHeaderSize + segHeaderSize*(uint64(n)+1) + 7) &^ 7 +} + +// marshalStreamHeader marshals the sizes into the byte slice, which +// must be of size streamHeaderSize(len(sizes) - 1). +// +// TODO: remove marshalStreamHeader and inline. +func marshalStreamHeader(b []byte, sizes []Size) { + binary.LittleEndian.PutUint32(b, uint32(len(sizes)-1)) + for i, sz := range sizes { + loc := msgHeaderSize + i*segHeaderSize + binary.LittleEndian.PutUint32(b[loc:], uint32(sz/Size(wordSize))) + } +} + +// appendUint32 appends a uint32 to a byte slice and returns the +// new slice. +func appendUint32(b []byte, v uint32) []byte { + b = append(b, 0, 0, 0, 0) + binary.LittleEndian.PutUint32(b[len(b)-4:], v) + return b +} + +type streamHeader struct { + b []byte +} + +// parseStreamHeader parses the header of the stream framing format. +func parseStreamHeader(data []byte) (h streamHeader, tail []byte, err error) { + if uint64(len(data)) < streamHeaderSize(0) { + return streamHeader{}, nil, io.ErrUnexpectedEOF + } + maxSeg := binary.LittleEndian.Uint32(data) + // TODO(light): check int + hdrSize := streamHeaderSize(maxSeg) + if uint64(len(data)) < hdrSize { + return streamHeader{}, nil, io.ErrUnexpectedEOF + } + return streamHeader{b: data}, data[hdrSize:], nil +} + +func (h streamHeader) maxSegment() uint32 { + return binary.LittleEndian.Uint32(h.b) +} + +func (h streamHeader) segmentSize(i uint32) (Size, error) { + s := binary.LittleEndian.Uint32(h.b[msgHeaderSize+i*segHeaderSize:]) + sz, ok := wordSize.times(int32(s)) + if !ok { + return 0, errSegmentTooLarge + } + return sz, nil +} + +func (h streamHeader) totalSize() (uint64, error) { + var sum uint64 + for i := uint64(0); i <= uint64(h.maxSegment()); i++ { + x, err := h.segmentSize(uint32(i)) + if err != nil { + return sum, err + } + sum += uint64(x) + } + return sum, nil +} + +func hasCapacity(b []byte, sz Size) bool { + return sz <= Size(cap(b)-len(b)) +} + +func totalSize(s []Size) uint64 { + var sum uint64 + for _, sz := range s { + sum += uint64(sz) + } + return sum +} + +const ( + maxInt32 = 0x7fffffff + maxInt = int(^uint(0) >> 1) + + isInt32Bit = maxInt == maxInt32 +) + +// maxSegmentSize returns the maximum permitted size of a single segment +// on this platform. +// +// This is effectively a compile-time constant, but can't be represented +// as a constant because it requires a conditional. It is trivially +// inlinable and optimizable, so should act like one. +func maxSegmentSize() Size { + if isInt32Bit { + return Size(maxInt32 - 7) + } else { + return maxSize - 7 + } +} + +var ( + errSegmentOutOfBounds = errors.New("capnp: segment ID out of bounds") + errSegment32Bit = errors.New("capnp: segment ID larger than 31 bits") + errMessageEmpty = errors.New("capnp: marshalling an empty message") + errHasData = errors.New("capnp: NewMessage called on arena with data") + errSegmentTooLarge = errors.New("capnp: segment too large") + errTooManySegments = errors.New("capnp: too many segments to decode") + errDecodeLimit = errors.New("capnp: message too large") +) diff --git a/vendor/zombiezen.com/go/capnproto2/mem_18.go b/vendor/zombiezen.com/go/capnproto2/mem_18.go new file mode 100644 index 00000000..d2853072 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/mem_18.go @@ -0,0 +1,10 @@ +// +build go1.8 + +package capnp + +import "net" + +func (e *Encoder) write(bufs [][]byte) error { + _, err := (*net.Buffers)(&bufs).WriteTo(e.w) + return err +} diff --git a/vendor/zombiezen.com/go/capnproto2/mem_other.go b/vendor/zombiezen.com/go/capnproto2/mem_other.go new file mode 100644 index 00000000..ba1ab667 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/mem_other.go @@ -0,0 +1,12 @@ +// +build !go1.8 + +package capnp + +func (e *Encoder) write(bufs [][]byte) error { + for _, b := range bufs { + if _, err := e.w.Write(b); err != nil { + return err + } + } + return nil +} diff --git a/vendor/zombiezen.com/go/capnproto2/pogs/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/pogs/BUILD.bazel new file mode 100644 index 00000000..d2226751 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/pogs/BUILD.bazel @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "doc.go", + "extract.go", + "fields.go", + "insert.go", + ], + importpath = "zombiezen.com/go/capnproto2/pogs", + visibility = ["//visibility:public"], + deps = [ + "//:go_default_library", + "//internal/nodemap:go_default_library", + "//internal/schema:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = [ + "bench_test.go", + "embed_test.go", + "example_test.go", + "interface_test.go", + "pogs_test.go", + ], + embed = [":go_default_library"], + deps = [ + "//:go_default_library", + "//internal/aircraftlib:go_default_library", + "//internal/demo/books:go_default_library", + "@com_github_kylelemons_godebug//pretty:go_default_library", + "@org_golang_x_net//context:go_default_library", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/pogs/doc.go b/vendor/zombiezen.com/go/capnproto2/pogs/doc.go new file mode 100644 index 00000000..b149e15b --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/pogs/doc.go @@ -0,0 +1,164 @@ +/* +Package pogs provides functions to convert Cap'n Proto messages to and +from Go structs. pogs operates similarly to encoding/json: define a +struct that is optionally marked up with tags, then Insert and Extract +will copy the fields to and from the corresponding Cap'n Proto struct. + +Inserting + +To copy data into a Cap'n Proto struct, we use the Insert function. +Consider the following schema: + + struct Message { + name @0 :Text; + body @1 :Text; + time @2 :Int64; + } + +and the Go struct: + + type Message struct { + Name string + Body string + Time int64 + } + +We can copy the Go struct into a Cap'n Proto struct like this: + + _, arena, _ := capnp.NewMessage(capnp.SingleSegment(nil)) + root, _ := myschema.NewRootMessage(arena) + m := &Message{"Alice", "Hello", 1294706395881547000} + err := pogs.Insert(myschema.Message_TypeID, root.Struct, m) + +Note that if any field names in our Go struct don't match to a field in +the Cap'n Proto struct, Insert returns an error. We'll see how to fix +that in a moment. + +Extracting + +Copying data back out from a Cap'n Proto struct is quite similar: we +pass a pointer to our Go struct to Extract. + + m := new(Message) + err := pogs.Extract(m, myschema.Message_TypeID, root.Struct) + +Types + +The mapping between Cap'n Proto types and underlying Go types is as +follows: + + Bool -> bool + Int8, Int16, Int32, Int64 -> int8, int16, int32, int64 + UInt8, UInt16, UInt32, UInt64 -> uint8, uint16, uint32, uint64 + Float32, Float64 -> float32, float64 + Text -> either []byte or string + Data -> []byte + List -> slice + enum -> uint16 + struct -> a struct or pointer to struct + interface -> a capnp.Client or struct with + exactly one field, named + "Client", of type capnp.Client + +Note that the unsized int and uint type can't be used: int and float +types must match in size. For Data and Text fields using []byte, the +filled-in byte slice will point to original segment. + +Renaming and Omitting Fields + +By default, the Go field name is the same as the Cap'n Proto schema +field name with the first letter capitalized. If we want to change this +mapping, we use the capnp field tag. + + type MessageRenamed struct { + Subject string `capnp:"name"` + Body string + SentMillis int64 `capnp:"time"` + } + +Using a "-" will cause the field to be ignored by the Insert and +Extract functions. + + type ExtraFieldsMessage struct { + ID uint64 `capnp:"-"` + Name string + Body string + Time int64 + } + +Unions + +Since Go does not have support for variant types, Go structs that want +to use fields inside a Cap'n Proto union must have an explicit +discriminant field called Which. The Extract function will populate the +Which field and the Insert function will read the Which field to +determine which field to set. Given this schema: + + struct Shape { + area @0 :Float64; + + union { + circle @1 :Float64; + square @2 :Float64; + } + } + +the Go struct should look like this: + + type Shape struct { + Area float64 + + Which myschema.Shape_Which // or any other uint16 type + Circle float64 + Square float64 + } + +Attempting to use fields in a union without a uint16 Which field will +result in an error. There is one exception: we can declare our Which +field to be fixed to one particular union value by using a field tag. + + type Square struct { + Which struct{} `capnp:",which=square"` + Area float64 + Width float64 `capnp:"square"` + } + +This can be useful if we want to use a different Go type depending on +which field in the union is set. + + shape, err := myschema.ReadRootShape(msg) + if err != nil { + return nil, err + } + switch shape.Which() { + case myschema.Shape_Which_square: + sq := new(Square) + err = pogs.Extract(sq, myschema.Square_TypeID, shape.Struct) + return sq, err + case myschema.Shape_Which_circle: + // ... + } + +Embedding + +Anonymous struct fields are usually extracted or inserted as if their +inner exported fields were fields in the outer struct, subject to the +rules in the next paragraph. An anonymous struct field with a name +given in its capnp tag is treated as having that name, rather than being +anonymous. An anonymous struct field with a capnp tag of "-" will be +ignored. + +The visibility rules for struct fields are amended for pogs in the same +way they are amended in encoding/json: if there are multiple fields at +the same level, and that level is the least nested, the following extra +rules apply: + +1) Of those fields, if any are capnp-tagged, only tagged fields are +considered, even if there are multiple untagged fields that would +otherwise conflict. +2) If there is exactly one field (tagged or not according to the first +rule), that is selected. +3) Otherwise, there are multiple fields, and all are ignored; no error +occurs. +*/ +package pogs // import "zombiezen.com/go/capnproto2/pogs" diff --git a/vendor/zombiezen.com/go/capnproto2/pogs/extract.go b/vendor/zombiezen.com/go/capnproto2/pogs/extract.go new file mode 100644 index 00000000..1a856189 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/pogs/extract.go @@ -0,0 +1,418 @@ +package pogs + +import ( + "errors" + "fmt" + "math" + "reflect" + + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/nodemap" + "zombiezen.com/go/capnproto2/internal/schema" +) + +// Extract copies s into val, a pointer to a Go struct. +func Extract(val interface{}, typeID uint64, s capnp.Struct) error { + e := new(extracter) + err := e.extractStruct(reflect.ValueOf(val), typeID, s) + if err != nil { + return fmt.Errorf("pogs: extract @%#x: %v", typeID, err) + } + return nil +} + +type extracter struct { + nodes nodemap.Map +} + +var clientType = reflect.TypeOf((*capnp.Client)(nil)).Elem() + +func (e *extracter) extractStruct(val reflect.Value, typeID uint64, s capnp.Struct) error { + if val.Kind() == reflect.Ptr { + if val.Type().Elem().Kind() != reflect.Struct { + return fmt.Errorf("can't extract struct into %v", val.Type()) + } + switch { + case !val.CanSet() && val.IsNil(): + // Even if the Cap'n Proto pointer isn't valid, this is probably + // the caller's fault and will be a bug at some point. + return errors.New("can't extract struct into nil") + case !s.IsValid() && val.CanSet(): + val.Set(reflect.Zero(val.Type())) + return nil + case s.IsValid() && val.CanSet() && val.IsNil(): + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } else if val.Kind() != reflect.Struct { + return fmt.Errorf("can't extract struct into %v", val.Type()) + } + if !val.CanSet() { + return errors.New("can't modify struct, did you pass in a pointer to your struct?") + } + n, err := e.nodes.Find(typeID) + if err != nil { + return err + } + if !n.IsValid() || n.Which() != schema.Node_Which_structNode { + return fmt.Errorf("cannot find struct type %#x", typeID) + } + props, err := mapStruct(val.Type(), n) + if err != nil { + return fmt.Errorf("can't extract %s: %v", val.Type(), err) + } + var discriminant uint16 + hasWhich := false + if hasDiscriminant(n) { + discriminant = s.Uint16(capnp.DataOffset(n.StructNode().DiscriminantOffset() * 2)) + if err := props.setWhich(val, discriminant); err == nil { + hasWhich = true + } else if !isNoWhichError(err) { + return err + } + } + fields, err := n.StructNode().Fields() + if err != nil { + return err + } + for i := 0; i < fields.Len(); i++ { + f := fields.At(i) + vf := props.makeFieldByOrdinal(val, i) + if !vf.IsValid() { + // Don't have a field for this. + continue + } + if dv := f.DiscriminantValue(); dv != schema.Field_noDiscriminant { + if !hasWhich { + return fmt.Errorf("can't extract %s into %v: has union field but no Which field", shortDisplayName(n), val.Type()) + } + if dv != discriminant { + continue + } + } + switch f.Which() { + case schema.Field_Which_slot: + if err := e.extractField(vf, s, f); err != nil { + return err + } + case schema.Field_Which_group: + if err := e.extractStruct(vf, f.Group().TypeId(), s); err != nil { + return err + } + } + } + return nil +} + +func (e *extracter) extractField(val reflect.Value, s capnp.Struct, f schema.Field) error { + typ, err := f.Slot().Type() + if err != nil { + return err + } + dv, err := f.Slot().DefaultValue() + if err != nil { + return err + } + if dv.IsValid() && int(typ.Which()) != int(dv.Which()) { + name, _ := f.NameBytes() + return fmt.Errorf("extract field %s: default value is a %v, want %v", name, dv.Which(), typ.Which()) + } + if !isTypeMatch(val.Type(), typ) { + name, _ := f.NameBytes() + return fmt.Errorf("can't extract field %s of type %v into a Go %v", name, typ.Which(), val.Type()) + } + switch typ.Which() { + case schema.Type_Which_bool: + v := s.Bit(capnp.BitOffset(f.Slot().Offset())) + d := dv.Bool() + val.SetBool(v != d) // != acts as XOR + case schema.Type_Which_int8: + v := int8(s.Uint8(capnp.DataOffset(f.Slot().Offset()))) + d := dv.Int8() + val.SetInt(int64(v ^ d)) + case schema.Type_Which_int16: + v := int16(s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2))) + d := dv.Int16() + val.SetInt(int64(v ^ d)) + case schema.Type_Which_int32: + v := int32(s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4))) + d := dv.Int32() + val.SetInt(int64(v ^ d)) + case schema.Type_Which_int64: + v := int64(s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8))) + d := dv.Int64() + val.SetInt(v ^ d) + case schema.Type_Which_uint8: + v := s.Uint8(capnp.DataOffset(f.Slot().Offset())) + d := dv.Uint8() + val.SetUint(uint64(v ^ d)) + case schema.Type_Which_uint16: + v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2)) + d := dv.Uint16() + val.SetUint(uint64(v ^ d)) + case schema.Type_Which_enum: + v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2)) + d := dv.Enum() + val.SetUint(uint64(v ^ d)) + case schema.Type_Which_uint32: + v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4)) + d := dv.Uint32() + val.SetUint(uint64(v ^ d)) + case schema.Type_Which_uint64: + v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8)) + d := dv.Uint64() + val.SetUint(v ^ d) + case schema.Type_Which_float32: + v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4)) + d := math.Float32bits(dv.Float32()) + val.SetFloat(float64(math.Float32frombits(v ^ d))) + case schema.Type_Which_float64: + v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8)) + d := math.Float64bits(dv.Float64()) + val.SetFloat(math.Float64frombits(v ^ d)) + case schema.Type_Which_text: + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + var b []byte + if p.IsValid() { + b = p.TextBytes() + } else { + b, _ = dv.TextBytes() + } + if val.Kind() == reflect.String { + val.SetString(string(b)) + } else { + // byte slice, as guaranteed by isTypeMatch + val.SetBytes(b) + } + case schema.Type_Which_data: + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + var b []byte + if p.IsValid() { + b = p.Data() + } else { + b, _ = dv.Data() + } + val.SetBytes(b) + case schema.Type_Which_structType: + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + ss := p.Struct() + if !ss.IsValid() { + p, _ = dv.StructValuePtr() + ss = p.Struct() + } + return e.extractStruct(val, typ.StructType().TypeId(), ss) + case schema.Type_Which_list: + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + l := p.List() + if !l.IsValid() { + p, _ = dv.ListPtr() + l = p.List() + } + return e.extractList(val, typ, l) + case schema.Type_Which_interface: + p, err := s.Ptr(uint16(f.Slot().Offset())) + if err != nil { + return err + } + if val.Type() != clientType { + // Must be a struct wrapper. + val = val.FieldByName("Client") + } + + client := p.Interface().Client() + if client == nil { + val.Set(reflect.Zero(val.Type())) + } else { + val.Set(reflect.ValueOf(client)) + } + default: + return fmt.Errorf("unknown field type %v", typ.Which()) + } + return nil +} + +func (e *extracter) extractList(val reflect.Value, typ schema.Type, l capnp.List) error { + vt := val.Type() + elem, err := typ.List().ElementType() + if err != nil { + return err + } + if !isTypeMatch(vt, typ) { + // TODO(light): the error won't be that useful for nested lists. + return fmt.Errorf("can't extract %v list into a Go %v", elem.Which(), vt) + } + if !l.IsValid() { + val.Set(reflect.Zero(vt)) + return nil + } + n := l.Len() + val.Set(reflect.MakeSlice(vt, n, n)) + switch elem.Which() { + case schema.Type_Which_bool: + for i := 0; i < n; i++ { + val.Index(i).SetBool(capnp.BitList{List: l}.At(i)) + } + case schema.Type_Which_int8: + for i := 0; i < n; i++ { + val.Index(i).SetInt(int64(capnp.Int8List{List: l}.At(i))) + } + case schema.Type_Which_int16: + for i := 0; i < n; i++ { + val.Index(i).SetInt(int64(capnp.Int16List{List: l}.At(i))) + } + case schema.Type_Which_int32: + for i := 0; i < n; i++ { + val.Index(i).SetInt(int64(capnp.Int32List{List: l}.At(i))) + } + case schema.Type_Which_int64: + for i := 0; i < n; i++ { + val.Index(i).SetInt(capnp.Int64List{List: l}.At(i)) + } + case schema.Type_Which_uint8: + for i := 0; i < n; i++ { + val.Index(i).SetUint(uint64(capnp.UInt8List{List: l}.At(i))) + } + case schema.Type_Which_uint16, schema.Type_Which_enum: + for i := 0; i < n; i++ { + val.Index(i).SetUint(uint64(capnp.UInt16List{List: l}.At(i))) + } + case schema.Type_Which_uint32: + for i := 0; i < n; i++ { + val.Index(i).SetUint(uint64(capnp.UInt32List{List: l}.At(i))) + } + case schema.Type_Which_uint64: + for i := 0; i < n; i++ { + val.Index(i).SetUint(capnp.UInt64List{List: l}.At(i)) + } + case schema.Type_Which_float32: + for i := 0; i < n; i++ { + val.Index(i).SetFloat(float64(capnp.Float32List{List: l}.At(i))) + } + case schema.Type_Which_float64: + for i := 0; i < n; i++ { + val.Index(i).SetFloat(capnp.Float64List{List: l}.At(i)) + } + case schema.Type_Which_text: + if val.Type().Elem().Kind() == reflect.String { + for i := 0; i < n; i++ { + s, err := capnp.TextList{List: l}.At(i) + if err != nil { + // TODO(light): collect errors and finish + return err + } + val.Index(i).SetString(s) + } + } else { + for i := 0; i < n; i++ { + b, err := capnp.TextList{List: l}.BytesAt(i) + if err != nil { + // TODO(light): collect errors and finish + return err + } + val.Index(i).SetBytes(b) + } + } + case schema.Type_Which_data: + for i := 0; i < n; i++ { + b, err := capnp.DataList{List: l}.At(i) + if err != nil { + // TODO(light): collect errors and finish + return err + } + val.Index(i).SetBytes(b) + } + case schema.Type_Which_list: + for i := 0; i < n; i++ { + p, err := capnp.PointerList{List: l}.PtrAt(i) + // TODO(light): collect errors and finish + if err != nil { + return err + } + if err := e.extractList(val.Index(i), elem, p.List()); err != nil { + return err + } + } + case schema.Type_Which_structType: + if val.Type().Elem().Kind() == reflect.Struct { + for i := 0; i < n; i++ { + err := e.extractStruct(val.Index(i), elem.StructType().TypeId(), l.Struct(i)) + if err != nil { + return err + } + } + } else { + for i := 0; i < n; i++ { + newval := reflect.New(val.Type().Elem().Elem()) + val.Index(i).Set(newval) + err := e.extractStruct(newval, elem.StructType().TypeId(), l.Struct(i)) + if err != nil { + return err + } + } + } + default: + return fmt.Errorf("unknown list type %v", elem.Which()) + } + return nil +} + +var typeMap = map[schema.Type_Which]reflect.Kind{ + schema.Type_Which_bool: reflect.Bool, + schema.Type_Which_int8: reflect.Int8, + schema.Type_Which_int16: reflect.Int16, + schema.Type_Which_int32: reflect.Int32, + schema.Type_Which_int64: reflect.Int64, + schema.Type_Which_uint8: reflect.Uint8, + schema.Type_Which_uint16: reflect.Uint16, + schema.Type_Which_uint32: reflect.Uint32, + schema.Type_Which_uint64: reflect.Uint64, + schema.Type_Which_float32: reflect.Float32, + schema.Type_Which_float64: reflect.Float64, + schema.Type_Which_enum: reflect.Uint16, +} + +func isTypeMatch(r reflect.Type, s schema.Type) bool { + switch s.Which() { + case schema.Type_Which_text: + return r.Kind() == reflect.String || r.Kind() == reflect.Slice && r.Elem().Kind() == reflect.Uint8 + case schema.Type_Which_data: + return r.Kind() == reflect.Slice && r.Elem().Kind() == reflect.Uint8 + case schema.Type_Which_structType: + return isStructOrStructPtr(r) + case schema.Type_Which_list: + e, _ := s.List().ElementType() + return r.Kind() == reflect.Slice && isTypeMatch(r.Elem(), e) + case schema.Type_Which_interface: + if r == clientType { + return true + } + + // Otherwise, the type must be a struct with one element named + // "Client" of type capnp.Client. + if r.Kind() != reflect.Struct { + return false + } + if r.NumField() != 1 { + return false + } + field, ok := r.FieldByName("Client") + if !ok { + return false + } + return field.Type == clientType + } + k, ok := typeMap[s.Which()] + return ok && k == r.Kind() +} diff --git a/vendor/zombiezen.com/go/capnproto2/pogs/fields.go b/vendor/zombiezen.com/go/capnproto2/pogs/fields.go new file mode 100644 index 00000000..9226cbd0 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/pogs/fields.go @@ -0,0 +1,350 @@ +package pogs + +import ( + "fmt" + "reflect" + "strings" + + "zombiezen.com/go/capnproto2/internal/schema" +) + +type fieldProps struct { + schemaName string // empty if doesn't map to schema + typ fieldType + fixedWhich string + tagged bool +} + +type fieldType int + +const ( + mappedField fieldType = iota + whichField + embedField +) + +func parseField(f reflect.StructField, hasDiscrim bool) fieldProps { + var p fieldProps + tag := f.Tag.Get("capnp") + p.tagged = tag != "" + tname, opts := nextOpt(tag) + switch tname { + case "-": + // omitted field + case "": + if f.Anonymous && isStructOrStructPtr(f.Type) { + p.typ = embedField + return p + } + if hasDiscrim && f.Name == "Which" { + p.typ = whichField + for len(opts) > 0 { + var curr string + curr, opts = nextOpt(opts) + if strings.HasPrefix(curr, "which=") { + p.fixedWhich = strings.TrimPrefix(curr, "which=") + break + } + } + return p + } + // TODO(light): check it's uppercase. + x := f.Name[0] - 'A' + 'a' + p.schemaName = string(x) + f.Name[1:] + default: + p.schemaName = tname + } + return p +} + +func nextOpt(opts string) (head, tail string) { + i := strings.Index(opts, ",") + if i == -1 { + return opts, "" + } + return opts[:i], opts[i+1:] +} + +type fieldLoc struct { + i int + path []int +} + +func (loc fieldLoc) depth() int { + if len(loc.path) > 0 { + return len(loc.path) + } + return 1 +} + +func (loc fieldLoc) sub(i int) fieldLoc { + n := len(loc.path) + switch { + case !loc.isValid(): + return fieldLoc{i: i} + case n > 0: + p := make([]int, n+1) + copy(p, loc.path) + p[n] = i + return fieldLoc{path: p} + default: + return fieldLoc{path: []int{loc.i, i}} + } +} + +func (loc fieldLoc) isValid() bool { + return loc.i >= 0 +} + +type structProps struct { + fields []fieldLoc + whichLoc fieldLoc // i == -1: none; i == -2: fixed + fixedWhich uint16 +} + +func mapStruct(t reflect.Type, n schema.Node) (structProps, error) { + fields, err := n.StructNode().Fields() + if err != nil { + return structProps{}, err + } + sp := structProps{ + fields: make([]fieldLoc, fields.Len()), + whichLoc: fieldLoc{i: -1}, + } + for i := range sp.fields { + sp.fields[i] = fieldLoc{i: -1} + } + sm := structMapper{ + sp: &sp, + t: t, + hasDiscrim: hasDiscriminant(n), + fields: fields, + } + if err := sm.visit(fieldLoc{i: -1}); err != nil { + return structProps{}, err + } + for len(sm.embedQueue) > 0 { + loc := sm.embedQueue[0] + copy(sm.embedQueue, sm.embedQueue[1:]) + sm.embedQueue = sm.embedQueue[:len(sm.embedQueue)-1] + if err := sm.visit(loc); err != nil { + return structProps{}, err + } + } + return sp, nil +} + +type structMapper struct { + sp *structProps + t reflect.Type + hasDiscrim bool + fields schema.Field_List + embedQueue []fieldLoc +} + +func (sm *structMapper) visit(base fieldLoc) error { + t := sm.t + if base.isValid() { + t = typeFieldByLoc(t, base).Type + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + } + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.PkgPath != "" && !f.Anonymous { + // unexported field + continue + } + loc := base.sub(i) + p := parseField(f, sm.hasDiscrim) + if p.typ == embedField { + sm.embedQueue = append(sm.embedQueue, loc) + continue + } + if err := sm.visitField(loc, f, p); err != nil { + return err + } + } + return nil +} + +func (sm *structMapper) visitField(loc fieldLoc, f reflect.StructField, p fieldProps) error { + switch p.typ { + case mappedField: + if p.schemaName == "" { + return nil + } + fi := fieldIndex(sm.fields, p.schemaName) + if fi < 0 { + return fmt.Errorf("%v has unknown field %s, maps to %s", sm.t, f.Name, p.schemaName) + } + switch oldloc := sm.sp.fields[fi]; { + case oldloc.i == -2: + // Prior tag collision, do nothing. + case oldloc.i == -3 && p.tagged && loc.depth() == len(oldloc.path): + // A tagged field wins over untagged fields. + sm.sp.fields[fi] = loc + case oldloc.isValid() && oldloc.depth() < loc.depth(): + // This is deeper, don't override. + case oldloc.isValid() && oldloc.depth() == loc.depth(): + oldp := parseField(typeFieldByLoc(sm.t, oldloc), sm.hasDiscrim) + if oldp.tagged && p.tagged { + // Tag collision + sm.sp.fields[fi] = fieldLoc{i: -2} + } else if p.tagged { + sm.sp.fields[fi] = loc + } else if !oldp.tagged { + // Multiple untagged fields. Keep path, because we need it for depth. + sm.sp.fields[fi].i = -3 + } + default: + sm.sp.fields[fi] = loc + } + case whichField: + if sm.sp.whichLoc.i != -1 { + return fmt.Errorf("%v embeds multiple Which fields", sm.t) + } + switch { + case p.fixedWhich != "": + fi := fieldIndex(sm.fields, p.fixedWhich) + if fi < 0 { + return fmt.Errorf("%v.Which is tagged with unknown field %s", sm.t, p.fixedWhich) + } + dv := sm.fields.At(fi).DiscriminantValue() + if dv == schema.Field_noDiscriminant { + return fmt.Errorf("%v.Which is tagged with non-union field %s", sm.t, p.fixedWhich) + } + sm.sp.whichLoc = fieldLoc{i: -2} + sm.sp.fixedWhich = dv + case f.Type.Kind() != reflect.Uint16: + return fmt.Errorf("%v.Which is type %v, not uint16", sm.t, f.Type) + default: + sm.sp.whichLoc = loc + } + } + return nil +} + +// fieldBySchemaName returns the field for the given name. +// Returns an invalid value if the field was not found or it is +// contained inside a nil anonymous struct pointer. +func (sp structProps) fieldByOrdinal(val reflect.Value, i int) reflect.Value { + return fieldByLoc(val, sp.fields[i], false) +} + +// makeFieldBySchemaName returns the field for the given name, creating +// its parent anonymous structs if necessary. Returns an invalid value +// if the field was not found. +func (sp structProps) makeFieldByOrdinal(val reflect.Value, i int) reflect.Value { + return fieldByLoc(val, sp.fields[i], true) +} + +// which returns the value of the discriminator field. +func (sp structProps) which(val reflect.Value) (discrim uint16, ok bool) { + if sp.whichLoc.i == -2 { + return sp.fixedWhich, true + } + f := fieldByLoc(val, sp.whichLoc, false) + if !f.IsValid() { + return 0, false + } + return uint16(f.Uint()), true +} + +// setWhich sets the value of the discriminator field, creating its +// parent anonymous structs if necessary. Returns whether the struct +// had a field to set. +func (sp structProps) setWhich(val reflect.Value, discrim uint16) error { + if sp.whichLoc.i == -2 { + if discrim != sp.fixedWhich { + return fmt.Errorf("extract union field @%d into %v; expected @%d", discrim, val.Type(), sp.fixedWhich) + } + return nil + } + f := fieldByLoc(val, sp.whichLoc, true) + if !f.IsValid() { + return noWhichError{val.Type()} + } + f.SetUint(uint64(discrim)) + return nil +} + +type noWhichError struct { + t reflect.Type +} + +func (e noWhichError) Error() string { + return fmt.Sprintf("%v has no field Which", e.t) +} + +func isNoWhichError(e error) bool { + _, ok := e.(noWhichError) + return ok +} + +func fieldByLoc(val reflect.Value, loc fieldLoc, mkparents bool) reflect.Value { + if !loc.isValid() { + return reflect.Value{} + } + if len(loc.path) > 0 { + for i, x := range loc.path { + if i > 0 { + if val.Kind() == reflect.Ptr { + if val.IsNil() { + if !mkparents { + return reflect.Value{} + } + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + } + val = val.Field(x) + } + return val + } + return val.Field(loc.i) +} + +func typeFieldByLoc(t reflect.Type, loc fieldLoc) reflect.StructField { + if len(loc.path) > 0 { + return t.FieldByIndex(loc.path) + } + return t.Field(loc.i) +} + +func hasDiscriminant(n schema.Node) bool { + return n.Which() == schema.Node_Which_structNode && n.StructNode().DiscriminantCount() > 0 +} + +func shortDisplayName(n schema.Node) []byte { + dn, _ := n.DisplayNameBytes() + return dn[n.DisplayNamePrefixLength():] +} + +func fieldIndex(fields schema.Field_List, name string) int { + for i := 0; i < fields.Len(); i++ { + b, _ := fields.At(i).NameBytes() + if bytesStrEqual(b, name) { + return i + } + } + return -1 +} + +func bytesStrEqual(b []byte, s string) bool { + if len(b) != len(s) { + return false + } + for i := range b { + if b[i] != s[i] { + return false + } + } + return true +} + +func isStructOrStructPtr(t reflect.Type) bool { + return t.Kind() == reflect.Struct || t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct +} diff --git a/vendor/zombiezen.com/go/capnproto2/pogs/insert.go b/vendor/zombiezen.com/go/capnproto2/pogs/insert.go new file mode 100644 index 00000000..83074ad4 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/pogs/insert.go @@ -0,0 +1,485 @@ +package pogs + +import ( + "fmt" + "math" + "reflect" + + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/nodemap" + "zombiezen.com/go/capnproto2/internal/schema" +) + +// Insert copies val, a pointer to a Go struct, into s. +func Insert(typeID uint64, s capnp.Struct, val interface{}) error { + ins := new(inserter) + err := ins.insertStruct(typeID, s, reflect.ValueOf(val)) + if err != nil { + return fmt.Errorf("pogs: insert @%#x: %v", typeID, err) + } + return nil +} + +type inserter struct { + nodes nodemap.Map +} + +func (ins *inserter) insertStruct(typeID uint64, s capnp.Struct, val reflect.Value) error { + if val.Kind() == reflect.Ptr { + // TODO(light): ignore if nil? + val = val.Elem() + } + if val.Kind() != reflect.Struct { + return fmt.Errorf("can't insert %v into a struct", val.Kind()) + } + n, err := ins.nodes.Find(typeID) + if err != nil { + return err + } + if !n.IsValid() || n.Which() != schema.Node_Which_structNode { + return fmt.Errorf("cannot find struct type %#x", typeID) + } + props, err := mapStruct(val.Type(), n) + if err != nil { + return fmt.Errorf("can't insert into %v: %v", val.Type(), err) + } + var discriminant uint16 + hasWhich := false + if hasDiscriminant(n) { + discriminant, hasWhich = props.which(val) + if hasWhich { + off := capnp.DataOffset(n.StructNode().DiscriminantOffset() * 2) + if s.Size().DataSize < capnp.Size(off+2) { + return fmt.Errorf("can't set discriminant for %s: allocated struct is too small", shortDisplayName(n)) + } + s.SetUint16(off, discriminant) + } + } + fields, err := n.StructNode().Fields() + if err != nil { + return err + } + for i := 0; i < fields.Len(); i++ { + f := fields.At(i) + vf := props.fieldByOrdinal(val, i) + if !vf.IsValid() { + // Don't have a field for this. + continue + } + if dv := f.DiscriminantValue(); dv != schema.Field_noDiscriminant { + if !hasWhich { + sname, _ := f.NameBytes() + return fmt.Errorf("can't insert %s from %v: has union field %s but no Which field", shortDisplayName(n), val.Type(), sname) + } + if dv != discriminant { + continue + } + } + switch f.Which() { + case schema.Field_Which_slot: + if err := ins.insertField(s, f, vf); err != nil { + return err + } + case schema.Field_Which_group: + if err := ins.insertStruct(f.Group().TypeId(), s, vf); err != nil { + return err + } + } + } + return nil +} + +func (ins *inserter) insertField(s capnp.Struct, f schema.Field, val reflect.Value) error { + typ, err := f.Slot().Type() + if err != nil { + return err + } + dv, err := f.Slot().DefaultValue() + if err != nil { + return err + } + if dv.IsValid() && int(typ.Which()) != int(dv.Which()) { + name, _ := f.NameBytes() + return fmt.Errorf("insert field %s: default value is a %v, want %v", name, dv.Which(), typ.Which()) + } + if !isTypeMatch(val.Type(), typ) { + name, _ := f.NameBytes() + return fmt.Errorf("can't insert field %s of type Go %v into a %v", name, val.Type(), typ.Which()) + } + if !isFieldInBounds(s.Size(), f.Slot().Offset(), typ) { + name, _ := f.NameBytes() + return fmt.Errorf("can't insert field %s: allocated struct is too small", name) + } + switch typ.Which() { + case schema.Type_Which_bool: + v := val.Bool() + d := dv.Bool() + s.SetBit(capnp.BitOffset(f.Slot().Offset()), v != d) // != acts as XOR + case schema.Type_Which_int8: + v := int8(val.Int()) + d := dv.Int8() + s.SetUint8(capnp.DataOffset(f.Slot().Offset()), uint8(v^d)) + case schema.Type_Which_int16: + v := int16(val.Int()) + d := dv.Int16() + s.SetUint16(capnp.DataOffset(f.Slot().Offset()*2), uint16(v^d)) + case schema.Type_Which_int32: + v := int32(val.Int()) + d := dv.Int32() + s.SetUint32(capnp.DataOffset(f.Slot().Offset()*4), uint32(v^d)) + case schema.Type_Which_int64: + v := val.Int() + d := dv.Int64() + s.SetUint64(capnp.DataOffset(f.Slot().Offset()*8), uint64(v^d)) + case schema.Type_Which_uint8: + v := uint8(val.Uint()) + d := dv.Uint8() + s.SetUint8(capnp.DataOffset(f.Slot().Offset()), v^d) + case schema.Type_Which_uint16: + v := uint16(val.Uint()) + d := dv.Uint16() + s.SetUint16(capnp.DataOffset(f.Slot().Offset()*2), v^d) + case schema.Type_Which_enum: + v := uint16(val.Uint()) + d := dv.Enum() + s.SetUint16(capnp.DataOffset(f.Slot().Offset()*2), v^d) + case schema.Type_Which_uint32: + v := uint32(val.Uint()) + d := dv.Uint32() + s.SetUint32(capnp.DataOffset(f.Slot().Offset()*4), v^d) + case schema.Type_Which_uint64: + v := val.Uint() + d := dv.Uint64() + s.SetUint64(capnp.DataOffset(f.Slot().Offset()*8), v^d) + case schema.Type_Which_float32: + v := math.Float32bits(float32(val.Float())) + d := math.Float32bits(dv.Float32()) + s.SetUint32(capnp.DataOffset(f.Slot().Offset()*4), v^d) + case schema.Type_Which_float64: + v := math.Float64bits(val.Float()) + d := uint64(math.Float64bits(dv.Float64())) + s.SetUint64(capnp.DataOffset(f.Slot().Offset()*8), v^d) + case schema.Type_Which_text: + off := uint16(f.Slot().Offset()) + if val.Len() == 0 { + if !isEmptyValue(dv) { + return s.SetNewText(off, "") + } + return s.SetText(off, "") + } + if val.Kind() == reflect.String { + return s.SetText(off, val.String()) + } else { + return s.SetTextFromBytes(off, val.Bytes()) + } + case schema.Type_Which_data: + b := val.Bytes() + if b == nil && !isEmptyValue(dv) { + b = []byte{} + } + off := uint16(f.Slot().Offset()) + return s.SetData(off, b) + case schema.Type_Which_structType: + off := uint16(f.Slot().Offset()) + sval := val + if val.Kind() == reflect.Ptr { + if val.IsNil() { + return s.SetPtr(off, capnp.Ptr{}) + } + sval = val.Elem() + } + id := typ.StructType().TypeId() + sz, err := ins.structSize(id) + if err != nil { + return err + } + ss, err := capnp.NewStruct(s.Segment(), sz) + if err != nil { + return err + } + if err := s.SetPtr(off, ss.ToPtr()); err != nil { + return err + } + return ins.insertStruct(id, ss, sval) + case schema.Type_Which_list: + off := uint16(f.Slot().Offset()) + if val.IsNil() && isEmptyValue(dv) { + return s.SetPtr(off, capnp.Ptr{}) + } + elem, err := typ.List().ElementType() + if err != nil { + return err + } + l, err := ins.newList(s.Segment(), elem, int32(val.Len())) + if err != nil { + return err + } + if err := s.SetPtr(off, l.ToPtr()); err != nil { + return err + } + return ins.insertList(l, typ, val) + case schema.Type_Which_interface: + off := uint16(f.Slot().Offset()) + ptr := capPtr(s.Segment(), val) + if err := s.SetPtr(off, ptr); err != nil { + return err + } + default: + return fmt.Errorf("unknown field type %v", typ.Which()) + } + return nil +} + +func capPtr(seg *capnp.Segment, val reflect.Value) capnp.Ptr { + client, ok := val.Interface().(capnp.Client) + if !ok { + client, ok = val.FieldByName("Client").Interface().(capnp.Client) + if !ok { + // interface is nil. + return capnp.Ptr{} + } + } + cap := seg.Message().AddCap(client) + iface := capnp.NewInterface(seg, cap) + return iface.ToPtr() +} + +func (ins *inserter) insertList(l capnp.List, typ schema.Type, val reflect.Value) error { + elem, err := typ.List().ElementType() + if err != nil { + return err + } + if !isTypeMatch(val.Type(), typ) { + // TODO(light): the error won't be that useful for nested lists. + return fmt.Errorf("can't insert Go %v into a %v list", val.Type(), elem.Which()) + } + n := val.Len() + switch elem.Which() { + case schema.Type_Which_void: + case schema.Type_Which_bool: + for i := 0; i < n; i++ { + capnp.BitList{List: l}.Set(i, val.Index(i).Bool()) + } + case schema.Type_Which_int8: + for i := 0; i < n; i++ { + capnp.Int8List{List: l}.Set(i, int8(val.Index(i).Int())) + } + case schema.Type_Which_int16: + for i := 0; i < n; i++ { + capnp.Int16List{List: l}.Set(i, int16(val.Index(i).Int())) + } + case schema.Type_Which_int32: + for i := 0; i < n; i++ { + capnp.Int32List{List: l}.Set(i, int32(val.Index(i).Int())) + } + case schema.Type_Which_int64: + for i := 0; i < n; i++ { + capnp.Int64List{List: l}.Set(i, val.Index(i).Int()) + } + case schema.Type_Which_uint8: + for i := 0; i < n; i++ { + capnp.UInt8List{List: l}.Set(i, uint8(val.Index(i).Uint())) + } + case schema.Type_Which_uint16, schema.Type_Which_enum: + for i := 0; i < n; i++ { + capnp.UInt16List{List: l}.Set(i, uint16(val.Index(i).Uint())) + } + case schema.Type_Which_uint32: + for i := 0; i < n; i++ { + capnp.UInt32List{List: l}.Set(i, uint32(val.Index(i).Uint())) + } + case schema.Type_Which_uint64: + for i := 0; i < n; i++ { + capnp.UInt64List{List: l}.Set(i, val.Index(i).Uint()) + } + case schema.Type_Which_float32: + for i := 0; i < n; i++ { + capnp.Float32List{List: l}.Set(i, float32(val.Index(i).Float())) + } + case schema.Type_Which_float64: + for i := 0; i < n; i++ { + capnp.Float64List{List: l}.Set(i, val.Index(i).Float()) + } + case schema.Type_Which_text: + if val.Type().Elem().Kind() == reflect.String { + for i := 0; i < n; i++ { + err := capnp.TextList{List: l}.Set(i, val.Index(i).String()) + if err != nil { + // TODO(light): collect errors and finish + return err + } + } + } else { + for i := 0; i < n; i++ { + b := val.Index(i).Bytes() + if len(b) == 0 { + err := capnp.PointerList{List: l}.SetPtr(i, capnp.Ptr{}) + if err != nil { + // TODO(light): collect errors and finish + return err + } + } + t, err := capnp.NewTextFromBytes(l.Segment(), b) + if err != nil { + // TODO(light): collect errors and finish + return err + } + err = capnp.PointerList{List: l}.SetPtr(i, t.ToPtr()) + if err != nil { + // TODO(light): collect errors and finish + return err + } + } + } + case schema.Type_Which_data: + for i := 0; i < n; i++ { + b := val.Index(i).Bytes() + if len(b) == 0 { + err := capnp.PointerList{List: l}.SetPtr(i, capnp.Ptr{}) + if err != nil { + // TODO(light): collect errors and finish + return err + } + } + err := capnp.DataList{List: l}.Set(i, b) + if err != nil { + // TODO(light): collect errors and finish + return err + } + } + case schema.Type_Which_list: + pl := capnp.PointerList{List: l} + for i := 0; i < n; i++ { + vi := val.Index(i) + if vi.IsNil() { + if err := pl.SetPtr(i, capnp.Ptr{}); err != nil { + return err + } + continue + } + ee, err := elem.List().ElementType() + if err != nil { + return err + } + li, err := ins.newList(l.Segment(), ee, int32(vi.Len())) + if err != nil { + return err + } + if err := pl.SetPtr(i, li.ToPtr()); err != nil { + return err + } + if err := ins.insertList(li, elem, vi); err != nil { + return err + } + } + case schema.Type_Which_structType: + id := elem.StructType().TypeId() + for i := 0; i < n; i++ { + err := ins.insertStruct(id, l.Struct(i), val.Index(i)) + if err != nil { + // TODO(light): collect errors and finish + return err + } + } + case schema.Type_Which_interface: + pl := capnp.PointerList{List: l} + for i := 0; i < n; i++ { + ptr := capPtr(l.Segment(), val.Index(i)) + if err := pl.SetPtr(i, ptr); err != nil { + // TODO(zenhack): collect errors and finish + return err + } + } + default: + return fmt.Errorf("unknown list type %v", elem.Which()) + } + return nil +} + +func (ins *inserter) newList(s *capnp.Segment, t schema.Type, len int32) (capnp.List, error) { + switch t.Which() { + case schema.Type_Which_void: + l := capnp.NewVoidList(s, len) + return l.List, nil + case schema.Type_Which_bool: + l, err := capnp.NewBitList(s, len) + return l.List, err + case schema.Type_Which_int8, schema.Type_Which_uint8: + l, err := capnp.NewUInt8List(s, len) + return l.List, err + case schema.Type_Which_int16, schema.Type_Which_uint16, schema.Type_Which_enum: + l, err := capnp.NewUInt16List(s, len) + return l.List, err + case schema.Type_Which_int32, schema.Type_Which_uint32, schema.Type_Which_float32: + l, err := capnp.NewUInt32List(s, len) + return l.List, err + case schema.Type_Which_int64, schema.Type_Which_uint64, schema.Type_Which_float64: + l, err := capnp.NewUInt64List(s, len) + return l.List, err + case schema.Type_Which_text, schema.Type_Which_data, schema.Type_Which_list, schema.Type_Which_interface, schema.Type_Which_anyPointer: + l, err := capnp.NewPointerList(s, len) + return l.List, err + case schema.Type_Which_structType: + sz, err := ins.structSize(t.StructType().TypeId()) + if err != nil { + return capnp.List{}, err + } + return capnp.NewCompositeList(s, sz, len) + default: + return capnp.List{}, fmt.Errorf("new list: unknown element type: %v", t.Which()) + } +} + +func (ins *inserter) structSize(id uint64) (capnp.ObjectSize, error) { + n, err := ins.nodes.Find(id) + if err != nil { + return capnp.ObjectSize{}, err + } + if n.Which() != schema.Node_Which_structNode { + return capnp.ObjectSize{}, fmt.Errorf("insert struct: sizing: node @%#x is not a struct", id) + } + return capnp.ObjectSize{ + DataSize: capnp.Size(n.StructNode().DataWordCount()) * 8, + PointerCount: n.StructNode().PointerCount(), + }, nil +} + +func isFieldInBounds(sz capnp.ObjectSize, off uint32, t schema.Type) bool { + switch t.Which() { + case schema.Type_Which_void: + return true + case schema.Type_Which_bool: + return sz.DataSize >= capnp.Size(off/8+1) + case schema.Type_Which_int8, schema.Type_Which_uint8: + return sz.DataSize >= capnp.Size(off+1) + case schema.Type_Which_int16, schema.Type_Which_uint16, schema.Type_Which_enum: + return sz.DataSize >= capnp.Size(off+1)*2 + case schema.Type_Which_int32, schema.Type_Which_uint32, schema.Type_Which_float32: + return sz.DataSize >= capnp.Size(off+1)*4 + case schema.Type_Which_int64, schema.Type_Which_uint64, schema.Type_Which_float64: + return sz.DataSize >= capnp.Size(off+1)*8 + case schema.Type_Which_text, schema.Type_Which_data, schema.Type_Which_list, schema.Type_Which_structType, schema.Type_Which_interface, schema.Type_Which_anyPointer: + return sz.PointerCount >= uint16(off+1) + default: + return false + } +} + +func isEmptyValue(v schema.Value) bool { + if !v.IsValid() { + return false + } + switch v.Which() { + case schema.Value_Which_text: + b, _ := v.TextBytes() + return len(b) == 0 + case schema.Value_Which_data: + b, _ := v.Data() + return len(b) == 0 + case schema.Value_Which_list: + p, _ := v.ListPtr() + return p.List().Len() == 0 + default: + return false + } +} diff --git a/vendor/zombiezen.com/go/capnproto2/pointer.go b/vendor/zombiezen.com/go/capnproto2/pointer.go new file mode 100644 index 00000000..6aa7ea8d --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/pointer.go @@ -0,0 +1,304 @@ +package capnp + +// A Ptr is a reference to a Cap'n Proto struct, list, or interface. +// The zero value is a null pointer. +type Ptr struct { + seg *Segment + off Address + lenOrCap uint32 + size ObjectSize + depthLimit uint + flags ptrFlags +} + +func toPtr(p Pointer) Ptr { + if p == nil { + return Ptr{} + } + switch p := p.underlying().(type) { + case Struct: + return p.ToPtr() + case List: + return p.ToPtr() + case Interface: + return p.ToPtr() + } + return Ptr{} +} + +// Struct converts p to a Struct. If p does not hold a Struct pointer, +// the zero value is returned. +func (p Ptr) Struct() Struct { + if p.flags.ptrType() != structPtrType { + return Struct{} + } + return Struct{ + seg: p.seg, + off: p.off, + size: p.size, + flags: p.flags.structFlags(), + depthLimit: p.depthLimit, + } +} + +// StructDefault attempts to convert p into a struct, reading the +// default value from def if p is not a struct. +func (p Ptr) StructDefault(def []byte) (Struct, error) { + s := p.Struct() + if s.seg == nil { + if def == nil { + return Struct{}, nil + } + defp, err := unmarshalDefault(def) + if err != nil { + return Struct{}, err + } + return defp.Struct(), nil + } + return s, nil +} + +// List converts p to a List. If p does not hold a List pointer, +// the zero value is returned. +func (p Ptr) List() List { + if p.flags.ptrType() != listPtrType { + return List{} + } + return List{ + seg: p.seg, + off: p.off, + length: int32(p.lenOrCap), + size: p.size, + flags: p.flags.listFlags(), + depthLimit: p.depthLimit, + } +} + +// ListDefault attempts to convert p into a list, reading the default +// value from def if p is not a list. +func (p Ptr) ListDefault(def []byte) (List, error) { + l := p.List() + if l.seg == nil { + if def == nil { + return List{}, nil + } + defp, err := unmarshalDefault(def) + if err != nil { + return List{}, err + } + return defp.List(), nil + } + return l, nil +} + +// Interface converts p to an Interface. If p does not hold a List +// pointer, the zero value is returned. +func (p Ptr) Interface() Interface { + if p.flags.ptrType() != interfacePtrType { + return Interface{} + } + return Interface{ + seg: p.seg, + cap: CapabilityID(p.lenOrCap), + } +} + +// Text attempts to convert p into Text, returning an empty string if +// p is not a valid 1-byte list pointer. +func (p Ptr) Text() string { + b, ok := p.text() + if !ok { + return "" + } + return string(b) +} + +// TextDefault attempts to convert p into Text, returning def if p is +// not a valid 1-byte list pointer. +func (p Ptr) TextDefault(def string) string { + b, ok := p.text() + if !ok { + return def + } + return string(b) +} + +// TextBytes attempts to convert p into Text, returning nil if p is not +// a valid 1-byte list pointer. It returns a slice directly into the +// segment. +func (p Ptr) TextBytes() []byte { + b, ok := p.text() + if !ok { + return nil + } + return b +} + +// TextBytesDefault attempts to convert p into Text, returning def if p +// is not a valid 1-byte list pointer. It returns a slice directly into +// the segment. +func (p Ptr) TextBytesDefault(def string) []byte { + b, ok := p.text() + if !ok { + return []byte(def) + } + return b +} + +func (p Ptr) text() (b []byte, ok bool) { + if !isOneByteList(p) { + return nil, false + } + l := p.List() + b = l.seg.slice(l.off, Size(l.length)) + if len(b) == 0 || b[len(b)-1] != 0 { + // Text must be null-terminated. + return nil, false + } + return b[: len(b)-1 : len(b)], true +} + +// Data attempts to convert p into Data, returning nil if p is not a +// valid 1-byte list pointer. +func (p Ptr) Data() []byte { + return p.DataDefault(nil) +} + +// DataDefault attempts to convert p into Data, returning def if p is +// not a valid 1-byte list pointer. +func (p Ptr) DataDefault(def []byte) []byte { + if !isOneByteList(p) { + return def + } + l := p.List() + b := l.seg.slice(l.off, Size(l.length)) + if b == nil { + return def + } + return b +} + +func (p Ptr) toPointer() Pointer { + if p.seg == nil { + return nil + } + switch p.flags.ptrType() { + case structPtrType: + return p.Struct() + case listPtrType: + return p.List() + case interfacePtrType: + return p.Interface() + } + return nil +} + +// IsValid reports whether p is valid. +func (p Ptr) IsValid() bool { + return p.seg != nil +} + +// Segment returns the segment this pointer points into. +// If nil, then this is an invalid pointer. +func (p Ptr) Segment() *Segment { + return p.seg +} + +// Default returns p if it is valid, otherwise it unmarshals def. +func (p Ptr) Default(def []byte) (Ptr, error) { + if !p.IsValid() { + return unmarshalDefault(def) + } + return p, nil +} + +// SamePtr reports whether p and q refer to the same object. +func SamePtr(p, q Ptr) bool { + return p.seg == q.seg && p.off == q.off +} + +// A value that implements Pointer is a reference to a Cap'n Proto object. +// +// Deprecated: Using this type introduces an unnecessary allocation. +// Use Ptr instead. +type Pointer interface { + // Segment returns the segment this pointer points into. + // If nil, then this is an invalid pointer. + Segment() *Segment + + // HasData reports whether the object referenced by the pointer has + // non-zero size. + HasData() bool + + // underlying returns a Pointer that is one of a Struct, a List, or an + // Interface. + underlying() Pointer +} + +// IsValid reports whether p is valid. +// +// Deprecated: Use Ptr.IsValid instead. +func IsValid(p Pointer) bool { + return p != nil && p.Segment() != nil +} + +// HasData reports whether p has non-zero size. +// +// Deprecated: There are usually better ways to determine this +// information: length of a list, checking fields, or using HasFoo +// accessors. +func HasData(p Pointer) bool { + return IsValid(p) && p.HasData() +} + +// PointerDefault returns p if it is valid, otherwise it unmarshals def. +// +// Deprecated: Use Ptr.Default. +func PointerDefault(p Pointer, def []byte) (Pointer, error) { + pp, err := toPtr(p).Default(def) + return pp.toPointer(), err +} + +func unmarshalDefault(def []byte) (Ptr, error) { + msg, err := Unmarshal(def) + if err != nil { + return Ptr{}, err + } + p, err := msg.RootPtr() + if err != nil { + return Ptr{}, err + } + return p, nil +} + +type ptrFlags uint8 + +const interfacePtrFlag ptrFlags = interfacePtrType << 6 + +func structPtrFlag(f structFlags) ptrFlags { + return structPtrType<<6 | ptrFlags(f)&ptrLowerMask +} + +func listPtrFlag(f listFlags) ptrFlags { + return listPtrType<<6 | ptrFlags(f)&ptrLowerMask +} + +const ( + structPtrType = iota + listPtrType + interfacePtrType +) + +func (f ptrFlags) ptrType() int { + return int(f >> 6) +} + +const ptrLowerMask ptrFlags = 0x3f + +func (f ptrFlags) listFlags() listFlags { + return listFlags(f & ptrLowerMask) +} + +func (f ptrFlags) structFlags() structFlags { + return structFlags(f & ptrLowerMask) +} diff --git a/vendor/zombiezen.com/go/capnproto2/rawpointer.go b/vendor/zombiezen.com/go/capnproto2/rawpointer.go new file mode 100644 index 00000000..b72e2c3d --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rawpointer.go @@ -0,0 +1,189 @@ +package capnp + +// pointerOffset is an address offset in multiples of word size. +type pointerOffset int32 + +// resolve returns an absolute address relative to a base address. +// For near pointers, the base is the end of the near pointer. +// For far pointers, the base is zero (the beginning of the segment). +func (off pointerOffset) resolve(base Address) (_ Address, ok bool) { + if off == 0 { + return base, true + } + addr := base + Address(off*pointerOffset(wordSize)) + return addr, (addr > base || off < 0) && (addr < base || off > 0) +} + +// nearPointerOffset computes the offset for a pointer at paddr to point to addr. +func nearPointerOffset(paddr, addr Address) pointerOffset { + return pointerOffset(addr/Address(wordSize) - paddr/Address(wordSize) - 1) +} + +// rawPointer is an encoded pointer. +type rawPointer uint64 + +// rawStructPointer returns a struct pointer. The offset is from the +// end of the pointer to the start of the struct. +func rawStructPointer(off pointerOffset, sz ObjectSize) rawPointer { + return rawPointer(structPointer) | rawPointer(uint32(off)<<2) | rawPointer(sz.dataWordCount())<<32 | rawPointer(sz.PointerCount)<<48 +} + +// rawListPointer returns a list pointer. The offset is the number of +// words relative to the end of the pointer that the list starts. If +// listType is compositeList, then length is the number of words +// that the list occupies, otherwise it is the number of elements in +// the list. +func rawListPointer(off pointerOffset, listType listType, length int32) rawPointer { + return rawPointer(listPointer) | rawPointer(uint32(off)<<2) | rawPointer(listType)<<32 | rawPointer(length)<<35 +} + +// rawInterfacePointer returns an interface pointer that references +// a capability number. +func rawInterfacePointer(capability CapabilityID) rawPointer { + return rawPointer(otherPointer) | rawPointer(capability)<<32 +} + +// rawFarPointer returns a pointer to a pointer in another segment. +func rawFarPointer(segID SegmentID, off Address) rawPointer { + return rawPointer(farPointer) | rawPointer(off&^7) | (rawPointer(segID) << 32) +} + +// rawDoubleFarPointer returns a pointer to a pointer in another segment. +func rawDoubleFarPointer(segID SegmentID, off Address) rawPointer { + return rawPointer(doubleFarPointer) | rawPointer(off&^7) | (rawPointer(segID) << 32) +} + +// landingPadNearPointer converts a double-far pointer landing pad into +// a near pointer in the destination segment. Its offset will be +// relative to the beginning of the segment. tag must be either a +// struct or a list pointer. +func landingPadNearPointer(far, tag rawPointer) rawPointer { + // Replace tag's offset with far's offset. + // far's offset (29-bit unsigned) just needs to be shifted down to + // make it into a signed 30-bit value. + return tag&^0xfffffffc | rawPointer(uint32(far&^3)>>1) +} + +type pointerType int + +// Raw pointer types. +const ( + structPointer pointerType = 0 + listPointer pointerType = 1 + farPointer pointerType = 2 + doubleFarPointer pointerType = 6 + otherPointer pointerType = 3 +) + +func (p rawPointer) pointerType() pointerType { + t := pointerType(p & 3) + if t == farPointer { + return pointerType(p & 7) + } + return t +} + +func (p rawPointer) structSize() ObjectSize { + c := uint16(p >> 32) + d := uint16(p >> 48) + return ObjectSize{ + DataSize: Size(c) * wordSize, + PointerCount: d, + } +} + +type listType int + +// Raw list pointer types. +const ( + voidList listType = 0 + bit1List listType = 1 + byte1List listType = 2 + byte2List listType = 3 + byte4List listType = 4 + byte8List listType = 5 + pointerList listType = 6 + compositeList listType = 7 +) + +func (p rawPointer) listType() listType { + return listType((p >> 32) & 7) +} + +func (p rawPointer) numListElements() int32 { + return int32(p >> 35) +} + +// elementSize returns the size of an individual element in the list referenced by p. +func (p rawPointer) elementSize() ObjectSize { + switch p.listType() { + case voidList: + return ObjectSize{} + case bit1List: + // Size is ignored on bit lists. + return ObjectSize{} + case byte1List: + return ObjectSize{DataSize: 1} + case byte2List: + return ObjectSize{DataSize: 2} + case byte4List: + return ObjectSize{DataSize: 4} + case byte8List: + return ObjectSize{DataSize: 8} + case pointerList: + return ObjectSize{PointerCount: 1} + default: + panic("elementSize not supposed to be called on composite or unknown list type") + } +} + +// totalListSize returns the total size of the list referenced by p. +func (p rawPointer) totalListSize() (sz Size, ok bool) { + n := p.numListElements() + switch p.listType() { + case voidList: + return 0, true + case bit1List: + return Size((n + 7) / 8), true + case compositeList: + // For a composite list, n represents the number of words (excluding the tag word). + return wordSize.times(n + 1) + default: + return p.elementSize().totalSize().times(n) + } +} + +// offset returns a pointer's offset. Only valid for struct or list +// pointers. +func (p rawPointer) offset() pointerOffset { + return pointerOffset(int32(p) >> 2) +} + +// withOffset replaces a pointer's offset. Only valid for struct or +// list pointers. +func (p rawPointer) withOffset(off pointerOffset) rawPointer { + return p&^0xfffffffc | rawPointer(uint32(off<<2)) +} + +// farAddress returns the address of the landing pad pointer. +func (p rawPointer) farAddress() Address { + // Far pointer offset is 29 bits, starting after the low 3 bits. + // It's an unsigned word offset, which would be equivalent to a + // logical left shift by 3. + return Address(p) &^ 7 +} + +// farSegment returns the segment ID that the far pointer references. +func (p rawPointer) farSegment() SegmentID { + return SegmentID(p >> 32) +} + +// otherPointerType returns the type of "other pointer" from p. +func (p rawPointer) otherPointerType() uint32 { + return uint32(p) >> 2 +} + +// capabilityIndex returns the index of the capability in the message's capability table. +func (p rawPointer) capabilityIndex() CapabilityID { + return CapabilityID(p >> 32) +} diff --git a/vendor/zombiezen.com/go/capnproto2/readlimit.go b/vendor/zombiezen.com/go/capnproto2/readlimit.go new file mode 100644 index 00000000..1e1f9808 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/readlimit.go @@ -0,0 +1,38 @@ +package capnp + +import "sync/atomic" + +// A ReadLimiter tracks the number of bytes read from a message in order +// to avoid amplification attacks as detailed in +// https://capnproto.org/encoding.html#amplification-attack. +// It is safe to use from multiple goroutines. +type ReadLimiter struct { + limit uint64 +} + +// canRead reports whether the amount of bytes can be stored safely. +func (rl *ReadLimiter) canRead(sz Size) bool { + for { + curr := atomic.LoadUint64(&rl.limit) + ok := curr >= uint64(sz) + var new uint64 + if ok { + new = curr - uint64(sz) + } else { + new = 0 + } + if atomic.CompareAndSwapUint64(&rl.limit, curr, new) { + return ok + } + } +} + +// Reset sets the number of bytes allowed to be read. +func (rl *ReadLimiter) Reset(limit uint64) { + atomic.StoreUint64(&rl.limit, limit) +} + +// Unread increases the limit by sz. +func (rl *ReadLimiter) Unread(sz Size) { + atomic.AddUint64(&rl.limit, uint64(sz)) +} diff --git a/vendor/zombiezen.com/go/capnproto2/regen.sh b/vendor/zombiezen.com/go/capnproto2/regen.sh new file mode 100644 index 00000000..a9c6cb14 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/regen.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# regen.sh - update capnpc-go and regenerate schemas +set -euo pipefail + +cd "$(dirname "$0")" + +echo "** mktemplates" +(cd internal/cmd/mktemplates && go build -tags=mktemplates) + +echo "** capnpc-go" +# Run tests so that we don't install a broken capnpc-go. +(cd capnpc-go && go generate && go test && go install) + +echo "** schemas" +(cd std/capnp; ./gen.sh compile) +capnp compile -ogo std/go.capnp && mv std/go.capnp.go ./ +go generate ./... diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/rpc/BUILD.bazel new file mode 100644 index 00000000..1cf9c4d3 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/BUILD.bazel @@ -0,0 +1,49 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "answer.go", + "errors.go", + "introspect.go", + "log.go", + "question.go", + "rpc.go", + "tables.go", + "transport.go", + ], + importpath = "zombiezen.com/go/capnproto2/rpc", + visibility = ["//visibility:public"], + deps = [ + "//:go_default_library", + "//internal/fulfiller:go_default_library", + "//internal/queue:go_default_library", + "//rpc/internal/refcount:go_default_library", + "//std/capnp/rpc:go_default_library", + "@org_golang_x_net//context:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = [ + "bench_test.go", + "cancel_test.go", + "embargo_test.go", + "example_test.go", + "issue3_test.go", + "promise_test.go", + "release_test.go", + "rpc_test.go", + ], + embed = [":go_default_library"], + deps = [ + "//:go_default_library", + "//rpc/internal/logtransport:go_default_library", + "//rpc/internal/pipetransport:go_default_library", + "//rpc/internal/testcapnp:go_default_library", + "//server:go_default_library", + "//std/capnp/rpc:go_default_library", + "@org_golang_x_net//context:go_default_library", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/answer.go b/vendor/zombiezen.com/go/capnproto2/rpc/answer.go new file mode 100644 index 00000000..3daa4737 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/answer.go @@ -0,0 +1,498 @@ +package rpc + +import ( + "errors" + "sync" + + "golang.org/x/net/context" + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/fulfiller" + "zombiezen.com/go/capnproto2/internal/queue" + rpccapnp "zombiezen.com/go/capnproto2/std/capnp/rpc" +) + +// callQueueSize is the maximum number of calls that can be queued per answer or client. +// TODO(light): make this a ConnOption +const callQueueSize = 64 + +// insertAnswer creates a new answer with the given ID, returning nil +// if the ID is already in use. +func (c *Conn) insertAnswer(id answerID, cancel context.CancelFunc) *answer { + if c.answers == nil { + c.answers = make(map[answerID]*answer) + } else if _, exists := c.answers[id]; exists { + return nil + } + a := &answer{ + id: id, + cancel: cancel, + conn: c, + resolved: make(chan struct{}), + queue: make([]pcall, 0, callQueueSize), + } + c.answers[id] = a + return a +} + +func (c *Conn) popAnswer(id answerID) *answer { + if c.answers == nil { + return nil + } + a := c.answers[id] + delete(c.answers, id) + return a +} + +type answer struct { + id answerID + cancel context.CancelFunc + resultCaps []exportID + conn *Conn + resolved chan struct{} + + mu sync.RWMutex + obj capnp.Ptr + err error + done bool + queue []pcall +} + +// fulfill is called to resolve an answer successfully. It returns an +// error if its connection is shut down while sending messages. The +// caller must be holding onto a.conn.mu. +func (a *answer) fulfill(obj capnp.Ptr) error { + a.mu.Lock() + if a.done { + panic("answer.fulfill called more than once") + } + a.obj, a.done = obj, true + // TODO(light): populate resultCaps + + var firstErr error + if err := a.conn.startWork(); err != nil { + firstErr = err + for i := range a.queue { + a.queue[i].a.reject(err) + } + a.queue = nil + } else { + retmsg := newReturnMessage(nil, a.id) + ret, _ := retmsg.Return() + payload, _ := ret.NewResults() + payload.SetContentPtr(obj) + if payloadTab, err := a.conn.makeCapTable(ret.Segment()); err != nil { + firstErr = err + } else { + payload.SetCapTable(payloadTab) + if err := a.conn.sendMessage(retmsg); err != nil { + firstErr = err + } + } + + queues, err := a.emptyQueue(obj) + if err != nil && firstErr == nil { + firstErr = err + } + ctab := obj.Segment().Message().CapTable + for capIdx, q := range queues { + ctab[capIdx] = newQueueClient(a.conn, ctab[capIdx], q) + } + a.conn.workers.Done() + } + close(a.resolved) + a.mu.Unlock() + return firstErr +} + +// reject is called to resolve an answer with failure. It returns an +// error if its connection is shut down while sending messages. The +// caller must be holding onto a.conn.mu. +func (a *answer) reject(err error) error { + if err == nil { + panic("answer.reject called with nil") + } + a.mu.Lock() + if a.done { + panic("answer.reject called more than once") + } + a.err, a.done = err, true + m := newReturnMessage(nil, a.id) + mret, _ := m.Return() + setReturnException(mret, err) + var firstErr error + if err := a.conn.sendMessage(m); err != nil { + firstErr = err + } + for i := range a.queue { + if err := a.queue[i].a.reject(err); err != nil && firstErr == nil { + firstErr = err + } + } + a.queue = nil + close(a.resolved) + a.mu.Unlock() + return firstErr +} + +// emptyQueue splits the queue by which capability it targets +// and drops any invalid calls. Once this function returns, a.queue +// will be nil. +func (a *answer) emptyQueue(obj capnp.Ptr) (map[capnp.CapabilityID][]qcall, error) { + var firstErr error + qs := make(map[capnp.CapabilityID][]qcall, len(a.queue)) + for i, pc := range a.queue { + c, err := capnp.TransformPtr(obj, pc.transform) + if err != nil { + if err := pc.a.reject(err); err != nil && firstErr == nil { + firstErr = err + } + continue + } + ci := c.Interface() + if !ci.IsValid() { + if err := pc.a.reject(capnp.ErrNullClient); err != nil && firstErr == nil { + firstErr = err + } + continue + } + cn := ci.Capability() + if qs[cn] == nil { + qs[cn] = make([]qcall, 0, len(a.queue)-i) + } + qs[cn] = append(qs[cn], pc.qcall) + } + a.queue = nil + return qs, firstErr +} + +// queueCallLocked enqueues a call to be made after the answer has been +// resolved. The answer must not be resolved yet. pc should have +// transform and one of pc.a or pc.f to be set. The caller must be +// holding onto a.mu. +func (a *answer) queueCallLocked(call *capnp.Call, pc pcall) error { + if len(a.queue) == cap(a.queue) { + return errQueueFull + } + var err error + pc.call, err = call.Copy(nil) + if err != nil { + return err + } + a.queue = append(a.queue, pc) + return nil +} + +// queueDisembargo enqueues a disembargo message. +func (a *answer) queueDisembargo(transform []capnp.PipelineOp, id embargoID, target rpccapnp.MessageTarget) (queued bool, err error) { + a.mu.Lock() + defer a.mu.Unlock() + if !a.done { + return false, errDisembargoOngoingAnswer + } + if a.err != nil { + return false, errDisembargoNonImport + } + targetPtr, err := capnp.TransformPtr(a.obj, transform) + if err != nil { + return false, err + } + client := targetPtr.Interface().Client() + qc, ok := client.(*queueClient) + if !ok { + // No need to embargo, disembargo immediately. + return false, nil + } + if ic := isImport(qc.client); ic == nil || a.conn != ic.conn { + return false, errDisembargoNonImport + } + qc.mu.Lock() + if !qc.isPassthrough() { + err = qc.pushEmbargoLocked(id, target) + if err == nil { + queued = true + } + } + qc.mu.Unlock() + return queued, err +} + +func (a *answer) pipelineClient(transform []capnp.PipelineOp) capnp.Client { + return &localAnswerClient{a: a, transform: transform} +} + +// joinAnswer resolves an RPC answer by waiting on a generic answer. +// The caller must not be holding onto a.conn.mu. +func joinAnswer(a *answer, ca capnp.Answer) { + s, err := ca.Struct() + a.conn.mu.Lock() + if err == nil { + a.fulfill(s.ToPtr()) + } else { + a.reject(err) + } + a.conn.mu.Unlock() +} + +// joinFulfiller resolves a fulfiller by waiting on a generic answer. +func joinFulfiller(f *fulfiller.Fulfiller, ca capnp.Answer) { + s, err := ca.Struct() + if err != nil { + f.Reject(err) + } else { + f.Fulfill(s) + } +} + +type queueClient struct { + client capnp.Client + conn *Conn + + mu sync.RWMutex + q queue.Queue + calls qcallList +} + +func newQueueClient(c *Conn, client capnp.Client, queue []qcall) *queueClient { + qc := &queueClient{ + client: client, + conn: c, + calls: make(qcallList, callQueueSize), + } + qc.q.Init(qc.calls, copy(qc.calls, queue)) + go qc.flushQueue() + return qc +} + +func (qc *queueClient) pushCallLocked(cl *capnp.Call) capnp.Answer { + f := new(fulfiller.Fulfiller) + cl, err := cl.Copy(nil) + if err != nil { + return capnp.ErrorAnswer(err) + } + i := qc.q.Push() + if i == -1 { + return capnp.ErrorAnswer(errQueueFull) + } + qc.calls[i] = qcall{call: cl, f: f} + return f +} + +func (qc *queueClient) pushEmbargoLocked(id embargoID, tgt rpccapnp.MessageTarget) error { + i := qc.q.Push() + if i == -1 { + return errQueueFull + } + qc.calls[i] = qcall{embargoID: id, embargoTarget: tgt} + return nil +} + +// flushQueue is run in its own goroutine. +func (qc *queueClient) flushQueue() { + var c qcall + qc.mu.RLock() + if i := qc.q.Front(); i != -1 { + c = qc.calls[i] + } + qc.mu.RUnlock() + for c.which() != qcallInvalid { + qc.handle(&c) + + qc.mu.Lock() + qc.q.Pop() + if i := qc.q.Front(); i != -1 { + c = qc.calls[i] + } else { + c = qcall{} + } + qc.mu.Unlock() + } +} + +func (qc *queueClient) handle(c *qcall) { + switch c.which() { + case qcallRemoteCall: + answer := qc.client.Call(c.call) + go joinAnswer(c.a, answer) + case qcallLocalCall: + answer := qc.client.Call(c.call) + go joinFulfiller(c.f, answer) + case qcallDisembargo: + msg := newDisembargoMessage(nil, rpccapnp.Disembargo_context_Which_receiverLoopback, c.embargoID) + d, _ := msg.Disembargo() + d.SetTarget(c.embargoTarget) + qc.conn.sendMessage(msg) + } +} + +func (qc *queueClient) isPassthrough() bool { + return qc.q.Len() == 0 +} + +func (qc *queueClient) Call(cl *capnp.Call) capnp.Answer { + // Fast path: queue is flushed. + qc.mu.RLock() + ok := qc.isPassthrough() + qc.mu.RUnlock() + if ok { + return qc.client.Call(cl) + } + + // Add to queue. + qc.mu.Lock() + // Since we released the lock, check that the queue hasn't been flushed. + if qc.isPassthrough() { + qc.mu.Unlock() + return qc.client.Call(cl) + } + ans := qc.pushCallLocked(cl) + qc.mu.Unlock() + return ans +} + +func (qc *queueClient) tryQueue(cl *capnp.Call) capnp.Answer { + qc.mu.Lock() + if qc.isPassthrough() { + qc.mu.Unlock() + return nil + } + ans := qc.pushCallLocked(cl) + qc.mu.Unlock() + return ans +} + +func (qc *queueClient) Close() error { + qc.conn.mu.Lock() + if err := qc.conn.startWork(); err != nil { + qc.conn.mu.Unlock() + return err + } + rejErr := qc.rejectQueue() + qc.conn.workers.Done() + qc.conn.mu.Unlock() + if err := qc.client.Close(); err != nil { + return err + } + return rejErr +} + +// rejectQueue drains the client's queue. It returns an error if the +// connection was shut down while messages are sent. The caller must be +// holding onto qc.conn.mu. +func (qc *queueClient) rejectQueue() error { + var firstErr error + qc.mu.Lock() + for ; qc.q.Len() > 0; qc.q.Pop() { + c := qc.calls[qc.q.Front()] + switch c.which() { + case qcallRemoteCall: + if err := c.a.reject(errQueueCallCancel); err != nil && firstErr == nil { + firstErr = err + } + case qcallLocalCall: + c.f.Reject(errQueueCallCancel) + case qcallDisembargo: + m := newDisembargoMessage(nil, rpccapnp.Disembargo_context_Which_receiverLoopback, c.embargoID) + d, _ := m.Disembargo() + d.SetTarget(c.embargoTarget) + if err := qc.conn.sendMessage(m); err != nil && firstErr == nil { + firstErr = err + } + } + } + qc.mu.Unlock() + return firstErr +} + +// pcall is a queued pipeline call. +type pcall struct { + transform []capnp.PipelineOp + qcall +} + +// qcall is a queued call. +type qcall struct { + // Calls + a *answer // non-nil if remote call + f *fulfiller.Fulfiller // non-nil if local call + call *capnp.Call + + // Disembargo + embargoID embargoID + embargoTarget rpccapnp.MessageTarget +} + +// Queued call types. +const ( + qcallInvalid = iota + qcallRemoteCall + qcallLocalCall + qcallDisembargo +) + +func (c *qcall) which() int { + switch { + case c.a != nil: + return qcallRemoteCall + case c.f != nil: + return qcallLocalCall + case c.embargoTarget.IsValid(): + return qcallDisembargo + default: + return qcallInvalid + } +} + +type qcallList []qcall + +func (ql qcallList) Len() int { + return len(ql) +} + +func (ql qcallList) Clear(i int) { + ql[i] = qcall{} +} + +// A localAnswerClient is used to provide a pipelined client of an answer. +type localAnswerClient struct { + a *answer + transform []capnp.PipelineOp +} + +func (lac *localAnswerClient) Call(call *capnp.Call) capnp.Answer { + lac.a.mu.Lock() + if lac.a.done { + obj, err := lac.a.obj, lac.a.err + lac.a.mu.Unlock() + return clientFromResolution(lac.transform, obj, err).Call(call) + } + f := new(fulfiller.Fulfiller) + err := lac.a.queueCallLocked(call, pcall{ + transform: lac.transform, + qcall: qcall{f: f}, + }) + lac.a.mu.Unlock() + if err != nil { + return capnp.ErrorAnswer(errQueueFull) + } + return f +} + +func (lac *localAnswerClient) Close() error { + lac.a.mu.RLock() + obj, err, done := lac.a.obj, lac.a.err, lac.a.done + lac.a.mu.RUnlock() + if !done { + return nil + } + client := clientFromResolution(lac.transform, obj, err) + return client.Close() +} + +var ( + errQueueFull = errors.New("rpc: pipeline queue full") + errQueueCallCancel = errors.New("rpc: queued call canceled") + + errDisembargoOngoingAnswer = errors.New("rpc: disembargo attempted on in-progress answer") + errDisembargoNonImport = errors.New("rpc: disembargo attempted on non-import capability") + errDisembargoMissingAnswer = errors.New("rpc: disembargo attempted on missing answer (finished too early?)") +) diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/errors.go b/vendor/zombiezen.com/go/capnproto2/rpc/errors.go new file mode 100644 index 00000000..26bb1420 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/errors.go @@ -0,0 +1,102 @@ +package rpc + +import ( + "errors" + "fmt" + + "zombiezen.com/go/capnproto2" + rpccapnp "zombiezen.com/go/capnproto2/std/capnp/rpc" +) + +// An Exception is a Cap'n Proto RPC error. +type Exception struct { + rpccapnp.Exception +} + +// Error returns the exception's reason. +func (e Exception) Error() string { + r, err := e.Reason() + if err != nil { + return "rpc exception" + } + return "rpc exception: " + r +} + +// An Abort is a hang-up by a remote vat. +type Abort Exception + +func copyAbort(m rpccapnp.Message) (Abort, error) { + ma, err := m.Abort() + if err != nil { + return Abort{}, err + } + msg, _, _ := capnp.NewMessage(capnp.SingleSegment(nil)) + if err := msg.SetRootPtr(ma.ToPtr()); err != nil { + return Abort{}, err + } + p, err := msg.RootPtr() + if err != nil { + return Abort{}, err + } + return Abort{rpccapnp.Exception{Struct: p.Struct()}}, nil +} + +// Error returns the exception's reason. +func (a Abort) Error() string { + r, err := a.Reason() + if err != nil { + return "rpc: aborted by remote" + } + return "rpc: aborted by remote: " + r +} + +// toException sets fields on exc to match err. +func toException(exc rpccapnp.Exception, err error) { + if ee, ok := err.(Exception); ok { + // TODO(light): copy struct + r, err := ee.Reason() + if err == nil { + exc.SetReason(r) + } + exc.SetType(ee.Type()) + return + } + + exc.SetReason(err.Error()) + exc.SetType(rpccapnp.Exception_Type_failed) +} + +// Errors +var ( + ErrConnClosed = errors.New("rpc: connection closed") +) + +// Internal errors +var ( + errQuestionReused = errors.New("rpc: question ID reused") + errNoMainInterface = errors.New("rpc: no bootstrap interface") + errBadTarget = errors.New("rpc: target not found") + errShutdown = errors.New("rpc: shutdown") + errUnimplemented = errors.New("rpc: remote used unimplemented protocol feature") +) + +type bootstrapError struct { + err error +} + +func (e bootstrapError) Error() string { + return "rpc bootstrap:" + e.err.Error() +} + +type questionError struct { + id questionID + method *capnp.Method // nil if this is bootstrap + err error +} + +func (qe *questionError) Error() string { + if qe.method == nil { + return fmt.Sprintf("bootstrap call id=%d: %v", qe.id, qe.err) + } + return fmt.Sprintf("%v call id=%d: %v", qe.method, qe.id, qe.err) +} diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/internal/refcount/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/rpc/internal/refcount/BUILD.bazel new file mode 100644 index 00000000..177ca998 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/internal/refcount/BUILD.bazel @@ -0,0 +1,16 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["refcount.go"], + importpath = "zombiezen.com/go/capnproto2/rpc/internal/refcount", + visibility = ["//rpc:__subpackages__"], + deps = ["//:go_default_library"], +) + +go_test( + name = "go_default_test", + srcs = ["refcount_test.go"], + embed = [":go_default_library"], + deps = ["//:go_default_library"], +) diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/internal/refcount/refcount.go b/vendor/zombiezen.com/go/capnproto2/rpc/internal/refcount/refcount.go new file mode 100644 index 00000000..6a17cd57 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/internal/refcount/refcount.go @@ -0,0 +1,116 @@ +// Package refcount implements a reference-counting client. +package refcount + +import ( + "errors" + "runtime" + "sync" + + "zombiezen.com/go/capnproto2" +) + +// A RefCount will close its underlying client once all its references are closed. +type RefCount struct { + Client capnp.Client + + mu sync.Mutex + refs int +} + +// New creates a reference counter and the first client reference. +func New(c capnp.Client) (rc *RefCount, ref1 capnp.Client) { + if rr, ok := c.(*Ref); ok { + return rr.rc, rr.rc.Ref() + } + rc = &RefCount{Client: c, refs: 1} + ref1 = rc.newRef() + return +} + +// Ref makes a new client reference. +func (rc *RefCount) Ref() capnp.Client { + rc.mu.Lock() + if rc.refs <= 0 { + rc.mu.Unlock() + return capnp.ErrorClient(errZeroRef) + } + rc.refs++ + rc.mu.Unlock() + return rc.newRef() +} + +func (rc *RefCount) newRef() *Ref { + r := &Ref{rc: rc} + runtime.SetFinalizer(r, (*Ref).Close) + return r +} + +func (rc *RefCount) call(cl *capnp.Call) capnp.Answer { + // We lock here so that we can prevent the client from being closed + // while we start the call. + rc.mu.Lock() + if rc.refs <= 0 { + rc.mu.Unlock() + return capnp.ErrorAnswer(errClosed) + } + ans := rc.Client.Call(cl) + rc.mu.Unlock() + return ans +} + +// decref decreases the reference count by one, closing the Client if it reaches zero. +func (rc *RefCount) decref() error { + shouldClose := false + + rc.mu.Lock() + if rc.refs <= 0 { + rc.mu.Unlock() + return errClosed + } + rc.refs-- + if rc.refs == 0 { + shouldClose = true + } + rc.mu.Unlock() + + if shouldClose { + return rc.Client.Close() + } + return nil +} + +var ( + errZeroRef = errors.New("rpc: Ref() called on zeroed refcount") + errClosed = errors.New("rpc: Close() called on closed client") +) + +// A Ref is a single reference to a client wrapped by RefCount. +type Ref struct { + rc *RefCount + once sync.Once +} + +// Call makes a call on the underlying client. +func (r *Ref) Call(cl *capnp.Call) capnp.Answer { + return r.rc.call(cl) +} + +// Client returns the underlying client. +func (r *Ref) Client() capnp.Client { + return r.rc.Client +} + +// Close decrements the reference count. Close will be called on +// finalization (i.e. garbage collection). +func (r *Ref) Close() error { + var err error + closed := false + r.once.Do(func() { + err = r.rc.decref() + closed = true + }) + if !closed { + return errClosed + } + return err +} diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/introspect.go b/vendor/zombiezen.com/go/capnproto2/rpc/introspect.go new file mode 100644 index 00000000..4b373ff9 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/introspect.go @@ -0,0 +1,347 @@ +package rpc + +import ( + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/fulfiller" + "zombiezen.com/go/capnproto2/rpc/internal/refcount" + rpccapnp "zombiezen.com/go/capnproto2/std/capnp/rpc" +) + +// While the code below looks repetitive, resist the urge to refactor. +// Each operation is distinct in assumptions it can make about +// particular cases, and there isn't a convenient type signature that +// fits all cases. + +// lockedCall is used to make a call to an arbitrary client while +// holding onto c.mu. Since the client could point back to c, naively +// calling c.Call could deadlock. +func (c *Conn) lockedCall(client capnp.Client, cl *capnp.Call) capnp.Answer { +dig: + for client := client; ; { + switch curr := client.(type) { + case *importClient: + if curr.conn != c { + // This doesn't use our conn's lock, so it is safe to call. + return curr.Call(cl) + } + return curr.lockedCall(cl) + case *fulfiller.EmbargoClient: + if ans := curr.TryQueue(cl); ans != nil { + return ans + } + client = curr.Client() + case *refcount.Ref: + client = curr.Client() + case *embargoClient: + if ans := curr.tryQueue(cl); ans != nil { + return ans + } + client = curr.client + case *queueClient: + if ans := curr.tryQueue(cl); ans != nil { + return ans + } + client = curr.client + case *localAnswerClient: + curr.a.mu.Lock() + if curr.a.done { + obj, err := curr.a.obj, curr.a.err + curr.a.mu.Unlock() + client = clientFromResolution(curr.transform, obj, err) + } else { + f := new(fulfiller.Fulfiller) + err := curr.a.queueCallLocked(cl, pcall{ + transform: curr.transform, + qcall: qcall{f: f}, + }) + curr.a.mu.Unlock() + if err != nil { + return capnp.ErrorAnswer(err) + } + return f + } + case *capnp.PipelineClient: + p := (*capnp.Pipeline)(curr) + ans := p.Answer() + transform := p.Transform() + if capnp.IsFixedAnswer(ans) { + s, err := ans.Struct() + client = clientFromResolution(transform, s.ToPtr(), err) + continue + } + switch ans := ans.(type) { + case *fulfiller.Fulfiller: + ap := ans.Peek() + if ap == nil { + break dig + } + s, err := ap.Struct() + client = clientFromResolution(transform, s.ToPtr(), err) + case *question: + if ans.conn != c { + // This doesn't use our conn's lock, so it is safe to call. + return ans.PipelineCall(transform, cl) + } + return ans.lockedPipelineCall(transform, cl) + default: + break dig + } + default: + break dig + } + } + + // TODO(light): Add a CallOption that signals to bypass sync. + // The above hack works in *most* cases. + // + // If your code is deadlocking here, you've hit the edge of the + // compromise between these three goals: + // 1) Package capnp is loosely coupled with package rpc + // 2) Arbitrary implementations of Client may exist + // 3) Local E-order must be preserved + // + // #3 is the one that creates a deadlock, since application code must + // acquire the connection mutex to preserve order of delivery. You + // can't really overcome this without breaking one of the first two + // constraints. + // + // To avoid #2 as much as possible, implementing Client is discouraged + // by several docs. + return client.Call(cl) +} + +// descriptorForClient fills desc for client, adding it to the export +// table if necessary. The caller must be holding onto c.mu. +func (c *Conn) descriptorForClient(desc rpccapnp.CapDescriptor, client capnp.Client) error { +dig: + for client := client; ; { + switch ct := client.(type) { + case *importClient: + if ct.conn != c { + break dig + } + desc.SetReceiverHosted(uint32(ct.id)) + return nil + case *fulfiller.EmbargoClient: + client = ct.Client() + if client == nil { + break dig + } + case *refcount.Ref: + client = ct.Client() + case *embargoClient: + ct.mu.RLock() + ok := ct.isPassthrough() + ct.mu.RUnlock() + if !ok { + break dig + } + client = ct.client + case *queueClient: + ct.mu.RLock() + ok := ct.isPassthrough() + ct.mu.RUnlock() + if !ok { + break dig + } + client = ct.client + case *localAnswerClient: + ct.a.mu.RLock() + obj, err, done := ct.a.obj, ct.a.err, ct.a.done + ct.a.mu.RUnlock() + if !done { + break dig + } + client = clientFromResolution(ct.transform, obj, err) + case *capnp.PipelineClient: + p := (*capnp.Pipeline)(ct) + ans := p.Answer() + transform := p.Transform() + if capnp.IsFixedAnswer(ans) { + s, err := ans.Struct() + client = clientFromResolution(transform, s.ToPtr(), err) + continue + } + switch ans := ans.(type) { + case *fulfiller.Fulfiller: + ap := ans.Peek() + if ap == nil { + break dig + } + s, err := ap.Struct() + client = clientFromResolution(transform, s.ToPtr(), err) + case *question: + ans.mu.RLock() + obj, err, state := ans.obj, ans.err, ans.state + ans.mu.RUnlock() + if state != questionInProgress { + client = clientFromResolution(transform, obj, err) + continue + } + if ans.conn != c { + break dig + } + a, err := desc.NewReceiverAnswer() + if err != nil { + return err + } + a.SetQuestionId(uint32(ans.id)) + err = transformToPromisedAnswer(desc.Segment(), a, p.Transform()) + if err != nil { + return err + } + return nil + default: + break dig + } + default: + break dig + } + } + + id := c.addExport(client) + desc.SetSenderHosted(uint32(id)) + return nil +} + +// isSameClient reports whether c and d refer to the same capability. +func isSameClient(c, d capnp.Client) bool { + norm := func(client capnp.Client) capnp.Client { + for { + switch curr := client.(type) { + case *fulfiller.EmbargoClient: + client = curr.Client() + if client == nil { + return curr + } + case *refcount.Ref: + client = curr.Client() + case *embargoClient: + curr.mu.RLock() + ok := curr.isPassthrough() + curr.mu.RUnlock() + if !ok { + return curr + } + client = curr.client + case *queueClient: + curr.mu.RLock() + ok := curr.isPassthrough() + curr.mu.RUnlock() + if !ok { + return curr + } + client = curr.client + case *localAnswerClient: + curr.a.mu.RLock() + obj, err, done := curr.a.obj, curr.a.err, curr.a.done + curr.a.mu.RUnlock() + if !done { + return curr + } + client = clientFromResolution(curr.transform, obj, err) + case *capnp.PipelineClient: + p := (*capnp.Pipeline)(curr) + ans := p.Answer() + if capnp.IsFixedAnswer(ans) { + s, err := ans.Struct() + client = clientFromResolution(p.Transform(), s.ToPtr(), err) + continue + } + switch ans := ans.(type) { + case *fulfiller.Fulfiller: + ap := ans.Peek() + if ap == nil { + return curr + } + s, err := ap.Struct() + client = clientFromResolution(p.Transform(), s.ToPtr(), err) + case *question: + ans.mu.RLock() + obj, err, state := ans.obj, ans.err, ans.state + ans.mu.RUnlock() + if state != questionResolved { + return curr + } + client = clientFromResolution(p.Transform(), obj, err) + default: + return curr + } + default: + return curr + } + } + } + return norm(c) == norm(d) +} + +// isImport returns the underlying import if client represents an import +// or nil otherwise. +func isImport(client capnp.Client) *importClient { + for { + switch curr := client.(type) { + case *importClient: + return curr + case *fulfiller.EmbargoClient: + client = curr.Client() + if client == nil { + return nil + } + case *refcount.Ref: + client = curr.Client() + case *embargoClient: + curr.mu.RLock() + ok := curr.isPassthrough() + curr.mu.RUnlock() + if !ok { + return nil + } + client = curr.client + case *queueClient: + curr.mu.RLock() + ok := curr.isPassthrough() + curr.mu.RUnlock() + if !ok { + return nil + } + client = curr.client + case *localAnswerClient: + curr.a.mu.RLock() + obj, err, done := curr.a.obj, curr.a.err, curr.a.done + curr.a.mu.RUnlock() + if !done { + return nil + } + client = clientFromResolution(curr.transform, obj, err) + case *capnp.PipelineClient: + p := (*capnp.Pipeline)(curr) + ans := p.Answer() + if capnp.IsFixedAnswer(ans) { + s, err := ans.Struct() + client = clientFromResolution(p.Transform(), s.ToPtr(), err) + continue + } + switch ans := ans.(type) { + case *fulfiller.Fulfiller: + ap := ans.Peek() + if ap == nil { + return nil + } + s, err := ap.Struct() + client = clientFromResolution(p.Transform(), s.ToPtr(), err) + case *question: + ans.mu.RLock() + obj, err, state := ans.obj, ans.err, ans.state + ans.mu.RUnlock() + if state != questionResolved { + return nil + } + client = clientFromResolution(p.Transform(), obj, err) + default: + return nil + } + default: + return nil + } + } +} diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/log.go b/vendor/zombiezen.com/go/capnproto2/rpc/log.go new file mode 100644 index 00000000..4df33325 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/log.go @@ -0,0 +1,49 @@ +package rpc + +import ( + "log" + + "golang.org/x/net/context" +) + +// A Logger records diagnostic information and errors that are not +// associated with a call. The arguments passed into a log call are +// interpreted like fmt.Printf. They should not be held onto past the +// call's return. +type Logger interface { + Infof(ctx context.Context, format string, args ...interface{}) + Errorf(ctx context.Context, format string, args ...interface{}) +} + +type defaultLogger struct{} + +func (defaultLogger) Infof(ctx context.Context, format string, args ...interface{}) { + log.Printf("rpc: "+format, args...) +} + +func (defaultLogger) Errorf(ctx context.Context, format string, args ...interface{}) { + log.Printf("rpc: "+format, args...) +} + +func (c *Conn) infof(format string, args ...interface{}) { + if c.log == nil { + return + } + c.log.Infof(c.bg, format, args...) +} + +func (c *Conn) errorf(format string, args ...interface{}) { + if c.log == nil { + return + } + c.log.Errorf(c.bg, format, args...) +} + +// ConnLog sets the connection's log to the given Logger, which may be +// nil to disable logging. By default, logs are sent to the standard +// log package. +func ConnLog(log Logger) ConnOption { + return ConnOption{func(c *connParams) { + c.log = log + }} +} diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/question.go b/vendor/zombiezen.com/go/capnproto2/rpc/question.go new file mode 100644 index 00000000..05d5f2f8 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/question.go @@ -0,0 +1,442 @@ +package rpc + +import ( + "sync" + + "golang.org/x/net/context" + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/fulfiller" + "zombiezen.com/go/capnproto2/internal/queue" + rpccapnp "zombiezen.com/go/capnproto2/std/capnp/rpc" +) + +// newQuestion creates a new question with an unassigned ID. +func (c *Conn) newQuestion(ctx context.Context, method *capnp.Method) *question { + id := questionID(c.questionID.next()) + q := &question{ + ctx: ctx, + conn: c, + method: method, + resolved: make(chan struct{}), + id: id, + } + // TODO(light): populate paramCaps + if int(id) == len(c.questions) { + c.questions = append(c.questions, q) + } else { + c.questions[id] = q + } + return q +} + +func (c *Conn) findQuestion(id questionID) *question { + if int(id) >= len(c.questions) { + return nil + } + return c.questions[id] +} + +func (c *Conn) popQuestion(id questionID) *question { + q := c.findQuestion(id) + if q == nil { + return nil + } + c.questions[id] = nil + c.questionID.remove(uint32(id)) + return q +} + +type question struct { + id questionID + ctx context.Context + conn *Conn + method *capnp.Method // nil if this is bootstrap + paramCaps []exportID + resolved chan struct{} + + // Protected by conn.mu + derived [][]capnp.PipelineOp + + // Fields below are protected by mu. + mu sync.RWMutex + obj capnp.Ptr + err error + state questionState +} + +type questionState uint8 + +// Question states +const ( + questionInProgress questionState = iota + questionResolved + questionCanceled +) + +// start signals that the question has been sent. +func (q *question) start() { + go func() { + select { + case <-q.resolved: + // Resolved naturally, nothing to do. + case <-q.conn.bg.Done(): + case <-q.ctx.Done(): + select { + case <-q.resolved: + case <-q.conn.bg.Done(): + case <-q.conn.mu: + if err := q.conn.startWork(); err != nil { + // teardown calls cancel. + q.conn.mu.Unlock() + return + } + if q.cancel(q.ctx.Err()) { + q.conn.sendMessage(newFinishMessage(nil, q.id, true /* release */)) + } + q.conn.workers.Done() + q.conn.mu.Unlock() + } + } + }() +} + +// fulfill is called to resolve a question successfully. +// The caller must be holding onto q.conn.mu. +func (q *question) fulfill(obj capnp.Ptr) { + var ctab []capnp.Client + if obj.IsValid() { + ctab = obj.Segment().Message().CapTable + } + visited := make([]bool, len(ctab)) + for _, d := range q.derived { + tgt, err := capnp.TransformPtr(obj, d) + if err != nil { + continue + } + in := tgt.Interface() + if !in.IsValid() { + continue + } + if ic := isImport(in.Client()); ic != nil && ic.conn == q.conn { + // Imported from remote vat. Don't need to disembargo. + continue + } + cn := in.Capability() + if visited[cn] { + continue + } + visited[cn] = true + id, e := q.conn.newEmbargo() + ctab[cn] = newEmbargoClient(ctab[cn], e, q.conn.bg.Done()) + m := newDisembargoMessage(nil, rpccapnp.Disembargo_context_Which_senderLoopback, id) + dis, _ := m.Disembargo() + mt, _ := dis.NewTarget() + pa, _ := mt.NewPromisedAnswer() + pa.SetQuestionId(uint32(q.id)) + transformToPromisedAnswer(m.Segment(), pa, d) + mt.SetPromisedAnswer(pa) + + select { + case q.conn.out <- m: + case <-q.conn.bg.Done(): + // TODO(soon): perhaps just drop all embargoes in this case? + } + } + + q.mu.Lock() + if q.state != questionInProgress { + panic("question.fulfill called more than once") + } + q.obj, q.state = obj, questionResolved + close(q.resolved) + q.mu.Unlock() +} + +// reject is called to resolve a question with failure. +// The caller must be holding onto q.conn.mu. +func (q *question) reject(err error) { + if err == nil { + panic("question.reject called with nil") + } + q.mu.Lock() + if q.state != questionInProgress { + panic("question.reject called more than once") + } + q.err = err + q.state = questionResolved + close(q.resolved) + q.mu.Unlock() +} + +// cancel is called to resolve a question with cancellation. +// The caller must be holding onto q.conn.mu. +func (q *question) cancel(err error) bool { + if err == nil { + panic("question.cancel called with nil") + } + q.mu.Lock() + canceled := q.state == questionInProgress + if canceled { + q.err = err + q.state = questionCanceled + close(q.resolved) + } + q.mu.Unlock() + return canceled +} + +// addPromise records a returned capability as being used for a call. +// This is needed for determining embargoes upon resolution. The +// caller must be holding onto q.conn.mu. +func (q *question) addPromise(transform []capnp.PipelineOp) { + for _, d := range q.derived { + if transformsEqual(transform, d) { + return + } + } + q.derived = append(q.derived, transform) +} + +func transformsEqual(t, u []capnp.PipelineOp) bool { + if len(t) != len(u) { + return false + } + for i := range t { + if t[i].Field != u[i].Field { + return false + } + } + return true +} + +func (q *question) Struct() (capnp.Struct, error) { + select { + case <-q.resolved: + case <-q.conn.bg.Done(): + return capnp.Struct{}, ErrConnClosed + } + q.mu.RLock() + s, err := q.obj.Struct(), q.err + q.mu.RUnlock() + return s, err +} + +func (q *question) PipelineCall(transform []capnp.PipelineOp, ccall *capnp.Call) capnp.Answer { + select { + case <-q.conn.mu: + if err := q.conn.startWork(); err != nil { + q.conn.mu.Unlock() + return capnp.ErrorAnswer(err) + } + case <-ccall.Ctx.Done(): + return capnp.ErrorAnswer(ccall.Ctx.Err()) + } + ans := q.lockedPipelineCall(transform, ccall) + q.conn.workers.Done() + q.conn.mu.Unlock() + return ans +} + +// lockedPipelineCall is equivalent to PipelineCall but assumes that the +// caller is already holding onto q.conn.mu. +func (q *question) lockedPipelineCall(transform []capnp.PipelineOp, ccall *capnp.Call) capnp.Answer { + if q.conn.findQuestion(q.id) != q { + // Question has been finished. The call should happen as if it is + // back in application code. + q.mu.RLock() + obj, err, state := q.obj, q.err, q.state + q.mu.RUnlock() + if state == questionInProgress { + panic("question popped but not done") + } + client := clientFromResolution(transform, obj, err) + return q.conn.lockedCall(client, ccall) + } + + pipeq := q.conn.newQuestion(ccall.Ctx, &ccall.Method) + msg := newMessage(nil) + msgCall, _ := msg.NewCall() + msgCall.SetQuestionId(uint32(pipeq.id)) + msgCall.SetInterfaceId(ccall.Method.InterfaceID) + msgCall.SetMethodId(ccall.Method.MethodID) + target, _ := msgCall.NewTarget() + a, _ := target.NewPromisedAnswer() + a.SetQuestionId(uint32(q.id)) + err := transformToPromisedAnswer(a.Segment(), a, transform) + if err != nil { + q.conn.popQuestion(pipeq.id) + return capnp.ErrorAnswer(err) + } + payload, _ := msgCall.NewParams() + if err := q.conn.fillParams(payload, ccall); err != nil { + q.conn.popQuestion(q.id) + return capnp.ErrorAnswer(err) + } + + select { + case q.conn.out <- msg: + case <-ccall.Ctx.Done(): + q.conn.popQuestion(pipeq.id) + return capnp.ErrorAnswer(ccall.Ctx.Err()) + case <-q.conn.bg.Done(): + q.conn.popQuestion(pipeq.id) + return capnp.ErrorAnswer(ErrConnClosed) + } + q.addPromise(transform) + pipeq.start() + return pipeq +} + +func (q *question) PipelineClose(transform []capnp.PipelineOp) error { + <-q.resolved + q.mu.RLock() + obj, err := q.obj, q.err + q.mu.RUnlock() + if err != nil { + return err + } + x, err := capnp.TransformPtr(obj, transform) + if err != nil { + return err + } + c := x.Interface().Client() + if c == nil { + return capnp.ErrNullClient + } + return c.Close() +} + +// embargoClient is a client that waits until an embargo signal is +// received to deliver calls. +type embargoClient struct { + cancel <-chan struct{} + client capnp.Client + embargo embargo + + mu sync.RWMutex + q queue.Queue + calls ecallList +} + +func newEmbargoClient(client capnp.Client, e embargo, cancel <-chan struct{}) *embargoClient { + ec := &embargoClient{ + client: client, + embargo: e, + cancel: cancel, + calls: make(ecallList, callQueueSize), + } + ec.q.Init(ec.calls, 0) + go ec.flushQueue() + return ec +} + +func (ec *embargoClient) push(cl *capnp.Call) capnp.Answer { + f := new(fulfiller.Fulfiller) + cl, err := cl.Copy(nil) + if err != nil { + return capnp.ErrorAnswer(err) + } + i := ec.q.Push() + if i == -1 { + return capnp.ErrorAnswer(errQueueFull) + } + ec.calls[i] = ecall{cl, f} + return f +} + +func (ec *embargoClient) Call(cl *capnp.Call) capnp.Answer { + // Fast path: queue is flushed. + ec.mu.RLock() + ok := ec.isPassthrough() + ec.mu.RUnlock() + if ok { + return ec.client.Call(cl) + } + + ec.mu.Lock() + if ec.isPassthrough() { + ec.mu.Unlock() + return ec.client.Call(cl) + } + ans := ec.push(cl) + ec.mu.Unlock() + return ans +} + +func (ec *embargoClient) tryQueue(cl *capnp.Call) capnp.Answer { + ec.mu.Lock() + if ec.isPassthrough() { + ec.mu.Unlock() + return nil + } + ans := ec.push(cl) + ec.mu.Unlock() + return ans +} + +func (ec *embargoClient) isPassthrough() bool { + select { + case <-ec.embargo: + default: + return false + } + return ec.q.Len() == 0 +} + +func (ec *embargoClient) Close() error { + ec.mu.Lock() + for ; ec.q.Len() > 0; ec.q.Pop() { + c := ec.calls[ec.q.Front()] + c.f.Reject(errQueueCallCancel) + } + ec.mu.Unlock() + return ec.client.Close() +} + +// flushQueue is run in its own goroutine. +func (ec *embargoClient) flushQueue() { + select { + case <-ec.embargo: + case <-ec.cancel: + ec.mu.Lock() + for ec.q.Len() > 0 { + ec.q.Pop() + } + ec.mu.Unlock() + return + } + var c ecall + ec.mu.RLock() + if i := ec.q.Front(); i != -1 { + c = ec.calls[i] + } + ec.mu.RUnlock() + for c.call != nil { + ans := ec.client.Call(c.call) + go joinFulfiller(c.f, ans) + + ec.mu.Lock() + ec.q.Pop() + if i := ec.q.Front(); i != -1 { + c = ec.calls[i] + } else { + c = ecall{} + } + ec.mu.Unlock() + } +} + +type ecall struct { + call *capnp.Call + f *fulfiller.Fulfiller +} + +type ecallList []ecall + +func (el ecallList) Len() int { + return len(el) +} + +func (el ecallList) Clear(i int) { + el[i] = ecall{} +} diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/rpc.go b/vendor/zombiezen.com/go/capnproto2/rpc/rpc.go new file mode 100644 index 00000000..5765c862 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/rpc.go @@ -0,0 +1,913 @@ +// Package rpc implements the Cap'n Proto RPC protocol. +package rpc // import "zombiezen.com/go/capnproto2/rpc" + +import ( + "fmt" + "io" + "sync" + + "golang.org/x/net/context" + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/rpc/internal/refcount" + rpccapnp "zombiezen.com/go/capnproto2/std/capnp/rpc" +) + +// A Conn is a connection to another Cap'n Proto vat. +// It is safe to use from multiple goroutines. +type Conn struct { + transport Transport + log Logger + mainFunc func(context.Context) (capnp.Client, error) + mainCloser io.Closer + death chan struct{} // closed after state is connDead + + out chan rpccapnp.Message + + bg context.Context + bgCancel context.CancelFunc + workers sync.WaitGroup + + // Mutable state protected by stateMu + // If you need to acquire both mu and stateMu, acquire mu first. + stateMu sync.RWMutex + state connState + closeErr error + + // Mutable state protected by mu + mu chanMutex + questions []*question + questionID idgen + exports []*export + exportID idgen + embargoes []chan<- struct{} + embargoID idgen + answers map[answerID]*answer + imports map[importID]*impent +} + +type connParams struct { + log Logger + mainFunc func(context.Context) (capnp.Client, error) + mainCloser io.Closer + sendBufferSize int +} + +// A ConnOption is an option for opening a connection. +type ConnOption struct { + f func(*connParams) +} + +// MainInterface specifies that the connection should use client when +// receiving bootstrap messages. By default, all bootstrap messages will +// fail. The client will be closed when the connection is closed. +func MainInterface(client capnp.Client) ConnOption { + rc, ref1 := refcount.New(client) + ref2 := rc.Ref() + return ConnOption{func(c *connParams) { + c.mainFunc = func(ctx context.Context) (capnp.Client, error) { + return ref1, nil + } + c.mainCloser = ref2 + }} +} + +// BootstrapFunc specifies the function to call to create a capability +// for handling bootstrap messages. This function should not make any +// RPCs or block. +func BootstrapFunc(f func(context.Context) (capnp.Client, error)) ConnOption { + return ConnOption{func(c *connParams) { + c.mainFunc = f + }} +} + +// SendBufferSize sets the number of outgoing messages to buffer on the +// connection. This is in addition to whatever buffering the connection's +// transport performs. +func SendBufferSize(numMsgs int) ConnOption { + return ConnOption{func(c *connParams) { + c.sendBufferSize = numMsgs + }} +} + +// NewConn creates a new connection that communicates on c. +// Closing the connection will cause c to be closed. +func NewConn(t Transport, options ...ConnOption) *Conn { + p := &connParams{ + log: defaultLogger{}, + sendBufferSize: 4, + } + for _, o := range options { + o.f(p) + } + + conn := &Conn{ + transport: t, + out: make(chan rpccapnp.Message, p.sendBufferSize), + mainFunc: p.mainFunc, + mainCloser: p.mainCloser, + log: p.log, + death: make(chan struct{}), + mu: newChanMutex(), + } + conn.bg, conn.bgCancel = context.WithCancel(context.Background()) + conn.workers.Add(2) + go conn.dispatchRecv() + go conn.dispatchSend() + return conn +} + +// Wait waits until the connection is closed or aborted by the remote vat. +// Wait will always return an error, usually ErrConnClosed or of type Abort. +func (c *Conn) Wait() error { + <-c.Done() + return c.Err() +} + +// Done is a channel that is closed once the connection is fully shut down. +func (c *Conn) Done() <-chan struct{} { + return c.death +} + +// Err returns the error that caused the connection to close. +// Err returns nil before Done is closed. +func (c *Conn) Err() error { + c.stateMu.RLock() + var err error + if c.state != connDead { + err = c.closeErr + } + c.stateMu.RUnlock() + return err +} + +// Close closes the connection and the underlying transport. +func (c *Conn) Close() error { + c.stateMu.Lock() + alive := c.state == connAlive + if alive { + c.bgCancel() + c.closeErr = ErrConnClosed + c.state = connDying + } + c.stateMu.Unlock() + if !alive { + return ErrConnClosed + } + c.teardown(newAbortMessage(nil, errShutdown)) + c.stateMu.RLock() + err := c.closeErr + c.stateMu.RUnlock() + if err != ErrConnClosed { + return err + } + return nil +} + +// shutdown cancels the background context and sets closeErr to e. +// No abort message will be sent on the transport. After shutdown +// returns, the Conn will be in the dying or dead state. Calling +// shutdown on a dying or dead Conn is a no-op. +func (c *Conn) shutdown(e error) { + c.stateMu.Lock() + if c.state == connAlive { + c.bgCancel() + c.closeErr = e + c.state = connDying + go c.teardown(rpccapnp.Message{}) + } + c.stateMu.Unlock() +} + +// abort cancels the background context, sets closeErr to e, and queues +// an abort message to be sent on the transport before the Conn goes +// into the dead state. After abort returns, the Conn will be in the +// dying or dead state. Calling abort on a dying or dead Conn is a +// no-op. +func (c *Conn) abort(e error) { + c.stateMu.Lock() + if c.state == connAlive { + c.bgCancel() + c.closeErr = e + c.state = connDying + go c.teardown(newAbortMessage(nil, e)) + } + c.stateMu.Unlock() +} + +// startWork adds a new worker if c is not dying or dead. +// Otherwise, it returns the close error. +// The caller is responsible for calling c.workers.Done(). +// The caller must not be holding onto c.stateMu. +func (c *Conn) startWork() error { + var err error + c.stateMu.RLock() + if c.state == connAlive { + c.workers.Add(1) + } else { + err = c.closeErr + } + c.stateMu.RUnlock() + return err +} + +// teardown moves the connection from the dying to the dead state. +func (c *Conn) teardown(abort rpccapnp.Message) { + c.workers.Wait() + + c.mu.Lock() + for _, q := range c.questions { + if q != nil { + q.cancel(ErrConnClosed) + } + } + c.questions = nil + exps := c.exports + c.exports = nil + c.embargoes = nil + for _, a := range c.answers { + a.cancel() + } + c.answers = nil + c.imports = nil + c.mainFunc = nil + c.mu.Unlock() + + if c.mainCloser != nil { + if err := c.mainCloser.Close(); err != nil { + c.errorf("closing main interface: %v", err) + } + c.mainCloser = nil + } + // Closing an export may try to lock the Conn, so run it outside + // critical section. + for id, e := range exps { + if e == nil { + continue + } + if err := e.client.Close(); err != nil { + c.errorf("export %v close: %v", id, err) + } + } + exps = nil + + var werr error + if abort.IsValid() { + werr = c.transport.SendMessage(context.Background(), abort) + } + cerr := c.transport.Close() + + c.stateMu.Lock() + if c.closeErr == ErrConnClosed { + if cerr != nil { + c.closeErr = cerr + } else if werr != nil { + c.closeErr = werr + } + } + c.state = connDead + close(c.death) + c.stateMu.Unlock() +} + +// Bootstrap returns the receiver's main interface. +func (c *Conn) Bootstrap(ctx context.Context) capnp.Client { + // TODO(light): Create a client that returns immediately. + select { + case <-c.mu: + // Locked. + defer c.mu.Unlock() + if err := c.startWork(); err != nil { + return capnp.ErrorClient(err) + } + defer c.workers.Done() + case <-ctx.Done(): + return capnp.ErrorClient(ctx.Err()) + case <-c.bg.Done(): + return capnp.ErrorClient(ErrConnClosed) + } + + q := c.newQuestion(ctx, nil /* method */) + msg := newMessage(nil) + boot, _ := msg.NewBootstrap() + boot.SetQuestionId(uint32(q.id)) + // The mutex must be held while sending so that call order is preserved. + // Worst case, this blocks until a message is sent on the transport. + // Common case, this just adds to the channel queue. + select { + case c.out <- msg: + q.start() + return capnp.NewPipeline(q).Client() + case <-ctx.Done(): + c.popQuestion(q.id) + return capnp.ErrorClient(ctx.Err()) + case <-c.bg.Done(): + c.popQuestion(q.id) + return capnp.ErrorClient(ErrConnClosed) + } +} + +// handleMessage is run from the receive goroutine to process a single +// message. m cannot be held onto past the return of handleMessage, and +// c.mu is not held at the start of handleMessage. +func (c *Conn) handleMessage(m rpccapnp.Message) { + switch m.Which() { + case rpccapnp.Message_Which_unimplemented: + // no-op for now to avoid feedback loop + case rpccapnp.Message_Which_abort: + a, err := copyAbort(m) + if err != nil { + c.errorf("decode abort: %v", err) + // Keep going, since we're trying to abort anyway. + } + c.infof("abort: %v", a) + c.shutdown(a) + case rpccapnp.Message_Which_return: + m = copyRPCMessage(m) + c.mu.Lock() + err := c.handleReturnMessage(m) + c.mu.Unlock() + + if err != nil { + c.errorf("handle return: %v", err) + } + case rpccapnp.Message_Which_finish: + mfin, err := m.Finish() + if err != nil { + c.errorf("decode finish: %v", err) + return + } + id := answerID(mfin.QuestionId()) + + c.mu.Lock() + a := c.popAnswer(id) + if a == nil { + c.mu.Unlock() + c.errorf("finish called for unknown answer %d", id) + return + } + a.cancel() + if mfin.ReleaseResultCaps() { + for _, id := range a.resultCaps { + c.releaseExport(id, 1) + } + } + c.mu.Unlock() + case rpccapnp.Message_Which_bootstrap: + boot, err := m.Bootstrap() + if err != nil { + c.errorf("decode bootstrap: %v", err) + return + } + id := answerID(boot.QuestionId()) + + c.mu.Lock() + err = c.handleBootstrapMessage(id) + c.mu.Unlock() + + if err != nil { + c.errorf("handle bootstrap: %v", err) + } + case rpccapnp.Message_Which_call: + m = copyRPCMessage(m) + c.mu.Lock() + err := c.handleCallMessage(m) + c.mu.Unlock() + + if err != nil { + c.errorf("handle call: %v", err) + } + case rpccapnp.Message_Which_release: + rel, err := m.Release() + if err != nil { + c.errorf("decode release: %v", err) + return + } + id := exportID(rel.Id()) + refs := int(rel.ReferenceCount()) + + c.mu.Lock() + c.releaseExport(id, refs) + c.mu.Unlock() + case rpccapnp.Message_Which_disembargo: + m = copyRPCMessage(m) + c.mu.Lock() + err := c.handleDisembargoMessage(m) + c.mu.Unlock() + + if err != nil { + // Any failure in a disembargo is a protocol violation. + c.abort(err) + } + default: + c.infof("received unimplemented message, which = %v", m.Which()) + um := newUnimplementedMessage(nil, m) + c.sendMessage(um) + } +} + +func newUnimplementedMessage(buf []byte, m rpccapnp.Message) rpccapnp.Message { + n := newMessage(buf) + n.SetUnimplemented(m) + return n +} + +func (c *Conn) fillParams(payload rpccapnp.Payload, cl *capnp.Call) error { + params, err := cl.PlaceParams(payload.Segment()) + if err != nil { + return err + } + if err := payload.SetContent(params); err != nil { + return err + } + ctab, err := c.makeCapTable(payload.Segment()) + if err != nil { + return err + } + if err := payload.SetCapTable(ctab); err != nil { + return err + } + return nil +} + +func transformToPromisedAnswer(s *capnp.Segment, answer rpccapnp.PromisedAnswer, transform []capnp.PipelineOp) error { + opList, err := rpccapnp.NewPromisedAnswer_Op_List(s, int32(len(transform))) + if err != nil { + return err + } + for i, op := range transform { + opList.At(i).SetGetPointerField(uint16(op.Field)) + } + err = answer.SetTransform(opList) + return err +} + +// handleReturnMessage is to handle a received return message. +// The caller is holding onto c.mu. +func (c *Conn) handleReturnMessage(m rpccapnp.Message) error { + ret, err := m.Return() + if err != nil { + return err + } + id := questionID(ret.AnswerId()) + q := c.popQuestion(id) + if q == nil { + return fmt.Errorf("received return for unknown question id=%d", id) + } + if ret.ReleaseParamCaps() { + for _, id := range q.paramCaps { + c.releaseExport(id, 1) + } + } + q.mu.RLock() + qstate := q.state + q.mu.RUnlock() + if qstate == questionCanceled { + // We already sent the finish message. + return nil + } + releaseResultCaps := true + switch ret.Which() { + case rpccapnp.Return_Which_results: + releaseResultCaps = false + results, err := ret.Results() + if err != nil { + return err + } + if err := c.populateMessageCapTable(results); err == errUnimplemented { + um := newUnimplementedMessage(nil, m) + c.sendMessage(um) + return errUnimplemented + } else if err != nil { + c.abort(err) + return err + } + content, err := results.ContentPtr() + if err != nil { + return err + } + q.fulfill(content) + case rpccapnp.Return_Which_exception: + exc, err := ret.Exception() + if err != nil { + return err + } + e := error(Exception{exc}) + if q.method != nil { + e = &capnp.MethodError{ + Method: q.method, + Err: e, + } + } else { + e = bootstrapError{e} + } + q.reject(e) + case rpccapnp.Return_Which_canceled: + err := &questionError{ + id: id, + method: q.method, + err: fmt.Errorf("receiver reported canceled"), + } + c.errorf("%v", err) + q.reject(err) + return nil + default: + um := newUnimplementedMessage(nil, m) + c.sendMessage(um) + return errUnimplemented + } + fin := newFinishMessage(nil, id, releaseResultCaps) + c.sendMessage(fin) + return nil +} + +func newFinishMessage(buf []byte, questionID questionID, release bool) rpccapnp.Message { + m := newMessage(buf) + f, _ := m.NewFinish() + f.SetQuestionId(uint32(questionID)) + f.SetReleaseResultCaps(release) + return m +} + +// populateMessageCapTable converts the descriptors in the payload into +// clients and sets it on the message the payload is a part of. +func (c *Conn) populateMessageCapTable(payload rpccapnp.Payload) error { + msg := payload.Segment().Message() + ctab, err := payload.CapTable() + if err != nil { + return err + } + for i, n := 0, ctab.Len(); i < n; i++ { + desc := ctab.At(i) + switch desc.Which() { + case rpccapnp.CapDescriptor_Which_none: + msg.AddCap(nil) + case rpccapnp.CapDescriptor_Which_senderHosted: + id := importID(desc.SenderHosted()) + client := c.addImport(id) + msg.AddCap(client) + case rpccapnp.CapDescriptor_Which_senderPromise: + // We do the same thing as senderHosted, above. @kentonv suggested this on + // issue #2; this let's messages be delivered properly, although it's a bit + // of a hack, and as Kenton describes, it has some disadvantages: + // + // > * Apps sometimes want to wait for promise resolution, and to find out if + // > it resolved to an exception. You won't be able to provide that API. But, + // > usually, it isn't needed. + // > * If the promise resolves to a capability hosted on the receiver, + // > messages sent to it will uselessly round-trip over the network + // > rather than being delivered locally. + id := importID(desc.SenderPromise()) + client := c.addImport(id) + msg.AddCap(client) + case rpccapnp.CapDescriptor_Which_receiverHosted: + id := exportID(desc.ReceiverHosted()) + e := c.findExport(id) + if e == nil { + return fmt.Errorf("rpc: capability table references unknown export ID %d", id) + } + msg.AddCap(e.rc.Ref()) + case rpccapnp.CapDescriptor_Which_receiverAnswer: + recvAns, err := desc.ReceiverAnswer() + if err != nil { + return err + } + id := answerID(recvAns.QuestionId()) + a := c.answers[id] + if a == nil { + return fmt.Errorf("rpc: capability table references unknown answer ID %d", id) + } + recvTransform, err := recvAns.Transform() + if err != nil { + return err + } + transform := promisedAnswerOpsToTransform(recvTransform) + msg.AddCap(a.pipelineClient(transform)) + default: + c.errorf("unknown capability type %v", desc.Which()) + return errUnimplemented + } + } + return nil +} + +// makeCapTable converts the clients in the segment's message into capability descriptors. +func (c *Conn) makeCapTable(s *capnp.Segment) (rpccapnp.CapDescriptor_List, error) { + msgtab := s.Message().CapTable + t, err := rpccapnp.NewCapDescriptor_List(s, int32(len(msgtab))) + if err != nil { + return rpccapnp.CapDescriptor_List{}, nil + } + for i, client := range msgtab { + desc := t.At(i) + if client == nil { + desc.SetNone() + continue + } + c.descriptorForClient(desc, client) + } + return t, nil +} + +// handleBootstrapMessage handles a received bootstrap message. +// The caller holds onto c.mu. +func (c *Conn) handleBootstrapMessage(id answerID) error { + ctx, cancel := c.newContext() + defer cancel() + a := c.insertAnswer(id, cancel) + if a == nil { + // Question ID reused, error out. + retmsg := newReturnMessage(nil, id) + r, _ := retmsg.Return() + setReturnException(r, errQuestionReused) + return c.sendMessage(retmsg) + } + if c.mainFunc == nil { + return a.reject(errNoMainInterface) + } + main, err := c.mainFunc(ctx) + if err != nil { + return a.reject(errNoMainInterface) + } + m := &capnp.Message{ + Arena: capnp.SingleSegment(make([]byte, 0)), + CapTable: []capnp.Client{main}, + } + s, _ := m.Segment(0) + in := capnp.NewInterface(s, 0) + return a.fulfill(in.ToPtr()) +} + +// handleCallMessage handles a received call message. It mutates the +// capability table of its parameter. The caller holds onto c.mu. +func (c *Conn) handleCallMessage(m rpccapnp.Message) error { + mcall, err := m.Call() + if err != nil { + return err + } + mt, err := mcall.Target() + if err != nil { + return err + } + if mt.Which() != rpccapnp.MessageTarget_Which_importedCap && mt.Which() != rpccapnp.MessageTarget_Which_promisedAnswer { + um := newUnimplementedMessage(nil, m) + return c.sendMessage(um) + } + mparams, err := mcall.Params() + if err != nil { + return err + } + if err := c.populateMessageCapTable(mparams); err == errUnimplemented { + um := newUnimplementedMessage(nil, m) + return c.sendMessage(um) + } else if err != nil { + c.abort(err) + return err + } + ctx, cancel := c.newContext() + id := answerID(mcall.QuestionId()) + a := c.insertAnswer(id, cancel) + if a == nil { + // Question ID reused, error out. + c.abort(errQuestionReused) + return errQuestionReused + } + meth := capnp.Method{ + InterfaceID: mcall.InterfaceId(), + MethodID: mcall.MethodId(), + } + paramContent, err := mparams.ContentPtr() + if err != nil { + return err + } + cl := &capnp.Call{ + Ctx: ctx, + Method: meth, + Params: paramContent.Struct(), + } + if err := c.routeCallMessage(a, mt, cl); err != nil { + return a.reject(err) + } + return nil +} + +func (c *Conn) routeCallMessage(result *answer, mt rpccapnp.MessageTarget, cl *capnp.Call) error { + switch mt.Which() { + case rpccapnp.MessageTarget_Which_importedCap: + id := exportID(mt.ImportedCap()) + e := c.findExport(id) + if e == nil { + return errBadTarget + } + answer := c.lockedCall(e.client, cl) + go joinAnswer(result, answer) + case rpccapnp.MessageTarget_Which_promisedAnswer: + mpromise, err := mt.PromisedAnswer() + if err != nil { + return err + } + id := answerID(mpromise.QuestionId()) + if id == result.id { + // Grandfather paradox. + return errBadTarget + } + pa := c.answers[id] + if pa == nil { + return errBadTarget + } + mtrans, err := mpromise.Transform() + if err != nil { + return err + } + transform := promisedAnswerOpsToTransform(mtrans) + pa.mu.Lock() + if pa.done { + obj, err := pa.obj, pa.err + pa.mu.Unlock() + client := clientFromResolution(transform, obj, err) + answer := c.lockedCall(client, cl) + go joinAnswer(result, answer) + } else { + err = pa.queueCallLocked(cl, pcall{transform: transform, qcall: qcall{a: result}}) + pa.mu.Unlock() + } + return err + default: + panic("unreachable") + } + return nil +} + +func (c *Conn) handleDisembargoMessage(msg rpccapnp.Message) error { + d, err := msg.Disembargo() + if err != nil { + return err + } + dtarget, err := d.Target() + if err != nil { + return err + } + switch d.Context().Which() { + case rpccapnp.Disembargo_context_Which_senderLoopback: + id := embargoID(d.Context().SenderLoopback()) + if dtarget.Which() != rpccapnp.MessageTarget_Which_promisedAnswer { + return errDisembargoNonImport + } + dpa, err := dtarget.PromisedAnswer() + if err != nil { + return err + } + aid := answerID(dpa.QuestionId()) + a := c.answers[aid] + if a == nil { + return errDisembargoMissingAnswer + } + dtrans, err := dpa.Transform() + if err != nil { + return err + } + transform := promisedAnswerOpsToTransform(dtrans) + queued, err := a.queueDisembargo(transform, id, dtarget) + if err != nil { + return err + } + if !queued { + // There's nothing to embargo; everything's been delivered. + resp := newDisembargoMessage(nil, rpccapnp.Disembargo_context_Which_receiverLoopback, id) + rd, _ := resp.Disembargo() + if err := rd.SetTarget(dtarget); err != nil { + return err + } + c.sendMessage(resp) + } + case rpccapnp.Disembargo_context_Which_receiverLoopback: + id := embargoID(d.Context().ReceiverLoopback()) + c.disembargo(id) + default: + um := newUnimplementedMessage(nil, msg) + c.sendMessage(um) + } + return nil +} + +// newDisembargoMessage creates a disembargo message. Its target will be left blank. +func newDisembargoMessage(buf []byte, which rpccapnp.Disembargo_context_Which, id embargoID) rpccapnp.Message { + msg := newMessage(buf) + d, _ := msg.NewDisembargo() + switch which { + case rpccapnp.Disembargo_context_Which_senderLoopback: + d.Context().SetSenderLoopback(uint32(id)) + case rpccapnp.Disembargo_context_Which_receiverLoopback: + d.Context().SetReceiverLoopback(uint32(id)) + default: + panic("unreachable") + } + return msg +} + +// newContext creates a new context for a local call. +func (c *Conn) newContext() (context.Context, context.CancelFunc) { + return context.WithCancel(c.bg) +} + +func promisedAnswerOpsToTransform(list rpccapnp.PromisedAnswer_Op_List) []capnp.PipelineOp { + n := list.Len() + transform := make([]capnp.PipelineOp, 0, n) + for i := 0; i < n; i++ { + op := list.At(i) + switch op.Which() { + case rpccapnp.PromisedAnswer_Op_Which_getPointerField: + transform = append(transform, capnp.PipelineOp{ + Field: op.GetPointerField(), + }) + case rpccapnp.PromisedAnswer_Op_Which_noop: + // no-op + } + } + return transform +} + +func newAbortMessage(buf []byte, err error) rpccapnp.Message { + n := newMessage(buf) + e, _ := n.NewAbort() + toException(e, err) + return n +} + +func newReturnMessage(buf []byte, id answerID) rpccapnp.Message { + retmsg := newMessage(buf) + ret, _ := retmsg.NewReturn() + ret.SetAnswerId(uint32(id)) + ret.SetReleaseParamCaps(false) + return retmsg +} + +func setReturnException(ret rpccapnp.Return, err error) rpccapnp.Exception { + e, _ := rpccapnp.NewException(ret.Segment()) + toException(e, err) + ret.SetException(e) + return e +} + +// clientFromResolution retrieves a client from a resolved question or +// answer by applying a transform. +func clientFromResolution(transform []capnp.PipelineOp, obj capnp.Ptr, err error) capnp.Client { + if err != nil { + return capnp.ErrorClient(err) + } + out, err := capnp.TransformPtr(obj, transform) + if err != nil { + return capnp.ErrorClient(err) + } + c := out.Interface().Client() + if c == nil { + return capnp.ErrorClient(capnp.ErrNullClient) + } + return c +} + +func newMessage(buf []byte) rpccapnp.Message { + _, s, err := capnp.NewMessage(capnp.SingleSegment(buf)) + if err != nil { + panic(err) + } + m, err := rpccapnp.NewRootMessage(s) + if err != nil { + panic(err) + } + return m +} + +// chanMutex is a mutex backed by a channel so that it can be used in a select. +// A receive is a lock and a send is an unlock. +type chanMutex chan struct{} + +type connState int + +const ( + connAlive connState = iota + connDying + connDead +) + +func newChanMutex() chanMutex { + mu := make(chanMutex, 1) + mu <- struct{}{} + return mu +} + +func (mu chanMutex) Lock() { + <-mu +} + +func (mu chanMutex) TryLock(ctx context.Context) error { + select { + case <-mu: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (mu chanMutex) Unlock() { + mu <- struct{}{} +} diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/tables.go b/vendor/zombiezen.com/go/capnproto2/rpc/tables.go new file mode 100644 index 00000000..535f3c3a --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/tables.go @@ -0,0 +1,255 @@ +package rpc + +import ( + "errors" + + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/rpc/internal/refcount" +) + +// Table IDs +type ( + questionID uint32 + answerID uint32 + exportID uint32 + importID uint32 + embargoID uint32 +) + +// impent is an entry in the import table. +type impent struct { + rc *refcount.RefCount + refs int +} + +// addImport increases the counter of the times the import ID was sent to this vat. +func (c *Conn) addImport(id importID) capnp.Client { + if c.imports == nil { + c.imports = make(map[importID]*impent) + } else if ent := c.imports[id]; ent != nil { + ent.refs++ + return ent.rc.Ref() + } + client := &importClient{ + id: id, + conn: c, + } + rc, ref := refcount.New(client) + c.imports[id] = &impent{rc: rc, refs: 1} + return ref +} + +// popImport removes the import ID and returns the number of times the import ID was sent to this vat. +func (c *Conn) popImport(id importID) (refs int) { + if c.imports == nil { + return 0 + } + ent := c.imports[id] + if ent == nil { + return 0 + } + refs = ent.refs + delete(c.imports, id) + return refs +} + +// An importClient implements capnp.Client for a remote capability. +type importClient struct { + id importID + conn *Conn + closed bool // protected by conn.mu +} + +func (ic *importClient) Call(cl *capnp.Call) capnp.Answer { + select { + case <-ic.conn.mu: + if err := ic.conn.startWork(); err != nil { + return capnp.ErrorAnswer(err) + } + case <-cl.Ctx.Done(): + return capnp.ErrorAnswer(cl.Ctx.Err()) + } + ans := ic.lockedCall(cl) + ic.conn.workers.Done() + ic.conn.mu.Unlock() + return ans +} + +// lockedCall is equivalent to Call but assumes that the caller is +// already holding onto ic.conn.mu. +func (ic *importClient) lockedCall(cl *capnp.Call) capnp.Answer { + if ic.closed { + return capnp.ErrorAnswer(errImportClosed) + } + + q := ic.conn.newQuestion(cl.Ctx, &cl.Method) + msg := newMessage(nil) + msgCall, _ := msg.NewCall() + msgCall.SetQuestionId(uint32(q.id)) + msgCall.SetInterfaceId(cl.Method.InterfaceID) + msgCall.SetMethodId(cl.Method.MethodID) + target, _ := msgCall.NewTarget() + target.SetImportedCap(uint32(ic.id)) + payload, _ := msgCall.NewParams() + if err := ic.conn.fillParams(payload, cl); err != nil { + ic.conn.popQuestion(q.id) + return capnp.ErrorAnswer(err) + } + + select { + case ic.conn.out <- msg: + case <-cl.Ctx.Done(): + ic.conn.popQuestion(q.id) + return capnp.ErrorAnswer(cl.Ctx.Err()) + case <-ic.conn.bg.Done(): + ic.conn.popQuestion(q.id) + return capnp.ErrorAnswer(ErrConnClosed) + } + q.start() + return q +} + +func (ic *importClient) Close() error { + ic.conn.mu.Lock() + if err := ic.conn.startWork(); err != nil { + ic.conn.mu.Unlock() + return err + } + closed := ic.closed + var i int + if !closed { + i = ic.conn.popImport(ic.id) + ic.closed = true + } + ic.conn.workers.Done() + ic.conn.mu.Unlock() + + if closed { + return errImportClosed + } + if i == 0 { + return nil + } + msg := newMessage(nil) + mr, err := msg.NewRelease() + if err != nil { + return err + } + mr.SetId(uint32(ic.id)) + mr.SetReferenceCount(uint32(i)) + select { + case ic.conn.out <- msg: + return nil + case <-ic.conn.bg.Done(): + return ErrConnClosed + } +} + +type export struct { + id exportID + rc *refcount.RefCount + client capnp.Client + wireRefs int +} + +func (c *Conn) findExport(id exportID) *export { + if int(id) >= len(c.exports) { + return nil + } + return c.exports[id] +} + +// addExport ensures that the client is present in the table, returning its ID. +// If the client is already in the table, the previous ID is returned. +func (c *Conn) addExport(client capnp.Client) exportID { + for i, e := range c.exports { + if e != nil && isSameClient(e.rc.Client, client) { + e.wireRefs++ + return exportID(i) + } + } + id := exportID(c.exportID.next()) + rc, client := refcount.New(client) + export := &export{ + id: id, + rc: rc, + client: client, + wireRefs: 1, + } + if int(id) == len(c.exports) { + c.exports = append(c.exports, export) + } else { + c.exports[id] = export + } + return id +} + +func (c *Conn) releaseExport(id exportID, refs int) { + e := c.findExport(id) + if e == nil { + return + } + e.wireRefs -= refs + if e.wireRefs > 0 { + return + } + if e.wireRefs < 0 { + c.errorf("warning: export %v has negative refcount (%d)", id, e.wireRefs) + } + if err := e.client.Close(); err != nil { + c.errorf("export %v close: %v", id, err) + } + c.exports[id] = nil + c.exportID.remove(uint32(id)) +} + +type embargo <-chan struct{} + +func (c *Conn) newEmbargo() (embargoID, embargo) { + id := embargoID(c.embargoID.next()) + e := make(chan struct{}) + if int(id) == len(c.embargoes) { + c.embargoes = append(c.embargoes, e) + } else { + c.embargoes[id] = e + } + return id, e +} + +func (c *Conn) disembargo(id embargoID) { + if int(id) >= len(c.embargoes) { + return + } + e := c.embargoes[id] + if e == nil { + return + } + close(e) + c.embargoes[id] = nil + c.embargoID.remove(uint32(id)) +} + +// idgen returns a sequence of monotonically increasing IDs with +// support for replacement. The zero value is a generator that +// starts at zero. +type idgen struct { + i uint32 + free []uint32 +} + +func (gen *idgen) next() uint32 { + if n := len(gen.free); n > 0 { + i := gen.free[n-1] + gen.free = gen.free[:n-1] + return i + } + i := gen.i + gen.i++ + return i +} + +func (gen *idgen) remove(i uint32) { + gen.free = append(gen.free, i) +} + +var errImportClosed = errors.New("rpc: call on closed import") diff --git a/vendor/zombiezen.com/go/capnproto2/rpc/transport.go b/vendor/zombiezen.com/go/capnproto2/rpc/transport.go new file mode 100644 index 00000000..c318703a --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/rpc/transport.go @@ -0,0 +1,175 @@ +package rpc + +import ( + "bytes" + "io" + "time" + + "golang.org/x/net/context" + "zombiezen.com/go/capnproto2" + rpccapnp "zombiezen.com/go/capnproto2/std/capnp/rpc" +) + +// Transport is the interface that abstracts sending and receiving +// individual messages of the Cap'n Proto RPC protocol. +type Transport interface { + // SendMessage sends msg. + SendMessage(ctx context.Context, msg rpccapnp.Message) error + + // RecvMessage waits to receive a message and returns it. + // Implementations may re-use buffers between calls, so the message is + // only valid until the next call to RecvMessage. + RecvMessage(ctx context.Context) (rpccapnp.Message, error) + + // Close releases any resources associated with the transport. + Close() error +} + +type streamTransport struct { + rwc io.ReadWriteCloser + deadline writeDeadlineSetter + + enc *capnp.Encoder + dec *capnp.Decoder + wbuf bytes.Buffer +} + +// StreamTransport creates a transport that sends and receives messages +// by serializing and deserializing unpacked Cap'n Proto messages. +// Closing the transport will close the underlying ReadWriteCloser. +func StreamTransport(rwc io.ReadWriteCloser) Transport { + d, _ := rwc.(writeDeadlineSetter) + s := &streamTransport{ + rwc: rwc, + deadline: d, + dec: capnp.NewDecoder(rwc), + } + s.wbuf.Grow(4096) + s.enc = capnp.NewEncoder(&s.wbuf) + return s +} + +func (s *streamTransport) SendMessage(ctx context.Context, msg rpccapnp.Message) error { + s.wbuf.Reset() + if err := s.enc.Encode(msg.Segment().Message()); err != nil { + return err + } + if s.deadline != nil { + // TODO(light): log errors + if d, ok := ctx.Deadline(); ok { + s.deadline.SetWriteDeadline(d) + } else { + s.deadline.SetWriteDeadline(time.Time{}) + } + } + _, err := s.rwc.Write(s.wbuf.Bytes()) + return err +} + +func (s *streamTransport) RecvMessage(ctx context.Context) (rpccapnp.Message, error) { + var ( + msg *capnp.Message + err error + ) + read := make(chan struct{}) + go func() { + msg, err = s.dec.Decode() + close(read) + }() + select { + case <-read: + case <-ctx.Done(): + return rpccapnp.Message{}, ctx.Err() + } + if err != nil { + return rpccapnp.Message{}, err + } + return rpccapnp.ReadRootMessage(msg) +} + +func (s *streamTransport) Close() error { + return s.rwc.Close() +} + +type writeDeadlineSetter interface { + SetWriteDeadline(t time.Time) error +} + +// dispatchSend runs in its own goroutine and sends messages on a transport. +func (c *Conn) dispatchSend() { + defer c.workers.Done() + for { + select { + case msg := <-c.out: + err := c.transport.SendMessage(c.bg, msg) + if err != nil { + c.errorf("writing %v: %v", msg.Which(), err) + } + case <-c.bg.Done(): + return + } + } +} + +// sendMessage enqueues a message to be sent or returns an error if the +// connection is shut down before the message is queued. It is safe to +// call from multiple goroutines and does not require holding c.mu. +func (c *Conn) sendMessage(msg rpccapnp.Message) error { + select { + case c.out <- msg: + return nil + case <-c.bg.Done(): + return ErrConnClosed + } +} + +// dispatchRecv runs in its own goroutine and receives messages from a transport. +func (c *Conn) dispatchRecv() { + defer c.workers.Done() + for { + msg, err := c.transport.RecvMessage(c.bg) + if err == nil { + c.handleMessage(msg) + } else if isTemporaryError(err) { + c.errorf("read temporary error: %v", err) + } else { + c.shutdown(err) + return + } + } +} + +// copyMessage clones a Cap'n Proto buffer. +func copyMessage(msg *capnp.Message) *capnp.Message { + n := msg.NumSegments() + segments := make([][]byte, n) + for i := range segments { + s, err := msg.Segment(capnp.SegmentID(i)) + if err != nil { + panic(err) + } + segments[i] = make([]byte, len(s.Data())) + copy(segments[i], s.Data()) + } + return &capnp.Message{Arena: capnp.MultiSegment(segments)} +} + +// copyRPCMessage clones an RPC packet. +func copyRPCMessage(m rpccapnp.Message) rpccapnp.Message { + mm := copyMessage(m.Segment().Message()) + rpcMsg, err := rpccapnp.ReadRootMessage(mm) + if err != nil { + panic(err) + } + return rpcMsg +} + +// isTemporaryError reports whether e has a Temporary() method that +// returns true. +func isTemporaryError(e error) bool { + type temp interface { + Temporary() bool + } + t, ok := e.(temp) + return ok && t.Temporary() +} diff --git a/vendor/zombiezen.com/go/capnproto2/schemas/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/schemas/BUILD.bazel new file mode 100644 index 00000000..378c4364 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/schemas/BUILD.bazel @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["schemas.go"], + importpath = "zombiezen.com/go/capnproto2/schemas", + visibility = ["//visibility:public"], + deps = ["//internal/packed:go_default_library"], +) + +go_test( + name = "go_default_test", + srcs = ["schemas_test.go"], + embed = [":go_default_library"], + deps = [ + "//:go_default_library", + "//internal/schema:go_default_library", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/schemas/schemas.go b/vendor/zombiezen.com/go/capnproto2/schemas/schemas.go new file mode 100644 index 00000000..70a174cb --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/schemas/schemas.go @@ -0,0 +1,185 @@ +// Package schemas provides a container for Cap'n Proto reflection data. +// The code generated by capnpc-go will register its schema in the +// default registry (unless disabled at generation time). +// +// Most programs will use the default registry. However, a program +// could dynamically build up a registry, perhaps by invoking the capnp +// tool or querying a service. +package schemas + +import ( + "bufio" + "bytes" + "compress/zlib" + "errors" + "fmt" + "io" + "io/ioutil" + "strings" + "sync" + + "zombiezen.com/go/capnproto2/internal/packed" +) + +// A Schema is a collection of schema nodes parsed by the capnp tool. +type Schema struct { + // Either String or Bytes must be populated with a CodeGeneratorRequest + // message in the standard Cap'n Proto framing format. + String string + Bytes []byte + + // If true, the input is assumed to be zlib-compressed and packed. + Compressed bool + + // Node IDs that are contained in this schema. + Nodes []uint64 +} + +// A Registry is a mapping of IDs to schema blobs. It is safe to read +// from multiple goroutines. The zero value is an empty registry. +type Registry struct { + m map[uint64]*record +} + +// Register indexes a schema in the registry. It is an error to +// register schemas with overlapping IDs. +func (reg *Registry) Register(s *Schema) error { + if len(s.String) > 0 && len(s.Bytes) > 0 { + return errors.New("schemas: schema should have only one of string or bytes") + } + r := &record{ + s: s.String, + data: s.Bytes, + compressed: s.Compressed, + } + if reg.m == nil { + reg.m = make(map[uint64]*record) + } + for _, id := range s.Nodes { + if _, dup := reg.m[id]; dup { + return &dupeError{id: id} + } + reg.m[id] = r + } + return nil +} + +// Find returns the CodeGeneratorRequest message for the given ID, +// suitable for capnp.Unmarshal. If the ID is not found, Find returns +// an error that can be identified with IsNotFound. The returned byte +// slice should not be modified. +func (reg *Registry) Find(id uint64) ([]byte, error) { + r := reg.m[id] + if r == nil { + return nil, ¬FoundError{id: id} + } + b, err := r.read() + if err != nil { + return nil, &decompressError{id, err} + } + return b, nil +} + +type record struct { + // All the fields are protected by once. + once sync.Once + s string // input + compressed bool + data []byte // input and result + err error // result +} + +func (r *record) read() ([]byte, error) { + r.once.Do(func() { + if !r.compressed { + if r.s != "" { + r.data = []byte(r.s) + r.s = "" + } + return + } + var in io.Reader + if r.s != "" { + in = strings.NewReader(r.s) + r.s = "" + } else { + in = bytes.NewReader(r.data) + } + z, err := zlib.NewReader(in) + if err != nil { + r.data, r.err = nil, err + return + } + p := packed.NewReader(bufio.NewReader(z)) + r.data, r.err = ioutil.ReadAll(p) + if r.err != nil { + r.data = nil + return + } + }) + return r.data, r.err +} + +// DefaultRegistry is the process-wide registry used by Register and Find. +var DefaultRegistry Registry + +// Register is called by generated code to associate a blob of zlib- +// compressed, packed Cap'n Proto data for a CodeGeneratorRequest with +// the IDs it contains. It should only be called during init(). +func Register(data string, ids ...uint64) { + err := DefaultRegistry.Register(&Schema{ + String: data, + Nodes: ids, + Compressed: true, + }) + if err != nil { + panic(err) + } +} + +// Find returns the CodeGeneratorRequest message for the given ID, +// suitable for capnp.Unmarshal, or nil if the ID was not found. +// It is safe to call Find from multiple goroutines, so the returned +// byte slice should not be modified. However, it is not safe to +// call Find concurrently with Register. +func Find(id uint64) []byte { + b, err := DefaultRegistry.Find(id) + if IsNotFound(err) { + return nil + } + if err != nil { + panic(err) + } + return b +} + +// IsNotFound reports whether e indicates a failure to find a schema. +func IsNotFound(e error) bool { + _, ok := e.(*notFoundError) + return ok +} + +type dupeError struct { + id uint64 +} + +func (e *dupeError) Error() string { + return fmt.Sprintf("schemas: registered @%#x twice", e.id) +} + +type notFoundError struct { + id uint64 +} + +func (e *notFoundError) Error() string { + return fmt.Sprintf("schemas: could not find @%#x", e.id) +} + +type decompressError struct { + id uint64 + err error +} + +func (e *decompressError) Error() string { + return fmt.Sprintf("schemas: decompressing schema for @%#x: %v", e.id, e.err) +} diff --git a/vendor/zombiezen.com/go/capnproto2/server/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/server/BUILD.bazel new file mode 100644 index 00000000..10395e17 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/server/BUILD.bazel @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["server.go"], + importpath = "zombiezen.com/go/capnproto2/server", + visibility = ["//visibility:public"], + deps = [ + "//:go_default_library", + "//internal/fulfiller:go_default_library", + "@org_golang_x_net//context:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["server_test.go"], + embed = [":go_default_library"], + deps = [ + "//internal/aircraftlib:go_default_library", + "@org_golang_x_net//context:go_default_library", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/server/server.go b/vendor/zombiezen.com/go/capnproto2/server/server.go new file mode 100644 index 00000000..52b055a8 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/server/server.go @@ -0,0 +1,231 @@ +// Package server provides runtime support for implementing Cap'n Proto +// interfaces locally. +package server // import "zombiezen.com/go/capnproto2/server" + +import ( + "errors" + "sort" + "sync" + + "golang.org/x/net/context" + "zombiezen.com/go/capnproto2" + "zombiezen.com/go/capnproto2/internal/fulfiller" +) + +// A Method describes a single method on a server object. +type Method struct { + capnp.Method + Impl Func + ResultsSize capnp.ObjectSize +} + +// A Func is a function that implements a single method. +type Func func(ctx context.Context, options capnp.CallOptions, params, results capnp.Struct) error + +// Closer is the interface that wraps the Close method. +type Closer interface { + Close() error +} + +// A server is a locally implemented interface. +type server struct { + methods sortedMethods + closer Closer + queue chan *call + stop chan struct{} + done chan struct{} +} + +// New returns a client that makes calls to a set of methods. +// If closer is nil then the client's Close is a no-op. The server +// guarantees message delivery order by blocking each call on the +// return or acknowledgment of the previous call. See the Ack function +// for more details. +func New(methods []Method, closer Closer) capnp.Client { + s := &server{ + methods: make(sortedMethods, len(methods)), + closer: closer, + queue: make(chan *call), + stop: make(chan struct{}), + done: make(chan struct{}), + } + copy(s.methods, methods) + sort.Sort(s.methods) + go s.dispatch() + return s +} + +// dispatch runs in its own goroutine. +func (s *server) dispatch() { + defer close(s.done) + for { + select { + case cl := <-s.queue: + err := s.startCall(cl) + if err != nil { + cl.ans.Reject(err) + } + case <-s.stop: + return + } + } +} + +// startCall runs in the dispatch goroutine to start a call. +func (s *server) startCall(cl *call) error { + _, out, err := capnp.NewMessage(capnp.SingleSegment(nil)) + if err != nil { + return err + } + results, err := capnp.NewRootStruct(out, cl.method.ResultsSize) + if err != nil { + return err + } + acksig := newAckSignal() + opts := cl.Options.With([]capnp.CallOption{capnp.SetOptionValue(ackSignalKey, acksig)}) + go func() { + err := cl.method.Impl(cl.Ctx, opts, cl.Params, results) + if err == nil { + cl.ans.Fulfill(results) + } else { + cl.ans.Reject(err) + } + }() + select { + case <-acksig.c: + case <-cl.ans.Done(): + // Implementation functions may not call Ack, which is fine for + // smaller functions. + case <-cl.Ctx.Done(): + // Ideally, this would reject the answer immediately, but then you + // would race with the implementation function. + } + return nil +} + +func (s *server) Call(cl *capnp.Call) capnp.Answer { + sm := s.methods.find(&cl.Method) + if sm == nil { + return capnp.ErrorAnswer(&capnp.MethodError{ + Method: &cl.Method, + Err: capnp.ErrUnimplemented, + }) + } + cl, err := cl.Copy(nil) + if err != nil { + return capnp.ErrorAnswer(err) + } + scall := newCall(cl, sm) + select { + case s.queue <- scall: + return &scall.ans + case <-s.stop: + return capnp.ErrorAnswer(errClosed) + case <-cl.Ctx.Done(): + return capnp.ErrorAnswer(cl.Ctx.Err()) + } +} + +func (s *server) Close() error { + close(s.stop) + <-s.done + if s.closer == nil { + return nil + } + return s.closer.Close() +} + +// Ack acknowledges delivery of a server call, allowing other methods +// to be called on the server. It is intended to be used inside the +// implementation of a server function. Calling Ack on options that +// aren't from a server method implementation is a no-op. +// +// Example: +// +// func (my *myServer) MyMethod(call schema.MyServer_myMethod) error { +// server.Ack(call.Options) +// // ... do long-running operation ... +// return nil +// } +// +// Ack need not be the first call in a function nor is it required. +// Since the function's return is also an acknowledgment of delivery, +// short functions can return without calling Ack. However, since +// clients will not return an Answer until the delivery is acknowledged, +// it is advisable to ack early. +func Ack(opts capnp.CallOptions) { + if ack, _ := opts.Value(ackSignalKey).(*ackSignal); ack != nil { + ack.signal() + } +} + +type call struct { + *capnp.Call + ans fulfiller.Fulfiller + method *Method +} + +func newCall(cl *capnp.Call, sm *Method) *call { + return &call{Call: cl, method: sm} +} + +type sortedMethods []Method + +// find returns the method with the given ID or nil. +func (sm sortedMethods) find(id *capnp.Method) *Method { + i := sort.Search(len(sm), func(i int) bool { + m := &sm[i] + if m.InterfaceID != id.InterfaceID { + return m.InterfaceID >= id.InterfaceID + } + return m.MethodID >= id.MethodID + }) + if i == len(sm) { + return nil + } + m := &sm[i] + if m.InterfaceID != id.InterfaceID || m.MethodID != id.MethodID { + return nil + } + return m +} + +func (sm sortedMethods) Len() int { + return len(sm) +} + +func (sm sortedMethods) Less(i, j int) bool { + if id1, id2 := sm[i].InterfaceID, sm[j].InterfaceID; id1 != id2 { + return id1 < id2 + } + return sm[i].MethodID < sm[j].MethodID +} + +func (sm sortedMethods) Swap(i, j int) { + sm[i], sm[j] = sm[j], sm[i] +} + +type ackSignal struct { + c chan struct{} + once sync.Once +} + +func newAckSignal() *ackSignal { + return &ackSignal{c: make(chan struct{})} +} + +func (ack *ackSignal) signal() { + ack.once.Do(func() { + close(ack.c) + }) +} + +// callOptionKey is the unexported key type for predefined options. +type callOptionKey int + +// Predefined call options +const ( + ackSignalKey callOptionKey = iota + 1 +) + +var errClosed = errors.New("capnp: server closed") diff --git a/vendor/zombiezen.com/go/capnproto2/std/capnp/rpc/BUILD.bazel b/vendor/zombiezen.com/go/capnproto2/std/capnp/rpc/BUILD.bazel new file mode 100644 index 00000000..8a21d804 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/std/capnp/rpc/BUILD.bazel @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["rpc.capnp.go"], + importpath = "zombiezen.com/go/capnproto2/std/capnp/rpc", + visibility = ["//visibility:public"], + deps = [ + "//:go_default_library", + "//encoding/text:go_default_library", + "//schemas:go_default_library", + ], +) diff --git a/vendor/zombiezen.com/go/capnproto2/std/capnp/rpc/rpc.capnp.go b/vendor/zombiezen.com/go/capnproto2/std/capnp/rpc/rpc.capnp.go new file mode 100644 index 00000000..c12bd691 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/std/capnp/rpc/rpc.capnp.go @@ -0,0 +1,2962 @@ +// Code generated by capnpc-go. DO NOT EDIT. + +package rpc + +import ( + strconv "strconv" + capnp "zombiezen.com/go/capnproto2" + text "zombiezen.com/go/capnproto2/encoding/text" + schemas "zombiezen.com/go/capnproto2/schemas" +) + +type Message struct{ capnp.Struct } +type Message_Which uint16 + +const ( + Message_Which_unimplemented Message_Which = 0 + Message_Which_abort Message_Which = 1 + Message_Which_bootstrap Message_Which = 8 + Message_Which_call Message_Which = 2 + Message_Which_return Message_Which = 3 + Message_Which_finish Message_Which = 4 + Message_Which_resolve Message_Which = 5 + Message_Which_release Message_Which = 6 + Message_Which_disembargo Message_Which = 13 + Message_Which_obsoleteSave Message_Which = 7 + Message_Which_obsoleteDelete Message_Which = 9 + Message_Which_provide Message_Which = 10 + Message_Which_accept Message_Which = 11 + Message_Which_join Message_Which = 12 +) + +func (w Message_Which) String() string { + const s = "unimplementedabortbootstrapcallreturnfinishresolvereleasedisembargoobsoleteSaveobsoleteDeleteprovideacceptjoin" + switch w { + case Message_Which_unimplemented: + return s[0:13] + case Message_Which_abort: + return s[13:18] + case Message_Which_bootstrap: + return s[18:27] + case Message_Which_call: + return s[27:31] + case Message_Which_return: + return s[31:37] + case Message_Which_finish: + return s[37:43] + case Message_Which_resolve: + return s[43:50] + case Message_Which_release: + return s[50:57] + case Message_Which_disembargo: + return s[57:67] + case Message_Which_obsoleteSave: + return s[67:79] + case Message_Which_obsoleteDelete: + return s[79:93] + case Message_Which_provide: + return s[93:100] + case Message_Which_accept: + return s[100:106] + case Message_Which_join: + return s[106:110] + + } + return "Message_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Message_TypeID is the unique identifier for the type Message. +const Message_TypeID = 0x91b79f1f808db032 + +func NewMessage(s *capnp.Segment) (Message, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Message{st}, err +} + +func NewRootMessage(s *capnp.Segment) (Message, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Message{st}, err +} + +func ReadRootMessage(msg *capnp.Message) (Message, error) { + root, err := msg.RootPtr() + return Message{root.Struct()}, err +} + +func (s Message) String() string { + str, _ := text.Marshal(0x91b79f1f808db032, s.Struct) + return str +} + +func (s Message) Which() Message_Which { + return Message_Which(s.Struct.Uint16(0)) +} +func (s Message) Unimplemented() (Message, error) { + if s.Struct.Uint16(0) != 0 { + panic("Which() != unimplemented") + } + p, err := s.Struct.Ptr(0) + return Message{Struct: p.Struct()}, err +} + +func (s Message) HasUnimplemented() bool { + if s.Struct.Uint16(0) != 0 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetUnimplemented(v Message) error { + s.Struct.SetUint16(0, 0) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewUnimplemented sets the unimplemented field to a newly +// allocated Message struct, preferring placement in s's segment. +func (s Message) NewUnimplemented() (Message, error) { + s.Struct.SetUint16(0, 0) + ss, err := NewMessage(s.Struct.Segment()) + if err != nil { + return Message{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Abort() (Exception, error) { + if s.Struct.Uint16(0) != 1 { + panic("Which() != abort") + } + p, err := s.Struct.Ptr(0) + return Exception{Struct: p.Struct()}, err +} + +func (s Message) HasAbort() bool { + if s.Struct.Uint16(0) != 1 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetAbort(v Exception) error { + s.Struct.SetUint16(0, 1) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewAbort sets the abort field to a newly +// allocated Exception struct, preferring placement in s's segment. +func (s Message) NewAbort() (Exception, error) { + s.Struct.SetUint16(0, 1) + ss, err := NewException(s.Struct.Segment()) + if err != nil { + return Exception{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Bootstrap() (Bootstrap, error) { + if s.Struct.Uint16(0) != 8 { + panic("Which() != bootstrap") + } + p, err := s.Struct.Ptr(0) + return Bootstrap{Struct: p.Struct()}, err +} + +func (s Message) HasBootstrap() bool { + if s.Struct.Uint16(0) != 8 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetBootstrap(v Bootstrap) error { + s.Struct.SetUint16(0, 8) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewBootstrap sets the bootstrap field to a newly +// allocated Bootstrap struct, preferring placement in s's segment. +func (s Message) NewBootstrap() (Bootstrap, error) { + s.Struct.SetUint16(0, 8) + ss, err := NewBootstrap(s.Struct.Segment()) + if err != nil { + return Bootstrap{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Call() (Call, error) { + if s.Struct.Uint16(0) != 2 { + panic("Which() != call") + } + p, err := s.Struct.Ptr(0) + return Call{Struct: p.Struct()}, err +} + +func (s Message) HasCall() bool { + if s.Struct.Uint16(0) != 2 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetCall(v Call) error { + s.Struct.SetUint16(0, 2) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewCall sets the call field to a newly +// allocated Call struct, preferring placement in s's segment. +func (s Message) NewCall() (Call, error) { + s.Struct.SetUint16(0, 2) + ss, err := NewCall(s.Struct.Segment()) + if err != nil { + return Call{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Return() (Return, error) { + if s.Struct.Uint16(0) != 3 { + panic("Which() != return") + } + p, err := s.Struct.Ptr(0) + return Return{Struct: p.Struct()}, err +} + +func (s Message) HasReturn() bool { + if s.Struct.Uint16(0) != 3 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetReturn(v Return) error { + s.Struct.SetUint16(0, 3) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewReturn sets the return field to a newly +// allocated Return struct, preferring placement in s's segment. +func (s Message) NewReturn() (Return, error) { + s.Struct.SetUint16(0, 3) + ss, err := NewReturn(s.Struct.Segment()) + if err != nil { + return Return{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Finish() (Finish, error) { + if s.Struct.Uint16(0) != 4 { + panic("Which() != finish") + } + p, err := s.Struct.Ptr(0) + return Finish{Struct: p.Struct()}, err +} + +func (s Message) HasFinish() bool { + if s.Struct.Uint16(0) != 4 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetFinish(v Finish) error { + s.Struct.SetUint16(0, 4) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewFinish sets the finish field to a newly +// allocated Finish struct, preferring placement in s's segment. +func (s Message) NewFinish() (Finish, error) { + s.Struct.SetUint16(0, 4) + ss, err := NewFinish(s.Struct.Segment()) + if err != nil { + return Finish{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Resolve() (Resolve, error) { + if s.Struct.Uint16(0) != 5 { + panic("Which() != resolve") + } + p, err := s.Struct.Ptr(0) + return Resolve{Struct: p.Struct()}, err +} + +func (s Message) HasResolve() bool { + if s.Struct.Uint16(0) != 5 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetResolve(v Resolve) error { + s.Struct.SetUint16(0, 5) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewResolve sets the resolve field to a newly +// allocated Resolve struct, preferring placement in s's segment. +func (s Message) NewResolve() (Resolve, error) { + s.Struct.SetUint16(0, 5) + ss, err := NewResolve(s.Struct.Segment()) + if err != nil { + return Resolve{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Release() (Release, error) { + if s.Struct.Uint16(0) != 6 { + panic("Which() != release") + } + p, err := s.Struct.Ptr(0) + return Release{Struct: p.Struct()}, err +} + +func (s Message) HasRelease() bool { + if s.Struct.Uint16(0) != 6 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetRelease(v Release) error { + s.Struct.SetUint16(0, 6) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewRelease sets the release field to a newly +// allocated Release struct, preferring placement in s's segment. +func (s Message) NewRelease() (Release, error) { + s.Struct.SetUint16(0, 6) + ss, err := NewRelease(s.Struct.Segment()) + if err != nil { + return Release{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Disembargo() (Disembargo, error) { + if s.Struct.Uint16(0) != 13 { + panic("Which() != disembargo") + } + p, err := s.Struct.Ptr(0) + return Disembargo{Struct: p.Struct()}, err +} + +func (s Message) HasDisembargo() bool { + if s.Struct.Uint16(0) != 13 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetDisembargo(v Disembargo) error { + s.Struct.SetUint16(0, 13) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewDisembargo sets the disembargo field to a newly +// allocated Disembargo struct, preferring placement in s's segment. +func (s Message) NewDisembargo() (Disembargo, error) { + s.Struct.SetUint16(0, 13) + ss, err := NewDisembargo(s.Struct.Segment()) + if err != nil { + return Disembargo{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) ObsoleteSave() (capnp.Pointer, error) { + if s.Struct.Uint16(0) != 7 { + panic("Which() != obsoleteSave") + } + return s.Struct.Pointer(0) +} + +func (s Message) HasObsoleteSave() bool { + if s.Struct.Uint16(0) != 7 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) ObsoleteSavePtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Message) SetObsoleteSave(v capnp.Pointer) error { + s.Struct.SetUint16(0, 7) + return s.Struct.SetPointer(0, v) +} + +func (s Message) SetObsoleteSavePtr(v capnp.Ptr) error { + s.Struct.SetUint16(0, 7) + return s.Struct.SetPtr(0, v) +} + +func (s Message) ObsoleteDelete() (capnp.Pointer, error) { + if s.Struct.Uint16(0) != 9 { + panic("Which() != obsoleteDelete") + } + return s.Struct.Pointer(0) +} + +func (s Message) HasObsoleteDelete() bool { + if s.Struct.Uint16(0) != 9 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) ObsoleteDeletePtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Message) SetObsoleteDelete(v capnp.Pointer) error { + s.Struct.SetUint16(0, 9) + return s.Struct.SetPointer(0, v) +} + +func (s Message) SetObsoleteDeletePtr(v capnp.Ptr) error { + s.Struct.SetUint16(0, 9) + return s.Struct.SetPtr(0, v) +} + +func (s Message) Provide() (Provide, error) { + if s.Struct.Uint16(0) != 10 { + panic("Which() != provide") + } + p, err := s.Struct.Ptr(0) + return Provide{Struct: p.Struct()}, err +} + +func (s Message) HasProvide() bool { + if s.Struct.Uint16(0) != 10 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetProvide(v Provide) error { + s.Struct.SetUint16(0, 10) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewProvide sets the provide field to a newly +// allocated Provide struct, preferring placement in s's segment. +func (s Message) NewProvide() (Provide, error) { + s.Struct.SetUint16(0, 10) + ss, err := NewProvide(s.Struct.Segment()) + if err != nil { + return Provide{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Accept() (Accept, error) { + if s.Struct.Uint16(0) != 11 { + panic("Which() != accept") + } + p, err := s.Struct.Ptr(0) + return Accept{Struct: p.Struct()}, err +} + +func (s Message) HasAccept() bool { + if s.Struct.Uint16(0) != 11 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetAccept(v Accept) error { + s.Struct.SetUint16(0, 11) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewAccept sets the accept field to a newly +// allocated Accept struct, preferring placement in s's segment. +func (s Message) NewAccept() (Accept, error) { + s.Struct.SetUint16(0, 11) + ss, err := NewAccept(s.Struct.Segment()) + if err != nil { + return Accept{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Message) Join() (Join, error) { + if s.Struct.Uint16(0) != 12 { + panic("Which() != join") + } + p, err := s.Struct.Ptr(0) + return Join{Struct: p.Struct()}, err +} + +func (s Message) HasJoin() bool { + if s.Struct.Uint16(0) != 12 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Message) SetJoin(v Join) error { + s.Struct.SetUint16(0, 12) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewJoin sets the join field to a newly +// allocated Join struct, preferring placement in s's segment. +func (s Message) NewJoin() (Join, error) { + s.Struct.SetUint16(0, 12) + ss, err := NewJoin(s.Struct.Segment()) + if err != nil { + return Join{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +// Message_List is a list of Message. +type Message_List struct{ capnp.List } + +// NewMessage creates a new list of Message. +func NewMessage_List(s *capnp.Segment, sz int32) (Message_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Message_List{l}, err +} + +func (s Message_List) At(i int) Message { return Message{s.List.Struct(i)} } + +func (s Message_List) Set(i int, v Message) error { return s.List.SetStruct(i, v.Struct) } + +func (s Message_List) String() string { + str, _ := text.MarshalList(0x91b79f1f808db032, s.List) + return str +} + +// Message_Promise is a wrapper for a Message promised by a client call. +type Message_Promise struct{ *capnp.Pipeline } + +func (p Message_Promise) Struct() (Message, error) { + s, err := p.Pipeline.Struct() + return Message{s}, err +} + +func (p Message_Promise) Unimplemented() Message_Promise { + return Message_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Abort() Exception_Promise { + return Exception_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Bootstrap() Bootstrap_Promise { + return Bootstrap_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Call() Call_Promise { + return Call_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Return() Return_Promise { + return Return_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Finish() Finish_Promise { + return Finish_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Resolve() Resolve_Promise { + return Resolve_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Release() Release_Promise { + return Release_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Disembargo() Disembargo_Promise { + return Disembargo_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) ObsoleteSave() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +func (p Message_Promise) ObsoleteDelete() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +func (p Message_Promise) Provide() Provide_Promise { + return Provide_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Accept() Accept_Promise { + return Accept_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Message_Promise) Join() Join_Promise { + return Join_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +type Bootstrap struct{ capnp.Struct } + +// Bootstrap_TypeID is the unique identifier for the type Bootstrap. +const Bootstrap_TypeID = 0xe94ccf8031176ec4 + +func NewBootstrap(s *capnp.Segment) (Bootstrap, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Bootstrap{st}, err +} + +func NewRootBootstrap(s *capnp.Segment) (Bootstrap, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Bootstrap{st}, err +} + +func ReadRootBootstrap(msg *capnp.Message) (Bootstrap, error) { + root, err := msg.RootPtr() + return Bootstrap{root.Struct()}, err +} + +func (s Bootstrap) String() string { + str, _ := text.Marshal(0xe94ccf8031176ec4, s.Struct) + return str +} + +func (s Bootstrap) QuestionId() uint32 { + return s.Struct.Uint32(0) +} + +func (s Bootstrap) SetQuestionId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Bootstrap) DeprecatedObjectId() (capnp.Pointer, error) { + return s.Struct.Pointer(0) +} + +func (s Bootstrap) HasDeprecatedObjectId() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Bootstrap) DeprecatedObjectIdPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Bootstrap) SetDeprecatedObjectId(v capnp.Pointer) error { + return s.Struct.SetPointer(0, v) +} + +func (s Bootstrap) SetDeprecatedObjectIdPtr(v capnp.Ptr) error { + return s.Struct.SetPtr(0, v) +} + +// Bootstrap_List is a list of Bootstrap. +type Bootstrap_List struct{ capnp.List } + +// NewBootstrap creates a new list of Bootstrap. +func NewBootstrap_List(s *capnp.Segment, sz int32) (Bootstrap_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Bootstrap_List{l}, err +} + +func (s Bootstrap_List) At(i int) Bootstrap { return Bootstrap{s.List.Struct(i)} } + +func (s Bootstrap_List) Set(i int, v Bootstrap) error { return s.List.SetStruct(i, v.Struct) } + +func (s Bootstrap_List) String() string { + str, _ := text.MarshalList(0xe94ccf8031176ec4, s.List) + return str +} + +// Bootstrap_Promise is a wrapper for a Bootstrap promised by a client call. +type Bootstrap_Promise struct{ *capnp.Pipeline } + +func (p Bootstrap_Promise) Struct() (Bootstrap, error) { + s, err := p.Pipeline.Struct() + return Bootstrap{s}, err +} + +func (p Bootstrap_Promise) DeprecatedObjectId() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +type Call struct{ capnp.Struct } +type Call_sendResultsTo Call +type Call_sendResultsTo_Which uint16 + +const ( + Call_sendResultsTo_Which_caller Call_sendResultsTo_Which = 0 + Call_sendResultsTo_Which_yourself Call_sendResultsTo_Which = 1 + Call_sendResultsTo_Which_thirdParty Call_sendResultsTo_Which = 2 +) + +func (w Call_sendResultsTo_Which) String() string { + const s = "calleryourselfthirdParty" + switch w { + case Call_sendResultsTo_Which_caller: + return s[0:6] + case Call_sendResultsTo_Which_yourself: + return s[6:14] + case Call_sendResultsTo_Which_thirdParty: + return s[14:24] + + } + return "Call_sendResultsTo_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Call_TypeID is the unique identifier for the type Call. +const Call_TypeID = 0x836a53ce789d4cd4 + +func NewCall(s *capnp.Segment) (Call, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 24, PointerCount: 3}) + return Call{st}, err +} + +func NewRootCall(s *capnp.Segment) (Call, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 24, PointerCount: 3}) + return Call{st}, err +} + +func ReadRootCall(msg *capnp.Message) (Call, error) { + root, err := msg.RootPtr() + return Call{root.Struct()}, err +} + +func (s Call) String() string { + str, _ := text.Marshal(0x836a53ce789d4cd4, s.Struct) + return str +} + +func (s Call) QuestionId() uint32 { + return s.Struct.Uint32(0) +} + +func (s Call) SetQuestionId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Call) Target() (MessageTarget, error) { + p, err := s.Struct.Ptr(0) + return MessageTarget{Struct: p.Struct()}, err +} + +func (s Call) HasTarget() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Call) SetTarget(v MessageTarget) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewTarget sets the target field to a newly +// allocated MessageTarget struct, preferring placement in s's segment. +func (s Call) NewTarget() (MessageTarget, error) { + ss, err := NewMessageTarget(s.Struct.Segment()) + if err != nil { + return MessageTarget{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Call) InterfaceId() uint64 { + return s.Struct.Uint64(8) +} + +func (s Call) SetInterfaceId(v uint64) { + s.Struct.SetUint64(8, v) +} + +func (s Call) MethodId() uint16 { + return s.Struct.Uint16(4) +} + +func (s Call) SetMethodId(v uint16) { + s.Struct.SetUint16(4, v) +} + +func (s Call) AllowThirdPartyTailCall() bool { + return s.Struct.Bit(128) +} + +func (s Call) SetAllowThirdPartyTailCall(v bool) { + s.Struct.SetBit(128, v) +} + +func (s Call) Params() (Payload, error) { + p, err := s.Struct.Ptr(1) + return Payload{Struct: p.Struct()}, err +} + +func (s Call) HasParams() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Call) SetParams(v Payload) error { + return s.Struct.SetPtr(1, v.Struct.ToPtr()) +} + +// NewParams sets the params field to a newly +// allocated Payload struct, preferring placement in s's segment. +func (s Call) NewParams() (Payload, error) { + ss, err := NewPayload(s.Struct.Segment()) + if err != nil { + return Payload{}, err + } + err = s.Struct.SetPtr(1, ss.Struct.ToPtr()) + return ss, err +} + +func (s Call) SendResultsTo() Call_sendResultsTo { return Call_sendResultsTo(s) } + +func (s Call_sendResultsTo) Which() Call_sendResultsTo_Which { + return Call_sendResultsTo_Which(s.Struct.Uint16(6)) +} +func (s Call_sendResultsTo) SetCaller() { + s.Struct.SetUint16(6, 0) + +} + +func (s Call_sendResultsTo) SetYourself() { + s.Struct.SetUint16(6, 1) + +} + +func (s Call_sendResultsTo) ThirdParty() (capnp.Pointer, error) { + if s.Struct.Uint16(6) != 2 { + panic("Which() != thirdParty") + } + return s.Struct.Pointer(2) +} + +func (s Call_sendResultsTo) HasThirdParty() bool { + if s.Struct.Uint16(6) != 2 { + return false + } + p, err := s.Struct.Ptr(2) + return p.IsValid() || err != nil +} + +func (s Call_sendResultsTo) ThirdPartyPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(2) +} + +func (s Call_sendResultsTo) SetThirdParty(v capnp.Pointer) error { + s.Struct.SetUint16(6, 2) + return s.Struct.SetPointer(2, v) +} + +func (s Call_sendResultsTo) SetThirdPartyPtr(v capnp.Ptr) error { + s.Struct.SetUint16(6, 2) + return s.Struct.SetPtr(2, v) +} + +// Call_List is a list of Call. +type Call_List struct{ capnp.List } + +// NewCall creates a new list of Call. +func NewCall_List(s *capnp.Segment, sz int32) (Call_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 24, PointerCount: 3}, sz) + return Call_List{l}, err +} + +func (s Call_List) At(i int) Call { return Call{s.List.Struct(i)} } + +func (s Call_List) Set(i int, v Call) error { return s.List.SetStruct(i, v.Struct) } + +func (s Call_List) String() string { + str, _ := text.MarshalList(0x836a53ce789d4cd4, s.List) + return str +} + +// Call_Promise is a wrapper for a Call promised by a client call. +type Call_Promise struct{ *capnp.Pipeline } + +func (p Call_Promise) Struct() (Call, error) { + s, err := p.Pipeline.Struct() + return Call{s}, err +} + +func (p Call_Promise) Target() MessageTarget_Promise { + return MessageTarget_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Call_Promise) Params() Payload_Promise { + return Payload_Promise{Pipeline: p.Pipeline.GetPipeline(1)} +} + +func (p Call_Promise) SendResultsTo() Call_sendResultsTo_Promise { + return Call_sendResultsTo_Promise{p.Pipeline} +} + +// Call_sendResultsTo_Promise is a wrapper for a Call_sendResultsTo promised by a client call. +type Call_sendResultsTo_Promise struct{ *capnp.Pipeline } + +func (p Call_sendResultsTo_Promise) Struct() (Call_sendResultsTo, error) { + s, err := p.Pipeline.Struct() + return Call_sendResultsTo{s}, err +} + +func (p Call_sendResultsTo_Promise) ThirdParty() *capnp.Pipeline { + return p.Pipeline.GetPipeline(2) +} + +type Return struct{ capnp.Struct } +type Return_Which uint16 + +const ( + Return_Which_results Return_Which = 0 + Return_Which_exception Return_Which = 1 + Return_Which_canceled Return_Which = 2 + Return_Which_resultsSentElsewhere Return_Which = 3 + Return_Which_takeFromOtherQuestion Return_Which = 4 + Return_Which_acceptFromThirdParty Return_Which = 5 +) + +func (w Return_Which) String() string { + const s = "resultsexceptioncanceledresultsSentElsewheretakeFromOtherQuestionacceptFromThirdParty" + switch w { + case Return_Which_results: + return s[0:7] + case Return_Which_exception: + return s[7:16] + case Return_Which_canceled: + return s[16:24] + case Return_Which_resultsSentElsewhere: + return s[24:44] + case Return_Which_takeFromOtherQuestion: + return s[44:65] + case Return_Which_acceptFromThirdParty: + return s[65:85] + + } + return "Return_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Return_TypeID is the unique identifier for the type Return. +const Return_TypeID = 0x9e19b28d3db3573a + +func NewReturn(s *capnp.Segment) (Return, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}) + return Return{st}, err +} + +func NewRootReturn(s *capnp.Segment) (Return, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}) + return Return{st}, err +} + +func ReadRootReturn(msg *capnp.Message) (Return, error) { + root, err := msg.RootPtr() + return Return{root.Struct()}, err +} + +func (s Return) String() string { + str, _ := text.Marshal(0x9e19b28d3db3573a, s.Struct) + return str +} + +func (s Return) Which() Return_Which { + return Return_Which(s.Struct.Uint16(6)) +} +func (s Return) AnswerId() uint32 { + return s.Struct.Uint32(0) +} + +func (s Return) SetAnswerId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Return) ReleaseParamCaps() bool { + return !s.Struct.Bit(32) +} + +func (s Return) SetReleaseParamCaps(v bool) { + s.Struct.SetBit(32, !v) +} + +func (s Return) Results() (Payload, error) { + if s.Struct.Uint16(6) != 0 { + panic("Which() != results") + } + p, err := s.Struct.Ptr(0) + return Payload{Struct: p.Struct()}, err +} + +func (s Return) HasResults() bool { + if s.Struct.Uint16(6) != 0 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Return) SetResults(v Payload) error { + s.Struct.SetUint16(6, 0) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewResults sets the results field to a newly +// allocated Payload struct, preferring placement in s's segment. +func (s Return) NewResults() (Payload, error) { + s.Struct.SetUint16(6, 0) + ss, err := NewPayload(s.Struct.Segment()) + if err != nil { + return Payload{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Return) Exception() (Exception, error) { + if s.Struct.Uint16(6) != 1 { + panic("Which() != exception") + } + p, err := s.Struct.Ptr(0) + return Exception{Struct: p.Struct()}, err +} + +func (s Return) HasException() bool { + if s.Struct.Uint16(6) != 1 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Return) SetException(v Exception) error { + s.Struct.SetUint16(6, 1) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewException sets the exception field to a newly +// allocated Exception struct, preferring placement in s's segment. +func (s Return) NewException() (Exception, error) { + s.Struct.SetUint16(6, 1) + ss, err := NewException(s.Struct.Segment()) + if err != nil { + return Exception{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Return) SetCanceled() { + s.Struct.SetUint16(6, 2) + +} + +func (s Return) SetResultsSentElsewhere() { + s.Struct.SetUint16(6, 3) + +} + +func (s Return) TakeFromOtherQuestion() uint32 { + if s.Struct.Uint16(6) != 4 { + panic("Which() != takeFromOtherQuestion") + } + return s.Struct.Uint32(8) +} + +func (s Return) SetTakeFromOtherQuestion(v uint32) { + s.Struct.SetUint16(6, 4) + s.Struct.SetUint32(8, v) +} + +func (s Return) AcceptFromThirdParty() (capnp.Pointer, error) { + if s.Struct.Uint16(6) != 5 { + panic("Which() != acceptFromThirdParty") + } + return s.Struct.Pointer(0) +} + +func (s Return) HasAcceptFromThirdParty() bool { + if s.Struct.Uint16(6) != 5 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Return) AcceptFromThirdPartyPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Return) SetAcceptFromThirdParty(v capnp.Pointer) error { + s.Struct.SetUint16(6, 5) + return s.Struct.SetPointer(0, v) +} + +func (s Return) SetAcceptFromThirdPartyPtr(v capnp.Ptr) error { + s.Struct.SetUint16(6, 5) + return s.Struct.SetPtr(0, v) +} + +// Return_List is a list of Return. +type Return_List struct{ capnp.List } + +// NewReturn creates a new list of Return. +func NewReturn_List(s *capnp.Segment, sz int32) (Return_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}, sz) + return Return_List{l}, err +} + +func (s Return_List) At(i int) Return { return Return{s.List.Struct(i)} } + +func (s Return_List) Set(i int, v Return) error { return s.List.SetStruct(i, v.Struct) } + +func (s Return_List) String() string { + str, _ := text.MarshalList(0x9e19b28d3db3573a, s.List) + return str +} + +// Return_Promise is a wrapper for a Return promised by a client call. +type Return_Promise struct{ *capnp.Pipeline } + +func (p Return_Promise) Struct() (Return, error) { + s, err := p.Pipeline.Struct() + return Return{s}, err +} + +func (p Return_Promise) Results() Payload_Promise { + return Payload_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Return_Promise) Exception() Exception_Promise { + return Exception_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Return_Promise) AcceptFromThirdParty() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +type Finish struct{ capnp.Struct } + +// Finish_TypeID is the unique identifier for the type Finish. +const Finish_TypeID = 0xd37d2eb2c2f80e63 + +func NewFinish(s *capnp.Segment) (Finish, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}) + return Finish{st}, err +} + +func NewRootFinish(s *capnp.Segment) (Finish, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}) + return Finish{st}, err +} + +func ReadRootFinish(msg *capnp.Message) (Finish, error) { + root, err := msg.RootPtr() + return Finish{root.Struct()}, err +} + +func (s Finish) String() string { + str, _ := text.Marshal(0xd37d2eb2c2f80e63, s.Struct) + return str +} + +func (s Finish) QuestionId() uint32 { + return s.Struct.Uint32(0) +} + +func (s Finish) SetQuestionId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Finish) ReleaseResultCaps() bool { + return !s.Struct.Bit(32) +} + +func (s Finish) SetReleaseResultCaps(v bool) { + s.Struct.SetBit(32, !v) +} + +// Finish_List is a list of Finish. +type Finish_List struct{ capnp.List } + +// NewFinish creates a new list of Finish. +func NewFinish_List(s *capnp.Segment, sz int32) (Finish_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}, sz) + return Finish_List{l}, err +} + +func (s Finish_List) At(i int) Finish { return Finish{s.List.Struct(i)} } + +func (s Finish_List) Set(i int, v Finish) error { return s.List.SetStruct(i, v.Struct) } + +func (s Finish_List) String() string { + str, _ := text.MarshalList(0xd37d2eb2c2f80e63, s.List) + return str +} + +// Finish_Promise is a wrapper for a Finish promised by a client call. +type Finish_Promise struct{ *capnp.Pipeline } + +func (p Finish_Promise) Struct() (Finish, error) { + s, err := p.Pipeline.Struct() + return Finish{s}, err +} + +type Resolve struct{ capnp.Struct } +type Resolve_Which uint16 + +const ( + Resolve_Which_cap Resolve_Which = 0 + Resolve_Which_exception Resolve_Which = 1 +) + +func (w Resolve_Which) String() string { + const s = "capexception" + switch w { + case Resolve_Which_cap: + return s[0:3] + case Resolve_Which_exception: + return s[3:12] + + } + return "Resolve_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Resolve_TypeID is the unique identifier for the type Resolve. +const Resolve_TypeID = 0xbbc29655fa89086e + +func NewResolve(s *capnp.Segment) (Resolve, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Resolve{st}, err +} + +func NewRootResolve(s *capnp.Segment) (Resolve, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Resolve{st}, err +} + +func ReadRootResolve(msg *capnp.Message) (Resolve, error) { + root, err := msg.RootPtr() + return Resolve{root.Struct()}, err +} + +func (s Resolve) String() string { + str, _ := text.Marshal(0xbbc29655fa89086e, s.Struct) + return str +} + +func (s Resolve) Which() Resolve_Which { + return Resolve_Which(s.Struct.Uint16(4)) +} +func (s Resolve) PromiseId() uint32 { + return s.Struct.Uint32(0) +} + +func (s Resolve) SetPromiseId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Resolve) Cap() (CapDescriptor, error) { + if s.Struct.Uint16(4) != 0 { + panic("Which() != cap") + } + p, err := s.Struct.Ptr(0) + return CapDescriptor{Struct: p.Struct()}, err +} + +func (s Resolve) HasCap() bool { + if s.Struct.Uint16(4) != 0 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Resolve) SetCap(v CapDescriptor) error { + s.Struct.SetUint16(4, 0) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewCap sets the cap field to a newly +// allocated CapDescriptor struct, preferring placement in s's segment. +func (s Resolve) NewCap() (CapDescriptor, error) { + s.Struct.SetUint16(4, 0) + ss, err := NewCapDescriptor(s.Struct.Segment()) + if err != nil { + return CapDescriptor{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Resolve) Exception() (Exception, error) { + if s.Struct.Uint16(4) != 1 { + panic("Which() != exception") + } + p, err := s.Struct.Ptr(0) + return Exception{Struct: p.Struct()}, err +} + +func (s Resolve) HasException() bool { + if s.Struct.Uint16(4) != 1 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Resolve) SetException(v Exception) error { + s.Struct.SetUint16(4, 1) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewException sets the exception field to a newly +// allocated Exception struct, preferring placement in s's segment. +func (s Resolve) NewException() (Exception, error) { + s.Struct.SetUint16(4, 1) + ss, err := NewException(s.Struct.Segment()) + if err != nil { + return Exception{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +// Resolve_List is a list of Resolve. +type Resolve_List struct{ capnp.List } + +// NewResolve creates a new list of Resolve. +func NewResolve_List(s *capnp.Segment, sz int32) (Resolve_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Resolve_List{l}, err +} + +func (s Resolve_List) At(i int) Resolve { return Resolve{s.List.Struct(i)} } + +func (s Resolve_List) Set(i int, v Resolve) error { return s.List.SetStruct(i, v.Struct) } + +func (s Resolve_List) String() string { + str, _ := text.MarshalList(0xbbc29655fa89086e, s.List) + return str +} + +// Resolve_Promise is a wrapper for a Resolve promised by a client call. +type Resolve_Promise struct{ *capnp.Pipeline } + +func (p Resolve_Promise) Struct() (Resolve, error) { + s, err := p.Pipeline.Struct() + return Resolve{s}, err +} + +func (p Resolve_Promise) Cap() CapDescriptor_Promise { + return CapDescriptor_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Resolve_Promise) Exception() Exception_Promise { + return Exception_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +type Release struct{ capnp.Struct } + +// Release_TypeID is the unique identifier for the type Release. +const Release_TypeID = 0xad1a6c0d7dd07497 + +func NewRelease(s *capnp.Segment) (Release, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}) + return Release{st}, err +} + +func NewRootRelease(s *capnp.Segment) (Release, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}) + return Release{st}, err +} + +func ReadRootRelease(msg *capnp.Message) (Release, error) { + root, err := msg.RootPtr() + return Release{root.Struct()}, err +} + +func (s Release) String() string { + str, _ := text.Marshal(0xad1a6c0d7dd07497, s.Struct) + return str +} + +func (s Release) Id() uint32 { + return s.Struct.Uint32(0) +} + +func (s Release) SetId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Release) ReferenceCount() uint32 { + return s.Struct.Uint32(4) +} + +func (s Release) SetReferenceCount(v uint32) { + s.Struct.SetUint32(4, v) +} + +// Release_List is a list of Release. +type Release_List struct{ capnp.List } + +// NewRelease creates a new list of Release. +func NewRelease_List(s *capnp.Segment, sz int32) (Release_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}, sz) + return Release_List{l}, err +} + +func (s Release_List) At(i int) Release { return Release{s.List.Struct(i)} } + +func (s Release_List) Set(i int, v Release) error { return s.List.SetStruct(i, v.Struct) } + +func (s Release_List) String() string { + str, _ := text.MarshalList(0xad1a6c0d7dd07497, s.List) + return str +} + +// Release_Promise is a wrapper for a Release promised by a client call. +type Release_Promise struct{ *capnp.Pipeline } + +func (p Release_Promise) Struct() (Release, error) { + s, err := p.Pipeline.Struct() + return Release{s}, err +} + +type Disembargo struct{ capnp.Struct } +type Disembargo_context Disembargo +type Disembargo_context_Which uint16 + +const ( + Disembargo_context_Which_senderLoopback Disembargo_context_Which = 0 + Disembargo_context_Which_receiverLoopback Disembargo_context_Which = 1 + Disembargo_context_Which_accept Disembargo_context_Which = 2 + Disembargo_context_Which_provide Disembargo_context_Which = 3 +) + +func (w Disembargo_context_Which) String() string { + const s = "senderLoopbackreceiverLoopbackacceptprovide" + switch w { + case Disembargo_context_Which_senderLoopback: + return s[0:14] + case Disembargo_context_Which_receiverLoopback: + return s[14:30] + case Disembargo_context_Which_accept: + return s[30:36] + case Disembargo_context_Which_provide: + return s[36:43] + + } + return "Disembargo_context_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// Disembargo_TypeID is the unique identifier for the type Disembargo. +const Disembargo_TypeID = 0xf964368b0fbd3711 + +func NewDisembargo(s *capnp.Segment) (Disembargo, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Disembargo{st}, err +} + +func NewRootDisembargo(s *capnp.Segment) (Disembargo, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Disembargo{st}, err +} + +func ReadRootDisembargo(msg *capnp.Message) (Disembargo, error) { + root, err := msg.RootPtr() + return Disembargo{root.Struct()}, err +} + +func (s Disembargo) String() string { + str, _ := text.Marshal(0xf964368b0fbd3711, s.Struct) + return str +} + +func (s Disembargo) Target() (MessageTarget, error) { + p, err := s.Struct.Ptr(0) + return MessageTarget{Struct: p.Struct()}, err +} + +func (s Disembargo) HasTarget() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Disembargo) SetTarget(v MessageTarget) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewTarget sets the target field to a newly +// allocated MessageTarget struct, preferring placement in s's segment. +func (s Disembargo) NewTarget() (MessageTarget, error) { + ss, err := NewMessageTarget(s.Struct.Segment()) + if err != nil { + return MessageTarget{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Disembargo) Context() Disembargo_context { return Disembargo_context(s) } + +func (s Disembargo_context) Which() Disembargo_context_Which { + return Disembargo_context_Which(s.Struct.Uint16(4)) +} +func (s Disembargo_context) SenderLoopback() uint32 { + if s.Struct.Uint16(4) != 0 { + panic("Which() != senderLoopback") + } + return s.Struct.Uint32(0) +} + +func (s Disembargo_context) SetSenderLoopback(v uint32) { + s.Struct.SetUint16(4, 0) + s.Struct.SetUint32(0, v) +} + +func (s Disembargo_context) ReceiverLoopback() uint32 { + if s.Struct.Uint16(4) != 1 { + panic("Which() != receiverLoopback") + } + return s.Struct.Uint32(0) +} + +func (s Disembargo_context) SetReceiverLoopback(v uint32) { + s.Struct.SetUint16(4, 1) + s.Struct.SetUint32(0, v) +} + +func (s Disembargo_context) SetAccept() { + s.Struct.SetUint16(4, 2) + +} + +func (s Disembargo_context) Provide() uint32 { + if s.Struct.Uint16(4) != 3 { + panic("Which() != provide") + } + return s.Struct.Uint32(0) +} + +func (s Disembargo_context) SetProvide(v uint32) { + s.Struct.SetUint16(4, 3) + s.Struct.SetUint32(0, v) +} + +// Disembargo_List is a list of Disembargo. +type Disembargo_List struct{ capnp.List } + +// NewDisembargo creates a new list of Disembargo. +func NewDisembargo_List(s *capnp.Segment, sz int32) (Disembargo_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Disembargo_List{l}, err +} + +func (s Disembargo_List) At(i int) Disembargo { return Disembargo{s.List.Struct(i)} } + +func (s Disembargo_List) Set(i int, v Disembargo) error { return s.List.SetStruct(i, v.Struct) } + +func (s Disembargo_List) String() string { + str, _ := text.MarshalList(0xf964368b0fbd3711, s.List) + return str +} + +// Disembargo_Promise is a wrapper for a Disembargo promised by a client call. +type Disembargo_Promise struct{ *capnp.Pipeline } + +func (p Disembargo_Promise) Struct() (Disembargo, error) { + s, err := p.Pipeline.Struct() + return Disembargo{s}, err +} + +func (p Disembargo_Promise) Target() MessageTarget_Promise { + return MessageTarget_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Disembargo_Promise) Context() Disembargo_context_Promise { + return Disembargo_context_Promise{p.Pipeline} +} + +// Disembargo_context_Promise is a wrapper for a Disembargo_context promised by a client call. +type Disembargo_context_Promise struct{ *capnp.Pipeline } + +func (p Disembargo_context_Promise) Struct() (Disembargo_context, error) { + s, err := p.Pipeline.Struct() + return Disembargo_context{s}, err +} + +type Provide struct{ capnp.Struct } + +// Provide_TypeID is the unique identifier for the type Provide. +const Provide_TypeID = 0x9c6a046bfbc1ac5a + +func NewProvide(s *capnp.Segment) (Provide, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return Provide{st}, err +} + +func NewRootProvide(s *capnp.Segment) (Provide, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return Provide{st}, err +} + +func ReadRootProvide(msg *capnp.Message) (Provide, error) { + root, err := msg.RootPtr() + return Provide{root.Struct()}, err +} + +func (s Provide) String() string { + str, _ := text.Marshal(0x9c6a046bfbc1ac5a, s.Struct) + return str +} + +func (s Provide) QuestionId() uint32 { + return s.Struct.Uint32(0) +} + +func (s Provide) SetQuestionId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Provide) Target() (MessageTarget, error) { + p, err := s.Struct.Ptr(0) + return MessageTarget{Struct: p.Struct()}, err +} + +func (s Provide) HasTarget() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Provide) SetTarget(v MessageTarget) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewTarget sets the target field to a newly +// allocated MessageTarget struct, preferring placement in s's segment. +func (s Provide) NewTarget() (MessageTarget, error) { + ss, err := NewMessageTarget(s.Struct.Segment()) + if err != nil { + return MessageTarget{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Provide) Recipient() (capnp.Pointer, error) { + return s.Struct.Pointer(1) +} + +func (s Provide) HasRecipient() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Provide) RecipientPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(1) +} + +func (s Provide) SetRecipient(v capnp.Pointer) error { + return s.Struct.SetPointer(1, v) +} + +func (s Provide) SetRecipientPtr(v capnp.Ptr) error { + return s.Struct.SetPtr(1, v) +} + +// Provide_List is a list of Provide. +type Provide_List struct{ capnp.List } + +// NewProvide creates a new list of Provide. +func NewProvide_List(s *capnp.Segment, sz int32) (Provide_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz) + return Provide_List{l}, err +} + +func (s Provide_List) At(i int) Provide { return Provide{s.List.Struct(i)} } + +func (s Provide_List) Set(i int, v Provide) error { return s.List.SetStruct(i, v.Struct) } + +func (s Provide_List) String() string { + str, _ := text.MarshalList(0x9c6a046bfbc1ac5a, s.List) + return str +} + +// Provide_Promise is a wrapper for a Provide promised by a client call. +type Provide_Promise struct{ *capnp.Pipeline } + +func (p Provide_Promise) Struct() (Provide, error) { + s, err := p.Pipeline.Struct() + return Provide{s}, err +} + +func (p Provide_Promise) Target() MessageTarget_Promise { + return MessageTarget_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Provide_Promise) Recipient() *capnp.Pipeline { + return p.Pipeline.GetPipeline(1) +} + +type Accept struct{ capnp.Struct } + +// Accept_TypeID is the unique identifier for the type Accept. +const Accept_TypeID = 0xd4c9b56290554016 + +func NewAccept(s *capnp.Segment) (Accept, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Accept{st}, err +} + +func NewRootAccept(s *capnp.Segment) (Accept, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Accept{st}, err +} + +func ReadRootAccept(msg *capnp.Message) (Accept, error) { + root, err := msg.RootPtr() + return Accept{root.Struct()}, err +} + +func (s Accept) String() string { + str, _ := text.Marshal(0xd4c9b56290554016, s.Struct) + return str +} + +func (s Accept) QuestionId() uint32 { + return s.Struct.Uint32(0) +} + +func (s Accept) SetQuestionId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Accept) Provision() (capnp.Pointer, error) { + return s.Struct.Pointer(0) +} + +func (s Accept) HasProvision() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Accept) ProvisionPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Accept) SetProvision(v capnp.Pointer) error { + return s.Struct.SetPointer(0, v) +} + +func (s Accept) SetProvisionPtr(v capnp.Ptr) error { + return s.Struct.SetPtr(0, v) +} + +func (s Accept) Embargo() bool { + return s.Struct.Bit(32) +} + +func (s Accept) SetEmbargo(v bool) { + s.Struct.SetBit(32, v) +} + +// Accept_List is a list of Accept. +type Accept_List struct{ capnp.List } + +// NewAccept creates a new list of Accept. +func NewAccept_List(s *capnp.Segment, sz int32) (Accept_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Accept_List{l}, err +} + +func (s Accept_List) At(i int) Accept { return Accept{s.List.Struct(i)} } + +func (s Accept_List) Set(i int, v Accept) error { return s.List.SetStruct(i, v.Struct) } + +func (s Accept_List) String() string { + str, _ := text.MarshalList(0xd4c9b56290554016, s.List) + return str +} + +// Accept_Promise is a wrapper for a Accept promised by a client call. +type Accept_Promise struct{ *capnp.Pipeline } + +func (p Accept_Promise) Struct() (Accept, error) { + s, err := p.Pipeline.Struct() + return Accept{s}, err +} + +func (p Accept_Promise) Provision() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +type Join struct{ capnp.Struct } + +// Join_TypeID is the unique identifier for the type Join. +const Join_TypeID = 0xfbe1980490e001af + +func NewJoin(s *capnp.Segment) (Join, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return Join{st}, err +} + +func NewRootJoin(s *capnp.Segment) (Join, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}) + return Join{st}, err +} + +func ReadRootJoin(msg *capnp.Message) (Join, error) { + root, err := msg.RootPtr() + return Join{root.Struct()}, err +} + +func (s Join) String() string { + str, _ := text.Marshal(0xfbe1980490e001af, s.Struct) + return str +} + +func (s Join) QuestionId() uint32 { + return s.Struct.Uint32(0) +} + +func (s Join) SetQuestionId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s Join) Target() (MessageTarget, error) { + p, err := s.Struct.Ptr(0) + return MessageTarget{Struct: p.Struct()}, err +} + +func (s Join) HasTarget() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Join) SetTarget(v MessageTarget) error { + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewTarget sets the target field to a newly +// allocated MessageTarget struct, preferring placement in s's segment. +func (s Join) NewTarget() (MessageTarget, error) { + ss, err := NewMessageTarget(s.Struct.Segment()) + if err != nil { + return MessageTarget{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s Join) KeyPart() (capnp.Pointer, error) { + return s.Struct.Pointer(1) +} + +func (s Join) HasKeyPart() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Join) KeyPartPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(1) +} + +func (s Join) SetKeyPart(v capnp.Pointer) error { + return s.Struct.SetPointer(1, v) +} + +func (s Join) SetKeyPartPtr(v capnp.Ptr) error { + return s.Struct.SetPtr(1, v) +} + +// Join_List is a list of Join. +type Join_List struct{ capnp.List } + +// NewJoin creates a new list of Join. +func NewJoin_List(s *capnp.Segment, sz int32) (Join_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz) + return Join_List{l}, err +} + +func (s Join_List) At(i int) Join { return Join{s.List.Struct(i)} } + +func (s Join_List) Set(i int, v Join) error { return s.List.SetStruct(i, v.Struct) } + +func (s Join_List) String() string { + str, _ := text.MarshalList(0xfbe1980490e001af, s.List) + return str +} + +// Join_Promise is a wrapper for a Join promised by a client call. +type Join_Promise struct{ *capnp.Pipeline } + +func (p Join_Promise) Struct() (Join, error) { + s, err := p.Pipeline.Struct() + return Join{s}, err +} + +func (p Join_Promise) Target() MessageTarget_Promise { + return MessageTarget_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p Join_Promise) KeyPart() *capnp.Pipeline { + return p.Pipeline.GetPipeline(1) +} + +type MessageTarget struct{ capnp.Struct } +type MessageTarget_Which uint16 + +const ( + MessageTarget_Which_importedCap MessageTarget_Which = 0 + MessageTarget_Which_promisedAnswer MessageTarget_Which = 1 +) + +func (w MessageTarget_Which) String() string { + const s = "importedCappromisedAnswer" + switch w { + case MessageTarget_Which_importedCap: + return s[0:11] + case MessageTarget_Which_promisedAnswer: + return s[11:25] + + } + return "MessageTarget_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// MessageTarget_TypeID is the unique identifier for the type MessageTarget. +const MessageTarget_TypeID = 0x95bc14545813fbc1 + +func NewMessageTarget(s *capnp.Segment) (MessageTarget, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return MessageTarget{st}, err +} + +func NewRootMessageTarget(s *capnp.Segment) (MessageTarget, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return MessageTarget{st}, err +} + +func ReadRootMessageTarget(msg *capnp.Message) (MessageTarget, error) { + root, err := msg.RootPtr() + return MessageTarget{root.Struct()}, err +} + +func (s MessageTarget) String() string { + str, _ := text.Marshal(0x95bc14545813fbc1, s.Struct) + return str +} + +func (s MessageTarget) Which() MessageTarget_Which { + return MessageTarget_Which(s.Struct.Uint16(4)) +} +func (s MessageTarget) ImportedCap() uint32 { + if s.Struct.Uint16(4) != 0 { + panic("Which() != importedCap") + } + return s.Struct.Uint32(0) +} + +func (s MessageTarget) SetImportedCap(v uint32) { + s.Struct.SetUint16(4, 0) + s.Struct.SetUint32(0, v) +} + +func (s MessageTarget) PromisedAnswer() (PromisedAnswer, error) { + if s.Struct.Uint16(4) != 1 { + panic("Which() != promisedAnswer") + } + p, err := s.Struct.Ptr(0) + return PromisedAnswer{Struct: p.Struct()}, err +} + +func (s MessageTarget) HasPromisedAnswer() bool { + if s.Struct.Uint16(4) != 1 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s MessageTarget) SetPromisedAnswer(v PromisedAnswer) error { + s.Struct.SetUint16(4, 1) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewPromisedAnswer sets the promisedAnswer field to a newly +// allocated PromisedAnswer struct, preferring placement in s's segment. +func (s MessageTarget) NewPromisedAnswer() (PromisedAnswer, error) { + s.Struct.SetUint16(4, 1) + ss, err := NewPromisedAnswer(s.Struct.Segment()) + if err != nil { + return PromisedAnswer{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +// MessageTarget_List is a list of MessageTarget. +type MessageTarget_List struct{ capnp.List } + +// NewMessageTarget creates a new list of MessageTarget. +func NewMessageTarget_List(s *capnp.Segment, sz int32) (MessageTarget_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return MessageTarget_List{l}, err +} + +func (s MessageTarget_List) At(i int) MessageTarget { return MessageTarget{s.List.Struct(i)} } + +func (s MessageTarget_List) Set(i int, v MessageTarget) error { return s.List.SetStruct(i, v.Struct) } + +func (s MessageTarget_List) String() string { + str, _ := text.MarshalList(0x95bc14545813fbc1, s.List) + return str +} + +// MessageTarget_Promise is a wrapper for a MessageTarget promised by a client call. +type MessageTarget_Promise struct{ *capnp.Pipeline } + +func (p MessageTarget_Promise) Struct() (MessageTarget, error) { + s, err := p.Pipeline.Struct() + return MessageTarget{s}, err +} + +func (p MessageTarget_Promise) PromisedAnswer() PromisedAnswer_Promise { + return PromisedAnswer_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +type Payload struct{ capnp.Struct } + +// Payload_TypeID is the unique identifier for the type Payload. +const Payload_TypeID = 0x9a0e61223d96743b + +func NewPayload(s *capnp.Segment) (Payload, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) + return Payload{st}, err +} + +func NewRootPayload(s *capnp.Segment) (Payload, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) + return Payload{st}, err +} + +func ReadRootPayload(msg *capnp.Message) (Payload, error) { + root, err := msg.RootPtr() + return Payload{root.Struct()}, err +} + +func (s Payload) String() string { + str, _ := text.Marshal(0x9a0e61223d96743b, s.Struct) + return str +} + +func (s Payload) Content() (capnp.Pointer, error) { + return s.Struct.Pointer(0) +} + +func (s Payload) HasContent() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Payload) ContentPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s Payload) SetContent(v capnp.Pointer) error { + return s.Struct.SetPointer(0, v) +} + +func (s Payload) SetContentPtr(v capnp.Ptr) error { + return s.Struct.SetPtr(0, v) +} + +func (s Payload) CapTable() (CapDescriptor_List, error) { + p, err := s.Struct.Ptr(1) + return CapDescriptor_List{List: p.List()}, err +} + +func (s Payload) HasCapTable() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s Payload) SetCapTable(v CapDescriptor_List) error { + return s.Struct.SetPtr(1, v.List.ToPtr()) +} + +// NewCapTable sets the capTable field to a newly +// allocated CapDescriptor_List, preferring placement in s's segment. +func (s Payload) NewCapTable(n int32) (CapDescriptor_List, error) { + l, err := NewCapDescriptor_List(s.Struct.Segment(), n) + if err != nil { + return CapDescriptor_List{}, err + } + err = s.Struct.SetPtr(1, l.List.ToPtr()) + return l, err +} + +// Payload_List is a list of Payload. +type Payload_List struct{ capnp.List } + +// NewPayload creates a new list of Payload. +func NewPayload_List(s *capnp.Segment, sz int32) (Payload_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz) + return Payload_List{l}, err +} + +func (s Payload_List) At(i int) Payload { return Payload{s.List.Struct(i)} } + +func (s Payload_List) Set(i int, v Payload) error { return s.List.SetStruct(i, v.Struct) } + +func (s Payload_List) String() string { + str, _ := text.MarshalList(0x9a0e61223d96743b, s.List) + return str +} + +// Payload_Promise is a wrapper for a Payload promised by a client call. +type Payload_Promise struct{ *capnp.Pipeline } + +func (p Payload_Promise) Struct() (Payload, error) { + s, err := p.Pipeline.Struct() + return Payload{s}, err +} + +func (p Payload_Promise) Content() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +type CapDescriptor struct{ capnp.Struct } +type CapDescriptor_Which uint16 + +const ( + CapDescriptor_Which_none CapDescriptor_Which = 0 + CapDescriptor_Which_senderHosted CapDescriptor_Which = 1 + CapDescriptor_Which_senderPromise CapDescriptor_Which = 2 + CapDescriptor_Which_receiverHosted CapDescriptor_Which = 3 + CapDescriptor_Which_receiverAnswer CapDescriptor_Which = 4 + CapDescriptor_Which_thirdPartyHosted CapDescriptor_Which = 5 +) + +func (w CapDescriptor_Which) String() string { + const s = "nonesenderHostedsenderPromisereceiverHostedreceiverAnswerthirdPartyHosted" + switch w { + case CapDescriptor_Which_none: + return s[0:4] + case CapDescriptor_Which_senderHosted: + return s[4:16] + case CapDescriptor_Which_senderPromise: + return s[16:29] + case CapDescriptor_Which_receiverHosted: + return s[29:43] + case CapDescriptor_Which_receiverAnswer: + return s[43:57] + case CapDescriptor_Which_thirdPartyHosted: + return s[57:73] + + } + return "CapDescriptor_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// CapDescriptor_TypeID is the unique identifier for the type CapDescriptor. +const CapDescriptor_TypeID = 0x8523ddc40b86b8b0 + +func NewCapDescriptor(s *capnp.Segment) (CapDescriptor, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return CapDescriptor{st}, err +} + +func NewRootCapDescriptor(s *capnp.Segment) (CapDescriptor, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return CapDescriptor{st}, err +} + +func ReadRootCapDescriptor(msg *capnp.Message) (CapDescriptor, error) { + root, err := msg.RootPtr() + return CapDescriptor{root.Struct()}, err +} + +func (s CapDescriptor) String() string { + str, _ := text.Marshal(0x8523ddc40b86b8b0, s.Struct) + return str +} + +func (s CapDescriptor) Which() CapDescriptor_Which { + return CapDescriptor_Which(s.Struct.Uint16(0)) +} +func (s CapDescriptor) SetNone() { + s.Struct.SetUint16(0, 0) + +} + +func (s CapDescriptor) SenderHosted() uint32 { + if s.Struct.Uint16(0) != 1 { + panic("Which() != senderHosted") + } + return s.Struct.Uint32(4) +} + +func (s CapDescriptor) SetSenderHosted(v uint32) { + s.Struct.SetUint16(0, 1) + s.Struct.SetUint32(4, v) +} + +func (s CapDescriptor) SenderPromise() uint32 { + if s.Struct.Uint16(0) != 2 { + panic("Which() != senderPromise") + } + return s.Struct.Uint32(4) +} + +func (s CapDescriptor) SetSenderPromise(v uint32) { + s.Struct.SetUint16(0, 2) + s.Struct.SetUint32(4, v) +} + +func (s CapDescriptor) ReceiverHosted() uint32 { + if s.Struct.Uint16(0) != 3 { + panic("Which() != receiverHosted") + } + return s.Struct.Uint32(4) +} + +func (s CapDescriptor) SetReceiverHosted(v uint32) { + s.Struct.SetUint16(0, 3) + s.Struct.SetUint32(4, v) +} + +func (s CapDescriptor) ReceiverAnswer() (PromisedAnswer, error) { + if s.Struct.Uint16(0) != 4 { + panic("Which() != receiverAnswer") + } + p, err := s.Struct.Ptr(0) + return PromisedAnswer{Struct: p.Struct()}, err +} + +func (s CapDescriptor) HasReceiverAnswer() bool { + if s.Struct.Uint16(0) != 4 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s CapDescriptor) SetReceiverAnswer(v PromisedAnswer) error { + s.Struct.SetUint16(0, 4) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewReceiverAnswer sets the receiverAnswer field to a newly +// allocated PromisedAnswer struct, preferring placement in s's segment. +func (s CapDescriptor) NewReceiverAnswer() (PromisedAnswer, error) { + s.Struct.SetUint16(0, 4) + ss, err := NewPromisedAnswer(s.Struct.Segment()) + if err != nil { + return PromisedAnswer{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +func (s CapDescriptor) ThirdPartyHosted() (ThirdPartyCapDescriptor, error) { + if s.Struct.Uint16(0) != 5 { + panic("Which() != thirdPartyHosted") + } + p, err := s.Struct.Ptr(0) + return ThirdPartyCapDescriptor{Struct: p.Struct()}, err +} + +func (s CapDescriptor) HasThirdPartyHosted() bool { + if s.Struct.Uint16(0) != 5 { + return false + } + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s CapDescriptor) SetThirdPartyHosted(v ThirdPartyCapDescriptor) error { + s.Struct.SetUint16(0, 5) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) +} + +// NewThirdPartyHosted sets the thirdPartyHosted field to a newly +// allocated ThirdPartyCapDescriptor struct, preferring placement in s's segment. +func (s CapDescriptor) NewThirdPartyHosted() (ThirdPartyCapDescriptor, error) { + s.Struct.SetUint16(0, 5) + ss, err := NewThirdPartyCapDescriptor(s.Struct.Segment()) + if err != nil { + return ThirdPartyCapDescriptor{}, err + } + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) + return ss, err +} + +// CapDescriptor_List is a list of CapDescriptor. +type CapDescriptor_List struct{ capnp.List } + +// NewCapDescriptor creates a new list of CapDescriptor. +func NewCapDescriptor_List(s *capnp.Segment, sz int32) (CapDescriptor_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return CapDescriptor_List{l}, err +} + +func (s CapDescriptor_List) At(i int) CapDescriptor { return CapDescriptor{s.List.Struct(i)} } + +func (s CapDescriptor_List) Set(i int, v CapDescriptor) error { return s.List.SetStruct(i, v.Struct) } + +func (s CapDescriptor_List) String() string { + str, _ := text.MarshalList(0x8523ddc40b86b8b0, s.List) + return str +} + +// CapDescriptor_Promise is a wrapper for a CapDescriptor promised by a client call. +type CapDescriptor_Promise struct{ *capnp.Pipeline } + +func (p CapDescriptor_Promise) Struct() (CapDescriptor, error) { + s, err := p.Pipeline.Struct() + return CapDescriptor{s}, err +} + +func (p CapDescriptor_Promise) ReceiverAnswer() PromisedAnswer_Promise { + return PromisedAnswer_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +func (p CapDescriptor_Promise) ThirdPartyHosted() ThirdPartyCapDescriptor_Promise { + return ThirdPartyCapDescriptor_Promise{Pipeline: p.Pipeline.GetPipeline(0)} +} + +type PromisedAnswer struct{ capnp.Struct } + +// PromisedAnswer_TypeID is the unique identifier for the type PromisedAnswer. +const PromisedAnswer_TypeID = 0xd800b1d6cd6f1ca0 + +func NewPromisedAnswer(s *capnp.Segment) (PromisedAnswer, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return PromisedAnswer{st}, err +} + +func NewRootPromisedAnswer(s *capnp.Segment) (PromisedAnswer, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return PromisedAnswer{st}, err +} + +func ReadRootPromisedAnswer(msg *capnp.Message) (PromisedAnswer, error) { + root, err := msg.RootPtr() + return PromisedAnswer{root.Struct()}, err +} + +func (s PromisedAnswer) String() string { + str, _ := text.Marshal(0xd800b1d6cd6f1ca0, s.Struct) + return str +} + +func (s PromisedAnswer) QuestionId() uint32 { + return s.Struct.Uint32(0) +} + +func (s PromisedAnswer) SetQuestionId(v uint32) { + s.Struct.SetUint32(0, v) +} + +func (s PromisedAnswer) Transform() (PromisedAnswer_Op_List, error) { + p, err := s.Struct.Ptr(0) + return PromisedAnswer_Op_List{List: p.List()}, err +} + +func (s PromisedAnswer) HasTransform() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s PromisedAnswer) SetTransform(v PromisedAnswer_Op_List) error { + return s.Struct.SetPtr(0, v.List.ToPtr()) +} + +// NewTransform sets the transform field to a newly +// allocated PromisedAnswer_Op_List, preferring placement in s's segment. +func (s PromisedAnswer) NewTransform(n int32) (PromisedAnswer_Op_List, error) { + l, err := NewPromisedAnswer_Op_List(s.Struct.Segment(), n) + if err != nil { + return PromisedAnswer_Op_List{}, err + } + err = s.Struct.SetPtr(0, l.List.ToPtr()) + return l, err +} + +// PromisedAnswer_List is a list of PromisedAnswer. +type PromisedAnswer_List struct{ capnp.List } + +// NewPromisedAnswer creates a new list of PromisedAnswer. +func NewPromisedAnswer_List(s *capnp.Segment, sz int32) (PromisedAnswer_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return PromisedAnswer_List{l}, err +} + +func (s PromisedAnswer_List) At(i int) PromisedAnswer { return PromisedAnswer{s.List.Struct(i)} } + +func (s PromisedAnswer_List) Set(i int, v PromisedAnswer) error { return s.List.SetStruct(i, v.Struct) } + +func (s PromisedAnswer_List) String() string { + str, _ := text.MarshalList(0xd800b1d6cd6f1ca0, s.List) + return str +} + +// PromisedAnswer_Promise is a wrapper for a PromisedAnswer promised by a client call. +type PromisedAnswer_Promise struct{ *capnp.Pipeline } + +func (p PromisedAnswer_Promise) Struct() (PromisedAnswer, error) { + s, err := p.Pipeline.Struct() + return PromisedAnswer{s}, err +} + +type PromisedAnswer_Op struct{ capnp.Struct } +type PromisedAnswer_Op_Which uint16 + +const ( + PromisedAnswer_Op_Which_noop PromisedAnswer_Op_Which = 0 + PromisedAnswer_Op_Which_getPointerField PromisedAnswer_Op_Which = 1 +) + +func (w PromisedAnswer_Op_Which) String() string { + const s = "noopgetPointerField" + switch w { + case PromisedAnswer_Op_Which_noop: + return s[0:4] + case PromisedAnswer_Op_Which_getPointerField: + return s[4:19] + + } + return "PromisedAnswer_Op_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} + +// PromisedAnswer_Op_TypeID is the unique identifier for the type PromisedAnswer_Op. +const PromisedAnswer_Op_TypeID = 0xf316944415569081 + +func NewPromisedAnswer_Op(s *capnp.Segment) (PromisedAnswer_Op, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}) + return PromisedAnswer_Op{st}, err +} + +func NewRootPromisedAnswer_Op(s *capnp.Segment) (PromisedAnswer_Op, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}) + return PromisedAnswer_Op{st}, err +} + +func ReadRootPromisedAnswer_Op(msg *capnp.Message) (PromisedAnswer_Op, error) { + root, err := msg.RootPtr() + return PromisedAnswer_Op{root.Struct()}, err +} + +func (s PromisedAnswer_Op) String() string { + str, _ := text.Marshal(0xf316944415569081, s.Struct) + return str +} + +func (s PromisedAnswer_Op) Which() PromisedAnswer_Op_Which { + return PromisedAnswer_Op_Which(s.Struct.Uint16(0)) +} +func (s PromisedAnswer_Op) SetNoop() { + s.Struct.SetUint16(0, 0) + +} + +func (s PromisedAnswer_Op) GetPointerField() uint16 { + if s.Struct.Uint16(0) != 1 { + panic("Which() != getPointerField") + } + return s.Struct.Uint16(2) +} + +func (s PromisedAnswer_Op) SetGetPointerField(v uint16) { + s.Struct.SetUint16(0, 1) + s.Struct.SetUint16(2, v) +} + +// PromisedAnswer_Op_List is a list of PromisedAnswer_Op. +type PromisedAnswer_Op_List struct{ capnp.List } + +// NewPromisedAnswer_Op creates a new list of PromisedAnswer_Op. +func NewPromisedAnswer_Op_List(s *capnp.Segment, sz int32) (PromisedAnswer_Op_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}, sz) + return PromisedAnswer_Op_List{l}, err +} + +func (s PromisedAnswer_Op_List) At(i int) PromisedAnswer_Op { + return PromisedAnswer_Op{s.List.Struct(i)} +} + +func (s PromisedAnswer_Op_List) Set(i int, v PromisedAnswer_Op) error { + return s.List.SetStruct(i, v.Struct) +} + +func (s PromisedAnswer_Op_List) String() string { + str, _ := text.MarshalList(0xf316944415569081, s.List) + return str +} + +// PromisedAnswer_Op_Promise is a wrapper for a PromisedAnswer_Op promised by a client call. +type PromisedAnswer_Op_Promise struct{ *capnp.Pipeline } + +func (p PromisedAnswer_Op_Promise) Struct() (PromisedAnswer_Op, error) { + s, err := p.Pipeline.Struct() + return PromisedAnswer_Op{s}, err +} + +type ThirdPartyCapDescriptor struct{ capnp.Struct } + +// ThirdPartyCapDescriptor_TypeID is the unique identifier for the type ThirdPartyCapDescriptor. +const ThirdPartyCapDescriptor_TypeID = 0xd37007fde1f0027d + +func NewThirdPartyCapDescriptor(s *capnp.Segment) (ThirdPartyCapDescriptor, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return ThirdPartyCapDescriptor{st}, err +} + +func NewRootThirdPartyCapDescriptor(s *capnp.Segment) (ThirdPartyCapDescriptor, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return ThirdPartyCapDescriptor{st}, err +} + +func ReadRootThirdPartyCapDescriptor(msg *capnp.Message) (ThirdPartyCapDescriptor, error) { + root, err := msg.RootPtr() + return ThirdPartyCapDescriptor{root.Struct()}, err +} + +func (s ThirdPartyCapDescriptor) String() string { + str, _ := text.Marshal(0xd37007fde1f0027d, s.Struct) + return str +} + +func (s ThirdPartyCapDescriptor) Id() (capnp.Pointer, error) { + return s.Struct.Pointer(0) +} + +func (s ThirdPartyCapDescriptor) HasId() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s ThirdPartyCapDescriptor) IdPtr() (capnp.Ptr, error) { + return s.Struct.Ptr(0) +} + +func (s ThirdPartyCapDescriptor) SetId(v capnp.Pointer) error { + return s.Struct.SetPointer(0, v) +} + +func (s ThirdPartyCapDescriptor) SetIdPtr(v capnp.Ptr) error { + return s.Struct.SetPtr(0, v) +} + +func (s ThirdPartyCapDescriptor) VineId() uint32 { + return s.Struct.Uint32(0) +} + +func (s ThirdPartyCapDescriptor) SetVineId(v uint32) { + s.Struct.SetUint32(0, v) +} + +// ThirdPartyCapDescriptor_List is a list of ThirdPartyCapDescriptor. +type ThirdPartyCapDescriptor_List struct{ capnp.List } + +// NewThirdPartyCapDescriptor creates a new list of ThirdPartyCapDescriptor. +func NewThirdPartyCapDescriptor_List(s *capnp.Segment, sz int32) (ThirdPartyCapDescriptor_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return ThirdPartyCapDescriptor_List{l}, err +} + +func (s ThirdPartyCapDescriptor_List) At(i int) ThirdPartyCapDescriptor { + return ThirdPartyCapDescriptor{s.List.Struct(i)} +} + +func (s ThirdPartyCapDescriptor_List) Set(i int, v ThirdPartyCapDescriptor) error { + return s.List.SetStruct(i, v.Struct) +} + +func (s ThirdPartyCapDescriptor_List) String() string { + str, _ := text.MarshalList(0xd37007fde1f0027d, s.List) + return str +} + +// ThirdPartyCapDescriptor_Promise is a wrapper for a ThirdPartyCapDescriptor promised by a client call. +type ThirdPartyCapDescriptor_Promise struct{ *capnp.Pipeline } + +func (p ThirdPartyCapDescriptor_Promise) Struct() (ThirdPartyCapDescriptor, error) { + s, err := p.Pipeline.Struct() + return ThirdPartyCapDescriptor{s}, err +} + +func (p ThirdPartyCapDescriptor_Promise) Id() *capnp.Pipeline { + return p.Pipeline.GetPipeline(0) +} + +type Exception struct{ capnp.Struct } + +// Exception_TypeID is the unique identifier for the type Exception. +const Exception_TypeID = 0xd625b7063acf691a + +func NewException(s *capnp.Segment) (Exception, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Exception{st}, err +} + +func NewRootException(s *capnp.Segment) (Exception, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) + return Exception{st}, err +} + +func ReadRootException(msg *capnp.Message) (Exception, error) { + root, err := msg.RootPtr() + return Exception{root.Struct()}, err +} + +func (s Exception) String() string { + str, _ := text.Marshal(0xd625b7063acf691a, s.Struct) + return str +} + +func (s Exception) Reason() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s Exception) HasReason() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s Exception) ReasonBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s Exception) SetReason(v string) error { + return s.Struct.SetText(0, v) +} + +func (s Exception) Type() Exception_Type { + return Exception_Type(s.Struct.Uint16(4)) +} + +func (s Exception) SetType(v Exception_Type) { + s.Struct.SetUint16(4, uint16(v)) +} + +func (s Exception) ObsoleteIsCallersFault() bool { + return s.Struct.Bit(0) +} + +func (s Exception) SetObsoleteIsCallersFault(v bool) { + s.Struct.SetBit(0, v) +} + +func (s Exception) ObsoleteDurability() uint16 { + return s.Struct.Uint16(2) +} + +func (s Exception) SetObsoleteDurability(v uint16) { + s.Struct.SetUint16(2, v) +} + +// Exception_List is a list of Exception. +type Exception_List struct{ capnp.List } + +// NewException creates a new list of Exception. +func NewException_List(s *capnp.Segment, sz int32) (Exception_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) + return Exception_List{l}, err +} + +func (s Exception_List) At(i int) Exception { return Exception{s.List.Struct(i)} } + +func (s Exception_List) Set(i int, v Exception) error { return s.List.SetStruct(i, v.Struct) } + +func (s Exception_List) String() string { + str, _ := text.MarshalList(0xd625b7063acf691a, s.List) + return str +} + +// Exception_Promise is a wrapper for a Exception promised by a client call. +type Exception_Promise struct{ *capnp.Pipeline } + +func (p Exception_Promise) Struct() (Exception, error) { + s, err := p.Pipeline.Struct() + return Exception{s}, err +} + +type Exception_Type uint16 + +// Exception_Type_TypeID is the unique identifier for the type Exception_Type. +const Exception_Type_TypeID = 0xb28c96e23f4cbd58 + +// Values of Exception_Type. +const ( + Exception_Type_failed Exception_Type = 0 + Exception_Type_overloaded Exception_Type = 1 + Exception_Type_disconnected Exception_Type = 2 + Exception_Type_unimplemented Exception_Type = 3 +) + +// String returns the enum's constant name. +func (c Exception_Type) String() string { + switch c { + case Exception_Type_failed: + return "failed" + case Exception_Type_overloaded: + return "overloaded" + case Exception_Type_disconnected: + return "disconnected" + case Exception_Type_unimplemented: + return "unimplemented" + + default: + return "" + } +} + +// Exception_TypeFromString returns the enum value with a name, +// or the zero value if there's no such value. +func Exception_TypeFromString(c string) Exception_Type { + switch c { + case "failed": + return Exception_Type_failed + case "overloaded": + return Exception_Type_overloaded + case "disconnected": + return Exception_Type_disconnected + case "unimplemented": + return Exception_Type_unimplemented + + default: + return 0 + } +} + +type Exception_Type_List struct{ capnp.List } + +func NewException_Type_List(s *capnp.Segment, sz int32) (Exception_Type_List, error) { + l, err := capnp.NewUInt16List(s, sz) + return Exception_Type_List{l.List}, err +} + +func (l Exception_Type_List) At(i int) Exception_Type { + ul := capnp.UInt16List{List: l.List} + return Exception_Type(ul.At(i)) +} + +func (l Exception_Type_List) Set(i int, v Exception_Type) { + ul := capnp.UInt16List{List: l.List} + ul.Set(i, uint16(v)) +} + +const schema_b312981b2552a250 = "x\xda\x9cX\x7f\x8c\x15\xd5\x15>\xe7\xde\xb7\xef-\xec" + + "\x8f\xf7f\xefC\x0b\x95@mM\x0a)D\xacm\xed" + + "\xb6\xe6!\xec\x12\xd6,a\xef\xbe\xa5*5ig\xdf" + + "\xbb\xec\xce2;3\xce\xcc\xc2.\x91\x00\xad6J%" + + "E\xa2\x16\x8c\xb4jlb-FD\x88\xb4\x95T\x08" + + "\xa6j\xa4j\x14\xa3\x8d\xa6j\xd2\xa8MM\xb4\xfe\xa8" + + "\xca\x8fi\xce\xcc\xbc\x99\xc7\xee\xdb\x10\xfb\xd7\xbe\xccw" + + "f\xee9\xdf=\xe7\xfb\xee\xddK\xaf\xcb.eK\x9a" + + "V\xcf\x00\x90fS6x\xb9w\xef\xf8\xdf\xca#?" + + "\x079\x13y\xd0w\x7f\xff%_\xdd\xdd\xf1\x184\xf1" + + "\x1c\x80\xd8\x91\xd9$n\xcf\xe4\x00\xbe\xbd#\xf3+\x04" + + "\x0c\xf6\x1f\xfeE\xcb\xf17\xbe~3Ec\x1a\xdd\x8d" + + "\xb9,\x80\xd0\xb2\xc7\xc4\xec,\x85\xcf\xca^C\xe1\x97" + + "\xed\xdf\xb1u\xdeo\x1f\xbf}jx;\x80\x98\xc8\xed" + + "\x12\xdbr\x14\xbe9w!\x07\x0c\x8e\x9e\x12\xd7\x0e\x14" + + "\x9f\xb8sj8C&\x8e\xcc<&\x9e\x9aIi\x1d" + + "\x9d\xb9\x110\xf8\x81\x7f\xd7\x95\x17\xeb\xedw\x836\xb3" + + ".\xb8\x89Q\xc4%-\xbb\xc4\xa2\x16\xfa\xb5\xa0\x85b" + + "\xd7\xee;zj}f\xe4\x9eI_\x8e\x82\xf7\xb4\xec" + + "\x12\xf7\x85\xc1{[\x1e\x01\x0c:\xafy\xec\xca\x1d\x07" + + "f\xff\x86\x82\xd9\xb9E\"\x17W\xb6n\x17\xdd\xad\x94" + + "\xf5U\xad\x7f\xa5\"\x7f\xed\xbf\xb0\xb9\xcd\x9c\xf3\xf0\xa4" + + "o\x13mbI\xfb.\xf1\xfdv\xfa\xf5\x9dv\xca\xe3" + + "\xda#\xbd\xa5\xb7\xef\xba\xed\x00hE\x16\xcc1\x9e\xef" + + "\xcc>~\xc9+\x00(\xeel\x7fV\xdc\x17\x06\xeem" + + "\x1f\x02\x0c\xac\xe6[\xbfXs\xd7\xb1?7\xa6\xe2D" + + "\xfb.q2\x8c~\xb1\x9d2\xde\xcc>x\xebL\xce" + + "yiryHi\xde\x90\xef@\xb1-O\xd1\x9b\xf3" + + "\x94D\xa5\xfd\xb3c\x07\x16o~\xa9Q\xc2\xaf\xe5\xb7" + + "\x8b\xb7\xc2\xd87\xc2\xd8\x0b\x96\xae\xd99x\xe8\x99\x97" + + "\x1b}Yt\x17\xb6\x8bU\x05\xfa\xd5S\xa04V\xbd" + + "\xf1c\xf5\x8f\x83\x83'A\xceB\x0c\xb4\xef\x1d\xc9\xff" + + "\xf2\xbb\xd5\xcfa\x0d\xe60\x83L\xbcW\xf8\x17\xa0x" + + "\xbf\xf0\x0e`Z{\xa3\xef\x9e\xd0\xee\x17'\xb5\x0b)" + + "\x09\xed\x1d\xc0\xbf\xdc{\x91}\xe2\x95G_m\x14z" + + "\xb4\xe3Yq\xa2\x83BOvP\xbe{~\xf2\x879" + + "\x9f\xee\x7f\xf7\xef \xf3\xc8\xd3\xe6^\xc3s\xc8\x91\x8b" + + "\x1eA)\xac\x12\x94\xedq\xeb\xc2%[\x9f\xef}\xaf" + + "a\x0a\xef\x8b\xfb\xc5'\x82~}(\xe8\xbb\xdbv\xfe" + + "hV\xd7\x1d\x17|\x04r6&\x09u\xe5\x18\x80\xb8" + + "\xae\xf8\xb6PE\x0a\xd5\x8b\x14\x9a\xd4\xdd0\xdf\xe2C" + + "\xe2\x990\xf8\xa90\xf8\x11|sgf\xf7[\xa7\x1a" + + "6f\xd3\xacMb\xc6\xac\xe8\xd7#\xb0\xfb\x01Gy\x9a\xf4\xe7t,\xd4\x9f?\x04 O" + + "s,7#\xc3\xb9\xd9S\x01\x8bT\xa6\x09\x0f\x00\x94" + + "\x9bil\x8b\xa1\xfc|\x11\xab\x8c\x86\x0f\x01\x94\x8b\x04" + + "\xcc\xa7y\xd6\xc3m\x8f\x1c.U\xe8p\x8c\xfa\x90\x9c" + + "n\xb9\xeex\x10ZV\x13y\x16M\xdf\x98\xe97\xf2" + + "?5N\xbdo\xd8\x80\xd6\xd4\xf1\x0f*\xbaUQ&" + + "\x89y.\x88\xbfQFe\xf9\xdd\xa6\xa76\xe6\x87\x95" + + "K\x1e\xe3\xeb\xeb\xd5\x0a\xd7\x1e\xc5\xd5\xfe\xb0r\xe5\x98" + + "\x9a\x17\xeeV\x92Y4^+\\\xb4G\x07B\x97\xc8" + + "\x93\xb16\xde\x1b\xaa!j\x9a\xbaf\x9d\xd3\xa8Y7" + + "\xc5\xcdz\x05Cn\xd4\x1b\xd5:\xe5*\xab\x02%\xb5" + + "\xdc\x1e\xb3\xfc\x14H\xa7\xb2;\xae\xd9Z<0\xe1\xa8" + + "\xa8\x15\x0a\xe1\xde.\xe8\xa4\xca\xb5\xaf\xad\x05@\xa6\xcd" + + "\x1d\x01@\xae\xcdv\x01J\xebt\xc3T\xd5\xc0\xde\xa0" + + "\\\xd3\xd6\xab\xc0U\x95t\xa0b[\x96\x82|\xc5W" + + "\xd5\xc9*{na\xa4~S\xa6\xa1?\x9d\x866\x0c" + + "b\x01Xuq:\x0fm\xecl\xd0` b\x01\xe8" + + "\x01L\x0a\xcfUtg\xd2D\x9e\x7f{k\x19r\xa7" + + "s \xf6o\x7f\xa2\xfeP\x83\xee\xf4[\x91\xecDg" + + "*c\xb4\x13\xf1\xbe\x966\x18\x96\xea\xa9N\xe1\x1f\x9d" + + "\xce\x15\xa1I\x00L\xfa\xf6\xda\xf4;\xc9\x08.\xd9\x05" + + " /\xe7(\x97N\xa3\x03\xb5\xbe\xef\xc7\xb0=I&" + + "\xbd\xa4\xef\xeb\x17\xbd*\xec\xc2h\xd1\xf3\x08\x12Q\xdd" + + "\xcbQ^K\x824?\xe2\x7f\xcd\xb2\xf3\x08R\x10\xfa" + + "\x8b\x17Q]\xf3\x9c\xd0&\x86\xecFg\xc7\xae\xd8D" + + "\x86\xec\xc5\x15\xdb\xca\xfbj\xdc\x97\x85\xd0\x1c\xa2,t" + + "j\xf0\x9fr\x94f\xcd\x1d(\x0d\x83$\xc9\xe4(\xc7" + + "\xa99\xce\xc4\xe23F[\xe0p\x947\x92$\x9d\x8e" + + "\xc5g\x82R\xf69\xca\xad\xacv\xe2\xeb\xb5\xa1d;" + + "\x83ze\xfd\x94\x93\x1d\xf6\xda\x11\x92jJl\x8c\x90" + + "M\xbc\xb3\xc1fF\xc3\x943lKf\xb0\xfe\x92\x8a" + + "\x0b\xf34^TTL\xb6Ni^\xcfQ\x0e3D" + + "\x16\x95\xa9\xfe\x04 \x879J\x9f\xee\x13\xb1\xfa\xdfp" + + "w\x9a\xb9\x86\xf1%c3\x9d\xa7\xc79\xca\x9b\x18\x1d" + + "@t\xcf\xb6\xb0\x15\x18\xb6\xd6\x99>\xf6xtXW" + + "n\xc9[\xa1\x8f\x99~B|\x12\xd05\xe6\xea\x83\x86" + + "ip\x7f\xa2v9\xc8\xfb\x13\x8e\xc2|\x9a: \xe6" + + "\xcf\xdd\xac\xbe\xd8q#\xbf\x05\x08KM\xaeu\x1a\xce" + + "\xe1\xab\x9diZ\xb9\xd6UK\xfac_\xef\x9d\xae\x81" + + "|W\xb7\xbcu\xb6\x0b8\x9aZl\xb2\xc8$\x8be" + + "\xd1-nq\xed\xfeb\xe6\xe9\xfaB\x9d\x1dv\x10\xd9" + + "L7\xd1\xbd4Z1\xea\xa0,\x80\xd6su*/" + + "t\xff`\xa1\xc5hrm\xda\xdf\xa5J\xc8!d\x83" + + "\x09{\xcc\xf5\x94\xb9\x8e\xf4\xbfv\xc2\x07\xdeX\xbc\x97" + + "\x85\xc7\xb2\x9c\xab;\xd3\xcfuB\xc6\xdd\xe7\x1b\xeb\xaa" + + "r\\U\xd1}T\xd5\xd5\x83#\xaa\xe2\x138y\xd5" + + ");\x93[\xbc\xda\x99|\xcaZ\x98JV\xdd5l" + + "\xd1\xcfR\xff\xc8[\xb6\xed@6\x18R~\x9fmX" + + ">*w\x85\xa1\xccjr}\xac/3\x9a\xdb<\x0d" + + "\xee\xa4:;\xeb\xb5\x11\xeb\xfe\xa3\xa1-Z\x06l\xda" + + "\x03Kt\xd4\x1a\xf7\xcf\xb9\xa1_m\x1b\xd6\xff{t" + + "Z\x96\xca\xd7\x97;:mY\xaf&\xc8\x02j<\xff" + + "/\x00\x00\xff\xff<\xff\x0e\x96" + +func init() { + schemas.Register(schema_b312981b2552a250, + 0x836a53ce789d4cd4, + 0x8523ddc40b86b8b0, + 0x91b79f1f808db032, + 0x95bc14545813fbc1, + 0x9a0e61223d96743b, + 0x9c6a046bfbc1ac5a, + 0x9e19b28d3db3573a, + 0xad1a6c0d7dd07497, + 0xb28c96e23f4cbd58, + 0xbbc29655fa89086e, + 0xd37007fde1f0027d, + 0xd37d2eb2c2f80e63, + 0xd4c9b56290554016, + 0xd562b4df655bdd4d, + 0xd625b7063acf691a, + 0xd800b1d6cd6f1ca0, + 0xdae8b0f61aab5f99, + 0xe94ccf8031176ec4, + 0xf316944415569081, + 0xf964368b0fbd3711, + 0xfbe1980490e001af) +} diff --git a/vendor/zombiezen.com/go/capnproto2/strings.go b/vendor/zombiezen.com/go/capnproto2/strings.go new file mode 100644 index 00000000..a3f45b4c --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/strings.go @@ -0,0 +1,125 @@ +// +build !nocapnpstrings + +package capnp + +import ( + "fmt" +) + +// String returns the address in hex format. +func (addr Address) String() string { + return fmt.Sprintf("%#08x", uint64(addr)) +} + +// GoString returns the address in hex format. +func (addr Address) GoString() string { + return fmt.Sprintf("capnp.Address(%#08x)", uint64(addr)) +} + +// String returns the size in the format "X bytes". +func (sz Size) String() string { + if sz == 1 { + return "1 byte" + } + return fmt.Sprintf("%d bytes", sz) +} + +// GoString returns the size as a Go expression. +func (sz Size) GoString() string { + return fmt.Sprintf("capnp.Size(%d)", sz) +} + +// String returns the offset in the format "+X bytes". +func (off DataOffset) String() string { + if off == 1 { + return "+1 byte" + } + return fmt.Sprintf("+%d bytes", off) +} + +// GoString returns the offset as a Go expression. +func (off DataOffset) GoString() string { + return fmt.Sprintf("capnp.DataOffset(%d)", off) +} + +// String returns a short, human readable representation of the object +// size. +func (sz ObjectSize) String() string { + return fmt.Sprintf("{datasz=%d ptrs=%d}", sz.DataSize, sz.PointerCount) +} + +// GoString formats the ObjectSize as a keyed struct literal. +func (sz ObjectSize) GoString() string { + return fmt.Sprintf("capnp.ObjectSize{DataSize: %d, PointerCount: %d}", sz.DataSize, sz.PointerCount) +} + +// String returns the offset in the format "bit X". +func (bit BitOffset) String() string { + return fmt.Sprintf("bit %d", bit) +} + +// GoString returns the offset as a Go expression. +func (bit BitOffset) GoString() string { + return fmt.Sprintf("capnp.BitOffset(%d)", bit) +} + +// String returns the ID in the format "capability X". +func (id CapabilityID) String() string { + return fmt.Sprintf("capability %d", id) +} + +// GoString returns the ID as a Go expression. +func (id CapabilityID) GoString() string { + return fmt.Sprintf("capnp.CapabilityID(%d)", id) +} + +// GoString formats the pointer as a call to one of the rawPointer +// construction functions. +func (p rawPointer) GoString() string { + if p == 0 { + return "rawPointer(0)" + } + switch p.pointerType() { + case structPointer: + return fmt.Sprintf("rawStructPointer(%d, %#v)", p.offset(), p.structSize()) + case listPointer: + var lt string + switch p.listType() { + case voidList: + lt = "voidList" + case bit1List: + lt = "bit1List" + case byte1List: + lt = "byte1List" + case byte2List: + lt = "byte2List" + case byte4List: + lt = "byte4List" + case byte8List: + lt = "byte8List" + case pointerList: + lt = "pointerList" + case compositeList: + lt = "compositeList" + } + return fmt.Sprintf("rawListPointer(%d, %s, %d)", p.offset(), lt, p.numListElements()) + case farPointer: + return fmt.Sprintf("rawFarPointer(%d, %v)", p.farSegment(), p.farAddress()) + case doubleFarPointer: + return fmt.Sprintf("rawDoubleFarPointer(%d, %v)", p.farSegment(), p.farAddress()) + default: + // other pointer + if p.otherPointerType() != 0 { + return fmt.Sprintf("rawPointer(%#016x)", uint64(p)) + } + return fmt.Sprintf("rawInterfacePointer(%d)", p.capabilityIndex()) + } +} + +func (ssa *singleSegmentArena) String() string { + return fmt.Sprintf("single-segment arena [len=%d cap=%d]", len(*ssa), cap(*ssa)) +} + +func (msa *multiSegmentArena) String() string { + return fmt.Sprintf("multi-segment arena [%d segments]", len(*msa)) +} diff --git a/vendor/zombiezen.com/go/capnproto2/struct.go b/vendor/zombiezen.com/go/capnproto2/struct.go new file mode 100644 index 00000000..92148253 --- /dev/null +++ b/vendor/zombiezen.com/go/capnproto2/struct.go @@ -0,0 +1,368 @@ +package capnp + +// Struct is a pointer to a struct. +type Struct struct { + seg *Segment + off Address + size ObjectSize + depthLimit uint + flags structFlags +} + +// NewStruct creates a new struct, preferring placement in s. +func NewStruct(s *Segment, sz ObjectSize) (Struct, error) { + if !sz.isValid() { + return Struct{}, errObjectSize + } + sz.DataSize = sz.DataSize.padToWord() + seg, addr, err := alloc(s, sz.totalSize()) + if err != nil { + return Struct{}, err + } + return Struct{ + seg: seg, + off: addr, + size: sz, + depthLimit: maxDepth, + }, nil +} + +// NewRootStruct creates a new struct, preferring placement in s, then sets the +// message's root to the new struct. +func NewRootStruct(s *Segment, sz ObjectSize) (Struct, error) { + st, err := NewStruct(s, sz) + if err != nil { + return st, err + } + if err := s.msg.SetRootPtr(st.ToPtr()); err != nil { + return st, err + } + return st, nil +} + +// ToStruct converts p to a Struct. +// +// Deprecated: Use Ptr.Struct. +func ToStruct(p Pointer) Struct { + if !IsValid(p) { + return Struct{} + } + s, ok := p.underlying().(Struct) + if !ok { + return Struct{} + } + return s +} + +// ToStructDefault attempts to convert p into a struct, reading the +// default value from def if p is not a struct. +// +// Deprecated: Use Ptr.StructDefault. +func ToStructDefault(p Pointer, def []byte) (Struct, error) { + return toPtr(p).StructDefault(def) +} + +// ToPtr converts the struct to a generic pointer. +func (p Struct) ToPtr() Ptr { + return Ptr{ + seg: p.seg, + off: p.off, + size: p.size, + depthLimit: p.depthLimit, + flags: structPtrFlag(p.flags), + } +} + +// Segment returns the segment this pointer came from. +func (p Struct) Segment() *Segment { + return p.seg +} + +// IsValid returns whether the struct is valid. +func (p Struct) IsValid() bool { + return p.seg != nil +} + +// Address returns the address the pointer references. +// +// Deprecated: The return value is not well-defined. Use SamePtr if you +// need to check whether two pointers refer to the same object. +func (p Struct) Address() Address { + return p.off +} + +// Size returns the size of the struct. +func (p Struct) Size() ObjectSize { + return p.size +} + +// HasData reports whether the struct has a non-zero size. +func (p Struct) HasData() bool { + return !p.size.isZero() +} + +// readSize returns the struct's size for the purposes of read limit +// accounting. +func (p Struct) readSize() Size { + if p.seg == nil { + return 0 + } + return p.size.totalSize() +} + +func (p Struct) underlying() Pointer { + return p +} + +// Pointer returns the i'th pointer in the struct. +// +// Deprecated: Use Ptr. +func (p Struct) Pointer(i uint16) (Pointer, error) { + pp, err := p.Ptr(i) + return pp.toPointer(), err +} + +// Ptr returns the i'th pointer in the struct. +func (p Struct) Ptr(i uint16) (Ptr, error) { + if p.seg == nil || i >= p.size.PointerCount { + return Ptr{}, nil + } + return p.seg.readPtr(p.pointerAddress(i), p.depthLimit) +} + +// SetPointer sets the i'th pointer in the struct to src. +// +// Deprecated: Use SetPtr. +func (p Struct) SetPointer(i uint16, src Pointer) error { + return p.SetPtr(i, toPtr(src)) +} + +// SetPtr sets the i'th pointer in the struct to src. +func (p Struct) SetPtr(i uint16, src Ptr) error { + if p.seg == nil || i >= p.size.PointerCount { + panic(errOutOfBounds) + } + return p.seg.writePtr(p.pointerAddress(i), src, false) +} + +// SetText sets the i'th pointer to a newly allocated text or null if v is empty. +func (p Struct) SetText(i uint16, v string) error { + if v == "" { + return p.SetPtr(i, Ptr{}) + } + return p.SetNewText(i, v) +} + +// SetNewText sets the i'th pointer to a newly allocated text. +func (p Struct) SetNewText(i uint16, v string) error { + t, err := NewText(p.seg, v) + if err != nil { + return err + } + return p.SetPtr(i, t.List.ToPtr()) +} + +// SetTextFromBytes sets the i'th pointer to a newly allocated text or null if v is nil. +func (p Struct) SetTextFromBytes(i uint16, v []byte) error { + if v == nil { + return p.SetPtr(i, Ptr{}) + } + t, err := NewTextFromBytes(p.seg, v) + if err != nil { + return err + } + return p.SetPtr(i, t.List.ToPtr()) +} + +// SetData sets the i'th pointer to a newly allocated data or null if v is nil. +func (p Struct) SetData(i uint16, v []byte) error { + if v == nil { + return p.SetPtr(i, Ptr{}) + } + d, err := NewData(p.seg, v) + if err != nil { + return err + } + return p.SetPtr(i, d.List.ToPtr()) +} + +func (p Struct) pointerAddress(i uint16) Address { + // Struct already had bounds check + ptrStart, _ := p.off.addSize(p.size.DataSize) + a, _ := ptrStart.element(int32(i), wordSize) + return a +} + +// bitInData reports whether bit is inside p's data section. +func (p Struct) bitInData(bit BitOffset) bool { + return p.seg != nil && bit < BitOffset(p.size.DataSize*8) +} + +// Bit returns the bit that is n bits from the start of the struct. +func (p Struct) Bit(n BitOffset) bool { + if !p.bitInData(n) { + return false + } + addr := p.off.addOffset(n.offset()) + return p.seg.readUint8(addr)&n.mask() != 0 +} + +// SetBit sets the bit that is n bits from the start of the struct to v. +func (p Struct) SetBit(n BitOffset, v bool) { + if !p.bitInData(n) { + panic(errOutOfBounds) + } + addr := p.off.addOffset(n.offset()) + b := p.seg.readUint8(addr) + if v { + b |= n.mask() + } else { + b &^= n.mask() + } + p.seg.writeUint8(addr, b) +} + +func (p Struct) dataAddress(off DataOffset, sz Size) (addr Address, ok bool) { + if p.seg == nil || Size(off)+sz > p.size.DataSize { + return 0, false + } + return p.off.addOffset(off), true +} + +// Uint8 returns an 8-bit integer from the struct's data section. +func (p Struct) Uint8(off DataOffset) uint8 { + addr, ok := p.dataAddress(off, 1) + if !ok { + return 0 + } + return p.seg.readUint8(addr) +} + +// Uint16 returns a 16-bit integer from the struct's data section. +func (p Struct) Uint16(off DataOffset) uint16 { + addr, ok := p.dataAddress(off, 2) + if !ok { + return 0 + } + return p.seg.readUint16(addr) +} + +// Uint32 returns a 32-bit integer from the struct's data section. +func (p Struct) Uint32(off DataOffset) uint32 { + addr, ok := p.dataAddress(off, 4) + if !ok { + return 0 + } + return p.seg.readUint32(addr) +} + +// Uint64 returns a 64-bit integer from the struct's data section. +func (p Struct) Uint64(off DataOffset) uint64 { + addr, ok := p.dataAddress(off, 8) + if !ok { + return 0 + } + return p.seg.readUint64(addr) +} + +// SetUint8 sets the 8-bit integer that is off bytes from the start of the struct to v. +func (p Struct) SetUint8(off DataOffset, v uint8) { + addr, ok := p.dataAddress(off, 1) + if !ok { + panic(errOutOfBounds) + } + p.seg.writeUint8(addr, v) +} + +// SetUint16 sets the 16-bit integer that is off bytes from the start of the struct to v. +func (p Struct) SetUint16(off DataOffset, v uint16) { + addr, ok := p.dataAddress(off, 2) + if !ok { + panic(errOutOfBounds) + } + p.seg.writeUint16(addr, v) +} + +// SetUint32 sets the 32-bit integer that is off bytes from the start of the struct to v. +func (p Struct) SetUint32(off DataOffset, v uint32) { + addr, ok := p.dataAddress(off, 4) + if !ok { + panic(errOutOfBounds) + } + p.seg.writeUint32(addr, v) +} + +// SetUint64 sets the 64-bit integer that is off bytes from the start of the struct to v. +func (p Struct) SetUint64(off DataOffset, v uint64) { + addr, ok := p.dataAddress(off, 8) + if !ok { + panic(errOutOfBounds) + } + p.seg.writeUint64(addr, v) +} + +// structFlags is a bitmask of flags for a pointer. +type structFlags uint8 + +// Pointer flags. +const ( + isListMember structFlags = 1 << iota +) + +// copyStruct makes a deep copy of src into dst. +func copyStruct(dst, src Struct) error { + if dst.seg == nil { + return nil + } + + // Q: how does version handling happen here, when the + // destination toData[] slice can be bigger or smaller + // than the source data slice, which is in + // src.seg.Data[src.off:src.off+src.size.DataSize] ? + // + // A: Newer fields only come *after* old fields. Note that + // copy only copies min(len(src), len(dst)) size, + // and then we manually zero the rest in the for loop + // that writes toData[j] = 0. + // + + // data section: + srcData := src.seg.slice(src.off, src.size.DataSize) + dstData := dst.seg.slice(dst.off, dst.size.DataSize) + copyCount := copy(dstData, srcData) + dstData = dstData[copyCount:] + for j := range dstData { + dstData[j] = 0 + } + + // ptrs section: + + // version handling: we ignore any extra-newer-pointers in src, + // i.e. the case when srcPtrSize > dstPtrSize, by only + // running j over the size of dstPtrSize, the destination size. + srcPtrSect, _ := src.off.addSize(src.size.DataSize) + dstPtrSect, _ := dst.off.addSize(dst.size.DataSize) + numSrcPtrs := src.size.PointerCount + numDstPtrs := dst.size.PointerCount + for j := uint16(0); j < numSrcPtrs && j < numDstPtrs; j++ { + srcAddr, _ := srcPtrSect.element(int32(j), wordSize) + dstAddr, _ := dstPtrSect.element(int32(j), wordSize) + m, err := src.seg.readPtr(srcAddr, src.depthLimit) + if err != nil { + return err + } + err = dst.seg.writePtr(dstAddr, m, true) + if err != nil { + return err + } + } + for j := numSrcPtrs; j < numDstPtrs; j++ { + // destination p is a newer version than source so these extra new pointer fields in p must be zeroed. + addr, _ := dstPtrSect.element(int32(j), wordSize) + dst.seg.writeRawPointer(addr, 0) + } + // Nothing more here: so any other pointers in srcPtrSize beyond + // those in dstPtrSize are ignored and discarded. + + return nil +}