diff --git a/vendor/github.com/coreos/go-semver/LICENSE b/vendor/github.com/coreos/go-semver/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/coreos/go-semver/NOTICE b/vendor/github.com/coreos/go-semver/NOTICE new file mode 100644 index 00000000000..23a0ada2fbb --- /dev/null +++ b/vendor/github.com/coreos/go-semver/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go new file mode 100644 index 00000000000..76cf4852c76 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/semver/semver.go @@ -0,0 +1,296 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Semantic Versions http://semver.org +package semver + +import ( + "bytes" + "errors" + "fmt" + "regexp" + "strconv" + "strings" +) + +type Version struct { + Major int64 + Minor int64 + Patch int64 + PreRelease PreRelease + Metadata string +} + +type PreRelease string + +func splitOff(input *string, delim string) (val string) { + parts := strings.SplitN(*input, delim, 2) + + if len(parts) == 2 { + *input = parts[0] + val = parts[1] + } + + return val +} + +func New(version string) *Version { + return Must(NewVersion(version)) +} + +func NewVersion(version string) (*Version, error) { + v := Version{} + + if err := v.Set(version); err != nil { + return nil, err + } + + return &v, nil +} + +// Must is a helper for wrapping NewVersion and will panic if err is not nil. +func Must(v *Version, err error) *Version { + if err != nil { + panic(err) + } + return v +} + +// Set parses and updates v from the given version string. Implements flag.Value +func (v *Version) Set(version string) error { + metadata := splitOff(&version, "+") + preRelease := PreRelease(splitOff(&version, "-")) + dotParts := strings.SplitN(version, ".", 3) + + if len(dotParts) != 3 { + return fmt.Errorf("%s is not in dotted-tri format", version) + } + + if err := validateIdentifier(string(preRelease)); err != nil { + return fmt.Errorf("failed to validate pre-release: %v", err) + } + + if err := validateIdentifier(metadata); err != nil { + return fmt.Errorf("failed to validate metadata: %v", err) + } + + parsed := make([]int64, 3, 3) + + for i, v := range dotParts[:3] { + val, err := strconv.ParseInt(v, 10, 64) + parsed[i] = val + if err != nil { + return err + } + } + + v.Metadata = metadata + v.PreRelease = preRelease + v.Major = parsed[0] + v.Minor = parsed[1] + v.Patch = parsed[2] + return nil +} + +func (v Version) String() string { + var buffer bytes.Buffer + + fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch) + + if v.PreRelease != "" { + fmt.Fprintf(&buffer, "-%s", v.PreRelease) + } + + if v.Metadata != "" { + fmt.Fprintf(&buffer, "+%s", v.Metadata) + } + + return buffer.String() +} + +func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error { + var data string + if err := unmarshal(&data); err != nil { + return err + } + return v.Set(data) +} + +func (v Version) MarshalJSON() ([]byte, error) { + return []byte(`"` + v.String() + `"`), nil +} + +func (v *Version) UnmarshalJSON(data []byte) error { + l := len(data) + if l == 0 || string(data) == `""` { + return nil + } + if l < 2 || data[0] != '"' || data[l-1] != '"' { + return errors.New("invalid semver string") + } + return v.Set(string(data[1 : l-1])) +} + +// Compare tests if v is less than, equal to, or greater than versionB, +// returning -1, 0, or +1 respectively. +func (v Version) Compare(versionB Version) int { + if cmp := recursiveCompare(v.Slice(), versionB.Slice()); cmp != 0 { + return cmp + } + return preReleaseCompare(v, versionB) +} + +// Equal tests if v is equal to versionB. +func (v Version) Equal(versionB Version) bool { + return v.Compare(versionB) == 0 +} + +// LessThan tests if v is less than versionB. +func (v Version) LessThan(versionB Version) bool { + return v.Compare(versionB) < 0 +} + +// Slice converts the comparable parts of the semver into a slice of integers. +func (v Version) Slice() []int64 { + return []int64{v.Major, v.Minor, v.Patch} +} + +func (p PreRelease) Slice() []string { + preRelease := string(p) + return strings.Split(preRelease, ".") +} + +func preReleaseCompare(versionA Version, versionB Version) int { + a := versionA.PreRelease + b := versionB.PreRelease + + /* Handle the case where if two versions are otherwise equal it is the + * one without a PreRelease that is greater */ + if len(a) == 0 && (len(b) > 0) { + return 1 + } else if len(b) == 0 && (len(a) > 0) { + return -1 + } + + // If there is a prerelease, check and compare each part. + return recursivePreReleaseCompare(a.Slice(), b.Slice()) +} + +func recursiveCompare(versionA []int64, versionB []int64) int { + if len(versionA) == 0 { + return 0 + } + + a := versionA[0] + b := versionB[0] + + if a > b { + return 1 + } else if a < b { + return -1 + } + + return recursiveCompare(versionA[1:], versionB[1:]) +} + +func recursivePreReleaseCompare(versionA []string, versionB []string) int { + // A larger set of pre-release fields has a higher precedence than a smaller set, + // if all of the preceding identifiers are equal. + if len(versionA) == 0 { + if len(versionB) > 0 { + return -1 + } + return 0 + } else if len(versionB) == 0 { + // We're longer than versionB so return 1. + return 1 + } + + a := versionA[0] + b := versionB[0] + + aInt := false + bInt := false + + aI, err := strconv.Atoi(versionA[0]) + if err == nil { + aInt = true + } + + bI, err := strconv.Atoi(versionB[0]) + if err == nil { + bInt = true + } + + // Numeric identifiers always have lower precedence than non-numeric identifiers. + if aInt && !bInt { + return -1 + } else if !aInt && bInt { + return 1 + } + + // Handle Integer Comparison + if aInt && bInt { + if aI > bI { + return 1 + } else if aI < bI { + return -1 + } + } + + // Handle String Comparison + if a > b { + return 1 + } else if a < b { + return -1 + } + + return recursivePreReleaseCompare(versionA[1:], versionB[1:]) +} + +// BumpMajor increments the Major field by 1 and resets all other fields to their default values +func (v *Version) BumpMajor() { + v.Major += 1 + v.Minor = 0 + v.Patch = 0 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// BumpMinor increments the Minor field by 1 and resets all other fields to their default values +func (v *Version) BumpMinor() { + v.Minor += 1 + v.Patch = 0 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// BumpPatch increments the Patch field by 1 and resets all other fields to their default values +func (v *Version) BumpPatch() { + v.Patch += 1 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// validateIdentifier makes sure the provided identifier satisfies semver spec +func validateIdentifier(id string) error { + if id != "" && !reIdentifier.MatchString(id) { + return fmt.Errorf("%s is not a valid semver identifier", id) + } + return nil +} + +// reIdentifier is a regular expression used to check that pre-release and metadata +// identifiers satisfy the spec requirements +var reIdentifier = regexp.MustCompile(`^[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*$`) diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go new file mode 100644 index 00000000000..e256b41a5dd --- /dev/null +++ b/vendor/github.com/coreos/go-semver/semver/sort.go @@ -0,0 +1,38 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semver + +import ( + "sort" +) + +type Versions []*Version + +func (s Versions) Len() int { + return len(s) +} + +func (s Versions) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s Versions) Less(i, j int) bool { + return s[i].LessThan(*s[j]) +} + +// Sort sorts the given slice of Version +func Sort(versions []*Version) { + sort.Sort(Versions(versions)) +} diff --git a/vendor/github.com/coreos/go-systemd/v22/LICENSE b/vendor/github.com/coreos/go-systemd/v22/LICENSE new file mode 100644 index 00000000000..37ec93a14fd --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/v22/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/coreos/go-systemd/v22/NOTICE b/vendor/github.com/coreos/go-systemd/v22/NOTICE new file mode 100644 index 00000000000..23a0ada2fbb --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/v22/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal.go new file mode 100644 index 00000000000..ac24c7767d3 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal.go @@ -0,0 +1,46 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package journal provides write bindings to the local systemd journal. +// It is implemented in pure Go and connects to the journal directly over its +// unix socket. +// +// To read from the journal, see the "sdjournal" package, which wraps the +// sd-journal a C API. +// +// http://www.freedesktop.org/software/systemd/man/systemd-journald.service.html +package journal + +import ( + "fmt" +) + +// Priority of a journal message +type Priority int + +const ( + PriEmerg Priority = iota + PriAlert + PriCrit + PriErr + PriWarning + PriNotice + PriInfo + PriDebug +) + +// Print prints a message to the local systemd journal using Send(). +func Print(priority Priority, format string, a ...interface{}) error { + return Send(fmt.Sprintf(format, a...), priority, nil) +} diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go new file mode 100644 index 00000000000..8d58ca0fbca --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go @@ -0,0 +1,210 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows + +// Package journal provides write bindings to the local systemd journal. +// It is implemented in pure Go and connects to the journal directly over its +// unix socket. +// +// To read from the journal, see the "sdjournal" package, which wraps the +// sd-journal a C API. +// +// http://www.freedesktop.org/software/systemd/man/systemd-journald.service.html +package journal + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "io/ioutil" + "net" + "os" + "strconv" + "strings" + "sync" + "sync/atomic" + "syscall" + "unsafe" +) + +var ( + // This can be overridden at build-time: + // https://github.com/golang/go/wiki/GcToolchainTricks#including-build-information-in-the-executable + journalSocket = "/run/systemd/journal/socket" + + // unixConnPtr atomically holds the local unconnected Unix-domain socket. + // Concrete safe pointer type: *net.UnixConn + unixConnPtr unsafe.Pointer + // onceConn ensures that unixConnPtr is initialized exactly once. + onceConn sync.Once +) + +func init() { + onceConn.Do(initConn) +} + +// Enabled checks whether the local systemd journal is available for logging. +func Enabled() bool { + onceConn.Do(initConn) + + if (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr)) == nil { + return false + } + + conn, err := net.Dial("unixgram", journalSocket) + if err != nil { + return false + } + defer conn.Close() + + return true +} + +// Send a message to the local systemd journal. vars is a map of journald +// fields to values. Fields must be composed of uppercase letters, numbers, +// and underscores, but must not start with an underscore. Within these +// restrictions, any arbitrary field name may be used. Some names have special +// significance: see the journalctl documentation +// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html) +// for more details. vars may be nil. +func Send(message string, priority Priority, vars map[string]string) error { + conn := (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr)) + if conn == nil { + return errors.New("could not initialize socket to journald") + } + + socketAddr := &net.UnixAddr{ + Name: journalSocket, + Net: "unixgram", + } + + data := new(bytes.Buffer) + appendVariable(data, "PRIORITY", strconv.Itoa(int(priority))) + appendVariable(data, "MESSAGE", message) + for k, v := range vars { + appendVariable(data, k, v) + } + + _, _, err := conn.WriteMsgUnix(data.Bytes(), nil, socketAddr) + if err == nil { + return nil + } + if !isSocketSpaceError(err) { + return err + } + + // Large log entry, send it via tempfile and ancillary-fd. + file, err := tempFd() + if err != nil { + return err + } + defer file.Close() + _, err = io.Copy(file, data) + if err != nil { + return err + } + rights := syscall.UnixRights(int(file.Fd())) + _, _, err = conn.WriteMsgUnix([]byte{}, rights, socketAddr) + if err != nil { + return err + } + + return nil +} + +func appendVariable(w io.Writer, name, value string) { + if err := validVarName(name); err != nil { + fmt.Fprintf(os.Stderr, "variable name %s contains invalid character, ignoring\n", name) + } + if strings.ContainsRune(value, '\n') { + /* When the value contains a newline, we write: + * - the variable name, followed by a newline + * - the size (in 64bit little endian format) + * - the data, followed by a newline + */ + fmt.Fprintln(w, name) + binary.Write(w, binary.LittleEndian, uint64(len(value))) + fmt.Fprintln(w, value) + } else { + /* just write the variable and value all on one line */ + fmt.Fprintf(w, "%s=%s\n", name, value) + } +} + +// validVarName validates a variable name to make sure journald will accept it. +// The variable name must be in uppercase and consist only of characters, +// numbers and underscores, and may not begin with an underscore: +// https://www.freedesktop.org/software/systemd/man/sd_journal_print.html +func validVarName(name string) error { + if name == "" { + return errors.New("Empty variable name") + } else if name[0] == '_' { + return errors.New("Variable name begins with an underscore") + } + + for _, c := range name { + if !(('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_') { + return errors.New("Variable name contains invalid characters") + } + } + return nil +} + +// isSocketSpaceError checks whether the error is signaling +// an "overlarge message" condition. +func isSocketSpaceError(err error) bool { + opErr, ok := err.(*net.OpError) + if !ok || opErr == nil { + return false + } + + sysErr, ok := opErr.Err.(*os.SyscallError) + if !ok || sysErr == nil { + return false + } + + return sysErr.Err == syscall.EMSGSIZE || sysErr.Err == syscall.ENOBUFS +} + +// tempFd creates a temporary, unlinked file under `/dev/shm`. +func tempFd() (*os.File, error) { + file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX") + if err != nil { + return nil, err + } + err = syscall.Unlink(file.Name()) + if err != nil { + return nil, err + } + return file, nil +} + +// initConn initializes the global `unixConnPtr` socket. +// It is meant to be called exactly once, at program startup. +func initConn() { + autobind, err := net.ResolveUnixAddr("unixgram", "") + if err != nil { + return + } + + sock, err := net.ListenUnixgram("unixgram", autobind) + if err != nil { + return + } + + atomic.StorePointer(&unixConnPtr, unsafe.Pointer(sock)) +} diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go new file mode 100644 index 00000000000..677aca68ed2 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go @@ -0,0 +1,35 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package journal provides write bindings to the local systemd journal. +// It is implemented in pure Go and connects to the journal directly over its +// unix socket. +// +// To read from the journal, see the "sdjournal" package, which wraps the +// sd-journal a C API. +// +// http://www.freedesktop.org/software/systemd/man/systemd-journald.service.html +package journal + +import ( + "errors" +) + +func Enabled() bool { + return false +} + +func Send(message string, priority Priority, vars map[string]string) error { + return errors.New("could not initialize socket to journald") +} diff --git a/vendor/github.com/ipld/go-codec-dagpb/gen.go b/vendor/github.com/ipld/go-codec-dagpb/gen.go new file mode 100644 index 00000000000..ec4c3c6aa30 --- /dev/null +++ b/vendor/github.com/ipld/go-codec-dagpb/gen.go @@ -0,0 +1,68 @@ +//go:build ignore + +package main + +// based on https://github.com/ipld/go-ipld-prime-proto/blob/master/gen/main.go + +import ( + "fmt" + "os" + + "github.com/ipld/go-ipld-prime/schema" + gengo "github.com/ipld/go-ipld-prime/schema/gen/go" +) + +func main() { + ts := schema.TypeSystem{} + ts.Init() + adjCfg := &gengo.AdjunctCfg{} + + pkgName := "dagpb" + + ts.Accumulate(schema.SpawnString("String")) + ts.Accumulate(schema.SpawnInt("Int")) + ts.Accumulate(schema.SpawnLink("Link")) + ts.Accumulate(schema.SpawnBytes("Bytes")) + + /* + type PBLink struct { + Hash Link + Name optional String + Tsize optional Int + } + */ + + ts.Accumulate(schema.SpawnStruct("PBLink", + []schema.StructField{ + schema.SpawnStructField("Hash", "Link", false, false), + schema.SpawnStructField("Name", "String", true, false), + schema.SpawnStructField("Tsize", "Int", true, false), + }, + schema.SpawnStructRepresentationMap(nil), + )) + ts.Accumulate(schema.SpawnList("PBLinks", "PBLink", false)) + + /* + type PBNode struct { + Links [PBLink] + Data optional Bytes + } + */ + + ts.Accumulate(schema.SpawnStruct("PBNode", + []schema.StructField{ + schema.SpawnStructField("Links", "PBLinks", false, false), + schema.SpawnStructField("Data", "Bytes", true, false), + }, + schema.SpawnStructRepresentationMap(nil), + )) + + if errs := ts.ValidateGraph(); errs != nil { + for _, err := range errs { + fmt.Printf("- %s\n", err) + } + os.Exit(1) + } + + gengo.Generate(".", pkgName, ts, adjCfg) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/dmt/gen.go b/vendor/github.com/ipld/go-ipld-prime/schema/dmt/gen.go new file mode 100644 index 00000000000..fd4760ca6fb --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/dmt/gen.go @@ -0,0 +1,25 @@ +//go:build ignore + +package main + +import ( + "fmt" + "os" + + "github.com/ipld/go-ipld-prime/node/bindnode" + schemadmt "github.com/ipld/go-ipld-prime/schema/dmt" +) + +func main() { + f, err := os.Create("types.go") + if err != nil { + panic(err) + } + fmt.Fprintf(f, "package schemadmt\n\n") + if err := bindnode.ProduceGoTypes(f, schemadmt.TypeSystem); err != nil { + panic(err) + } + if err := f.Close(); err != nil { + panic(err) + } +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME.md new file mode 100644 index 00000000000..d037e8e18d8 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME.md @@ -0,0 +1,135 @@ +hacking gengo +============= + +What the heck? +-------------- + +We're doing code generation. + +The name of the game is "keep it simple". +Most of this is implemented as string templating. +No, we didn't use the Go AST system. We could have; we didn't. +Implementing this as string templating seemed easier to mentally model, +and the additional value provided by use of AST libraries seems minimal +since we feed the outputs into a compiler for verification immediately anyway. + +Some things seem significantly redundant. +That's probably because they are. +In general, if there's a choice between apparent redundancy in the generator itself +versus almost any other tradeoff which affects the outputs, we prioritize the outputs. +(This may be especially noticable when it comes to error messages: we emit a lot +of them... while making sure they contain very specific references. This leads +to some seemingly redundant code, but good error messages are worth it.) + +See [README_behaviors](README_behaviors.md) for notes about the behaviors of the code output by the generator; +this document is about the generator code itself and the design thereof. + + +Entrypoints +----------- + +The most important intefaces are all in [`generators.go`](generators.go). + +The function you're most likely looking for that "does the thing" is the +`Generate(outputPath string, pkgName string, schema.TypeSystem, *AdjunctCfg)` method, +which can be found in the [`generate.go`](generate.go) file. +You can take any of the functions inside of that and use them as well, +if you want more granular control over what content ends up in which files. + +The eventual plan is be able to drive this whole apparatus around via a CLI +which consumes IPLD Schema files. +Implementing this can come after more of the core is done. +(Seealso the `schema/tmpBuilders.go` file a couple directories up for why +this is currently filed as nontrivial/do-later.) + + +Organization +------------ + +### How many things are generated, anyway? + +There are roughly *seven* categories of API to generate per type: + +- 1: the readonly thing a native caller uses +- 2: the builder thing a native caller uses +- 3: the readonly typed node +- 4: the builder/assembler for typed node +- 5: the readonly representation node +- 6: the builder/assembler via representation +- 7: and a maybe wrapper + +(And these are just the ones nominally visible in the exported API surface! +There are several more concrete types than this implied by some parts of that list, +such as iterators for the nodes, internal parts of builders, and so forth.) + +These numbers will be used to describe some further organization. + +### How are the generator components grouped? + +There are three noteworthy types of generator internals: + +- `TypeGenerator` +- `NodeGenerator` +- `NodebuilderGenerator` + +The first one is where you start; the latter two do double duty for each type. + +Exported types for purpose 1, 2, 3, and 7 are emitted from `TypeGenerator` (3 from the embedded `NodeGenerator`). + +The exported type for purpose 5 is emitted from another `NodeGenerator` instance. + +The exported types for purposes 4 and 6 are emitted from two distinct `NodebuilderGenerator` instances. + +For every variation in type kind and representation strategy for that type kind, +one type implementing `TypeGenerator` is composed, and it has functions which +yield all the other interfaces for addressing the various purposes. + +### How are files and their contents grouped? + +Most of the files in this package are following a pattern: + +- for each kind: + - `gen{Kind}.go` -- has emitters for the native type parts (1, 2, 7) and type-level node behaviors (3, 4). + - for each representation that kind can have: + - `gen{Kind}Repr{ReprStrat}.go` -- has emitters for (5, 6). + +A `mixins` sub-package contains some code which is used and embedded in the generators in this package. +These features are mostly per-kind -- representation kind, not type-level kind. +For example, you'll see "map" behaviors from the mixins package added to "struct" generators. + +### What are all these abbreviations? + +See [HACKME_abbrevs.md](HACKME_abbrevs.md). + +### Code architecture + +See [HACKME_tradeoffs.md](HACKME_tradeoffs.md) for an overview of tradeoffs, +and which priorities we selected in this package. +(There are *many* tradeoffs.) + +See [HACKME_memorylayout.md](HACKME_memorylayout.md) for a (large) amount of +exposition on how this code is designed in order to be allocation-avoidant +and fast in general. + +See [HACKME_templates.md](HACKME_templates.md) for some overview on how we've +used templates, and what forms of reuse and abstraction there are. + +See [HACKME_scalars.md](HACKME_scalars.md) for some discussion of scalars +and (why we generate more of them than you might expect). + +See [HACKME_maybe.md](HACKME_maybe.md) for notes how how the 'maybe' feature +(how we describe `nullable` and `optional` schema features in generated golang code) +has evolved. + + +Testing +------- + +See [HACKME_testing.md](HACKME_testing.md) for some details about how this works. + +In general, try to copy some of the existing tests and get things to suit. + +Be advised that we use the golang plugin feature, and that has some additional +requirements of your development environment than is usual in golang. +(Namely, you have to be on linux and you have to have a c compiler!) + diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_abbrevs.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_abbrevs.md new file mode 100644 index 00000000000..23b38f9821e --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_abbrevs.md @@ -0,0 +1,25 @@ +abbreviations +============= + +A lot of abbreviations are used the generated code in the interest of minimizing the size of the output. + +This is a short index of the most common ones: + +- `n` -- **n**ode, of course -- the accessor functions on node implementations usually refer to their 'this' as 'n'. +- `na` -- **n**ode **a**ssembler + - `la` or `ma` may also be seen for **l**ist and **m**ap in some contexts (but may refer to same type being called `na` in other contexts). +- `w` -- **w**ork-in-progress node -- you'll see this in nearly every assembler (e.g. `na.w` is a very common string). + +inside nodes: + +- `x` -- a placeholder for "the thing" for types that contain only one element of data (e.g., the string inside a codegen'd node of string kind). +- `t` -- **t**able -- the slice inside most map nodes that is used for alloc amortizations and maintaining order. +- `m` -- **m**ap -- the actual map inside most map nodes (seealso `t`, which is usually a sibling). + +inside assemblers: + +- `va` -- **v**alue **a**ssembler -- an assembler for values in lists or maps (often embedded in the node asembler, e.g. `ma.va` and `la.va` are common strings). +- `ka` -- **k**ey **a**ssembler -- an assembler for keys in maps (often embedded in the node asembler, e.g. `ma.ka` is a common string). +- `ca_*` -- **c**hild **a**ssembler -- the same concept as `ka` and `va`, but appearing in structs and other types that have differentiated children. +- `cm` -- **c**hild **m**aybe -- a piece of memory sometimes found in a node assembler for statekeeping for child assemblers. +- `m` -- **m**aybe pointer -- a pointer to where an assembler should put a mark when it's finished. (this is often a pointer to a parent structure's 'cm'!) diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_dry.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_dry.md new file mode 100644 index 00000000000..cbcce80166b --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_dry.md @@ -0,0 +1,82 @@ +HACKME: "don't repeat yourself": how-to (and, limits of that goal) +================================================================== + +Which kind of extraction applies? +--------------------------------- + +Things vary in how identical they are. + +- **Textually identical**: Some code is textually identical between different types, + varying only in the most simple and obvious details, like the actual type name it's attached to. + - These cases can often be extracted on the generation side... + - We tend to put them in `genparts{*}.go` files. + - But the output is still pretty duplicacious. + +- **Textually identical minus simple variations**: Some code is textually *nearly* identical, + but varies in relatively minor ways (such as whether or not the "Repr" is part of munges, and "Representation()" calls are made, etc). + - These cases can often be extracted on the generation side... + - We tend to put them in `genparts{*}.go` files. + - There's just a bit more `{{ various templating }}` injected in them, compared to other textually identical templates. + - But the output is still pretty duplicacious. + +- **Linkologically identical**: When code is not _only_ textually identical, + but also refers to identical types. + - These cases can be extracted on the generation side... + - but it may be questionable to do so: if its terse enough in the output, there's that much less incentive to make a template-side shorthand for it. + - The output in this case can actually be deduplicated! + - It's possible we haven't bothered yet. **That doesn't mean it's not worth it**; we probably just haven't had time yet. PRs welcome. + - How? + - functions? This is the most likely to apply. + - embedded types? We haven't seen many cases where this can help, yet (unfortunately?). + - shared constants? + - It's not always easy to do this. + - We usually put something in the "minima" file. + - We don't currently have a way to toggle whether whole features or shared constants are emitted in the minima file. Todo? + - This requires keeping state that records what's necessary as we go, so that we can do them all together at the end. + - May also require varying the imports at the top of the minima file. (But: by doing it only here, we can avoid that complexity in every other file.) + - **This is actually pretty rare**. _Things that are textually identical are not necessarily linkologically identical_. + - One can generally turn things that are textually identical into linkologically identical by injecting an interface into the types... + - ... but this isn't always a *good* idea: + - if this would cause more allocations? Yeah, very no. + - even if this can be done without a heap allocation, it probably means inlining and other optimizations will become impossible for the compiler to perform, and often, we're not okay with the performance implications of that either. + +- **Identical if it wasn't for debugability**: In some cases, code varies only by some small constants... + and really, those constants could be removed entirely. If... we didn't care about debugging. Which we do. + - This is really the same as "textually identical minus simple variations", but worth talking about briefly just because of the user story around it. + - A bunch of the error-thunking methods on Node and NodeAssemblers exemplify this. + - It's really annoying that we can't remove this boilerplate entirely from the generated code. + - It's also basically impossible, because we *want* information that varies per type in those error messages. + + +What mechanism of extraction should be used? +-------------------------------------------- + +- (for gen-side dry) gen-side functions + - this is most of what we've done so far +- (for gen-side dry) sub-templates + - we currently don't really use this at all +- (for gen-side dry) template concatenation + - some of this: kinded union representations do this +- (for output-side dry) output side functions + - some of this: see "minima" file. +- (for output-side dry) output side embeds + - we currently don't really use this at all (it hasn't really turned out applicable in any cases yet). + + +Don't overdo it +--------------- + +I'd rather have longer templates than harder-to-read and harder-to-maintain templates. + +There's a balance to this and it's tricky to pick out. + +A good heuristic to consider might be: are we extracting this thing because we can? +Or because if we made changes to this thing in the future, we'd expect to need to make that change in every single place we've extracted it from, +which therefore makes the extraction a net win for maintainability? +If it's the latter: then yes, extract it. +If it's not clear: maybe let it be. + +(It may be the case that the preferable balance for DRYing changes over time as we keep maintaining things. +We'll see; but it's certainly the case that the first draft of this package has favored length heavily. +There was a lot of "it's not clear" when the maintainability heuristic was applied during the first writing of this; +that may change! If so, that's great.) diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_maybe.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_maybe.md new file mode 100644 index 00000000000..8621fcfef15 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_maybe.md @@ -0,0 +1,392 @@ +How do maybe/nullable/optional work? +==================================== + +(No, this document is not about things that we should "maybe" hack on. +It's about the feature we use to describe `nullable` and `optional` fields +in generated golang code.) + +background +---------- + +You'll need to understand what the `nullable` and `optional` modifiers in IPLD schemas mean. +The https://specs.datamodel.io/ site has more content about that. + +### how this works outside of schemas + +There are concepts of null and of absent present in the core `Node` and `NodeAssembler` interfaces. +`Node` specifies `IsNull() bool` and `IsAbsent() bool` predicates; +and `NodeAssembler` specifies an `AssignNull` function. + +There are also singleton values available called `datamodel.Null` and `datamodel.Absent` +which report true for `IsNull` and `IsAbsent`, respectively. +These singletons can be used by an function that need to return a null or absence indicator. + +There's really no reason for any package full of `Node` implementations need to make their own types for these values, +since the singletons are always fine to use. +However, there's also nothing stopping a `Node` implementation from doing interesting +custom internal memory layouts to describe whether they contain nulls, etc -- +and there's nothing particularly blessed about the `datamodel.Null` singleton. +Any value reporting `IsNull` to be `true` must be treated indistinguishably from `datamodel.Null`. + +This indistinguishability is bidirectional. +For example, if you have some `myFancyNodeType`, and it answers `IsNull` as `true`, +and you insert this into a `basicnode.Map`, then ask for that value back from the map later... +you're very likely to get `datamodel.Null`, and not your concrete value of `myFancyNodeType` back again. +(This contract is important because some node implementations may compress +the concept of null into a bitmask, or otherwise similarly optimize things internally.) + +#### null + +The concept of "null" has a Kind in the IPLD Data Model. +It's implemented by the `datamodel.nullNode` type (which has no fields -- it's a "unit" type), +and is exposed as the `datamodel.Null` singleton value. + +(More generally, `datamodel.Node` can be null by having its `Kind()` method return `datamodel.Kind_Null`, +and having the `IsNull()` method return `true`. +However, most code prefers to return the `datamodel.Null` singleton value whenever it can.) + +Null values can be easily produced: the `AssignNull()` method on `datamodel.NodeAssembler` produces nulls; +and many codecs have some concept of null, meaning deserialization can produce them. + +Null values work essentially the same way in both the plain Data Model and when working with Schemas. + +#### absent + +There's also a concept of "absent". +"Absent" is separate and distinct from the concept of "null" -- null is still a _value_; absent just means _nothing there_. + +(Those familiar with javascript might note that javascript also has concepts of "null" versus "undefined". +It's the same idea -- we just call it "absent" instead of "undefined".) + +Absent is implemented by the `datamodel.absentNode` type (which has no fields -- it's a "unit" type), +and is exposed as the `datamodel.Absent` singleton value. + +(More generally, an `datamodel.Node` can describe itself as containing "absent" by having the `IsAbsent()` method return `true`. +(The `Kind()` method still returns `datamodel.Kind_Null`, for lack of better option.) +However, most code prefers to return the `datamodel.Absent` singleton value whenever it can.) + +Absent values aren't really used at the Data Model level. +If you ask for a map key that isn't present in the map, the lookup method will return `nil` and `ErrNotExists`. + +Absent values *do* show up at the Schema level, however. +Specifically, in structs: a struct can have a field which is `optional`, +one of the values such an optional field may report itself as having is `datamodel.Absent`. +This represents when a value *wasn't present* in the serialized form of the struct, +even though the schema lets us know that it could be, and that it's part of the struct's type. +(Accordingly, no `ErrNotExists` is returned for a lookup of that field -- +the field is always considered to _exist_... the value is just _absent_.) +Iterators will also return the field name key, together with `datamodel.Absent` as the value. + +However, absent values can't really be *created*. +There's no such thing as an `AssignAbsent` or `AssignAbsent` method on the `datamodel.NodeAssembler` interface. +Codecs similarly can't produce absent as a value (obviously -- codecs work over `datamodel.NodeAssembler`, so how could they?). +Absent values are just produced by implication, when a field is defined, but its value isn't set. + +Despite absent values not being used or produced at the Data Model, we still have methods like `IsAbsent` specified +as part of the `datamodel.Node` interface so that it's possible to write code which is generic over +either plain Data Model or Schema data while using just that interface. + +### the above is all regarding generic interfaces + +As long as we're talking about the `datamodel.Node` _interface_, +we talk about the `datamodel.Null` and `datamodel.Absent` singletons, and their contracts in terms of the interface. + +(Part of the reason this works is because an interface, in golang, +comes in two parts: a pointer to the typeinfo of the inhabitant value, +and a pointer to the value itself. +This means anywhere we have an `datamodel.Node` return type, we can toss `datamodel.Null` +or `datamodel.Absent` into it with no additional overhead!) + +When we talk about concrete types, rather than the `datamodel.Node` _interface_ -- +as we're going to, in codegen -- it's a different scenario. +We can't just return `datamodel.Null` pointers for a `genresult.Foo` value; +if `genresult.Foo` is a concrete type, that's just flat out a compile error. + +So what shall we do? + +We introduce the "maybe" types. + + + +the maybe types +--------------- + +The general rule of "return `datamodel.Null` whenever you have a null value" +holds up only as long as our API is returning monomorphized `datamodel.Node` interfaces -- +in that situation, `datamodel.Null` fits within `datamodel.Node`, and there's no trouble. + +This doesn't hold up when we get to codegen. +Or rather, more specifically, it even holds up for codegen... +as long as we're still returning monomorphized `datamodel.Node` interfaces (and a decent amount of the API surface still does so). +At the moment we want to return a concrete native type, it breaks. + +We call methods created by codegen that use specific types +(e.g., methods that you _couldn't have_ without codegen) +"speciated" methods. And we do want them! + +So we have to decide how to handle null and absent for these speciated methods. + +### goals of the maybe types + +There are a couple of things we want to accomplish with the maybe types: + +- Be able to have speciated methods that return a specific type (for doc, editor autocomplete, etc purposes). +- Be able to have speciated methods that return specific *concrete* type (i.e. not only do we want to be more specific than `datamodel.Node`, we don't want an interface _at all_ -- so that the compiler can do inlining and optimization and so forth). +- Make reading and writing code that uses speciated methods and handles nullable or optional fields be reasonably ergonomic (and as always, this may vary by "taste"). + +And we'll consider one more fourth, bonus goal: + +- It would be nice if the maybe types can clearly discuss whether the type is `(null|value)` vs `(absent|value)` vs `(absent|null|value)`, because this would let the golang compiler help check more of our logical correctness in code written using optionals and nullables. + +### there is only one type generated for each maybe + +For every type generated, there is one maybe type also generated. +(At least this much is clearly necesary to satisfy the goals about "specific types".) + +This means *we dropped the bonus goal* above. +Making `(null|value)` vs `(absent|value)` vs `(absent|null|value)` distinguishable to the golang compiler +would require three *additional* generated types (for obvious reasons) for each type specified by the Schema. +We decided that's simply too onerous. + +(A different codegen project could certainly make a different choice here, though.) + +### the symbol for maybe types + +For some type named `T` generated into a package named `gen`... + +- the main type symbol is `gen.T`; +- the maybe for that type is `gen.MaybeT`; + +Beware that this may spell trouble if your schema contains any types +with names starting in "Maybe". +(You can use adjunct config to change symbols for those types, if necessary.) + +(There are also internal symbols for the same things, +but these are prefixed in such a way as to make collision not a concern.) + +### maybe types don't implement the full Node interface + +The "maybe" types don't implement the full `datamodel.Node` interface. +They could have! They don't. + +Arguments that went in favor of implementing `Node`: + +- generally "seem fine" +- certainly makes sense to be able to 'IsNull' on it like any other Node. +- if in practice the maybe is embeded, we can return an internal pointer to it just fine, so there's no obvious runtime perf reason not to. + +Arguments against: + +- it's another type with a ton of methods. or two, or four. + - may increase the binary size. possibly by a significant constant multiplier. + - definitely increases the gsloc size, significantly. +- would it have a 'Type' accessor on it? + - if so, what does it say? +- simply not sure how useful this is! + - istm one will often either be passing the MaybeT to other speciated functions, or, fairly immediately de-maybing it. + - if this is true, the number of times anyone wants to treat it as a Node in practice are near zero. +- does this imply the existence of a _MaybeT__Assembler type, as well? + - binary and gsloc size still drifting up; this needs to justify itself and provide value to be worth it. + - what would be the expected behavior of handing a _MaybeT__Assembler to something like unmarshalling? + - if you have a null in the root, you can describe this with a kinded union, and probably would be better off for it. + - if you have can absent value in the root of a document you're unmarshalling... what? That's called "EOF". + - does a _MaybeT__Assembler show up usefully in the middle of a tree? + - it does not! there's always a _P_ValueAssembler type involved there anyway (this is needed for parent state machine purposes), and it largely delegates to the _T__Assembler, but is already a perfect position to add on the "maybe" semantics if the P type has them for its children. + +The arguments against carried the day. + +### the maybe type is emebbedable + +It's important that the "maybe" types be embeddable, for all the same reasons that +[we normally want embeddable types](./HACKME_memorylayout.md#embed-by-default). + +It's interesting to consider the alternatives, though: + +We could've bitpacked the isAbsent or isNull flags for a field into one word at the top of a struct, for example. +But, there are numerous drawbacks to this: + +- the complexity of this is high. +- it would be exposed to anyone who writes addntl code in-package, which is asking for errors. +- the only thing this buys us is *slightly* less resident memory size. + - and long story short: if you look at how many other programming language do this, pareto-wise, no one in the world at large appears to care. +- it only applies to structs! maps or lists would require yet more custom bitpacking of a different arrangement. + +If someone wants to do another codegen project someday, or make PRs to this one, which does choose bitpacking, +it would probably be neat. It's just a lot of effort for a payout that doesn't seem to often be worth it. + +(We also ended up using pointers to a field with a `schema.Maybe` type _heavily_ +in the internals of our codegen outputs, in order to let child and parent assemblers coordinate. +Rebuilding this to work with a bitpacking alignment and yet still be composable enough to do its job... uufdah. Tricky. +It might be possible to use the current system in the assembler state, but flip it bitpack in the resulting immutable nodes, +and thereby get the best of both worlds. If you who reads this is enthusiastic, feel free to explore it.) + +### ...but the user is only exposed to the pointer form + +This is the same story as for the main types: it's covered in +[unexported implementations, exported aliases](./HACKME_memorylayout.md#unexported-implementations-exported-aliases). + +Genenerally, this "shielded" type means you can only have a MaybeT with valid contents, +because no one can ever produce the uninitialized "zero" value of the type. +This means there's no "invalid" state which can kick you in the shins at runtime, +and we generally regard that as a good thing. + +It also just keeps things syntactically simple. +One always refers to "MaybeT"; never with a star. + +### whether or not the maybe's inhabitant type is embedded is based on adjunct config + +Although the maybe type itself is embeddable, its _inhabitant_ may be +either embedded in the maybe type or be a pointer, at your option. + +This is clearest to explain in code: you can have either: + +```go +type MaybeFoo struct { + m schema.Maybe // enum bit for present|absent|null + v Foo // the inhabitant (here, embedded) +} +``` + +or: + +```go +type MaybeFoo struct { + m schema.Maybe // enum bit for present|absent|null + v *Foo // the inhabitant (here, a pointer!) +} +``` + +(Yes, we're talking about a one-character difference in the code.) + +Which of these two forms is generated can be selected by adjunct config. +("Adjunct" config just means: it's not part of the schema; it's part of the +config for this codegen tool.) + +There are advantages to each: + +- the embedded form is ([as usual](./HACKME_memorylayout.md#embed-by-default)), faster for workloads where the value is usually present (it provokes fewer allocations). +- the pointer form may use less memory when the value is absent; it works for cyclic structures; and if assigning a whole subtree at once, it allows faster assignment. + +Also, for cyclic structures, such as `type Foo {String:nullable Foo}`, or `type Bar struct{ recurse optional Bar }`, the pointer form is *required*. +(Otherwise... how big of a slab of memory would we be allocating? Infinite? Nope; compile error.) + +By default, we generate the pointer form. +However, your application may experience significant performance improvements by selectively using the embed form. +Check it out and tune for what's right for your application. + +(FUTURE: we should make more clever defaults: it's reasonable to default to embed form for any type that is of scalar kind.) + + + +implementation detail notes +--------------------------- + +### how state machines and maybes work + +Assemblers for recursive stuff have state machines that are used to insure +orderly transitions between each key and value assembly, +and that a complete entry has been assembled before the next entry or the finish. +(For example, you can't go key-then-key in a map, +nor start a value and then start another value before finishing the first one in a list, +nor finish a map when you've just inserted a key and no value, and so forth.) + +One part of this is straightforward: we simply implement state machines, +using bog-standard patterns around a typed uint and logical transition guards +in all the relevant functions. Done and done. Except... + +How do child assemblers signal to their parent that they've become finished? +Theoretically, easy; in practice, to work efficiently... +This poses a bit of an implementation challenge. + +One obvious solution is to put a callback field in assemblers, and have +the parent assembler supply the child assembler with a callback that can +update the parent's state machine when the child becomes finished. +This is logically correct, but practically, problematic and Not Fast: +it requires generating a closure of some kind which composes the function +pointer with the pointer to that parent assembler: and since this is two words +of memory, it implies an allocation and (unfortunately) a heap escape. +An allocation per child key and value in a recursive structure is unacceptable; +we want to set a _much_ higher bar for performance here. + +So, we move on to less obvious solutions: we're all in the same package here, +so we can twiddle the bits of our neighboring structures quite directly, yes? +What if we just have assemblers contain pointers to a state machine uint, +and they do a fixed-value compare-and-swap when they're done? +This is terrifyingly direct and has no abstractions, yes indeed: but +we do generally assume control all the code in this package for any of our +correctness constraints, so this is in-bounds (if admittedly uncomfortable). + +Now let's combine that with one more concern: nullables. When an assembler +is not at the root of a document, it may need to accept null values. +We could do this by generating distinct assembler types for use in positions +where nulls are allowed; but though such an approach would work, it is bulky. +We'd much rather be able to reuse assembler types in either scenario. + +So, let's have assemblers contain two pointers: +the already-familiar 'w' pointer, and also an 'm' pointer. +The 'm' pointer effectively communicates up whether the child has become finished +when it becomes either 'Maybe_Null' or 'Maybe_Value'. + +We add a few new states to the 'm' value, and use it to hint in both directions: +assemblers will assume nulls are not an acceptable transition *unless* the 'm' +value comes initialized with a hint that we are in a situation where they work. + +The costs here are "some": it's another pointer indirection and memory set. +However, compared to the alternatives, it's pretty good: versus an allocation +(in the callback approach), this is a huge win; and we're even pretty safe to +bet that that pointer indirection is going to land in a cache line already hot. + +You can find the additional magic consts crammed into `schema.Maybe` fields +for this statekeeping during assembly defined in the "minima" file in codegen output. +They are named `midvalue` and `allowNull`. + + + +this could have been different +------------------------------ + +There are many ways this design could've been different: + +### we could have every maybe type implement Node + +As already discussed above, it would cause a lot of extra boilerplate methods, +increasing both the generated code source size and binary size; +but on the plus side, it would've been in some ways arguably more consistent. + +We didn't. + +### we could've generated three maybes per type + +Already discussed above. + +We didn't. + +### we could've designed schemas differently + +A lot of the twists of the design originate from the fact that both `optional` +and `nullable` are both rather special as well as very contextual in IPLD Schemas +(e.g., `optional` is only permitted in a very few special places in a schema). +If we had built a very different type system, maybe things would come out differently. + +Some of this has some exploration in some gists: + +- https://gist.github.com/warpfork/9dd8b68deff2b90f96167c900ea31eec#dubious-soln-drop-nullable-completely-make-inline-anonymous-union-syntax-instead +- https://gist.github.com/warpfork/9dd8b68deff2b90f96167c900ea31eec#soln-change-how-schemas-regard-nullable-and-optional +- https://gist.github.com/warpfork/9dd8b68deff2b90f96167c900ea31eec#soln-support-absent-as-a-discriminator-in-kinded-unions + +But suffice to say, that's a very big topic. + +Optionals and nullables are the way they are because they seemed like useful +concepts for describing the structure of data which has serial forms; +how they map onto any particular programming language (such as Go) was a secondary concern. +This design for a golang library is trying to do its best within that. + +### we could've done X with techinque Y + +Probably, yes :) + +This is just one implementation of codegen for Golang for IPLD Schemas. +Competing implementations that make different choices are absolutely welcome :) + + + diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_memorylayout.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_memorylayout.md new file mode 100644 index 00000000000..5f6894c0de9 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_memorylayout.md @@ -0,0 +1,437 @@ +about memory layout +=================== + +Memory layout is important when designing a system for going fast. +It also shows up in exported types (whether or not they're pointers, etc). + +For the most part, we try to hide these details; +or, failing that, at least make them appear consistent. +There's some deeper logic required to *pick* which way we do things, though. + +This document was written to describe codegen and all of the tradeoffs here, +but much of it (particularly the details about embedding and internal pointers) +also strongly informed the design of the core NodeAssembler semantics, +and thus also may be useful reading to understand some of the forces that +shaped even the various un-typed node implementations. + + + +Prerequisite understandings +--------------------------- + +The following headings contain brief summaries of information that's important +to know in order to understand how we designed the IPLD data structure +memory layouts (and how to tune them). + +Most of these concepts are common to many programming languages, so you can +likely skim those sections if you know them. Others are fairly golang-specific. + +### heap vs stack + +The concept of heap vs stack in Golang is pretty similar to the concept +in most other languages with garbage collection, so we won't cover it +in great detail here. + +The key concept to know: the *count* of allocations which are made on +the heap significantly affects performance. Allocations on the heap +consume CPU time both when made, and later, as part of GC. + +The *size* of the allocations affects the total memory needed, but +does *not* significantly affect the speed of execution. + +Allocations which are made on the stack are (familiarly) effectively free. + +### escape analysis + +"Escape Analysis" refers to the efforts the compiler makes to figure out if some +piece of memory can be kept on the stack or if it must "escape" to the heap. +If escape analysis finds that some memory can be kept on the stack, +it will prefer to do so (and this is faster/preferable because it both means +allocation is simple and that no 'garbage' is generated to collect later). + +Since whether things are allocated on the stack or the heap affects performance, +the concept of escape analysis is important. The details (fortunately) are not: +For the purposes of what we need to do in in our IPLD data structures, +our goal with our code is to A) flunk out and escape to heap +as soon as possible, but B) do that in one big chunk of memory at once +(because we'll be able to use [internal pointers](#internal-pointers) +thereafter). + +One implication of escape analysis that's both useful and easy to note is that +whether or not you use a struct literal (`Foo{}`) or a pointer (`&Foo{}`) +*does not determine* whether that memory gets allocated on the heap or stack. +If you use a pointer, the escape analysis can still prove that the pointer +never escapes, it will still end up allocated on the stack. + +Another way to thing about this is: use pointers freely! By using pointers, +you're in effect giving the compiler *more* freedom to decide where memory resides; +in contrast, avoiding the use of pointers in method signitures, etc, will +give the compiler *less* choice about where the memory should reside, +and typically forces copying. Giving the compiler more freedom generally +has better results. + +**pro-tip**: you can compile a program with the arguments `-gcflags "-m -m"` to +get lots of information about the escape analysis the compiler performs. + +### embed vs pointer + +Structs can be embeded -- e.g. `type Foo struct { field Otherstruct }` -- +or referenced by a pointer -- e.g. `type Foo struct { field *Otherstruct }`. + +The difference is substantial. + +When structs are embedded, the layout in memory of the larger struct is simply +a concatenation of the embedded structs. This means the amount of memory +that structure takes is the sum of the size of all of the embedded things; +and by the other side of the same coint, the *count* of allocations needed +(remember! the *count* affects performance more than the *size*, as we briefly +discussed in the [heap-vs-stack](#heap-vs-stack) section) is exactly *one*. + +When pointers are used instead of embedding, the parent struct is typically +smaller (pointers are one word of memory, whereas the embedded thing can often +be larger), and null values can be used... but if fields are assigned to some +other value than null, there's a very high likelihood that heap allocations +will start cropping up in the process of creating values to take pointers +to before then assigning the pointer field! (This can be subverted by +either [escape analysis](#escape-analysis) (though it's fairly uncommon), +or by [internal pointers](#internal-pointers) (which are going to turn out +very important, and will be discussed later)... but it's wise to default +to worrying about it until you can prove that one of the two will save you.) + +When setting fields, another difference appears: a pointer field takes one +instruction (assuming the value already exists, and we're not invoking heap +allocation to get the pointer!) to assign, +whereas an embedded field generally signifies a memcopy, which +may take several instructions if the embedded value is large. + +You can see how the choice between use of pointers and embeds results +in significantly different memory usage and performance characteristics! + +(Quick mention in passing: "cache lines", etc, are also potential concerns that +can be addressed by embedding choices. However, it's probably wise to attend +to GC first. While cache alignment *can* be important, it's almost always going +to be a winning bet that GC will be a much higher impact concern.) + +It is an unfortunate truth that whether or not a field can be null in Golang +and whether or not it's a pointer are two properties that are conflated -- +you can't choose one independently of the other. (The reasoning for this is +based on intuitions around mechanical sympathy -- but it's worth mentioning that +a sufficiently smart compiler *could* address both the logical separation +and simultaneously have the compiler solve for the mechanical sympathy concerns +in order to reach good performance in many cases; Golang just doesn't do so.) + +### interfaces are two words and may cause implicit allocation + +Interfaces in Golang are always two words in size. The first word is a pointer +to the type information for what the interface contains. The second word is +a pointer to the data itself. + +This means if some data is assigned into an interface value, it *must* become +a pointer -- the compiler will do this implicitly; and this is the case even if +the type info in the first word retains a claim that the data is not a pointer. +In practice, this also almost guarantees in practice that the data in question +will escape to the heap. + +(This applies even to primitives that are one word in size! At least, as of +golang version 1.13 -- keep an eye on on the `runtime.convT32` functions +if you want to look into this further; the `mallocgc` call is clear to see. +There's a special case inside `malloc` which causes zero values to get a +free pass (!), but in all other cases, allocation will occur.) + +Knowing this, you probably can conclude a general rule of thumb: if your +application is going to put a value in an interface, and *especially* if it's +going to do that more than once, you're probably best off explicitly handling +it as a pointer rather than a value. Any other approach wil be very likely to +provoke unnecessary copy behavior and/or multiple unnecessary heap allocations +as the value moves in and out of pointer form. + +(Fun note: if attempting to probe this by microbenchmarking experiments, be +careful to avoid using zero values! Zero values get special treatment and avoid +allocations in ways that aren't general.) + +### internal pointers + +"Internal pointers" refer to any pointer taken to some position in a piece +of memory that was already allocated somewhere. + +For example, given some `type Foo struct { a, b, c Otherstruct }`, the +value of `f := &Foo{}` and `b := &f.b` will be very related: they will +differ by the size of `Otherstruct`! + +The main consequence of this is: using internal pointers can allow you to +construct large structure containing many pointers... *without* using a +correspondingly large *count of allocations*. This unlocks a lot of potential +choices for how to build data structures in memory while minimizing allocs! + +Internal pointers are not without their tradeoffs, however: in particular, +internal pointers have an interesting relationship with garbage collection. +When there's an internal pointer to some field in a large struct, that pointer +will cause the *entire* containing struct to be still considered to be +referenced for garbage collection purposes -- that is, *it won't be collected*. +So, in our example above, keeping a reference to `&f.b` will in fact cause +memory of the size of *three* `Otherstruct`s to be uncollectable, not one. + +You can find more information about internal pointers in this talk: +https://blog.golang.org/ismmkeynote + +### inlining functions + +Function inlining is an important compiler optimization. + +Inlining optimizes in two regards: one, can remove some of the overhead of +function calls; and two, it can enable *other* optimizations by getting the +relevant instruction blocks to be located together and thus rearrangable. +(Inlining does increase the compiled binary size, so it's not all upside.) + +Calling a function has some fixed overhead -- shuffling arguments from registers +into calling convention order on the stack; potentially growing the stack; etc. +While these overheads are small in practice... if the function is called many +(many) times, this overhead can still add up. Inlining can remove these costs! + +More interestingly, function inlining can also enable *other* optimizations. +For example, a function that *would* have caused escape analysis to flunk +something out to the heap *if* that function as called was alone... can +potentially be inlined in such a way that in its contextual usage, +the escape analysis flunking can actually disappear entirely. +Many other kinds of optimizations can similarly be enabled by inlining. +This makes designing library code to be inline-friendly a potentially +high-impact concern -- sometimes even more so than can be easily seen. + +The exact mechanisms used by the compiler to determine what can (and should) +be inlined may vary significantly from version to version of the Go compiler, +which means one should be cautious of spending too much time in the details. +However, we *can* make useful choices around things that will predictably +obstruct inlining -- such as [virtual function calls](#virtual-function-calls). +Occasionally there are positive stories in teasing the inliner to do well, +such as https://blog.filippo.io/efficient-go-apis-with-the-inliner/ (but these +seem to generally require a lot of thought and probably aren't the first stop +on most optimization quests). + +### virtual function calls + +Function calls which are intermediated by interfaces are called "virtual" +function calls. (You may also encounter the term "v-table" in compiler +and runtime design literature -- this 'v' stands for "virtual".) + +Virtual function calls generally can't be inlined. This can have significant +effects, as described in the [inlining functions](#inlining-functions) section -- +it both means function call overhead can't be removed, and it can have cascading +consequences by making other potential optimizations unreachable. + + + +Resultant Design Features +------------------------- + +### concrete implementations + +We generate a concrete type for each type in the schema. + +Using a concrete type means methods on it are possible to inline. +This is important to us because most of the methods are "accessors" -- that is, +a style of function that has a small body and does little work -- and these +are precisely the sort of function where inlining can add up. + +### natively-typed methods in addition to the general interface + +We generate two sets of methods: **both** the general interface methods to +comply with Node and NodeBuilder interfaces, **and** also natively-typed +variants of the same methods (e.g. a `Lookup` method for maps that takes +the concrete type key and returns the concrete type value, rather than +taking and returning `Node` interfaces). + +While both sets of methods can accomplish the same end goals, both are needed. +There are two distinct advantages to natively-typed methods; +and at the same time, the need for the general methods is system critical. + +Firstly, to programmers writing code that can use the concrete types, the +natively-typed methods provide more value in the form of compile-time type +checking, autocompletion and other tooling assist opportunities, and +less verbosity. + +Secondly, natively-typed funtions on concrete types can be higher performance: +since they're not [virtual function calls](#virtual-function-calls), we +can expect [inlining](#inlining-functions) to work. We might expect this to +be particularly consequential in builders and in accessor methods, since these +involve numerous calls to methods with small bodies -- precisely the sort of +situation that often substantially benefits from inlining. + +At the same time, it goes without saying that we need the general Node and +NodeBuilder interfaces to be satisfied, so that we can write generic library +code such as reusable traversals, etc. It is not possible to satisfy both +needs with a single set of methods with the Golang typesystem; therefore, +we generate both. + +### embed by default + +Embedded structs amortizes the count of memory allocations. +This addresses what is typically our biggest concern. + +The increase in size is generally not consequential. We expect most fields +end up filled anyway, so reserving that memory up front is reasonable. +(Indeed, unfilled fields are only possible for nullable or optional fields +which are implemented as embedded.) + +If assigning whole sub-trees at once, assignment into embedded fields +incurs the cost of a memcopy (whereas by contrast, if fields were pointers, +assigning them would be cheap... it's just that we would've had to pay +a (possibly _extra_) allocation cost elsewhere earlier.) +However, this is usually a worthy trade. +Linear memcpy in practice can be significantly cheaper than extra allocations +(especially if it's one long memcpy vs many allocations); +and if we assume a balance of use cases such as "unmarshal happens more often +than sub-tree-assignment", then it's pretty clear we should prioritize getting +allocation minimization for unmarshal rather than fret sub-tree assignment. + +### nodebuilders point to the concrete type + +We generate NodeBuilder types which contain a pointer to the type they build. + +This means we can hold onto the Node pointer when its building is completed, +and discard the NodeBuilder. (Or, reset and reuse the NodeBuilder.) +Garbage collection can apply on the NodeBuilder independently of the lifespan +of the Node it built. + +This means a single NodeBuilder and its produced Node will require +**two** allocations -- one for the NodeBuilder, and a separate one for the Node. + +(An alternative would be to embed the concrete Node value in the NodeBuilder, +and return a pointer to when finalizing the creation of the Node; +however, because due to the garbage collection semantics around +[internal pointers](#internal-pointers), such a design would cause the entirety +of the memory needed in the NodeBuilder to remain uncollectable as long as +completed Node is reachable! This would be an unfortunate trade.) + +While we pay two allocations for the Node and its Builder, we earn that back +in spades via our approach to recursion with +[NodeAssemblers](#nodeassemblers-accumulate-mutations), and specifically, how +[NodeAssemblers embed more NodeAssemblers](#nodeassemblers-embed-nodeassemblers). +Long story short: we pay two allocations, yes. But it's *fixed* at two, +no matter how large and complex the structure is. + +### nodeassemblers accumulate mutations + +The NodeBuilder type is only used at the root of construction of a value. +After that, recursion works with an interface called NodeAssembler isntead. + +A NodeAssembler is essentially the same thing as a NodeBuilder, except +_it doesn't return a Node_. + +This means we can use the NodeAssembler interface to describe constructing +the data in the middle of some complex value, and we're not burdened by the +need to be able to return the finished product. (Sufficient state-keeping +and defensive checks to ensure we don't leak mutable references would not +come for free; reducing the number of points we might need to do this makes +it possible to create a more efficient system overall.) + +The documentation on the datamodel.NodeAssembler type gives some general +description of this. + +NodeBuilder types end up being just a NodeAssembler embed, plus a few methods +for exposing the final results and optionally resetting the whole system. + +### nodeassemblers embed nodeassemblers + +In addition to each NodeAssembler containing a pointer to the value they modify +(the same as [NodeBuilders](#nodebuilders-point-to-the-concrete-type))... +for assemblers that work with recursive structures, they also embed another +NodeAssembler for each of their child values. + +This lets us amortize the allocations for all the *assemblers* in the same way +as embedding in the actual value structs let us amortized allocations there. + +The code for this gets a little complex, and the result also carries several +additional limitations to the usage, but it does keep the allocations finite, +and thus makes the overall performance fast. + +(To be more specific, for recursive types that are infinite (namely, maps and +lists; whereas structs and unions are finite), the NodeAssembler embeds +*one* NodeAssembler for all values. (Obviously, we can't embed an infinite +number of them, right?) This leads to a restriction: you can't assemble +multiple children of an infinite recursive value simultaneously.) + +### nullable and optional struct fields embed too + +TODO intro + +There is some chance of over-allocation in the event of nullable or optional +fields. We support tuning that via adjunct configuration to the code generator +which allows you to opt in to using pointers for fields; choosing to do this +will of course cause you to lose out on alloc amortization features in exchange. + +TODO also resolve the loops note, at bottom + +### unexported implementations, exported aliases + +Our concrete types are unexported. For those that need to be exported, +we export an alias to the pointer type. + +This has an interesting set of effects: + +- copy-by-value from outside the package becomes impossible; +- creating zero values from outside the package becomes impossible; +- and yet refering to the type for type assertions remains possible. + +This addresses one downside to using [concrete implementations](#concrete-implementations): +if the concrete implementation is an exported symbol, it means any code external +to the package can produce Golang's natural "zero" for the type. +This is problematic because it's true even if the Golang "zero" value for the +type doesn't correspond to a valid value. +While keeping an unexported implementation and an exported interface makes +external fabrication of zero values impossible, it breaks inlining. +Exporting an alias of the pointer type, however, strikes both goals at once: +external fabrication of zero values is blocked, and yet inlining works. + + + +Amusing Details and Edge Cases +------------------------------ + +### looped references + +// who's job is it to detect this? +// the schema validator should check it... +// but something that breaks the cycle *there* doesn't necessarily do so for the emitted code! aggh! +// ... unless we go back to optional and nullable both making ptrs unconditionally. + + + +Learning more (the hard way) +---------------------------- + +If this document doesn't provide enough information for you, +you've probably graduated to the point where doing experiments is next. :) + +Prototypes and research examples can be found in the +`go-ipld-prime/_rsrch/` directories. +In particular, the "multihoisting" and "nodeassembler" packages are relevant, +containing research that lead to the drafting of this doc, +as well as some partially-worked alternative interface drafts. +(You may have to search back through git history to find these directories; +they're removed after some time, when the lessons have been applied.) + +Tests there include some benchmarks (self-explanitory); +some tests based on runtime memory stats inspection; +and some tests which are simply meant to be disassembled and read thusly. + +Compiler flags can provide useful insights: + +- `-gcflags '-S'` -- gives you assembler dump. + - read this to see for sure what's inlined and not. + - easy to quickly skim for calls like `runtime.newObject`, etc. + - often critically useful to ensure a benchmark hasn't optimized out the question you meant to ask it! + - generally gives a ground truth which puts an end to guessing. +- `-gcflags '-m -m'` -- reports escape analysis and other decisions. + - note the two m's -- not a typo: this gives you info in stack form, + which is radically more informative than the single-m output. +- `-gcflags '-l'` -- disables inlining! + - useful on benchmarks to quickly detect whether inlining is a major part of performance. + +These flags can apply to any command like `go install`... as well as `go test`. + +Profiling information collected from live systems in use is of course always +intensely useful... if you have any on hand. When handling this, be aware of +how data-dependent performance can be when handling serialization systems: +different workload content can very much lead to different hot spots. + +Happy hunting. diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_scalars.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_scalars.md new file mode 100644 index 00000000000..20629a17abc --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_scalars.md @@ -0,0 +1,226 @@ +What's the deal with scalars, anyway? +===================================== + +Two sorts of scalars +-------------------- + +There are two sorts of scalars that show up in codegen: + +- 1: scalars that are just the plain kind (e.g. "string", not even named); +- 2: scalars that have named types. + +Plain scalars can't have any special rules or semantics attached to them. + +Named types with scalar kinds (aka a "typedef") **can** have additional rules and semantics attached to them. + +Let's talk about named scalars first, because it's clearer that there's fun there. + + +### named scalars + +Named scalars cause a type to be generated. +That type information is part of their identity (practically speaking: affects their definition of equality). + +#### named scalars are never equal even if their contents are + +It stands to reason that named scalars can't be freely interchanged. + +If you have a schema: + +```ipldsch +type Foo string +type Bar string +``` + +... then you'll get codegen output code with an exported type for each: + +```go +type Foo struct{ x string } +/*...*/ + +type Bar struct{ x string } +/*...*/ +``` + +... and clearly, `(Foo{"asdf"} == Bar{"asdf"}) == false`. + +#### named scalars appear in specialized method argument types and return types + +Just like any other named type, named scalars will appear in specialized methods +which are exported on codegen'd types. + +For example, if you have a schema: + +```ipldsch +type Foo string +type Bar string +type Foomp map {Foo:Bar} +``` + +... then you'll get codegen output code which includes a method on Foomp: + +```go +func (x *Foomp) LookupByNode(k *Foo) (*Bar) { /*...*/ } +``` + +Such specialized methods are often much shorter, much more efficient to execute, +and involve much less error handling to use than their more generalized +counterparts on the `datamodel.Node` interface. + +Note that when named scalars appear in the signitures of specialized methods, +they always appear as pointers. They will never be `nil`, but there is still +a reason that pointers are used here, and it's based on performance. +(The details don't matter as a user, but: it means if those values need to be +regarded as the `datamodel.Node` interface again in the future, that boxing is +inexpensive since we already have a (heap-escaped long ago) pointer. +By contrast, copying by value in more places is likely to result in more +heap escapes and thus additional undesirable new allocation costs in the +(entirely common!) case that the values end up handled as `datamodel.Node` later.) + +#### named scalars have a specialized method which unboxes them to a native primitive unconditionally + +Every named scalar type as a specialized unbox method corresponding to its kind. + +For example, for a `type Foo string`, there will be a `func (f Foo) String() string` method +(in addition to the `func (f Foo) AsString() (string, error)` method, +which does the same thing but is stuck presenting an error due to interface conformance even though we know that it's statically impossible). + +#### named scalars can have additional methods attached to them + +It's possible for users of codegen to attach additional methods to the types +generated for a named scalar. + +This can be either done for purely aesthetic/ergonomic purposes particular +to the user's exact product, or, as part of some extended library features. +For example, we plan support extended features like "validation" methods +via detecting when a user adds a `Valdiate() error` method to a generated type. + + +### plain scalars + +Plain scalars also cause a type to be generated; +one type for each kind in the Data Model is sufficient. + +Plain scalars show up in codegen output packages almost exactly as if +there was a short preamble in every schema: + +```ipldsch +type Int int +type Bool bool +type Float float +type String string +type Bytes bytes +``` + +#### note about schema syntax + +There's an issue about capitalization that's somewhat unresolved in schemas: +namely, is `type Fwee struct { someField string }` allowed, or a parse error? + +This syntax is questionable because it means some of the scalar kind identifier +keywords are allowed in the same place as type names, +and it's potentially confusing because when we come to interacting with the +generated output code in golang, we still have `String`-with-a-capital-S +as a type identifier. + +At any rate, it seems clear that you can mentally capitalize the 's' +at any time you see this debatable syntax. + +(We should resolve this issue in the specs, which are in the `datamodel.specs` repo.) + +#### plain scalars appear in specialized method argument types and return types + +This is the same story as for named scalars. + +For example, if you have a schema: + +```ipldsch +type Foomp map {String:String} +``` + +... then you'll get codegen output code which includes a method on Foomp: + +```go +func (x *Foomp) LookupByNode(k String) (String) { /*...*/ } +``` + +(The exact symbols involved and whether or not they're pointers may vary.) + +The type might carry less semantic information than it does when a +named scalar shows up in the same position, but we still use a generated +type (and a pointer) here for two reasons: first of all, and more simply, +consistency; but secondly, for the same performance reasons as applied +to named scalars (if we need to treat this value as an `datamodel.Node` again +in the future, it's much better if we already have a heap pointer rather +than a bare primitive value (`runtime.convT*` functions are often not your +favorite thing to see in a pprof flamegraph)). + +(FUTURE: this is still worth review. We might actually want to use +bare primitives in a lot of these cases, because surely, if you're about +to want to treat something as an `datamodel.Node` again, then you can use the +generalized methods conforming to `datamodel.Node` which already yield that...? +We'll get more information and impressions about this after trying to use +codegen in bulk (especially the specialized methods).) + +#### plain scalars do not allow additional method attachedments + +While we can't *stop* developers from modifying the source code emitted by codegen, +adding a method to any of the plain scalars is intensely discouraged. +Nothing sensible or good can come of trying to attach a "Validate" method +to something like the `String` type. Don't do it. + + +Code reuse for plain scalars +---------------------------- + +We *always* need some type that can contain a plain scalar while also +implementing all the `datamodel.Node` methods. Even if we didn't export it +or show it in any method signitures anywhere at all, we'd *still* need it +for internal implementation of other types, because it's important those +types be able to return a pointer to their fields in their implements of +the `datamodel.Node` contract (otherwise, they'd be terribly slow and alloc-heavy). + +### can we reuse another package's plain scalars? + +Since there's no functional difference between the plain scalars in a schema +and the scalars implementation from another package that's untyped in the first place, +can we reuse some code from an untyped package in codegen output packages? + +No. + +(Or: "maybe, conditionally, and it would have a lot of caveats and make the +untyped package we try to hitch a ride on become significantly weirder, so... +it's probably not worth it".) + +The reason to desire this so there's less (admittedly quite duplicative) code +in the package emitted by using codegen. + +However, there are *many* "cons" which outweight that single "pro": + +- This would require the untyped package to export their concrete implementation types. + - This is the *only* reason those implementation types would need to be exported, which is a concerning smell all by itself. + - In the case of we consider using the 'basicnode' package in particular: + - Exporting those types allows creation by casting, which exposes an API surface that's not conventional (nor necessarily even possible) for other packages, and will thus be likely to create confusion as well as create multiple ways of doing things which will make refactors harder. + - We don't like allowing casting for creating values in general for reasons explored well in the go-cid refactors to use wrapper structs: if casting is possible, it's far too easy for an end-user to write shoddy code which dodges all constructors and validation logic. + - Exporting those types allows unboxing by casting, which again exposes an API surface that's not conventional (nor necessarily even possible) for other packages, and will thus be likely to create confusion as well as create multiple ways of doing things which will make refactors harder. + - Since we're talking about scalars and they're essentially copy-by-value (except for bytes -- but we give up and rely on "lawful" code for those anyway, since defensive copies are completely nonviable in performance terms), this doesn't create incorrectness issues... but it's still not *good*. + - Note that while casting to concrete types exported by the output package of codegen is considered acceptable, this is a different beast: you still can't get the raw content out without using at least one more unboxing method; and, if you're casting or doing a type switch with type in a codegen package, it should already instantly be clear that your code is no longer general-purpose, and this will surprise no one. + - ...And while the above two are true only because the implmentation is by typedefs and they could be fixed by using a wrapper struct... that fix would have exactly the effect of making reuse impossible anyway, since the field in that wrapper struct would need to be unexported (otherwise, immutability would then in turn trivially shatter). + - The implementation of the scalar for link kinds can't be reused anyway (it *does* use a wrapper struct already, and needs to; type aliases on an interface don't permit adding methods), adding yet more inconsistency and jagged edges to the picture. + - The "more unnecessarily(-for-end-user-perspectives) exported symbols" code smell counts about 10x as hard for this package in particular, since it's often one of the first ones a newcomer to this library will see: there shouldn't be weird designs with elaborate and far away justifications poking up here. +- Reusing concrete types between packages makes it more likely uncautious users could write code that uses native equality on scalars and get away with it *sometimes*. Since this is still incorrect and would sometimes fail in fully general code, it's better if code like this flunks out as early as possible, which results in a better ecosystem overall. +- We like it when error messages can include a type name. It's marginally better for that to be something like "gendemo.String" ('gendemo' being consistent with whatever the rest of the package also says) than just bare "string". + +There are also a few bits that aren't entirely known (at least, at the time of this writing): +namely, how 'any' types are going to be handled in codegen. +Probably, though, the answer is: it's just treated as 'datamodel.Node', +and the codegen package doesn't export *any* more types which regard this situation because that's already sufficient. + +Long story short? It's better to have plain scalar types in codegen output, +even if they look somewhat duplicative, +because trying to do anything fancier either fails outright +or spawns ridiculously detailed epicycles of complexity. +Emitting the plain scalar types in codegen output +is *more consistent* in almost every way, +will generate less cognitive load for users, +and just plain *works unconditionally*. diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_templates.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_templates.md new file mode 100644 index 00000000000..3471f1fb22f --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_templates.md @@ -0,0 +1,119 @@ +Notes about how Templates are used in this package +================================================== + +This package makes heavy use of go's `text/template`. + +Some of it is not pretty. But beware of trying to trade elegance for legibility. + +An overview of the choices that got us here: + +### string templating is fine + +String templating for code is fine, actually. + +An alternative would be to use the golang AST packages. +While those are nice... for our purposes, they're a bit verbose. +It's not necessarily helpful to have the visual distance between our +generation code and the actual result _increase_ (at least, without a good reason). + +### don't make indirections around uncomplicated munges + +Don't make indirections that aren't needed for simple string operations. +(This goes for both the template funcmap, or in the form of reusable templates.) + +One very common situation is that for some type `T`, there's a related thing to be generated +called `T__Foo`, where "Foo" is some kind of modifier that is completely predictable +and not user-selected nor configurable. + +In this situation: simply conjoining `{{ .T }}__Foo` as string in the template is fine! +Don't turn it into a shell game with functions that make the reader jump around more to see what's happening. +(Even when refactoring, it's easy enough to use simple string replace on these patterns; +extracting a function to enable "changing it in one place" doesn't really add much value.) + +If there's something more complicated going on, or it's user-configurable? +Fine, get more functions involved. But be judicious about it. + +(An earlier draft of the code introduced a new method for each modifier form in the example above. +The result was... just repeating the modifiers in the function name in the template! +It produced more code, yet no additional flexibility. +It is advisable to resist making this mistake again ;)) + +### maintain distinction between **symbol** versus **name** + +- **symbol** is what is used in type and function names in code. +- **name** is the string that comes from the schema; it is never modified nor overridable. + +Symbols can change based on adjunct config. +(In theory, they could also be munged to avoid collisions with language constructs +or favor certain library conventions... however, this is currently not automatic.) + +Names can't change. They're _exactly_ what was written in in the Schema. + +Types and functions and most of the _code_ part of codegen use Symbols. +Error messages, reflectable type information, etc, use Names. + +Symbols may also need to be _generated_ for types that don't have names. +For example, `type Foo struct { field {String:Int} }` might result in codegen +creating *two* symbols: `Foo`, and `Map__String__Int`. + +One way to check that the goal is being satisfied is to consider that +someone just experiencing error messages from a program should not end up exposed to any information about: + +- what language the program is written in, +- or which codegen tool was used (or even *if* a codegen tool was used), +- or what adjunct config was present when codegen was performed. + +(n.b. this consideration does not include errors with stack traces -- then +of course you will unavoidably see symbols appear.) + +### anything that is configurable goes through adjunctCfg; adjunctCfg is accessed via the template funcmap + +For example, all Symbol processing all pipes through an adjunct configuration object. +We make this available in the templates via a funcmap so it's available context-free as a nice tidy pipe syntax. + +### there are several kinds of reuse + +(Oh, boy.) + +It may be wise to read the ["values we can balance"](./HACKME_tradeoffs.md#values-we-can-balance) document before continuing. +There's also a _seventh_ tradeoff to consider, in addition to those from that document: +how much reuse there is in our _template_ code, and (_eighth!_) how _readable_ and maintainable the template code is. +Also, (_ninth!!_) how _fast_ the template code is. + +We've generally favored *all* of the priorities for the output code (speed, size, allocation count, etc) over the niceness of the codegen. +We've also _completely_ disregarded speed of the template code (it's always going to be "fast enough"; you don't run this in a hot loop!). +When there's a tension between readability and reuse, we've often favored readability. +That means sometimes text is outright duplicated, if it seemed like extracting it would make it harder to read the template. + +Here's what we've ended up with: + +- There are mixins from the `node/mixins` package, which save some amount of code and standardize some behaviors. + - These end up in the final result code. + - It doesn't save *much* code, and they generally don't save *any* binary size (because it all gets inlined). + - The consistency is the main virtue of these. + - These are used mainly for error handling (specifically, returning of errors for methods called on nodes that have the wrong kind for that method). +- There are mixins from the `schema/gen/go/mixins` package. + - These are in the template code only -- they don't show up in the final result code. + - These attempt to make it easier to create new 'generator' types. (There's a 'generator' type for each kind-plus-representation.) + - They only attempt to take away some boilerplate, and you don't _have_ to use them. +- There are functions in the template funcmap. + - ... not many of them, though. +- There's the idea of using associated templates (templates that are invoked by other templates). + - There's currently none of this in use. Might it be helpful? Maybe. +- There are functions which apply well-known templates to a generator. + - These compose at the golang level, so it's easy to have the compiler check that they're all in order without running them (unlike templates, which have to be exercised in order to detect even basic problems like "does this named template exist"). + - Many of these assume some pattern of methods on the generator objects. (Not of all these are super well documented.) + - Generators usually call out to one or more of these from within the methods that their interface requires them to have. +- The generator types themselves are usually split into two parts: the mechanisms for type-plus-repr, and just mechanisms for the type. + - The mechanisms for the type alone aren't actually a full generator. The type-plus-repr thing just embeds the type-level semantics in itself. + +*Mostly*, it's general aim has been to keep relatively close to the structure of the code being generated. +When reading a generator, one generally has to do *zero* or *one* jump-to-definition in order to see the fulltext of a template -- no more than that. +(And so far, all those jump-to-definition lookups are on _go code_, not inside the template -- so an IDE can help you.) + +By example: if there are things which turn out common between _representation kinds_, +those will probably end up in a function containing a well-known template, +and that will end up being called from the generator type in one of the functions its required to have per its interface contract. + +This all probably has plenty of room for improvement! +But know you know the reasoning that got things to be in the shape they are. diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_testing.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_testing.md new file mode 100644 index 00000000000..6e971ccba6d --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_testing.md @@ -0,0 +1,91 @@ +Testing Generated Code +====================== + +Getting nice testing scenarios for generated code is tricky. + +There are three major phases of testing we can do: + +1. unit tests on the codegen tooling itself +2. tests that the emitted generated code can compile +3. behavioral tests on the emitted generated code + +Groups 1 and 2 are pretty easy (and we don't have a lot of group 1, +because group 2 covers it pretty nicely). + +Group 3, however, is tricky. +The rest of the document will talk more about this kind of testing. + + +Behavioral Tests +---------------- + +### Behavioral tests are run via plugins + +This package does some fancy footwork with the golang `plugin` system +and `go build -buildmode=plugin` in order to compile and load the +generated code into the same memory as the test process, +thereby letting us do behavioral tests on the gen'd code quite seamlessly. + +This does have some downsides -- namely, the `plugin` system requires +the use of `cgo`. This means you'll need more things installed on your +host system than just the go toolchain -- you might need `gcc` and friends too. +The `plugin` system also (at time of writing) doesn't support windows. +You can skip the behavioral tests if this is a problem: see the next section. + +### Skipping the behavioral tests + +You can skip behavioral tests by adding a build tag of `"skipgenbehavtests"`. +They'll also be automatically skipped if you're running in `"!cgo"` mode -- +however, the `go` tools don't automatically set `"!cgo"` just because it +doesn't have enough tools, so you'll still need to be explicit about this. + +The ability of the generated code to be compiled will still be checked, +even if the behavioral tests are skipped. + +You can grep through your test output for "bhvtest=skip" to see at-a-glance +if the behavioral tests are being skipped. + +### Plugins don't jive with race detection + +Long story short: if running tests with the race detector, skip the gen tests. +Any `go test -race` is going to need `go test -race -tags 'skipgenbehavtests'`. + +The go plugin system requires the plugin and host process have the same "runtime". +The way '-race' works makes for an effectively distinct runtime. + +### Alternatives to plugins + +Are there other ways this could be done? Well, surely. There always are. + +Invoking 'go test' as a subprocess is usually central to alternative ideas, +but this has several downsides I haven't yet figured out how to counter: + +- it tends to result in very difficult-to-wrangle output; +- it ends up imposing a lot of constraints on file organization, + which in turn makes writing tests into a very high-friction endeavour; +- passing down flags to the test process (e.g., '-v' and friends) + begins to require additional infrastructure; +- some flags such as '-run' are even yet more difficult to pass down usefully; +- every single behavioral test has to have an exported top-level function, + making some things that are trivial with closures now difficult... +- You get the idea. + +You can see some attempts around +commit 79de0e26469f0d2899c813a2c70d921fe5946f23 and its halfdozen or so +parents; remarks can be found in the git commit messages. + +There are probably yet more variations in ways files and functions could +be reorganized, particularly to minimize the downsides of the file and +package splitting requirements, but if you're looking at this scenario and +wanting to propose one... Do read those commits to avoid getting into a +Chesterton's Fence situation, and kindly try it before proposing it. +Not all of the hurdles are immediately obvious. + +### Plugins are only used in testing + +This might not need a clarification statement, but just in case it does: +**plugins** (and by extention, cgo) **are not necessary** +for **doing** codegen nor for **using** the resulting generated code. +They are _only_ used for our testing of the codegen tooling +(and specifically, at that, for the behavioral tests). +We would not foist a dependency like cgo on codegen users. diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_tradeoffs.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_tradeoffs.md new file mode 100644 index 00000000000..0c028db87b4 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_tradeoffs.md @@ -0,0 +1,71 @@ +tradeoffs and design decisions in codegen +========================================= + +In creating codegen for IPLD, as with any piece of software, +there are design decisions to be made, and tradeoffs to be considered. + +Some of these decisions and tradeoffs are particularly interesting +in IPLD codegen because they're: + +- significantly different resolutions and answers than the same decisions for non-codegen Node implementations +- able to make significantly different choices, expanding the decision space dimentionality, since they have more information before compile-time +- can reach higher upper bounds of performance, due to that pre-compile-time foothold +- have correspondingly less flexibility in many ways because of the same. + + +values we can balance +--------------------- + +Let's enumerate the things we can balance (and give them some short reference codes): + +- AS: assembly/binary/final-shipping size, in bytes +- BM: builder memory, in bytes, used as long as a NodeBuilder is in use +- SP: execution speed, in seconds, especially of NodeBuilder in deserialization use +- AC: allocations, in count, needed for operations (though in truth, this is just a proxy for SP due to its outsized impact there) +- ERG: ergonomics, as an ineffable, ellusive-to-measurement sort of vibe of the thing, and how well it self-explains use and deters erroneous application +- GLOC: generated lines of code, as a line count or in bytes, of interest because it may be of noticable cost in version control weight + +This list is in particular regarding concerns that come to light in considering performant deserialization operations... +however, it's fairly representative of general use as well: +traversals and serialization are generally easier situations to handle (they essentially get to skip the "BM" term); +and while different operations might encounter different scalars for how much these different values affect them, +as we'll see in the prioritization coming up in the next section... that turns out not to matter for our priorities. + +We can also other code which knows it's addressing generated code can use special methods, + which means we can in a way disregard its effect on this ordering (mostly). + +Side note: though "AC" is *mostly* just a proxy for SP, +AC can also count on its own in *addition* to SP because it increases the *variance* in SP. +(But we don't often regard this; it's a pretty fine detail, and the goal is "minimize" either way.) + + +prioritization of those values +------------------------------ + +The designs here emerge from `SP > BM > AS`. + +More fully: `SP|AC > BM > ERG > AS > GLOC`. + +In other words: speed is the overwhelming priority; +thereafter, we'd like to conserve memory (but will readily sell it for speed); +ergonomics takes a side seat to both of these (the intention being that we can add 'porcelain' layers separately later); +assembly size is a concern but fourth fiddle (if this is your dominant concern, you may not want to use codegen, or may want a different library implementation that aims at the same specs); +and generated code size is a concern but we'll trade it away for any of the other priorities +(because it's a cost that doesn't end up affecting final users of products built with this system!). + +(Some caveats: it's still possible to consider it a red flag if ratios on these get wild. +For example if BM gets > 2x, it's questionable; +and at some point we could imagine saying that AS has really gotten out of hand.) + +(BM also has some special conditions such that if it increases on recursive kinds, but not on scalars, +we regard that as roughly half price, because generally most of a tree is leaves. +(As it happens, though, this has turned out not to change any results much.)) + +"Ergonomics" remains a tricky to account for. +It's true that when push comes to shove, speed and memory economy win. +But it's not at all single-dimentional; and with codegen, there are many options +which set a higher bar for all three concerns at the same time. +(In contrast, there's a stark upper limit to the ergonomic possbilities for +non-codegen no-schema handling of data -- code handling the data model has +the limits that its monomorphized approach imposes on it, and there's little +that can be done to avoid or improve upon that.) diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_wip.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_wip.md new file mode 100644 index 00000000000..7076479e875 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/HACKME_wip.md @@ -0,0 +1,151 @@ + +### absent values + +The handling of absent values is still not consistent. + +Currently: + +- reading (via accessors or iterators) yields `datamodel.Absent` values for absent fields +- putting those datamodel.Absent values via NodeAssembler.AssignNode will result in `ErrWrongKind`. +- *the recursive copies embedded in AssignNode methods don't handle absents either*. + +The first two are defensible and consistent (if not necessarily ergonomic). +The third is downright a bug, and needs to be fixed. + +How we fix it is not entirely settled. + +- Option 1: keep the hostility to absent assignment +- Option 2: *require* explicit absent assignment +- Option 3: become indifferent to absent assignment when it's valid +- Option 4: don't yield values that are absent during iteration at all + +Option 3 seems the most preferrable (and least user-hostile). +(Options 1 and 2 create work for end users; +Option 4 has questionable logical consistency.) + +Updating the codegen to do Option 3 needs some work, though. + +It's likely that the way to go about this would involve adding two more valid +bit states to the extended schema.Maybe values: one for allowAbsent (similar to +the existing allowNull), and another for both (for "nullable optional" fields). +Every NodeAssembler would then have to support that, just as they each support allowNull now. + +I think the above design is valid, but it's not implemented nor tested yet. + + +### AssignNode optimality + +The AssignNode methods we generate currently do pretty blithe things with large structures: +they iterate over the given node, and hurl entries into the assembler's AssignKey and AssignValue methods. + +This isn't always optimal. +For any structure that is more efficient when fed info in an ideal order, we might want to take account of that. + +For example, unions with representation mode "inline" are a stellar example of this: +if the discriminant key comes first, they can work *much, much* more efficiently. +By contrast, if the discriminant key shows up late in the object, it is necessary to +have buffered *all the other* data, then backtrack to handle it once the discriminant is found and parsed. + +At best, this probably means iterating once, plucking out the discriminant entry, +and then *getting a new iterator* that starts from the beginning (which shifts +the buffer problem to the Node we're consuming data from). + +Even more irritatingly: since NodeAssembler has to accept entries in any order +if it is to accept information streamingly from codecs, the NodeAssembler +*also* has to be ready to do the buffering work... +TODO ouch what are the ValueAssembler going to yield for dealing with children? +TODO we have to hand out dummy ValueAssembler types that buffer... a crazy amount of stuff. (Reinvent refmt.Tok?? argh.) cannot avoid??? +TODO this means where errors arise from will be nuts: you cant say if anything is wrong until you figure out the discriminant. then we replay everything? your errors for deeper stuff will appear... uh... midway, from a random AssembleValue finishing that happens to be for the discriminant. that is not pleasant. + +... let's leave that thought aside: suffice to say, some assemblers are *really* +not happy or performant if they have to accept things in unpleasant orderings. + +So. + +We should flip all this on its head. The AssignNode methods should lean in +on the knowledge they have about the structure they're building, and assume +that the Node we're copying content from supports random access: +pluck the fields that we care most about out first with direct lookups, +and only use iteration to cover the remaining data that the new structure +doesn't care about the ordering of. + +Perhaps this only matters for certain styles of unions. + + +### sidenote about codec interfaces + +Perhaps we should get used to the idea of codec packages offering two styles of methods: + +- `UnmarshalIntoAssembler(io.Reader, datamodel.NodeAssembler) error` + - this is for when you have opinions about what kind of in-memory format should be used +- `Unmarshal(io.Reader) (datamodel.Node, error)` + - this is for when you want to let the codec pick. + +We might actually end up preferring the latter in a fair number of cases. + +Looking at this inline union ordering situation described above: +the best path through that (other than saying "don't fking use inline unions, +and if you do, put the discriminant in the first fking entry or gtfo") would probably be +to do a cbor (or whatever) unmarshal that produces the half-deserialized skip-list nodes +(which are specialized to the cbor format rather than general purpose, but we want that in this story)... +and those can then claim to do random access, thereby letting them take on the "buffering". +This approach would let the serialization-specialized nodes take on the work, +rather than forcing the union's NodeAssembler to do buffer at a higher level... +which is good because doing that buffering in a structured way at a higher level +is actually more work and causes more memory fragmentation and allocations. + +Whew. + +I have not worked out what this implies for multicodecs or other muxes that do compositions of codecs. + + +### enums of union keys + +It's extremely common to have an enum that is the discrimant values of a union. + +We should make a schema syntax for that. + +We tend to generate such an enum in codegen anyway, for various purposes. +Might as well let people name it outright too, if they have the slightest desire to do so. + +(Doesn't apply to kinded unions.) + + +### can reset methods be replaced with duff's device? + +Yes. Well, sort of. Okay, no. + +It's close! Assemblers were all written such that their zero values are ready to go. + +However, there's a couple of situations where you *wouldn't* want to blithely zero everything: +for example, if an assembler has to do some allocations, but they're reusable, +you wouldn't want to turn those other objects into garbage by zeroing the pointer to them. +See the following section about new-alloc child assemblers for an example of this. + + +### what's up with new-alloc child assemblers? + +Mostly, child assemblers are embedded in the assembler for the type that contains them; +this is part of our allocation amortization strategy and important to performance. +However, it doesn't always apply: +Sometimes we *need* independently allocated assemblers, even when they're child assemblers: +recursive structures need this (otherwise, how big would the slab be? infinite? no; halt). +Sometimes we also just *want* them, somewhat more mildly: if a union is one of several things, +and some of them are uncommonly used but huuuuge, then maybe we'd rather allocate the child assemblers +individually on demand rather than pay a large resident memory cost to embed all the possibilities. + +There's a couple things to think about with these: + +- resetting assemblers with a duff's device strategy wouldn't recursively reset these; + it would just orphan them. While possibly leaving them pointed into some parts of memory in the parent slab ('cm' in particular comes to mind). + This could be a significant correctness issue. + - But who's responsibility is it to "safe" this? Nilling 'w' proactively should also make this pretty innocuous, as one option (but we don't currently do this). + +- if the parent assembler is being used in some highly reusable situation (e.g. it's a list value or map value), + is the parent able to hold onto and re-use the child assembler? We probably usually still want to do this, even if it's in a separate piece of heap. + - For unions, there's a question of if we should hold onto each child assembler, or just the most recent; that's a choice we could make and tune. + If the answer is "most recent only", we could even crank down the resident size by use of more interfaces instead of concrete types (at the cost of some other runtime performance debufs, most likely). + +We've chosen to discard the possibility of duff's device as an assembler resetting implementation. +As a result, we don't have to do proactive 'w'-nil'ing in places we might otherwise have to. +And union assemblers hold on to all child assembler types they've ever needed. diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README.md new file mode 100644 index 00000000000..681b476cb5b --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README.md @@ -0,0 +1,121 @@ +gengo +===== + +This package contains a codegenerator for emitting Golang source code +for datastructures based on IPLD Schemas. + +It is reasonably complete. See the [feature table](#completeness) below for details. + +There is a CLI tool which can be used to run this generator. +See https://github.com/ipld/go-ipldtool ! + +Some features may still requiring writing code to fully configure them. +(PRs, here or in the go-ipldtool repo, welcome.) + +See [README_behaviors](README_behaviors.md) for notes about the behaviors of the code output by the generator. + +Check out the [HACKME](HACKME.md) document for more info about the internals, +how they're organized, and how to hack on this package. + + +aims +---- + +`gengo` aims to: + +- generate native Golang code +- that faithfully represents the data structuring specified by an IPLD Schema, +- operating efficiently, both in speed (both creating and inspecting) and memory compactness; +- producing a better type system for Golang (we've got unions and enums!) +- that is both powerful and generic (when you need it) +- and minimalist (when you don't), +- with immutable data structures, +- good validation primitives and type-supported safety systems, +- and is friendly to embellishments of other hand-written Golang code. + +Some of these aims should be satisfied. + +Some are still a stretch ;) (we definitely don't have "minimalist" outputs, yet. +Making this reachable by tuning is a goal, however!) + + +completeness +------------ + +Legend: + +- `✔` - supported! +- `✘` - not currently supported. +- `âš ` - not currently supported -- and might not be obvious; be careful. +- `-` - is not applicable +- `?` - feature definition needed! (applies to many of the "native extras" rows -- often there's partial features, but also room for more.) +- ` ` - table is not finished, please refer to the code and help fix the table :) + +| feature | accessors | builders | +|:---------------------------------|:---------:|:--------:| +| structs | ... | ... | +| ... type level | ✔ | ✔ | +| ... native extras | ? | ? | +| ... map representation | ✔ | ✔ | +| ... ... including optional | ✔ | ✔ | +| ... ... including renames | ✔ | ✔ | +| ... ... including implicits | âš  | âš  | +| ... tuple representation | ✔ | ✔ | +| ... ... including optional | ✔ | ✔ | +| ... ... including renames | - | - | +| ... ... including implicits | âš  | âš  | +| ... stringjoin representation | ✔ | ✔ | +| ... ... including optional | - | - | +| ... ... including renames | - | - | +| ... ... including implicits | - | - | +| ... stringpairs representation | ✘ | ✘ | +| ... ... including optional | | | +| ... ... including renames | | | +| ... ... including implicits | | | +| ... listpairs representation | ✘ | ✘ | +| ... ... including optional | | | +| ... ... including renames | | | +| ... ... including implicits | | | + +| feature | accessors | builders | +|:---------------------------------|:---------:|:--------:| +| lists | ... | ... | +| ... type level | ✔ | ✔ | +| ... native extras | ? | ? | +| ... list representation | ✔ | ✔ | + +| feature | accessors | builders | +|:---------------------------------|:---------:|:--------:| +| maps | ... | ... | +| ... type level | ✔ | ✔ | +| ... native extras | ? | ? | +| ... map representation | ✔ | ✔ | +| ... stringpairs representation | ✘ | ✘ | +| ... listpairs representation | ✘ | ✘ | + +| feature | accessors | builders | +|:---------------------------------|:---------:|:--------:| +| unions | ... | ... | +| ... type level | ✔ | ✔ | +| ... keyed representation | ✔ | ✔ | +| ... envelope representation | ✘ | ✘ | +| ... kinded representation | ✔ | ✔ | +| ... inline representation | ✘ | ✘ | +| ... stringprefix representation | ✔ | ✔ | +| ... byteprefix representation | ✘ | ✘ | + +| feature | accessors | builders | +|:---------------------------------|:---------:|:--------:| +| strings | ✔ | ✔ | +| bytes | ✔ | ✔ | +| ints | ✔ | ✔ | +| floats | ✔ | ✔ | +| bools | ✔ | ✔ | +| links | ✔ | ✔ | + +| feature | accessors | builders | +|:---------------------------------|:---------:|:--------:| +| enums | ... | ... | +| ... type level | ✘ | ✘ | +| ... string representation | ✘ | ✘ | +| ... int representation | ✘ | ✘ | diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README_behaviors.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README_behaviors.md new file mode 100644 index 00000000000..5c6d1c4aa75 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README_behaviors.md @@ -0,0 +1,38 @@ +Behaviors of Generated Types +============================ + +Types generated by `gogen` obey the rules that already exist for the IPLD Data Model, +and the rules that exist for Schema typed nodes. + +There are some further details of behavior that might be worth noting, though. + +Some of these details aren't necessarily programmer-friendly(!), +and arise from prioritizing performance over other concerns; +so especially watch out for these as you develop against the code output by this tool. + +### retaining assemblers beyond their intended lifespan is not guaranteed to be safe + +There is no promise of nice-to-read errors if you over-hold child assemblers beyond their valid lifespan. +`NodeAssembler` values should not be retained for any longer than they're actively in use. + +- We **do** care about making things fail hard and fast rather than potentially leak inappropriate mutability. +- We do **not** care about making these errors pretty (it's high cost to do so, and code that hits this path is almost certainly statically (and hopefully fairly obviously) wrong). + +In some cases it may also be the case that a `NodeAssembler` that populates the internals of some large structure +may become invalid (because of state transitions that block inappropriate mutability), +and yet become possible to use again later (because of coincidences of how we reuse memory internally for efficiency reasons). +We don't reliably raise errors in some of these situations, for efficiency reasons, but wish we could. +Users of the generated code should not rely on these behaviors: +it results in difficult-to-read code in any case, +and such internal details should not be considered part of the intended public API (e.g., such details may be subject to change without notice). + +### absent values + +Iterating a type-level node with optional fields will yield the field key and the `datamodel.Absent` constant as a value. +Getting a such a field will also yield the `datamodel.Absent` constant as a value, and will not return a "not found" error. + +Attempting to *assign* an `datamodel.Absent` value, however -- +via the `NodeAssembler.AssignNode` function (none of the other function signatures permit expressing this) -- +will result in an `datamodel.ErrWrongKind` error. + +// Seealso some unresolved todos in the [HACKME_wip](HACKME_wip.md) document regarding how absent values are handled. diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README_wishes.md b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README_wishes.md new file mode 100644 index 00000000000..6ec8b14a178 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/README_wishes.md @@ -0,0 +1,18 @@ +wishes and dreams of other things that could be +=============================================== + +### minimal gen for regular code + +(In other short words: gen without the monomorphization.) + +It'd be neat to have a mode that generates all public fields (shrugging on immutability), +and can also toggle off generating all the data model Node interface satisfaction methods. +This would let us use IPLD Schemas to define types (including enums and unions) and get Golang code out, +and easily use it in programs even where we don't particularly care about the Node interface. +(E.g., suppose we want an enum or a union type -- which Go doesn't naturally have -- but aren't going to use it +for serialization or anything else. We've already got a lot of codegen here; why not make it help there too?) + +It's unclear if we can load that much into this gen project, or if it'd be easier to make another one for this. +The output code would definitely be substantially structurally different; +and it would also tend to be useless/silly to generate different parts of a type system in each of the different modes, +so it's pretty likely that any practical user story would involve different process invocations to use them anyway. diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/adjunctCfg.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/adjunctCfg.go new file mode 100644 index 00000000000..13adbd0593a --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/adjunctCfg.go @@ -0,0 +1,186 @@ +package gengo + +import ( + "fmt" + "reflect" + "strings" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/basicnode" + "github.com/ipld/go-ipld-prime/schema" +) + +// This entire file is placeholder-quality implementations. +// +// The AdjunctCfg struct should be replaced with an IPLD Schema-specified thing! +// The values in the unionMemlayout field should be an enum; +// etcetera! + +type FieldTuple struct { + TypeName schema.TypeName + FieldName string +} + +type AdjunctCfg struct { + typeSymbolOverrides map[schema.TypeName]string + FieldSymbolLowerOverrides map[FieldTuple]string + fieldSymbolUpperOverrides map[FieldTuple]string + maybeUsesPtr map[schema.TypeName]bool // absent uses a heuristic + CfgUnionMemlayout map[schema.TypeName]string // "embedAll"|"interface"; maybe more options later, unclear for now. + + // ... some of these fields have sprouted messy name prefixes so they don't collide with their matching method names. + // this structure has reached the critical threshhold where it due to be cleaned up and taken seriously. + + // note: PkgName doesn't appear in here, because it's... + // not adjunct data. it's a generation invocation parameter. + // ... this might not hold up in the future though. + // There are unanswered questions about how (also, tbf, *if*) we'll handle generation of multiple packages which use each other's types. +} + +// TypeSymbol returns the symbol for a type; +// by default, it's the same string as its name in the schema, +// but it can be overriden. +// +// This is the base, unembellished symbol. +// It's frequently augmented: +// prefixing an underscore to make it unexported; +// suffixing "__Something" to make the name of a supporting type; +// etc. +// (Most such augmentations are not configurable.) +func (cfg *AdjunctCfg) TypeSymbol(t schema.Type) string { + if x, ok := cfg.typeSymbolOverrides[t.Name()]; ok { + return x + } + return string(t.Name()) // presumed already upper +} + +func (cfg *AdjunctCfg) FieldSymbolLower(f schema.StructField) string { + if x, ok := cfg.FieldSymbolLowerOverrides[FieldTuple{f.Parent().Name(), f.Name()}]; ok { + return x + } + return f.Name() // presumed already lower +} + +func (cfg *AdjunctCfg) FieldSymbolUpper(f schema.StructField) string { + if x, ok := cfg.fieldSymbolUpperOverrides[FieldTuple{f.Type().Name(), f.Name()}]; ok { + return x + } + return strings.Title(f.Name()) //lint:ignore SA1019 cases.Title doesn't work for this +} + +// Comments returns a bool for whether comments should be included in gen output or not. +func (cfg *AdjunctCfg) Comments() bool { + return true // FUTURE: okay, maybe this should be configurable :) +} + +func (cfg *AdjunctCfg) MaybeUsesPtr(t schema.Type) bool { + if x, ok := cfg.maybeUsesPtr[t.Name()]; ok { + return x + } + + // As a simple heuristic, + // check how large the Go representation of this type will be. + // If it weighs little, we estimate that a pointer is not worthwhile, + // as storing the data directly will barely take more memory. + // Plus, the resulting code will be shorter and have fewer branches. + return sizeOfSchemaType(t) > sizeSmallEnoughForInlining +} + +var ( + // The cutoff for "weighs little" is any size up to this number. + // It's hasn't been measured with any benchmarks or stats just yet. + // It's possible that, with those, it might increase in the future. + // Intuitively, any type 4x the size of a pointer is fine to inline. + // Adding a pointer will already add 1x overhead, anyway. + sizeSmallEnoughForInlining = 4 * reflect.TypeOf(new(int)).Size() + + sizeOfTypeKind [128]uintptr +) + +func init() { + // Uncomment for debugging. + // fmt.Fprintf(os.Stderr, "sizeOf(small): %d (4x pointer size)\n", sizeSmallEnoughForInlining) + + // Get the basic node sizes via basicnode. + for _, tk := range []struct { + typeKind schema.TypeKind + prototype datamodel.NodePrototype + }{ + {schema.TypeKind_Bool, basicnode.Prototype.Bool}, + {schema.TypeKind_Int, basicnode.Prototype.Int}, + {schema.TypeKind_Float, basicnode.Prototype.Float}, + {schema.TypeKind_String, basicnode.Prototype.String}, + {schema.TypeKind_Bytes, basicnode.Prototype.Bytes}, + {schema.TypeKind_List, basicnode.Prototype.List}, + {schema.TypeKind_Map, basicnode.Prototype.Map}, + {schema.TypeKind_Link, basicnode.Prototype.Link}, + } { + nb := tk.prototype.NewBuilder() + switch tk.typeKind { + case schema.TypeKind_List: + am, err := nb.BeginList(0) + if err != nil { + panic(err) + } + if err := am.Finish(); err != nil { + panic(err) + } + case schema.TypeKind_Map: + am, err := nb.BeginMap(0) + if err != nil { + panic(err) + } + if err := am.Finish(); err != nil { + panic(err) + } + } + // Note that the Node interface has a pointer underneath, + // so we use Elem to reach the underlying type. + size := reflect.TypeOf(nb.Build()).Elem().Size() + sizeOfTypeKind[tk.typeKind] = size + + // Uncomment for debugging. + // fmt.Fprintf(os.Stderr, "sizeOf(%s): %d\n", tk.typeKind, size) + } +} + +// sizeOfSchemaType returns the size of a schema type, +// relative to the size of a pointer in native Go. +// +// For example, TypeInt and TypeMap returns 1, but TypeList returns 3, as a +// slice in Go has a pointer and two integers for length and capacity. +// Any basic type smaller than a pointer, such as TypeBool, returns 1. +func sizeOfSchemaType(t schema.Type) uintptr { + kind := t.TypeKind() + + // If this TypeKind is represented by the basicnode package, + // we statically know its size and we can return here. + if size := sizeOfTypeKind[kind]; size > 0 { + return size + } + + // TODO: handle typekinds like structs, unions, etc. + // For now, return a large size to fall back to using a pointer. + return 100 * sizeSmallEnoughForInlining +} + +// UnionMemlayout returns a plain string at present; +// there's a case-switch in the templates that processes it. +// We validate that it's a known string when this method is called. +// This should probably be improved in type-safety, +// and validated more aggressively up front when adjcfg is loaded. +func (cfg *AdjunctCfg) UnionMemlayout(t schema.Type) string { + if t.TypeKind() != schema.TypeKind_Union { + panic(fmt.Errorf("%s is not a union", t.Name())) + } + v, ok := cfg.CfgUnionMemlayout[t.Name()] + if !ok { + return "embedAll" + } + switch v { + case "embedAll", "interface": + return v + default: + panic(fmt.Errorf("invalid config: unionMemlayout values must be either \"embedAll\" or \"interface\", not %q", v)) + } +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/externUtil.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/externUtil.go new file mode 100644 index 00000000000..b41b6964c97 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/externUtil.go @@ -0,0 +1,40 @@ +package gengo + +import ( + "go/ast" + "go/parser" + "go/token" + path "path/filepath" + "strings" +) + +// getExternTypes provides a mapping of all types defined in the destination package. +// It is used by generate to not duplicate defined types to allow overriding of types. +func getExternTypes(pth string) (map[string]struct{}, error) { + set := token.NewFileSet() + packs, err := parser.ParseDir(set, pth, nil, 0) + if err != nil { + return nil, err + } + + types := make(map[string]struct{}) + for _, pack := range packs { + for fname, f := range pack.Files { + if strings.HasPrefix(path.Base(fname), "ipldsch_") { + continue + } + for _, d := range f.Decls { + if t, isType := d.(*ast.GenDecl); isType { + if t.Tok == token.TYPE { + for _, s := range t.Specs { + ts := s.(*ast.TypeSpec) + types[ts.Name.Name] = struct{}{} + } + } + } + } + } + } + + return types, nil +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBool.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBool.go new file mode 100644 index 00000000000..0f9530f4a85 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBool.go @@ -0,0 +1,119 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type boolGenerator struct { + AdjCfg *AdjunctCfg + mixins.BoolTraits + PkgName string + Type *schema.TypeBool +} + +func (boolGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g boolGenerator) EmitNativeType(w io.Writer) { + emitNativeType_scalar(w, g.AdjCfg, g) +} +func (g boolGenerator) EmitNativeAccessors(w io.Writer) { + emitNativeAccessors_scalar(w, g.AdjCfg, g) +} +func (g boolGenerator) EmitNativeBuilder(w io.Writer) { + emitNativeBuilder_scalar(w, g.AdjCfg, g) +} + +func (g boolGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g boolGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g boolGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g boolGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g boolGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. +} +func (g boolGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} +func (g boolGenerator) EmitNodeMethodAsBool(w io.Writer) { + emitNodeMethodAsKind_scalar(w, g.AdjCfg, g) +} +func (g boolGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} +func (g boolGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g boolGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return boolBuilderGenerator{ + g.AdjCfg, + mixins.BoolAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type boolBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.BoolAssemblerTraits + PkgName string + Type *schema.TypeBool +} + +func (boolBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g boolBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g boolBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g boolBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + emitNodeAssemblerType_scalar(w, g.AdjCfg, g) +} +func (g boolBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g) +} +func (g boolBuilderGenerator) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + emitNodeAssemblerMethodAssignKind_scalar(w, g.AdjCfg, g) +} +func (g boolBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_scalar(w, g.AdjCfg, g) +} +func (g boolBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // Nothing needed here for bool kinds. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBoolReprBool.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBoolReprBool.go new file mode 100644 index 00000000000..f563292be0c --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBoolReprBool.go @@ -0,0 +1,108 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &boolReprBoolGenerator{} + +func NewBoolReprBoolGenerator(pkgName string, typ *schema.TypeBool, adjCfg *AdjunctCfg) TypeGenerator { + return boolReprBoolGenerator{ + boolGenerator{ + adjCfg, + mixins.BoolTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type boolReprBoolGenerator struct { + boolGenerator +} + +func (g boolReprBoolGenerator) GetRepresentationNodeGen() NodeGenerator { + return boolReprBoolReprGenerator{ + g.AdjCfg, + g.Type, + } +} + +type boolReprBoolReprGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeBool +} + +func (g boolReprBoolReprGenerator) EmitNodeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr = _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} +func (g boolReprBoolReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} +func (boolReprBoolReprGenerator) EmitNodeMethodKind(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodLookupByString(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodLookupByNode(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodLookupByIndex(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodLookupBySegment(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodMapIterator(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodListIterator(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodLength(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodIsAbsent(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodIsNull(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodAsBool(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodAsInt(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodAsFloat(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodAsString(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodAsBytes(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodAsLink(io.Writer) {} +func (boolReprBoolReprGenerator) EmitNodeMethodPrototype(io.Writer) {} +func (g boolReprBoolReprGenerator) EmitNodePrototypeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprPrototype = _{{ .Type | TypeSymbol }}__Prototype + `, w, g.AdjCfg, g) +} +func (g boolReprBoolReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return boolReprBoolReprBuilderGenerator(g) +} + +type boolReprBoolReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeBool +} + +func (boolReprBoolReprBuilderGenerator) EmitNodeBuilderType(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeBuilderMethods(io.Writer) {} +func (g boolReprBoolReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler = _{{ .Type | TypeSymbol }}__Assembler + `, w, g.AdjCfg, g) +} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodAssignBool(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodAssignInt(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodAssignFloat(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodAssignBytes(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodAssignLink(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerMethodPrototype(io.Writer) {} +func (boolReprBoolReprBuilderGenerator) EmitNodeAssemblerOtherBits(io.Writer) {} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBytes.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBytes.go new file mode 100644 index 00000000000..de2d34616ff --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBytes.go @@ -0,0 +1,119 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type bytesGenerator struct { + AdjCfg *AdjunctCfg + mixins.BytesTraits + PkgName string + Type *schema.TypeBytes +} + +func (bytesGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g bytesGenerator) EmitNativeType(w io.Writer) { + emitNativeType_scalar(w, g.AdjCfg, g) +} +func (g bytesGenerator) EmitNativeAccessors(w io.Writer) { + emitNativeAccessors_scalar(w, g.AdjCfg, g) +} +func (g bytesGenerator) EmitNativeBuilder(w io.Writer) { + emitNativeBuilder_scalar(w, g.AdjCfg, g) +} + +func (g bytesGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g bytesGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g bytesGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g bytesGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g bytesGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. +} +func (g bytesGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} +func (g bytesGenerator) EmitNodeMethodAsBytes(w io.Writer) { + emitNodeMethodAsKind_scalar(w, g.AdjCfg, g) +} +func (g bytesGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} +func (g bytesGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g bytesGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return bytesBuilderGenerator{ + g.AdjCfg, + mixins.BytesAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type bytesBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.BytesAssemblerTraits + PkgName string + Type *schema.TypeBytes +} + +func (bytesBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g bytesBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g bytesBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g bytesBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + emitNodeAssemblerType_scalar(w, g.AdjCfg, g) +} +func (g bytesBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g) +} +func (g bytesBuilderGenerator) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + emitNodeAssemblerMethodAssignKind_scalar(w, g.AdjCfg, g) +} +func (g bytesBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_scalar(w, g.AdjCfg, g) +} +func (g bytesBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // Nothing needed here for bytes kinds. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBytesReprBytes.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBytesReprBytes.go new file mode 100644 index 00000000000..9374bb3603b --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genBytesReprBytes.go @@ -0,0 +1,108 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &bytesReprBytesGenerator{} + +func NewBytesReprBytesGenerator(pkgName string, typ *schema.TypeBytes, adjCfg *AdjunctCfg) TypeGenerator { + return bytesReprBytesGenerator{ + bytesGenerator{ + adjCfg, + mixins.BytesTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type bytesReprBytesGenerator struct { + bytesGenerator +} + +func (g bytesReprBytesGenerator) GetRepresentationNodeGen() NodeGenerator { + return bytesReprBytesReprGenerator{ + g.AdjCfg, + g.Type, + } +} + +type bytesReprBytesReprGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeBytes +} + +func (g bytesReprBytesReprGenerator) EmitNodeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr = _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} +func (g bytesReprBytesReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} +func (bytesReprBytesReprGenerator) EmitNodeMethodKind(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodLookupByString(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodLookupByNode(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodLookupByIndex(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodLookupBySegment(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodMapIterator(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodListIterator(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodLength(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodIsAbsent(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodIsNull(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodAsBool(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodAsInt(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodAsFloat(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodAsString(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodAsBytes(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodAsLink(io.Writer) {} +func (bytesReprBytesReprGenerator) EmitNodeMethodPrototype(io.Writer) {} +func (g bytesReprBytesReprGenerator) EmitNodePrototypeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprPrototype = _{{ .Type | TypeSymbol }}__Prototype + `, w, g.AdjCfg, g) +} +func (g bytesReprBytesReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return bytesReprBytesReprBuilderGenerator(g) +} + +type bytesReprBytesReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeBytes +} + +func (bytesReprBytesReprBuilderGenerator) EmitNodeBuilderType(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeBuilderMethods(io.Writer) {} +func (g bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler = _{{ .Type | TypeSymbol }}__Assembler + `, w, g.AdjCfg, g) +} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodAssignBool(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodAssignInt(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodAssignFloat(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodAssignBytes(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodAssignLink(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerMethodPrototype(io.Writer) {} +func (bytesReprBytesReprBuilderGenerator) EmitNodeAssemblerOtherBits(io.Writer) {} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genFloat.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genFloat.go new file mode 100644 index 00000000000..24bc59bbd4e --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genFloat.go @@ -0,0 +1,119 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type float64Generator struct { + AdjCfg *AdjunctCfg + mixins.FloatTraits + PkgName string + Type *schema.TypeFloat +} + +func (float64Generator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g float64Generator) EmitNativeType(w io.Writer) { + emitNativeType_scalar(w, g.AdjCfg, g) +} +func (g float64Generator) EmitNativeAccessors(w io.Writer) { + emitNativeAccessors_scalar(w, g.AdjCfg, g) +} +func (g float64Generator) EmitNativeBuilder(w io.Writer) { + emitNativeBuilder_scalar(w, g.AdjCfg, g) +} + +func (g float64Generator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g float64Generator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g float64Generator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g float64Generator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g float64Generator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. +} +func (g float64Generator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} +func (g float64Generator) EmitNodeMethodAsFloat(w io.Writer) { + emitNodeMethodAsKind_scalar(w, g.AdjCfg, g) +} +func (g float64Generator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} +func (g float64Generator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g float64Generator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return float64BuilderGenerator{ + g.AdjCfg, + mixins.FloatAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type float64BuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.FloatAssemblerTraits + PkgName string + Type *schema.TypeFloat +} + +func (float64BuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g float64BuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g float64BuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g float64BuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + emitNodeAssemblerType_scalar(w, g.AdjCfg, g) +} +func (g float64BuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g) +} +func (g float64BuilderGenerator) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + emitNodeAssemblerMethodAssignKind_scalar(w, g.AdjCfg, g) +} +func (g float64BuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_scalar(w, g.AdjCfg, g) +} +func (g float64BuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // Nothing needed here for float64 kinds. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genFloatReprFloat.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genFloatReprFloat.go new file mode 100644 index 00000000000..be0c918c2bd --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genFloatReprFloat.go @@ -0,0 +1,108 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &float64ReprFloatGenerator{} + +func NewFloatReprFloatGenerator(pkgName string, typ *schema.TypeFloat, adjCfg *AdjunctCfg) TypeGenerator { + return float64ReprFloatGenerator{ + float64Generator{ + adjCfg, + mixins.FloatTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type float64ReprFloatGenerator struct { + float64Generator +} + +func (g float64ReprFloatGenerator) GetRepresentationNodeGen() NodeGenerator { + return float64ReprFloatReprGenerator{ + g.AdjCfg, + g.Type, + } +} + +type float64ReprFloatReprGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeFloat +} + +func (g float64ReprFloatReprGenerator) EmitNodeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr = _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} +func (g float64ReprFloatReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} +func (float64ReprFloatReprGenerator) EmitNodeMethodKind(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodLookupByString(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodLookupByNode(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodLookupByIndex(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodLookupBySegment(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodMapIterator(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodListIterator(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodLength(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodIsAbsent(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodIsNull(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodAsBool(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodAsInt(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodAsFloat(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodAsString(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodAsBytes(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodAsLink(io.Writer) {} +func (float64ReprFloatReprGenerator) EmitNodeMethodPrototype(io.Writer) {} +func (g float64ReprFloatReprGenerator) EmitNodePrototypeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprPrototype = _{{ .Type | TypeSymbol }}__Prototype + `, w, g.AdjCfg, g) +} +func (g float64ReprFloatReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return float64ReprFloatReprBuilderGenerator(g) +} + +type float64ReprFloatReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeFloat +} + +func (float64ReprFloatReprBuilderGenerator) EmitNodeBuilderType(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeBuilderMethods(io.Writer) {} +func (g float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler = _{{ .Type | TypeSymbol }}__Assembler + `, w, g.AdjCfg, g) +} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodAssignBool(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodAssignInt(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodAssignFloat(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodAssignBytes(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodAssignLink(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerMethodPrototype(io.Writer) {} +func (float64ReprFloatReprBuilderGenerator) EmitNodeAssemblerOtherBits(io.Writer) {} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genInt.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genInt.go new file mode 100644 index 00000000000..3f3ad7ae983 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genInt.go @@ -0,0 +1,119 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type intGenerator struct { + AdjCfg *AdjunctCfg + mixins.IntTraits + PkgName string + Type *schema.TypeInt +} + +func (intGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g intGenerator) EmitNativeType(w io.Writer) { + emitNativeType_scalar(w, g.AdjCfg, g) +} +func (g intGenerator) EmitNativeAccessors(w io.Writer) { + emitNativeAccessors_scalar(w, g.AdjCfg, g) +} +func (g intGenerator) EmitNativeBuilder(w io.Writer) { + emitNativeBuilder_scalar(w, g.AdjCfg, g) +} + +func (g intGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g intGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g intGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g intGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g intGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. +} +func (g intGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} +func (g intGenerator) EmitNodeMethodAsInt(w io.Writer) { + emitNodeMethodAsKind_scalar(w, g.AdjCfg, g) +} +func (g intGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} +func (g intGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g intGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return intBuilderGenerator{ + g.AdjCfg, + mixins.IntAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type intBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.IntAssemblerTraits + PkgName string + Type *schema.TypeInt +} + +func (intBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g intBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g intBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g intBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + emitNodeAssemblerType_scalar(w, g.AdjCfg, g) +} +func (g intBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g) +} +func (g intBuilderGenerator) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + emitNodeAssemblerMethodAssignKind_scalar(w, g.AdjCfg, g) +} +func (g intBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_scalar(w, g.AdjCfg, g) +} +func (g intBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // Nothing needed here for int kinds. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genIntReprInt.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genIntReprInt.go new file mode 100644 index 00000000000..5991ad917e8 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genIntReprInt.go @@ -0,0 +1,108 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &intReprIntGenerator{} + +func NewIntReprIntGenerator(pkgName string, typ *schema.TypeInt, adjCfg *AdjunctCfg) TypeGenerator { + return intReprIntGenerator{ + intGenerator{ + adjCfg, + mixins.IntTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type intReprIntGenerator struct { + intGenerator +} + +func (g intReprIntGenerator) GetRepresentationNodeGen() NodeGenerator { + return intReprIntReprGenerator{ + g.AdjCfg, + g.Type, + } +} + +type intReprIntReprGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeInt +} + +func (g intReprIntReprGenerator) EmitNodeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr = _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} +func (g intReprIntReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} +func (intReprIntReprGenerator) EmitNodeMethodKind(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodLookupByString(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodLookupByNode(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodLookupByIndex(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodLookupBySegment(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodMapIterator(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodListIterator(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodLength(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodIsAbsent(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodIsNull(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodAsBool(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodAsInt(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodAsFloat(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodAsString(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodAsBytes(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodAsLink(io.Writer) {} +func (intReprIntReprGenerator) EmitNodeMethodPrototype(io.Writer) {} +func (g intReprIntReprGenerator) EmitNodePrototypeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprPrototype = _{{ .Type | TypeSymbol }}__Prototype + `, w, g.AdjCfg, g) +} +func (g intReprIntReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return intReprIntReprBuilderGenerator(g) +} + +type intReprIntReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeInt +} + +func (intReprIntReprBuilderGenerator) EmitNodeBuilderType(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeBuilderMethods(io.Writer) {} +func (g intReprIntReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler = _{{ .Type | TypeSymbol }}__Assembler + `, w, g.AdjCfg, g) +} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodAssignBool(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodAssignInt(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodAssignFloat(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodAssignBytes(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodAssignLink(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerMethodPrototype(io.Writer) {} +func (intReprIntReprBuilderGenerator) EmitNodeAssemblerOtherBits(io.Writer) {} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genLink.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genLink.go new file mode 100644 index 00000000000..89ea79ae5d7 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genLink.go @@ -0,0 +1,128 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type linkGenerator struct { + AdjCfg *AdjunctCfg + mixins.LinkTraits + PkgName string + Type *schema.TypeLink +} + +func (linkGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g linkGenerator) EmitNativeType(w io.Writer) { + emitNativeType_scalar(w, g.AdjCfg, g) +} +func (g linkGenerator) EmitNativeAccessors(w io.Writer) { + emitNativeAccessors_scalar(w, g.AdjCfg, g) +} +func (g linkGenerator) EmitNativeBuilder(w io.Writer) { + emitNativeBuilder_scalar(w, g.AdjCfg, g) +} + +func (g linkGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g linkGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g linkGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) + + // Bonus feature for some links (conforms to the schema.TypedLinkNode interface): + if g.Type.HasReferencedType() { + doTemplate(` + func ({{ .Type | TypeSymbol }}) LinkTargetNodePrototype() datamodel.NodePrototype { + return Type.{{ .Type.ReferencedType | TypeSymbol }}__Repr + } + `, w, g.AdjCfg, g) + } +} + +func (g linkGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g linkGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. +} +func (g linkGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} +func (g linkGenerator) EmitNodeMethodAsLink(w io.Writer) { + emitNodeMethodAsKind_scalar(w, g.AdjCfg, g) +} +func (g linkGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} +func (g linkGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g linkGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return linkBuilderGenerator{ + g.AdjCfg, + mixins.LinkAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type linkBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.LinkAssemblerTraits + PkgName string + Type *schema.TypeLink +} + +func (linkBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g linkBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g linkBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g linkBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + emitNodeAssemblerType_scalar(w, g.AdjCfg, g) +} +func (g linkBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g) +} +func (g linkBuilderGenerator) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + emitNodeAssemblerMethodAssignKind_scalar(w, g.AdjCfg, g) +} +func (g linkBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_scalar(w, g.AdjCfg, g) +} +func (g linkBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // Nothing needed here for link kinds. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genLinkReprLink.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genLinkReprLink.go new file mode 100644 index 00000000000..23647c97b93 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genLinkReprLink.go @@ -0,0 +1,108 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &linkReprLinkGenerator{} + +func NewLinkReprLinkGenerator(pkgName string, typ *schema.TypeLink, adjCfg *AdjunctCfg) TypeGenerator { + return linkReprLinkGenerator{ + linkGenerator{ + adjCfg, + mixins.LinkTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type linkReprLinkGenerator struct { + linkGenerator +} + +func (g linkReprLinkGenerator) GetRepresentationNodeGen() NodeGenerator { + return linkReprLinkReprGenerator{ + g.AdjCfg, + g.Type, + } +} + +type linkReprLinkReprGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeLink +} + +func (g linkReprLinkReprGenerator) EmitNodeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr = _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} +func (g linkReprLinkReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} +func (linkReprLinkReprGenerator) EmitNodeMethodKind(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodLookupByString(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodLookupByNode(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodLookupByIndex(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodLookupBySegment(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodMapIterator(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodListIterator(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodLength(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodIsAbsent(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodIsNull(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodAsBool(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodAsInt(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodAsFloat(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodAsString(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodAsBytes(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodAsLink(io.Writer) {} +func (linkReprLinkReprGenerator) EmitNodeMethodPrototype(io.Writer) {} +func (g linkReprLinkReprGenerator) EmitNodePrototypeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprPrototype = _{{ .Type | TypeSymbol }}__Prototype + `, w, g.AdjCfg, g) +} +func (g linkReprLinkReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return linkReprLinkReprBuilderGenerator(g) +} + +type linkReprLinkReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeLink +} + +func (linkReprLinkReprBuilderGenerator) EmitNodeBuilderType(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeBuilderMethods(io.Writer) {} +func (g linkReprLinkReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler = _{{ .Type | TypeSymbol }}__Assembler + `, w, g.AdjCfg, g) +} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodAssignBool(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodAssignInt(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodAssignFloat(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodAssignBytes(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodAssignLink(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerMethodPrototype(io.Writer) {} +func (linkReprLinkReprBuilderGenerator) EmitNodeAssemblerOtherBits(io.Writer) {} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genList.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genList.go new file mode 100644 index 00000000000..390a80c9740 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genList.go @@ -0,0 +1,297 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type listGenerator struct { + AdjCfg *AdjunctCfg + mixins.ListTraits + PkgName string + Type *schema.TypeList +} + +func (listGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g listGenerator) EmitNativeType(w io.Writer) { + // Lists are a pretty straightforward struct enclosing a slice. + doTemplate(` + {{- if Comments -}} + // {{ .Type | TypeSymbol }} matches the IPLD Schema type "{{ .Type.Name }}". It has {{ .Kind }} kind. + {{- end}} + type {{ .Type | TypeSymbol }} = *_{{ .Type | TypeSymbol }} + type _{{ .Type | TypeSymbol }} struct { + x []_{{ .Type.ValueType | TypeSymbol }}{{if .Type.ValueIsNullable }}__Maybe{{end}} + } + `, w, g.AdjCfg, g) +} + +func (g listGenerator) EmitNativeAccessors(w io.Writer) { + // Generate a speciated Lookup as well as LookupMaybe method. + // The Lookup method returns nil in case of *either* an out-of-range/absent value or a null value, + // and so should only be used if the list type doesn't allow nullable keys or if the caller doesn't care about the difference. + // The LookupMaybe method returns a MaybeT type for the list value, + // and is needed if the list allows nullable values and the caller wishes to distinguish between null and out-of-range/absent. + // (The Lookup method should be preferred for lists that have non-nullable keys, because LookupMaybe may incur additional costs; + // boxing something into a maybe when it wasn't already stored that way costs an alloc(!), + // and may additionally incur a memcpy if the maybe for the value type doesn't use pointers internally). + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}) Lookup(idx int64) {{ .Type.ValueType | TypeSymbol }} { + if n.Length() <= idx { + return nil + } + v := &n.x[idx] + {{- if .Type.ValueIsNullable }} + if v.m == schema.Maybe_Null { + return nil + } + return {{ if not (MaybeUsesPtr .Type.ValueType) }}&{{end}}v.v + {{- else}} + return v + {{- end}} + } + func (n *_{{ .Type | TypeSymbol }}) LookupMaybe(idx int64) Maybe{{ .Type.ValueType | TypeSymbol }} { + if n.Length() <= idx { + return nil + } + v := &n.x[idx] + {{- if .Type.ValueIsNullable }} + return v + {{- else}} + return &_{{ .Type.ValueType | TypeSymbol }}__Maybe{ + m: schema.Maybe_Value, + v: {{ if not (MaybeUsesPtr .Type.ValueType) }}*{{end}}v, + } + {{- end}} + } + + var _{{ .Type | TypeSymbol }}__valueAbsent = _{{ .Type.ValueType | TypeSymbol }}__Maybe{m:schema.Maybe_Absent} + `, w, g.AdjCfg, g) + + // Generate a speciated iterator. + // The main advantage of this over the general datamodel.ListIterator is of course keeping types visible (and concrete, to the compiler's eyes in optimizations, too). + // It also elides the error return from the iterator's Next method. (Overreads will result in -1 as an index and nil values; this is both easily avoidable, and unambiguous if you do goof and hit it.) + doTemplate(` + func (n {{ .Type | TypeSymbol }}) Iterator() *{{ .Type | TypeSymbol }}__Itr { + return &{{ .Type | TypeSymbol }}__Itr{n, 0} + } + + type {{ .Type | TypeSymbol }}__Itr struct { + n {{ .Type | TypeSymbol }} + idx int + } + + func (itr *{{ .Type | TypeSymbol }}__Itr) Next() (idx int64, v {{if .Type.ValueIsNullable }}Maybe{{end}}{{ .Type.ValueType | TypeSymbol }}) { + if itr.idx >= len(itr.n.x) { + return -1, nil + } + idx = int64(itr.idx) + v = &itr.n.x[itr.idx] + itr.idx++ + return + } + func (itr *{{ .Type | TypeSymbol }}__Itr) Done() bool { + return itr.idx >= len(itr.n.x) + } + + `, w, g.AdjCfg, g) +} + +func (g listGenerator) EmitNativeBuilder(w io.Writer) { + // FUTURE: come back to this -- not yet clear what exactly might be most worth emitting here. +} + +func (g listGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g listGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g listGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g listGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g listGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. +} + +func (g listGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} + +func (g listGenerator) EmitNodeMethodLookupByIndex(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) LookupByIndex(idx int64) (datamodel.Node, error) { + if n.Length() <= idx { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfInt(idx)} + } + v := &n.x[idx] + {{- if .Type.ValueIsNullable }} + if v.m == schema.Maybe_Null { + return datamodel.Null, nil + } + return {{ if not (MaybeUsesPtr .Type.ValueType) }}&{{end}}v.v, nil + {{- else}} + return v, nil + {{- end}} + } + `, w, g.AdjCfg, g) +} + +func (g listGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + // LookupByNode will procede by coercing to int64 if it can; or fail; those are really the only options. + // REVIEW: how much coercion is done by other types varies quite wildly. so we should figure out if that inconsistency is acceptable, and at least document it if so. + doTemplate(` + func (n {{ .Type | TypeSymbol }}) LookupByNode(k datamodel.Node) (datamodel.Node, error) { + idx, err := k.AsInt() + if err != nil { + return nil, err + } + return n.LookupByIndex(idx) + } + `, w, g.AdjCfg, g) +} + +func (g listGenerator) EmitNodeMethodListIterator(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) ListIterator() datamodel.ListIterator { + return &_{{ .Type | TypeSymbol }}__ListItr{n, 0} + } + + type _{{ .Type | TypeSymbol }}__ListItr struct { + n {{ .Type | TypeSymbol }} + idx int + } + + func (itr *_{{ .Type | TypeSymbol }}__ListItr) Next() (idx int64, v datamodel.Node, _ error) { + if itr.idx >= len(itr.n.x) { + return -1, nil, datamodel.ErrIteratorOverread{} + } + idx = int64(itr.idx) + x := &itr.n.x[itr.idx] + {{- if .Type.ValueIsNullable }} + switch x.m { + case schema.Maybe_Null: + v = datamodel.Null + case schema.Maybe_Value: + v = {{ if not (MaybeUsesPtr .Type.ValueType) }}&{{end}}x.v + } + {{- else}} + v = x + {{- end}} + itr.idx++ + return + } + func (itr *_{{ .Type | TypeSymbol }}__ListItr) Done() bool { + return itr.idx >= len(itr.n.x) + } + + `, w, g.AdjCfg, g) +} + +func (g listGenerator) EmitNodeMethodLength(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) Length() int64 { + return int64(len(n.x)) + } + `, w, g.AdjCfg, g) +} + +func (g listGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g listGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g listGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return listBuilderGenerator{ + g.AdjCfg, + mixins.ListAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type listBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.ListAssemblerTraits + PkgName string + Type *schema.TypeList +} + +func (listBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g listBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g listBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g listBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // - 'w' is the "**w**ip" pointer. + // - 'm' is the **m**aybe which communicates our completeness to the parent if we're a child assembler. + // - 'state' is what it says on the tin. this is used for the list state (the broad transitions between null, start-list, and finish are handled by 'm' for consistency with other types). + // + // - 'cm' is **c**hild **m**aybe and is used for the completion message from children. + // It's only present if list values *aren't* allowed to be nullable, since otherwise they have their own per-value maybe slot we can use. + // - 'va' is the embedded child value assembler. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Assembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state laState + + {{ if not .Type.ValueIsNullable }}cm schema.Maybe{{end}} + va _{{ .Type.ValueType | TypeSymbol }}__Assembler + } + + func (na *_{{ .Type | TypeSymbol }}__Assembler) reset() { + na.state = laState_initial + na.va.reset() + } + `, w, g.AdjCfg, g) +} +func (g listBuilderGenerator) EmitNodeAssemblerMethodBeginList(w io.Writer) { + emitNodeAssemblerMethodBeginList_listoid(w, g.AdjCfg, g) +} +func (g listBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g listBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_listoid(w, g.AdjCfg, g) +} +func (g listBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + emitNodeAssemblerHelper_listoid_tidyHelper(w, g.AdjCfg, g) + emitNodeAssemblerHelper_listoid_listAssemblerMethods(w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genListReprList.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genListReprList.go new file mode 100644 index 00000000000..d17a7e7f3bc --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genListReprList.go @@ -0,0 +1,206 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &listReprListGenerator{} + +func NewListReprListGenerator(pkgName string, typ *schema.TypeList, adjCfg *AdjunctCfg) TypeGenerator { + return listReprListGenerator{ + listGenerator{ + adjCfg, + mixins.ListTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type listReprListGenerator struct { + listGenerator +} + +func (g listReprListGenerator) GetRepresentationNodeGen() NodeGenerator { + return listReprListReprGenerator{ + g.AdjCfg, + mixins.ListTraits{ + PkgName: g.PkgName, + TypeName: string(g.Type.Name()) + ".Repr", + TypeSymbol: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type listReprListReprGenerator struct { + AdjCfg *AdjunctCfg + mixins.ListTraits + PkgName string + Type *schema.TypeList +} + +func (listReprListReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g listReprListReprGenerator) EmitNodeType(w io.Writer) { + // Even though this is a "natural" representation... we need a new type here, + // because lists are recursive, and so all our functions that access + // children need to remember to return the representation node of those child values. + // It's still structurally the same, though (and we'll be able to cast in the methodset pattern). + // Error-thunking methods also have a different string in their error, so those are unique even if they don't seem particularly interesting. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} + +func (g listReprListReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} + +func (g listReprListReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + // Null is also already a branch in the method we're calling; hopefully the compiler inlines and sees this and DTRT. + // REVIEW: these unchecked casts are definitely safe at compile time, but I'm not sure if the compiler considers that provable, + // so we should investigate if there's any runtime checks injected here that waste time. If so: write this with more gsloc to avoid :( + doTemplate(` + func (nr *_{{ .Type | TypeSymbol }}__Repr) LookupByNode(k datamodel.Node) (datamodel.Node, error) { + v, err := ({{ .Type | TypeSymbol }})(nr).LookupByNode(k) + if err != nil || v == datamodel.Null { + return v, err + } + return v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil + } + `, w, g.AdjCfg, g) + +} + +func (g listReprListReprGenerator) EmitNodeMethodLookupByIndex(w io.Writer) { + doTemplate(` + func (nr *_{{ .Type | TypeSymbol }}__Repr) LookupByIndex(idx int64) (datamodel.Node, error) { + v, err := ({{ .Type | TypeSymbol }})(nr).LookupByIndex(idx) + if err != nil || v == datamodel.Null { + return v, err + } + return v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil + } + `, w, g.AdjCfg, g) +} + +func (g listReprListReprGenerator) EmitNodeMethodListIterator(w io.Writer) { + // FUTURE: trying to get this to share the preallocated memory if we get iterators wedged into their node slab will be ... fun. + doTemplate(` + func (nr *_{{ .Type | TypeSymbol }}__Repr) ListIterator() datamodel.ListIterator { + return &_{{ .Type | TypeSymbol }}__ReprListItr{({{ .Type | TypeSymbol }})(nr), 0} + } + + type _{{ .Type | TypeSymbol }}__ReprListItr _{{ .Type | TypeSymbol }}__ListItr + + func (itr *_{{ .Type | TypeSymbol }}__ReprListItr) Next() (idx int64, v datamodel.Node, err error) { + idx, v, err = (*_{{ .Type | TypeSymbol }}__ListItr)(itr).Next() + if err != nil || v == datamodel.Null { + return + } + return idx, v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil + } + func (itr *_{{ .Type | TypeSymbol }}__ReprListItr) Done() bool { + return (*_{{ .Type | TypeSymbol }}__ListItr)(itr).Done() + } + + `, w, g.AdjCfg, g) +} + +func (g listReprListReprGenerator) EmitNodeMethodLength(w io.Writer) { + doTemplate(` + func (rn *_{{ .Type | TypeSymbol }}__Repr) Length() int64 { + return int64(len(rn.x)) + } + `, w, g.AdjCfg, g) +} + +func (g listReprListReprGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g listReprListReprGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g listReprListReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return listReprListReprBuilderGenerator{ + g.AdjCfg, + mixins.ListAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type listReprListReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.ListAssemblerTraits + PkgName string + Type *schema.TypeList +} + +func (listReprListReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g listReprListReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g listReprListReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g listReprListReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // - 'w' is the "**w**ip" pointer. + // - 'm' is the **m**aybe which communicates our completeness to the parent if we're a child assembler. + // - 'state' is what it says on the tin. this is used for the list state (the broad transitions between null, start-list, and finish are handled by 'm' for consistency with other types). + // + // - 'cm' is **c**hild **m**aybe and is used for the completion message from children. + // It's only present if list values *aren't* allowed to be nullable, since otherwise they have their own per-value maybe slot we can use. + // - 'va' is the embedded child value assembler. + // + // Note that this textually similar to the type-level assembler, but because it embeds the repr assembler for the child types, + // it might be *significantly* different in size and memory layout in that trailing part of the struct. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state laState + + {{ if not .Type.ValueIsNullable }}cm schema.Maybe{{end}} + va _{{ .Type.ValueType | TypeSymbol }}__ReprAssembler + } + + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() { + na.state = laState_initial + na.va.reset() + } + `, w, g.AdjCfg, g) +} +func (g listReprListReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(w io.Writer) { + emitNodeAssemblerMethodBeginList_listoid(w, g.AdjCfg, g) +} +func (g listReprListReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g listReprListReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_listoid(w, g.AdjCfg, g) +} +func (g listReprListReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + emitNodeAssemblerHelper_listoid_tidyHelper(w, g.AdjCfg, g) + emitNodeAssemblerHelper_listoid_listAssemblerMethods(w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genMap.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genMap.go new file mode 100644 index 00000000000..6dc496ec15a --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genMap.go @@ -0,0 +1,349 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type mapGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapTraits + PkgName string + Type *schema.TypeMap +} + +func (mapGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g mapGenerator) EmitNativeType(w io.Writer) { + // Maps do double bookkeeping. + // - 'm' is used for quick lookup. + // - 't' is used for both for order maintainence, and for allocation amortization for both keys and values. + // Note that the key in 'm' is *not* a pointer. + // The value in 'm' is a pointer into 't' (except when it's a maybe; maybes are already pointers). + doTemplate(` + {{- if Comments -}} + // {{ .Type | TypeSymbol }} matches the IPLD Schema type "{{ .Type.Name }}". It has {{ .Kind }} kind. + {{- end}} + type {{ .Type | TypeSymbol }} = *_{{ .Type | TypeSymbol }} + type _{{ .Type | TypeSymbol }} struct { + m map[_{{ .Type.KeyType | TypeSymbol }}]{{if .Type.ValueIsNullable }}Maybe{{else}}*_{{end}}{{ .Type.ValueType | TypeSymbol }} + t []_{{ .Type | TypeSymbol }}__entry + } + `, w, g.AdjCfg, g) + // - address of 'k' is used when we return keys as nodes, such as in iterators. + // Having these in the 't' slice above amortizes moving all of them to heap at once, + // which makes iterators that have to return them as an interface much (much) lower cost -- no 'runtime.conv*' pain. + // - address of 'v' is used in map values, to return, and of course also in iterators. + doTemplate(` + type _{{ .Type | TypeSymbol }}__entry struct { + k _{{ .Type.KeyType | TypeSymbol }} + v _{{ .Type.ValueType | TypeSymbol }}{{if .Type.ValueIsNullable }}__Maybe{{end}} + } + `, w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitNativeAccessors(w io.Writer) { + // Generate a speciated Lookup as well as LookupMaybe method. + // The Lookup method returns nil in case of *either* an absent value or a null value, + // and so should only be used if the map type doesn't allow nullable keys or if the caller doesn't care about the difference. + // The LookupMaybe method returns a MaybeT type for the map value, + // and is needed if the map allows nullable values and the caller wishes to distinguish between null and absent. + // (The Lookup method should be preferred for maps that have non-nullable keys, because LookupMaybe may incur additional costs; + // boxing something into a maybe when it wasn't already stored that way costs an alloc(!), + // and may additionally incur a memcpy if the maybe for the value type doesn't use pointers internally). + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}) Lookup(k {{ .Type.KeyType | TypeSymbol }}) {{ .Type.ValueType | TypeSymbol }} { + v, exists := n.m[*k] + if !exists { + return nil + } + {{- if .Type.ValueIsNullable }} + if v.m == schema.Maybe_Null { + return nil + } + return {{ if not (MaybeUsesPtr .Type.ValueType) }}&{{end}}v.v + {{- else}} + return v + {{- end}} + } + func (n *_{{ .Type | TypeSymbol }}) LookupMaybe(k {{ .Type.KeyType | TypeSymbol }}) Maybe{{ .Type.ValueType | TypeSymbol }} { + v, exists := n.m[*k] + if !exists { + return &_{{ .Type | TypeSymbol }}__valueAbsent + } + {{- if .Type.ValueIsNullable }} + return v + {{- else}} + return &_{{ .Type.ValueType | TypeSymbol }}__Maybe{ + m: schema.Maybe_Value, + v: {{ if not (MaybeUsesPtr .Type.ValueType) }}*{{end}}v, + } + {{- end}} + } + + var _{{ .Type | TypeSymbol }}__valueAbsent = _{{ .Type.ValueType | TypeSymbol }}__Maybe{m:schema.Maybe_Absent} + `, w, g.AdjCfg, g) + + // Generate a speciated iterator. + // The main advantage of this over the general datamodel.MapIterator is of course keeping types visible (and concrete, to the compiler's eyes in optimizations, too). + // It also elides the error return from the iterator's Next method. (Overreads will result in nil keys; this is both easily avoidable, and unambiguous if you do goof and hit it.) + doTemplate(` + func (n {{ .Type | TypeSymbol }}) Iterator() *{{ .Type | TypeSymbol }}__Itr { + return &{{ .Type | TypeSymbol }}__Itr{n, 0} + } + + type {{ .Type | TypeSymbol }}__Itr struct { + n {{ .Type | TypeSymbol }} + idx int + } + + func (itr *{{ .Type | TypeSymbol }}__Itr) Next() (k {{ .Type.KeyType | TypeSymbol }}, v {{if .Type.ValueIsNullable }}Maybe{{end}}{{ .Type.ValueType | TypeSymbol }}) { + if itr.idx >= len(itr.n.t) { + return nil, nil + } + x := &itr.n.t[itr.idx] + k = &x.k + v = &x.v + itr.idx++ + return + } + func (itr *{{ .Type | TypeSymbol }}__Itr) Done() bool { + return itr.idx >= len(itr.n.t) + } + + `, w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitNativeBuilder(w io.Writer) { + // Not yet clear what exactly might be most worth emitting here. +} + +func (g mapGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g mapGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g mapGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g mapGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. +} + +func (g mapGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitNodeMethodLookupByString(w io.Writer) { + // What should be coercible in which directions (and how surprising that is) is an interesting question. + // Most of the answer comes from considering what needs to be possible when working with PathSegment: + // we *must* be able to accept a string in a PathSegment and be able to use it to navigate a map -- even if the map has complex keys. + // For that to work out, it means if the key type doesn't have a string type kind, we must be willing to reach into its representation and use the fromString there. + // If the key type *does* have a string kind at the type level, we'll use that; no need to consider going through the representation. + doTemplate(` + func (n {{ .Type | TypeSymbol }}) LookupByString(k string) (datamodel.Node, error) { + var k2 _{{ .Type.KeyType | TypeSymbol }} + {{- if eq .Type.KeyType.TypeKind.String "String" }} + if err := (_{{ .Type.KeyType | TypeSymbol }}__Prototype{}).fromString(&k2, k); err != nil { + return nil, err // TODO wrap in some kind of ErrInvalidKey + } + {{- else}} + if err := (_{{ .Type.KeyType | TypeSymbol }}__ReprPrototype{}).fromString(&k2, k); err != nil { + return nil, err // TODO wrap in some kind of ErrInvalidKey + } + {{- end}} + v, exists := n.m[k2] + if !exists { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(k)} + } + {{- if .Type.ValueIsNullable }} + if v.m == schema.Maybe_Null { + return datamodel.Null, nil + } + return {{ if not (MaybeUsesPtr .Type.ValueType) }}&{{end}}v.v, nil + {{- else}} + return v, nil + {{- end}} + } + `, w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + // LookupByNode will procede by cast if it can; or simply error if that doesn't work. + // There's no attempt to turn the node (or its repr) into a string and then reify that into a key; + // if you used a Node here, you should've meant it. + // REVIEW: by comparison structs will coerce anything stringish silently...! so we should figure out if that inconsistency is acceptable, and at least document it if so. + doTemplate(` + func (n {{ .Type | TypeSymbol }}) LookupByNode(k datamodel.Node) (datamodel.Node, error) { + k2, ok := k.({{ .Type.KeyType | TypeSymbol }}) + if !ok { + panic("todo invalid key type error") + // 'schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}", Key:&_String{k}}' doesn't quite cut it: need room to explain the type, and it's not guaranteed k can be turned into a string at all + } + v, exists := n.m[*k2] + if !exists { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(k2.String())} + } + {{- if .Type.ValueIsNullable }} + if v.m == schema.Maybe_Null { + return datamodel.Null, nil + } + return {{ if not (MaybeUsesPtr .Type.ValueType) }}&{{end}}v.v, nil + {{- else}} + return v, nil + {{- end}} + } + `, w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitNodeMethodMapIterator(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) MapIterator() datamodel.MapIterator { + return &_{{ .Type | TypeSymbol }}__MapItr{n, 0} + } + + type _{{ .Type | TypeSymbol }}__MapItr struct { + n {{ .Type | TypeSymbol }} + idx int + } + + func (itr *_{{ .Type | TypeSymbol }}__MapItr) Next() (k datamodel.Node, v datamodel.Node, _ error) { + if itr.idx >= len(itr.n.t) { + return nil, nil, datamodel.ErrIteratorOverread{} + } + x := &itr.n.t[itr.idx] + k = &x.k + {{- if .Type.ValueIsNullable }} + switch x.v.m { + case schema.Maybe_Null: + v = datamodel.Null + case schema.Maybe_Value: + v = {{ if not (MaybeUsesPtr .Type.ValueType) }}&{{end}}x.v.v + } + {{- else}} + v = &x.v + {{- end}} + itr.idx++ + return + } + func (itr *_{{ .Type | TypeSymbol }}__MapItr) Done() bool { + return itr.idx >= len(itr.n.t) + } + + `, w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitNodeMethodLength(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) Length() int64 { + return int64(len(n.t)) + } + `, w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g mapGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g mapGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return mapBuilderGenerator{ + g.AdjCfg, + mixins.MapAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type mapBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapAssemblerTraits + PkgName string + Type *schema.TypeMap +} + +func (mapBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g mapBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g mapBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g mapBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // - 'w' is the "**w**ip" pointer. + // - 'm' is the **m**aybe which communicates our completeness to the parent if we're a child assembler. + // - 'state' is what it says on the tin. this is used for the map state (the broad transitions between null, start-map, and finish are handled by 'm' for consistency.) + // - there's no equivalent of the 'f' (**f**ocused next) field in struct assemblers -- that's implicitly the last row of the 'w.t'. + // + // - 'cm' is **c**hild **m**aybe and is used for the completion message from children. + // It's used for values if values aren't allowed to be nullable and thus don't have their own per-value maybe slot we can use. + // It's always used for key assembly, since keys are never allowed to be nullable and thus etc. + // - 'ka' and 'va' are the key assembler and value assembler respectively. + // Perhaps surprisingly, we can get away with using the assemblers for each type just straight up, no wrappers necessary; + // All of the required magic is handled through maybe pointers and some tidy methods used during state transitions. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Assembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state maState + + cm schema.Maybe + ka _{{ .Type.KeyType | TypeSymbol }}__Assembler + va _{{ .Type.ValueType | TypeSymbol }}__Assembler + } + + func (na *_{{ .Type | TypeSymbol }}__Assembler) reset() { + na.state = maState_initial + na.ka.reset() + na.va.reset() + } + `, w, g.AdjCfg, g) +} +func (g mapBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + emitNodeAssemblerMethodBeginMap_mapoid(w, g.AdjCfg, g) +} +func (g mapBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g mapBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_mapoid(w, g.AdjCfg, g) +} +func (g mapBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + emitNodeAssemblerHelper_mapoid_keyTidyHelper(w, g.AdjCfg, g) + emitNodeAssemblerHelper_mapoid_valueTidyHelper(w, g.AdjCfg, g) + emitNodeAssemblerHelper_mapoid_mapAssemblerMethods(w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genMapReprMap.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genMapReprMap.go new file mode 100644 index 00000000000..977fc1a6a2a --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genMapReprMap.go @@ -0,0 +1,206 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &mapReprMapGenerator{} + +func NewMapReprMapGenerator(pkgName string, typ *schema.TypeMap, adjCfg *AdjunctCfg) TypeGenerator { + return mapReprMapGenerator{ + mapGenerator{ + adjCfg, + mixins.MapTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type mapReprMapGenerator struct { + mapGenerator +} + +func (g mapReprMapGenerator) GetRepresentationNodeGen() NodeGenerator { + return mapReprMapReprGenerator{ + g.AdjCfg, + mixins.MapTraits{ + PkgName: g.PkgName, + TypeName: string(g.Type.Name()) + ".Repr", + TypeSymbol: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type mapReprMapReprGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapTraits + PkgName string + Type *schema.TypeMap +} + +func (mapReprMapReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g mapReprMapReprGenerator) EmitNodeType(w io.Writer) { + // Even though this is a "natural" representation... we need a new type here, + // because maps are recursive, and so all our functions that access + // children need to remember to return the representation node of those child values. + // It's still structurally the same, though (and we'll be able to cast in the methodset pattern). + // Error-thunking methods also have a different string in their error, so those are unique even if they don't seem particularly interesting. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} +func (g mapReprMapReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} + +func (g mapReprMapReprGenerator) EmitNodeMethodLookupByString(w io.Writer) { + doTemplate(` + func (nr *_{{ .Type | TypeSymbol }}__Repr) LookupByString(k string) (datamodel.Node, error) { + v, err := ({{ .Type | TypeSymbol }})(nr).LookupByString(k) + if err != nil || v == datamodel.Null { + return v, err + } + return v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil + } + `, w, g.AdjCfg, g) +} +func (g mapReprMapReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + // Null is also already a branch in the method we're calling; hopefully the compiler inlines and sees this and DTRT. + // REVIEW: these unchecked casts are definitely safe at compile time, but I'm not sure if the compiler considers that provable, + // so we should investigate if there's any runtime checks injected here that waste time. If so: write this with more gsloc to avoid :( + doTemplate(` + func (nr *_{{ .Type | TypeSymbol }}__Repr) LookupByNode(k datamodel.Node) (datamodel.Node, error) { + v, err := ({{ .Type | TypeSymbol }})(nr).LookupByNode(k) + if err != nil || v == datamodel.Null { + return v, err + } + return v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil + } + `, w, g.AdjCfg, g) +} +func (g mapReprMapReprGenerator) EmitNodeMethodMapIterator(w io.Writer) { + // FUTURE: trying to get this to share the preallocated memory if we get iterators wedged into their node slab will be ... fun. + doTemplate(` + func (nr *_{{ .Type | TypeSymbol }}__Repr) MapIterator() datamodel.MapIterator { + return &_{{ .Type | TypeSymbol }}__ReprMapItr{({{ .Type | TypeSymbol }})(nr), 0} + } + + type _{{ .Type | TypeSymbol }}__ReprMapItr _{{ .Type | TypeSymbol }}__MapItr + + func (itr *_{{ .Type | TypeSymbol }}__ReprMapItr) Next() (k datamodel.Node, v datamodel.Node, err error) { + k, v, err = (*_{{ .Type | TypeSymbol }}__MapItr)(itr).Next() + if err != nil || v == datamodel.Null { + return + } + return k, v.({{ .Type.ValueType | TypeSymbol}}).Representation(), nil + } + func (itr *_{{ .Type | TypeSymbol }}__ReprMapItr) Done() bool { + return (*_{{ .Type | TypeSymbol }}__MapItr)(itr).Done() + } + + `, w, g.AdjCfg, g) +} +func (g mapReprMapReprGenerator) EmitNodeMethodLength(w io.Writer) { + doTemplate(` + func (rn *_{{ .Type | TypeSymbol }}__Repr) Length() int64 { + return int64(len(rn.t)) + } + `, w, g.AdjCfg, g) +} +func (g mapReprMapReprGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} +func (g mapReprMapReprGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g mapReprMapReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return mapReprMapReprBuilderGenerator{ + g.AdjCfg, + mixins.MapAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type mapReprMapReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapAssemblerTraits + PkgName string + Type *schema.TypeMap +} + +func (mapReprMapReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g mapReprMapReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g mapReprMapReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g mapReprMapReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // - 'w' is the "**w**ip" pointer. + // - 'm' is the **m**aybe which communicates our completeness to the parent if we're a child assembler. + // - 'state' is what it says on the tin. this is used for the map state (the broad transitions between null, start-map, and finish are handled by 'm' for consistency.) + // - there's no equivalent of the 'f' (**f**ocused next) field in struct assemblers -- that's implicitly the last row of the 'w.t'. + // + // - 'cm' is **c**hild **m**aybe and is used for the completion message from children. + // It's used for values if values aren't allowed to be nullable and thus don't have their own per-value maybe slot we can use. + // It's always used for key assembly, since keys are never allowed to be nullable and thus etc. + // - 'ka' and 'va' are the key assembler and value assembler respectively. + // Perhaps surprisingly, we can get away with using the assemblers for each type just straight up, no wrappers necessary; + // All of the required magic is handled through maybe pointers and some tidy methods used during state transitions. + // + // Note that this textually similar to the type-level assembler, but because it embeds the repr assembler for the child types, + // it might be *significantly* different in size and memory layout in that trailing part of the struct. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state maState + + cm schema.Maybe + ka _{{ .Type.KeyType | TypeSymbol }}__ReprAssembler + va _{{ .Type.ValueType | TypeSymbol }}__ReprAssembler + } + + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() { + na.state = maState_initial + na.ka.reset() + na.va.reset() + } + `, w, g.AdjCfg, g) +} +func (g mapReprMapReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + emitNodeAssemblerMethodBeginMap_mapoid(w, g.AdjCfg, g) +} +func (g mapReprMapReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g mapReprMapReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_mapoid(w, g.AdjCfg, g) +} +func (g mapReprMapReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + emitNodeAssemblerHelper_mapoid_keyTidyHelper(w, g.AdjCfg, g) + emitNodeAssemblerHelper_mapoid_valueTidyHelper(w, g.AdjCfg, g) + emitNodeAssemblerHelper_mapoid_mapAssemblerMethods(w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genString.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genString.go new file mode 100644 index 00000000000..d4a117e5bba --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genString.go @@ -0,0 +1,135 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type stringGenerator struct { + AdjCfg *AdjunctCfg + mixins.StringTraits + PkgName string + Type *schema.TypeString +} + +func (stringGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g stringGenerator) EmitNativeType(w io.Writer) { + emitNativeType_scalar(w, g.AdjCfg, g) +} +func (g stringGenerator) EmitNativeAccessors(w io.Writer) { + emitNativeAccessors_scalar(w, g.AdjCfg, g) +} +func (g stringGenerator) EmitNativeBuilder(w io.Writer) { + // Generate a single-step construction function -- this is easy to do for a scalar, + // and all representations of scalar kind can be expected to have a method like this. + // The function is attached to the NodePrototype for convenient namespacing; + // it needs no new memory, so it would be inappropriate to attach to the builder or assembler. + // The function is directly used internally by anything else that might involve recursive destructuring on the same scalar kind + // (for example, structs using stringjoin strategies that have one of this type as a field, etc). + // FUTURE: should engage validation flow. + doTemplate(` + func (_{{ .Type | TypeSymbol }}__Prototype) fromString(w *_{{ .Type | TypeSymbol }}, v string) error { + *w = _{{ .Type | TypeSymbol }}{v} + return nil + } + `, w, g.AdjCfg, g) + // And generate a publicly exported version of that single-step constructor, too. + // (Just don't expose the details about allocation, because you can't meaningfully use that from outside the package.) + emitNativeBuilder_scalar(w, g.AdjCfg, g) +} + +func (g stringGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g stringGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g stringGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g stringGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g stringGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. +} + +func (g stringGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} +func (g stringGenerator) EmitNodeMethodAsString(w io.Writer) { + emitNodeMethodAsKind_scalar(w, g.AdjCfg, g) +} +func (g stringGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} +func (g stringGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g stringGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return stringBuilderGenerator{ + g.AdjCfg, + mixins.StringAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type stringBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.StringAssemblerTraits + PkgName string + Type *schema.TypeString +} + +func (stringBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g stringBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g stringBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g stringBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + emitNodeAssemblerType_scalar(w, g.AdjCfg, g) +} +func (g stringBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g) +} +func (g stringBuilderGenerator) EmitNodeAssemblerMethodAssignString(w io.Writer) { + emitNodeAssemblerMethodAssignKind_scalar(w, g.AdjCfg, g) +} +func (g stringBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_scalar(w, g.AdjCfg, g) +} +func (g stringBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // Nothing needed here for string kinds. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStringReprString.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStringReprString.go new file mode 100644 index 00000000000..05c346df1e1 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStringReprString.go @@ -0,0 +1,108 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &stringReprStringGenerator{} + +func NewStringReprStringGenerator(pkgName string, typ *schema.TypeString, adjCfg *AdjunctCfg) TypeGenerator { + return stringReprStringGenerator{ + stringGenerator{ + adjCfg, + mixins.StringTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type stringReprStringGenerator struct { + stringGenerator +} + +func (g stringReprStringGenerator) GetRepresentationNodeGen() NodeGenerator { + return stringReprStringReprGenerator{ + g.AdjCfg, + g.Type, + } +} + +type stringReprStringReprGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeString +} + +func (g stringReprStringReprGenerator) EmitNodeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr = _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} +func (g stringReprStringReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} +func (stringReprStringReprGenerator) EmitNodeMethodKind(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodLookupByString(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodLookupByNode(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodLookupByIndex(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodLookupBySegment(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodMapIterator(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodListIterator(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodLength(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodIsAbsent(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodIsNull(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodAsBool(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodAsInt(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodAsFloat(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodAsString(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodAsBytes(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodAsLink(io.Writer) {} +func (stringReprStringReprGenerator) EmitNodeMethodPrototype(io.Writer) {} +func (g stringReprStringReprGenerator) EmitNodePrototypeType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprPrototype = _{{ .Type | TypeSymbol }}__Prototype + `, w, g.AdjCfg, g) +} +func (g stringReprStringReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return stringReprStringReprBuilderGenerator(g) +} + +type stringReprStringReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + Type *schema.TypeString +} + +func (stringReprStringReprBuilderGenerator) EmitNodeBuilderType(io.Writer) {} +func (g stringReprStringReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) {} +func (g stringReprStringReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Since this is a "natural" representation... there's just a type alias here. + // No new functions are necessary. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler = _{{ .Type | TypeSymbol }}__Assembler + `, w, g.AdjCfg, g) +} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodAssignBool(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodAssignInt(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodAssignFloat(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodAssignBytes(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodAssignLink(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerMethodPrototype(io.Writer) {} +func (stringReprStringReprBuilderGenerator) EmitNodeAssemblerOtherBits(io.Writer) {} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStruct.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStruct.go new file mode 100644 index 00000000000..1351eb3c909 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStruct.go @@ -0,0 +1,594 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +type structGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapTraits + PkgName string + Type *schema.TypeStruct +} + +func (structGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g structGenerator) EmitNativeType(w io.Writer) { + doTemplate(` + {{- if Comments -}} + // {{ .Type | TypeSymbol }} matches the IPLD Schema type "{{ .Type.Name }}". It has {{ .Type.TypeKind }} type-kind, and may be interrogated like {{ .Kind }} kind. + {{- end}} + type {{ .Type | TypeSymbol }} = *_{{ .Type | TypeSymbol }} + type _{{ .Type | TypeSymbol }} struct { + {{- range $field := .Type.Fields}} + {{ $field | FieldSymbolLower }} _{{ $field.Type | TypeSymbol }}{{if $field.IsMaybe }}__Maybe{{end}} + {{- end}} + } + `, w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNativeAccessors(w io.Writer) { + doTemplate(` + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $field := .Type.Fields }} + func (n _{{ $type | TypeSymbol }}) Field{{ $field | FieldSymbolUpper }}() {{ if $field.IsMaybe }}Maybe{{end}}{{ $field.Type | TypeSymbol }} { + return &n.{{ $field | FieldSymbolLower }} + } + {{- end}} + `, w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNativeBuilder(w io.Writer) { + // Unclear what, if anything, goes here. +} + +func (g structGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g structGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g structGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g structGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g structGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. + // We do, however, want some constants for our fields; + // they'll make iterators able to work faster. So let's emit those. + doTemplate(` + var ( + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $field := .Type.Fields }} + fieldName__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} = _String{"{{ $field.Name }}"} + {{- end }} + ) + `, w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNodeMethodLookupByString(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) LookupByString(key string) (datamodel.Node, error) { + switch key { + {{- range $field := .Type.Fields }} + case "{{ $field.Name }}": + {{- if $field.IsOptional }} + if n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Absent { + return datamodel.Absent, nil + } + {{- end}} + {{- if $field.IsNullable }} + if n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Null { + return datamodel.Null, nil + } + {{- end}} + {{- if $field.IsMaybe }} + return {{if not (MaybeUsesPtr $field.Type) }}&{{end}}n.{{ $field | FieldSymbolLower }}.v, nil + {{- else}} + return &n.{{ $field | FieldSymbolLower }}, nil + {{- end}} + {{- end}} + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfString(key)} + } + } + `, w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) + } + `, w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNodeMethodMapIterator(w io.Writer) { + // Note that the typed iterator will report absent fields. + // The representation iterator (if has one) however will skip those. + doTemplate(` + func (n {{ .Type | TypeSymbol }}) MapIterator() datamodel.MapIterator { + return &_{{ .Type | TypeSymbol }}__MapItr{n, 0} + } + + type _{{ .Type | TypeSymbol }}__MapItr struct { + n {{ .Type | TypeSymbol }} + idx int + } + + func (itr *_{{ .Type | TypeSymbol }}__MapItr) Next() (k datamodel.Node, v datamodel.Node, _ error) { + {{- if not .Type.Fields }} + return nil, nil, datamodel.ErrIteratorOverread{} + {{ else -}} + if itr.idx >= {{ len .Type.Fields }} { + return nil, nil, datamodel.ErrIteratorOverread{} + } + switch itr.idx { + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + k = &fieldName__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} + {{- if $field.IsOptional }} + if itr.n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Absent { + v = datamodel.Absent + break + } + {{- end}} + {{- if $field.IsNullable }} + if itr.n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Null { + v = datamodel.Null + break + } + {{- end}} + {{- if $field.IsMaybe }} + v = {{if not (MaybeUsesPtr $field.Type) }}&{{end}}itr.n.{{ $field | FieldSymbolLower}}.v + {{- else}} + v = &itr.n.{{ $field | FieldSymbolLower}} + {{- end}} + {{- end}} + default: + panic("unreachable") + } + itr.idx++ + return + {{- end}} + } + func (itr *_{{ .Type | TypeSymbol }}__MapItr) Done() bool { + return itr.idx >= {{ len .Type.Fields }} + } + + `, w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNodeMethodLength(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Length() int64 { + return {{ len .Type.Fields }} + } + `, w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g structGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g structGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return structBuilderGenerator{ + g.AdjCfg, + mixins.MapAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type structBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapAssemblerTraits + PkgName string + Type *schema.TypeStruct +} + +func (structBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g structBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g structBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g structBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // - 'w' is the "**w**ip" pointer. + // - 'm' is the **m**aybe which communicates our completeness to the parent if we're a child assembler. + // - 'state' is what it says on the tin. this is used for the map state (the broad transitions between null, start-map, and finish are handled by 'm' for consistency.) + // - 's' is a bitfield for what's been **s**et. + // - 'f' is the **f**ocused field that will be assembled next. + // + // - 'cm' is **c**hild **m**aybe and is used for the completion message from children that aren't allowed to be nullable (for those that are, their own maybe.m is used). + // ('cm' could be elided for structs where all fields are maybes. trivial but not yet implemented.) + // - the 'ca_*' fields embed **c**hild **a**ssemblers -- these are embedded so we can yield pointers to them without causing new allocations. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Assembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state maState + s int + f int + + cm schema.Maybe + {{range $field := .Type.Fields -}} + ca_{{ $field | FieldSymbolLower }} _{{ $field.Type | TypeSymbol }}__Assembler + {{end -}} + } + + func (na *_{{ .Type | TypeSymbol }}__Assembler) reset() { + na.state = maState_initial + na.s = 0 + {{- range $field := .Type.Fields }} + na.ca_{{ $field | FieldSymbolLower }}.reset() + {{- end}} + } + + var ( + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $i, $field := .Type.Fields }} + fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} = 1 << {{ $i }} + {{- end}} + fieldBits__{{ $type | TypeSymbol }}_sufficient = 0 {{- range $i, $field := .Type.Fields }}{{if not $field.IsOptional }} + 1 << {{ $i }}{{end}}{{end}} + ) + `, w, g.AdjCfg, g) +} +func (g structBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + emitNodeAssemblerMethodBeginMap_strictoid(w, g.AdjCfg, g) +} +func (g structBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g structBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + // AssignNode goes through three phases: + // 1. is it null? Jump over to AssignNull (which may or may not reject it). + // 2. is it our own type? Handle specially -- we might be able to do efficient things. + // 3. is it the right kind to morph into us? Do so. + // + // We do not set m=midvalue in phase 3 -- it shouldn't matter unless you're trying to pull off concurrent access, which is wrong and unsafe regardless. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != datamodel.Kind_Map { + return datamodel.ErrWrongKind{TypeName: "{{ .PkgName }}.{{ .Type.Name }}", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() + } + `, w, g.AdjCfg, g) +} +func (g structBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + g.emitMapAssemblerChildTidyHelper(w) + g.emitMapAssemblerMethods(w) + g.emitKeyAssembler(w) +} +func (g structBuilderGenerator) emitMapAssemblerChildTidyHelper(w io.Writer) { + // This function attempts to clean up the state machine to acknolwedge child assembly finish. + // If the child was finished and we just collected it, return true and update state to maState_initial. + // Otherwise, if it wasn't done, return false; + // and the caller is almost certain to emit an error momentarily. + // The function will only be called when the current state is maState_midValue. + // (In general, the idea is that if the user is doing things correctly, + // this function will only be called when the child is in fact finished.) + // Most of the logic here is about nullables and not optionals, + // because if you're an optional that's absent, you never got to value assembly. + // There's still one branch for optionals, though, because they have a different residence for 'm' just as nullables do. + // Child assemblers are expected to control their own state machines; + // for values that have maybes, we never change their maybe state again, so the usual logic should hold; + // for values that don't have maybes (and thus share 'cm')... + // We don't bother to nil their 'm' pointer; the worst that can happen is an over-held assembler for that field + // can make a bizarre and broken transition for a subsequent field, which will result in very ugly errors, but isn't unsafe per se. + // We do nil their 'w' pointer, though: we don't want a set to that able to leak in later if we're on the way to Finish! + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__Assembler) valueFinishTidy() bool { + switch ma.f { + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + {{- if $field.IsNullable }} + switch ma.w.{{ $field | FieldSymbolLower }}.m { + case schema.Maybe_Null: + ma.state = maState_initial + return true + case schema.Maybe_Value: + {{- if (MaybeUsesPtr $field.Type) }} + ma.w.{{ $field | FieldSymbolLower }}.v = ma.ca_{{ $field | FieldSymbolLower }}.w + {{- end}} + ma.state = maState_initial + return true + default: + return false + } + {{- else if $field.IsOptional }} + switch ma.w.{{ $field | FieldSymbolLower }}.m { + case schema.Maybe_Value: + {{- if (MaybeUsesPtr $field.Type) }} + ma.w.{{ $field | FieldSymbolLower }}.v = ma.ca_{{ $field | FieldSymbolLower }}.w + {{- end}} + ma.state = maState_initial + return true + default: + return false + } + {{- else}} + switch ma.cm { + case schema.Maybe_Value: + ma.ca_{{ $field | FieldSymbolLower }}.w = nil + ma.cm = schema.Maybe_Absent + ma.state = maState_initial + return true + default: + return false + } + {{- end}} + {{- end}} + default: + panic("unreachable") + } + } + `, w, g.AdjCfg, g) +} +func (g structBuilderGenerator) emitMapAssemblerMethods(w io.Writer) { + // FUTURE: some of the setup of the child assemblers could probably be DRY'd up. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__Assembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- if .Type.Fields }} + switch k { + {{- range $i, $field := .Type.Fields }} + case "{{ $field.Name }}": + if ma.s & fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} != 0 { + return nil, datamodel.ErrRepeatedMapKey{Key: &fieldName__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }}} + } + ma.s += fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} + ma.state = maState_midValue + ma.f = {{ $i }} + {{- if $field.IsMaybe }} + ma.ca_{{ $field | FieldSymbolLower }}.w = {{if not (MaybeUsesPtr $field.Type) }}&{{end}}ma.w.{{ $field | FieldSymbolLower }}.v + ma.ca_{{ $field | FieldSymbolLower }}.m = &ma.w.{{ $field | FieldSymbolLower }}.m + {{- if $field.IsNullable }} + ma.w.{{ $field | FieldSymbolLower }}.m = allowNull + {{- end}} + {{- else}} + ma.ca_{{ $field | FieldSymbolLower }}.w = &ma.w.{{ $field | FieldSymbolLower }} + ma.ca_{{ $field | FieldSymbolLower }}.m = &ma.cm + {{- end}} + return &ma.ca_{{ $field | FieldSymbolLower }}, nil + {{- end}} + } + {{- end}} + return nil, schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}", Key:&_String{k}} + } + func (ma *_{{ .Type | TypeSymbol }}__Assembler) AssembleKey() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_{{ .Type | TypeSymbol }}__KeyAssembler)(ma) + } + func (ma *_{{ .Type | TypeSymbol }}__Assembler) AssembleValue() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.f { + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + {{- if $field.IsMaybe }} + ma.ca_{{ $field | FieldSymbolLower }}.w = {{if not (MaybeUsesPtr $field.Type) }}&{{end}}ma.w.{{ $field | FieldSymbolLower }}.v + ma.ca_{{ $field | FieldSymbolLower }}.m = &ma.w.{{ $field | FieldSymbolLower }}.m + {{- if $field.IsNullable }} + ma.w.{{ $field | FieldSymbolLower }}.m = allowNull + {{- end}} + {{- else}} + ma.ca_{{ $field | FieldSymbolLower }}.w = &ma.w.{{ $field | FieldSymbolLower }} + ma.ca_{{ $field | FieldSymbolLower }}.m = &ma.cm + {{- end}} + return &ma.ca_{{ $field | FieldSymbolLower }} + {{- end}} + default: + panic("unreachable") + } + } + func (ma *_{{ .Type | TypeSymbol }}__Assembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.s & fieldBits__{{ $type | TypeSymbol }}_sufficient != fieldBits__{{ $type | TypeSymbol }}_sufficient { + err := schema.ErrMissingRequiredField{Missing: make([]string, 0)} + {{- range $i, $field := .Type.Fields }} + {{- if not $field.IsMaybe}} + if ma.s & fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} == 0 { + err.Missing = append(err.Missing, "{{ $field.Name }}") + } + {{- end}} + {{- end}} + return err + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil + } + func (ma *_{{ .Type | TypeSymbol }}__Assembler) KeyPrototype() datamodel.NodePrototype { + return _String__Prototype{} + } + func (ma *_{{ .Type | TypeSymbol }}__Assembler) ValuePrototype(k string) datamodel.NodePrototype { + panic("todo structbuilder mapassembler valueprototype") + } + `, w, g.AdjCfg, g) +} +func (g structBuilderGenerator) emitKeyAssembler(w io.Writer) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__KeyAssembler _{{ .Type | TypeSymbol }}__Assembler + `, w, g.AdjCfg, g) + stubs := mixins.StringAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName + ".KeyAssembler", + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Key", + } + // This key assembler can disregard any idea of complex keys because it's a struct! + // Struct field names must be strings (and quite simple ones at that). + stubs.EmitNodeAssemblerMethodBeginMap(w) + stubs.EmitNodeAssemblerMethodBeginList(w) + stubs.EmitNodeAssemblerMethodAssignNull(w) + stubs.EmitNodeAssemblerMethodAssignBool(w) + stubs.EmitNodeAssemblerMethodAssignInt(w) + stubs.EmitNodeAssemblerMethodAssignFloat(w) + doTemplate(` + func (ka *_{{ .Type | TypeSymbol }}__KeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + switch k { + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $i, $field := .Type.Fields }} + case "{{ $field.Name }}": + if ka.s & fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} != 0 { + return datamodel.ErrRepeatedMapKey{Key: &fieldName__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }}} + } + ka.s += fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} + ka.state = maState_expectValue + ka.f = {{ $i }} + return nil + {{- end}} + default: + return schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}", Key:&_String{k}} + } + } + `, w, g.AdjCfg, g) + stubs.EmitNodeAssemblerMethodAssignBytes(w) + stubs.EmitNodeAssemblerMethodAssignLink(w) + doTemplate(` + func (ka *_{{ .Type | TypeSymbol }}__KeyAssembler) AssignNode(v datamodel.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } + } + func (_{{ .Type | TypeSymbol }}__KeyAssembler) Prototype() datamodel.NodePrototype { + return _String__Prototype{} + } + `, w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprMap.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprMap.go new file mode 100644 index 00000000000..368a3111350 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprMap.go @@ -0,0 +1,634 @@ +package gengo + +import ( + "io" + "strconv" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &structReprMapGenerator{} + +func NewStructReprMapGenerator(pkgName string, typ *schema.TypeStruct, adjCfg *AdjunctCfg) TypeGenerator { + return structReprMapGenerator{ + structGenerator{ + adjCfg, + mixins.MapTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type structReprMapGenerator struct { + structGenerator +} + +func (g structReprMapGenerator) GetRepresentationNodeGen() NodeGenerator { + return structReprMapReprGenerator{ + g.AdjCfg, + mixins.MapTraits{ + PkgName: g.PkgName, + TypeName: string(g.Type.Name()) + ".Repr", + TypeSymbol: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type structReprMapReprGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapTraits + PkgName string + Type *schema.TypeStruct +} + +func (structReprMapReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g structReprMapReprGenerator) EmitNodeType(w io.Writer) { + // The type is structurally the same, but will have a different set of methods. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) + + // We do also want some constants for our fields; + // they'll make iterators able to work faster. + // These might be the same strings as the type-level field names + // (in fact, they are, unless renames are used)... but that's fine. + // We get simpler code by just doing this unconditionally. + doTemplate(` + var ( + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $field := .Type.Fields }} + fieldName__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }}_serial = _String{"{{ $field | $type.RepresentationStrategy.GetFieldKey }}"} + {{- end }} + ) + `, w, g.AdjCfg, g) +} + +func (g structReprMapReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} + +func (g structReprMapReprGenerator) EmitNodeMethodLookupByString(w io.Writer) { + // Similar to the type-level method, except any absent fields also return ErrNotExists. + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) LookupByString(key string) (datamodel.Node, error) { + switch key { + {{- range $field := .Type.Fields }} + case "{{ $field | $field.Parent.RepresentationStrategy.GetFieldKey }}": + {{- if $field.IsOptional }} + if n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Absent { + return datamodel.Absent, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} + } + {{- end}} + {{- if $field.IsNullable }} + if n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Null { + return datamodel.Null, nil + } + {{- end}} + {{- if $field.IsMaybe }} + return n.{{ $field | FieldSymbolLower }}.v.Representation(), nil + {{- else}} + return n.{{ $field | FieldSymbolLower }}.Representation(), nil + {{- end}} + {{- end}} + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfString(key)} + } + } + `, w, g.AdjCfg, g) +} + +func (g structReprMapReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) + } + `, w, g.AdjCfg, g) +} + +func (g structReprMapReprGenerator) EmitNodeMethodMapIterator(w io.Writer) { + // The 'idx' int is what field we'll yield next. + // Note that this iterator doesn't mention fields that are absent. + // This makes things a bit trickier -- especially the 'Done' predicate, + // since it may have to do lookahead if there's any optionals at the end of the structure! + // It also means 'idx' can jump ahead by more than one per Next call in order to skip over absent fields. + // TODO : support for implicits is still future work. + + // First: Determine if there are any optionals at all. + // If there are none, some control flow symbols need to not be emitted. + fields := g.Type.Fields() + haveOptionals := false + for _, field := range fields { + if field.IsOptional() { + haveOptionals = true + break + } + } + + // Second: Count how many trailing fields are optional. + // The 'Done' predicate gets more complex when in the trailing optionals. + fieldCount := len(fields) + beginTrailingOptionalField := fieldCount + for i := fieldCount - 1; i >= 0; i-- { + if !fields[i].IsOptional() { + break + } + beginTrailingOptionalField = i + } + haveTrailingOptionals := beginTrailingOptionalField < fieldCount + + // Now: finally we can get on with the actual templating. + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) MapIterator() datamodel.MapIterator { + {{- if .HaveTrailingOptionals }} + end := {{ len .Type.Fields }}`+ + func() string { // this next part was too silly in templates due to lack of reverse ranging. + v := "\n" + for i := fieldCount - 1; i >= beginTrailingOptionalField; i-- { + v += "\t\t\tif n." + g.AdjCfg.FieldSymbolLower(fields[i]) + ".m == schema.Maybe_Absent {\n" + v += "\t\t\t\tend = " + strconv.Itoa(i) + "\n" + v += "\t\t\t} else {\n" + v += "\t\t\t\tgoto done\n" + v += "\t\t\t}\n" + } + return v + }()+`done: + return &_{{ .Type | TypeSymbol }}__ReprMapItr{n, 0, end} + {{- else}} + return &_{{ .Type | TypeSymbol }}__ReprMapItr{n, 0} + {{- end}} + } + + type _{{ .Type | TypeSymbol }}__ReprMapItr struct { + n *_{{ .Type | TypeSymbol }}__Repr + idx int + {{if .HaveTrailingOptionals }}end int{{end}} + } + + func (itr *_{{ .Type | TypeSymbol }}__ReprMapItr) Next() (k datamodel.Node, v datamodel.Node, _ error) { + {{- if not .Type.Fields }} + {{- /* TODO: deduplicate all these methods which just error */ -}} + return nil, nil, datamodel.ErrIteratorOverread{} + {{ else -}} + {{ if .HaveOptionals }}advance:{{end -}} + if itr.idx >= {{ len .Type.Fields }} { + return nil, nil, datamodel.ErrIteratorOverread{} + } + switch itr.idx { + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + k = &fieldName__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }}_serial + {{- if $field.IsOptional }} + if itr.n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + {{- end}} + {{- if $field.IsNullable }} + if itr.n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Null { + v = datamodel.Null + break + } + {{- end}} + {{- if $field.IsMaybe }} + v = itr.n.{{ $field | FieldSymbolLower}}.v.Representation() + {{- else}} + v = itr.n.{{ $field | FieldSymbolLower}}.Representation() + {{- end}} + {{- end}} + default: + panic("unreachable") + } + itr.idx++ + return + {{- end}} + } + {{- if .HaveTrailingOptionals }} + func (itr *_{{ .Type | TypeSymbol }}__ReprMapItr) Done() bool { + return itr.idx >= itr.end + } + {{- else}} + func (itr *_{{ .Type | TypeSymbol }}__ReprMapItr) Done() bool { + return itr.idx >= {{ len .Type.Fields }} + } + {{- end}} + `, w, g.AdjCfg, struct { + Type *schema.TypeStruct + HaveOptionals bool + HaveTrailingOptionals bool + BeginTrailingOptionalField int + }{ + g.Type, + haveOptionals, + haveTrailingOptionals, + beginTrailingOptionalField, + }) +} + +func (g structReprMapReprGenerator) EmitNodeMethodLength(w io.Writer) { + // This is fun: it has to count down for any unset optional fields. + // TODO : support for implicits is still future work. + doTemplate(` + func (rn *_{{ .Type | TypeSymbol }}__Repr) Length() int64 { + l := {{ len .Type.Fields }} + {{- range $field := .Type.Fields }} + {{- if $field.IsOptional }} + if rn.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Absent { + l-- + } + {{- end}} + {{- end}} + return int64(l) + } + `, w, g.AdjCfg, g) +} + +func (g structReprMapReprGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g structReprMapReprGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g structReprMapReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return structReprMapReprBuilderGenerator{ + g.AdjCfg, + mixins.MapAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type structReprMapReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapAssemblerTraits + PkgName string + Type *schema.TypeStruct +} + +func (structReprMapReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g structReprMapReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g structReprMapReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g structReprMapReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // - 'w' is the "**w**ip" pointer. + // - 'm' is the **m**aybe which communicates our completeness to the parent if we're a child assembler. + // - 'state' is what it says on the tin. this is used for the map state (the broad transitions between null, start-map, and finish are handled by 'm' for consistency.) + // - 's' is a bitfield for what's been **s**et. + // - 'f' is the **f**ocused field that will be assembled next. + // + // - 'cm' is **c**hild **m**aybe and is used for the completion message from children that aren't allowed to be nullable (for those that are, their own maybe.m is used). + // - the 'ca_*' fields embed **c**hild **a**ssemblers -- these are embedded so we can yield pointers to them without causing new allocations. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state maState + s int + f int + + cm schema.Maybe + {{range $field := .Type.Fields -}} + ca_{{ $field | FieldSymbolLower }} _{{ $field.Type | TypeSymbol }}__ReprAssembler + {{end -}} + } + + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() { + na.state = maState_initial + na.s = 0 + {{- range $field := .Type.Fields }} + na.ca_{{ $field | FieldSymbolLower }}.reset() + {{- end}} + } + `, w, g.AdjCfg, g) +} +func (g structReprMapReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + emitNodeAssemblerMethodBeginMap_strictoid(w, g.AdjCfg, g) +} +func (g structReprMapReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g structReprMapReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + // AssignNode goes through three phases: + // 1. is it null? Jump over to AssignNull (which may or may not reject it). + // 2. is it our own type? Handle specially -- we might be able to do efficient things. + // 3. is it the right kind to morph into us? Do so. + // + // We do not set m=midvalue in phase 3 -- it shouldn't matter unless you're trying to pull off concurrent access, which is wrong and unsafe regardless. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != datamodel.Kind_Map { + return datamodel.ErrWrongKind{TypeName: "{{ .PkgName }}.{{ .Type.Name }}.Repr", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() + } + `, w, g.AdjCfg, g) +} +func (g structReprMapReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + g.emitMapAssemblerChildTidyHelper(w) + g.emitMapAssemblerMethods(w) + g.emitKeyAssembler(w) +} +func (g structReprMapReprBuilderGenerator) emitMapAssemblerChildTidyHelper(w io.Writer) { + // This is exactly the same as the matching method on the type-level assembler; + // everything that differs happens to be hidden behind the 'f' indirection, which is numeric. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) valueFinishTidy() bool { + switch ma.f { + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + {{- if $field.IsNullable }} + switch ma.w.{{ $field | FieldSymbolLower }}.m { + case schema.Maybe_Null: + ma.state = maState_initial + return true + case schema.Maybe_Value: + {{- if (MaybeUsesPtr $field.Type) }} + ma.w.{{ $field | FieldSymbolLower }}.v = ma.ca_{{ $field | FieldSymbolLower }}.w + {{- end}} + ma.state = maState_initial + return true + default: + return false + } + {{- else if $field.IsOptional }} + switch ma.w.{{ $field | FieldSymbolLower }}.m { + case schema.Maybe_Value: + {{- if (MaybeUsesPtr $field.Type) }} + ma.w.{{ $field | FieldSymbolLower }}.v = ma.ca_{{ $field | FieldSymbolLower }}.w + {{- end}} + ma.state = maState_initial + return true + default: + return false + } + {{- else}} + switch ma.cm { + case schema.Maybe_Value: + {{- /* while defense in depth here might avoid some 'wat' outcomes, it's not strictly necessary for safety */ -}} + {{- /* ma.ca_{{ $field | FieldSymbolLower }}.w = nil */ -}} + {{- /* ma.ca_{{ $field | FieldSymbolLower }}.m = nil */ -}} + ma.cm = schema.Maybe_Absent + ma.state = maState_initial + return true + default: + return false + } + {{- end}} + {{- end}} + default: + panic("unreachable") + } + } + `, w, g.AdjCfg, g) +} +func (g structReprMapReprBuilderGenerator) emitMapAssemblerMethods(w io.Writer) { + // FUTURE: some of the setup of the child assemblers could probably be DRY'd up. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- if .Type.Fields }} + switch k { + {{- range $i, $field := .Type.Fields }} + case "{{ $field | $type.RepresentationStrategy.GetFieldKey }}": + if ma.s & fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} != 0 { + return nil, datamodel.ErrRepeatedMapKey{Key: &fieldName__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }}_serial} + } + ma.s += fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} + ma.state = maState_midValue + ma.f = {{ $i }} + {{- if $field.IsMaybe }} + ma.ca_{{ $field | FieldSymbolLower }}.w = {{if not (MaybeUsesPtr $field.Type) }}&{{end}}ma.w.{{ $field | FieldSymbolLower }}.v + ma.ca_{{ $field | FieldSymbolLower }}.m = &ma.w.{{ $field | FieldSymbolLower }}.m + {{if $field.IsNullable }}ma.w.{{ $field | FieldSymbolLower }}.m = allowNull{{end}} + {{- else}} + ma.ca_{{ $field | FieldSymbolLower }}.w = &ma.w.{{ $field | FieldSymbolLower }} + ma.ca_{{ $field | FieldSymbolLower }}.m = &ma.cm + {{- end}} + return &ma.ca_{{ $field | FieldSymbolLower }}, nil + {{- end}} + default: + } + {{- end}} + return nil, schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr", Key:&_String{k}} + } + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) AssembleKey() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_{{ .Type | TypeSymbol }}__ReprKeyAssembler)(ma) + } + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) AssembleValue() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.f { + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + {{- if $field.IsMaybe }} + ma.ca_{{ $field | FieldSymbolLower }}.w = {{if not (MaybeUsesPtr $field.Type) }}&{{end}}ma.w.{{ $field | FieldSymbolLower }}.v + ma.ca_{{ $field | FieldSymbolLower }}.m = &ma.w.{{ $field | FieldSymbolLower }}.m + {{if $field.IsNullable }}ma.w.{{ $field | FieldSymbolLower }}.m = allowNull{{end}} + {{- else}} + ma.ca_{{ $field | FieldSymbolLower }}.w = &ma.w.{{ $field | FieldSymbolLower }} + ma.ca_{{ $field | FieldSymbolLower }}.m = &ma.cm + {{- end}} + return &ma.ca_{{ $field | FieldSymbolLower }} + {{- end}} + default: + panic("unreachable") + } + } + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.s & fieldBits__{{ $type | TypeSymbol }}_sufficient != fieldBits__{{ $type | TypeSymbol }}_sufficient { + err := schema.ErrMissingRequiredField{Missing: make([]string, 0)} + {{- range $i, $field := .Type.Fields }} + {{- if not $field.IsMaybe}} + if ma.s & fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} == 0 { + {{- if $field | $type.RepresentationStrategy.FieldHasRename }} + err.Missing = append(err.Missing, "{{ $field.Name }} (serial:\"{{ $field | $type.RepresentationStrategy.GetFieldKey }}\")") + {{- else}} + err.Missing = append(err.Missing, "{{ $field.Name }}") + {{- end}} + } + {{- end}} + {{- end}} + return err + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil + } + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) KeyPrototype() datamodel.NodePrototype { + return _String__Prototype{} + } + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) ValuePrototype(k string) datamodel.NodePrototype { + panic("todo structbuilder mapassembler repr valueprototype") + } + `, w, g.AdjCfg, g) +} +func (g structReprMapReprBuilderGenerator) emitKeyAssembler(w io.Writer) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprKeyAssembler _{{ .Type | TypeSymbol }}__ReprAssembler + `, w, g.AdjCfg, g) + stubs := mixins.StringAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName + ".KeyAssembler", // ".Repr" is already in `g.TypeName`, so don't stutter the "Repr" part. + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__ReprKey", + } + // This key assembler can disregard any idea of complex keys because it's at the representation level! + // Map keys must always be plain strings at the representation level. + stubs.EmitNodeAssemblerMethodBeginMap(w) + stubs.EmitNodeAssemblerMethodBeginList(w) + stubs.EmitNodeAssemblerMethodAssignNull(w) + stubs.EmitNodeAssemblerMethodAssignBool(w) + stubs.EmitNodeAssemblerMethodAssignInt(w) + stubs.EmitNodeAssemblerMethodAssignFloat(w) + doTemplate(` + func (ka *_{{ .Type | TypeSymbol }}__ReprKeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + {{- if .Type.Fields }} + switch k { + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $i, $field := .Type.Fields }} + case "{{ $field | $type.RepresentationStrategy.GetFieldKey }}": + if ka.s & fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} != 0 { + return datamodel.ErrRepeatedMapKey{Key: &fieldName__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }}_serial} + } + ka.s += fieldBit__{{ $type | TypeSymbol }}_{{ $field | FieldSymbolUpper }} + ka.state = maState_expectValue + ka.f = {{ $i }} + return nil + {{- end }} + } + {{- end }} + return schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr", Key:&_String{k}} + } + `, w, g.AdjCfg, g) + stubs.EmitNodeAssemblerMethodAssignBytes(w) + stubs.EmitNodeAssemblerMethodAssignLink(w) + doTemplate(` + func (ka *_{{ .Type | TypeSymbol }}__ReprKeyAssembler) AssignNode(v datamodel.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } + } + func (_{{ .Type | TypeSymbol }}__ReprKeyAssembler) Prototype() datamodel.NodePrototype { + return _String__Prototype{} + } + `, w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprStringjoin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprStringjoin.go new file mode 100644 index 00000000000..cb7025454da --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprStringjoin.go @@ -0,0 +1,241 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &structReprStringjoinGenerator{} + +func NewStructReprStringjoinGenerator(pkgName string, typ *schema.TypeStruct, adjCfg *AdjunctCfg) TypeGenerator { + return structReprStringjoinGenerator{ + structGenerator{ + adjCfg, + mixins.MapTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type structReprStringjoinGenerator struct { + structGenerator +} + +func (g structReprStringjoinGenerator) GetRepresentationNodeGen() NodeGenerator { + return structReprStringjoinReprGenerator{ + g.AdjCfg, + mixins.StringTraits{ + PkgName: g.PkgName, + TypeName: string(g.Type.Name()) + ".Repr", + TypeSymbol: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type structReprStringjoinReprGenerator struct { + AdjCfg *AdjunctCfg + mixins.StringTraits + PkgName string + Type *schema.TypeStruct +} + +func (structReprStringjoinReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g structReprStringjoinReprGenerator) EmitNodeType(w io.Writer) { + // The type is structurally the same, but will have a different set of methods. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} + +func (g structReprStringjoinReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} + +func (g structReprStringjoinReprGenerator) EmitNodeMethodAsString(w io.Writer) { + // Prerequisites: + // - every field must be a string, or have string representation. + // - this should've been checked when compiling the type system info. + // - we're willing to imply a base-10 atoi/itoa for ints (but it's not currently supported). + // - there are NO sanity checks that your value doesn't contain the delimiter + // - you need to do this in validation hooks or some other way + // - optional or nullable fields are not supported with this representation strategy. + // - this should've been checked when compiling the type system info. + // - if support for this is added in the future, you can bet all optionals + // will be required to be *either* in a row at the start, or in a row at the end. + // (a 'direction' property might also be needed, so behavior is defined if every field is optional.) + // + // A speciated String method is also generated here. + // (Organization questionable: if this was at type level, it'd be in the 'EmitNativeAccessors' block, + // but we don't have that in the NodeGenerator interface so we don't have it here. Maybe that's a mistake.) + // + // A String method is *also* generated on the type-level node. + // This might be worth consistency review... + // It's a practical necessity in areas like stringifying for key error messages if used in map keys, for example. + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) AsString() (string, error) { + return n.String(), nil + } + func (n *_{{ .Type | TypeSymbol }}__Repr) String() string { + return {{ "" }} + {{- $type := .Type -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $i, $field := .Type.Fields }} + {{- if $i }} + "{{ $type.RepresentationStrategy.GetDelim }}" + {{end -}} + (*_{{ $field.Type | TypeSymbol }}__Repr)(&n.{{ $field | FieldSymbolLower }}).String() + {{- end}} + } + func (n {{ .Type | TypeSymbol }}) String() string { + return (*_{{ .Type | TypeSymbol }}__Repr)(n).String() + } + `, w, g.AdjCfg, g) +} + +func (g structReprStringjoinReprGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g structReprStringjoinReprGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g structReprStringjoinReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return structReprStringjoinReprBuilderGenerator{ + g.AdjCfg, + mixins.StringAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type structReprStringjoinReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.StringAssemblerTraits + PkgName string + Type *schema.TypeStruct +} + +func (structReprStringjoinReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g structReprStringjoinReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g structReprStringjoinReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) + + // Generate a single-step construction function -- this is easy to do for a scalar, + // and all representations of scalar kind can be expected to have a method like this. + // The function is attached to the NodePrototype for convenient namespacing; + // it needs no new memory, so it would be inappropriate to attach to the builder or assembler. + // The function is directly used internally by anything else that might involve recursive destructuring on the same scalar kind + // (for example, structs using stringjoin strategies that have one of this type as a field, etc). + // Since we're a representation of scalar kind, and can recurse, + // we ourselves presume this plain construction method must also exist for all our members. + // REVIEW: We could make an immut-safe verion of this and export it on the NodePrototype too, as `FromString(string)`. + // FUTURE: should engage validation flow. + doTemplate(` + func (_{{ .Type | TypeSymbol }}__ReprPrototype) fromString(w *_{{ .Type | TypeSymbol }}, v string) error { + ss, err := mixins.SplitExact(v, "{{ .Type.RepresentationStrategy.GetDelim }}", {{ len .Type.Fields }}) + if err != nil { + return schema.ErrUnmatchable{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr", Reason: err} + } + {{- $dot := . -}} {{- /* ranging modifies dot, unhelpfully */ -}} + {{- range $i, $field := .Type.Fields }} + if err := (_{{ $field.Type | TypeSymbol }}__ReprPrototype{}).fromString(&w.{{ $field | FieldSymbolLower }}, ss[{{ $i }}]); err != nil { + return schema.ErrUnmatchable{TypeName:"{{ $dot.PkgName }}.{{ $dot.Type.Name }}.Repr", Reason: err} + } + {{- end}} + return nil + } + `, w, g.AdjCfg, g) +} +func (g structReprStringjoinReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + } + + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() {} + `, w, g.AdjCfg, g) +} +func (g structReprStringjoinReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g) +} +func (g structReprStringjoinReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(w io.Writer) { + // This method contains a branch to support MaybeUsesPtr because new memory may need to be allocated. + // This allocation only happens if the 'w' ptr is nil, which means we're being used on a Maybe; + // otherwise, the 'w' ptr should already be set, and we fill that memory location without allocating, as usual. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) AssignString(v string) error { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = &_{{ .Type | TypeSymbol }}{} + } + {{- end}} + if err := (_{{ .Type | TypeSymbol }}__ReprPrototype{}).fromString(na.w, v); err != nil { + return err + } + *na.m = schema.Maybe_Value + return nil + } + `, w, g.AdjCfg, g) +} + +func (g structReprStringjoinReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + // AssignNode goes through three phases: + // 1. is it null? Jump over to AssignNull (which may or may not reject it). + // 2. is it our own type? Handle specially -- we might be able to do efficient things. + // 3. is it the right kind to morph into us? Do so. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v2, err := v.AsString(); err != nil { + return err + } else { + return na.AssignString(v2) + } + } + `, w, g.AdjCfg, g) +} +func (g structReprStringjoinReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // None for this. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprTuple.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprTuple.go new file mode 100644 index 00000000000..f4a255ffb42 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genStructReprTuple.go @@ -0,0 +1,443 @@ +package gengo + +import ( + "io" + "strconv" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &structReprTupleGenerator{} + +// Optional fields for tuple representation are only allowed at the end, and contiguously. +// Present fields are matched greedily: if the struct has five fields, +// and the last two are optional, and there's four values, then they will be mapped onto the first four fields, period. +// In theory, it would be possible to support a variety of fancier modes, configurably; +// in practice, let's not: the ROI would be atrocious: +// few people seem to want this; +// the implementation complexity would rise dramatically; +// and the next nearest substitutes for such behavior are already available, and cheap (and also sturdier). +// It would make about as much sense to support implicits as it does trailing optionals, +// which means we probably should consider that someday, +// but it's not implemented today. + +func NewStructReprTupleGenerator(pkgName string, typ *schema.TypeStruct, adjCfg *AdjunctCfg) TypeGenerator { + return structReprTupleGenerator{ + structGenerator{ + adjCfg, + mixins.MapTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type structReprTupleGenerator struct { + structGenerator +} + +func (g structReprTupleGenerator) GetRepresentationNodeGen() NodeGenerator { + return structReprTupleReprGenerator{ + g.AdjCfg, + mixins.ListTraits{ + PkgName: g.PkgName, + TypeName: string(g.Type.Name()) + ".Repr", + TypeSymbol: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type structReprTupleReprGenerator struct { + AdjCfg *AdjunctCfg + mixins.ListTraits + PkgName string + Type *schema.TypeStruct +} + +func (structReprTupleReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g structReprTupleReprGenerator) EmitNodeType(w io.Writer) { + // The type is structurally the same, but will have a different set of methods. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} + +func (g structReprTupleReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} + +func (g structReprTupleReprGenerator) EmitNodeMethodLookupByIndex(w io.Writer) { + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) LookupByIndex(idx int64) (datamodel.Node, error) { + switch idx { + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + {{- if $field.IsOptional }} + if n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Absent { + return datamodel.Absent, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfInt(idx)} + } + {{- end}} + {{- if $field.IsNullable }} + if n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Null { + return datamodel.Null, nil + } + {{- end}} + {{- if $field.IsMaybe }} + return n.{{ $field | FieldSymbolLower }}.v.Representation(), nil + {{- else}} + return n.{{ $field | FieldSymbolLower }}.Representation(), nil + {{- end}} + {{- end}} + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfInt(idx)} + } + } + `, w, g.AdjCfg, g) +} + +func (g structReprTupleReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + ki, err := key.AsInt() + if err != nil { + return nil, err + } + return n.LookupByIndex(ki) + } + `, w, g.AdjCfg, g) +} + +func (g structReprTupleReprGenerator) EmitNodeMethodListIterator(w io.Writer) { + // DRY: much of this precalcuation about doneness is common with the map representation. + // (or at least: it is for now: the addition of support for implicits in the map representation may bamboozle that.) + // Some of the templating also experiences the `.HaveTrailingOptionals` branching, + // but not quite as much as the map representation: since we always know those come at the end + // (and in particular, once we hit one absent, we're done!), some simplifications can be made. + + // The 'idx' int is what field we'll yield next. + // Note that this iterator doesn't mention fields that are absent. + // This makes things a bit trickier -- especially the 'Done' predicate, + // since it may have to do lookahead if there's any optionals at the end of the structure! + + // Count how many trailing fields are optional. + // The 'Done' predicate gets more complex when in the trailing optionals. + fields := g.Type.Fields() + fieldCount := len(fields) + beginTrailingOptionalField := fieldCount + for i := fieldCount - 1; i >= 0; i-- { + if !fields[i].IsOptional() { + break + } + beginTrailingOptionalField = i + } + haveTrailingOptionals := beginTrailingOptionalField < fieldCount + + // Now: finally we can get on with the actual templating. + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) ListIterator() datamodel.ListIterator { + {{- if .HaveTrailingOptionals }} + end := {{ len .Type.Fields }}`+ + func() string { // this next part was too silly in templates due to lack of reverse ranging. + v := "\n" + for i := fieldCount - 1; i >= beginTrailingOptionalField; i-- { + v += "\t\t\tif n." + g.AdjCfg.FieldSymbolLower(fields[i]) + ".m == schema.Maybe_Absent {\n" + v += "\t\t\t\tend = " + strconv.Itoa(i) + "\n" + v += "\t\t\t} else {\n" + v += "\t\t\t\tgoto done\n" + v += "\t\t\t}\n" + } + return v + }()+`done: + return &_{{ .Type | TypeSymbol }}__ReprListItr{n, 0, end} + {{- else}} + return &_{{ .Type | TypeSymbol }}__ReprListItr{n, 0} + {{- end}} + } + + type _{{ .Type | TypeSymbol }}__ReprListItr struct { + n *_{{ .Type | TypeSymbol }}__Repr + idx int + {{if .HaveTrailingOptionals }}end int{{end}} + } + + func (itr *_{{ .Type | TypeSymbol }}__ReprListItr) Next() (idx int64, v datamodel.Node, err error) { + if itr.idx >= {{ len .Type.Fields }} { + return -1, nil, datamodel.ErrIteratorOverread{} + } + switch itr.idx { + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + idx = int64(itr.idx) + {{- if $field.IsOptional }} + if itr.n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Absent { + return -1, nil, datamodel.ErrIteratorOverread{} + } + {{- end}} + {{- if $field.IsNullable }} + if itr.n.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Null { + v = datamodel.Null + break + } + {{- end}} + {{- if $field.IsMaybe }} + v = itr.n.{{ $field | FieldSymbolLower}}.v.Representation() + {{- else}} + v = itr.n.{{ $field | FieldSymbolLower}}.Representation() + {{- end}} + {{- end}} + default: + panic("unreachable") + } + itr.idx++ + return + } + {{- if .HaveTrailingOptionals }} + func (itr *_{{ .Type | TypeSymbol }}__ReprListItr) Done() bool { + return itr.idx >= itr.end + } + {{- else}} + func (itr *_{{ .Type | TypeSymbol }}__ReprListItr) Done() bool { + return itr.idx >= {{ len .Type.Fields }} + } + {{- end}} + + `, w, g.AdjCfg, struct { + Type *schema.TypeStruct + HaveTrailingOptionals bool + }{ + g.Type, + haveTrailingOptionals, + }) +} + +func (g structReprTupleReprGenerator) EmitNodeMethodLength(w io.Writer) { + // This is fun: it has to count down for any unset optional fields. + doTemplate(` + func (rn *_{{ .Type | TypeSymbol }}__Repr) Length() int64 { + l := {{ len .Type.Fields }} + {{- range $field := .Type.Fields }} + {{- if $field.IsOptional }} + if rn.{{ $field | FieldSymbolLower }}.m == schema.Maybe_Absent { + l-- + } + {{- end}} + {{- end}} + return int64(l) + } + `, w, g.AdjCfg, g) +} + +func (g structReprTupleReprGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g structReprTupleReprGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g structReprTupleReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return structReprTupleReprBuilderGenerator{ + g.AdjCfg, + mixins.ListAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type structReprTupleReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.ListAssemblerTraits + PkgName string + Type *schema.TypeStruct +} + +func (structReprTupleReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g structReprTupleReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g structReprTupleReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g structReprTupleReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // - 'w' is the "**w**ip" pointer. + // - 'm' is the **m**aybe which communicates our completeness to the parent if we're a child assembler. + // - 'state' is what it says on the tin. this is used for the list state (the broad transitions between null, start-list, and finish are handled by 'm' for consistency with other types). + // - contrasted to the map representation, there's no 's' bitfield for what's been **s**et -- because we know things must procede in order, it would be redundant with 'f'. + // - 'f' is the **f**ocused field that will be assembled next. + // + // - 'cm' is **c**hild **m**aybe and is used for the completion message from children that aren't allowed to be nullable (for those that are, their own maybe.m is used). + // - the 'ca_*' fields embed **c**hild **a**ssemblers -- these are embedded so we can yield pointers to them without causing new allocations. + // + // Note that this textually similar to the type-level assembler, but because it embeds the repr assembler for the child types, + // it might be *significantly* different in size and memory layout in that trailing part of the struct. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state laState + f int + + cm schema.Maybe + {{range $field := .Type.Fields -}} + ca_{{ $field | FieldSymbolLower }} _{{ $field.Type | TypeSymbol }}__ReprAssembler + {{end -}} + } + + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() { + na.state = laState_initial + na.f = 0 + {{- range $field := .Type.Fields }} + na.ca_{{ $field | FieldSymbolLower }}.reset() + {{- end}} + } + `, w, g.AdjCfg, g) +} +func (g structReprTupleReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(w io.Writer) { + // Future: This could do something strict with the sizehint; it currently ignores it. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) BeginList(int64) (datamodel.ListAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = &_{{ .Type | TypeSymbol }}{} + } + {{- end}} + return na, nil + } + `, w, g.AdjCfg, g) +} +func (g structReprTupleReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g structReprTupleReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + emitNodeAssemblerMethodAssignNode_listoid(w, g.AdjCfg, g) +} +func (g structReprTupleReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + g.emitListAssemblerChildTidyHelper(w) + g.emitListAssemblerChildListAssemblerMethods(w) +} +func (g structReprTupleReprBuilderGenerator) emitListAssemblerChildTidyHelper(w io.Writer) { + doTemplate(` + func (la *_{{ .Type | TypeSymbol }}__ReprAssembler) valueFinishTidy() bool { + switch la.f { + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + {{- if $field.IsMaybe }} + switch la.w.{{ $field | FieldSymbolLower }}.m { + case schema.Maybe_Value: + {{- if (MaybeUsesPtr $field.Type) }} + la.w.{{ $field | FieldSymbolLower }}.v = la.ca_{{ $field | FieldSymbolLower }}.w + {{- end}} + la.state = laState_initial + la.f++ + return true + {{- else}} + switch la.cm { + case schema.Maybe_Value: + la.cm = schema.Maybe_Absent + la.state = laState_initial + la.f++ + return true + {{- end}} + {{- if $field.IsNullable }} + case schema.Maybe_Null: + la.state = laState_initial + la.f++ + return true + {{- end}} + default: + return false + } + {{- end}} + default: + panic("unreachable") + } + } + `, w, g.AdjCfg, g) +} +func (g structReprTupleReprBuilderGenerator) emitListAssemblerChildListAssemblerMethods(w io.Writer) { + doTemplate(` + func (la *_{{ .Type | TypeSymbol }}__ReprAssembler) AssembleValue() datamodel.NodeAssembler { + switch la.state { + case laState_initial: + // carry on + case laState_midValue: + if !la.valueFinishTidy() { + panic("invalid state: AssembleValue cannot be called when still in the middle of assembling the previous value") + } // if tidy success: carry on + case laState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + if la.f >= {{ len .Type.Fields }} { + return _ErrorThunkAssembler{schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfInt({{ len .Type.Fields }})}} + } + la.state = laState_midValue + switch la.f { + {{- range $i, $field := .Type.Fields }} + case {{ $i }}: + {{- if $field.IsMaybe }} + la.ca_{{ $field | FieldSymbolLower }}.w = {{if not (MaybeUsesPtr $field.Type) }}&{{end}}la.w.{{ $field | FieldSymbolLower }}.v + la.ca_{{ $field | FieldSymbolLower }}.m = &la.w.{{ $field | FieldSymbolLower }}.m + {{- if $field.IsNullable }} + la.w.{{ $field | FieldSymbolLower }}.m = allowNull + {{- end}} + {{- else}} + la.ca_{{ $field | FieldSymbolLower }}.w = &la.w.{{ $field | FieldSymbolLower }} + la.ca_{{ $field | FieldSymbolLower }}.m = &la.cm + {{- end}} + return &la.ca_{{ $field | FieldSymbolLower }} + {{- end}} + default: + panic("unreachable") + } + } + `, w, g.AdjCfg, g) + // Surprisingly, the Finish method doesn't have anything to do regarding any trailing optionals: + // if they weren't assigned yet, their Maybe state is still the zero value: absent. And that's correct. + // DRY: okay, this finish component is actually identical, both textually and in terms of linking, to lists. This we should actually extract. + doTemplate(` + func (la *_{{ .Type | TypeSymbol }}__ReprAssembler) Finish() error { + switch la.state { + case laState_initial: + // carry on + case laState_midValue: + if !la.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case laState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + la.state = laState_finished + *la.m = schema.Maybe_Value + return nil + } + `, w, g.AdjCfg, g) + doTemplate(` + func (la *_{{ .Type | TypeSymbol }}__ReprAssembler) ValuePrototype(_ int64) datamodel.NodePrototype { + panic("todo structbuilder tuplerepr valueprototype") + } + `, w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnion.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnion.go new file mode 100644 index 00000000000..a185bbfdf64 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnion.go @@ -0,0 +1,661 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +// The generator for unions is a bit more wild than most others: +// it has at three major branches for how its internals are laid out: +// +// - all possible children are embedded. +// - all possible children are pointers... in which case we collapse to one interface resident. +// (n.b. this does give up some inlining potential as well as gives up on alloc amortization, but it does make resident memory size minimal.) +// - some children are emebedded and some are pointers, and of the latter set, they may be either in one interface field or several discrete pointers. +// (discrete fields of pointer type makes inlining possible in some paths, whereas an interface field blocks it). +// +// ... We're not doing that last one at all right now. The pareto-prevalence of these concerns is extremely low compared to the effort required. +// But the first two are both very reasonable, and both are often wanted. +// +// These choices are made from adjunct config (which should make sense, because they're clearly all "golang" details -- not type semantics). +// We still tackle all the generation for all these strategies this in one file, +// because all of the interfaces we export are the same, regardless of the internals (and it just seems easiest to do this way). + +type unionGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapTraits + PkgName string + Type *schema.TypeUnion +} + +func (unionGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +// --- native content and specializations ---> + +func (g unionGenerator) EmitNativeType(w io.Writer) { + // We generate *two* types: a struct which acts as the union node, + // and also an interface which covers the members (and has an unexported marker function to make sure the set can't be extended). + // + // The interface *mostly* isn't used... except for in the return type of a speciated function which can be used to do golang-native type switches. + // + // The interface also includes a requirement for an errorless primitive access method (such as `String() string`) + // if our representation strategy is one that has that semantic (e.g., stringprefix repr does). + // + // A note about index: in all cases the index of a member type is used, we increment it by one, to avoid using zero. + // We do this because it's desirable to reserve the zero in the 'tag' field (if we generate one) as a sentinel value + // (see further comments in the EmitNodeAssemblerType function); + // and since we do it in that one case, it's just as well to do it uniformly. + doTemplate(` + {{- if Comments -}} + // {{ .Type | TypeSymbol }} matches the IPLD Schema type "{{ .Type.Name }}". + // {{ .Type | TypeSymbol }} has {{ .Type.TypeKind }} typekind, which means its data model behaviors are that of a {{ .Kind }} kind. + {{- end}} + type {{ .Type | TypeSymbol }} = *_{{ .Type | TypeSymbol }} + type _{{ .Type | TypeSymbol }} struct { + {{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }} + tag uint + {{- range $i, $member := .Type.Members }} + x{{ add $i 1 }} _{{ $member | TypeSymbol }} + {{- end}} + {{- else if (eq (.AdjCfg.UnionMemlayout .Type) "interface") }} + x _{{ .Type | TypeSymbol }}__iface + {{- end}} + } + type _{{ .Type | TypeSymbol }}__iface interface { + _{{ .Type | TypeSymbol }}__member() + {{- if (eq (.Type.RepresentationStrategy | printf "%T") "schema.UnionRepresentation_Stringprefix") }} + String() string + {{- end}} + } + + {{- range $member := .Type.Members }} + func (_{{ $member | TypeSymbol }}) _{{ dot.Type | TypeSymbol }}__member() {} + {{- end}} + `, w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNativeAccessors(w io.Writer) { + doTemplate(` + func (n _{{ .Type | TypeSymbol }}) AsInterface() _{{ .Type | TypeSymbol }}__iface { + {{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }} + switch n.tag { + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + return &n.x{{ add $i 1 }} + {{- end}} + default: + panic("invalid union state; how did you create this object?") + } + {{- else if (eq (.AdjCfg.UnionMemlayout .Type) "interface") }} + return n.x + {{- end}} + } + `, w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNativeBuilder(w io.Writer) { + // Unclear as yet what should go here. +} + +func (g unionGenerator) EmitNativeMaybe(w io.Writer) { + emitNativeMaybe(w, g.AdjCfg, g) +} + +// --- type info ---> + +func (g unionGenerator) EmitTypeConst(w io.Writer) { + doTemplate(` + // TODO EmitTypeConst + `, w, g.AdjCfg, g) +} + +// --- TypedNode interface satisfaction ---> + +func (g unionGenerator) EmitTypedNodeMethodType(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Type() schema.Type { + return nil /*TODO:typelit*/ + } + `, w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitTypedNodeMethodRepresentation(w io.Writer) { + emitTypicalTypedNodeMethodRepresentation(w, g.AdjCfg, g) +} + +// --- Node interface satisfaction ---> + +func (g unionGenerator) EmitNodeType(w io.Writer) { + // No additional types needed. Methods all attach to the native type. + + // We do, however, want some constants for our member names; + // they'll make iterators able to work faster. So let's emit those. + // These are a bit perplexing, because they're... type names. + // However, oddly enough, we don't have type names available *as nodes* anywhere else centrally available, + // so... we generate some values for them here with scoped identifers and get on with it. + // Maybe this could be elided with future work. + doTemplate(` + var ( + {{- range $member := .Type.Members }} + memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }} = _String{"{{ $member.Name }}"} + {{- end }} + ) + `, w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNodeTypeAssertions(w io.Writer) { + emitNodeTypeAssertions_typical(w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNodeMethodLookupByString(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) LookupByString(key string) (datamodel.Node, error) { + switch key { + {{- range $i, $member := .Type.Members }} + case "{{ $member.Name }}": + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + if n.tag != {{ add $i 1 }} { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} + } + return &n.x{{ add $i 1 }}, nil + {{- else if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }} + if n2, ok := n.x.({{ $member | TypeSymbol }}); ok { + return n2, nil + } else { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} + } + {{- end}} + {{- end}} + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfString(key)} + } + } + `, w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) + } + `, w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNodeMethodMapIterator(w io.Writer) { + // This is kind of a hilarious "iterator": it has to count all the way up to... 1. + doTemplate(` + func (n {{ .Type | TypeSymbol }}) MapIterator() datamodel.MapIterator { + return &_{{ .Type | TypeSymbol }}__MapItr{n, false} + } + + type _{{ .Type | TypeSymbol }}__MapItr struct { + n {{ .Type | TypeSymbol }} + done bool + } + + func (itr *_{{ .Type | TypeSymbol }}__MapItr) Next() (k datamodel.Node, v datamodel.Node, _ error) { + if itr.done { + return nil, nil, datamodel.ErrIteratorOverread{} + } + {{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }} + switch itr.n.tag { + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + k, v = &memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }}, &itr.n.x{{ add $i 1 }} + {{- end}} + {{- else if (eq (.AdjCfg.UnionMemlayout .Type) "interface") }} + switch n2 := itr.n.x.(type) { + {{- range $member := .Type.Members }} + case {{ $member | TypeSymbol }}: + k, v = &memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }}, n2 + {{- end}} + {{- end}} + default: + panic("unreachable") + } + itr.done = true + return + } + func (itr *_{{ .Type | TypeSymbol }}__MapItr) Done() bool { + return itr.done + } + + `, w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNodeMethodLength(w io.Writer) { + doTemplate(` + func ({{ .Type | TypeSymbol }}) Length() int64 { + return 1 + } + `, w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g unionGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g unionGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return unionBuilderGenerator{ + g.AdjCfg, + mixins.MapAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__", + }, + g.PkgName, + g.Type, + } +} + +type unionBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapAssemblerTraits + PkgName string + Type *schema.TypeUnion +} + +func (unionBuilderGenerator) IsRepr() bool { return false } // hint used in some generalized templates. + +func (g unionBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g unionBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g unionBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Assemblers for unions are not unlikely those for structs or maps: + // + // - 'w' is the "**w**ip" pointer. + // - 'm' is the pointer to a **m**aybe which communicates our completeness to the parent if we're a child assembler. + // Like any other structure, a union can be nullable in the context of some enclosing object, and we'll have the usual branches for handling that in our various Assign methods. + // - 'state' is what it says on the tin. Unions use maState to sequence the transitions between a new assembler, the map having been started, key insertions, value insertions, and finish. + // Most of this is just like the way struct and map use maState. + // However, we also need to guard to make sure a second entry never begins; after the first, finish is the *only* valid transition. + // In structs, this is done using the "set" bitfield; in maps, the state resides in the wip map itself. + // Unions are more like the latter: depending on which memory layout we're using, either the `na.w.tag` value, or, a non-nil `na.w.x`, is indicative that one key has been entered. + // (The zero value for `na.w.tag` is reserved, and all for this reason. + // - There is no additional state need to store "focus" (in contrast to structs); + // information during the AssembleValue phase about which member is selected is also just handled in `na.w.tag`, or, in the type info of `na.w.x`, again depending on memory layout strategy. + // (This is subverted a bit by the 'ca' field, however... which effectively mirrors `na.w.tag`, and is only active in the resetting process, but is necessary because it outlives its twin inside 'w'.) + // + // - 'cm' is **c**hild **m**aybe and is used for the completion message from children. + // - 'ca*' fields embed **c**hild **a**ssemblers -- these are embedded so we can yield pointers to them during recusion into child value assembly without causing new allocations. + // In unions, only one of these will every be used! However, we don't know *which one* in advance, so, we have to embed them all. + // (It's ironic to note that if the golang compiler had an understanding of unions itself (either tagged or untagged would suffice), we could compile this down into *much* more minimal amounts of resident memory reservation. Alas!) + // The 'ca*' fields are pointers (and allocated on demand) instead of embeds for unions with memlayout=interface mode. (Arguably, this is overloading that config; PRs for more granular configurability welcome.) + // - 'ca' (with no further suffix) identifies which child assembler was previously used. + // This is for minimizing the amount of work that resetting has to do: it will only recurse into resetting that child assembler. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Assembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state maState + + cm schema.Maybe + {{- range $i, $member := .Type.Members }} + ca{{ add $i 1 }} {{ if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }}*{{end}}_{{ $member | TypeSymbol }}__Assembler + {{end -}} + ca uint + } + `, w, g.AdjCfg, g) + + // Reset methods for unions are a tad more involved than for most other assemblers: + // we only want to bother to reset whichever child assembler (if any) we actually used last. + // We *could* blithely reset *all* child assemblers every time; but, trading an extra bit of state in our assembler + // for the privledge of trimming off a potentially sizable amount of unnecessary zeroing efforts seems preferrable. + // Also, although go syntax makes it not textually obvious here, note that it's possible for the child assemblers to be either pointers or embeds: + // on consequence of this is that just zeroing this struct would be both unreliable and undesirable in the pointer case + // (it would leave orphan child assemblers that might still have pointers into us, which could be guarded against but is nonetheless is considerably scary in complexity; + // and it would also mean that we can't keep ahold of the child assemblers across resets and thus amortize allocations, which... is the whole reason the reset system exists in the first place). + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__Assembler) reset() { + na.state = maState_initial + switch na.ca { + case 0: + return + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + na.ca{{ add $i 1 }}.reset() + {{end -}} + default: + panic("unreachable") + } + na.ca = 0 + na.cm = schema.Maybe_Absent + } + `, w, g.AdjCfg, g) +} +func (g unionBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + emitNodeAssemblerMethodBeginMap_strictoid(w, g.AdjCfg, g) +} +func (g unionBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + // It might sound a bit odd to call a union "recursive", since it's so very trivially so (no fan-out), + // but it's functionally accurate: the generated method should include a branch for the 'midvalue' state. + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g unionBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + // AssignNode goes through three phases: + // 1. is it null? Jump over to AssignNull (which may or may not reject it). + // 2. is it our own type? Handle specially -- we might be able to do efficient things. + // 3. is it the right kind to morph into us? Do so. + // + // We do not set m=midvalue in phase 3 -- it shouldn't matter unless you're trying to pull off concurrent access, which is wrong and unsafe regardless. + // + // DRY: this turns out to be textually identical to the method for structs! (At least, for now. It could/should probably be optimized to get to the point faster in phase 3.) + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != datamodel.Kind_Map { + return datamodel.ErrWrongKind{TypeName: "{{ .PkgName }}.{{ .Type.Name }}", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() + } + `, w, g.AdjCfg, g) +} +func (g unionBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + g.emitMapAssemblerChildTidyHelper(w) + g.emitMapAssemblerMethods(w) + g.emitKeyAssembler(w) +} +func (g unionBuilderGenerator) emitMapAssemblerChildTidyHelper(w io.Writer) { + // This function attempts to clean up the state machine to acknolwedge child assembly finish. + // If the child was finished and we just collected it, return true and update state to maState_initial. + // Otherwise, if it wasn't done, return false; + // and the caller is almost certain to emit an error momentarily. + // The function will only be called when the current state is maState_midValue. + // (In general, the idea is that if the user is doing things correctly, + // this function will only be called when the child is in fact finished.) + // This is a *lot* simpler than the tidy behaviors needed for any of the other recursive kinds: + // unions don't allow either nullable nor optional members, so there's no need to process anything except Maybe_Value state, + // and the lack of need to consider nullable nor optionals also means we never need to worry about moving memory in the case of MaybeUsePtr modes. + // (FUTURE: this may get a bit more conditional if we support members that are of unit ype and have null as a representation. Unsure how that would work out exactly, but should be possible.) + // We don't bother to nil the child assembler's 'w' pointer: it's not necessary, + // because we'll never "share" 'cm' (as some systems, like maps and lists, do) or change its value (short of the whole assembler resetting), + // and therefore we should be able to rely on the child assembler to be reasonable and never start acting again after finish. + // (This *does* mean some care is required in the reset logic: we have to be absolutely sure that resetting propagates to all child assemblers, + // even if they're in other regions of the heap; otherwise, they might end up still holding actionable 'w' and 'm' pointers into bad times!) + // (If you want to compare this to the logic in struct assemblers: it's similar to how only children that don't have maybes need an active 'w' nil'ing; + // but the salient reason there isn't "because the don't have maybes"; it's "because they have a potentially-reused 'cm'". We don't have the former; but we *also* don't have the latter, for other reasons.) + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__Assembler) valueFinishTidy() bool { + switch ma.cm { + case schema.Maybe_Value: + {{- /* nothing to do for memlayout=embedAll; the tag is already set and memory already in place. */ -}} + {{- /* nothing to do for memlayout=interface either; same story, the values are already in place. */ -}} + ma.state = maState_initial + return true + default: + return false + } + } + `, w, g.AdjCfg, g) +} +func (g unionBuilderGenerator) emitMapAssemblerMethods(w io.Writer) { + // DRY: I did an interesting thing here: the `switch ma.state` block remains textually identical to the one for structs, + // even though the branch by valueFinishTidy could jump directly to an error state. + // That same semantic error state gets checked separately a few lines later in a different mechanism. + // The later check is needed either way (the assembler needs to *keep* erroring if some derp calls AssembleEntry *again* after a previous call already did the tidy and got rejected), + // but we could arguably save a step there. It would probably trade more assembly size for the cycles saved, too, though. + // Ah, tradeoffs. I think the textually simple approach here is probably in fact the best. But it could be done differently, yes. + // Note that calling AssembleEntry again when it's not for the first entry *returns* an error; it doesn't panic. + // This is subtle but important: trying to add more data than is acceptable is a data mismatch, not a system misuse, and must error accordingly politely. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__Assembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on for the moment, but we'll still be erroring shortly. + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + if ma.ca != 0 { + return nil, schema.ErrNotUnionStructure{TypeName:"{{ .PkgName }}.{{ .Type.Name }}", Detail: "cannot add another entry -- a union can only contain one thing!"} + } + {{- if .Type.Members }} + switch k { + {{- range $i, $member := .Type.Members }} + case "{{ $member.Name }}": + ma.state = maState_midValue + ma.ca = {{ add $i 1 }} + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + ma.w.tag = {{ add $i 1 }} + ma.ca{{ add $i 1 }}.w = &ma.w.x{{ add $i 1 }} + ma.ca{{ add $i 1 }}.m = &ma.cm + return &ma.ca{{ add $i 1 }}, nil + {{- else if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }} + x := &_{{ $member | TypeSymbol}}{} + ma.w.x = x + if ma.ca{{ add $i 1 }} == nil { + ma.ca{{ add $i 1 }} = &_{{ $member | TypeSymbol }}__Assembler{} + } + ma.ca{{ add $i 1 }}.w = x + ma.ca{{ add $i 1 }}.m = &ma.cm + return ma.ca{{ add $i 1 }}, nil + {{- end}} + {{- end}} + {{- end}} + } + return nil, schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}", Key:&_String{k}} + } + `, w, g.AdjCfg, g) + + // AssembleKey has a similar DRY note as the AssembleEntry above had. + // One misfortune in this method: we may know that we're doomed to errors because the caller is trying to start a second entry, + // but we can't report it from this method: we have to sit on our tongue, slide to midKey state (even though we're doomed!), + // and let the keyAssembler return the error later. + // This sucks, but panicking wouldn't be correct (see remarks about error vs panic on the AssembleEntry method), + // and we don't want to make this call unchainable for everyone everywhere, either, so it can't be rewritten to have an immmediate error return. + // The transition to midKey state is particularly irritating because it means this assembler will be perma-wedged; but I see no alternative. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__Assembler) AssembleKey() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on for the moment, but we'll still be erroring shortly... or rather, the keyassembler will be. + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_{{ .Type | TypeSymbol }}__KeyAssembler)(ma) + } + `, w, g.AdjCfg, g) + + // As with structs, the responsibilties of this are similar to AssembleEntry, but with some of the burden split into the key assembler (which should have acted earlier), + // and some of the logical continuity bounces through state in the form of 'ma.ca'. + // The potential to DRY up some of this should be plentiful, but it's a bit heady. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__Assembler) AssembleValue() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.ca { + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + ma.ca{{ add $i 1 }}.w = &ma.w.x{{ add $i 1 }} + ma.ca{{ add $i 1 }}.m = &ma.cm + return &ma.ca{{ add $i 1 }} + {{- else if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }} + x := &_{{ $member | TypeSymbol}}{} + ma.w.x = x + if ma.ca{{ add $i 1 }} == nil { + ma.ca{{ add $i 1 }} = &_{{ $member | TypeSymbol }}__Assembler{} + } + ma.ca{{ add $i 1 }}.w = x + ma.ca{{ add $i 1 }}.m = &ma.cm + return ma.ca{{ add $i 1 }} + {{- end}} + {{- end}} + default: + panic("unreachable") + } + } + `, w, g.AdjCfg, g) + + // Finish checks are nice and easy. Is the maState in the right place now and was a 'ca' ever marked? + // If yes and yes, then together with the rules elsewhere, we must've processed and accepted exactly one entry; perfect. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__Assembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.ca == 0 { + return schema.ErrNotUnionStructure{TypeName:"{{ .PkgName }}.{{ .Type.Name }}", Detail: "a union must have exactly one entry (not none)!"} + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil + } + `, w, g.AdjCfg, g) + + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__Assembler) KeyPrototype() datamodel.NodePrototype { + return _String__Prototype{} + } + func (ma *_{{ .Type | TypeSymbol }}__Assembler) ValuePrototype(k string) datamodel.NodePrototype { + switch k { + {{- range $i, $member := .Type.Members }} + case "{{ $member.Name }}": + return _{{ $member | TypeSymbol }}__Prototype{} + {{- end}} + default: + return nil + } + } + `, w, g.AdjCfg, g) +} +func (g unionBuilderGenerator) emitKeyAssembler(w io.Writer) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__KeyAssembler _{{ .Type | TypeSymbol }}__Assembler + `, w, g.AdjCfg, g) + stubs := mixins.StringAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName + ".KeyAssembler", + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Key", + } + // This key assembler can disregard any idea of complex keys because we're fronting for a union! + // Union member names must be strings (and quite simple ones at that). + stubs.EmitNodeAssemblerMethodBeginMap(w) + stubs.EmitNodeAssemblerMethodBeginList(w) + stubs.EmitNodeAssemblerMethodAssignNull(w) + stubs.EmitNodeAssemblerMethodAssignBool(w) + stubs.EmitNodeAssemblerMethodAssignInt(w) + stubs.EmitNodeAssemblerMethodAssignFloat(w) + doTemplate(` + func (ka *_{{ .Type | TypeSymbol }}__KeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + if ka.ca != 0 { + return schema.ErrNotUnionStructure{TypeName:"{{ .PkgName }}.{{ .Type.Name }}", Detail: "cannot add another entry -- a union can only contain one thing!"} + } + switch k { + {{- range $i, $member := .Type.Members }} + case "{{ $member.Name }}": + ka.ca = {{ add $i 1 }} + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + ka.w.tag = {{ add $i 1 }} + {{- end}} + ka.state = maState_expectValue + return nil + {{- end}} + } + return schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}", Key:&_String{k}} // TODO: error quality: ErrInvalidUnionDiscriminant ? + } + `, w, g.AdjCfg, g) + stubs.EmitNodeAssemblerMethodAssignBytes(w) + stubs.EmitNodeAssemblerMethodAssignLink(w) + doTemplate(` + func (ka *_{{ .Type | TypeSymbol }}__KeyAssembler) AssignNode(v datamodel.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } + } + func (_{{ .Type | TypeSymbol }}__KeyAssembler) Prototype() datamodel.NodePrototype { + return _String__Prototype{} + } + `, w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprKeyed.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprKeyed.go new file mode 100644 index 00000000000..c2af0253263 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprKeyed.go @@ -0,0 +1,522 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &unionReprKeyedGenerator{} + +// General observation: many things about the keyed representation of unions is *very* similar to the type-level code, +// because the type level code effective does espouse keyed-style behavior (just with type names as the keys). +// Be advised that this similarity does not hold at *all* true of any of the other representation modes of unions! + +func NewUnionReprKeyedGenerator(pkgName string, typ *schema.TypeUnion, adjCfg *AdjunctCfg) TypeGenerator { + return unionReprKeyedGenerator{ + unionGenerator{ + adjCfg, + mixins.MapTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type unionReprKeyedGenerator struct { + unionGenerator +} + +func (g unionReprKeyedGenerator) GetRepresentationNodeGen() NodeGenerator { + return unionReprKeyedReprGenerator{ + g.AdjCfg, + mixins.MapTraits{ + PkgName: g.PkgName, + TypeName: string(g.Type.Name()) + ".Repr", + TypeSymbol: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type unionReprKeyedReprGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapTraits + PkgName string + Type *schema.TypeUnion +} + +func (unionReprKeyedReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g unionReprKeyedReprGenerator) EmitNodeType(w io.Writer) { + // The type is structurally the same, but will have a different set of methods. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) + + // We do also want some constants for our discriminant values; + // they'll make iterators able to work faster. + doTemplate(` + var ( + {{- range $member := .Type.Members }} + memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }}_serial = _String{"{{ $member | dot.Type.RepresentationStrategy.GetDiscriminant }}"} + {{- end }} + ) + `, w, g.AdjCfg, g) +} + +func (g unionReprKeyedReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} + +func (g unionReprKeyedReprGenerator) EmitNodeMethodLookupByString(w io.Writer) { + // Similar to the type-level method, except uses discriminant values as keys instead of the member type names. + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) LookupByString(key string) (datamodel.Node, error) { + switch key { + {{- range $i, $member := .Type.Members }} + case "{{ $member | dot.Type.RepresentationStrategy.GetDiscriminant }}": + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + if n.tag != {{ add $i 1 }} { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} + } + return n.x{{ add $i 1 }}.Representation(), nil + {{- else if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }} + if n2, ok := n.x.({{ $member | TypeSymbol }}); ok { + return n2.Representation(), nil + } else { + return nil, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfString(key)} + } + {{- end}} + {{- end}} + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfString(key)} + } + } + `, w, g.AdjCfg, g) +} + +func (g unionReprKeyedReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) + } + `, w, g.AdjCfg, g) +} + +func (g unionReprKeyedReprGenerator) EmitNodeMethodMapIterator(w io.Writer) { + // Similar to the type-level method, except yields discriminant values as keys instead of the member type names. + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) MapIterator() datamodel.MapIterator { + return &_{{ .Type | TypeSymbol }}__ReprMapItr{n, false} + } + + type _{{ .Type | TypeSymbol }}__ReprMapItr struct { + n *_{{ .Type | TypeSymbol }}__Repr + done bool + } + + func (itr *_{{ .Type | TypeSymbol }}__ReprMapItr) Next() (k datamodel.Node, v datamodel.Node, _ error) { + if itr.done { + return nil, nil, datamodel.ErrIteratorOverread{} + } + {{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }} + switch itr.n.tag { + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + k, v = &memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }}_serial, itr.n.x{{ add $i 1 }}.Representation() + {{- end}} + {{- else if (eq (.AdjCfg.UnionMemlayout .Type) "interface") }} + switch n2 := itr.n.x.(type) { + {{- range $member := .Type.Members }} + case {{ $member | TypeSymbol }}: + k, v = &memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }}_serial, n2.Representation() + {{- end}} + {{- end}} + default: + panic("unreachable") + } + itr.done = true + return + } + func (itr *_{{ .Type | TypeSymbol }}__ReprMapItr) Done() bool { + return itr.done + } + + `, w, g.AdjCfg, g) +} + +func (g unionReprKeyedReprGenerator) EmitNodeMethodLength(w io.Writer) { + doTemplate(` + func (_{{ .Type | TypeSymbol }}__Repr) Length() int64 { + return 1 + } + `, w, g.AdjCfg, g) +} + +func (g unionReprKeyedReprGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g unionReprKeyedReprGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g unionReprKeyedReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return unionReprKeyedReprBuilderGenerator{ + g.AdjCfg, + mixins.MapAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type unionReprKeyedReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.MapAssemblerTraits + PkgName string + Type *schema.TypeUnion +} + +func (unionReprKeyedReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g unionReprKeyedReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g unionReprKeyedReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g unionReprKeyedReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Nearly identical to the type-level system, except it embeds the Repr variant of child assemblers + // (which is a very minor difference textually, but means this structure can end up with a pretty wildly different resident memory size than the type-level one). + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + state maState + + cm schema.Maybe + {{- range $i, $member := .Type.Members }} + ca{{ add $i 1 }} {{ if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }}*{{end}}_{{ $member | TypeSymbol }}__ReprAssembler + {{end -}} + ca uint + } + `, w, g.AdjCfg, g) + + // Reset methods: also nearly identical to the type-level ones. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() { + na.state = maState_initial + switch na.ca { + case 0: + return + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + na.ca{{ add $i 1 }}.reset() + {{end -}} + default: + panic("unreachable") + } + na.ca = 0 + na.cm = schema.Maybe_Absent + } + `, w, g.AdjCfg, g) +} +func (g unionReprKeyedReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + emitNodeAssemblerMethodBeginMap_strictoid(w, g.AdjCfg, g) +} +func (g unionReprKeyedReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + // It might sound a bit odd to call a union "recursive", since it's so very trivially so (no fan-out), + // but it's functionally accurate: the generated method should include a branch for the 'midvalue' state. + emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g) +} +func (g unionReprKeyedReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + // DRY: this is once again not-coincidentally very nearly equal to the type-level method. Would be good to dedup them... after we do the get-to-the-point-in-phase-3 improvement. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != datamodel.Kind_Map { + return datamodel.ErrWrongKind{TypeName: "{{ .PkgName }}.{{ .Type.Name }}.Repr", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() + } + `, w, g.AdjCfg, g) +} +func (g unionReprKeyedReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + g.emitMapAssemblerChildTidyHelper(w) + g.emitMapAssemblerMethods(w) + g.emitKeyAssembler(w) +} +func (g unionReprKeyedReprBuilderGenerator) emitMapAssemblerChildTidyHelper(w io.Writer) { + // Nearly identical to the type-level equivalent. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) valueFinishTidy() bool { + switch ma.cm { + case schema.Maybe_Value: + {{- /* nothing to do for memlayout=embedAll; the tag is already set and memory already in place. */ -}} + {{- /* nothing to do for memlayout=interface either; same story, the values are already in place. */ -}} + ma.state = maState_initial + return true + default: + return false + } + } + `, w, g.AdjCfg, g) +} +func (g unionReprKeyedReprBuilderGenerator) emitMapAssemblerMethods(w io.Writer) { + // All of these: shamelessly similar to the type-level equivalent, modulo a few appearances of "Repr". + // Alright, and also the "discriminant values as keys instead of the member type names" thing. + // DRY: the number of times these `ma.state` switches are appearing is truly intense! This is starting to look like one of them most important things to shrink the GSLOC/ASM size of! + + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on for the moment, but we'll still be erroring shortly. + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + if ma.ca != 0 { + return nil, schema.ErrNotUnionStructure{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr", Detail: "cannot add another entry -- a union can only contain one thing!"} + } + {{- if .Type.Members }} + switch k { + {{- range $i, $member := .Type.Members }} + case "{{ $member | dot.Type.RepresentationStrategy.GetDiscriminant }}": + ma.state = maState_midValue + ma.ca = {{ add $i 1 }} + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + ma.w.tag = {{ add $i 1 }} + ma.ca{{ add $i 1 }}.w = &ma.w.x{{ add $i 1 }} + ma.ca{{ add $i 1 }}.m = &ma.cm + return &ma.ca{{ add $i 1 }}, nil + {{- else if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }} + x := &_{{ $member | TypeSymbol }}{} + ma.w.x = x + if ma.ca{{ add $i 1 }} == nil { + ma.ca{{ add $i 1 }} = &_{{ $member | TypeSymbol }}__ReprAssembler{} + } + ma.ca{{ add $i 1 }}.w = x + ma.ca{{ add $i 1 }}.m = &ma.cm + return ma.ca{{ add $i 1 }}, nil + {{- end}} + {{- end}} + } + {{- end}} + return nil, schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr", Key:&_String{k}} + } + `, w, g.AdjCfg, g) + + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) AssembleKey() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on for the moment, but we'll still be erroring shortly... or rather, the keyassembler will be. + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_{{ .Type | TypeSymbol }}__ReprKeyAssembler)(ma) + } + `, w, g.AdjCfg, g) + + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) AssembleValue() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.ca { + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + ma.ca{{ add $i 1 }}.w = &ma.w.x{{ add $i 1 }} + ma.ca{{ add $i 1 }}.m = &ma.cm + return &ma.ca{{ add $i 1 }} + {{- else if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }} + x := &_{{ $member | TypeSymbol }}{} + ma.w.x = x + if ma.ca{{ add $i 1 }} == nil { + ma.ca{{ add $i 1 }} = &_{{ $member | TypeSymbol }}__ReprAssembler{} + } + ma.ca{{ add $i 1 }}.w = x + ma.ca{{ add $i 1 }}.m = &ma.cm + return ma.ca{{ add $i 1 }} + {{- end}} + {{- end}} + default: + panic("unreachable") + } + } + `, w, g.AdjCfg, g) + + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.ca == 0 { + return schema.ErrNotUnionStructure{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr", Detail: "a union must have exactly one entry (not none)!"} + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil + } + `, w, g.AdjCfg, g) + + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) KeyPrototype() datamodel.NodePrototype { + return _String__Prototype{} + } + func (ma *_{{ .Type | TypeSymbol }}__ReprAssembler) ValuePrototype(k string) datamodel.NodePrototype { + switch k { + {{- range $i, $member := .Type.Members }} + case "{{ $member.Name }}": + return _{{ $member | TypeSymbol }}__ReprPrototype{} + {{- end}} + default: + return nil + } + } + `, w, g.AdjCfg, g) +} +func (g unionReprKeyedReprBuilderGenerator) emitKeyAssembler(w io.Writer) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprKeyAssembler _{{ .Type | TypeSymbol }}__ReprAssembler + `, w, g.AdjCfg, g) + stubs := mixins.StringAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName + ".KeyAssembler", // ".Repr" is already in `g.TypeName`, so don't stutter the "Repr" part. + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__ReprKey", + } + // This key assembler can disregard any idea of complex keys because we know that our discriminants are just strings! + stubs.EmitNodeAssemblerMethodBeginMap(w) + stubs.EmitNodeAssemblerMethodBeginList(w) + stubs.EmitNodeAssemblerMethodAssignNull(w) + stubs.EmitNodeAssemblerMethodAssignBool(w) + stubs.EmitNodeAssemblerMethodAssignInt(w) + stubs.EmitNodeAssemblerMethodAssignFloat(w) + doTemplate(` + func (ka *_{{ .Type | TypeSymbol }}__ReprKeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + if ka.ca != 0 { + return schema.ErrNotUnionStructure{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr", Detail: "cannot add another entry -- a union can only contain one thing!"} + } + switch k { + {{- range $i, $member := .Type.Members }} + case "{{ $member | dot.Type.RepresentationStrategy.GetDiscriminant }}": + ka.ca = {{ add $i 1 }} + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + ka.w.tag = {{ add $i 1 }} + {{- end}} + ka.state = maState_expectValue + return nil + {{- end}} + } + return schema.ErrInvalidKey{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr", Key:&_String{k}} // TODO: error quality: ErrInvalidUnionDiscriminant ? + } + `, w, g.AdjCfg, g) + stubs.EmitNodeAssemblerMethodAssignBytes(w) + stubs.EmitNodeAssemblerMethodAssignLink(w) + doTemplate(` + func (ka *_{{ .Type | TypeSymbol }}__ReprKeyAssembler) AssignNode(v datamodel.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } + } + func (_{{ .Type | TypeSymbol }}__ReprKeyAssembler) Prototype() datamodel.NodePrototype { + return _String__Prototype{} + } + `, w, g.AdjCfg, g) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprKinded.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprKinded.go new file mode 100644 index 00000000000..6fe32f1a213 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprKinded.go @@ -0,0 +1,645 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &unionKindedGenerator{} + +// Kinded union representations are quite wild: their behavior varies almost completely per inhabitant, +// and their implementation is generally delegating directly to something else, +// rather than having an intermediate node (like most unions do, and like the type-level view of this same value will). +// +// This also means any error values can be a little weird: +// sometimes they'll have the union's type name, but sometimes they'll have the inhabitant's type name instead; +// this depends on whether the error is an ErrWrongKind that was found while checking the method for appropriateness on the union's inhabitant +// versus if the error came from the union inhabitant itself after delegation occured. + +func NewUnionReprKindedGenerator(pkgName string, typ *schema.TypeUnion, adjCfg *AdjunctCfg) TypeGenerator { + return unionKindedGenerator{ + unionGenerator{ + adjCfg, + mixins.MapTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + pkgName, + typ, + }, + } +} + +type unionKindedGenerator struct { + unionGenerator +} + +func (g unionKindedGenerator) GetRepresentationNodeGen() NodeGenerator { + return unionKindedReprGenerator{ + g.AdjCfg, + g.PkgName, + g.Type, + } +} + +type unionKindedReprGenerator struct { + // Note that there's no MapTraits (or any other FooTraits) mixin in this one! + // This is no accident: *None* of them apply! + + AdjCfg *AdjunctCfg + PkgName string + Type *schema.TypeUnion +} + +func (unionKindedReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g unionKindedReprGenerator) EmitNodeType(w io.Writer) { + // The type is structurally the same, but will have a different set of methods. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) Kind() datamodel.Kind { + {{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }} + switch n.tag { + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + return {{ $member.RepresentationBehavior | KindSymbol }} + {{- end}} + {{- else if (eq (.AdjCfg.UnionMemlayout .Type) "interface") }} + switch n.x.(type) { + {{- range $i, $member := .Type.Members }} + case {{ $member | TypeSymbol }}: + return {{ $member.RepresentationBehavior | KindSymbol }} + {{- end}} + {{- end}} + default: + panic("unreachable") + } + } + `, w, g.AdjCfg, g) +} + +func kindedUnionNodeMethodTemplateMunge( + methodName string, // for error messages + methodSig string, // output literally + someSwitchClause string, // template condition for if *any* switch clause should be present + condClause string, // template condition for the member this should match on when in the range + retClause string, // clause returning the thing (how to delegate methodsig, generally) + appropriateKind string, // for error messages + nopeSentinel string, // for error return paths; generally the zero value for the first return type. + nopeSentinelOnly bool, // true if this method has no error return, just the sentinel. +) string { + // We really could just... call the methods directly (and elide the switch entirely all the time), in the case of the "interface" implementation strategy. + // We don't, though, because that would deprive us of getting the union type's name in the wrong-kind errors... + // and in addition to that being sadface in general, it would be downright unacceptable if that behavior varied based on implementation strategy. + // + // This error text doesn't tell us what the member kind is. This might read weirdly. + // It's possible we could try to cram a description of the inhabitant into the "TypeName" since it's stringy; but unclear if that's a good idea either. + + // These template concatenations have evolved into a mess very quickly. This entire thing should be replaced. + // String concatenations of template clauses is an atrociously unhygenic way to compose things; + // it looked like we could limp by with it for a while, but it's gotten messier faster than expected. + + errorClause := `return ` + nopeSentinel + if !nopeSentinelOnly { + errorClause += `, datamodel.ErrWrongKind{TypeName: "{{ .PkgName }}.{{ .Type.Name }}.Repr", MethodName: "` + methodName + `", AppropriateKind: ` + appropriateKind + `, ActualKind: n.Kind()}` + } + return ` + func (n *_{{ .Type | TypeSymbol }}__Repr) ` + methodSig + ` { + ` + someSwitchClause + ` + {{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }} + switch n.tag { + {{- range $i, $member := .Type.Members }} + ` + condClause + ` + case {{ add $i 1 }}: + return n.x{{ add $i 1 }}.Representation()` + retClause + ` + {{- end}} + {{- end}} + {{- else if (eq (.AdjCfg.UnionMemlayout .Type) "interface") }} + switch n2 := n.x.(type) { + {{- range $i, $member := .Type.Members }} + ` + condClause + ` + case {{ $member | TypeSymbol }}: + return n2.Representation()` + retClause + ` + {{- end}} + {{- end}} + {{- end}} + default: + {{- end}} + ` + errorClause + ` + ` + someSwitchClause + ` + } + {{- end}} + } + ` +} + +func (g unionKindedReprGenerator) EmitNodeMethodLookupByString(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `LookupByString`, + `LookupByString(key string) (datamodel.Node, error)`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "map") }}`, + `{{- if eq $member.RepresentationBehavior.String "map" }}`, + `.LookupByString(key)`, + `datamodel.KindSet_JustMap`, + `nil`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodLookupByIndex(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `LookupByIndex`, + `LookupByIndex(idx int64) (datamodel.Node, error)`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "list") }}`, + `{{- if eq $member.RepresentationBehavior.String "list" }}`, + `.LookupByIndex(idx)`, + `datamodel.KindSet_JustList`, + `nil`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodLookupByNode(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `LookupByNode`, + `LookupByNode(key datamodel.Node) (datamodel.Node, error)`, + `{{- if or (.Type.RepresentationStrategy.GetMember (Kind "map")) (.Type.RepresentationStrategy.GetMember (Kind "list")) }}`, + `{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`, + `.LookupByNode(key)`, + `datamodel.KindSet_Recursive`, + `nil`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodLookupBySegment(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `LookupBySegment`, + `LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error)`, + `{{- if or (.Type.RepresentationStrategy.GetMember (Kind "map")) (.Type.RepresentationStrategy.GetMember (Kind "list")) }}`, + `{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`, + `.LookupBySegment(seg)`, + `datamodel.KindSet_Recursive`, + `nil`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodMapIterator(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `MapIterator`, + `MapIterator() datamodel.MapIterator`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "map") }}`, + `{{- if eq $member.RepresentationBehavior.String "map" }}`, + `.MapIterator()`, + `datamodel.KindSet_JustMap`, + `nil`, + true, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodListIterator(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `ListIterator`, + `ListIterator() datamodel.ListIterator`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "list") }}`, + `{{- if eq $member.RepresentationBehavior.String "list" }}`, + `.ListIterator()`, + `datamodel.KindSet_JustList`, + `nil`, + true, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodLength(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `Length`, + `Length() int64`, + `{{- if or (.Type.RepresentationStrategy.GetMember (Kind "map")) (.Type.RepresentationStrategy.GetMember (Kind "list")) }}`, + `{{- if or (eq $member.RepresentationBehavior.String "map") (eq $member.RepresentationBehavior.String "list") }}`, + `.Length()`, + `datamodel.KindSet_Recursive`, + `-1`, + true, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodIsAbsent(w io.Writer) { + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) IsAbsent() bool { + return false + } + `, w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodIsNull(w io.Writer) { + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) IsNull() bool { + return false + } + `, w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodAsBool(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `AsBool`, + `AsBool() (bool, error)`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "bool") }}`, + `{{- if eq $member.RepresentationBehavior.String "bool" }}`, + `.AsBool()`, + `datamodel.KindSet_JustBool`, + `false`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodAsInt(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `AsInt`, + `AsInt() (int64, error)`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "int") }}`, + `{{- if eq $member.RepresentationBehavior.String "int" }}`, + `.AsInt()`, + `datamodel.KindSet_JustInt`, + `0`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodAsFloat(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `AsFloat`, + `AsFloat() (float64, error)`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "float") }}`, + `{{- if eq $member.RepresentationBehavior.String "float" }}`, + `.AsFloat()`, + `datamodel.KindSet_JustFloat`, + `0`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodAsString(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `AsString`, + `AsString() (string, error)`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "string") }}`, + `{{- if eq $member.RepresentationBehavior.String "string" }}`, + `.AsString()`, + `datamodel.KindSet_JustString`, + `""`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodAsBytes(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `AsBytes`, + `AsBytes() ([]byte, error)`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "bytes") }}`, + `{{- if eq $member.RepresentationBehavior.String "bytes" }}`, + `.AsBytes()`, + `datamodel.KindSet_JustBytes`, + `nil`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodAsLink(w io.Writer) { + doTemplate(kindedUnionNodeMethodTemplateMunge( + `AsLink`, + `AsLink() (datamodel.Link, error)`, + `{{- if .Type.RepresentationStrategy.GetMember (Kind "link") }}`, + `{{- if eq $member.RepresentationBehavior.String "link" }}`, + `.AsLink()`, + `datamodel.KindSet_JustLink`, + `nil`, + false, + ), w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g unionKindedReprGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g unionKindedReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return unionKindedReprBuilderGenerator(g) +} + +type unionKindedReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + PkgName string + Type *schema.TypeUnion +} + +func (unionKindedReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g unionKindedReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + // Much of this is familiar: the 'w', the 'm' are all as usual. + // Some things may look a little odd here compared to all other assemblers: + // we're kinda halfway between what's conventionally seen for a scalar and what's conventionally seen for a recursive. + // There's no 'maState' or 'laState'-typed fields (which feels like a scalar) because even if we end up acting like a map or list, that state is in the relevant child assembler. + // We don't even have a 'cm' field, because we can get away with something really funky: we can just copy our own 'm' _pointer_ into children; our doneness and their doneness is the same. + // We never have to worry about maybeism of our children; the nullable and optional modifiers aren't possible on union members. + // (We *do* still have to consider null values though, as null is still a kind, and thus can be routed to one of our members!) + // 'ca' is as it is in the type-level assembler: technically, not super necessary, except that it allows minimizing the amount of work that resetting needs to do. + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + + {{- range $i, $member := .Type.Members }} + ca{{ add $i 1 }} {{ if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }}*{{end}}_{{ $member | TypeSymbol }}__ReprAssembler + {{- end}} + ca uint + } + `, w, g.AdjCfg, g) + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() { + switch na.ca { + case 0: + return + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + na.ca{{ add $i 1 }}.reset() + {{- end}} + default: + panic("unreachable") + } + na.ca = 0 + } + `, w, g.AdjCfg, g) +} + +func kindedUnionNodeAssemblerMethodTemplateMunge( + methodName string, // for error messages + methodSig string, // output literally + condClause string, // template condition for the member this should match on + retClause string, // clause returning the thing (how to delegate methodsig, generally) + twoReturns bool, // true if a nil should be returned as well as the error +) string { + // The value pointed to by `na.m` isn't modified here, because we're sharing it with the child, who should do so. + // This also means that value gets checked twice -- once by us, because we need to halt if we've already been used -- + // and also a second time by the child when we delegate to it, which, unbeknownst to it, is irrelevant. + // I don't see a good way to remedy this shy of making more granular (unexported!) methods. (Might be worth it.) + // This probably also isn't the same for all of the assembler methods: the methods we delegate to aren't doing as many check branches when they're for scalars, + // because they expected to be used in contexts where many values of the 'm' enum aren't reachable -- an expectation we've suddenly subverted with this path! + // + // FUTURE: The error returns here are deeply questionable, and not as helpful as they could be. + // ErrNotUnionStructure is about the most applicable thing so far, but it's very freetext. + // ErrWrongKind wouldn't fit at all: assumes that we can say what kind of node we have, but this is the one case in the whole system where *we can't*; also, assumes there's one actual correct kind, and that too is false here! + maybeNilComma := "" + if twoReturns { + maybeNilComma += "nil," + } + return ` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) ` + methodSig + ` { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign into assembler that's already working on a larger structure!") + } + {{- $returned := false -}} + {{- range $i, $member := .Type.Members }} + ` + condClause + ` + {{- if dot.Type | MaybeUsesPtr }} + if na.w == nil { + na.w = &_{{ dot.Type | TypeSymbol }}{} + } + {{- end}} + na.ca = {{ add $i 1 }} + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + na.w.tag = {{ add $i 1 }} + na.ca{{ add $i 1 }}.w = &na.w.x{{ add $i 1 }} + na.ca{{ add $i 1 }}.m = na.m + return na.ca{{ add $i 1 }}` + retClause + ` + {{- else if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }} + x := &_{{ $member | TypeSymbol }}{} + na.w.x = x + if na.ca{{ add $i 1 }} == nil { + na.ca{{ add $i 1 }} = &_{{ $member | TypeSymbol }}__ReprAssembler{} + } + na.ca{{ add $i 1 }}.w = x + na.ca{{ add $i 1 }}.m = na.m + return na.ca{{ add $i 1 }}` + retClause + ` + {{- end}} + {{- $returned = true -}} + {{- end }} + {{- end }} + {{- if not $returned }} + return ` + maybeNilComma + ` schema.ErrNotUnionStructure{TypeName: "{{ .PkgName }}.{{ .Type.Name }}.Repr", Detail: "` + methodName + ` called but is not valid for any of the kinds that are valid members of this union"} + {{- end }} + } + ` +} + +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `BeginMap`, + `BeginMap(sizeHint int64) (datamodel.MapAssembler, error)`, + `{{- if eq $member.RepresentationBehavior.String "map" }}`, + `.BeginMap(sizeHint)`, + true, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodBeginList(w io.Writer) { + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `BeginList`, + `BeginList(sizeHint int64) (datamodel.ListAssembler, error)`, + `{{- if eq $member.RepresentationBehavior.String "list" }}`, + `.BeginList(sizeHint)`, + true, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + // TODO: I think this may need some special handling to account for if our union is itself used in a nullable circumstance; that should overrule this behavior. + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `AssignNull`, + `AssignNull() error `, + `{{- if eq $member.RepresentationBehavior.String "null" }}`, + `.AssignNull()`, + false, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `AssignBool`, + `AssignBool(v bool) error `, + `{{- if eq $member.RepresentationBehavior.String "bool" }}`, + `.AssignBool(v)`, + false, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `AssignInt`, + `AssignInt(v int64) error `, + `{{- if eq $member.RepresentationBehavior.String "int" }}`, + `.AssignInt(v)`, + false, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `AssignFloat`, + `AssignFloat(v float64) error `, + `{{- if eq $member.RepresentationBehavior.String "float" }}`, + `.AssignFloat(v)`, + false, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(w io.Writer) { + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `AssignString`, + `AssignString(v string) error `, + `{{- if eq $member.RepresentationBehavior.String "string" }}`, + `.AssignString(v)`, + false, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `AssignBytes`, + `AssignBytes(v []byte) error `, + `{{- if eq $member.RepresentationBehavior.String "bytes" }}`, + `.AssignBytes(v)`, + false, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + doTemplate(kindedUnionNodeAssemblerMethodTemplateMunge( + `AssignLink`, + `AssignLink(v datamodel.Link) error `, + `{{- if eq $member.RepresentationBehavior.String "link" }}`, + `.AssignLink(v)`, + false, + ), w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + // This is a very mundane AssignNode: it just calls out to the other methods on this type. + // However, even that is a little more exciting than usual: because we can't *necessarily* reject any kind of arg, + // we have the whole barrage of switch cases here. We then leave any particular rejections to those methods. + // Several cases could be statically replaced with errors and it would be an improvement. + // + // Errors are problematic again, same as is noted in kindedUnionNodeAssemblerMethodTemplateMunge. + // We also end up returning errors with other method names due to how we delegate; unfortunate. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + switch v.Kind() { + case datamodel.Kind_Bool: + v2, _ := v.AsBool() + return na.AssignBool(v2) + case datamodel.Kind_Int: + v2, _ := v.AsInt() + return na.AssignInt(v2) + case datamodel.Kind_Float: + v2, _ := v.AsFloat() + return na.AssignFloat(v2) + case datamodel.Kind_String: + v2, _ := v.AsString() + return na.AssignString(v2) + case datamodel.Kind_Bytes: + v2, _ := v.AsBytes() + return na.AssignBytes(v2) + case datamodel.Kind_Map: + na, err := na.BeginMap(v.Length()) + if err != nil { + return err + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() + case datamodel.Kind_List: + na, err := na.BeginList(v.Length()) + if err != nil { + return err + } + itr := v.ListIterator() + for !itr.Done() { + _, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() + case datamodel.Kind_Link: + v2, _ := v.AsLink() + return na.AssignLink(v2) + default: + panic("unreachable") + } + } + `, w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerMethodPrototype(w io.Writer) { + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) Prototype() datamodel.NodePrototype { + return _{{ .Type | TypeSymbol }}__ReprPrototype{} + } + `, w, g.AdjCfg, g) +} +func (g unionKindedReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // somewhat shockingly: nothing. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprStringprefix.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprStringprefix.go new file mode 100644 index 00000000000..7bc4fb63ad2 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genUnionReprStringprefix.go @@ -0,0 +1,258 @@ +package gengo + +import ( + "io" + + "github.com/ipld/go-ipld-prime/schema" + "github.com/ipld/go-ipld-prime/schema/gen/go/mixins" +) + +var _ TypeGenerator = &unionReprStringprefixGenerator{} + +func NewUnionReprStringprefixGenerator(pkgName string, typ *schema.TypeUnion, adjCfg *AdjunctCfg) TypeGenerator { + return unionReprStringprefixGenerator{ + unionGenerator{ + AdjCfg: adjCfg, + MapTraits: mixins.MapTraits{ + PkgName: pkgName, + TypeName: string(typ.Name()), + TypeSymbol: adjCfg.TypeSymbol(typ), + }, + PkgName: pkgName, + Type: typ, + }, + } +} + +type unionReprStringprefixGenerator struct { + unionGenerator +} + +func (g unionReprStringprefixGenerator) GetRepresentationNodeGen() NodeGenerator { + return unionReprStringprefixReprGenerator{ + AdjCfg: g.AdjCfg, + StringTraits: mixins.StringTraits{ + PkgName: g.PkgName, + TypeName: string(g.Type.Name()) + ".Repr", + TypeSymbol: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + PkgName: g.PkgName, + Type: g.Type, + } +} + +type unionReprStringprefixReprGenerator struct { + AdjCfg *AdjunctCfg + mixins.StringTraits + PkgName string + Type *schema.TypeUnion +} + +func (unionReprStringprefixReprGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g unionReprStringprefixReprGenerator) EmitNodeType(w io.Writer) { + // The type is structurally the same, but will have a different set of methods. + doTemplate(` + type _{{ .Type | TypeSymbol }}__Repr _{{ .Type | TypeSymbol }} + `, w, g.AdjCfg, g) + + // We do also want some constants for our discriminant values; + // they'll make iterators able to work faster. + doTemplate(` + var ( + {{- range $member := .Type.Members }} + memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }}_serial = _String{"{{ $member | dot.Type.RepresentationStrategy.GetDiscriminant }}"} + {{- end }} + ) + `, w, g.AdjCfg, g) +} + +func (g unionReprStringprefixReprGenerator) EmitNodeTypeAssertions(w io.Writer) { + doTemplate(` + var _ datamodel.Node = &_{{ .Type | TypeSymbol }}__Repr{} + `, w, g.AdjCfg, g) +} + +func (g unionReprStringprefixReprGenerator) EmitNodeMethodAsString(w io.Writer) { + // See comment block in structReprStringjoinReprGenerator.EmitNodeMethodAsString for a lot of philosophizing about this. + doTemplate(` + func (n *_{{ .Type | TypeSymbol }}__Repr) AsString() (string, error) { + return n.String(), nil + } + func (n *_{{ .Type | TypeSymbol }}__Repr) String() string { + {{- if (eq (.AdjCfg.UnionMemlayout .Type) "embedAll") }} + switch n.tag { + {{- range $i, $member := .Type.Members }} + case {{ add $i 1 }}: + return memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }}_serial.String() + "{{ dot.Type.RepresentationStrategy.GetDelim }}" + n.x{{ add $i 1 }}.String() + {{- end}} + {{- else if (eq (.AdjCfg.UnionMemlayout .Type) "interface") }} + switch n2 := n.x.(type) { + {{- range $member := .Type.Members }} + case {{ $member | TypeSymbol }}: + return memberName__{{ dot.Type | TypeSymbol }}_{{ $member.Name }}_serial.String() + "{{ dot.Type.RepresentationStrategy.GetDelim }}" + n2.String() + {{- end}} + {{- end}} + default: + panic("unreachable") + } + } + func (n {{ .Type | TypeSymbol }}) String() string { + return (*_{{ .Type | TypeSymbol }}__Repr)(n).String() + } + `, w, g.AdjCfg, g) +} + +func (g unionReprStringprefixReprGenerator) EmitNodeMethodPrototype(w io.Writer) { + emitNodeMethodPrototype_typical(w, g.AdjCfg, g) +} + +func (g unionReprStringprefixReprGenerator) EmitNodePrototypeType(w io.Writer) { + emitNodePrototypeType_typical(w, g.AdjCfg, g) +} + +// --- NodeBuilder and NodeAssembler ---> + +func (g unionReprStringprefixReprGenerator) GetNodeBuilderGenerator() NodeBuilderGenerator { + return unionReprStringprefixReprBuilderGenerator{ + g.AdjCfg, + mixins.StringAssemblerTraits{ + PkgName: g.PkgName, + TypeName: g.TypeName, + AppliedPrefix: "_" + g.AdjCfg.TypeSymbol(g.Type) + "__Repr", + }, + g.PkgName, + g.Type, + } +} + +type unionReprStringprefixReprBuilderGenerator struct { + AdjCfg *AdjunctCfg + mixins.StringAssemblerTraits + PkgName string + Type *schema.TypeUnion +} + +func (unionReprStringprefixReprBuilderGenerator) IsRepr() bool { return true } // hint used in some generalized templates. + +func (g unionReprStringprefixReprBuilderGenerator) EmitNodeBuilderType(w io.Writer) { + emitEmitNodeBuilderType_typical(w, g.AdjCfg, g) +} +func (g unionReprStringprefixReprBuilderGenerator) EmitNodeBuilderMethods(w io.Writer) { + emitNodeBuilderMethods_typical(w, g.AdjCfg, g) + + // Generate a single-step construction function -- this is easy to do for a scalar, + // and all representations of scalar kind can be expected to have a method like this. + // The function is attached to the NodePrototype for convenient namespacing; + // it needs no new memory, so it would be inappropriate to attach to the builder or assembler. + // The function is directly used internally by anything else that might involve recursive destructuring on the same scalar kind + // (for example, structs using stringjoin strategies that have one of this type as a field, etc). + // Since we're a representation of scalar kind, and can recurse, + // we ourselves presume this plain construction method must also exist for all our members. + // REVIEW: We could make an immut-safe verion of this and export it on the NodePrototype too, as `FromString(string)`. + doTemplate(` + func (_{{ .Type | TypeSymbol }}__ReprPrototype) fromString(w *_{{ .Type | TypeSymbol }}, v string) error { + ss := mixins.SplitN(v, "{{ .Type.RepresentationStrategy.GetDelim }}", 2) + if len(ss) != 2 { + return schema.ErrUnmatchable{TypeName:"{{ .PkgName }}.{{ .Type.Name }}.Repr"}.Reasonf("expecting a stringprefix union but found no delimiter in the value") + } + switch ss[0] { + {{- range $i, $member := .Type.Members }} + case "{{ $member | dot.Type.RepresentationStrategy.GetDiscriminant }}": + {{- if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "embedAll") }} + w.tag = {{ add $i 1 }} + if err := (_{{ $member | TypeSymbol }}__ReprPrototype{}).fromString(&w.x{{ add $i 1 }}, ss[1]); err != nil { + return schema.ErrUnmatchable{TypeName:"{{ dot.PkgName }}.{{ dot.Type.Name }}.Repr", Reason: err} + } + return nil + {{- else if (eq (dot.AdjCfg.UnionMemlayout dot.Type) "interface") }} + var n2 _{{ $member | TypeSymbol }} + if err := (_{{ $member | TypeSymbol }}__ReprPrototype{}).fromString(&n2, ss[1]); err != nil { + return schema.ErrUnmatchable{TypeName:"{{ dot.PkgName }}.{{ dot.Type.Name }}.Repr", Reason: err} + } + w.x = &n2 + return nil + {{- end}} + {{- end}} + default: + return schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfString(ss[0])} + } + } + `, w, g.AdjCfg, g) +} +func (g unionReprStringprefixReprBuilderGenerator) EmitNodeAssemblerType(w io.Writer) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__ReprAssembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + } + + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) reset() {} + `, w, g.AdjCfg, g) +} +func (g unionReprStringprefixReprBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g) +} +func (g unionReprStringprefixReprBuilderGenerator) EmitNodeAssemblerMethodAssignString(w io.Writer) { + // This method contains a branch to support MaybeUsesPtr because new memory may need to be allocated. + // This allocation only happens if the 'w' ptr is nil, which means we're being used on a Maybe; + // otherwise, the 'w' ptr should already be set, and we fill that memory location without allocating, as usual. + // TODO:DRY: this is identical to other string-repr-on-non-string-type. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) AssignString(v string) error { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = &_{{ .Type | TypeSymbol }}{} + } + {{- end}} + if err := (_{{ .Type | TypeSymbol }}__ReprPrototype{}).fromString(na.w, v); err != nil { + return err + } + *na.m = schema.Maybe_Value + return nil + } + `, w, g.AdjCfg, g) +} + +func (g unionReprStringprefixReprBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) { + // AssignNode goes through three phases: + // 1. is it null? Jump over to AssignNull (which may or may not reject it). + // 2. is it our own type? Handle specially -- we might be able to do efficient things. + // 3. is it the right kind to morph into us? Do so. + // TODO:DRY: this is identical to other string-repr-on-non-string-type. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__ReprAssembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v2, err := v.AsString(); err != nil { + return err + } else { + return na.AssignString(v2) + } + } + `, w, g.AdjCfg, g) +} +func (g unionReprStringprefixReprBuilderGenerator) EmitNodeAssemblerOtherBits(w io.Writer) { + // None for this. +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/generate.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/generate.go new file mode 100644 index 00000000000..b87355fff4f --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/generate.go @@ -0,0 +1,172 @@ +package gengo + +import ( + "bytes" + "fmt" + "go/format" + "io" + "os" + "path/filepath" + "sort" + + "github.com/ipld/go-ipld-prime/schema" +) + +// Generate takes a typesystem and the adjunct config for codegen, +// and emits generated code in the given path with the given package name. +// +// All of the files produced will match the pattern "ipldsch.*.gen.go". +func Generate(pth string, pkgName string, ts schema.TypeSystem, adjCfg *AdjunctCfg) { + // Emit fixed bits. + withFile(filepath.Join(pth, "ipldsch_minima.go"), func(f io.Writer) { + EmitInternalEnums(pkgName, f) + }) + + externs, err := getExternTypes(pth) + if err != nil { + // Consider warning that duplication may be present due to inability to parse destination. + externs = make(map[string]struct{}) + } + + // Local helper function for applying generation logic to each type. + // We will end up doing this more than once because in this layout, more than one file contains part of the story for each type. + applyToEachType := func(fn func(tg TypeGenerator, w io.Writer), f io.Writer) { + // Sort the type names so we have a determinisic order; this affects output consistency. + // Any stable order would do, but we don't presently have one, so a sort is necessary. + types := ts.GetTypes() + keys := make(sortableTypeNames, 0, len(types)) + for tn := range types { + if _, exists := externs[tn]; !exists { + keys = append(keys, tn) + } + } + sort.Sort(keys) + for _, tn := range keys { + switch t2 := types[tn].(type) { + case *schema.TypeBool: + fn(NewBoolReprBoolGenerator(pkgName, t2, adjCfg), f) + case *schema.TypeInt: + fn(NewIntReprIntGenerator(pkgName, t2, adjCfg), f) + case *schema.TypeFloat: + fn(NewFloatReprFloatGenerator(pkgName, t2, adjCfg), f) + case *schema.TypeString: + fn(NewStringReprStringGenerator(pkgName, t2, adjCfg), f) + case *schema.TypeBytes: + fn(NewBytesReprBytesGenerator(pkgName, t2, adjCfg), f) + case *schema.TypeLink: + fn(NewLinkReprLinkGenerator(pkgName, t2, adjCfg), f) + case *schema.TypeStruct: + switch t2.RepresentationStrategy().(type) { + case schema.StructRepresentation_Map: + fn(NewStructReprMapGenerator(pkgName, t2, adjCfg), f) + case schema.StructRepresentation_Tuple: + fn(NewStructReprTupleGenerator(pkgName, t2, adjCfg), f) + case schema.StructRepresentation_Stringjoin: + fn(NewStructReprStringjoinGenerator(pkgName, t2, adjCfg), f) + default: + panic("unrecognized struct representation strategy") + } + case *schema.TypeMap: + fn(NewMapReprMapGenerator(pkgName, t2, adjCfg), f) + case *schema.TypeList: + fn(NewListReprListGenerator(pkgName, t2, adjCfg), f) + case *schema.TypeUnion: + switch t2.RepresentationStrategy().(type) { + case schema.UnionRepresentation_Keyed: + fn(NewUnionReprKeyedGenerator(pkgName, t2, adjCfg), f) + case schema.UnionRepresentation_Kinded: + fn(NewUnionReprKindedGenerator(pkgName, t2, adjCfg), f) + case schema.UnionRepresentation_Stringprefix: + fn(NewUnionReprStringprefixGenerator(pkgName, t2, adjCfg), f) + default: + panic("unrecognized union representation strategy") + } + default: + panic(fmt.Sprintf("add more type switches here :), failed at type %s", tn)) + } + } + } + + // Emit a file with the type table, and the golang type defns for each type. + withFile(filepath.Join(pth, "ipldsch_types.go"), func(f io.Writer) { + // Emit headers, import statements, etc. + fmt.Fprintf(f, "package %s\n\n", pkgName) + fmt.Fprintf(f, doNotEditComment+"\n\n") + fmt.Fprintf(f, "import (\n") + fmt.Fprintf(f, "\t\"github.com/ipld/go-ipld-prime/datamodel\"\n") // referenced for links + fmt.Fprintf(f, ")\n") + fmt.Fprintf(f, "var _ datamodel.Node = nil // suppress errors when this dependency is not referenced\n") + + // Emit the type table. + EmitTypeTable(pkgName, ts, adjCfg, f) + + // Emit the type defns matching the schema types. + fmt.Fprintf(f, "\n// --- type definitions follow ---\n\n") + applyToEachType(func(tg TypeGenerator, w io.Writer) { + tg.EmitNativeType(w) + fmt.Fprintf(f, "\n") + }, f) + + }) + + // Emit a file with all the Node/NodeBuilder/NodeAssembler boilerplate. + // Also includes typedefs for representation-level data. + // Also includes the MaybeT boilerplate. + withFile(filepath.Join(pth, "ipldsch_satisfaction.go"), func(f io.Writer) { + // Emit headers, import statements, etc. + fmt.Fprintf(f, "package %s\n\n", pkgName) + fmt.Fprintf(f, doNotEditComment+"\n\n") + fmt.Fprintf(f, "import (\n") + fmt.Fprintf(f, "\t\"github.com/ipld/go-ipld-prime/datamodel\"\n") // referenced everywhere. + fmt.Fprintf(f, "\t\"github.com/ipld/go-ipld-prime/node/mixins\"\n") // referenced by node implementation guts. + fmt.Fprintf(f, "\t\"github.com/ipld/go-ipld-prime/schema\"\n") // referenced by maybes (and surprisingly little else). + fmt.Fprintf(f, ")\n\n") + + // For each type, we'll emit... everything except the native type, really. + applyToEachType(func(tg TypeGenerator, w io.Writer) { + tg.EmitNativeAccessors(w) + tg.EmitNativeBuilder(w) + tg.EmitNativeMaybe(w) + EmitNode(tg, w) + tg.EmitTypedNodeMethodType(w) + tg.EmitTypedNodeMethodRepresentation(w) + + nrg := tg.GetRepresentationNodeGen() + EmitNode(nrg, w) + + fmt.Fprintf(f, "\n") + }, f) + }) +} + +func withFile(filename string, fn func(io.Writer)) { + // Don't write directly to the file, as that many write syscalls can be + // expensive. Moreover, they can have a knock-on effect on daemons + // watching for file changes. gopls can easily eat CPU for many seconds + // just handling tens of thousands of file writes, for example. + // + // To alleviate both of those problems, write to a buffer first, and + // then write the resulting bytes to disk in a single go. + // A buffer is slightly better than bufio.Writer, as it gets us a bit + // more atomicity via the single write. + buf := new(bytes.Buffer) + fn(buf) + + src := buf.Bytes() + // Format the source before writing, just like gofmt would. + // This also prevents us from writing invalid syntax to disk. + src, err := format.Source(src) + if err != nil { + panic(err) + } + + if err := os.WriteFile(filename, src, 0666); err != nil { + panic(err) + } +} + +type sortableTypeNames []schema.TypeName + +func (a sortableTypeNames) Len() int { return len(a) } +func (a sortableTypeNames) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a sortableTypeNames) Less(i, j int) bool { return a[i] < a[j] } diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/generators.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/generators.go new file mode 100644 index 00000000000..7671aeda3e0 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/generators.go @@ -0,0 +1,181 @@ +package gengo + +import ( + "fmt" + "io" + + "github.com/ipld/go-ipld-prime/schema" +) + +// TypeGenerator gathers all the info for generating all code related to one +// type in the schema. +type TypeGenerator interface { + // -- the natively-typed apis --> + + EmitNativeType(io.Writer) + EmitNativeAccessors(io.Writer) // depends on the kind -- field accessors for struct, typed iterators for map, etc. + EmitNativeBuilder(io.Writer) // typically emits some kind of struct that has a Build method. + EmitNativeMaybe(io.Writer) // a pointer-free 'maybe' mechanism is generated for all types. + + // -- the schema.TypedNode.Type method and vars --> + + EmitTypeConst(io.Writer) // these emit dummies for now + EmitTypedNodeMethodType(io.Writer) // these emit dummies for now + + // -- all node methods --> + // (and note that the nodeBuilder for this one should be the "semantic" one, + // e.g. it *always* acts like a map for structs, even if the repr is different.) + + NodeGenerator + + // -- and the representation and its node and nodebuilder --> + // (these vary!) + + EmitTypedNodeMethodRepresentation(io.Writer) + GetRepresentationNodeGen() NodeGenerator // includes transitively the matched NodeBuilderGenerator +} + +type NodeGenerator interface { + EmitNodeType(io.Writer) // usually already covered by EmitNativeType for the primary node, but has a nonzero body for the repr node + EmitNodeTypeAssertions(io.Writer) // optional to include this content + EmitNodeMethodKind(io.Writer) + EmitNodeMethodLookupByString(io.Writer) + EmitNodeMethodLookupByNode(io.Writer) + EmitNodeMethodLookupByIndex(io.Writer) + EmitNodeMethodLookupBySegment(io.Writer) + EmitNodeMethodMapIterator(io.Writer) // also iterator itself + EmitNodeMethodListIterator(io.Writer) // also iterator itself + EmitNodeMethodLength(io.Writer) + EmitNodeMethodIsAbsent(io.Writer) + EmitNodeMethodIsNull(io.Writer) + EmitNodeMethodAsBool(io.Writer) + EmitNodeMethodAsInt(io.Writer) + EmitNodeMethodAsFloat(io.Writer) + EmitNodeMethodAsString(io.Writer) + EmitNodeMethodAsBytes(io.Writer) + EmitNodeMethodAsLink(io.Writer) + EmitNodeMethodPrototype(io.Writer) + EmitNodePrototypeType(io.Writer) + GetNodeBuilderGenerator() NodeBuilderGenerator // assembler features also included inside +} + +type NodeBuilderGenerator interface { + EmitNodeBuilderType(io.Writer) + EmitNodeBuilderMethods(io.Writer) // not many, so just slung them together. + EmitNodeAssemblerType(io.Writer) // you can call this and not EmitNodeBuilderType in some situations. + EmitNodeAssemblerMethodBeginMap(io.Writer) + EmitNodeAssemblerMethodBeginList(io.Writer) + EmitNodeAssemblerMethodAssignNull(io.Writer) + EmitNodeAssemblerMethodAssignBool(io.Writer) + EmitNodeAssemblerMethodAssignInt(io.Writer) + EmitNodeAssemblerMethodAssignFloat(io.Writer) + EmitNodeAssemblerMethodAssignString(io.Writer) + EmitNodeAssemblerMethodAssignBytes(io.Writer) + EmitNodeAssemblerMethodAssignLink(io.Writer) + EmitNodeAssemblerMethodAssignNode(io.Writer) + EmitNodeAssemblerMethodPrototype(io.Writer) + EmitNodeAssemblerOtherBits(io.Writer) // key and value child assemblers are done here. +} + +// EmitFileHeader emits a baseline package header that will +// allow a file with a generated type to compile. +// (Fortunately, there are no variations in this.) +func EmitFileHeader(packageName string, w io.Writer) { + fmt.Fprintf(w, "package %s\n\n", packageName) + fmt.Fprintf(w, doNotEditComment+"\n\n") + fmt.Fprintf(w, "import (\n") + fmt.Fprintf(w, "\t\"github.com/ipld/go-ipld-prime/datamodel\"\n") + fmt.Fprintf(w, "\t\"github.com/ipld/go-ipld-prime/node/mixins\"\n") + fmt.Fprintf(w, "\t\"github.com/ipld/go-ipld-prime/schema\"\n") + fmt.Fprintf(w, ")\n\n") +} + +// EmitEntireType is a helper function calls all methods of TypeGenerator +// and streams all results into a single writer. +// (This implies two calls to EmitNode -- one for the type-level and one for the representation-level.) +func EmitEntireType(tg TypeGenerator, w io.Writer) { + tg.EmitNativeType(w) + tg.EmitNativeAccessors(w) + tg.EmitNativeBuilder(w) + tg.EmitNativeMaybe(w) + EmitNode(tg, w) + tg.EmitTypedNodeMethodType(w) + tg.EmitTypedNodeMethodRepresentation(w) + + rng := tg.GetRepresentationNodeGen() + if rng == nil { // FIXME: hack to save me from stubbing tons right now, remove when done + return + } + EmitNode(rng, w) +} + +// EmitNode is a helper function that calls all methods of NodeGenerator +// and streams all results into a single writer. +func EmitNode(ng NodeGenerator, w io.Writer) { + ng.EmitNodeType(w) + ng.EmitNodeTypeAssertions(w) + ng.EmitNodeMethodKind(w) + ng.EmitNodeMethodLookupByString(w) + ng.EmitNodeMethodLookupByNode(w) + ng.EmitNodeMethodLookupByIndex(w) + ng.EmitNodeMethodLookupBySegment(w) + ng.EmitNodeMethodMapIterator(w) + ng.EmitNodeMethodListIterator(w) + ng.EmitNodeMethodLength(w) + ng.EmitNodeMethodIsAbsent(w) + ng.EmitNodeMethodIsNull(w) + ng.EmitNodeMethodAsBool(w) + ng.EmitNodeMethodAsInt(w) + ng.EmitNodeMethodAsFloat(w) + ng.EmitNodeMethodAsString(w) + ng.EmitNodeMethodAsBytes(w) + ng.EmitNodeMethodAsLink(w) + ng.EmitNodeMethodPrototype(w) + + ng.EmitNodePrototypeType(w) + + nbg := ng.GetNodeBuilderGenerator() + if nbg == nil { // FIXME: hack to save me from stubbing tons right now, remove when done + return + } + nbg.EmitNodeBuilderType(w) + nbg.EmitNodeBuilderMethods(w) + nbg.EmitNodeAssemblerType(w) + nbg.EmitNodeAssemblerMethodBeginMap(w) + nbg.EmitNodeAssemblerMethodBeginList(w) + nbg.EmitNodeAssemblerMethodAssignNull(w) + nbg.EmitNodeAssemblerMethodAssignBool(w) + nbg.EmitNodeAssemblerMethodAssignInt(w) + nbg.EmitNodeAssemblerMethodAssignFloat(w) + nbg.EmitNodeAssemblerMethodAssignString(w) + nbg.EmitNodeAssemblerMethodAssignBytes(w) + nbg.EmitNodeAssemblerMethodAssignLink(w) + nbg.EmitNodeAssemblerMethodAssignNode(w) + nbg.EmitNodeAssemblerMethodPrototype(w) + nbg.EmitNodeAssemblerOtherBits(w) +} + +func EmitTypeTable(pkgName string, ts schema.TypeSystem, adjCfg *AdjunctCfg, w io.Writer) { + // REVIEW: if "T__Repr" is how we want to expose this. We could also put 'Repr' accessors on the type/prototype objects. + // FUTURE: types and prototypes are proposed to be the same. Some of this text pretends they already are, but work is needed on this. + doTemplate(` + // Type is a struct embeding a NodePrototype/Type for every Node implementation in this package. + // One of its major uses is to start the construction of a value. + // You can use it like this: + // + // `+pkgName+`.Type.YourTypeName.NewBuilder().BeginMap() //... + // + // and: + // + // `+pkgName+`.Type.OtherTypeName.NewBuilder().AssignString("x") // ... + // + var Type typeSlab + + type typeSlab struct { + {{- range . }} + {{ .Name }} _{{ . | TypeSymbol }}__Prototype + {{ .Name }}__Repr _{{ . | TypeSymbol }}__ReprPrototype + {{- end}} + } + `, w, adjCfg, ts.GetTypes()) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsCommon.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsCommon.go new file mode 100644 index 00000000000..fc4058a9e90 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsCommon.go @@ -0,0 +1,288 @@ +package gengo + +import ( + "io" +) + +/* + This file is full of "typical" templates. + They may not be used by *every* type and representation, + but if they're extracted here, they're at least used by *many*. +*/ + +// The codegen do-not-edit warning comment. +// Follows the pattern in https://golang.org/s/generatedcode / https://github.com/golang/go/issues/13560#issuecomment-288457920 . +// Should appear somewhere near the top of every file (though precise order doesn't matter). +const doNotEditComment = `// Code generated by go-ipld-prime gengo. DO NOT EDIT.` + +// emitNativeMaybe turns out to be completely agnostic to pretty much everything; +// it doesn't vary by kind at all, and has never yet ended up needing specialization. +func emitNativeMaybe(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__Maybe struct { + m schema.Maybe + v {{if not (MaybeUsesPtr .Type) }}_{{end}}{{ .Type | TypeSymbol }} + } + type Maybe{{ .Type | TypeSymbol }} = *_{{ .Type | TypeSymbol }}__Maybe + + func (m Maybe{{ .Type | TypeSymbol }}) IsNull() bool { + return m.m == schema.Maybe_Null + } + func (m Maybe{{ .Type | TypeSymbol }}) IsAbsent() bool { + return m.m == schema.Maybe_Absent + } + func (m Maybe{{ .Type | TypeSymbol }}) Exists() bool { + return m.m == schema.Maybe_Value + } + func (m Maybe{{ .Type | TypeSymbol }}) AsNode() datamodel.Node { + switch m.m { + case schema.Maybe_Absent: + return datamodel.Absent + case schema.Maybe_Null: + return datamodel.Null + case schema.Maybe_Value: + return {{if not (MaybeUsesPtr .Type) }}&{{end}}m.v + default: + panic("unreachable") + } + } + func (m Maybe{{ .Type | TypeSymbol }}) Must() {{ .Type | TypeSymbol }} { + if !m.Exists() { + panic("unbox of a maybe rejected") + } + return {{if not (MaybeUsesPtr .Type) }}&{{end}}m.v + } + `, w, adjCfg, data) +} + +func emitNativeType_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // Using a struct with a single member is the same size in memory as a typedef, + // while also having the advantage of meaning we can block direct casting, + // which is desirable because the compiler then ensures our validate methods can't be evaded. + doTemplate(` + {{- if Comments -}} + // {{ .Type | TypeSymbol }} matches the IPLD Schema type "{{ .Type.Name }}". It has {{ .Kind }} kind. + {{- end}} + type {{ .Type | TypeSymbol }} = *_{{ .Type | TypeSymbol }} + type _{{ .Type | TypeSymbol }} struct{ x {{ .Kind | KindPrim }} } + `, w, adjCfg, data) +} + +func emitNativeAccessors_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // The node interface's `AsFoo` method is almost sufficient... but + // this method unboxes without needing to return an error that's statically impossible, + // which makes it easier to use in chaining. + doTemplate(` + func (n {{ .Type | TypeSymbol }}) {{ .Kind.String | title }}() {{ .Kind | KindPrim }} { + return n.x + } + `, w, adjCfg, data) +} + +func emitNativeBuilder_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // Generate a single-step construction function -- this is easy to do for a scalar, + // and all representations of scalar kind can be expected to have a method like this. + // The function is attached to the NodePrototype for convenient namespacing; + // it needs no new memory, so it would be inappropriate to attach to the builder or assembler. + // FUTURE: should engage validation flow. + doTemplate(` + func (_{{ .Type | TypeSymbol }}__Prototype) From{{ .Kind.String | title }}(v {{ .Kind | KindPrim }}) ({{ .Type | TypeSymbol }}, error) { + n := _{{ .Type | TypeSymbol }}{v} + return &n, nil + } + `, w, adjCfg, data) +} + +func emitNodeTypeAssertions_typical(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + var _ datamodel.Node = ({{ .Type | TypeSymbol }})(&_{{ .Type | TypeSymbol }}{}) + var _ schema.TypedNode = ({{ .Type | TypeSymbol }})(&_{{ .Type | TypeSymbol }}{}) + `, w, adjCfg, data) +} + +func emitNodeMethodAsKind_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) As{{ .Kind.String | title }}() ({{ .Kind | KindPrim }}, error) { + return n.x, nil + } + `, w, adjCfg, data) +} + +func emitNodeMethodPrototype_typical(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + func ({{ if .IsRepr }}_{{end}}{{ .Type | TypeSymbol }}{{ if .IsRepr }}__Repr{{end}}) Prototype() datamodel.NodePrototype { + return _{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Prototype{} + } + `, w, adjCfg, data) +} + +// nodePrototype doesn't really vary textually at all between types and kinds +// because it's just builders and standard resets. +func emitNodePrototypeType_typical(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Prototype struct{} + + func (_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Prototype) NewBuilder() datamodel.NodeBuilder { + var nb _{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Builder + nb.Reset() + return &nb + } + `, w, adjCfg, data) +} + +// emitTypicalTypedNodeMethodRepresentation does... what it says on the tin. +// +// For most types, the way to get the representation node pointer doesn't +// textually depend on either the node implementation details nor what the representation strategy is, +// or really much at all for that matter. +// It only depends on that they have the same structure, so this cast works. +// +// Most (all?) types can use this. However, it's here rather in the mixins, for two reasons: +// one, it still seems possible to imagine we'll have a type someday for which this pattern won't hold; +// and two, mixins are also used in the repr generators, and it wouldn't be all sane for this method to end up also on reprs. +func emitTypicalTypedNodeMethodRepresentation(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + func (n {{ .Type | TypeSymbol }}) Representation() datamodel.Node { + return (*_{{ .Type | TypeSymbol }}__Repr)(n) + } + `, w, adjCfg, data) +} + +// Turns out basically all builders are just an embed of the corresponding assembler. +func emitEmitNodeBuilderType_typical(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Builder struct { + _{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler + } + `, w, adjCfg, data) +} + +// Builder build and reset methods are common even when some parts of the assembler vary. +// We count on the zero value of any addntl non-common fields of the assembler being correct. +func emitNodeBuilderMethods_typical(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + func (nb *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Builder) Build() datamodel.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w + } + func (nb *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Builder) Reset() { + var w _{{ .Type | TypeSymbol }} + var m schema.Maybe + *nb = _{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Builder{_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler{w: &w, m: &m}} + } + `, w, adjCfg, data) +} + +// emitNodeAssemblerType_scalar emits a NodeAssembler that's typical for a scalar. +// Types that are recursive tend to have more state and custom stuff, so won't use this +// (although the 'm' and 'w' variable names may still be presumed universally). +func emitNodeAssemblerType_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + type _{{ .Type | TypeSymbol }}__Assembler struct { + w *_{{ .Type | TypeSymbol }} + m *schema.Maybe + } + + func (na *_{{ .Type | TypeSymbol }}__Assembler) reset() {} + `, w, adjCfg, data) +} + +func emitNodeAssemblerMethodAssignNull_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}{{ if .IsRepr }}.Repr{{end}}"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + panic("unreachable") + } + `, w, adjCfg, data) +} + +// almost the same as the variant for scalars, but also has to check for midvalue state. +func emitNodeAssemblerMethodAssignNull_recursive(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}{{ if .IsRepr }}.Repr{{end}}"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") + } + `, w, adjCfg, data) +} + +// works for the AssignFoo methods for scalar kinds that are just boxing a thing. +// There's no equivalent of this at all for recursives -- they're too diverse. +func emitNodeAssemblerMethodAssignKind_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // This method contains a branch to support MaybeUsesPtr because new memory may need to be allocated. + // This allocation only happens if the 'w' ptr is nil, which means we're being used on a Maybe; + // otherwise, the 'w' ptr should already be set, and we fill that memory location without allocating, as usual. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__Assembler) Assign{{ .Kind.String | title }}(v {{ .Kind | KindPrim }}) error { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = &_{{ .Type | TypeSymbol }}{} + } + {{- end}} + na.w.x = v + *na.m = schema.Maybe_Value + return nil + } + `, w, adjCfg, data) +} + +// leans heavily on the fact all the AsFoo and AssignFoo methods follow a very consistent textual pattern. +// FUTURE: may be able to get this to work for recursives, too -- but maps and lists each have very unique bottom thirds of this function. +func emitNodeAssemblerMethodAssignNode_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // AssignNode goes through three phases: + // 1. is it null? Jump over to AssignNull (which may or may not reject it). + // 2. is it our own type? Handle specially -- we might be able to do efficient things. + // 3. is it the right kind to morph into us? Do so. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v2, err := v.As{{ .Kind.String | title }}(); err != nil { + return err + } else { + return na.Assign{{ .Kind.String | title }}(v2) + } + } + `, w, adjCfg, data) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsList.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsList.go new file mode 100644 index 00000000000..ca087a58d70 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsList.go @@ -0,0 +1,206 @@ +package gengo + +import ( + "io" +) + +// FIXME docs: these methods all say "-oid" but I think that was overoptimistic and not actually that applicable, really. +// AssignNode? Okay, that one's fine. +// The rest? They're all *very* emphatic about knowing either: +// - that na.w.x is a slice; or, +// - that there's only one 'va' (one type; and that it's reused). +// The reuse level for those two traits is pretty minimal. + +func emitNodeAssemblerMethodBeginList_listoid(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // This method contains a branch to support MaybeUsesPtr because new memory may need to be allocated. + // This allocation only happens if the 'w' ptr is nil, which means we're being used on a Maybe; + // otherwise, the 'w' ptr should already be set, and we fill that memory location without allocating, as usual. + // + // There's surprisingly little variation for IsRepr on this one: + // - the child types we *store* are the same either way, so that doesn't vary; + // - the only thing that we return that's different is... ourself. + // + // DRY: even further, to an extracted function in the final output? Maybe. + // This could be plausible, iff... the top half of the struct (na.m, na.w) was independently addressable. (na.va has a varying concrete type and blocks extractions.) + // Would also want to examine if that makes desirable trades in gsloc/asmsize/speed/debuggability. + // Only seems to apply to case of list-repr-list, so unclear if worth the effort. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if sizeHint < 0 { + sizeHint = 0 + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = &_{{ .Type | TypeSymbol }}{} + } + {{- end}} + if sizeHint > 0 { + na.w.x = make([]_{{ .Type.ValueType | TypeSymbol }}{{if .Type.ValueIsNullable }}__Maybe{{end}}, 0, sizeHint) + } + return na, nil + } + `, w, adjCfg, data) +} + +func emitNodeAssemblerMethodAssignNode_listoid(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // AssignNode goes through three phases: + // 1. is it null? Jump over to AssignNull (which may or may not reject it). + // 2. is it our own type? Handle specially -- we might be able to do efficient things. + // 3. is it the right kind to morph into us? Do so. + // + // We do not set m=midvalue in phase 3 -- it shouldn't matter unless you're trying to pull off concurrent access, which is wrong and unsafe regardless. + // + // This works easily for both type-level and representational nodes because + // any divergences that have to do with the child value are nicely hidden behind `AssembleValue`. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != datamodel.Kind_List { + return datamodel.ErrWrongKind{TypeName: "{{ .PkgName }}.{{ .Type.Name }}{{ if .IsRepr }}.Repr{{end}}", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustList, ActualKind: v.Kind()} + } + itr := v.ListIterator() + for !itr.Done() { + _, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() + } + `, w, adjCfg, data) +} + +func emitNodeAssemblerHelper_listoid_tidyHelper(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // This function attempts to clean up the state machine to acknolwedge child value assembly finish. + // If the child was finished and we just collected it, return true and update state to laState_initial. + // Otherwise, if it wasn't done, return false; + // and the caller is almost certain to emit an error momentarily. + // The function will only be called when the current state is laState_midValue. + // (In general, the idea is that if the user is doing things correctly, + // this function will only be called when the child is in fact finished.) + // If 'cm' is used, we reset it to its initial condition of Maybe_Absent here. + // At the same time, we nil the 'w' pointer for the child assembler; otherwise its own state machine would probably let it modify 'w' again! + // + // DRY(nope): Can this be extracted to be a shared function between repr and type level nodes? + // It is textually identical, so... yeah, that'd be nice. But... + // Nope. It touches `la.va` directly. + // Attempting to extract that or hide it behind an interface would create virtual function calls in a very tight spot, and we don't want the execution time cost. + doTemplate(` + func (la *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) valueFinishTidy() bool { + {{- if .Type.ValueIsNullable }} + row := &la.w.x[len(la.w.x)-1] + switch row.m { + case schema.Maybe_Value: + {{- if (MaybeUsesPtr .Type.ValueType) }} + row.v = la.va.w + {{- end}} + la.va.w = nil + fallthrough + case schema.Maybe_Null: + la.state = laState_initial + la.va.reset() + return true + {{- else}} + switch la.cm { + case schema.Maybe_Value: + la.va.w = nil + la.cm = schema.Maybe_Absent + la.state = laState_initial + la.va.reset() + return true + {{- end}} + default: + return false + } + } + `, w, adjCfg, data) +} + +func emitNodeAssemblerHelper_listoid_listAssemblerMethods(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // DRY: Might want to split this up a bit further so it can be used by more kinds. + // Some parts of this could be reused by struct-repr-tuple, potentially, but would require being able to insert some more checks relating to length. + // This would also require excluding *all* 'va' references; those are radicaly different for structs, in that there's not even one (singular) of them. + // + // DRY(nope): Can this be extracted to a shared function in the output? + // Same story as the tidy helper -- it touches `la.va` concretely in several places, and that blocks extraction. + doTemplate(` + func (la *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) AssembleValue() datamodel.NodeAssembler { + switch la.state { + case laState_initial: + // carry on + case laState_midValue: + if !la.valueFinishTidy() { + panic("invalid state: AssembleValue cannot be called when still in the middle of assembling the previous value") + } // if tidy success: carry on + case laState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + la.w.x = append(la.w.x, _{{ .Type.ValueType | TypeSymbol }}{{if .Type.ValueIsNullable }}__Maybe{{end}}{}) + la.state = laState_midValue + row := &la.w.x[len(la.w.x)-1] + {{- if .Type.ValueIsNullable }} + {{- if not (MaybeUsesPtr .Type.ValueType) }} + la.va.w = &row.v + {{- end}} + la.va.m = &row.m + row.m = allowNull + {{- else}} + la.va.w = row + la.va.m = &la.cm + {{- end}} + return &la.va + } + `, w, adjCfg, data) + doTemplate(` + func (la *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) Finish() error { + switch la.state { + case laState_initial: + // carry on + case laState_midValue: + if !la.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case laState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + la.state = laState_finished + *la.m = schema.Maybe_Value + return nil + } + `, w, adjCfg, data) + doTemplate(` + func (la *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) ValuePrototype(_ int64) datamodel.NodePrototype { + return _{{ .Type.ValueType | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Prototype{} + } + `, w, adjCfg, data) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsMap.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsMap.go new file mode 100644 index 00000000000..571d5497c5a --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsMap.go @@ -0,0 +1,322 @@ +package gengo + +import ( + "io" +) + +// FIXME docs: these methods all say "-oid" but I think that was overoptimistic and not actually that applicable, really. +// AssignNode? Okay, that one's fine. +// The rest? They're all *very* emphatic about knowing either: +// - that na.w.t and na.w.m are fields; or, +// - that there's only one 'ka' and 'va' (one type each; and that it's reused). +// The reuse level for those two traits is pretty minimal. + +func emitNodeAssemblerMethodBeginMap_mapoid(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // This method contains a branch to support MaybeUsesPtr because new memory may need to be allocated. + // This allocation only happens if the 'w' ptr is nil, which means we're being used on a Maybe; + // otherwise, the 'w' ptr should already be set, and we fill that memory location without allocating, as usual. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if sizeHint < 0 { + sizeHint = 0 + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = &_{{ .Type | TypeSymbol }}{} + } + {{- end}} + na.w.m = make(map[_{{ .Type.KeyType | TypeSymbol }}]{{if .Type.ValueIsNullable }}Maybe{{else}}*_{{end}}{{ .Type.ValueType | TypeSymbol }}, sizeHint) + na.w.t = make([]_{{ .Type | TypeSymbol }}__entry, 0, sizeHint) + return na, nil + } + `, w, adjCfg, data) +} + +func emitNodeAssemblerMethodAssignNode_mapoid(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // AssignNode goes through three phases: + // 1. is it null? Jump over to AssignNull (which may or may not reject it). + // 2. is it our own type? Handle specially -- we might be able to do efficient things. + // 3. is it the right kind to morph into us? Do so. + // + // We do not set m=midvalue in phase 3 -- it shouldn't matter unless you're trying to pull off concurrent access, which is wrong and unsafe regardless. + // + // This works easily for both type-level and representational nodes because + // any divergences that have to do with the child value are nicely hidden behind `AssembleKey` and `AssembleValue`. + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) AssignNode(v datamodel.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_{{ .Type | TypeSymbol }}); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + {{- end}} + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != datamodel.Kind_Map { + return datamodel.ErrWrongKind{TypeName: "{{ .PkgName }}.{{ .Type.Name }}{{ if .IsRepr }}.Repr{{end}}", MethodName: "AssignNode", AppropriateKind: datamodel.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() + } + `, w, adjCfg, data) +} + +func emitNodeAssemblerHelper_mapoid_keyTidyHelper(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // This function attempts to clean up the state machine to acknolwedge key assembly finish. + // If the child was finished and we just collected it, return true and update state to maState_expectValue. + // Collecting the child includes updating the 'ma.w.m' to point into the relevant row of 'ma.w.t', since that couldn't be done earlier, + // AND initializing the 'ma.va' (since we're already holding relevant offsets into 'ma.w.t'). + // Otherwise, if it wasn't done, return false; + // and the caller is almost certain to emit an error momentarily. + // The function will only be called when the current state is maState_midKey. + // (In general, the idea is that if the user is doing things correctly, + // this function will only be called when the child is in fact finished.) + // Completion info always comes via 'cm', and we reset it to its initial condition of Maybe_Absent here. + // At the same time, we nil the 'w' pointer for the child assembler; otherwise its own state machine would probably let it modify 'w' again! + // + // DRY(nope): Can this be extracted to be a shared function between repr and type level nodes? + // It is textually identical, so... yeah, that'd be nice. But... + // Nope. It touches `ma.ka` and `ma.va` directly. + // Attempting to extract or hide those behind an interface would create virtual function calls in a very tight spot, and we don't want the execution time cost. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) keyFinishTidy() bool { + switch ma.cm { + case schema.Maybe_Value: + ma.ka.w = nil + tz := &ma.w.t[len(ma.w.t)-1] + ma.cm = schema.Maybe_Absent + ma.state = maState_expectValue + ma.w.m[tz.k] = &tz.v + {{- if .Type.ValueIsNullable }} + {{- if not (MaybeUsesPtr .Type.ValueType) }} + ma.va.w = &tz.v.v + {{- end}} + ma.va.m = &tz.v.m + tz.v.m = allowNull + {{- else}} + ma.va.w = &tz.v + ma.va.m = &ma.cm + {{- end}} + ma.ka.reset() + return true + default: + return false + } + } + `, w, adjCfg, data) +} + +func emitNodeAssemblerHelper_mapoid_valueTidyHelper(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // This function attempts to clean up the state machine to acknolwedge child value assembly finish. + // If the child was finished and we just collected it, return true and update state to maState_initial. + // Otherwise, if it wasn't done, return false; + // and the caller is almost certain to emit an error momentarily. + // The function will only be called when the current state is maState_midValue. + // (In general, the idea is that if the user is doing things correctly, + // this function will only be called when the child is in fact finished.) + // If 'cm' is used, we reset it to its initial condition of Maybe_Absent here. + // At the same time, we nil the 'w' pointer for the child assembler; otherwise its own state machine would probably let it modify 'w' again! + // + // DRY(nope): Can this be extracted to be a shared function between repr and type level nodes? + // Exact same story as the key tidy helper -- touches child assemblers concretely, and that blocks extraction. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) valueFinishTidy() bool { + {{- if .Type.ValueIsNullable }} + tz := &ma.w.t[len(ma.w.t)-1] + switch tz.v.m { + case schema.Maybe_Null: + ma.state = maState_initial + ma.va.reset() + return true + case schema.Maybe_Value: + {{- if (MaybeUsesPtr .Type.ValueType) }} + tz.v.v = ma.va.w + {{- end}} + ma.va.w = nil + ma.state = maState_initial + ma.va.reset() + return true + {{- else}} + switch ma.cm { + case schema.Maybe_Value: + ma.va.w = nil + ma.cm = schema.Maybe_Absent + ma.state = maState_initial + ma.va.reset() + return true + {{- end}} + default: + return false + } + } + `, w, adjCfg, data) +} + +func emitNodeAssemblerHelper_mapoid_mapAssemblerMethods(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // FUTURE: some of the setup of the child assemblers could probably be DRY'd up. + // + // REVIEW: there's a copy-by-value of k2 that's avoidable. But it simplifies the error path. Worth working on? + // + // REVIEW: processing the key via the reprPrototype of the key even when we're at the type level if it's type kind isn't string is currently supported, but should it be? or is that more confusing than valuable? + // Very possible that it shouldn't be supported: the full-on keyAssembler route won't accept this, so consistency with that might be best. + // On the other hand, lookups by string *do* support this kind of processing (and it must, or PathSegment utility becomes unacceptably damaged), so either way, something feels surprising. + // + // DRY(nope): Can this be extracted to a shared function in the output? + // Same story as the tidy helpers -- it touches `va` and `ka` concretely in several places, and that blocks extraction. + // + // DRY: a lot of the state transition fences again are common for all mapoids, and could probably even be a function over '*state'... + // except for the fact they need to call the valueFinishTidy function, which is another one of those points that blocks extraction because we strongly don't want virtual functions calls there. + // Maybe the templates can be textually dedup'd more, though, at least. + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) AssembleEntry(k string) (datamodel.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + + var k2 _{{ .Type.KeyType | TypeSymbol }} + {{- if or (not (eq .Type.KeyType.TypeKind.String "String")) .IsRepr }} + if err := (_{{ .Type.KeyType | TypeSymbol }}__ReprPrototype{}).fromString(&k2, k); err != nil { + return nil, err // TODO wrap in some kind of ErrInvalidKey + } + {{- else}} + if err := (_{{ .Type.KeyType | TypeSymbol }}__Prototype{}).fromString(&k2, k); err != nil { + return nil, err // TODO wrap in some kind of ErrInvalidKey + } + {{- end}} + if _, exists := ma.w.m[k2]; exists { + return nil, datamodel.ErrRepeatedMapKey{Key: &k2} + } + ma.w.t = append(ma.w.t, _{{ .Type | TypeSymbol }}__entry{k: k2}) + tz := &ma.w.t[len(ma.w.t)-1] + ma.state = maState_midValue + + ma.w.m[k2] = &tz.v + {{- if .Type.ValueIsNullable }} + {{- if not (MaybeUsesPtr .Type.ValueType) }} + ma.va.w = &tz.v.v + {{- end}} + ma.va.m = &tz.v.m + tz.v.m = allowNull + {{- else}} + ma.va.w = &tz.v + ma.va.m = &ma.cm + {{- end}} + return &ma.va, nil + } + `, w, adjCfg, data) + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) AssembleKey() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.w.t = append(ma.w.t, _{{ .Type | TypeSymbol }}__entry{}) + ma.state = maState_midKey + ma.ka.m = &ma.cm + ma.ka.w = &ma.w.t[len(ma.w.t)-1].k + return &ma.ka + } + `, w, adjCfg, data) + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) AssembleValue() datamodel.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + if !ma.keyFinishTidy() { + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + } // if tidy success: carry on + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + return &ma.va + } + `, w, adjCfg, data) + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil + } + `, w, adjCfg, data) + doTemplate(` + func (ma *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) KeyPrototype() datamodel.NodePrototype { + return _{{ .Type.KeyType | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Prototype{} + } + func (ma *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) ValuePrototype(_ string) datamodel.NodePrototype { + return _{{ .Type.ValueType | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Prototype{} + } + `, w, adjCfg, data) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsMinima.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsMinima.go new file mode 100644 index 00000000000..17f8411ab24 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsMinima.go @@ -0,0 +1,88 @@ +package gengo + +import ( + "fmt" + "io" + + "github.com/ipld/go-ipld-prime/testutil" +) + +// EmitInternalEnums creates a file with enum types used internally. +// For example, the state machine values used in map and list builders. +// These always need to exist exactly once in each package created by codegen. +// +// The file header and import statements are included in the output of this function. +// (The imports in this file are different than most others in codegen output; +// we gather up any references to other packages in this file in order to simplify the rest of codegen's awareness of imports.) +func EmitInternalEnums(packageName string, w io.Writer) { + fmt.Fprint(w, testutil.Dedent(` + package `+packageName+` + + `+doNotEditComment+` + + import ( + "fmt" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/schema" + ) + + `)) + + // The 'Maybe' enum does double-duty in this package as a state machine for assembler completion. + // + // The 'Maybe_Absent' value gains the additional semantic of "clear to assign (but not null)" + // (which works because if you're *in* a value assembler, "absent" as a final result is already off the table). + // Additionally, we get a few extra states that we cram into the same area of bits: + // - `midvalue` is used by assemblers of recursives to block AssignNull after BeginX. + // - `allowNull` is used by parent assemblers when initializing a child assembler to tell the child a transition to Maybe_Null is allowed in this context. + fmt.Fprint(w, testutil.Dedent(` + const ( + midvalue = schema.Maybe(4) + allowNull = schema.Maybe(5) + ) + + `)) + + fmt.Fprint(w, testutil.Dedent(` + type maState uint8 + + const ( + maState_initial maState = iota + maState_midKey + maState_expectValue + maState_midValue + maState_finished + ) + + type laState uint8 + + const ( + laState_initial laState = iota + laState_midValue + laState_finished + ) + `)) + + // We occasionally need this erroring thunk to be able to snake an error out from some assembly processes. + // It implements all of datamodel.NodeAssembler, but all of its methods return errors when used. + fmt.Fprint(w, testutil.Dedent(` + type _ErrorThunkAssembler struct { + e error + } + + func (ea _ErrorThunkAssembler) BeginMap(_ int64) (datamodel.MapAssembler, error) { return nil, ea.e } + func (ea _ErrorThunkAssembler) BeginList(_ int64) (datamodel.ListAssembler, error) { return nil, ea.e } + func (ea _ErrorThunkAssembler) AssignNull() error { return ea.e } + func (ea _ErrorThunkAssembler) AssignBool(bool) error { return ea.e } + func (ea _ErrorThunkAssembler) AssignInt(int64) error { return ea.e } + func (ea _ErrorThunkAssembler) AssignFloat(float64) error { return ea.e } + func (ea _ErrorThunkAssembler) AssignString(string) error { return ea.e } + func (ea _ErrorThunkAssembler) AssignBytes([]byte) error { return ea.e } + func (ea _ErrorThunkAssembler) AssignLink(datamodel.Link) error { return ea.e } + func (ea _ErrorThunkAssembler) AssignNode(datamodel.Node) error { return ea.e } + func (ea _ErrorThunkAssembler) Prototype() datamodel.NodePrototype { + panic(fmt.Errorf("cannot get prototype from error-carrying assembler: already derailed with error: %w", ea.e)) + } + `)) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsStrictoid.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsStrictoid.go new file mode 100644 index 00000000000..2bf795edc36 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/genpartsStrictoid.go @@ -0,0 +1,35 @@ +package gengo + +import ( + "io" +) + +// What's "strictoid" mean? Anything that's recursive but not infinite -- so structs, unions. + +// This form of BeginMap method is reusable for anything that has fixed size and thus ignores sizehint. +// That means: structs, unions, and their relevant representations. +func emitNodeAssemblerMethodBeginMap_strictoid(w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + // We currently disregard sizeHint. It's not relevant to us. + // We could check it strictly and emit errors; presently, we don't. + // This method contains a branch to support MaybeUsesPtr because new memory may need to be allocated. + // This allocation only happens if the 'w' ptr is nil, which means we're being used on a Maybe; + // otherwise, the 'w' ptr should already be set, and we fill that memory location without allocating, as usual. + // (Note that the Maybe we're talking about here is for us, not our children: so it applies on unions too.) + doTemplate(` + func (na *_{{ .Type | TypeSymbol }}__{{ if .IsRepr }}Repr{{end}}Assembler) BeginMap(int64) (datamodel.MapAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + {{- if .Type | MaybeUsesPtr }} + if na.w == nil { + na.w = &_{{ .Type | TypeSymbol }}{} + } + {{- end}} + return na, nil + } + `, w, adjCfg, data) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/boolGenMixin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/boolGenMixin.go new file mode 100644 index 00000000000..b048050ab14 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/boolGenMixin.go @@ -0,0 +1,103 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +type BoolTraits struct { + PkgName string + TypeName string // see doc in kindTraitsGenerator + TypeSymbol string // see doc in kindTraitsGenerator +} + +func (BoolTraits) Kind() datamodel.Kind { + return datamodel.Kind_Bool +} +func (g BoolTraits) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) Kind() datamodel.Kind { + return datamodel.Kind_Bool + } + `, w, g) +} +func (g BoolTraits) EmitNodeMethodLookupByString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodLookupByString(w) +} +func (g BoolTraits) EmitNodeMethodLookupByNode(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodLookupByNode(w) +} +func (g BoolTraits) EmitNodeMethodLookupByIndex(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodLookupByIndex(w) +} +func (g BoolTraits) EmitNodeMethodLookupBySegment(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodLookupBySegment(w) +} +func (g BoolTraits) EmitNodeMethodMapIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodMapIterator(w) +} +func (g BoolTraits) EmitNodeMethodListIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodListIterator(w) +} +func (g BoolTraits) EmitNodeMethodLength(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodLength(w) +} +func (g BoolTraits) EmitNodeMethodIsAbsent(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodIsAbsent(w) +} +func (g BoolTraits) EmitNodeMethodIsNull(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodIsNull(w) +} +func (g BoolTraits) EmitNodeMethodAsInt(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodAsInt(w) +} +func (g BoolTraits) EmitNodeMethodAsFloat(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodAsFloat(w) +} +func (g BoolTraits) EmitNodeMethodAsString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodAsString(w) +} +func (g BoolTraits) EmitNodeMethodAsBytes(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodAsBytes(w) +} +func (g BoolTraits) EmitNodeMethodAsLink(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bool}.emitNodeMethodAsLink(w) +} + +type BoolAssemblerTraits struct { + PkgName string + TypeName string // see doc in kindAssemblerTraitsGenerator + AppliedPrefix string // see doc in kindAssemblerTraitsGenerator +} + +func (BoolAssemblerTraits) Kind() datamodel.Kind { + return datamodel.Kind_Bool +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodBeginMap(w) +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodBeginList(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodBeginList(w) +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodAssignNull(w) +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodAssignInt(w) +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodAssignFloat(w) +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodAssignString(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodAssignString(w) +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodAssignBytes(w) +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodAssignLink(w) +} +func (g BoolAssemblerTraits) EmitNodeAssemblerMethodPrototype(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bool}.emitNodeAssemblerMethodPrototype(w) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/bytesGenMixin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/bytesGenMixin.go new file mode 100644 index 00000000000..953819efe2a --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/bytesGenMixin.go @@ -0,0 +1,103 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +type BytesTraits struct { + PkgName string + TypeName string // see doc in kindTraitsGenerator + TypeSymbol string // see doc in kindTraitsGenerator +} + +func (BytesTraits) Kind() datamodel.Kind { + return datamodel.Kind_Bytes +} +func (g BytesTraits) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) Kind() datamodel.Kind { + return datamodel.Kind_Bytes + } + `, w, g) +} +func (g BytesTraits) EmitNodeMethodLookupByString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodLookupByString(w) +} +func (g BytesTraits) EmitNodeMethodLookupByNode(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodLookupByNode(w) +} +func (g BytesTraits) EmitNodeMethodLookupByIndex(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodLookupByIndex(w) +} +func (g BytesTraits) EmitNodeMethodLookupBySegment(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodLookupBySegment(w) +} +func (g BytesTraits) EmitNodeMethodMapIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodMapIterator(w) +} +func (g BytesTraits) EmitNodeMethodListIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodListIterator(w) +} +func (g BytesTraits) EmitNodeMethodLength(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodLength(w) +} +func (g BytesTraits) EmitNodeMethodIsAbsent(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodIsAbsent(w) +} +func (g BytesTraits) EmitNodeMethodIsNull(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodIsNull(w) +} +func (g BytesTraits) EmitNodeMethodAsBool(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodAsBool(w) +} +func (g BytesTraits) EmitNodeMethodAsInt(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodAsInt(w) +} +func (g BytesTraits) EmitNodeMethodAsFloat(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodAsFloat(w) +} +func (g BytesTraits) EmitNodeMethodAsString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodAsString(w) +} +func (g BytesTraits) EmitNodeMethodAsLink(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Bytes}.emitNodeMethodAsLink(w) +} + +type BytesAssemblerTraits struct { + PkgName string + TypeName string // see doc in kindAssemblerTraitsGenerator + AppliedPrefix string // see doc in kindAssemblerTraitsGenerator +} + +func (BytesAssemblerTraits) Kind() datamodel.Kind { + return datamodel.Kind_Bytes +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodBeginMap(w) +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodBeginList(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodBeginList(w) +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodAssignNull(w) +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodAssignBool(w) +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodAssignInt(w) +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodAssignFloat(w) +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodAssignString(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodAssignString(w) +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodAssignLink(w) +} +func (g BytesAssemblerTraits) EmitNodeAssemblerMethodPrototype(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Bytes}.emitNodeAssemblerMethodPrototype(w) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/floatGenMixin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/floatGenMixin.go new file mode 100644 index 00000000000..8e993cefb28 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/floatGenMixin.go @@ -0,0 +1,103 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +type FloatTraits struct { + PkgName string + TypeName string // see doc in kindTraitsGenerator + TypeSymbol string // see doc in kindTraitsGenerator +} + +func (FloatTraits) Kind() datamodel.Kind { + return datamodel.Kind_Float +} +func (g FloatTraits) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) Kind() datamodel.Kind { + return datamodel.Kind_Float + } + `, w, g) +} +func (g FloatTraits) EmitNodeMethodLookupByString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodLookupByString(w) +} +func (g FloatTraits) EmitNodeMethodLookupByNode(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodLookupByNode(w) +} +func (g FloatTraits) EmitNodeMethodLookupByIndex(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodLookupByIndex(w) +} +func (g FloatTraits) EmitNodeMethodLookupBySegment(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodLookupBySegment(w) +} +func (g FloatTraits) EmitNodeMethodMapIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodMapIterator(w) +} +func (g FloatTraits) EmitNodeMethodListIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodListIterator(w) +} +func (g FloatTraits) EmitNodeMethodLength(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodLength(w) +} +func (g FloatTraits) EmitNodeMethodIsAbsent(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodIsAbsent(w) +} +func (g FloatTraits) EmitNodeMethodIsNull(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodIsNull(w) +} +func (g FloatTraits) EmitNodeMethodAsBool(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodAsBool(w) +} +func (g FloatTraits) EmitNodeMethodAsInt(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodAsInt(w) +} +func (g FloatTraits) EmitNodeMethodAsString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodAsString(w) +} +func (g FloatTraits) EmitNodeMethodAsBytes(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodAsBytes(w) +} +func (g FloatTraits) EmitNodeMethodAsLink(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Float}.emitNodeMethodAsLink(w) +} + +type FloatAssemblerTraits struct { + PkgName string + TypeName string // see doc in kindAssemblerTraitsGenerator + AppliedPrefix string // see doc in kindAssemblerTraitsGenerator +} + +func (FloatAssemblerTraits) Kind() datamodel.Kind { + return datamodel.Kind_Float +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodBeginMap(w) +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodBeginList(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodBeginList(w) +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodAssignNull(w) +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodAssignBool(w) +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodAssignInt(w) +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodAssignString(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodAssignString(w) +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodAssignBytes(w) +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodAssignLink(w) +} +func (g FloatAssemblerTraits) EmitNodeAssemblerMethodPrototype(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Float}.emitNodeAssemblerMethodPrototype(w) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/intGenMixin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/intGenMixin.go new file mode 100644 index 00000000000..c45b136bd8b --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/intGenMixin.go @@ -0,0 +1,103 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +type IntTraits struct { + PkgName string + TypeName string // see doc in kindTraitsGenerator + TypeSymbol string // see doc in kindTraitsGenerator +} + +func (IntTraits) Kind() datamodel.Kind { + return datamodel.Kind_Int +} +func (g IntTraits) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) Kind() datamodel.Kind { + return datamodel.Kind_Int + } + `, w, g) +} +func (g IntTraits) EmitNodeMethodLookupByString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodLookupByString(w) +} +func (g IntTraits) EmitNodeMethodLookupByNode(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodLookupByNode(w) +} +func (g IntTraits) EmitNodeMethodLookupByIndex(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodLookupByIndex(w) +} +func (g IntTraits) EmitNodeMethodLookupBySegment(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodLookupBySegment(w) +} +func (g IntTraits) EmitNodeMethodMapIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodMapIterator(w) +} +func (g IntTraits) EmitNodeMethodListIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodListIterator(w) +} +func (g IntTraits) EmitNodeMethodLength(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodLength(w) +} +func (g IntTraits) EmitNodeMethodIsAbsent(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodIsAbsent(w) +} +func (g IntTraits) EmitNodeMethodIsNull(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodIsNull(w) +} +func (g IntTraits) EmitNodeMethodAsBool(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodAsBool(w) +} +func (g IntTraits) EmitNodeMethodAsFloat(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodAsFloat(w) +} +func (g IntTraits) EmitNodeMethodAsString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodAsString(w) +} +func (g IntTraits) EmitNodeMethodAsBytes(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodAsBytes(w) +} +func (g IntTraits) EmitNodeMethodAsLink(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Int}.emitNodeMethodAsLink(w) +} + +type IntAssemblerTraits struct { + PkgName string + TypeName string // see doc in kindAssemblerTraitsGenerator + AppliedPrefix string // see doc in kindAssemblerTraitsGenerator +} + +func (IntAssemblerTraits) Kind() datamodel.Kind { + return datamodel.Kind_Int +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodBeginMap(w) +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodBeginList(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodBeginList(w) +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodAssignNull(w) +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodAssignBool(w) +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodAssignFloat(w) +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodAssignString(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodAssignString(w) +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodAssignBytes(w) +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodAssignLink(w) +} +func (g IntAssemblerTraits) EmitNodeAssemblerMethodPrototype(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Int}.emitNodeAssemblerMethodPrototype(w) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/kindTraits.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/kindTraits.go new file mode 100644 index 00000000000..61bf3c89feb --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/kindTraits.go @@ -0,0 +1,319 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +// kindTraitsGenerator is the center of all the other mixins, +// and handles all the method generation which is a pure function of the kind. +// +// OVERRIDE THE METHODS THAT DO APPLY TO YOUR KIND; +// the default method bodies produced by this mixin are those that return errors, +// and that is not what you want for the methods that *are* interesting for your kind. +// The kindTraitsGenerator methods will panic if called for a kind that should've overriden them. +// +// If you're implementing something that can hold "any" kind, +// probably none of these methods apply to you at all. +// +// The other types in this package use kindTraitsGenerator with a fixed Kind, +// and only forward the methods to it that don't apply for their kind; +// this means when they're used as an anonymous embed, they grant +// all the appropriate dummy methods to their container, +// while leaving the ones that are still needed entirely absent, +// so the compiler helpfully tells you to finish rather than waiting until +// runtime to panic if a should-have-been-overriden method slips through. +type kindTraitsGenerator struct { + PkgName string + TypeName string // as will be printed in messages (e.g. can be goosed up a bit, like "Thing.Repr" instead of "_Thing__Repr"). + TypeSymbol string // the identifier in code (sometimes is munged internals like "_Thing__Repr" corresponding to no publicly admitted schema.Type.Name). + Kind datamodel.Kind +} + +func (g kindTraitsGenerator) emitNodeMethodLookupByString(w io.Writer) { + if datamodel.KindSet_JustMap.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) LookupByString(string) (datamodel.Node, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByString("") + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodLookupByNode(w io.Writer) { + if datamodel.KindSet_JustMap.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) LookupByNode(datamodel.Node) (datamodel.Node, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByNode(nil) + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodLookupByIndex(w io.Writer) { + if datamodel.KindSet_JustList.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) LookupByIndex(idx int64) (datamodel.Node, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByIndex(0) + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodLookupBySegment(w io.Writer) { + if datamodel.KindSet_Recursive.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupBySegment(seg) + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodMapIterator(w io.Writer) { + if datamodel.KindSet_JustMap.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) MapIterator() datamodel.MapIterator { + return nil + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodListIterator(w io.Writer) { + if datamodel.KindSet_JustList.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) ListIterator() datamodel.ListIterator { + return nil + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodLength(w io.Writer) { + if datamodel.KindSet_Recursive.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) Length() int64 { + return -1 + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodIsAbsent(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) IsAbsent() bool { + return false + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodIsNull(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) IsNull() bool { + return false + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodAsBool(w io.Writer) { + if datamodel.KindSet_JustBool.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) AsBool() (bool, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsBool() + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodAsInt(w io.Writer) { + if datamodel.KindSet_JustInt.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) AsInt() (int64, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsInt() + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodAsFloat(w io.Writer) { + if datamodel.KindSet_JustFloat.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) AsFloat() (float64, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsFloat() + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodAsString(w io.Writer) { + if datamodel.KindSet_JustString.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) AsString() (string, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsString() + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodAsBytes(w io.Writer) { + if datamodel.KindSet_JustBytes.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) AsBytes() ([]byte, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsBytes() + } + `, w, g) +} + +func (g kindTraitsGenerator) emitNodeMethodAsLink(w io.Writer) { + if datamodel.KindSet_JustLink.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .TypeSymbol }}) AsLink() (datamodel.Link, error) { + return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsLink() + } + `, w, g) +} + +// kindAssemblerTraitsGenerator is an awfully lot like kindTraitsGenerator, +// except applying to methods for builders and assemblers. +type kindAssemblerTraitsGenerator struct { + PkgName string + TypeName string // as will be printed in messages (e.g. can be goosed up a bit, like "Thing.Repr" instead of "_Thing__Repr"). + AppliedPrefix string // the prefix of what to attach methods to... this one is a little wild: should probably be either "_{{ .Type | TypeSymbol }}__" or "_{{ .Type | TypeSymbol }}__Repr", and we'll just add the words "Builder" and "Assembler". + Kind datamodel.Kind +} + +// bailed on extracting a common emitNodeBuilderType: too many variations in content and pointer placement to be worth it. +// bailed on extracting a common emitNodeBuilderMethods: same. +// bailed on extracting a common emitNodeAssemblerType: same. +// +// If you try to do these, you'll probably need: +// - an explicit understanding of if generating representations or not +// - to still be ready for boatloads of exceptions if the representation isn't directly castable to and from the type-level node. + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodBeginMap(w io.Writer) { + if datamodel.KindSet_JustMap.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.BeginMap(0) + } + `, w, g) +} + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodBeginList(w io.Writer) { + if datamodel.KindSet_JustList.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.BeginList(0) + } + `, w, g) +} + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignNull(w io.Writer) { + if datamodel.KindSet_JustNull.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func (na *{{ .AppliedPrefix }}Assembler) AssignNull() error { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignNull() + } + `, w, g) +} + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignBool(w io.Writer) { + if datamodel.KindSet_JustBool.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) AssignBool(bool) error { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignBool(false) + } + `, w, g) +} + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignInt(w io.Writer) { + if datamodel.KindSet_JustInt.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) AssignInt(int64) error { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignInt(0) + } + `, w, g) +} + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignFloat(w io.Writer) { + if datamodel.KindSet_JustFloat.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) AssignFloat(float64) error { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignFloat(0) + } + `, w, g) +} + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignString(w io.Writer) { + if datamodel.KindSet_JustString.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) AssignString(string) error { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignString("") + } + `, w, g) +} + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignBytes(w io.Writer) { + if datamodel.KindSet_JustBytes.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) AssignBytes([]byte) error { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignBytes(nil) + } + `, w, g) +} + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignLink(w io.Writer) { + if datamodel.KindSet_JustLink.Contains(g.Kind) { + panic("gen internals error: you should've overriden this") + } + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) AssignLink(datamodel.Link) error { + return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignLink(nil) + } + `, w, g) +} + +// bailed on extracting a common emitNodeAssemblerMethodAssignNode: way too many variations. + +func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodPrototype(w io.Writer) { + doTemplate(` + func ({{ .AppliedPrefix }}Assembler) Prototype() datamodel.NodePrototype { + return {{ .AppliedPrefix }}Prototype{} + } + `, w, g) +} + +// bailed on extracting a common emitNodeAssemblerOtherBits: it's just self-evident there's nothing common there. diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/linkGenMixin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/linkGenMixin.go new file mode 100644 index 00000000000..1b8d29730e9 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/linkGenMixin.go @@ -0,0 +1,103 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +type LinkTraits struct { + PkgName string + TypeName string // see doc in kindTraitsGenerator + TypeSymbol string // see doc in kindTraitsGenerator +} + +func (LinkTraits) Kind() datamodel.Kind { + return datamodel.Kind_Link +} +func (g LinkTraits) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) Kind() datamodel.Kind { + return datamodel.Kind_Link + } + `, w, g) +} +func (g LinkTraits) EmitNodeMethodLookupByString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodLookupByString(w) +} +func (g LinkTraits) EmitNodeMethodLookupByNode(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodLookupByNode(w) +} +func (g LinkTraits) EmitNodeMethodLookupByIndex(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodLookupByIndex(w) +} +func (g LinkTraits) EmitNodeMethodLookupBySegment(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodLookupBySegment(w) +} +func (g LinkTraits) EmitNodeMethodMapIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodMapIterator(w) +} +func (g LinkTraits) EmitNodeMethodListIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodListIterator(w) +} +func (g LinkTraits) EmitNodeMethodLength(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodLength(w) +} +func (g LinkTraits) EmitNodeMethodIsAbsent(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodIsAbsent(w) +} +func (g LinkTraits) EmitNodeMethodIsNull(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodIsNull(w) +} +func (g LinkTraits) EmitNodeMethodAsBool(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodAsBool(w) +} +func (g LinkTraits) EmitNodeMethodAsInt(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodAsInt(w) +} +func (g LinkTraits) EmitNodeMethodAsFloat(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodAsFloat(w) +} +func (g LinkTraits) EmitNodeMethodAsString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodAsString(w) +} +func (g LinkTraits) EmitNodeMethodAsBytes(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Link}.emitNodeMethodAsBytes(w) +} + +type LinkAssemblerTraits struct { + PkgName string + TypeName string // see doc in kindAssemblerTraitsGenerator + AppliedPrefix string // see doc in kindAssemblerTraitsGenerator +} + +func (LinkAssemblerTraits) Kind() datamodel.Kind { + return datamodel.Kind_Link +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodBeginMap(w) +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodBeginList(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodBeginList(w) +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodAssignNull(w) +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodAssignBool(w) +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodAssignInt(w) +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodAssignFloat(w) +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodAssignString(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodAssignString(w) +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodAssignBytes(w) +} +func (g LinkAssemblerTraits) EmitNodeAssemblerMethodPrototype(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Link}.emitNodeAssemblerMethodPrototype(w) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/listGenMixin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/listGenMixin.go new file mode 100644 index 00000000000..7c26d4c23c3 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/listGenMixin.go @@ -0,0 +1,102 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +type ListTraits struct { + PkgName string + TypeName string // see doc in kindTraitsGenerator + TypeSymbol string // see doc in kindTraitsGenerator +} + +func (ListTraits) Kind() datamodel.Kind { + return datamodel.Kind_List +} +func (g ListTraits) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) Kind() datamodel.Kind { + return datamodel.Kind_List + } + `, w, g) +} +func (g ListTraits) EmitNodeMethodLookupByString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodLookupByString(w) +} +func (g ListTraits) EmitNodeMethodLookupBySegment(w io.Writer) { + doTemplate(` + func (n {{ .TypeSymbol }}) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + i, err := seg.Index() + if err != nil { + return nil, datamodel.ErrInvalidSegmentForList{TypeName: "{{ .PkgName }}.{{ .TypeName }}", TroubleSegment: seg, Reason: err} + } + return n.LookupByIndex(i) + } + `, w, g) +} +func (g ListTraits) EmitNodeMethodMapIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodMapIterator(w) +} +func (g ListTraits) EmitNodeMethodIsAbsent(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodIsAbsent(w) +} +func (g ListTraits) EmitNodeMethodIsNull(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodIsNull(w) +} +func (g ListTraits) EmitNodeMethodAsBool(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodAsBool(w) +} +func (g ListTraits) EmitNodeMethodAsInt(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodAsInt(w) +} +func (g ListTraits) EmitNodeMethodAsFloat(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodAsFloat(w) +} +func (g ListTraits) EmitNodeMethodAsString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodAsString(w) +} +func (g ListTraits) EmitNodeMethodAsBytes(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodAsBytes(w) +} +func (g ListTraits) EmitNodeMethodAsLink(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_List}.emitNodeMethodAsLink(w) +} + +type ListAssemblerTraits struct { + PkgName string + TypeName string // see doc in kindAssemblerTraitsGenerator + AppliedPrefix string // see doc in kindAssemblerTraitsGenerator +} + +func (ListAssemblerTraits) Kind() datamodel.Kind { + return datamodel.Kind_List +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodBeginMap(w) +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodAssignNull(w) +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodAssignBool(w) +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodAssignInt(w) +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodAssignFloat(w) +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodAssignString(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodAssignString(w) +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodAssignBytes(w) +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodAssignLink(w) +} +func (g ListAssemblerTraits) EmitNodeAssemblerMethodPrototype(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_List}.emitNodeAssemblerMethodPrototype(w) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/mapGenMixin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/mapGenMixin.go new file mode 100644 index 00000000000..570deccb266 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/mapGenMixin.go @@ -0,0 +1,98 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +type MapTraits struct { + PkgName string + TypeName string // see doc in kindTraitsGenerator + TypeSymbol string // see doc in kindTraitsGenerator +} + +func (MapTraits) Kind() datamodel.Kind { + return datamodel.Kind_Map +} +func (g MapTraits) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) Kind() datamodel.Kind { + return datamodel.Kind_Map + } + `, w, g) +} +func (g MapTraits) EmitNodeMethodLookupByIndex(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodLookupByIndex(w) +} +func (g MapTraits) EmitNodeMethodLookupBySegment(w io.Writer) { + doTemplate(` + func (n {{ .TypeSymbol }}) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return n.LookupByString(seg.String()) + } + `, w, g) +} +func (g MapTraits) EmitNodeMethodListIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodListIterator(w) +} +func (g MapTraits) EmitNodeMethodIsAbsent(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodIsAbsent(w) +} +func (g MapTraits) EmitNodeMethodIsNull(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodIsNull(w) +} +func (g MapTraits) EmitNodeMethodAsBool(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodAsBool(w) +} +func (g MapTraits) EmitNodeMethodAsInt(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodAsInt(w) +} +func (g MapTraits) EmitNodeMethodAsFloat(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodAsFloat(w) +} +func (g MapTraits) EmitNodeMethodAsString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodAsString(w) +} +func (g MapTraits) EmitNodeMethodAsBytes(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodAsBytes(w) +} +func (g MapTraits) EmitNodeMethodAsLink(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_Map}.emitNodeMethodAsLink(w) +} + +type MapAssemblerTraits struct { + PkgName string + TypeName string // see doc in kindAssemblerTraitsGenerator + AppliedPrefix string // see doc in kindAssemblerTraitsGenerator +} + +func (MapAssemblerTraits) Kind() datamodel.Kind { + return datamodel.Kind_Map +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodBeginList(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodBeginList(w) +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodAssignNull(w) +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodAssignBool(w) +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodAssignInt(w) +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodAssignFloat(w) +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodAssignString(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodAssignString(w) +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodAssignBytes(w) +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodAssignLink(w) +} +func (g MapAssemblerTraits) EmitNodeAssemblerMethodPrototype(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_Map}.emitNodeAssemblerMethodPrototype(w) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/stringGenMixin.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/stringGenMixin.go new file mode 100644 index 00000000000..c4e21c12f4a --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/stringGenMixin.go @@ -0,0 +1,103 @@ +package mixins + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" +) + +type StringTraits struct { + PkgName string + TypeName string // see doc in kindTraitsGenerator + TypeSymbol string // see doc in kindTraitsGenerator +} + +func (StringTraits) Kind() datamodel.Kind { + return datamodel.Kind_String +} +func (g StringTraits) EmitNodeMethodKind(w io.Writer) { + doTemplate(` + func ({{ .TypeSymbol }}) Kind() datamodel.Kind { + return datamodel.Kind_String + } + `, w, g) +} +func (g StringTraits) EmitNodeMethodLookupByString(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodLookupByString(w) +} +func (g StringTraits) EmitNodeMethodLookupByNode(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodLookupByNode(w) +} +func (g StringTraits) EmitNodeMethodLookupByIndex(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodLookupByIndex(w) +} +func (g StringTraits) EmitNodeMethodLookupBySegment(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodLookupBySegment(w) +} +func (g StringTraits) EmitNodeMethodMapIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodMapIterator(w) +} +func (g StringTraits) EmitNodeMethodListIterator(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodListIterator(w) +} +func (g StringTraits) EmitNodeMethodLength(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodLength(w) +} +func (g StringTraits) EmitNodeMethodIsAbsent(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodIsAbsent(w) +} +func (g StringTraits) EmitNodeMethodIsNull(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodIsNull(w) +} +func (g StringTraits) EmitNodeMethodAsBool(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodAsBool(w) +} +func (g StringTraits) EmitNodeMethodAsInt(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodAsInt(w) +} +func (g StringTraits) EmitNodeMethodAsFloat(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodAsFloat(w) +} +func (g StringTraits) EmitNodeMethodAsBytes(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodAsBytes(w) +} +func (g StringTraits) EmitNodeMethodAsLink(w io.Writer) { + kindTraitsGenerator{g.PkgName, g.TypeName, g.TypeSymbol, datamodel.Kind_String}.emitNodeMethodAsLink(w) +} + +type StringAssemblerTraits struct { + PkgName string + TypeName string // see doc in kindAssemblerTraitsGenerator + AppliedPrefix string // see doc in kindAssemblerTraitsGenerator +} + +func (StringAssemblerTraits) Kind() datamodel.Kind { + return datamodel.Kind_String +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodBeginMap(w) +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodBeginList(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodBeginList(w) +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodAssignNull(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodAssignNull(w) +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodAssignBool(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodAssignBool(w) +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodAssignInt(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodAssignInt(w) +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodAssignFloat(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodAssignFloat(w) +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodAssignBytes(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodAssignBytes(w) +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodAssignLink(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodAssignLink(w) +} +func (g StringAssemblerTraits) EmitNodeAssemblerMethodPrototype(w io.Writer) { + kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, datamodel.Kind_String}.emitNodeAssemblerMethodPrototype(w) +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/templateUtil.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/templateUtil.go new file mode 100644 index 00000000000..39389c2e539 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/mixins/templateUtil.go @@ -0,0 +1,20 @@ +package mixins + +import ( + "io" + "strings" + "text/template" + + "github.com/ipld/go-ipld-prime/testutil" +) + +func doTemplate(tmplstr string, w io.Writer, data interface{}) { + tmpl := template.Must(template.New(""). + Funcs(template.FuncMap{ + "title": func(s string) string { return strings.Title(s) }, //lint:ignore SA1019 cases.Title doesn't work for this + }). + Parse(testutil.Dedent(tmplstr))) + if err := tmpl.Execute(w, data); err != nil { + panic(err) + } +} diff --git a/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/templateUtil.go b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/templateUtil.go new file mode 100644 index 00000000000..ab68f044ed3 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/schema/gen/go/templateUtil.go @@ -0,0 +1,127 @@ +package gengo + +import ( + "io" + "strings" + "text/template" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/testutil" +) + +func doTemplate(tmplstr string, w io.Writer, adjCfg *AdjunctCfg, data interface{}) { + tmpl := template.Must(template.New(""). + Funcs(template.FuncMap{ + + // These methods are used for symbol munging and appear constantly, so they need to be short. + // (You could also get at them through `.AdjCfg`, but going direct saves some screen real estate.) + "TypeSymbol": adjCfg.TypeSymbol, + "FieldSymbolLower": adjCfg.FieldSymbolLower, + "FieldSymbolUpper": adjCfg.FieldSymbolUpper, + "MaybeUsesPtr": adjCfg.MaybeUsesPtr, + "Comments": adjCfg.Comments, + + // The whole AdjunctConfig can be accessed. + // Access methods like UnionMemlayout through this, as e.g. `.AdjCfg.UnionMemlayout`. + "AdjCfg": func() *AdjunctCfg { return adjCfg }, + + // "dot" is a dummy value that's equal to the original `.` expression, but stays there. + // Use this if you're inside a range or other feature that shifted the dot and you want the original. + // (This may seem silly, but empirically, I found myself writing a dummy line to store the value of dot before endering a range clause >20 times; that's plenty.) + "dot": func() interface{} { return data }, + + "KindPrim": func(k datamodel.Kind) string { + switch k { + case datamodel.Kind_Map: + panic("this isn't useful for non-scalars") + case datamodel.Kind_List: + panic("this isn't useful for non-scalars") + case datamodel.Kind_Null: + panic("this isn't useful for null") + case datamodel.Kind_Bool: + return "bool" + case datamodel.Kind_Int: + return "int64" + case datamodel.Kind_Float: + return "float64" + case datamodel.Kind_String: + return "string" + case datamodel.Kind_Bytes: + return "[]byte" + case datamodel.Kind_Link: + return "datamodel.Link" + default: + panic("invalid enumeration value!") + } + }, + "Kind": func(s string) datamodel.Kind { + switch s { + case "map": + return datamodel.Kind_Map + case "list": + return datamodel.Kind_List + case "null": + return datamodel.Kind_Null + case "bool": + return datamodel.Kind_Bool + case "int": + return datamodel.Kind_Int + case "float": + return datamodel.Kind_Float + case "string": + return datamodel.Kind_String + case "bytes": + return datamodel.Kind_Bytes + case "link": + return datamodel.Kind_Link + default: + panic("invalid enumeration value!") + } + }, + "KindSymbol": func(k datamodel.Kind) string { + switch k { + case datamodel.Kind_Map: + return "datamodel.Kind_Map" + case datamodel.Kind_List: + return "datamodel.Kind_List" + case datamodel.Kind_Null: + return "datamodel.Kind_Null" + case datamodel.Kind_Bool: + return "datamodel.Kind_Bool" + case datamodel.Kind_Int: + return "datamodel.Kind_Int" + case datamodel.Kind_Float: + return "datamodel.Kind_Float" + case datamodel.Kind_String: + return "datamodel.Kind_String" + case datamodel.Kind_Bytes: + return "datamodel.Kind_Bytes" + case datamodel.Kind_Link: + return "datamodel.Kind_Link" + default: + panic("invalid enumeration value!") + } + }, + "add": func(a, b int) int { return a + b }, + "title": func(s string) string { return strings.Title(s) }, //lint:ignore SA1019 cases.Title doesn't work for this + }). + Parse(testutil.Dedent(tmplstr))) + if err := tmpl.Execute(w, data); err != nil { + panic(err) + } +} + +// We really need to do some more composable stuff around here. +// Generators should probably be carrying down their own doTemplate methods that curry customizations. +// E.g., map generators would benefit hugely from being able to make a clause for "entTypeStrung", "mTypeStrung", etc. +// +// Open question: how exactly? Should some of this stuff should be composed by: +// - composing template fragments; +// - amending the funcmap; +// - computing the whole result and injecting it as a string; +// - ... combinations of the above? +// Adding to the complexity of the question is that sometimes we want to be +// doing composition inside the output (e.g. DRY by functions in the result, +// rather than by DRY'ing the templates). +// Best practice to make this evolve nicely is not at all obvious to this author. +// diff --git a/vendor/github.com/ipld/go-ipld-prime/testutil/indent.go b/vendor/github.com/ipld/go-ipld-prime/testutil/indent.go new file mode 100644 index 00000000000..03b774ce7b6 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/testutil/indent.go @@ -0,0 +1,50 @@ +package testutil + +import "bytes" + +// Dedent strips leading tabs from every line of a string, taking a hint of +// how many tabs should be stripped from the number of consecutive tabs found +// on the first non-empty line. Dedent also strips one leading blank +// line if it contains nothing but the linebreak. +// +// If later lines have fewer leading tab characters than the depth we intuited +// from the first line, then stripping will still only remove tab characters. +// +// Roughly, Dedent is "Do What I Mean" to normalize a heredoc string +// that contains leading indentation to make it congruent with the +// surrounding source code. +func Dedent(s string) string { + // Originally from: https://github.com/warpfork/go-wish/blob/master/indent.go + // Forked here to reduce dependencies in go-ipld-prime. + return string(DedentBytes([]byte(s))) +} + +// DedentBytes is identically to Dedent, but works on a byte slice. +func DedentBytes(bs []byte) []byte { + lines := bytes.SplitAfter(bs, []byte{'\n'}) + buf := bytes.Buffer{} + if len(lines[0]) == 1 && lines[0][0] == '\n' { + lines = lines[1:] + } + if len(lines) == 0 { + return []byte{} + } + depth := 0 + for _, r := range lines[0] { + depth++ + if r != '\t' { + depth-- + break + } + } + for _, line := range lines { + for i, r := range line { + if i < depth && r == '\t' { + continue + } + buf.Write(line[i:]) + break + } + } + return buf.Bytes() +} diff --git a/vendor/github.com/ipld/go-ipld-prime/testutil/multibytenode.go b/vendor/github.com/ipld/go-ipld-prime/testutil/multibytenode.go new file mode 100644 index 00000000000..88c87e2ac5b --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/testutil/multibytenode.go @@ -0,0 +1,147 @@ +package testutil + +import ( + "io" + + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/basicnode" +) + +var _ datamodel.Node = MultiByteNode{} +var _ datamodel.LargeBytesNode = (*MultiByteNode)(nil) + +// MultiByteNode is a node that is a concatenation of multiple byte slices. +// It's not particularly sophisticated but lets us exercise LargeBytesNode in a +// non-trivial way. +// The novel behaviour of Read() and Seek() on the AsLargeBytes is similar to +// that which would be expected from a LBN ADL, such as UnixFS sharded files. +type MultiByteNode struct { + bytes [][]byte +} + +func NewMultiByteNode(bytes ...[]byte) MultiByteNode { + return MultiByteNode{bytes: bytes} +} + +func (mbn MultiByteNode) Kind() datamodel.Kind { + return datamodel.Kind_Bytes +} + +func (mbn MultiByteNode) AsBytes() ([]byte, error) { + ret := make([]byte, 0, mbn.TotalLength()) + for _, b := range mbn.bytes { + ret = append(ret, b...) + } + return ret, nil +} + +func (mbn MultiByteNode) TotalLength() int { + var size int + for _, b := range mbn.bytes { + size += len(b) + } + return size +} + +func (mbn MultiByteNode) AsLargeBytes() (io.ReadSeeker, error) { + return &mbnReadSeeker{node: mbn}, nil +} + +func (mbn MultiByteNode) AsBool() (bool, error) { + return false, datamodel.ErrWrongKind{TypeName: "bool", MethodName: "AsBool", AppropriateKind: datamodel.KindSet_JustBytes} +} + +func (mbn MultiByteNode) AsInt() (int64, error) { + return 0, datamodel.ErrWrongKind{TypeName: "int", MethodName: "AsInt", AppropriateKind: datamodel.KindSet_JustBytes} +} + +func (mbn MultiByteNode) AsFloat() (float64, error) { + return 0, datamodel.ErrWrongKind{TypeName: "float", MethodName: "AsFloat", AppropriateKind: datamodel.KindSet_JustBytes} +} + +func (mbn MultiByteNode) AsString() (string, error) { + return "", datamodel.ErrWrongKind{TypeName: "string", MethodName: "AsString", AppropriateKind: datamodel.KindSet_JustBytes} +} + +func (mbn MultiByteNode) AsLink() (datamodel.Link, error) { + return nil, datamodel.ErrWrongKind{TypeName: "link", MethodName: "AsLink", AppropriateKind: datamodel.KindSet_JustBytes} +} + +func (mbn MultiByteNode) AsNode() (datamodel.Node, error) { + return nil, nil +} + +func (mbn MultiByteNode) Size() int { + return 0 +} + +func (mbn MultiByteNode) IsAbsent() bool { + return false +} + +func (mbn MultiByteNode) IsNull() bool { + return false +} + +func (mbn MultiByteNode) Length() int64 { + return 0 +} + +func (mbn MultiByteNode) ListIterator() datamodel.ListIterator { + return nil +} + +func (mbn MultiByteNode) MapIterator() datamodel.MapIterator { + return nil +} + +func (mbn MultiByteNode) LookupByIndex(idx int64) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{} +} + +func (mbn MultiByteNode) LookupByString(key string) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{} +} + +func (mbn MultiByteNode) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{} +} + +func (mbn MultiByteNode) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return nil, datamodel.ErrWrongKind{} +} + +func (mbn MultiByteNode) Prototype() datamodel.NodePrototype { + return basicnode.Prototype.Bytes // not really ... but it'll do for this test +} + +type mbnReadSeeker struct { + node MultiByteNode + offset int +} + +func (mbnrs *mbnReadSeeker) Read(p []byte) (int, error) { + var acc int + for _, byts := range mbnrs.node.bytes { + if mbnrs.offset-acc >= len(byts) { + acc += len(byts) + continue + } + n := copy(p, byts[mbnrs.offset-acc:]) + mbnrs.offset += n + return n, nil + } + return 0, io.EOF +} + +func (mbnrs *mbnReadSeeker) Seek(offset int64, whence int) (int64, error) { + switch whence { + case io.SeekStart: + mbnrs.offset = int(offset) + case io.SeekCurrent: + mbnrs.offset += int(offset) + case io.SeekEnd: + mbnrs.offset = mbnrs.node.TotalLength() + int(offset) + } + return int64(mbnrs.offset), nil +} diff --git a/vendor/github.com/ipld/go-ipld-prime/testutil/simplebytes.go b/vendor/github.com/ipld/go-ipld-prime/testutil/simplebytes.go new file mode 100644 index 00000000000..964d129ef81 --- /dev/null +++ b/vendor/github.com/ipld/go-ipld-prime/testutil/simplebytes.go @@ -0,0 +1,75 @@ +package testutil + +import ( + "github.com/ipld/go-ipld-prime/datamodel" + "github.com/ipld/go-ipld-prime/node/basicnode" + "github.com/ipld/go-ipld-prime/node/mixins" +) + +var _ datamodel.Node = simpleBytes(nil) + +// simpleBytes is like basicnode's plainBytes but it doesn't implement +// LargeBytesNode so we can exercise the non-LBN case. +type simpleBytes []byte + +// NewSimpleBytes is identical to basicnode.NewBytes but the returned node +// doesn't implement LargeBytesNode, which can be useful for testing cases +// where we want to exercise non-LBN code paths. +func NewSimpleBytes(value []byte) datamodel.Node { + v := simpleBytes(value) + return &v +} + +// -- Node interface methods --> + +func (simpleBytes) Kind() datamodel.Kind { + return datamodel.Kind_Bytes +} +func (simpleBytes) LookupByString(string) (datamodel.Node, error) { + return mixins.Bytes{TypeName: "bytes"}.LookupByString("") +} +func (simpleBytes) LookupByNode(key datamodel.Node) (datamodel.Node, error) { + return mixins.Bytes{TypeName: "bytes"}.LookupByNode(nil) +} +func (simpleBytes) LookupByIndex(idx int64) (datamodel.Node, error) { + return mixins.Bytes{TypeName: "bytes"}.LookupByIndex(0) +} +func (simpleBytes) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { + return mixins.Bytes{TypeName: "bytes"}.LookupBySegment(seg) +} +func (simpleBytes) MapIterator() datamodel.MapIterator { + return nil +} +func (simpleBytes) ListIterator() datamodel.ListIterator { + return nil +} +func (simpleBytes) Length() int64 { + return -1 +} +func (simpleBytes) IsAbsent() bool { + return false +} +func (simpleBytes) IsNull() bool { + return false +} +func (simpleBytes) AsBool() (bool, error) { + return mixins.Bytes{TypeName: "bytes"}.AsBool() +} +func (simpleBytes) AsInt() (int64, error) { + return mixins.Bytes{TypeName: "bytes"}.AsInt() +} +func (simpleBytes) AsFloat() (float64, error) { + return mixins.Bytes{TypeName: "bytes"}.AsFloat() +} +func (simpleBytes) AsString() (string, error) { + return mixins.Bytes{TypeName: "bytes"}.AsString() +} +func (n simpleBytes) AsBytes() ([]byte, error) { + return []byte(n), nil +} +func (simpleBytes) AsLink() (datamodel.Link, error) { + return mixins.Bytes{TypeName: "bytes"}.AsLink() +} +func (simpleBytes) Prototype() datamodel.NodePrototype { + return basicnode.Prototype__Bytes{} +} diff --git a/vendor/github.com/marten-seemann/qtls-go1-18/generate_cert.go b/vendor/github.com/marten-seemann/qtls-go1-18/generate_cert.go new file mode 100644 index 00000000000..74509c9deaa --- /dev/null +++ b/vendor/github.com/marten-seemann/qtls-go1-18/generate_cert.go @@ -0,0 +1,172 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +// Generate a self-signed X.509 certificate for a TLS server. Outputs to +// 'cert.pem' and 'key.pem' and will overwrite existing files. + +package main + +import ( + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "flag" + "log" + "math/big" + "net" + "os" + "strings" + "time" +) + +var ( + host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") + validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") + validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") + isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") + rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set") + ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521") + ed25519Key = flag.Bool("ed25519", false, "Generate an Ed25519 key") +) + +func publicKey(priv any) any { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &k.PublicKey + case *ecdsa.PrivateKey: + return &k.PublicKey + case ed25519.PrivateKey: + return k.Public().(ed25519.PublicKey) + default: + return nil + } +} + +func main() { + flag.Parse() + + if len(*host) == 0 { + log.Fatalf("Missing required --host parameter") + } + + var priv any + var err error + switch *ecdsaCurve { + case "": + if *ed25519Key { + _, priv, err = ed25519.GenerateKey(rand.Reader) + } else { + priv, err = rsa.GenerateKey(rand.Reader, *rsaBits) + } + case "P224": + priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) + case "P256": + priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + case "P384": + priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + case "P521": + priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + default: + log.Fatalf("Unrecognized elliptic curve: %q", *ecdsaCurve) + } + if err != nil { + log.Fatalf("Failed to generate private key: %v", err) + } + + // ECDSA, ED25519 and RSA subject keys should have the DigitalSignature + // KeyUsage bits set in the x509.Certificate template + keyUsage := x509.KeyUsageDigitalSignature + // Only RSA subject keys should have the KeyEncipherment KeyUsage bits set. In + // the context of TLS this KeyUsage is particular to RSA key exchange and + // authentication. + if _, isRSA := priv.(*rsa.PrivateKey); isRSA { + keyUsage |= x509.KeyUsageKeyEncipherment + } + + var notBefore time.Time + if len(*validFrom) == 0 { + notBefore = time.Now() + } else { + notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) + if err != nil { + log.Fatalf("Failed to parse creation date: %v", err) + } + } + + notAfter := notBefore.Add(*validFor) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("Failed to generate serial number: %v", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Acme Co"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: keyUsage, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + hosts := strings.Split(*host, ",") + for _, h := range hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } + + if *isCA { + template.IsCA = true + template.KeyUsage |= x509.KeyUsageCertSign + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) + if err != nil { + log.Fatalf("Failed to create certificate: %v", err) + } + + certOut, err := os.Create("cert.pem") + if err != nil { + log.Fatalf("Failed to open cert.pem for writing: %v", err) + } + if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { + log.Fatalf("Failed to write data to cert.pem: %v", err) + } + if err := certOut.Close(); err != nil { + log.Fatalf("Error closing cert.pem: %v", err) + } + log.Print("wrote cert.pem\n") + + keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + log.Fatalf("Failed to open key.pem for writing: %v", err) + return + } + privBytes, err := x509.MarshalPKCS8PrivateKey(priv) + if err != nil { + log.Fatalf("Unable to marshal private key: %v", err) + } + if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil { + log.Fatalf("Failed to write data to key.pem: %v", err) + } + if err := keyOut.Close(); err != nil { + log.Fatalf("Error closing key.pem: %v", err) + } + log.Print("wrote key.pem\n") +} diff --git a/vendor/github.com/multiformats/go-multicodec/gen.go b/vendor/github.com/multiformats/go-multicodec/gen.go new file mode 100644 index 00000000000..dcd44834415 --- /dev/null +++ b/vendor/github.com/multiformats/go-multicodec/gen.go @@ -0,0 +1,137 @@ +//go:build ignore + +package main + +import ( + "encoding/csv" + "io" + "log" + "os" + "sort" + "strings" + "text/template" + "unicode" + "unicode/utf8" +) + +const codeTemplate = ` +// Code generated by gen.go; DO NOT EDIT. + +package multicodec + +const ( +{{- range .Entries }} + // {{ if .IsDeprecated }}Deprecated: {{ end }}{{ .ConstName }} is a {{ .Status }} code tagged "{{ .Tag }}"{{ if .Description }} and described by: {{ .Description }}{{ end }}. + {{ .ConstName }} Code = {{ .Code }} // {{ .Name }} +{{ end -}} +) + +var knownCodes = []Code{ +{{- range .Entries }} + {{ .ConstName }}, +{{- end }} +} + +func (c Code) Tag() string { + switch c { +{{- range $i, $tag := .Tags }} + case {{ $first := true }} + {{- range $.Entries }} + {{- /* we don't include the only deprecated code, as it's a duplicate */ -}} + {{- if not .IsDeprecated }}{{ if eq .Tag $tag }} + {{- if not $first }}, +{{ end }}{{ $first = false -}} + {{ .ConstName -}} + {{ end }}{{ end -}} + {{ end -}} + : + return {{ printf "%q" $tag }} +{{ end -}} + default: + return "" + } +} +` + +type tableEntry struct { + Name string + Tag string + Code string + Status string + Description string +} + +func (c tableEntry) IsDeprecated() bool { + return strings.Contains(c.Description, "deprecated") +} + +func (c tableEntry) ConstName() string { + var b strings.Builder + var last rune + for _, part := range strings.Split(c.Name, "-") { + first, firstSize := utf8.DecodeRuneInString(part) + if unicode.IsNumber(last) && unicode.IsNumber(first) { + // 123-456 should result in 123_456 for readability. + b.WriteByte('_') + } + b.WriteRune(unicode.ToUpper(first)) + b.WriteString(part[firstSize:]) + last, _ = utf8.DecodeLastRuneInString(part) + } + return b.String() +} + +func main() { + f, err := os.Open("multicodec/table.csv") + if err != nil { + log.Fatal(err) + } + defer f.Close() + + var tmplData struct { + Entries []tableEntry + Tags []string + } + tags := make(map[string]bool) + csvReader := csv.NewReader(f) + csvReader.Read() // skip the header line + for { + record, err := csvReader.Read() + if err == io.EOF { + break + } + if err != nil { + log.Fatal(err) + } + entry := tableEntry{ + Name: strings.TrimSpace(record[0]), + Tag: strings.TrimSpace(record[1]), + Code: strings.TrimSpace(record[2]), + Status: strings.TrimSpace(record[3]), + Description: strings.TrimSpace(record[4]), + } + tmplData.Entries = append(tmplData.Entries, entry) + tags[entry.Tag] = true // use a map to deduplicate + } + for tag := range tags { + tmplData.Tags = append(tmplData.Tags, tag) + } + sort.Strings(tmplData.Tags) + + tmpl, err := template.New(""). + Funcs(template.FuncMap{"ToTitle": strings.Title}). + Parse(codeTemplate) + if err != nil { + log.Fatal(err) + } + + out, err := os.Create("code_table.go") + if err != nil { + log.Fatal(err) + } + defer out.Close() + + if err := tmpl.Execute(out, tmplData); err != nil { + log.Fatal(err) + } +} diff --git a/vendor/go.uber.org/zap/zapgrpc/zapgrpc.go b/vendor/go.uber.org/zap/zapgrpc/zapgrpc.go new file mode 100644 index 00000000000..71ca30b5113 --- /dev/null +++ b/vendor/go.uber.org/zap/zapgrpc/zapgrpc.go @@ -0,0 +1,245 @@ +// Copyright (c) 2016 Uber Technologies, Inc. +// +// 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. + +// Package zapgrpc provides a logger that is compatible with grpclog. +package zapgrpc // import "go.uber.org/zap/zapgrpc" + +import ( + "fmt" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +// See https://github.com/grpc/grpc-go/blob/v1.35.0/grpclog/loggerv2.go#L77-L86 +const ( + grpcLvlInfo = 0 + grpcLvlWarn = 1 + grpcLvlError = 2 + grpcLvlFatal = 3 +) + +var ( + // _grpcToZapLevel maps gRPC log levels to zap log levels. + // See https://pkg.go.dev/go.uber.org/zap@v1.16.0/zapcore#Level + _grpcToZapLevel = map[int]zapcore.Level{ + grpcLvlInfo: zapcore.InfoLevel, + grpcLvlWarn: zapcore.WarnLevel, + grpcLvlError: zapcore.ErrorLevel, + grpcLvlFatal: zapcore.FatalLevel, + } +) + +// An Option overrides a Logger's default configuration. +type Option interface { + apply(*Logger) +} + +type optionFunc func(*Logger) + +func (f optionFunc) apply(log *Logger) { + f(log) +} + +// WithDebug configures a Logger to print at zap's DebugLevel instead of +// InfoLevel. +// It only affects the Printf, Println and Print methods, which are only used in the gRPC v1 grpclog.Logger API. +// +// Deprecated: use grpclog.SetLoggerV2() for v2 API. +func WithDebug() Option { + return optionFunc(func(logger *Logger) { + logger.print = &printer{ + enab: logger.levelEnabler, + level: zapcore.DebugLevel, + print: logger.delegate.Debug, + printf: logger.delegate.Debugf, + } + }) +} + +// withWarn redirects the fatal level to the warn level, which makes testing +// easier. This is intentionally unexported. +func withWarn() Option { + return optionFunc(func(logger *Logger) { + logger.fatal = &printer{ + enab: logger.levelEnabler, + level: zapcore.WarnLevel, + print: logger.delegate.Warn, + printf: logger.delegate.Warnf, + } + }) +} + +// NewLogger returns a new Logger. +func NewLogger(l *zap.Logger, options ...Option) *Logger { + logger := &Logger{ + delegate: l.Sugar(), + levelEnabler: l.Core(), + } + logger.print = &printer{ + enab: logger.levelEnabler, + level: zapcore.InfoLevel, + print: logger.delegate.Info, + printf: logger.delegate.Infof, + } + logger.fatal = &printer{ + enab: logger.levelEnabler, + level: zapcore.FatalLevel, + print: logger.delegate.Fatal, + printf: logger.delegate.Fatalf, + } + for _, option := range options { + option.apply(logger) + } + return logger +} + +// printer implements Print, Printf, and Println operations for a Zap level. +// +// We use it to customize Debug vs Info, and Warn vs Fatal for Print and Fatal +// respectively. +type printer struct { + enab zapcore.LevelEnabler + level zapcore.Level + print func(...interface{}) + printf func(string, ...interface{}) +} + +func (v *printer) Print(args ...interface{}) { + v.print(args...) +} + +func (v *printer) Printf(format string, args ...interface{}) { + v.printf(format, args...) +} + +func (v *printer) Println(args ...interface{}) { + if v.enab.Enabled(v.level) { + v.print(sprintln(args)) + } +} + +// Logger adapts zap's Logger to be compatible with grpclog.LoggerV2 and the deprecated grpclog.Logger. +type Logger struct { + delegate *zap.SugaredLogger + levelEnabler zapcore.LevelEnabler + print *printer + fatal *printer + // printToDebug bool + // fatalToWarn bool +} + +// Print implements grpclog.Logger. +// +// Deprecated: use [Logger.Info]. +func (l *Logger) Print(args ...interface{}) { + l.print.Print(args...) +} + +// Printf implements grpclog.Logger. +// +// Deprecated: use [Logger.Infof]. +func (l *Logger) Printf(format string, args ...interface{}) { + l.print.Printf(format, args...) +} + +// Println implements grpclog.Logger. +// +// Deprecated: use [Logger.Info]. +func (l *Logger) Println(args ...interface{}) { + l.print.Println(args...) +} + +// Info implements grpclog.LoggerV2. +func (l *Logger) Info(args ...interface{}) { + l.delegate.Info(args...) +} + +// Infoln implements grpclog.LoggerV2. +func (l *Logger) Infoln(args ...interface{}) { + if l.levelEnabler.Enabled(zapcore.InfoLevel) { + l.delegate.Info(sprintln(args)) + } +} + +// Infof implements grpclog.LoggerV2. +func (l *Logger) Infof(format string, args ...interface{}) { + l.delegate.Infof(format, args...) +} + +// Warning implements grpclog.LoggerV2. +func (l *Logger) Warning(args ...interface{}) { + l.delegate.Warn(args...) +} + +// Warningln implements grpclog.LoggerV2. +func (l *Logger) Warningln(args ...interface{}) { + if l.levelEnabler.Enabled(zapcore.WarnLevel) { + l.delegate.Warn(sprintln(args)) + } +} + +// Warningf implements grpclog.LoggerV2. +func (l *Logger) Warningf(format string, args ...interface{}) { + l.delegate.Warnf(format, args...) +} + +// Error implements grpclog.LoggerV2. +func (l *Logger) Error(args ...interface{}) { + l.delegate.Error(args...) +} + +// Errorln implements grpclog.LoggerV2. +func (l *Logger) Errorln(args ...interface{}) { + if l.levelEnabler.Enabled(zapcore.ErrorLevel) { + l.delegate.Error(sprintln(args)) + } +} + +// Errorf implements grpclog.LoggerV2. +func (l *Logger) Errorf(format string, args ...interface{}) { + l.delegate.Errorf(format, args...) +} + +// Fatal implements grpclog.LoggerV2. +func (l *Logger) Fatal(args ...interface{}) { + l.fatal.Print(args...) +} + +// Fatalln implements grpclog.LoggerV2. +func (l *Logger) Fatalln(args ...interface{}) { + l.fatal.Println(args...) +} + +// Fatalf implements grpclog.LoggerV2. +func (l *Logger) Fatalf(format string, args ...interface{}) { + l.fatal.Printf(format, args...) +} + +// V implements grpclog.LoggerV2. +func (l *Logger) V(level int) bool { + return l.levelEnabler.Enabled(_grpcToZapLevel[level]) +} + +func sprintln(args []interface{}) string { + s := fmt.Sprintln(args...) + // Drop the new line character added by Sprintln + return s[:len(s)-1] +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/annotations.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/annotations.pb.go new file mode 100644 index 00000000000..191bea48c86 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/annotations.pb.go @@ -0,0 +1,119 @@ +// Copyright 2015 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.2 +// source: google/api/annotations.proto + +package annotations + +import ( + reflect "reflect" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var file_google_api_annotations_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*HttpRule)(nil), + Field: 72295728, + Name: "google.api.http", + Tag: "bytes,72295728,opt,name=http", + Filename: "google/api/annotations.proto", + }, +} + +// Extension fields to descriptorpb.MethodOptions. +var ( + // See `HttpRule`. + // + // optional google.api.HttpRule http = 72295728; + E_Http = &file_google_api_annotations_proto_extTypes[0] +) + +var File_google_api_annotations_proto protoreflect.FileDescriptor + +var file_google_api_annotations_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x15, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x3a, 0x4b, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x1e, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb0, 0xca, 0xbc, 0x22, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, + 0x42, 0x6e, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, + 0x70, 0x69, 0x42, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, + 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa2, 0x02, 0x04, 0x47, 0x41, 0x50, 0x49, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_google_api_annotations_proto_goTypes = []interface{}{ + (*descriptorpb.MethodOptions)(nil), // 0: google.protobuf.MethodOptions + (*HttpRule)(nil), // 1: google.api.HttpRule +} +var file_google_api_annotations_proto_depIdxs = []int32{ + 0, // 0: google.api.http:extendee -> google.protobuf.MethodOptions + 1, // 1: google.api.http:type_name -> google.api.HttpRule + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 1, // [1:2] is the sub-list for extension type_name + 0, // [0:1] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_google_api_annotations_proto_init() } +func file_google_api_annotations_proto_init() { + if File_google_api_annotations_proto != nil { + return + } + file_google_api_http_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_api_annotations_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 1, + NumServices: 0, + }, + GoTypes: file_google_api_annotations_proto_goTypes, + DependencyIndexes: file_google_api_annotations_proto_depIdxs, + ExtensionInfos: file_google_api_annotations_proto_extTypes, + }.Build() + File_google_api_annotations_proto = out.File + file_google_api_annotations_proto_rawDesc = nil + file_google_api_annotations_proto_goTypes = nil + file_google_api_annotations_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go new file mode 100644 index 00000000000..4c91534d5a9 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go @@ -0,0 +1,1655 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.21.9 +// source: google/api/client.proto + +package annotations + +import ( + reflect "reflect" + sync "sync" + + api "google.golang.org/genproto/googleapis/api" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + durationpb "google.golang.org/protobuf/types/known/durationpb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The organization for which the client libraries are being published. +// Affects the url where generated docs are published, etc. +type ClientLibraryOrganization int32 + +const ( + // Not useful. + ClientLibraryOrganization_CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED ClientLibraryOrganization = 0 + // Google Cloud Platform Org. + ClientLibraryOrganization_CLOUD ClientLibraryOrganization = 1 + // Ads (Advertising) Org. + ClientLibraryOrganization_ADS ClientLibraryOrganization = 2 + // Photos Org. + ClientLibraryOrganization_PHOTOS ClientLibraryOrganization = 3 + // Street View Org. + ClientLibraryOrganization_STREET_VIEW ClientLibraryOrganization = 4 +) + +// Enum value maps for ClientLibraryOrganization. +var ( + ClientLibraryOrganization_name = map[int32]string{ + 0: "CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED", + 1: "CLOUD", + 2: "ADS", + 3: "PHOTOS", + 4: "STREET_VIEW", + } + ClientLibraryOrganization_value = map[string]int32{ + "CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED": 0, + "CLOUD": 1, + "ADS": 2, + "PHOTOS": 3, + "STREET_VIEW": 4, + } +) + +func (x ClientLibraryOrganization) Enum() *ClientLibraryOrganization { + p := new(ClientLibraryOrganization) + *p = x + return p +} + +func (x ClientLibraryOrganization) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ClientLibraryOrganization) Descriptor() protoreflect.EnumDescriptor { + return file_google_api_client_proto_enumTypes[0].Descriptor() +} + +func (ClientLibraryOrganization) Type() protoreflect.EnumType { + return &file_google_api_client_proto_enumTypes[0] +} + +func (x ClientLibraryOrganization) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ClientLibraryOrganization.Descriptor instead. +func (ClientLibraryOrganization) EnumDescriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{0} +} + +// To where should client libraries be published? +type ClientLibraryDestination int32 + +const ( + // Client libraries will neither be generated nor published to package + // managers. + ClientLibraryDestination_CLIENT_LIBRARY_DESTINATION_UNSPECIFIED ClientLibraryDestination = 0 + // Generate the client library in a repo under github.com/googleapis, + // but don't publish it to package managers. + ClientLibraryDestination_GITHUB ClientLibraryDestination = 10 + // Publish the library to package managers like nuget.org and npmjs.com. + ClientLibraryDestination_PACKAGE_MANAGER ClientLibraryDestination = 20 +) + +// Enum value maps for ClientLibraryDestination. +var ( + ClientLibraryDestination_name = map[int32]string{ + 0: "CLIENT_LIBRARY_DESTINATION_UNSPECIFIED", + 10: "GITHUB", + 20: "PACKAGE_MANAGER", + } + ClientLibraryDestination_value = map[string]int32{ + "CLIENT_LIBRARY_DESTINATION_UNSPECIFIED": 0, + "GITHUB": 10, + "PACKAGE_MANAGER": 20, + } +) + +func (x ClientLibraryDestination) Enum() *ClientLibraryDestination { + p := new(ClientLibraryDestination) + *p = x + return p +} + +func (x ClientLibraryDestination) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ClientLibraryDestination) Descriptor() protoreflect.EnumDescriptor { + return file_google_api_client_proto_enumTypes[1].Descriptor() +} + +func (ClientLibraryDestination) Type() protoreflect.EnumType { + return &file_google_api_client_proto_enumTypes[1] +} + +func (x ClientLibraryDestination) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ClientLibraryDestination.Descriptor instead. +func (ClientLibraryDestination) EnumDescriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{1} +} + +// Required information for every language. +type CommonLanguageSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Link to automatically generated reference documentation. Example: + // https://cloud.google.com/nodejs/docs/reference/asset/latest + // + // Deprecated: Do not use. + ReferenceDocsUri string `protobuf:"bytes,1,opt,name=reference_docs_uri,json=referenceDocsUri,proto3" json:"reference_docs_uri,omitempty"` + // The destination where API teams want this client library to be published. + Destinations []ClientLibraryDestination `protobuf:"varint,2,rep,packed,name=destinations,proto3,enum=google.api.ClientLibraryDestination" json:"destinations,omitempty"` +} + +func (x *CommonLanguageSettings) Reset() { + *x = CommonLanguageSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommonLanguageSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommonLanguageSettings) ProtoMessage() {} + +func (x *CommonLanguageSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommonLanguageSettings.ProtoReflect.Descriptor instead. +func (*CommonLanguageSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{0} +} + +// Deprecated: Do not use. +func (x *CommonLanguageSettings) GetReferenceDocsUri() string { + if x != nil { + return x.ReferenceDocsUri + } + return "" +} + +func (x *CommonLanguageSettings) GetDestinations() []ClientLibraryDestination { + if x != nil { + return x.Destinations + } + return nil +} + +// Details about how and where to publish client libraries. +type ClientLibrarySettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Version of the API to apply these settings to. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // Launch stage of this version of the API. + LaunchStage api.LaunchStage `protobuf:"varint,2,opt,name=launch_stage,json=launchStage,proto3,enum=google.api.LaunchStage" json:"launch_stage,omitempty"` + // When using transport=rest, the client request will encode enums as + // numbers rather than strings. + RestNumericEnums bool `protobuf:"varint,3,opt,name=rest_numeric_enums,json=restNumericEnums,proto3" json:"rest_numeric_enums,omitempty"` + // Settings for legacy Java features, supported in the Service YAML. + JavaSettings *JavaSettings `protobuf:"bytes,21,opt,name=java_settings,json=javaSettings,proto3" json:"java_settings,omitempty"` + // Settings for C++ client libraries. + CppSettings *CppSettings `protobuf:"bytes,22,opt,name=cpp_settings,json=cppSettings,proto3" json:"cpp_settings,omitempty"` + // Settings for PHP client libraries. + PhpSettings *PhpSettings `protobuf:"bytes,23,opt,name=php_settings,json=phpSettings,proto3" json:"php_settings,omitempty"` + // Settings for Python client libraries. + PythonSettings *PythonSettings `protobuf:"bytes,24,opt,name=python_settings,json=pythonSettings,proto3" json:"python_settings,omitempty"` + // Settings for Node client libraries. + NodeSettings *NodeSettings `protobuf:"bytes,25,opt,name=node_settings,json=nodeSettings,proto3" json:"node_settings,omitempty"` + // Settings for .NET client libraries. + DotnetSettings *DotnetSettings `protobuf:"bytes,26,opt,name=dotnet_settings,json=dotnetSettings,proto3" json:"dotnet_settings,omitempty"` + // Settings for Ruby client libraries. + RubySettings *RubySettings `protobuf:"bytes,27,opt,name=ruby_settings,json=rubySettings,proto3" json:"ruby_settings,omitempty"` + // Settings for Go client libraries. + GoSettings *GoSettings `protobuf:"bytes,28,opt,name=go_settings,json=goSettings,proto3" json:"go_settings,omitempty"` +} + +func (x *ClientLibrarySettings) Reset() { + *x = ClientLibrarySettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientLibrarySettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientLibrarySettings) ProtoMessage() {} + +func (x *ClientLibrarySettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientLibrarySettings.ProtoReflect.Descriptor instead. +func (*ClientLibrarySettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{1} +} + +func (x *ClientLibrarySettings) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ClientLibrarySettings) GetLaunchStage() api.LaunchStage { + if x != nil { + return x.LaunchStage + } + return api.LaunchStage_LAUNCH_STAGE_UNSPECIFIED +} + +func (x *ClientLibrarySettings) GetRestNumericEnums() bool { + if x != nil { + return x.RestNumericEnums + } + return false +} + +func (x *ClientLibrarySettings) GetJavaSettings() *JavaSettings { + if x != nil { + return x.JavaSettings + } + return nil +} + +func (x *ClientLibrarySettings) GetCppSettings() *CppSettings { + if x != nil { + return x.CppSettings + } + return nil +} + +func (x *ClientLibrarySettings) GetPhpSettings() *PhpSettings { + if x != nil { + return x.PhpSettings + } + return nil +} + +func (x *ClientLibrarySettings) GetPythonSettings() *PythonSettings { + if x != nil { + return x.PythonSettings + } + return nil +} + +func (x *ClientLibrarySettings) GetNodeSettings() *NodeSettings { + if x != nil { + return x.NodeSettings + } + return nil +} + +func (x *ClientLibrarySettings) GetDotnetSettings() *DotnetSettings { + if x != nil { + return x.DotnetSettings + } + return nil +} + +func (x *ClientLibrarySettings) GetRubySettings() *RubySettings { + if x != nil { + return x.RubySettings + } + return nil +} + +func (x *ClientLibrarySettings) GetGoSettings() *GoSettings { + if x != nil { + return x.GoSettings + } + return nil +} + +// This message configures the settings for publishing [Google Cloud Client +// libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) +// generated from the service config. +type Publishing struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of API method settings, e.g. the behavior for methods that use the + // long-running operation pattern. + MethodSettings []*MethodSettings `protobuf:"bytes,2,rep,name=method_settings,json=methodSettings,proto3" json:"method_settings,omitempty"` + // Link to a place that API users can report issues. Example: + // https://issuetracker.google.com/issues/new?component=190865&template=1161103 + NewIssueUri string `protobuf:"bytes,101,opt,name=new_issue_uri,json=newIssueUri,proto3" json:"new_issue_uri,omitempty"` + // Link to product home page. Example: + // https://cloud.google.com/asset-inventory/docs/overview + DocumentationUri string `protobuf:"bytes,102,opt,name=documentation_uri,json=documentationUri,proto3" json:"documentation_uri,omitempty"` + // Used as a tracking tag when collecting data about the APIs developer + // relations artifacts like docs, packages delivered to package managers, + // etc. Example: "speech". + ApiShortName string `protobuf:"bytes,103,opt,name=api_short_name,json=apiShortName,proto3" json:"api_short_name,omitempty"` + // GitHub label to apply to issues and pull requests opened for this API. + GithubLabel string `protobuf:"bytes,104,opt,name=github_label,json=githubLabel,proto3" json:"github_label,omitempty"` + // GitHub teams to be added to CODEOWNERS in the directory in GitHub + // containing source code for the client libraries for this API. + CodeownerGithubTeams []string `protobuf:"bytes,105,rep,name=codeowner_github_teams,json=codeownerGithubTeams,proto3" json:"codeowner_github_teams,omitempty"` + // A prefix used in sample code when demarking regions to be included in + // documentation. + DocTagPrefix string `protobuf:"bytes,106,opt,name=doc_tag_prefix,json=docTagPrefix,proto3" json:"doc_tag_prefix,omitempty"` + // For whom the client library is being published. + Organization ClientLibraryOrganization `protobuf:"varint,107,opt,name=organization,proto3,enum=google.api.ClientLibraryOrganization" json:"organization,omitempty"` + // Client library settings. If the same version string appears multiple + // times in this list, then the last one wins. Settings from earlier + // settings with the same version string are discarded. + LibrarySettings []*ClientLibrarySettings `protobuf:"bytes,109,rep,name=library_settings,json=librarySettings,proto3" json:"library_settings,omitempty"` +} + +func (x *Publishing) Reset() { + *x = Publishing{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Publishing) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Publishing) ProtoMessage() {} + +func (x *Publishing) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Publishing.ProtoReflect.Descriptor instead. +func (*Publishing) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{2} +} + +func (x *Publishing) GetMethodSettings() []*MethodSettings { + if x != nil { + return x.MethodSettings + } + return nil +} + +func (x *Publishing) GetNewIssueUri() string { + if x != nil { + return x.NewIssueUri + } + return "" +} + +func (x *Publishing) GetDocumentationUri() string { + if x != nil { + return x.DocumentationUri + } + return "" +} + +func (x *Publishing) GetApiShortName() string { + if x != nil { + return x.ApiShortName + } + return "" +} + +func (x *Publishing) GetGithubLabel() string { + if x != nil { + return x.GithubLabel + } + return "" +} + +func (x *Publishing) GetCodeownerGithubTeams() []string { + if x != nil { + return x.CodeownerGithubTeams + } + return nil +} + +func (x *Publishing) GetDocTagPrefix() string { + if x != nil { + return x.DocTagPrefix + } + return "" +} + +func (x *Publishing) GetOrganization() ClientLibraryOrganization { + if x != nil { + return x.Organization + } + return ClientLibraryOrganization_CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED +} + +func (x *Publishing) GetLibrarySettings() []*ClientLibrarySettings { + if x != nil { + return x.LibrarySettings + } + return nil +} + +// Settings for Java client libraries. +type JavaSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The package name to use in Java. Clobbers the java_package option + // set in the protobuf. This should be used **only** by APIs + // who have already set the language_settings.java.package_name" field + // in gapic.yaml. API teams should use the protobuf java_package option + // where possible. + // + // Example of a YAML configuration:: + // + // publishing: + // java_settings: + // library_package: com.google.cloud.pubsub.v1 + LibraryPackage string `protobuf:"bytes,1,opt,name=library_package,json=libraryPackage,proto3" json:"library_package,omitempty"` + // Configure the Java class name to use instead of the service's for its + // corresponding generated GAPIC client. Keys are fully-qualified + // service names as they appear in the protobuf (including the full + // the language_settings.java.interface_names" field in gapic.yaml. API + // teams should otherwise use the service name as it appears in the + // protobuf. + // + // Example of a YAML configuration:: + // + // publishing: + // java_settings: + // service_class_names: + // - google.pubsub.v1.Publisher: TopicAdmin + // - google.pubsub.v1.Subscriber: SubscriptionAdmin + ServiceClassNames map[string]string `protobuf:"bytes,2,rep,name=service_class_names,json=serviceClassNames,proto3" json:"service_class_names,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Some settings. + Common *CommonLanguageSettings `protobuf:"bytes,3,opt,name=common,proto3" json:"common,omitempty"` +} + +func (x *JavaSettings) Reset() { + *x = JavaSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *JavaSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JavaSettings) ProtoMessage() {} + +func (x *JavaSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JavaSettings.ProtoReflect.Descriptor instead. +func (*JavaSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{3} +} + +func (x *JavaSettings) GetLibraryPackage() string { + if x != nil { + return x.LibraryPackage + } + return "" +} + +func (x *JavaSettings) GetServiceClassNames() map[string]string { + if x != nil { + return x.ServiceClassNames + } + return nil +} + +func (x *JavaSettings) GetCommon() *CommonLanguageSettings { + if x != nil { + return x.Common + } + return nil +} + +// Settings for C++ client libraries. +type CppSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Some settings. + Common *CommonLanguageSettings `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"` +} + +func (x *CppSettings) Reset() { + *x = CppSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CppSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CppSettings) ProtoMessage() {} + +func (x *CppSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CppSettings.ProtoReflect.Descriptor instead. +func (*CppSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{4} +} + +func (x *CppSettings) GetCommon() *CommonLanguageSettings { + if x != nil { + return x.Common + } + return nil +} + +// Settings for Php client libraries. +type PhpSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Some settings. + Common *CommonLanguageSettings `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"` +} + +func (x *PhpSettings) Reset() { + *x = PhpSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PhpSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PhpSettings) ProtoMessage() {} + +func (x *PhpSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PhpSettings.ProtoReflect.Descriptor instead. +func (*PhpSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{5} +} + +func (x *PhpSettings) GetCommon() *CommonLanguageSettings { + if x != nil { + return x.Common + } + return nil +} + +// Settings for Python client libraries. +type PythonSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Some settings. + Common *CommonLanguageSettings `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"` +} + +func (x *PythonSettings) Reset() { + *x = PythonSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PythonSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PythonSettings) ProtoMessage() {} + +func (x *PythonSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PythonSettings.ProtoReflect.Descriptor instead. +func (*PythonSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{6} +} + +func (x *PythonSettings) GetCommon() *CommonLanguageSettings { + if x != nil { + return x.Common + } + return nil +} + +// Settings for Node client libraries. +type NodeSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Some settings. + Common *CommonLanguageSettings `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"` +} + +func (x *NodeSettings) Reset() { + *x = NodeSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NodeSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NodeSettings) ProtoMessage() {} + +func (x *NodeSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NodeSettings.ProtoReflect.Descriptor instead. +func (*NodeSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{7} +} + +func (x *NodeSettings) GetCommon() *CommonLanguageSettings { + if x != nil { + return x.Common + } + return nil +} + +// Settings for Dotnet client libraries. +type DotnetSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Some settings. + Common *CommonLanguageSettings `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"` +} + +func (x *DotnetSettings) Reset() { + *x = DotnetSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DotnetSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DotnetSettings) ProtoMessage() {} + +func (x *DotnetSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DotnetSettings.ProtoReflect.Descriptor instead. +func (*DotnetSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{8} +} + +func (x *DotnetSettings) GetCommon() *CommonLanguageSettings { + if x != nil { + return x.Common + } + return nil +} + +// Settings for Ruby client libraries. +type RubySettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Some settings. + Common *CommonLanguageSettings `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"` +} + +func (x *RubySettings) Reset() { + *x = RubySettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RubySettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RubySettings) ProtoMessage() {} + +func (x *RubySettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RubySettings.ProtoReflect.Descriptor instead. +func (*RubySettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{9} +} + +func (x *RubySettings) GetCommon() *CommonLanguageSettings { + if x != nil { + return x.Common + } + return nil +} + +// Settings for Go client libraries. +type GoSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Some settings. + Common *CommonLanguageSettings `protobuf:"bytes,1,opt,name=common,proto3" json:"common,omitempty"` +} + +func (x *GoSettings) Reset() { + *x = GoSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GoSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GoSettings) ProtoMessage() {} + +func (x *GoSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GoSettings.ProtoReflect.Descriptor instead. +func (*GoSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{10} +} + +func (x *GoSettings) GetCommon() *CommonLanguageSettings { + if x != nil { + return x.Common + } + return nil +} + +// Describes the generator configuration for a method. +type MethodSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The fully qualified name of the method, for which the options below apply. + // This is used to find the method to apply the options. + Selector string `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"` + // Describes settings to use for long-running operations when generating + // API methods for RPCs. Complements RPCs that use the annotations in + // google/longrunning/operations.proto. + // + // Example of a YAML configuration:: + // + // publishing: + // method_behavior: + // - selector: CreateAdDomain + // long_running: + // initial_poll_delay: + // seconds: 60 # 1 minute + // poll_delay_multiplier: 1.5 + // max_poll_delay: + // seconds: 360 # 6 minutes + // total_poll_timeout: + // seconds: 54000 # 90 minutes + LongRunning *MethodSettings_LongRunning `protobuf:"bytes,2,opt,name=long_running,json=longRunning,proto3" json:"long_running,omitempty"` +} + +func (x *MethodSettings) Reset() { + *x = MethodSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MethodSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MethodSettings) ProtoMessage() {} + +func (x *MethodSettings) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MethodSettings.ProtoReflect.Descriptor instead. +func (*MethodSettings) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{11} +} + +func (x *MethodSettings) GetSelector() string { + if x != nil { + return x.Selector + } + return "" +} + +func (x *MethodSettings) GetLongRunning() *MethodSettings_LongRunning { + if x != nil { + return x.LongRunning + } + return nil +} + +// Describes settings to use when generating API methods that use the +// long-running operation pattern. +// All default values below are from those used in the client library +// generators (e.g. +// [Java](https://github.com/googleapis/gapic-generator-java/blob/04c2faa191a9b5a10b92392fe8482279c4404803/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java)). +type MethodSettings_LongRunning struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Initial delay after which the first poll request will be made. + // Default value: 5 seconds. + InitialPollDelay *durationpb.Duration `protobuf:"bytes,1,opt,name=initial_poll_delay,json=initialPollDelay,proto3" json:"initial_poll_delay,omitempty"` + // Multiplier to gradually increase delay between subsequent polls until it + // reaches max_poll_delay. + // Default value: 1.5. + PollDelayMultiplier float32 `protobuf:"fixed32,2,opt,name=poll_delay_multiplier,json=pollDelayMultiplier,proto3" json:"poll_delay_multiplier,omitempty"` + // Maximum time between two subsequent poll requests. + // Default value: 45 seconds. + MaxPollDelay *durationpb.Duration `protobuf:"bytes,3,opt,name=max_poll_delay,json=maxPollDelay,proto3" json:"max_poll_delay,omitempty"` + // Total polling timeout. + // Default value: 5 minutes. + TotalPollTimeout *durationpb.Duration `protobuf:"bytes,4,opt,name=total_poll_timeout,json=totalPollTimeout,proto3" json:"total_poll_timeout,omitempty"` +} + +func (x *MethodSettings_LongRunning) Reset() { + *x = MethodSettings_LongRunning{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_client_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MethodSettings_LongRunning) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MethodSettings_LongRunning) ProtoMessage() {} + +func (x *MethodSettings_LongRunning) ProtoReflect() protoreflect.Message { + mi := &file_google_api_client_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MethodSettings_LongRunning.ProtoReflect.Descriptor instead. +func (*MethodSettings_LongRunning) Descriptor() ([]byte, []int) { + return file_google_api_client_proto_rawDescGZIP(), []int{11, 0} +} + +func (x *MethodSettings_LongRunning) GetInitialPollDelay() *durationpb.Duration { + if x != nil { + return x.InitialPollDelay + } + return nil +} + +func (x *MethodSettings_LongRunning) GetPollDelayMultiplier() float32 { + if x != nil { + return x.PollDelayMultiplier + } + return 0 +} + +func (x *MethodSettings_LongRunning) GetMaxPollDelay() *durationpb.Duration { + if x != nil { + return x.MaxPollDelay + } + return nil +} + +func (x *MethodSettings_LongRunning) GetTotalPollTimeout() *durationpb.Duration { + if x != nil { + return x.TotalPollTimeout + } + return nil +} + +var file_google_api_client_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: ([]string)(nil), + Field: 1051, + Name: "google.api.method_signature", + Tag: "bytes,1051,rep,name=method_signature", + Filename: "google/api/client.proto", + }, + { + ExtendedType: (*descriptorpb.ServiceOptions)(nil), + ExtensionType: (*string)(nil), + Field: 1049, + Name: "google.api.default_host", + Tag: "bytes,1049,opt,name=default_host", + Filename: "google/api/client.proto", + }, + { + ExtendedType: (*descriptorpb.ServiceOptions)(nil), + ExtensionType: (*string)(nil), + Field: 1050, + Name: "google.api.oauth_scopes", + Tag: "bytes,1050,opt,name=oauth_scopes", + Filename: "google/api/client.proto", + }, +} + +// Extension fields to descriptorpb.MethodOptions. +var ( + // A definition of a client library method signature. + // + // In client libraries, each proto RPC corresponds to one or more methods + // which the end user is able to call, and calls the underlying RPC. + // Normally, this method receives a single argument (a struct or instance + // corresponding to the RPC request object). Defining this field will + // add one or more overloads providing flattened or simpler method signatures + // in some languages. + // + // The fields on the method signature are provided as a comma-separated + // string. + // + // For example, the proto RPC and annotation: + // + // rpc CreateSubscription(CreateSubscriptionRequest) + // returns (Subscription) { + // option (google.api.method_signature) = "name,topic"; + // } + // + // Would add the following Java overload (in addition to the method accepting + // the request object): + // + // public final Subscription createSubscription(String name, String topic) + // + // The following backwards-compatibility guidelines apply: + // + // - Adding this annotation to an unannotated method is backwards + // compatible. + // - Adding this annotation to a method which already has existing + // method signature annotations is backwards compatible if and only if + // the new method signature annotation is last in the sequence. + // - Modifying or removing an existing method signature annotation is + // a breaking change. + // - Re-ordering existing method signature annotations is a breaking + // change. + // + // repeated string method_signature = 1051; + E_MethodSignature = &file_google_api_client_proto_extTypes[0] +) + +// Extension fields to descriptorpb.ServiceOptions. +var ( + // The hostname for this service. + // This should be specified with no prefix or protocol. + // + // Example: + // + // service Foo { + // option (google.api.default_host) = "foo.googleapi.com"; + // ... + // } + // + // optional string default_host = 1049; + E_DefaultHost = &file_google_api_client_proto_extTypes[1] + // OAuth scopes needed for the client. + // + // Example: + // + // service Foo { + // option (google.api.oauth_scopes) = \ + // "https://www.googleapis.com/auth/cloud-platform"; + // ... + // } + // + // If there is more than one scope, use a comma-separated string: + // + // Example: + // + // service Foo { + // option (google.api.oauth_scopes) = \ + // "https://www.googleapis.com/auth/cloud-platform," + // "https://www.googleapis.com/auth/monitoring"; + // ... + // } + // + // optional string oauth_scopes = 1050; + E_OauthScopes = &file_google_api_client_proto_extTypes[2] +) + +var File_google_api_client_proto protoreflect.FileDescriptor + +var file_google_api_client_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x1d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x94, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x12, 0x30, 0x0a, 0x12, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x64, + 0x6f, 0x63, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, + 0x01, 0x52, 0x10, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x44, 0x6f, 0x63, 0x73, + 0x55, 0x72, 0x69, 0x12, 0x48, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x62, + 0x72, 0x61, 0x72, 0x79, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x93, 0x05, + 0x0a, 0x15, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x3a, 0x0a, 0x0c, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, + 0x52, 0x0b, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, + 0x12, 0x72, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x65, 0x6e, + 0x75, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x65, 0x73, 0x74, 0x4e, + 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x45, 0x6e, 0x75, 0x6d, 0x73, 0x12, 0x3d, 0x0a, 0x0d, 0x6a, + 0x61, 0x76, 0x61, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x4a, 0x61, 0x76, 0x61, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0c, 0x6a, 0x61, + 0x76, 0x61, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x0c, 0x63, 0x70, + 0x70, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x70, + 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0b, 0x63, 0x70, 0x70, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x0c, 0x70, 0x68, 0x70, 0x5f, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x68, 0x70, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0b, 0x70, 0x68, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0e, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3d, 0x0a, 0x0d, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x6f, 0x64, 0x65, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x64, 0x6f, 0x74, 0x6e, 0x65, 0x74, + 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x6f, 0x74, + 0x6e, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0e, 0x64, 0x6f, 0x74, + 0x6e, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3d, 0x0a, 0x0d, 0x72, + 0x75, 0x62, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x1b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x52, 0x75, 0x62, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0c, 0x72, 0x75, + 0x62, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x67, 0x6f, + 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x6f, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0a, 0x67, 0x6f, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x22, 0xe0, 0x03, 0x0a, 0x0a, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x69, + 0x6e, 0x67, 0x12, 0x43, 0x0a, 0x0f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x65, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x6e, 0x65, 0x77, 0x49, 0x73, 0x73, 0x75, 0x65, 0x55, 0x72, 0x69, 0x12, 0x2b, 0x0a, 0x11, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x69, + 0x18, 0x66, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x69, 0x12, 0x24, 0x0a, 0x0e, 0x61, 0x70, 0x69, 0x5f, + 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x67, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x61, 0x70, 0x69, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x68, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x12, 0x34, 0x0a, 0x16, 0x63, 0x6f, 0x64, 0x65, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x69, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x14, 0x63, 0x6f, 0x64, 0x65, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x47, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x6f, 0x63, 0x5f, 0x74, + 0x61, 0x67, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x64, 0x6f, 0x63, 0x54, 0x61, 0x67, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x49, 0x0a, + 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x6b, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, + 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x10, 0x6c, 0x69, 0x62, 0x72, + 0x61, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x6d, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x0c, 0x4a, 0x61, 0x76, 0x61, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6c, 0x69, 0x62, 0x72, 0x61, + 0x72, 0x79, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, + 0x12, 0x5f, 0x0a, 0x13, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x1a, 0x44, 0x0a, + 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x49, 0x0a, 0x0b, 0x43, 0x70, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x22, 0x49, + 0x0a, 0x0b, 0x50, 0x68, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x0a, + 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x22, 0x4c, 0x0a, 0x0e, 0x50, 0x79, 0x74, + 0x68, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, + 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x22, 0x4a, 0x0a, 0x0c, 0x4e, 0x6f, 0x64, 0x65, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x22, 0x4c, 0x0a, 0x0e, 0x44, 0x6f, 0x74, 0x6e, 0x65, 0x74, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x22, 0x4a, 0x0a, 0x0c, 0x52, 0x75, 0x62, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x22, 0x48, 0x0a, + 0x0a, 0x47, 0x6f, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, + 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x22, 0x8e, 0x03, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x49, 0x0a, 0x0c, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x72, + 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, + 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x6c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x1a, 0x94, 0x02, 0x0a, 0x0b, 0x4c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, + 0x67, 0x12, 0x47, 0x0a, 0x12, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, + 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, + 0x6c, 0x50, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x6f, + 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x13, 0x70, 0x6f, 0x6c, 0x6c, 0x44, + 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x12, 0x3f, + 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x50, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, + 0x47, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x6f, 0x6c, + 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x2a, 0x79, 0x0a, 0x19, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x27, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, + 0x4c, 0x49, 0x42, 0x52, 0x41, 0x52, 0x59, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4c, 0x4f, 0x55, 0x44, 0x10, 0x01, 0x12, 0x07, 0x0a, + 0x03, 0x41, 0x44, 0x53, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x48, 0x4f, 0x54, 0x4f, 0x53, + 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x52, 0x45, 0x45, 0x54, 0x5f, 0x56, 0x49, 0x45, + 0x57, 0x10, 0x04, 0x2a, 0x67, 0x0a, 0x18, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x62, + 0x72, 0x61, 0x72, 0x79, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x2a, 0x0a, 0x26, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x4c, 0x49, 0x42, 0x52, 0x41, 0x52, + 0x59, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x47, + 0x49, 0x54, 0x48, 0x55, 0x42, 0x10, 0x0a, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x41, 0x43, 0x4b, 0x41, + 0x47, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x52, 0x10, 0x14, 0x3a, 0x4a, 0x0a, 0x10, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x9b, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x3a, 0x43, 0x0a, 0x0c, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x99, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x43, 0x0a, + 0x0c, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9a, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x53, 0x63, 0x6f, 0x70, + 0x65, 0x73, 0x42, 0x69, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, + 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa2, 0x02, 0x04, 0x47, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_api_client_proto_rawDescOnce sync.Once + file_google_api_client_proto_rawDescData = file_google_api_client_proto_rawDesc +) + +func file_google_api_client_proto_rawDescGZIP() []byte { + file_google_api_client_proto_rawDescOnce.Do(func() { + file_google_api_client_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_api_client_proto_rawDescData) + }) + return file_google_api_client_proto_rawDescData +} + +var file_google_api_client_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_google_api_client_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_google_api_client_proto_goTypes = []interface{}{ + (ClientLibraryOrganization)(0), // 0: google.api.ClientLibraryOrganization + (ClientLibraryDestination)(0), // 1: google.api.ClientLibraryDestination + (*CommonLanguageSettings)(nil), // 2: google.api.CommonLanguageSettings + (*ClientLibrarySettings)(nil), // 3: google.api.ClientLibrarySettings + (*Publishing)(nil), // 4: google.api.Publishing + (*JavaSettings)(nil), // 5: google.api.JavaSettings + (*CppSettings)(nil), // 6: google.api.CppSettings + (*PhpSettings)(nil), // 7: google.api.PhpSettings + (*PythonSettings)(nil), // 8: google.api.PythonSettings + (*NodeSettings)(nil), // 9: google.api.NodeSettings + (*DotnetSettings)(nil), // 10: google.api.DotnetSettings + (*RubySettings)(nil), // 11: google.api.RubySettings + (*GoSettings)(nil), // 12: google.api.GoSettings + (*MethodSettings)(nil), // 13: google.api.MethodSettings + nil, // 14: google.api.JavaSettings.ServiceClassNamesEntry + (*MethodSettings_LongRunning)(nil), // 15: google.api.MethodSettings.LongRunning + (api.LaunchStage)(0), // 16: google.api.LaunchStage + (*durationpb.Duration)(nil), // 17: google.protobuf.Duration + (*descriptorpb.MethodOptions)(nil), // 18: google.protobuf.MethodOptions + (*descriptorpb.ServiceOptions)(nil), // 19: google.protobuf.ServiceOptions +} +var file_google_api_client_proto_depIdxs = []int32{ + 1, // 0: google.api.CommonLanguageSettings.destinations:type_name -> google.api.ClientLibraryDestination + 16, // 1: google.api.ClientLibrarySettings.launch_stage:type_name -> google.api.LaunchStage + 5, // 2: google.api.ClientLibrarySettings.java_settings:type_name -> google.api.JavaSettings + 6, // 3: google.api.ClientLibrarySettings.cpp_settings:type_name -> google.api.CppSettings + 7, // 4: google.api.ClientLibrarySettings.php_settings:type_name -> google.api.PhpSettings + 8, // 5: google.api.ClientLibrarySettings.python_settings:type_name -> google.api.PythonSettings + 9, // 6: google.api.ClientLibrarySettings.node_settings:type_name -> google.api.NodeSettings + 10, // 7: google.api.ClientLibrarySettings.dotnet_settings:type_name -> google.api.DotnetSettings + 11, // 8: google.api.ClientLibrarySettings.ruby_settings:type_name -> google.api.RubySettings + 12, // 9: google.api.ClientLibrarySettings.go_settings:type_name -> google.api.GoSettings + 13, // 10: google.api.Publishing.method_settings:type_name -> google.api.MethodSettings + 0, // 11: google.api.Publishing.organization:type_name -> google.api.ClientLibraryOrganization + 3, // 12: google.api.Publishing.library_settings:type_name -> google.api.ClientLibrarySettings + 14, // 13: google.api.JavaSettings.service_class_names:type_name -> google.api.JavaSettings.ServiceClassNamesEntry + 2, // 14: google.api.JavaSettings.common:type_name -> google.api.CommonLanguageSettings + 2, // 15: google.api.CppSettings.common:type_name -> google.api.CommonLanguageSettings + 2, // 16: google.api.PhpSettings.common:type_name -> google.api.CommonLanguageSettings + 2, // 17: google.api.PythonSettings.common:type_name -> google.api.CommonLanguageSettings + 2, // 18: google.api.NodeSettings.common:type_name -> google.api.CommonLanguageSettings + 2, // 19: google.api.DotnetSettings.common:type_name -> google.api.CommonLanguageSettings + 2, // 20: google.api.RubySettings.common:type_name -> google.api.CommonLanguageSettings + 2, // 21: google.api.GoSettings.common:type_name -> google.api.CommonLanguageSettings + 15, // 22: google.api.MethodSettings.long_running:type_name -> google.api.MethodSettings.LongRunning + 17, // 23: google.api.MethodSettings.LongRunning.initial_poll_delay:type_name -> google.protobuf.Duration + 17, // 24: google.api.MethodSettings.LongRunning.max_poll_delay:type_name -> google.protobuf.Duration + 17, // 25: google.api.MethodSettings.LongRunning.total_poll_timeout:type_name -> google.protobuf.Duration + 18, // 26: google.api.method_signature:extendee -> google.protobuf.MethodOptions + 19, // 27: google.api.default_host:extendee -> google.protobuf.ServiceOptions + 19, // 28: google.api.oauth_scopes:extendee -> google.protobuf.ServiceOptions + 29, // [29:29] is the sub-list for method output_type + 29, // [29:29] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 26, // [26:29] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name +} + +func init() { file_google_api_client_proto_init() } +func file_google_api_client_proto_init() { + if File_google_api_client_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_google_api_client_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommonLanguageSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientLibrarySettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Publishing); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*JavaSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CppSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PhpSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PythonSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NodeSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DotnetSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RubySettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GoSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MethodSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_client_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MethodSettings_LongRunning); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_api_client_proto_rawDesc, + NumEnums: 2, + NumMessages: 14, + NumExtensions: 3, + NumServices: 0, + }, + GoTypes: file_google_api_client_proto_goTypes, + DependencyIndexes: file_google_api_client_proto_depIdxs, + EnumInfos: file_google_api_client_proto_enumTypes, + MessageInfos: file_google_api_client_proto_msgTypes, + ExtensionInfos: file_google_api_client_proto_extTypes, + }.Build() + File_google_api_client_proto = out.File + file_google_api_client_proto_rawDesc = nil + file_google_api_client_proto_goTypes = nil + file_google_api_client_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/field_behavior.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/field_behavior.pb.go new file mode 100644 index 00000000000..164e0df0bf5 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/field_behavior.pb.go @@ -0,0 +1,250 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.12.2 +// source: google/api/field_behavior.proto + +package annotations + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// An indicator of the behavior of a given field (for example, that a field +// is required in requests, or given as output but ignored as input). +// This **does not** change the behavior in protocol buffers itself; it only +// denotes the behavior and may affect how API tooling handles the field. +// +// Note: This enum **may** receive new values in the future. +type FieldBehavior int32 + +const ( + // Conventional default for enums. Do not use this. + FieldBehavior_FIELD_BEHAVIOR_UNSPECIFIED FieldBehavior = 0 + // Specifically denotes a field as optional. + // While all fields in protocol buffers are optional, this may be specified + // for emphasis if appropriate. + FieldBehavior_OPTIONAL FieldBehavior = 1 + // Denotes a field as required. + // This indicates that the field **must** be provided as part of the request, + // and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + FieldBehavior_REQUIRED FieldBehavior = 2 + // Denotes a field as output only. + // This indicates that the field is provided in responses, but including the + // field in a request does nothing (the server *must* ignore it and + // *must not* throw an error as a result of the field's presence). + FieldBehavior_OUTPUT_ONLY FieldBehavior = 3 + // Denotes a field as input only. + // This indicates that the field is provided in requests, and the + // corresponding field is not included in output. + FieldBehavior_INPUT_ONLY FieldBehavior = 4 + // Denotes a field as immutable. + // This indicates that the field may be set once in a request to create a + // resource, but may not be changed thereafter. + FieldBehavior_IMMUTABLE FieldBehavior = 5 + // Denotes that a (repeated) field is an unordered list. + // This indicates that the service may provide the elements of the list + // in any arbitrary order, rather than the order the user originally + // provided. Additionally, the list's order may or may not be stable. + FieldBehavior_UNORDERED_LIST FieldBehavior = 6 + // Denotes that this field returns a non-empty default value if not set. + // This indicates that if the user provides the empty value in a request, + // a non-empty value will be returned. The user will not be aware of what + // non-empty value to expect. + FieldBehavior_NON_EMPTY_DEFAULT FieldBehavior = 7 +) + +// Enum value maps for FieldBehavior. +var ( + FieldBehavior_name = map[int32]string{ + 0: "FIELD_BEHAVIOR_UNSPECIFIED", + 1: "OPTIONAL", + 2: "REQUIRED", + 3: "OUTPUT_ONLY", + 4: "INPUT_ONLY", + 5: "IMMUTABLE", + 6: "UNORDERED_LIST", + 7: "NON_EMPTY_DEFAULT", + } + FieldBehavior_value = map[string]int32{ + "FIELD_BEHAVIOR_UNSPECIFIED": 0, + "OPTIONAL": 1, + "REQUIRED": 2, + "OUTPUT_ONLY": 3, + "INPUT_ONLY": 4, + "IMMUTABLE": 5, + "UNORDERED_LIST": 6, + "NON_EMPTY_DEFAULT": 7, + } +) + +func (x FieldBehavior) Enum() *FieldBehavior { + p := new(FieldBehavior) + *p = x + return p +} + +func (x FieldBehavior) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FieldBehavior) Descriptor() protoreflect.EnumDescriptor { + return file_google_api_field_behavior_proto_enumTypes[0].Descriptor() +} + +func (FieldBehavior) Type() protoreflect.EnumType { + return &file_google_api_field_behavior_proto_enumTypes[0] +} + +func (x FieldBehavior) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use FieldBehavior.Descriptor instead. +func (FieldBehavior) EnumDescriptor() ([]byte, []int) { + return file_google_api_field_behavior_proto_rawDescGZIP(), []int{0} +} + +var file_google_api_field_behavior_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtensionType: ([]FieldBehavior)(nil), + Field: 1052, + Name: "google.api.field_behavior", + Tag: "varint,1052,rep,name=field_behavior,enum=google.api.FieldBehavior", + Filename: "google/api/field_behavior.proto", + }, +} + +// Extension fields to descriptorpb.FieldOptions. +var ( + // A designation of a specific field behavior (required, output only, etc.) + // in protobuf messages. + // + // Examples: + // + // string name = 1 [(google.api.field_behavior) = REQUIRED]; + // State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; + // google.protobuf.Duration ttl = 1 + // [(google.api.field_behavior) = INPUT_ONLY]; + // google.protobuf.Timestamp expire_time = 1 + // [(google.api.field_behavior) = OUTPUT_ONLY, + // (google.api.field_behavior) = IMMUTABLE]; + // + // repeated google.api.FieldBehavior field_behavior = 1052; + E_FieldBehavior = &file_google_api_field_behavior_proto_extTypes[0] +) + +var File_google_api_field_behavior_proto protoreflect.FileDescriptor + +var file_google_api_field_behavior_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x20, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, + 0xa6, 0x01, 0x0a, 0x0d, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, + 0x72, 0x12, 0x1e, 0x0a, 0x1a, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x42, 0x45, 0x48, 0x41, 0x56, + 0x49, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, + 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0f, 0x0a, + 0x0b, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x03, 0x12, 0x0e, + 0x0a, 0x0a, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x04, 0x12, 0x0d, + 0x0a, 0x09, 0x49, 0x4d, 0x4d, 0x55, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x12, 0x0a, + 0x0e, 0x55, 0x4e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, + 0x06, 0x12, 0x15, 0x0a, 0x11, 0x4e, 0x4f, 0x4e, 0x5f, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x5f, 0x44, + 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x07, 0x3a, 0x60, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9c, 0x08, 0x20, 0x03, 0x28, 0x0e, + 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x52, 0x0d, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x42, 0x70, 0x0a, 0x0e, 0x63, 0x6f, + 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x12, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, + 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa2, 0x02, 0x04, 0x47, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_api_field_behavior_proto_rawDescOnce sync.Once + file_google_api_field_behavior_proto_rawDescData = file_google_api_field_behavior_proto_rawDesc +) + +func file_google_api_field_behavior_proto_rawDescGZIP() []byte { + file_google_api_field_behavior_proto_rawDescOnce.Do(func() { + file_google_api_field_behavior_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_api_field_behavior_proto_rawDescData) + }) + return file_google_api_field_behavior_proto_rawDescData +} + +var file_google_api_field_behavior_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_google_api_field_behavior_proto_goTypes = []interface{}{ + (FieldBehavior)(0), // 0: google.api.FieldBehavior + (*descriptorpb.FieldOptions)(nil), // 1: google.protobuf.FieldOptions +} +var file_google_api_field_behavior_proto_depIdxs = []int32{ + 1, // 0: google.api.field_behavior:extendee -> google.protobuf.FieldOptions + 0, // 1: google.api.field_behavior:type_name -> google.api.FieldBehavior + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 1, // [1:2] is the sub-list for extension type_name + 0, // [0:1] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_google_api_field_behavior_proto_init() } +func file_google_api_field_behavior_proto_init() { + if File_google_api_field_behavior_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_api_field_behavior_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 1, + NumServices: 0, + }, + GoTypes: file_google_api_field_behavior_proto_goTypes, + DependencyIndexes: file_google_api_field_behavior_proto_depIdxs, + EnumInfos: file_google_api_field_behavior_proto_enumTypes, + ExtensionInfos: file_google_api_field_behavior_proto_extTypes, + }.Build() + File_google_api_field_behavior_proto = out.File + file_google_api_field_behavior_proto_rawDesc = nil + file_google_api_field_behavior_proto_goTypes = nil + file_google_api_field_behavior_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/http.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/http.pb.go new file mode 100644 index 00000000000..6f11b7c500f --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/http.pb.go @@ -0,0 +1,777 @@ +// Copyright 2015 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.2 +// source: google/api/http.proto + +package annotations + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +type Http struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + Rules []*HttpRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` + // When set to true, URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + FullyDecodeReservedExpansion bool `protobuf:"varint,2,opt,name=fully_decode_reserved_expansion,json=fullyDecodeReservedExpansion,proto3" json:"fully_decode_reserved_expansion,omitempty"` +} + +func (x *Http) Reset() { + *x = Http{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_http_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Http) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Http) ProtoMessage() {} + +func (x *Http) ProtoReflect() protoreflect.Message { + mi := &file_google_api_http_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Http.ProtoReflect.Descriptor instead. +func (*Http) Descriptor() ([]byte, []int) { + return file_google_api_http_proto_rawDescGZIP(), []int{0} +} + +func (x *Http) GetRules() []*HttpRule { + if x != nil { + return x.Rules + } + return nil +} + +func (x *Http) GetFullyDecodeReservedExpansion() bool { + if x != nil { + return x.FullyDecodeReservedExpansion + } + return false +} + +// # gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | +// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: +// "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: +// "123456")` +// +// ## Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all +// fields are passed via URL path and URL query parameters. +// +// ### Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// ## Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// Example: +// +// http: +// rules: +// # Selects a gRPC method and applies HttpRule to it. +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// ## Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +type HttpRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + Selector string `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"` + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + // + // Types that are assignable to Pattern: + // *HttpRule_Get + // *HttpRule_Put + // *HttpRule_Post + // *HttpRule_Delete + // *HttpRule_Patch + // *HttpRule_Custom + Pattern isHttpRule_Pattern `protobuf_oneof:"pattern"` + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + Body string `protobuf:"bytes,7,opt,name=body,proto3" json:"body,omitempty"` + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + ResponseBody string `protobuf:"bytes,12,opt,name=response_body,json=responseBody,proto3" json:"response_body,omitempty"` + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + AdditionalBindings []*HttpRule `protobuf:"bytes,11,rep,name=additional_bindings,json=additionalBindings,proto3" json:"additional_bindings,omitempty"` +} + +func (x *HttpRule) Reset() { + *x = HttpRule{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_http_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HttpRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HttpRule) ProtoMessage() {} + +func (x *HttpRule) ProtoReflect() protoreflect.Message { + mi := &file_google_api_http_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HttpRule.ProtoReflect.Descriptor instead. +func (*HttpRule) Descriptor() ([]byte, []int) { + return file_google_api_http_proto_rawDescGZIP(), []int{1} +} + +func (x *HttpRule) GetSelector() string { + if x != nil { + return x.Selector + } + return "" +} + +func (m *HttpRule) GetPattern() isHttpRule_Pattern { + if m != nil { + return m.Pattern + } + return nil +} + +func (x *HttpRule) GetGet() string { + if x, ok := x.GetPattern().(*HttpRule_Get); ok { + return x.Get + } + return "" +} + +func (x *HttpRule) GetPut() string { + if x, ok := x.GetPattern().(*HttpRule_Put); ok { + return x.Put + } + return "" +} + +func (x *HttpRule) GetPost() string { + if x, ok := x.GetPattern().(*HttpRule_Post); ok { + return x.Post + } + return "" +} + +func (x *HttpRule) GetDelete() string { + if x, ok := x.GetPattern().(*HttpRule_Delete); ok { + return x.Delete + } + return "" +} + +func (x *HttpRule) GetPatch() string { + if x, ok := x.GetPattern().(*HttpRule_Patch); ok { + return x.Patch + } + return "" +} + +func (x *HttpRule) GetCustom() *CustomHttpPattern { + if x, ok := x.GetPattern().(*HttpRule_Custom); ok { + return x.Custom + } + return nil +} + +func (x *HttpRule) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + +func (x *HttpRule) GetResponseBody() string { + if x != nil { + return x.ResponseBody + } + return "" +} + +func (x *HttpRule) GetAdditionalBindings() []*HttpRule { + if x != nil { + return x.AdditionalBindings + } + return nil +} + +type isHttpRule_Pattern interface { + isHttpRule_Pattern() +} + +type HttpRule_Get struct { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + Get string `protobuf:"bytes,2,opt,name=get,proto3,oneof"` +} + +type HttpRule_Put struct { + // Maps to HTTP PUT. Used for replacing a resource. + Put string `protobuf:"bytes,3,opt,name=put,proto3,oneof"` +} + +type HttpRule_Post struct { + // Maps to HTTP POST. Used for creating a resource or performing an action. + Post string `protobuf:"bytes,4,opt,name=post,proto3,oneof"` +} + +type HttpRule_Delete struct { + // Maps to HTTP DELETE. Used for deleting a resource. + Delete string `protobuf:"bytes,5,opt,name=delete,proto3,oneof"` +} + +type HttpRule_Patch struct { + // Maps to HTTP PATCH. Used for updating a resource. + Patch string `protobuf:"bytes,6,opt,name=patch,proto3,oneof"` +} + +type HttpRule_Custom struct { + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + Custom *CustomHttpPattern `protobuf:"bytes,8,opt,name=custom,proto3,oneof"` +} + +func (*HttpRule_Get) isHttpRule_Pattern() {} + +func (*HttpRule_Put) isHttpRule_Pattern() {} + +func (*HttpRule_Post) isHttpRule_Pattern() {} + +func (*HttpRule_Delete) isHttpRule_Pattern() {} + +func (*HttpRule_Patch) isHttpRule_Pattern() {} + +func (*HttpRule_Custom) isHttpRule_Pattern() {} + +// A custom pattern is used for defining custom HTTP verb. +type CustomHttpPattern struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of this custom HTTP verb. + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + // The path matched by this custom verb. + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *CustomHttpPattern) Reset() { + *x = CustomHttpPattern{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_http_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CustomHttpPattern) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CustomHttpPattern) ProtoMessage() {} + +func (x *CustomHttpPattern) ProtoReflect() protoreflect.Message { + mi := &file_google_api_http_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CustomHttpPattern.ProtoReflect.Descriptor instead. +func (*CustomHttpPattern) Descriptor() ([]byte, []int) { + return file_google_api_http_proto_rawDescGZIP(), []int{2} +} + +func (x *CustomHttpPattern) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *CustomHttpPattern) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +var File_google_api_http_proto protoreflect.FileDescriptor + +var file_google_api_http_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x61, 0x70, 0x69, 0x22, 0x79, 0x0a, 0x04, 0x48, 0x74, 0x74, 0x70, 0x12, 0x2a, 0x0a, 0x05, 0x72, + 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x75, 0x6c, 0x6c, 0x79, + 0x5f, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x5f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1c, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x64, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xda, + 0x02, 0x0a, 0x08, 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x03, 0x70, + 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x70, 0x75, 0x74, 0x12, + 0x14, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, + 0x16, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x12, 0x37, 0x0a, 0x06, 0x63, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x74, 0x74, 0x70, 0x50, + 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x62, 0x6f, 0x64, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x45, 0x0a, 0x13, 0x61, 0x64, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, + 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x12, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, + 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x3b, 0x0a, 0x11, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x74, 0x74, 0x70, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, + 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x6a, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x09, 0x48, 0x74, 0x74, 0x70, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x04, + 0x47, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_api_http_proto_rawDescOnce sync.Once + file_google_api_http_proto_rawDescData = file_google_api_http_proto_rawDesc +) + +func file_google_api_http_proto_rawDescGZIP() []byte { + file_google_api_http_proto_rawDescOnce.Do(func() { + file_google_api_http_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_api_http_proto_rawDescData) + }) + return file_google_api_http_proto_rawDescData +} + +var file_google_api_http_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_google_api_http_proto_goTypes = []interface{}{ + (*Http)(nil), // 0: google.api.Http + (*HttpRule)(nil), // 1: google.api.HttpRule + (*CustomHttpPattern)(nil), // 2: google.api.CustomHttpPattern +} +var file_google_api_http_proto_depIdxs = []int32{ + 1, // 0: google.api.Http.rules:type_name -> google.api.HttpRule + 2, // 1: google.api.HttpRule.custom:type_name -> google.api.CustomHttpPattern + 1, // 2: google.api.HttpRule.additional_bindings:type_name -> google.api.HttpRule + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_google_api_http_proto_init() } +func file_google_api_http_proto_init() { + if File_google_api_http_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_google_api_http_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Http); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_http_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HttpRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_http_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CustomHttpPattern); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_google_api_http_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*HttpRule_Get)(nil), + (*HttpRule_Put)(nil), + (*HttpRule_Post)(nil), + (*HttpRule_Delete)(nil), + (*HttpRule_Patch)(nil), + (*HttpRule_Custom)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_api_http_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_google_api_http_proto_goTypes, + DependencyIndexes: file_google_api_http_proto_depIdxs, + MessageInfos: file_google_api_http_proto_msgTypes, + }.Build() + File_google_api_http_proto = out.File + file_google_api_http_proto_rawDesc = nil + file_google_api_http_proto_goTypes = nil + file_google_api_http_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/resource.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/resource.pb.go new file mode 100644 index 00000000000..13ea54b2940 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/resource.pb.go @@ -0,0 +1,655 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.2 +// source: google/api/resource.proto + +package annotations + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// A description of the historical or future-looking state of the +// resource pattern. +type ResourceDescriptor_History int32 + +const ( + // The "unset" value. + ResourceDescriptor_HISTORY_UNSPECIFIED ResourceDescriptor_History = 0 + // The resource originally had one pattern and launched as such, and + // additional patterns were added later. + ResourceDescriptor_ORIGINALLY_SINGLE_PATTERN ResourceDescriptor_History = 1 + // The resource has one pattern, but the API owner expects to add more + // later. (This is the inverse of ORIGINALLY_SINGLE_PATTERN, and prevents + // that from being necessary once there are multiple patterns.) + ResourceDescriptor_FUTURE_MULTI_PATTERN ResourceDescriptor_History = 2 +) + +// Enum value maps for ResourceDescriptor_History. +var ( + ResourceDescriptor_History_name = map[int32]string{ + 0: "HISTORY_UNSPECIFIED", + 1: "ORIGINALLY_SINGLE_PATTERN", + 2: "FUTURE_MULTI_PATTERN", + } + ResourceDescriptor_History_value = map[string]int32{ + "HISTORY_UNSPECIFIED": 0, + "ORIGINALLY_SINGLE_PATTERN": 1, + "FUTURE_MULTI_PATTERN": 2, + } +) + +func (x ResourceDescriptor_History) Enum() *ResourceDescriptor_History { + p := new(ResourceDescriptor_History) + *p = x + return p +} + +func (x ResourceDescriptor_History) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ResourceDescriptor_History) Descriptor() protoreflect.EnumDescriptor { + return file_google_api_resource_proto_enumTypes[0].Descriptor() +} + +func (ResourceDescriptor_History) Type() protoreflect.EnumType { + return &file_google_api_resource_proto_enumTypes[0] +} + +func (x ResourceDescriptor_History) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ResourceDescriptor_History.Descriptor instead. +func (ResourceDescriptor_History) EnumDescriptor() ([]byte, []int) { + return file_google_api_resource_proto_rawDescGZIP(), []int{0, 0} +} + +// A flag representing a specific style that a resource claims to conform to. +type ResourceDescriptor_Style int32 + +const ( + // The unspecified value. Do not use. + ResourceDescriptor_STYLE_UNSPECIFIED ResourceDescriptor_Style = 0 + // This resource is intended to be "declarative-friendly". + // + // Declarative-friendly resources must be more strictly consistent, and + // setting this to true communicates to tools that this resource should + // adhere to declarative-friendly expectations. + // + // Note: This is used by the API linter (linter.aip.dev) to enable + // additional checks. + ResourceDescriptor_DECLARATIVE_FRIENDLY ResourceDescriptor_Style = 1 +) + +// Enum value maps for ResourceDescriptor_Style. +var ( + ResourceDescriptor_Style_name = map[int32]string{ + 0: "STYLE_UNSPECIFIED", + 1: "DECLARATIVE_FRIENDLY", + } + ResourceDescriptor_Style_value = map[string]int32{ + "STYLE_UNSPECIFIED": 0, + "DECLARATIVE_FRIENDLY": 1, + } +) + +func (x ResourceDescriptor_Style) Enum() *ResourceDescriptor_Style { + p := new(ResourceDescriptor_Style) + *p = x + return p +} + +func (x ResourceDescriptor_Style) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ResourceDescriptor_Style) Descriptor() protoreflect.EnumDescriptor { + return file_google_api_resource_proto_enumTypes[1].Descriptor() +} + +func (ResourceDescriptor_Style) Type() protoreflect.EnumType { + return &file_google_api_resource_proto_enumTypes[1] +} + +func (x ResourceDescriptor_Style) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ResourceDescriptor_Style.Descriptor instead. +func (ResourceDescriptor_Style) EnumDescriptor() ([]byte, []int) { + return file_google_api_resource_proto_rawDescGZIP(), []int{0, 1} +} + +// A simple descriptor of a resource type. +// +// ResourceDescriptor annotates a resource message (either by means of a +// protobuf annotation or use in the service config), and associates the +// resource's schema, the resource type, and the pattern of the resource name. +// +// Example: +// +// message Topic { +// // Indicates this message defines a resource schema. +// // Declares the resource type in the format of {service}/{kind}. +// // For Kubernetes resources, the format is {api group}/{kind}. +// option (google.api.resource) = { +// type: "pubsub.googleapis.com/Topic" +// pattern: "projects/{project}/topics/{topic}" +// }; +// } +// +// The ResourceDescriptor Yaml config will look like: +// +// resources: +// - type: "pubsub.googleapis.com/Topic" +// pattern: "projects/{project}/topics/{topic}" +// +// Sometimes, resources have multiple patterns, typically because they can +// live under multiple parents. +// +// Example: +// +// message LogEntry { +// option (google.api.resource) = { +// type: "logging.googleapis.com/LogEntry" +// pattern: "projects/{project}/logs/{log}" +// pattern: "folders/{folder}/logs/{log}" +// pattern: "organizations/{organization}/logs/{log}" +// pattern: "billingAccounts/{billing_account}/logs/{log}" +// }; +// } +// +// The ResourceDescriptor Yaml config will look like: +// +// resources: +// - type: 'logging.googleapis.com/LogEntry' +// pattern: "projects/{project}/logs/{log}" +// pattern: "folders/{folder}/logs/{log}" +// pattern: "organizations/{organization}/logs/{log}" +// pattern: "billingAccounts/{billing_account}/logs/{log}" +type ResourceDescriptor struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The resource type. It must be in the format of + // {service_name}/{resource_type_kind}. The `resource_type_kind` must be + // singular and must not include version numbers. + // + // Example: `storage.googleapis.com/Bucket` + // + // The value of the resource_type_kind must follow the regular expression + // /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and + // should use PascalCase (UpperCamelCase). The maximum number of + // characters allowed for the `resource_type_kind` is 100. + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + // Optional. The relative resource name pattern associated with this resource + // type. The DNS prefix of the full resource name shouldn't be specified here. + // + // The path pattern must follow the syntax, which aligns with HTTP binding + // syntax: + // + // Template = Segment { "/" Segment } ; + // Segment = LITERAL | Variable ; + // Variable = "{" LITERAL "}" ; + // + // Examples: + // + // - "projects/{project}/topics/{topic}" + // - "projects/{project}/knowledgeBases/{knowledge_base}" + // + // The components in braces correspond to the IDs for each resource in the + // hierarchy. It is expected that, if multiple patterns are provided, + // the same component name (e.g. "project") refers to IDs of the same + // type of resource. + Pattern []string `protobuf:"bytes,2,rep,name=pattern,proto3" json:"pattern,omitempty"` + // Optional. The field on the resource that designates the resource name + // field. If omitted, this is assumed to be "name". + NameField string `protobuf:"bytes,3,opt,name=name_field,json=nameField,proto3" json:"name_field,omitempty"` + // Optional. The historical or future-looking state of the resource pattern. + // + // Example: + // + // // The InspectTemplate message originally only supported resource + // // names with organization, and project was added later. + // message InspectTemplate { + // option (google.api.resource) = { + // type: "dlp.googleapis.com/InspectTemplate" + // pattern: + // "organizations/{organization}/inspectTemplates/{inspect_template}" + // pattern: "projects/{project}/inspectTemplates/{inspect_template}" + // history: ORIGINALLY_SINGLE_PATTERN + // }; + // } + History ResourceDescriptor_History `protobuf:"varint,4,opt,name=history,proto3,enum=google.api.ResourceDescriptor_History" json:"history,omitempty"` + // The plural name used in the resource name and permission names, such as + // 'projects' for the resource name of 'projects/{project}' and the permission + // name of 'cloudresourcemanager.googleapis.com/projects.get'. It is the same + // concept of the `plural` field in k8s CRD spec + // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ + // + // Note: The plural form is required even for singleton resources. See + // https://aip.dev/156 + Plural string `protobuf:"bytes,5,opt,name=plural,proto3" json:"plural,omitempty"` + // The same concept of the `singular` field in k8s CRD spec + // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ + // Such as "project" for the `resourcemanager.googleapis.com/Project` type. + Singular string `protobuf:"bytes,6,opt,name=singular,proto3" json:"singular,omitempty"` + // Style flag(s) for this resource. + // These indicate that a resource is expected to conform to a given + // style. See the specific style flags for additional information. + Style []ResourceDescriptor_Style `protobuf:"varint,10,rep,packed,name=style,proto3,enum=google.api.ResourceDescriptor_Style" json:"style,omitempty"` +} + +func (x *ResourceDescriptor) Reset() { + *x = ResourceDescriptor{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_resource_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceDescriptor) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceDescriptor) ProtoMessage() {} + +func (x *ResourceDescriptor) ProtoReflect() protoreflect.Message { + mi := &file_google_api_resource_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceDescriptor.ProtoReflect.Descriptor instead. +func (*ResourceDescriptor) Descriptor() ([]byte, []int) { + return file_google_api_resource_proto_rawDescGZIP(), []int{0} +} + +func (x *ResourceDescriptor) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ResourceDescriptor) GetPattern() []string { + if x != nil { + return x.Pattern + } + return nil +} + +func (x *ResourceDescriptor) GetNameField() string { + if x != nil { + return x.NameField + } + return "" +} + +func (x *ResourceDescriptor) GetHistory() ResourceDescriptor_History { + if x != nil { + return x.History + } + return ResourceDescriptor_HISTORY_UNSPECIFIED +} + +func (x *ResourceDescriptor) GetPlural() string { + if x != nil { + return x.Plural + } + return "" +} + +func (x *ResourceDescriptor) GetSingular() string { + if x != nil { + return x.Singular + } + return "" +} + +func (x *ResourceDescriptor) GetStyle() []ResourceDescriptor_Style { + if x != nil { + return x.Style + } + return nil +} + +// Defines a proto annotation that describes a string field that refers to +// an API resource. +type ResourceReference struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The resource type that the annotated field references. + // + // Example: + // + // message Subscription { + // string topic = 2 [(google.api.resource_reference) = { + // type: "pubsub.googleapis.com/Topic" + // }]; + // } + // + // Occasionally, a field may reference an arbitrary resource. In this case, + // APIs use the special value * in their resource reference. + // + // Example: + // + // message GetIamPolicyRequest { + // string resource = 2 [(google.api.resource_reference) = { + // type: "*" + // }]; + // } + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + // The resource type of a child collection that the annotated field + // references. This is useful for annotating the `parent` field that + // doesn't have a fixed resource type. + // + // Example: + // + // message ListLogEntriesRequest { + // string parent = 1 [(google.api.resource_reference) = { + // child_type: "logging.googleapis.com/LogEntry" + // }; + // } + ChildType string `protobuf:"bytes,2,opt,name=child_type,json=childType,proto3" json:"child_type,omitempty"` +} + +func (x *ResourceReference) Reset() { + *x = ResourceReference{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_resource_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceReference) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceReference) ProtoMessage() {} + +func (x *ResourceReference) ProtoReflect() protoreflect.Message { + mi := &file_google_api_resource_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceReference.ProtoReflect.Descriptor instead. +func (*ResourceReference) Descriptor() ([]byte, []int) { + return file_google_api_resource_proto_rawDescGZIP(), []int{1} +} + +func (x *ResourceReference) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ResourceReference) GetChildType() string { + if x != nil { + return x.ChildType + } + return "" +} + +var file_google_api_resource_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtensionType: (*ResourceReference)(nil), + Field: 1055, + Name: "google.api.resource_reference", + Tag: "bytes,1055,opt,name=resource_reference", + Filename: "google/api/resource.proto", + }, + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: ([]*ResourceDescriptor)(nil), + Field: 1053, + Name: "google.api.resource_definition", + Tag: "bytes,1053,rep,name=resource_definition", + Filename: "google/api/resource.proto", + }, + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*ResourceDescriptor)(nil), + Field: 1053, + Name: "google.api.resource", + Tag: "bytes,1053,opt,name=resource", + Filename: "google/api/resource.proto", + }, +} + +// Extension fields to descriptorpb.FieldOptions. +var ( + // An annotation that describes a resource reference, see + // [ResourceReference][]. + // + // optional google.api.ResourceReference resource_reference = 1055; + E_ResourceReference = &file_google_api_resource_proto_extTypes[0] +) + +// Extension fields to descriptorpb.FileOptions. +var ( + // An annotation that describes a resource definition without a corresponding + // message; see [ResourceDescriptor][]. + // + // repeated google.api.ResourceDescriptor resource_definition = 1053; + E_ResourceDefinition = &file_google_api_resource_proto_extTypes[1] +) + +// Extension fields to descriptorpb.MessageOptions. +var ( + // An annotation that describes a resource definition, see + // [ResourceDescriptor][]. + // + // optional google.api.ResourceDescriptor resource = 1053; + E_Resource = &file_google_api_resource_proto_extTypes[2] +) + +var File_google_api_resource_proto protoreflect.FileDescriptor + +var file_google_api_resource_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaa, 0x03, 0x0a, 0x12, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1d, + 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x40, 0x0a, + 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x16, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x72, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x70, 0x6c, 0x75, 0x72, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x69, 0x6e, 0x67, 0x75, + 0x6c, 0x61, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x69, 0x6e, 0x67, 0x75, + 0x6c, 0x61, 0x72, 0x12, 0x3a, 0x0a, 0x05, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x03, + 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x2e, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x52, 0x05, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x22, + 0x5b, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x49, + 0x53, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x4f, 0x52, 0x49, 0x47, 0x49, 0x4e, 0x41, 0x4c, 0x4c, + 0x59, 0x5f, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, + 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x55, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x4d, 0x55, 0x4c, + 0x54, 0x49, 0x5f, 0x50, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4e, 0x10, 0x02, 0x22, 0x38, 0x0a, 0x05, + 0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x59, 0x4c, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, + 0x44, 0x45, 0x43, 0x4c, 0x41, 0x52, 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x52, 0x49, 0x45, + 0x4e, 0x44, 0x4c, 0x59, 0x10, 0x01, 0x22, 0x46, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x6c, + 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x9f, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x3a, 0x6e, 0x0a, 0x13, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x9d, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x5c, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9d, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x6e, 0x0a, 0x0e, 0x63, 0x6f, + 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0d, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, + 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x61, 0x70, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x04, 0x47, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_google_api_resource_proto_rawDescOnce sync.Once + file_google_api_resource_proto_rawDescData = file_google_api_resource_proto_rawDesc +) + +func file_google_api_resource_proto_rawDescGZIP() []byte { + file_google_api_resource_proto_rawDescOnce.Do(func() { + file_google_api_resource_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_api_resource_proto_rawDescData) + }) + return file_google_api_resource_proto_rawDescData +} + +var file_google_api_resource_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_google_api_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_google_api_resource_proto_goTypes = []interface{}{ + (ResourceDescriptor_History)(0), // 0: google.api.ResourceDescriptor.History + (ResourceDescriptor_Style)(0), // 1: google.api.ResourceDescriptor.Style + (*ResourceDescriptor)(nil), // 2: google.api.ResourceDescriptor + (*ResourceReference)(nil), // 3: google.api.ResourceReference + (*descriptorpb.FieldOptions)(nil), // 4: google.protobuf.FieldOptions + (*descriptorpb.FileOptions)(nil), // 5: google.protobuf.FileOptions + (*descriptorpb.MessageOptions)(nil), // 6: google.protobuf.MessageOptions +} +var file_google_api_resource_proto_depIdxs = []int32{ + 0, // 0: google.api.ResourceDescriptor.history:type_name -> google.api.ResourceDescriptor.History + 1, // 1: google.api.ResourceDescriptor.style:type_name -> google.api.ResourceDescriptor.Style + 4, // 2: google.api.resource_reference:extendee -> google.protobuf.FieldOptions + 5, // 3: google.api.resource_definition:extendee -> google.protobuf.FileOptions + 6, // 4: google.api.resource:extendee -> google.protobuf.MessageOptions + 3, // 5: google.api.resource_reference:type_name -> google.api.ResourceReference + 2, // 6: google.api.resource_definition:type_name -> google.api.ResourceDescriptor + 2, // 7: google.api.resource:type_name -> google.api.ResourceDescriptor + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 5, // [5:8] is the sub-list for extension type_name + 2, // [2:5] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_google_api_resource_proto_init() } +func file_google_api_resource_proto_init() { + if File_google_api_resource_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_google_api_resource_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceDescriptor); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_resource_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceReference); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_api_resource_proto_rawDesc, + NumEnums: 2, + NumMessages: 2, + NumExtensions: 3, + NumServices: 0, + }, + GoTypes: file_google_api_resource_proto_goTypes, + DependencyIndexes: file_google_api_resource_proto_depIdxs, + EnumInfos: file_google_api_resource_proto_enumTypes, + MessageInfos: file_google_api_resource_proto_msgTypes, + ExtensionInfos: file_google_api_resource_proto_extTypes, + }.Build() + File_google_api_resource_proto = out.File + file_google_api_resource_proto_rawDesc = nil + file_google_api_resource_proto_goTypes = nil + file_google_api_resource_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/routing.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/routing.pb.go new file mode 100644 index 00000000000..6707a7b1c1d --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/routing.pb.go @@ -0,0 +1,693 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.2 +// source: google/api/routing.proto + +package annotations + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Specifies the routing information that should be sent along with the request +// in the form of routing header. +// **NOTE:** All service configuration rules follow the "last one wins" order. +// +// The examples below will apply to an RPC which has the following request type: +// +// Message Definition: +// +// message Request { +// // The name of the Table +// // Values can be of the following formats: +// // - `projects//tables/` +// // - `projects//instances//tables/
` +// // - `region//zones//tables/
` +// string table_name = 1; +// +// // This value specifies routing for replication. +// // It can be in the following formats: +// // - `profiles/` +// // - a legacy `profile_id` that can be any string +// string app_profile_id = 2; +// } +// +// Example message: +// +// { +// table_name: projects/proj_foo/instances/instance_bar/table/table_baz, +// app_profile_id: profiles/prof_qux +// } +// +// The routing header consists of one or multiple key-value pairs. Every key +// and value must be percent-encoded, and joined together in the format of +// `key1=value1&key2=value2`. +// In the examples below I am skipping the percent-encoding for readablity. +// +// # Example 1 +// +// Extracting a field from the request to put into the routing header +// unchanged, with the key equal to the field name. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `app_profile_id`. +// routing_parameters { +// field: "app_profile_id" +// } +// }; +// +// result: +// +// x-goog-request-params: app_profile_id=profiles/prof_qux +// +// # Example 2 +// +// Extracting a field from the request to put into the routing header +// unchanged, with the key different from the field name. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `app_profile_id`, but name it `routing_id` in the header. +// routing_parameters { +// field: "app_profile_id" +// path_template: "{routing_id=**}" +// } +// }; +// +// result: +// +// x-goog-request-params: routing_id=profiles/prof_qux +// +// # Example 3 +// +// Extracting a field from the request to put into the routing +// header, while matching a path template syntax on the field's value. +// +// NB: it is more useful to send nothing than to send garbage for the purpose +// of dynamic routing, since garbage pollutes cache. Thus the matching. +// +// # Sub-example 3a +// +// The field matches the template. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `table_name`, if it's well-formed (with project-based +// // syntax). +// routing_parameters { +// field: "table_name" +// path_template: "{table_name=projects/*/instances/*/**}" +// } +// }; +// +// result: +// +// x-goog-request-params: +// table_name=projects/proj_foo/instances/instance_bar/table/table_baz +// +// # Sub-example 3b +// +// The field does not match the template. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `table_name`, if it's well-formed (with region-based +// // syntax). +// routing_parameters { +// field: "table_name" +// path_template: "{table_name=regions/*/zones/*/**}" +// } +// }; +// +// result: +// +// +// +// # Sub-example 3c +// +// Multiple alternative conflictingly named path templates are +// specified. The one that matches is used to construct the header. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `table_name`, if it's well-formed, whether +// // using the region- or projects-based syntax. +// +// routing_parameters { +// field: "table_name" +// path_template: "{table_name=regions/*/zones/*/**}" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{table_name=projects/*/instances/*/**}" +// } +// }; +// +// result: +// +// x-goog-request-params: +// table_name=projects/proj_foo/instances/instance_bar/table/table_baz +// +// # Example 4 +// +// Extracting a single routing header key-value pair by matching a +// template syntax on (a part of) a single request field. +// +// annotation: +// +// option (google.api.routing) = { +// // Take just the project id from the `table_name` field. +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*}/**" +// } +// }; +// +// result: +// +// x-goog-request-params: routing_id=projects/proj_foo +// +// # Example 5 +// +// Extracting a single routing header key-value pair by matching +// several conflictingly named path templates on (parts of) a single request +// field. The last template to match "wins" the conflict. +// +// annotation: +// +// option (google.api.routing) = { +// // If the `table_name` does not have instances information, +// // take just the project id for routing. +// // Otherwise take project + instance. +// +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*}/**" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*/instances/*}/**" +// } +// }; +// +// result: +// +// x-goog-request-params: +// routing_id=projects/proj_foo/instances/instance_bar +// +// # Example 6 +// +// Extracting multiple routing header key-value pairs by matching +// several non-conflicting path templates on (parts of) a single request field. +// +// # Sub-example 6a +// +// Make the templates strict, so that if the `table_name` does not +// have an instance information, nothing is sent. +// +// annotation: +// +// option (google.api.routing) = { +// // The routing code needs two keys instead of one composite +// // but works only for the tables with the "project-instance" name +// // syntax. +// +// routing_parameters { +// field: "table_name" +// path_template: "{project_id=projects/*}/instances/*/**" +// } +// routing_parameters { +// field: "table_name" +// path_template: "projects/*/{instance_id=instances/*}/**" +// } +// }; +// +// result: +// +// x-goog-request-params: +// project_id=projects/proj_foo&instance_id=instances/instance_bar +// +// # Sub-example 6b +// +// Make the templates loose, so that if the `table_name` does not +// have an instance information, just the project id part is sent. +// +// annotation: +// +// option (google.api.routing) = { +// // The routing code wants two keys instead of one composite +// // but will work with just the `project_id` for tables without +// // an instance in the `table_name`. +// +// routing_parameters { +// field: "table_name" +// path_template: "{project_id=projects/*}/**" +// } +// routing_parameters { +// field: "table_name" +// path_template: "projects/*/{instance_id=instances/*}/**" +// } +// }; +// +// result (is the same as 6a for our example message because it has the instance +// information): +// +// x-goog-request-params: +// project_id=projects/proj_foo&instance_id=instances/instance_bar +// +// # Example 7 +// +// Extracting multiple routing header key-value pairs by matching +// several path templates on multiple request fields. +// +// NB: note that here there is no way to specify sending nothing if one of the +// fields does not match its template. E.g. if the `table_name` is in the wrong +// format, the `project_id` will not be sent, but the `routing_id` will be. +// The backend routing code has to be aware of that and be prepared to not +// receive a full complement of keys if it expects multiple. +// +// annotation: +// +// option (google.api.routing) = { +// // The routing needs both `project_id` and `routing_id` +// // (from the `app_profile_id` field) for routing. +// +// routing_parameters { +// field: "table_name" +// path_template: "{project_id=projects/*}/**" +// } +// routing_parameters { +// field: "app_profile_id" +// path_template: "{routing_id=**}" +// } +// }; +// +// result: +// +// x-goog-request-params: +// project_id=projects/proj_foo&routing_id=profiles/prof_qux +// +// # Example 8 +// +// Extracting a single routing header key-value pair by matching +// several conflictingly named path templates on several request fields. The +// last template to match "wins" the conflict. +// +// annotation: +// +// option (google.api.routing) = { +// // The `routing_id` can be a project id or a region id depending on +// // the table name format, but only if the `app_profile_id` is not set. +// // If `app_profile_id` is set it should be used instead. +// +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*}/**" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=regions/*}/**" +// } +// routing_parameters { +// field: "app_profile_id" +// path_template: "{routing_id=**}" +// } +// }; +// +// result: +// +// x-goog-request-params: routing_id=profiles/prof_qux +// +// # Example 9 +// +// Bringing it all together. +// +// annotation: +// +// option (google.api.routing) = { +// // For routing both `table_location` and a `routing_id` are needed. +// // +// // table_location can be either an instance id or a region+zone id. +// // +// // For `routing_id`, take the value of `app_profile_id` +// // - If it's in the format `profiles/`, send +// // just the `` part. +// // - If it's any other literal, send it as is. +// // If the `app_profile_id` is empty, and the `table_name` starts with +// // the project_id, send that instead. +// +// routing_parameters { +// field: "table_name" +// path_template: "projects/*/{table_location=instances/*}/tables/*" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{table_location=regions/*/zones/*}/tables/*" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*}/**" +// } +// routing_parameters { +// field: "app_profile_id" +// path_template: "{routing_id=**}" +// } +// routing_parameters { +// field: "app_profile_id" +// path_template: "profiles/{routing_id=*}" +// } +// }; +// +// result: +// +// x-goog-request-params: +// table_location=instances/instance_bar&routing_id=prof_qux +type RoutingRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A collection of Routing Parameter specifications. + // **NOTE:** If multiple Routing Parameters describe the same key + // (via the `path_template` field or via the `field` field when + // `path_template` is not provided), "last one wins" rule + // determines which Parameter gets used. + // See the examples for more details. + RoutingParameters []*RoutingParameter `protobuf:"bytes,2,rep,name=routing_parameters,json=routingParameters,proto3" json:"routing_parameters,omitempty"` +} + +func (x *RoutingRule) Reset() { + *x = RoutingRule{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_routing_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RoutingRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RoutingRule) ProtoMessage() {} + +func (x *RoutingRule) ProtoReflect() protoreflect.Message { + mi := &file_google_api_routing_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RoutingRule.ProtoReflect.Descriptor instead. +func (*RoutingRule) Descriptor() ([]byte, []int) { + return file_google_api_routing_proto_rawDescGZIP(), []int{0} +} + +func (x *RoutingRule) GetRoutingParameters() []*RoutingParameter { + if x != nil { + return x.RoutingParameters + } + return nil +} + +// A projection from an input message to the GRPC or REST header. +type RoutingParameter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A request field to extract the header key-value pair from. + Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"` + // A pattern matching the key-value field. Optional. + // If not specified, the whole field specified in the `field` field will be + // taken as value, and its name used as key. If specified, it MUST contain + // exactly one named segment (along with any number of unnamed segments) The + // pattern will be matched over the field specified in the `field` field, then + // if the match is successful: + // - the name of the single named segment will be used as a header name, + // - the match value of the segment will be used as a header value; + // if the match is NOT successful, nothing will be sent. + // + // Example: + // + // -- This is a field in the request message + // | that the header value will be extracted from. + // | + // | -- This is the key name in the + // | | routing header. + // V | + // field: "table_name" v + // path_template: "projects/*/{table_location=instances/*}/tables/*" + // ^ ^ + // | | + // In the {} brackets is the pattern that -- | + // specifies what to extract from the | + // field as a value to be sent. | + // | + // The string in the field must match the whole pattern -- + // before brackets, inside brackets, after brackets. + // + // When looking at this specific example, we can see that: + // - A key-value pair with the key `table_location` + // and the value matching `instances/*` should be added + // to the x-goog-request-params routing header. + // - The value is extracted from the request message's `table_name` field + // if it matches the full pattern specified: + // `projects/*/instances/*/tables/*`. + // + // **NB:** If the `path_template` field is not provided, the key name is + // equal to the field name, and the whole field should be sent as a value. + // This makes the pattern for the field and the value functionally equivalent + // to `**`, and the configuration + // + // { + // field: "table_name" + // } + // + // is a functionally equivalent shorthand to: + // + // { + // field: "table_name" + // path_template: "{table_name=**}" + // } + // + // See Example 1 for more details. + PathTemplate string `protobuf:"bytes,2,opt,name=path_template,json=pathTemplate,proto3" json:"path_template,omitempty"` +} + +func (x *RoutingParameter) Reset() { + *x = RoutingParameter{} + if protoimpl.UnsafeEnabled { + mi := &file_google_api_routing_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RoutingParameter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RoutingParameter) ProtoMessage() {} + +func (x *RoutingParameter) ProtoReflect() protoreflect.Message { + mi := &file_google_api_routing_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RoutingParameter.ProtoReflect.Descriptor instead. +func (*RoutingParameter) Descriptor() ([]byte, []int) { + return file_google_api_routing_proto_rawDescGZIP(), []int{1} +} + +func (x *RoutingParameter) GetField() string { + if x != nil { + return x.Field + } + return "" +} + +func (x *RoutingParameter) GetPathTemplate() string { + if x != nil { + return x.PathTemplate + } + return "" +} + +var file_google_api_routing_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*RoutingRule)(nil), + Field: 72295729, + Name: "google.api.routing", + Tag: "bytes,72295729,opt,name=routing", + Filename: "google/api/routing.proto", + }, +} + +// Extension fields to descriptorpb.MethodOptions. +var ( + // See RoutingRule. + // + // optional google.api.RoutingRule routing = 72295729; + E_Routing = &file_google_api_routing_proto_extTypes[0] +) + +var File_google_api_routing_proto protoreflect.FileDescriptor + +var file_google_api_routing_proto_rawDesc = []byte{ + 0x0a, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5a, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x12, 0x72, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x52, 0x11, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x22, 0x4d, 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x23, + 0x0a, 0x0d, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x61, 0x74, 0x68, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x3a, 0x54, 0x0a, 0x07, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1e, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb1, + 0xca, 0xbc, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x07, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x42, 0x6a, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0c, 0x52, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, + 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, + 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa2, 0x02, + 0x04, 0x47, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_api_routing_proto_rawDescOnce sync.Once + file_google_api_routing_proto_rawDescData = file_google_api_routing_proto_rawDesc +) + +func file_google_api_routing_proto_rawDescGZIP() []byte { + file_google_api_routing_proto_rawDescOnce.Do(func() { + file_google_api_routing_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_api_routing_proto_rawDescData) + }) + return file_google_api_routing_proto_rawDescData +} + +var file_google_api_routing_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_google_api_routing_proto_goTypes = []interface{}{ + (*RoutingRule)(nil), // 0: google.api.RoutingRule + (*RoutingParameter)(nil), // 1: google.api.RoutingParameter + (*descriptorpb.MethodOptions)(nil), // 2: google.protobuf.MethodOptions +} +var file_google_api_routing_proto_depIdxs = []int32{ + 1, // 0: google.api.RoutingRule.routing_parameters:type_name -> google.api.RoutingParameter + 2, // 1: google.api.routing:extendee -> google.protobuf.MethodOptions + 0, // 2: google.api.routing:type_name -> google.api.RoutingRule + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 2, // [2:3] is the sub-list for extension type_name + 1, // [1:2] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_google_api_routing_proto_init() } +func file_google_api_routing_proto_init() { + if File_google_api_routing_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_google_api_routing_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RoutingRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_api_routing_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RoutingParameter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_api_routing_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 1, + NumServices: 0, + }, + GoTypes: file_google_api_routing_proto_goTypes, + DependencyIndexes: file_google_api_routing_proto_depIdxs, + MessageInfos: file_google_api_routing_proto_msgTypes, + ExtensionInfos: file_google_api_routing_proto_extTypes, + }.Build() + File_google_api_routing_proto = out.File + file_google_api_routing_proto_rawDesc = nil + file_google_api_routing_proto_goTypes = nil + file_google_api_routing_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/genproto/googleapis/api/launch_stage.pb.go b/vendor/google.golang.org/genproto/googleapis/api/launch_stage.pb.go new file mode 100644 index 00000000000..71075313773 --- /dev/null +++ b/vendor/google.golang.org/genproto/googleapis/api/launch_stage.pb.go @@ -0,0 +1,203 @@ +// Copyright 2015 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.18.1 +// source: google/api/launch_stage.proto + +package api + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The launch stage as defined by [Google Cloud Platform +// Launch Stages](https://cloud.google.com/terms/launch-stages). +type LaunchStage int32 + +const ( + // Do not use this default value. + LaunchStage_LAUNCH_STAGE_UNSPECIFIED LaunchStage = 0 + // The feature is not yet implemented. Users can not use it. + LaunchStage_UNIMPLEMENTED LaunchStage = 6 + // Prelaunch features are hidden from users and are only visible internally. + LaunchStage_PRELAUNCH LaunchStage = 7 + // Early Access features are limited to a closed group of testers. To use + // these features, you must sign up in advance and sign a Trusted Tester + // agreement (which includes confidentiality provisions). These features may + // be unstable, changed in backward-incompatible ways, and are not + // guaranteed to be released. + LaunchStage_EARLY_ACCESS LaunchStage = 1 + // Alpha is a limited availability test for releases before they are cleared + // for widespread use. By Alpha, all significant design issues are resolved + // and we are in the process of verifying functionality. Alpha customers + // need to apply for access, agree to applicable terms, and have their + // projects allowlisted. Alpha releases don't have to be feature complete, + // no SLAs are provided, and there are no technical support obligations, but + // they will be far enough along that customers can actually use them in + // test environments or for limited-use tests -- just like they would in + // normal production cases. + LaunchStage_ALPHA LaunchStage = 2 + // Beta is the point at which we are ready to open a release for any + // customer to use. There are no SLA or technical support obligations in a + // Beta release. Products will be complete from a feature perspective, but + // may have some open outstanding issues. Beta releases are suitable for + // limited production use cases. + LaunchStage_BETA LaunchStage = 3 + // GA features are open to all developers and are considered stable and + // fully qualified for production use. + LaunchStage_GA LaunchStage = 4 + // Deprecated features are scheduled to be shut down and removed. For more + // information, see the "Deprecation Policy" section of our [Terms of + // Service](https://cloud.google.com/terms/) + // and the [Google Cloud Platform Subject to the Deprecation + // Policy](https://cloud.google.com/terms/deprecation) documentation. + LaunchStage_DEPRECATED LaunchStage = 5 +) + +// Enum value maps for LaunchStage. +var ( + LaunchStage_name = map[int32]string{ + 0: "LAUNCH_STAGE_UNSPECIFIED", + 6: "UNIMPLEMENTED", + 7: "PRELAUNCH", + 1: "EARLY_ACCESS", + 2: "ALPHA", + 3: "BETA", + 4: "GA", + 5: "DEPRECATED", + } + LaunchStage_value = map[string]int32{ + "LAUNCH_STAGE_UNSPECIFIED": 0, + "UNIMPLEMENTED": 6, + "PRELAUNCH": 7, + "EARLY_ACCESS": 1, + "ALPHA": 2, + "BETA": 3, + "GA": 4, + "DEPRECATED": 5, + } +) + +func (x LaunchStage) Enum() *LaunchStage { + p := new(LaunchStage) + *p = x + return p +} + +func (x LaunchStage) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (LaunchStage) Descriptor() protoreflect.EnumDescriptor { + return file_google_api_launch_stage_proto_enumTypes[0].Descriptor() +} + +func (LaunchStage) Type() protoreflect.EnumType { + return &file_google_api_launch_stage_proto_enumTypes[0] +} + +func (x LaunchStage) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use LaunchStage.Descriptor instead. +func (LaunchStage) EnumDescriptor() ([]byte, []int) { + return file_google_api_launch_stage_proto_rawDescGZIP(), []int{0} +} + +var File_google_api_launch_stage_proto protoreflect.FileDescriptor + +var file_google_api_launch_stage_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6c, 0x61, 0x75, + 0x6e, 0x63, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2a, 0x8c, 0x01, 0x0a, 0x0b, + 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x4c, + 0x41, 0x55, 0x4e, 0x43, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x49, + 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x06, 0x12, 0x0d, 0x0a, 0x09, + 0x50, 0x52, 0x45, 0x4c, 0x41, 0x55, 0x4e, 0x43, 0x48, 0x10, 0x07, 0x12, 0x10, 0x0a, 0x0c, 0x45, + 0x41, 0x52, 0x4c, 0x59, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x09, 0x0a, + 0x05, 0x41, 0x4c, 0x50, 0x48, 0x41, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x45, 0x54, 0x41, + 0x10, 0x03, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x41, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, + 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x05, 0x42, 0x5a, 0x0a, 0x0e, 0x63, 0x6f, + 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x10, 0x4c, 0x61, + 0x75, 0x6e, 0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x2d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, 0x69, 0xa2, + 0x02, 0x04, 0x47, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_api_launch_stage_proto_rawDescOnce sync.Once + file_google_api_launch_stage_proto_rawDescData = file_google_api_launch_stage_proto_rawDesc +) + +func file_google_api_launch_stage_proto_rawDescGZIP() []byte { + file_google_api_launch_stage_proto_rawDescOnce.Do(func() { + file_google_api_launch_stage_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_api_launch_stage_proto_rawDescData) + }) + return file_google_api_launch_stage_proto_rawDescData +} + +var file_google_api_launch_stage_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_google_api_launch_stage_proto_goTypes = []interface{}{ + (LaunchStage)(0), // 0: google.api.LaunchStage +} +var file_google_api_launch_stage_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_google_api_launch_stage_proto_init() } +func file_google_api_launch_stage_proto_init() { + if File_google_api_launch_stage_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_api_launch_stage_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_google_api_launch_stage_proto_goTypes, + DependencyIndexes: file_google_api_launch_stage_proto_depIdxs, + EnumInfos: file_google_api_launch_stage_proto_enumTypes, + }.Build() + File_google_api_launch_stage_proto = out.File + file_google_api_launch_stage_proto_rawDesc = nil + file_google_api_launch_stage_proto_goTypes = nil + file_google_api_launch_stage_proto_depIdxs = nil +} diff --git a/vendor/google.golang.org/grpc/resolver/manual/manual.go b/vendor/google.golang.org/grpc/resolver/manual/manual.go new file mode 100644 index 00000000000..f6e7b5ae358 --- /dev/null +++ b/vendor/google.golang.org/grpc/resolver/manual/manual.go @@ -0,0 +1,96 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package manual defines a resolver that can be used to manually send resolved +// addresses to ClientConn. +package manual + +import ( + "google.golang.org/grpc/resolver" +) + +// NewBuilderWithScheme creates a new test resolver builder with the given scheme. +func NewBuilderWithScheme(scheme string) *Resolver { + return &Resolver{ + BuildCallback: func(resolver.Target, resolver.ClientConn, resolver.BuildOptions) {}, + ResolveNowCallback: func(resolver.ResolveNowOptions) {}, + CloseCallback: func() {}, + scheme: scheme, + } +} + +// Resolver is also a resolver builder. +// It's build() function always returns itself. +type Resolver struct { + // BuildCallback is called when the Build method is called. Must not be + // nil. Must not be changed after the resolver may be built. + BuildCallback func(resolver.Target, resolver.ClientConn, resolver.BuildOptions) + // ResolveNowCallback is called when the ResolveNow method is called on the + // resolver. Must not be nil. Must not be changed after the resolver may + // be built. + ResolveNowCallback func(resolver.ResolveNowOptions) + // CloseCallback is called when the Close method is called. Must not be + // nil. Must not be changed after the resolver may be built. + CloseCallback func() + scheme string + + // Fields actually belong to the resolver. + CC resolver.ClientConn + bootstrapState *resolver.State +} + +// InitialState adds initial state to the resolver so that UpdateState doesn't +// need to be explicitly called after Dial. +func (r *Resolver) InitialState(s resolver.State) { + r.bootstrapState = &s +} + +// Build returns itself for Resolver, because it's both a builder and a resolver. +func (r *Resolver) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { + r.BuildCallback(target, cc, opts) + r.CC = cc + if r.bootstrapState != nil { + r.UpdateState(*r.bootstrapState) + } + return r, nil +} + +// Scheme returns the test scheme. +func (r *Resolver) Scheme() string { + return r.scheme +} + +// ResolveNow is a noop for Resolver. +func (r *Resolver) ResolveNow(o resolver.ResolveNowOptions) { + r.ResolveNowCallback(o) +} + +// Close is a noop for Resolver. +func (r *Resolver) Close() { + r.CloseCallback() +} + +// UpdateState calls CC.UpdateState. +func (r *Resolver) UpdateState(s resolver.State) { + r.CC.UpdateState(s) +} + +// ReportError calls CC.ReportError. +func (r *Resolver) ReportError(err error) { + r.CC.ReportError(err) +}