diff --git a/.gitignore b/.gitignore index ab9c6a2d37..2e07bc01e5 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,7 @@ docs/website/.hugo_build.lock docs/website/data/versions # generated when building windows binary to add icon and product version -resource.syso \ No newline at end of file +resource.syso + +# generated when building proto codegen plugin (see Makefile generate-proto) +build/tools/bin/ diff --git a/Makefile b/Makefile index 6ce8a7ad92..ad11cddb20 100644 --- a/Makefile +++ b/Makefile @@ -91,6 +91,15 @@ ifeq ($(GOOS),windows) endif $(GO) generate +.PHONY: generate-proto +generate-proto: + cd build/tools && $(GO) build -o $(CURDIR)/build/tools/bin/protoc-gen-go google.golang.org/protobuf/cmd/protoc-gen-go + PATH="$(CURDIR)/build/tools/bin:$$PATH" protoc \ + --go_out=. \ + --go_opt=module=github.com/open-policy-agent/opa \ + v1/ir/plan.proto \ + v1/bundle/manifest.proto + .PHONY: build build: go-build diff --git a/build/tools/go.mod b/build/tools/go.mod index 780b52cc50..8a98e24fb4 100644 --- a/build/tools/go.mod +++ b/build/tools/go.mod @@ -7,6 +7,7 @@ tool ( github.com/rogpeppe/go-internal/cmd/testscript golang.org/x/perf/cmd/benchstat golang.org/x/vuln/cmd/govulncheck + google.golang.org/protobuf/cmd/protoc-gen-go rsc.io/cmd/benchlab ) @@ -27,6 +28,7 @@ require ( golang.org/x/telemetry v0.0.0-20260421165255-392afab6f40e // indirect golang.org/x/tools v0.44.0 // indirect golang.org/x/vuln v1.3.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect rsc.io/cmd/benchlab v0.0.0-20260520161042-9fc40f0f0431 // indirect ) diff --git a/build/tools/go.sum b/build/tools/go.sum index 1e3d075acc..a9592a8796 100644 --- a/build/tools/go.sum +++ b/build/tools/go.sum @@ -12,10 +12,13 @@ github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJ github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU= github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786/go.mod h1:apVn/GCasLZUVpAJ6oWAuyP7Ne7CEsQbTnc0plM3m+o= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/josephspurrier/goversioninfo v1.7.0 h1:LQzXOlVm/CtbwJ9/UHl5a2HT0BjcLAwid5gqGd7ZUJ8= @@ -48,5 +51,11 @@ golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTF golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= golang.org/x/vuln v1.3.0 h1:hZYzR8uRhYhDSX88d+40TWbKAVw7BIvRWm26rtEn8jw= golang.org/x/vuln v1.3.0/go.mod h1:MIY2PaR1y52stzZM3uHBboUAdVJvSVMl5nP3OQrwQaE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cmd/build.go b/cmd/build.go index a7e647b042..9a26d10e37 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -29,6 +29,7 @@ const defaultPublicKeyID = "default" type buildParams struct { capabilities *capabilitiesFlag target *util.EnumFlag + planFormat *util.EnumFlag bundleMode bool pruneUnused bool optimizationLevel int @@ -57,6 +58,7 @@ func newBuildParams() buildParams { return buildParams{ capabilities: newCapabilitiesFlag(), target: util.NewEnumFlag(compile.TargetRego, compile.Targets), + planFormat: util.NewEnumFlag(compile.PlanFormatJSON, compile.PlanFormats), stderr: os.Stderr, } } @@ -254,6 +256,7 @@ against ` + brand + ` v0.22.0: } buildCommand.Flags().VarP(buildParams.target, "target", "t", "set the output bundle target type") + buildCommand.Flags().Var(buildParams.planFormat, "format", "set the plan output format (only applies when --target=plan)") buildCommand.Flags().BoolVar(&buildParams.pruneUnused, "prune-unused", false, "exclude dependents of entrypoints") buildCommand.Flags().BoolVar(&buildParams.debug, "debug", false, "enable debug output") buildCommand.Flags().IntVarP(&buildParams.optimizationLevel, "optimize", "O", 0, "set optimization level") @@ -312,11 +315,12 @@ func dobuild(params buildParams, args []string) error { continue } - if _, err := os.Stat(filepath.Join(arg, ".manifest")); err != nil { - continue + for _, name := range []string{bundle.ManifestExt, bundle.ManifestProtoExt} { + if _, err := os.Stat(filepath.Join(arg, name)); err == nil { + fmt.Fprintf(params.stderr, "Warning: %s file found in %q but -b flag not specified. Manifest will be ignored.\n", name, arg) + break + } } - - fmt.Fprintf(params.stderr, "Warning: .manifest file found in %q but -b flag not specified. Manifest will be ignored.\n", arg) } } @@ -329,6 +333,7 @@ func dobuild(params buildParams, args []string) error { compiler := compile.New(). WithCapabilities(capabilities). WithTarget(params.target.String()). + WithPlanFormat(params.planFormat.String()). WithAsBundle(params.bundleMode). WithPruneUnused(params.pruneUnused). WithOptimizationLevel(params.optimizationLevel). diff --git a/cmd/build_test.go b/cmd/build_test.go index 077afddf1a..c9b9335003 100644 --- a/cmd/build_test.go +++ b/cmd/build_test.go @@ -449,6 +449,114 @@ func TestBuildPlanWithPruneUnused(t *testing.T) { }) } +func TestBuildPlanProtoFormat(t *testing.T) { + files := map[string]string{ + "test.rego": ` + package test + default p := false + p if input.user == "alice" + `, + } + + test.WithTempFS(files, func(root string) { + params := newBuildParams() + if err := params.target.Set("plan"); err != nil { + t.Fatal(err) + } + if err := params.planFormat.Set("proto"); err != nil { + t.Fatal(err) + } + params.entrypoints.v = []string{"test"} + params.outputFile = path.Join(root, "bundle.tar.gz") + + if err := dobuild(params, []string{root}); err != nil { + t.Fatal(err) + } + + f, err := os.Open(params.outputFile) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + gr, err := gzip.NewReader(f) + if err != nil { + t.Fatal(err) + } + tr := tar.NewReader(gr) + + var foundPlan, foundManifest bool + var sawJSONPlan, sawJSONManifest bool + + for { + h, err := tr.Next() + if err == io.EOF { + break + } else if err != nil { + t.Fatal(err) + } + switch h.Name { + case "/plan.pb": + foundPlan = true + case "/.manifest.pb": + foundManifest = true + case "/plan.json": + sawJSONPlan = true + case "/.manifest": + sawJSONManifest = true + } + } + + if !foundPlan { + t.Error("plan.pb not found in bundle") + } + if !foundManifest { + t.Error("/.manifest.pb not found in bundle") + } + if sawJSONPlan { + t.Error("plan.json should not be present when --format=proto") + } + if sawJSONManifest { + t.Error("/.manifest should not be present when --format=proto") + } + + loaded, err := loader.NewFileLoader().AsBundle(params.outputFile) + if err != nil { + t.Fatalf("load proto bundle: %v", err) + } + if len(loaded.PlanModules) != 1 { + t.Fatalf("expected 1 plan module, got %d", len(loaded.PlanModules)) + } + if filepath.Base(loaded.PlanModules[0].Path) != "plan.pb" { + t.Errorf("plan module path should end in plan.pb, got %q", loaded.PlanModules[0].Path) + } + if loaded.Manifest.Empty() { + t.Error("manifest should not be empty after loading proto bundle") + } + }) +} + +func TestBuildFormatRequiresPlanTarget(t *testing.T) { + files := map[string]string{ + "test.rego": `package test`, + } + test.WithTempFS(files, func(root string) { + params := newBuildParams() + if err := params.planFormat.Set("proto"); err != nil { + t.Fatal(err) + } + params.outputFile = path.Join(root, "bundle.tar.gz") + + err := dobuild(params, []string{root}) + if err == nil { + t.Fatal("expected error, got nil") + } + if !strings.Contains(err.Error(), "plan") { + t.Fatalf("error should mention plan target, got: %v", err) + } + }) +} + func TestBuildPlanWithPrintStatements(t *testing.T) { files := map[string]string{ @@ -3266,6 +3374,17 @@ Warning: .manifest file found in %q but -b flag not specified. Manifest will be path.Join(root, "bundle1"), path.Join(root, "bundle2")) }, }, + "warns when proto manifest ignored": { + files: map[string]string{ + "bundle/.manifest.pb": "ignored-content", + "bundle/data.json": `{"data": "value"}`, + }, + bundleMode: false, + buildArgs: []string{"bundle"}, + expectedStderr: func(root string) string { + return fmt.Sprintf("Warning: .manifest.pb file found in %q but -b flag not specified. Manifest will be ignored.\n", path.Join(root, "bundle")) + }, + }, } for name, tc := range testCases { diff --git a/e2e/proto/manifest_test.go b/e2e/proto/manifest_test.go index a21fbcaefb..3cbe950ef0 100644 --- a/e2e/proto/manifest_test.go +++ b/e2e/proto/manifest_test.go @@ -29,6 +29,11 @@ func TestManifestProtoConsistency(t *testing.T) { { Name: "Manifest", GoType: reflect.TypeOf(bundle.Manifest{}), + // roots_set is wire-form bookkeeping: it preserves the + // nil-vs-explicit-empty distinction that Manifest.Roots + // (*[]string) carries on the Go side. No Go counterpart by + // design. + SkipProtoFields: []string{"roots_set"}, }, { Name: "WasmResolver", diff --git a/e2e/proto/protoschemacheck/protoschemacheck.go b/e2e/proto/protoschemacheck/protoschemacheck.go index 90e7ded765..de784f7b89 100644 --- a/e2e/proto/protoschemacheck/protoschemacheck.go +++ b/e2e/proto/protoschemacheck/protoschemacheck.go @@ -73,6 +73,11 @@ type MessageSpec struct { // is intentionally absent from the proto because consumers consult // their own registry for builtin signatures. SkipGoFields []string + // SkipProtoFields names proto fields with no Go counterpart by design — + // wire-form bookkeeping that the Go side carries differently. For + // example, bundle.Manifest.roots_set distinguishes nil from explicit- + // empty on the wire; the Go side already carries that as Roots *[]string. + SkipProtoFields []string } // OneofSpec asserts that the named oneof on MessageName has exactly the @@ -289,6 +294,14 @@ func checkMessage(t *testing.T, declared map[string]protoreflect.MessageDescript } } + skipProto := map[string]bool{} + for _, n := range m.SkipProtoFields { + skipProto[n] = true + if msg.Fields().ByName(protoreflect.Name(n)) == nil { + t.Errorf("%s: SkipProtoFields entry %q does not match any proto field on this message", m.Name, n) + } + } + // Validate FieldNameOverride entries point at real Go fields. for goJSONName := range override { if !goJSONNameExists(m.GoType, goJSONName) { @@ -333,6 +346,9 @@ func checkMessage(t *testing.T, declared map[string]protoreflect.MessageDescript if opaque[name] { continue } + if skipProto[name] { + continue + } // Fields belonging to a oneof handled by an OneofSpec are // validated there, not here. Skip them so the orphan check // doesn't double-fire. diff --git a/v1/ast/parser.go b/v1/ast/parser.go index af6581338f..e407808d25 100644 --- a/v1/ast/parser.go +++ b/v1/ast/parser.go @@ -3172,7 +3172,7 @@ func (b *metadataParser) Parse() (result *Annotations, err error) { switch v := v.(type) { case string: - a.Schema, err = parseSchemaRef(v) + a.Schema, err = ParseSchemaRef(v) if err != nil { return nil, err } @@ -3275,10 +3275,14 @@ func unwrapPair(pair map[string]any) (string, any) { var errInvalidSchemaRef = errors.New("invalid schema reference") +// ParseSchemaRef parses a schema reference string into a Ref. Unlike +// ParseRef, it accepts the bare `schema` Var and Refs prefixed with the +// schema root document. +// // NOTE(tsandall): 'schema' is not registered as a root because it's not // supported by the compiler or evaluator today. Once we fix that, we can remove // this function. -func parseSchemaRef(s string) (Ref, error) { +func ParseSchemaRef(s string) (Ref, error) { term, err := ParseTerm(s) if err == nil { diff --git a/v1/bundle/bundle.go b/v1/bundle/bundle.go index b717a5a718..9045b5b160 100644 --- a/v1/bundle/bundle.go +++ b/v1/bundle/bundle.go @@ -23,11 +23,13 @@ import ( "github.com/gobwas/glob" "golang.org/x/sync/errgroup" + "google.golang.org/protobuf/proto" "github.com/open-policy-agent/opa/internal/file/archive" "github.com/open-policy-agent/opa/internal/merge" "github.com/open-policy-agent/opa/v1/ast" astJSON "github.com/open-policy-agent/opa/v1/ast/json" + pb "github.com/open-policy-agent/opa/v1/bundle/v1pb" "github.com/open-policy-agent/opa/v1/format" "github.com/open-policy-agent/opa/v1/metrics" "github.com/open-policy-agent/opa/v1/storage" @@ -39,7 +41,9 @@ const ( RegoExt = ".rego" WasmFile = "policy.wasm" PlanFile = "plan.json" + PlanProtoFile = "plan.pb" ManifestExt = ".manifest" + ManifestProtoExt = ".manifest.pb" SignaturesFile = "signatures.json" patchFile = "patch.json" dataFile = "data.json" @@ -70,6 +74,13 @@ type Bundle struct { lazyLoadingMode bool sizeLimitBytes int64 + manifestProto bool +} + +// SetManifestProto configures the bundle to serialize its manifest as +// protobuf at /.manifest.pb instead of JSON at /.manifest. +func (b *Bundle) SetManifestProto(yes bool) { + b.manifestProto = yes } // Raw contains raw bytes representing the bundle's content @@ -641,6 +652,7 @@ func (r *Reader) Read() (Bundle, error) { } var modules []ModuleFile + var manifestPath string for _, f := range descriptors { buf, err := readFile(f, r.sizeLimitBytes) if err != nil { @@ -695,7 +707,7 @@ func (r *Reader) Read() (Bundle, error) { Path: r.fullPath(path), Raw: buf.Bytes(), }) - } else if filepath.Base(path) == PlanFile { + } else if filepath.Base(path) == PlanFile || filepath.Base(path) == PlanProtoFile { bundle.PlanModules = append(bundle.PlanModules, PlanModuleFile{ URL: f.URL(), Path: r.fullPath(path), @@ -741,7 +753,26 @@ func (r *Reader) Read() (Bundle, error) { return empty, err } + } else if strings.HasSuffix(path, ManifestProtoExt) { + if manifestPath != "" { + return empty, fmt.Errorf("bundle contains multiple manifest files: %q and %q", manifestPath, path) + } + manifestPath = path + pbManifest := &pb.Manifest{} + if err := proto.Unmarshal(buf.Bytes(), pbManifest); err != nil { + return empty, fmt.Errorf("bundle load failed on manifest decode: %w", err) + } + m, err := ManifestFromProto(pbManifest) + if err != nil { + return empty, fmt.Errorf("bundle load failed on manifest decode: %w", err) + } + bundle.Manifest = *m + bundle.manifestProto = true } else if strings.HasSuffix(path, ManifestExt) { + if manifestPath != "" { + return empty, fmt.Errorf("bundle contains multiple manifest files: %q and %q", manifestPath, path) + } + manifestPath = path if err := util.NewJSONDecoder(&buf).Decode(&bundle.Manifest); err != nil { return empty, fmt.Errorf("bundle load failed on manifest decode: %w", err) } @@ -935,6 +966,9 @@ func (w *Writer) DisableFormat(yes bool) *Writer { // Write writes the bundle to the writer's output stream. func (w *Writer) Write(bundle Bundle) error { + if err := validateBundleFormat(&bundle); err != nil { + return err + } tw := archive.NewTarGzWriter(w.w) if bundle.Type() == SnapshotBundleType { @@ -971,8 +1005,18 @@ func (w *Writer) Write(bundle Bundle) error { } if !bundle.Manifest.Empty() { - if err := tw.WriteJSONFile("/.manifest", bundle.Manifest); err != nil { - return err + if bundle.manifestProto { + bs, err := marshalManifestProto(&bundle.Manifest) + if err != nil { + return err + } + if err := tw.WriteFile(util.WithPrefix(ManifestProtoExt, "/"), bs); err != nil { + return err + } + } else { + if err := tw.WriteJSONFile("/.manifest", bundle.Manifest); err != nil { + return err + } } } @@ -1060,32 +1104,74 @@ func hashBundleFiles(hash SignatureHasher, b *Bundle) ([]FileInfo, error) { files = append(files, NewFile(strings.TrimPrefix(planmodule.Path, "/"), hex.EncodeToString(bs), defaultHashingAlg)) } - // If the manifest is essentially empty, don't add it to the signatures since it - // won't be written to the bundle. Otherwise: - // parse the manifest into a JSON structure; - // then recursively order the fields of all objects alphabetically and then apply - // the hash function to result to compute the hash. + // Skip empty manifest — Writer.Write skips it too, so no entry to hash. + // Proto manifest is hashed as raw deterministic-marshal bytes (matches + // what VerifyBundleFile sees, since IsStructuredDoc is false for /.manifest.pb). if !b.Manifest.Empty() { - mbs, err := json.Marshal(b.Manifest) - if err != nil { - return files, err - } + if b.manifestProto { + pbBytes, err := marshalManifestProto(&b.Manifest) + if err != nil { + return files, err + } + if bs, err = hash.HashFile(pbBytes); err != nil { + return files, err + } + files = append(files, NewFile(strings.TrimPrefix(ManifestProtoExt, "/"), hex.EncodeToString(bs), defaultHashingAlg)) + } else { + mbs, err := json.Marshal(b.Manifest) + if err != nil { + return files, err + } - var result map[string]any - if err := util.Unmarshal(mbs, &result); err != nil { - return files, err - } + var result map[string]any + if err := util.Unmarshal(mbs, &result); err != nil { + return files, err + } - if bs, err = hash.HashFile(result); err != nil { - return files, err - } + if bs, err = hash.HashFile(result); err != nil { + return files, err + } - files = append(files, NewFile(strings.TrimPrefix(ManifestExt, "/"), hex.EncodeToString(bs), defaultHashingAlg)) + files = append(files, NewFile(strings.TrimPrefix(ManifestExt, "/"), hex.EncodeToString(bs), defaultHashingAlg)) + } } return files, err } +// marshalManifestProto returns the deterministic protobuf wire form so +// signer and writer produce byte-identical output (sign/verify on +// /.manifest.pb depends on it). +func marshalManifestProto(m *Manifest) ([]byte, error) { + pbManifest, err := ManifestToProto(m) + if err != nil { + return nil, err + } + return proto.MarshalOptions{Deterministic: true}.Marshal(pbManifest) +} + +// validateBundleFormat rejects bundles whose plan format disagrees with +// the manifest format (e.g. /plan.pb + /.manifest). +func validateBundleFormat(b *Bundle) error { + if b.Manifest.Empty() { + return nil + } + for _, pm := range b.PlanModules { + base := filepath.Base(pm.Path) + switch base { + case PlanFile: + if b.manifestProto { + return fmt.Errorf("bundle has proto manifest but JSON plan %q; SetManifestProto must agree with plan format", pm.Path) + } + case PlanProtoFile: + if !b.manifestProto { + return fmt.Errorf("bundle has JSON manifest but proto plan %q; SetManifestProto(true) required", pm.Path) + } + } + } + return nil +} + // FormatModules formats Rego modules // Modules will be formatted to comply with [ast.DefaultRegoVersion], but Rego compatibility of individual parsed modules will be respected (e.g. if 'rego.v1' is imported). func (b *Bundle) FormatModules(useModulePath bool) error { @@ -1473,11 +1559,34 @@ func MergeWithRegoVersion(bundles []*Bundle, regoVersion ast.RegoVersion, usePat var roots []string var result Bundle + var planFile string + var manifestProto bool + var manifestProtoSet bool + for _, b := range bundles { if b.Manifest.Roots == nil { return nil, errors.New("bundle manifest not initialized") } + for _, pm := range b.PlanModules { + base := filepath.Base(pm.Path) + if base != PlanFile && base != PlanProtoFile { + continue + } + if planFile == "" { + planFile = base + } else if planFile != base { + return nil, fmt.Errorf("cannot merge bundles with mixed plan formats (%s and %s)", planFile, base) + } + } + + if !manifestProtoSet { + manifestProto = b.manifestProto + manifestProtoSet = true + } else if manifestProto != b.manifestProto { + return nil, errors.New("cannot merge bundles with mixed manifest formats") + } + roots = append(roots, *b.Manifest.Roots...) result.Modules = append(result.Modules, b.Modules...) @@ -1508,6 +1617,8 @@ func MergeWithRegoVersion(bundles []*Bundle, regoVersion ast.RegoVersion, usePat } } + result.manifestProto = manifestProto + // We respect the bundle rego-version, defaulting to the provided rego version if not set. result.SetRegoVersion(result.RegoVersion(regoVersion)) @@ -1666,7 +1777,9 @@ func modulePathWithPrefix(bundleName string, modulePath string) string { return path.Join(bundleName, modulePath) } -// IsStructuredDoc checks if the file name equals a structured file extension ex. ".json" +// IsStructuredDoc checks if the file name equals a structured file extension ex. ".json". +// Note: ManifestProtoExt (".manifest.pb") is intentionally absent — proto manifests are +// hashed as raw wire bytes on both the sign and verify paths. func IsStructuredDoc(name string) bool { base := filepath.Base(name) return base == dataFile || base == yamlDataFile || base == SignaturesFile || base == ManifestExt diff --git a/v1/bundle/bundle_test.go b/v1/bundle/bundle_test.go index 91d5ba0bac..4e2820f6a6 100644 --- a/v1/bundle/bundle_test.go +++ b/v1/bundle/bundle_test.go @@ -492,6 +492,46 @@ func TestReadWithManifest(t *testing.T) { } } +func TestReadRejectsDuplicateManifests(t *testing.T) { + pbBytes, err := marshalManifestProto(&Manifest{Revision: "from-proto"}) + if err != nil { + t.Fatal(err) + } + + cases := []struct { + note string + files [][2]string + }{ + { + note: "json + proto manifest", + files: [][2]string{ + {"/.manifest", `{"revision": "from-json"}`}, + {"/.manifest.pb", string(pbBytes)}, + }, + }, + { + note: "two json manifests at different paths (HasSuffix shadowing)", + files: [][2]string{ + {"/.manifest", `{"revision": "from-root"}`}, + {"/sub/release.manifest", `{"revision": "from-sub"}`}, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.note, func(t *testing.T) { + buf := archive.MustWriteTarGz(tc.files) + _, err := NewReader(buf).Read() + if err == nil { + t.Fatal("expected error for duplicate manifests, got nil") + } + if !strings.Contains(err.Error(), "multiple manifest files") { + t.Fatalf("unexpected error: %v", err) + } + }) + } +} + func TestManifestMetadata(t *testing.T) { files := [][2]string{ {"/.manifest", `{ @@ -1297,6 +1337,168 @@ func TestRoundtrip(t *testing.T) { } } +func TestWriterRejectsMixedPlanManifestFormats(t *testing.T) { + manifest := Manifest{Roots: &[]string{""}, Revision: "r"} + + t.Run("proto manifest with JSON plan", func(t *testing.T) { + b := Bundle{ + Manifest: manifest, + PlanModules: []PlanModuleFile{{ + Path: PlanFile, URL: PlanFile, Raw: []byte("{}"), + }}, + } + b.SetManifestProto(true) + var buf bytes.Buffer + err := NewWriter(&buf).Write(b) + if err == nil || !strings.Contains(err.Error(), "proto manifest but JSON plan") { + t.Fatalf("expected mixed-format error, got: %v", err) + } + }) + + t.Run("JSON manifest with proto plan", func(t *testing.T) { + b := Bundle{ + Manifest: manifest, + PlanModules: []PlanModuleFile{{ + Path: PlanProtoFile, URL: PlanProtoFile, Raw: []byte{0x00}, + }}, + } + var buf bytes.Buffer + err := NewWriter(&buf).Write(b) + if err == nil || !strings.Contains(err.Error(), "JSON manifest but proto plan") { + t.Fatalf("expected mixed-format error, got: %v", err) + } + }) + + t.Run("empty manifest exempts proto plan", func(t *testing.T) { + b := Bundle{ + Manifest: Manifest{}, + PlanModules: []PlanModuleFile{{ + Path: PlanProtoFile, URL: PlanProtoFile, Raw: []byte{0x00}, + }}, + } + var buf bytes.Buffer + if err := NewWriter(&buf).Write(b); err != nil { + t.Fatalf("expected empty-manifest write to succeed, got: %v", err) + } + }) + + t.Run("uniform proto succeeds", func(t *testing.T) { + b := Bundle{ + Manifest: manifest, + PlanModules: []PlanModuleFile{{ + Path: PlanProtoFile, URL: PlanProtoFile, Raw: []byte{0x00}, + }}, + } + b.SetManifestProto(true) + var buf bytes.Buffer + if err := NewWriter(&buf).Write(b); err != nil { + t.Fatalf("expected uniform-proto write to succeed, got: %v", err) + } + }) +} + +func TestRoundtripWithProtoManifestSigned(t *testing.T) { + + bundle := Bundle{ + Data: map[string]any{ + "foo": map[string]any{ + "bar": []any{json.Number("1"), json.Number("2"), json.Number("3")}, + }, + }, + PlanModules: []PlanModuleFile{ + { + Path: PlanProtoFile, + URL: PlanProtoFile, + Raw: []byte("plan-proto-bytes"), + }, + }, + Manifest: Manifest{ + Roots: &[]string{""}, + Revision: "quickbrownfaux", + Metadata: map[string]any{"version": "v1", "hello": "world"}, + }, + } + bundle.SetManifestProto(true) + + if err := bundle.GenerateSignature(NewSigningConfig("secret", "HS256", ""), "foo", false); err != nil { + t.Fatal("Unexpected error:", err) + } + + var buf bytes.Buffer + if err := NewWriter(&buf).Write(bundle); err != nil { + t.Fatal("Unexpected error:", err) + } + + vc := NewVerificationConfig(map[string]*KeyConfig{"foo": {Key: "secret", Algorithm: "HS256"}}, "foo", "", nil) + bundle2, err := NewReader(&buf).WithBundleVerificationConfig(vc).Read() + if err != nil { + t.Fatalf("verify failed for proto-manifest bundle: %v", err) + } + + if bundle2.Manifest.Revision != bundle.Manifest.Revision { + t.Fatalf("manifest not preserved through proto round-trip: got revision %q", bundle2.Manifest.Revision) + } + if !reflect.DeepEqual(bundle2.Signatures, bundle.Signatures) { + t.Fatal("expected signatures to be same after read") + } +} + +func TestReadProtoManifestPreservesFormatIntent(t *testing.T) { + src := Bundle{ + Data: map[string]any{}, + Manifest: Manifest{ + Roots: &[]string{""}, + Revision: "abc", + }, + } + src.SetManifestProto(true) + + var buf bytes.Buffer + if err := NewWriter(&buf).Write(src); err != nil { + t.Fatal(err) + } + + loaded, err := NewReader(&buf).Read() + if err != nil { + t.Fatal(err) + } + if !loaded.manifestProto { + t.Fatal("Reader did not propagate manifestProto onto the loaded bundle") + } + + var out bytes.Buffer + if err := NewWriter(&out).Write(loaded); err != nil { + t.Fatal(err) + } + gr, err := gzip.NewReader(&out) + if err != nil { + t.Fatal(err) + } + tr := tar.NewReader(gr) + var sawProto, sawJSON bool + for { + h, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + switch h.Name { + case "/.manifest.pb": + sawProto = true + case "/.manifest": + sawJSON = true + } + } + if !sawProto { + t.Error("re-written bundle missing /.manifest.pb") + } + if sawJSON { + t.Error("re-written bundle silently downgraded to /.manifest") + } +} + func TestRoundtripWithPlanModules(t *testing.T) { b := Bundle{ @@ -1804,6 +2006,75 @@ func TestMergeCorruptManifest(t *testing.T) { } } +func TestMergeRejectsMixedFormats(t *testing.T) { + rootEmpty := &[]string{""} + + t.Run("mixed plan formats", func(t *testing.T) { + jsonBundle := &Bundle{ + Manifest: Manifest{Roots: rootEmpty}, + PlanModules: []PlanModuleFile{{ + Path: PlanFile, URL: PlanFile, Raw: []byte("{}"), + }}, + } + protoBundle := &Bundle{ + Manifest: Manifest{Roots: rootEmpty}, + PlanModules: []PlanModuleFile{{ + Path: PlanProtoFile, URL: PlanProtoFile, Raw: []byte{0x00}, + }}, + } + _, err := Merge([]*Bundle{jsonBundle, protoBundle}) + if err == nil { + t.Fatal("expected error for mixed plan formats, got nil") + } + if !strings.Contains(err.Error(), "mixed plan formats") { + t.Fatalf("unexpected error: %v", err) + } + }) + + t.Run("mixed manifest formats", func(t *testing.T) { + jsonManifestBundle := &Bundle{ + Manifest: Manifest{Roots: rootEmpty, Revision: "j"}, + } + protoManifestBundle := &Bundle{ + Manifest: Manifest{Roots: rootEmpty, Revision: "p"}, + } + protoManifestBundle.SetManifestProto(true) + + _, err := Merge([]*Bundle{jsonManifestBundle, protoManifestBundle}) + if err == nil { + t.Fatal("expected error for mixed manifest formats, got nil") + } + if !strings.Contains(err.Error(), "mixed manifest formats") { + t.Fatalf("unexpected error: %v", err) + } + }) + + t.Run("uniform proto inputs propagate flag", func(t *testing.T) { + a := &Bundle{ + Manifest: Manifest{Roots: &[]string{"a"}, Revision: "a"}, + PlanModules: []PlanModuleFile{{ + Path: PlanProtoFile, URL: PlanProtoFile, Raw: []byte{0x00}, + }}, + } + a.SetManifestProto(true) + b := &Bundle{ + Manifest: Manifest{Roots: &[]string{"b"}, Revision: "b"}, + PlanModules: []PlanModuleFile{{ + Path: PlanProtoFile, URL: PlanProtoFile, Raw: []byte{0x01}, + }}, + } + b.SetManifestProto(true) + + merged, err := Merge([]*Bundle{a, b}) + if err != nil { + t.Fatalf("expected uniform-format merge to succeed, got %v", err) + } + if !merged.manifestProto { + t.Fatal("merged bundle should carry manifestProto=true forward from inputs") + } + }) +} + func TestMerge(t *testing.T) { expRegoVersion := ast.DefaultRegoVersion.Int() diff --git a/v1/bundle/file.go b/v1/bundle/file.go index 4897ee7b91..e4f74cc0e4 100644 --- a/v1/bundle/file.go +++ b/v1/bundle/file.go @@ -200,7 +200,10 @@ func formatPath(fileName string, root string, pathFormat PathFormat) string { case Chrooted: // Trim off the root directory and return path as if chrooted result := strings.TrimPrefix(fileName, filepath.FromSlash(root)) - if root == "." && filepath.Base(fileName) == ManifestExt { + // TrimPrefix at root="." strips the leading dot from dotfile manifests + // (".manifest" → "manifest"), which then misses the Reader's HasSuffix + // check. Restore the original name for both manifest forms. + if root == "." && (filepath.Base(fileName) == ManifestExt || filepath.Base(fileName) == ManifestProtoExt) { result = fileName } if !strings.HasPrefix(result, string(filepath.Separator)) { diff --git a/v1/bundle/file_test.go b/v1/bundle/file_test.go index 82e87d174c..67b2bac02e 100644 --- a/v1/bundle/file_test.go +++ b/v1/bundle/file_test.go @@ -544,3 +544,47 @@ func getFilter(pattern string, minDepth int) filter.LoaderFilter { return match && depth >= minDepth } } + +func TestFormatPathChrootedManifests(t *testing.T) { + sep := string(filepath.Separator) + cases := []struct { + note string + fileName string + root string + want string + }{ + { + note: "json manifest at chroot .", + fileName: ".manifest", + root: ".", + want: sep + ".manifest", + }, + { + note: "proto manifest at chroot .", + fileName: ".manifest.pb", + root: ".", + want: sep + ".manifest.pb", + }, + { + note: "json manifest at named chroot", + fileName: filepath.Join("a", "b", ".manifest"), + root: filepath.Join("a", "b"), + want: sep + ".manifest", + }, + { + note: "proto manifest at named chroot", + fileName: filepath.Join("a", "b", ".manifest.pb"), + root: filepath.Join("a", "b"), + want: sep + ".manifest.pb", + }, + } + + for _, tc := range cases { + t.Run(tc.note, func(t *testing.T) { + got := formatPath(tc.fileName, tc.root, Chrooted) + if got != tc.want { + t.Fatalf("formatPath(%q, %q, Chrooted) = %q, want %q", tc.fileName, tc.root, got, tc.want) + } + }) + } +} diff --git a/v1/bundle/manifest.proto b/v1/bundle/manifest.proto index 96a79a707a..ed3c1498ce 100644 --- a/v1/bundle/manifest.proto +++ b/v1/bundle/manifest.proto @@ -16,7 +16,7 @@ message Manifest { // Bundle revision string. string revision = 1; - // Root paths the bundle owns. + // Root paths the bundle owns. See `roots_set` for nil-vs-empty. repeated string roots = 2; // Wasm resolvers attached to the bundle. JSON key is `wasm`. @@ -31,6 +31,10 @@ message Manifest { // Free-form metadata object. Modeled as `Struct` because the Go field // is `map[string]any`. google.protobuf.Struct metadata = 6; + + // True if `bundle.Manifest.Roots` was non-nil. `repeated string` can't + // distinguish nil (default to [""]) from explicit-empty (owns no paths). + bool roots_set = 7; } // WasmResolver mirrors `bundle.WasmResolver` in v1/bundle/bundle.go. diff --git a/v1/bundle/proto.go b/v1/bundle/proto.go new file mode 100644 index 0000000000..500be418d5 --- /dev/null +++ b/v1/bundle/proto.go @@ -0,0 +1,434 @@ +// Copyright 2026 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package bundle + +import ( + "encoding/json" + "fmt" + "net/url" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/structpb" + + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/ast/location" + pb "github.com/open-policy-agent/opa/v1/bundle/v1pb" +) + +// ManifestToProto converts a bundle Manifest to its protobuf wire-form, +// defined in v1/bundle/manifest.proto. The compiled-only fileRegoVersions +// cache is intentionally not modeled. Roots presence (nil vs explicit-empty) +// is preserved via the `roots_set` wire field. +func ManifestToProto(m *Manifest) (*pb.Manifest, error) { + if m == nil { + return nil, nil + } + out := &pb.Manifest{ + Revision: proto.String(m.Revision), + } + if m.Roots != nil { + out.Roots = append([]string(nil), (*m.Roots)...) + out.RootsSet = proto.Bool(true) + } + if len(m.WasmResolvers) > 0 { + out.Wasm = make([]*pb.WasmResolver, len(m.WasmResolvers)) + for i := range m.WasmResolvers { + wr, err := wasmResolverToProto(&m.WasmResolvers[i]) + if err != nil { + return nil, fmt.Errorf("manifest wasm[%d]: %w", i, err) + } + out.Wasm[i] = wr + } + } + if m.RegoVersion != nil { + out.RegoVersion = proto.Int32(int32(*m.RegoVersion)) + } + if len(m.FileRegoVersions) > 0 { + out.FileRegoVersions = make(map[string]int32, len(m.FileRegoVersions)) + for k, v := range m.FileRegoVersions { + out.FileRegoVersions[k] = int32(v) + } + } + if len(m.Metadata) > 0 { + s, err := jsonNormalizeStruct(m.Metadata) + if err != nil { + return nil, fmt.Errorf("manifest metadata: %w", err) + } + out.Metadata = s + } + return out, nil +} + +func wasmResolverToProto(w *WasmResolver) (*pb.WasmResolver, error) { + if w == nil { + return nil, nil + } + out := &pb.WasmResolver{ + Entrypoint: proto.String(w.Entrypoint), + Module: proto.String(w.Module), + } + if len(w.Annotations) > 0 { + out.Annotations = make([]*pb.Annotations, len(w.Annotations)) + for i, a := range w.Annotations { + ap, err := annotationsToProto(a) + if err != nil { + return nil, fmt.Errorf("annotations[%d]: %w", i, err) + } + out.Annotations[i] = ap + } + } + return out, nil +} + +func annotationsToProto(a *ast.Annotations) (*pb.Annotations, error) { + if a == nil { + return nil, nil + } + out := &pb.Annotations{ + Scope: proto.String(a.Scope), + Title: proto.String(a.Title), + Entrypoint: proto.Bool(a.Entrypoint), + Description: proto.String(a.Description), + Organizations: append([]string(nil), a.Organizations...), + } + if len(a.RelatedResources) > 0 { + out.RelatedResources = make([]*pb.RelatedResourceAnnotation, len(a.RelatedResources)) + for i, r := range a.RelatedResources { + out.RelatedResources[i] = relatedResourceToProto(r) + } + } + if len(a.Authors) > 0 { + out.Authors = make([]*pb.AuthorAnnotation, len(a.Authors)) + for i, au := range a.Authors { + out.Authors[i] = authorToProto(au) + } + } + if len(a.Schemas) > 0 { + out.Schemas = make([]*pb.SchemaAnnotation, len(a.Schemas)) + for i, s := range a.Schemas { + sa, err := schemaToProto(s) + if err != nil { + return nil, fmt.Errorf("schemas[%d]: %w", i, err) + } + out.Schemas[i] = sa + } + } + if a.Compile != nil { + out.Compile = compileToProto(a.Compile) + } + if len(a.Custom) > 0 { + s, err := jsonNormalizeStruct(a.Custom) + if err != nil { + return nil, fmt.Errorf("custom: %w", err) + } + out.Custom = s + } + if len(a.Labels) > 0 { + s, err := jsonNormalizeStruct(a.Labels) + if err != nil { + return nil, fmt.Errorf("labels: %w", err) + } + out.Labels = s + } + if a.Location != nil { + out.Location = locationToProto(a.Location) + } + return out, nil +} + +func relatedResourceToProto(r *ast.RelatedResourceAnnotation) *pb.RelatedResourceAnnotation { + if r == nil { + return nil + } + return &pb.RelatedResourceAnnotation{ + Ref: proto.String(r.Ref.String()), + Description: proto.String(r.Description), + } +} + +func authorToProto(a *ast.AuthorAnnotation) *pb.AuthorAnnotation { + if a == nil { + return nil + } + return &pb.AuthorAnnotation{ + Name: proto.String(a.Name), + Email: proto.String(a.Email), + } +} + +func schemaToProto(s *ast.SchemaAnnotation) (*pb.SchemaAnnotation, error) { + if s == nil { + return nil, nil + } + out := &pb.SchemaAnnotation{ + Path: proto.String(s.Path.String()), + Schema: proto.String(s.Schema.String()), + } + if s.Definition != nil { + v, err := jsonNormalizeValue(*s.Definition) + if err != nil { + return nil, fmt.Errorf("definition: %w", err) + } + out.Definition = v + } + return out, nil +} + +func compileToProto(c *ast.CompileAnnotation) *pb.CompileAnnotation { + if c == nil { + return nil + } + out := &pb.CompileAnnotation{ + MaskRule: proto.String(c.MaskRule.String()), + } + if len(c.Unknowns) > 0 { + out.Unknowns = make([]string, len(c.Unknowns)) + for i, u := range c.Unknowns { + out.Unknowns[i] = u.String() + } + } + return out +} + +func locationToProto(l *location.Location) *pb.Location { + if l == nil { + return nil + } + return &pb.Location{ + File: proto.String(l.File), + Row: proto.Int32(int32(l.Row)), + Col: proto.Int32(int32(l.Col)), + } +} + +// ManifestFromProto is the inverse of ManifestToProto. +func ManifestFromProto(m *pb.Manifest) (*Manifest, error) { + if m == nil { + return nil, nil + } + out := &Manifest{ + Revision: m.GetRevision(), + } + if m.GetRootsSet() { + roots := make([]string, len(m.Roots)) + copy(roots, m.Roots) + out.Roots = &roots + } + if len(m.Wasm) > 0 { + out.WasmResolvers = make([]WasmResolver, len(m.Wasm)) + for i, wr := range m.Wasm { + converted, err := wasmResolverFromProto(wr) + if err != nil { + return nil, fmt.Errorf("manifest wasm[%d]: %w", i, err) + } + out.WasmResolvers[i] = converted + } + } + if m.RegoVersion != nil { + v := int(*m.RegoVersion) + out.RegoVersion = &v + } + if len(m.FileRegoVersions) > 0 { + out.FileRegoVersions = make(map[string]int, len(m.FileRegoVersions)) + for k, v := range m.FileRegoVersions { + out.FileRegoVersions[k] = int(v) + } + } + if m.Metadata != nil { + out.Metadata = m.Metadata.AsMap() + } + return out, nil +} + +func wasmResolverFromProto(w *pb.WasmResolver) (WasmResolver, error) { + out := WasmResolver{ + Entrypoint: w.GetEntrypoint(), + Module: w.GetModule(), + } + if len(w.Annotations) > 0 { + out.Annotations = make([]*ast.Annotations, len(w.Annotations)) + for i, a := range w.Annotations { + converted, err := annotationsFromProto(a) + if err != nil { + return WasmResolver{}, fmt.Errorf("annotations[%d]: %w", i, err) + } + out.Annotations[i] = converted + } + } + return out, nil +} + +func annotationsFromProto(a *pb.Annotations) (*ast.Annotations, error) { + if a == nil { + return nil, nil + } + out := &ast.Annotations{ + Scope: a.GetScope(), + Title: a.GetTitle(), + Entrypoint: a.GetEntrypoint(), + Description: a.GetDescription(), + } + if len(a.Organizations) > 0 { + out.Organizations = append([]string(nil), a.Organizations...) + } + if len(a.RelatedResources) > 0 { + out.RelatedResources = make([]*ast.RelatedResourceAnnotation, len(a.RelatedResources)) + for i, r := range a.RelatedResources { + converted, err := relatedResourceFromProto(r) + if err != nil { + return nil, fmt.Errorf("related_resources[%d]: %w", i, err) + } + out.RelatedResources[i] = converted + } + } + if len(a.Authors) > 0 { + out.Authors = make([]*ast.AuthorAnnotation, len(a.Authors)) + for i, au := range a.Authors { + out.Authors[i] = authorFromProto(au) + } + } + if len(a.Schemas) > 0 { + out.Schemas = make([]*ast.SchemaAnnotation, len(a.Schemas)) + for i, s := range a.Schemas { + converted, err := schemaFromProto(s) + if err != nil { + return nil, fmt.Errorf("schemas[%d]: %w", i, err) + } + out.Schemas[i] = converted + } + } + if a.Compile != nil { + converted, err := compileFromProto(a.Compile) + if err != nil { + return nil, fmt.Errorf("compile: %w", err) + } + out.Compile = converted + } + if a.Custom != nil { + out.Custom = a.Custom.AsMap() + } + if a.Labels != nil { + out.Labels = a.Labels.AsMap() + } + if a.Location != nil { + out.Location = locationFromProto(a.Location) + } + return out, nil +} + +func relatedResourceFromProto(r *pb.RelatedResourceAnnotation) (*ast.RelatedResourceAnnotation, error) { + if r == nil { + return nil, nil + } + out := &ast.RelatedResourceAnnotation{ + Description: r.GetDescription(), + } + if ref := r.GetRef(); ref != "" { + u, err := url.Parse(ref) + if err != nil { + return nil, fmt.Errorf("ref %q: %w", ref, err) + } + out.Ref = *u + } + return out, nil +} + +func authorFromProto(a *pb.AuthorAnnotation) *ast.AuthorAnnotation { + if a == nil { + return nil + } + return &ast.AuthorAnnotation{ + Name: a.GetName(), + Email: a.GetEmail(), + } +} + +func schemaFromProto(s *pb.SchemaAnnotation) (*ast.SchemaAnnotation, error) { + if s == nil { + return nil, nil + } + out := &ast.SchemaAnnotation{} + if p := s.GetPath(); p != "" { + ref, err := ast.ParseRef(p) + if err != nil { + return nil, fmt.Errorf("path %q: %w", p, err) + } + out.Path = ref + } + if sc := s.GetSchema(); sc != "" { + ref, err := ast.ParseSchemaRef(sc) + if err != nil { + return nil, fmt.Errorf("schema %q: %w", sc, err) + } + out.Schema = ref + } + if s.Definition != nil { + def := s.Definition.AsInterface() + out.Definition = &def + } + return out, nil +} + +func compileFromProto(c *pb.CompileAnnotation) (*ast.CompileAnnotation, error) { + if c == nil { + return nil, nil + } + out := &ast.CompileAnnotation{} + if mr := c.GetMaskRule(); mr != "" { + ref, err := ast.ParseRef(mr) + if err != nil { + return nil, fmt.Errorf("mask_rule %q: %w", mr, err) + } + out.MaskRule = ref + } + if len(c.Unknowns) > 0 { + out.Unknowns = make([]ast.Ref, len(c.Unknowns)) + for i, u := range c.Unknowns { + ref, err := ast.ParseRef(u) + if err != nil { + return nil, fmt.Errorf("unknowns[%d] %q: %w", i, u, err) + } + out.Unknowns[i] = ref + } + } + return out, nil +} + +func locationFromProto(l *pb.Location) *location.Location { + if l == nil { + return nil + } + return &location.Location{ + File: l.GetFile(), + Row: int(l.GetRow()), + Col: int(l.GetCol()), + } +} + +// jsonNormalizeStruct routes a map through JSON before structpb.NewStruct +// so the proto path accepts the same value types the JSON path does. +func jsonNormalizeStruct(m map[string]any) (*structpb.Struct, error) { + bs, err := json.Marshal(m) + if err != nil { + return nil, err + } + var normalized map[string]any + if err := json.Unmarshal(bs, &normalized); err != nil { + return nil, err + } + return structpb.NewStruct(normalized) +} + +func jsonNormalizeValue(v any) (*structpb.Value, error) { + bs, err := json.Marshal(v) + if err != nil { + return nil, err + } + var normalized any + if err := json.Unmarshal(bs, &normalized); err != nil { + return nil, err + } + return structpb.NewValue(normalized) +} diff --git a/v1/bundle/proto_test.go b/v1/bundle/proto_test.go new file mode 100644 index 0000000000..1fefe5200f --- /dev/null +++ b/v1/bundle/proto_test.go @@ -0,0 +1,236 @@ +// Copyright 2026 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package bundle + +import ( + "encoding/json" + "net/url" + "reflect" + "testing" + + "google.golang.org/protobuf/proto" + + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/ast/location" + pb "github.com/open-policy-agent/opa/v1/bundle/v1pb" +) + +func TestManifestProtoRoundTrip(t *testing.T) { + regoV1 := 1 + roots := []string{"", "a/b"} + relatedURL, err := url.Parse("https://example.com/policy") + if err != nil { + t.Fatal(err) + } + def := any(map[string]any{"type": "string"}) + + m := &Manifest{ + Revision: "rev-1", + Roots: &roots, + WasmResolvers: []WasmResolver{{ + Entrypoint: "data.example.allow", + Module: "/policy.wasm", + Annotations: []*ast.Annotations{{ + Scope: "rule", + Title: "t", + Entrypoint: true, + Description: "d", + Organizations: []string{"o1", "o2"}, + RelatedResources: []*ast.RelatedResourceAnnotation{{ + Ref: *relatedURL, + Description: "rr", + }}, + Authors: []*ast.AuthorAnnotation{{Name: "Ada", Email: "ada@example.com"}}, + Schemas: []*ast.SchemaAnnotation{{ + Path: ast.MustParseRef("input.x"), + Schema: ast.MustParseRef("schema.foo"), + Definition: &def, + }}, + Compile: &ast.CompileAnnotation{ + MaskRule: ast.MustParseRef("data.mask.rule"), + Unknowns: []ast.Ref{ast.MustParseRef("input.unknown")}, + }, + Custom: map[string]any{"k": "v"}, + Labels: map[string]any{"team": "core"}, + Location: &location.Location{File: "f.rego", Row: 1, Col: 2}, + }}, + }}, + RegoVersion: ®oV1, + FileRegoVersions: map[string]int{"a.rego": 1}, + Metadata: map[string]any{"k": "v", "n": float64(7)}, + } + + pbManifest, err := ManifestToProto(m) + if err != nil { + t.Fatalf("to proto: %v", err) + } + bs, err := proto.Marshal(pbManifest) + if err != nil { + t.Fatalf("marshal: %v", err) + } + decoded := &pb.Manifest{} + if err := proto.Unmarshal(bs, decoded); err != nil { + t.Fatalf("unmarshal: %v", err) + } + got, err := ManifestFromProto(decoded) + if err != nil { + t.Fatalf("from proto: %v", err) + } + + if !m.Equal(*got) { + t.Fatal("manifest semantic equality failed after round trip") + } + if !reflect.DeepEqual(m.FileRegoVersions, got.FileRegoVersions) { + t.Fatalf("file rego versions: want %v, got %v", m.FileRegoVersions, got.FileRegoVersions) + } + if got.WasmResolvers[0].Annotations[0].Compile.MaskRule.String() != "data.mask.rule" { + t.Fatalf("compile mask rule round-trip lost: %v", got.WasmResolvers[0].Annotations[0].Compile.MaskRule) + } + if got.WasmResolvers[0].Annotations[0].RelatedResources[0].Ref.String() != "https://example.com/policy" { + t.Fatalf("related resource ref round-trip lost: %v", got.WasmResolvers[0].Annotations[0].RelatedResources[0].Ref) + } +} + +func TestManifestToProtoNil(t *testing.T) { + got, err := ManifestToProto(nil) + if err != nil { + t.Fatal(err) + } + if got != nil { + t.Fatalf("expected nil, got %v", got) + } +} + +func TestManifestFromProtoNil(t *testing.T) { + got, err := ManifestFromProto(nil) + if err != nil { + t.Fatal(err) + } + if got != nil { + t.Fatalf("expected nil, got %v", got) + } +} + +// TestManifestMetadataAcceptsJSONTypes pins fidelity parity with the +// JSON path. structpb.NewStruct rejects ints, json.RawMessage, +// time-like values, etc.; the encoder routes Metadata through JSON so +// the proto path accepts whatever the JSON path does. +func TestManifestMetadataAcceptsJSONTypes(t *testing.T) { + m := &Manifest{ + Revision: "r", + Metadata: map[string]any{ + "count": int(7), + "raw": json.RawMessage(`{"k":"v"}`), + "nested": map[string]any{ + "items": []any{int64(1), int64(2)}, + }, + }, + } + pm, err := ManifestToProto(m) + if err != nil { + t.Fatalf("ManifestToProto rejected JSON-friendly types: %v", err) + } + out, err := ManifestFromProto(pm) + if err != nil { + t.Fatal(err) + } + got := out.Metadata + if got["count"].(float64) != 7 { + t.Fatalf("count not preserved: %v", got["count"]) + } + raw, ok := got["raw"].(map[string]any) + if !ok || raw["k"].(string) != "v" { + t.Fatalf("json.RawMessage not preserved: %v", got["raw"]) + } +} + +func TestManifestFromProtoMalformedRef(t *testing.T) { + pm := &pb.Manifest{ + Wasm: []*pb.WasmResolver{{ + Annotations: []*pb.Annotations{{ + Compile: &pb.CompileAnnotation{MaskRule: proto.String("not a ref!!!")}, + }}, + }}, + } + if _, err := ManifestFromProto(pm); err == nil { + t.Fatal("expected error for malformed mask_rule, got nil") + } +} + +// TestManifestRootsPresenceRoundTrip pins the nil-vs-explicit-empty +// distinction across the proto round-trip. `repeated string` cannot +// carry that bit on its own; the `roots_set` wire field does. +func TestManifestRootsPresenceRoundTrip(t *testing.T) { + cases := []struct { + note string + in *[]string + }{ + {note: "nil (default to [\"\"])", in: nil}, + {note: "explicit empty (owns nothing)", in: &[]string{}}, + {note: "populated", in: &[]string{"a", "b"}}, + } + for _, tc := range cases { + t.Run(tc.note, func(t *testing.T) { + pm, err := ManifestToProto(&Manifest{Revision: "r", Roots: tc.in}) + if err != nil { + t.Fatal(err) + } + out, err := ManifestFromProto(pm) + if err != nil { + t.Fatal(err) + } + if (tc.in == nil) != (out.Roots == nil) { + t.Fatalf("roots nil-ness lost: in=%v out=%v", tc.in, out.Roots) + } + if tc.in != nil && !reflect.DeepEqual(*tc.in, *out.Roots) { + t.Fatalf("roots values lost: want %v, got %v", *tc.in, *out.Roots) + } + }) + } +} + +// TestSchemaAnnotationBareVarRoundTrip pins the schema-ref decoder. +// Annotations using `schemas: [{input: schema}]` produce a bare Var Ref +// from the canonical parser (parseSchemaRef in v1/ast). The encoder +// serializes that as the literal "schema". ast.ParseRef cannot decode a +// bare Var, so the proto round-trip used to fail with `expected ref but +// got schema` — load-blocking for any annotation using this idiom. +func TestSchemaAnnotationBareVarRoundTrip(t *testing.T) { + cases := []struct { + note string + ref ast.Ref + }{ + {note: "bare schema var", ref: ast.SchemaRootRef.Copy()}, + {note: "schema with subpath", ref: ast.MustParseRef("schema.foo")}, + } + for _, tc := range cases { + t.Run(tc.note, func(t *testing.T) { + m := &Manifest{ + Revision: "r1", + WasmResolvers: []WasmResolver{{ + Annotations: []*ast.Annotations{{ + Schemas: []*ast.SchemaAnnotation{{ + Path: ast.MustParseRef("input.x"), + Schema: tc.ref, + }}, + }}, + }}, + } + + pm, err := ManifestToProto(m) + if err != nil { + t.Fatal(err) + } + out, err := ManifestFromProto(pm) + if err != nil { + t.Fatalf("decode failed for %v: %v", tc.ref, err) + } + gotRef := out.WasmResolvers[0].Annotations[0].Schemas[0].Schema + if !gotRef.Equal(tc.ref) { + t.Fatalf("schema ref not preserved: want %v, got %v", tc.ref, gotRef) + } + }) + } +} diff --git a/v1/bundle/v1pb/manifest.pb.go b/v1/bundle/v1pb/manifest.pb.go new file mode 100644 index 0000000000..018001f2d9 --- /dev/null +++ b/v1/bundle/v1pb/manifest.pb.go @@ -0,0 +1,751 @@ +// Copyright 2026 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v7.35.1 +// source: v1/bundle/manifest.proto + +package v1pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +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) +) + +// Manifest mirrors `bundle.Manifest` in v1/bundle/bundle.go. +type Manifest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Bundle revision string. + Revision *string `protobuf:"bytes,1,opt,name=revision" json:"revision,omitempty"` + // Root paths the bundle owns. See `roots_set` for nil-vs-empty. + Roots []string `protobuf:"bytes,2,rep,name=roots" json:"roots,omitempty"` + // Wasm resolvers attached to the bundle. JSON key is `wasm`. + Wasm []*WasmResolver `protobuf:"bytes,3,rep,name=wasm" json:"wasm,omitempty"` + // Global Rego version for the bundle. Currently 0 (RegoV0) or 1 (RegoV1). + RegoVersion *int32 `protobuf:"varint,4,opt,name=rego_version,json=regoVersion" json:"rego_version,omitempty"` + // Per-file Rego version overrides keyed by file path. + FileRegoVersions map[string]int32 `protobuf:"bytes,5,rep,name=file_rego_versions,json=fileRegoVersions" json:"file_rego_versions,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + // Free-form metadata object. Modeled as `Struct` because the Go field + // is `map[string]any`. + Metadata *structpb.Struct `protobuf:"bytes,6,opt,name=metadata" json:"metadata,omitempty"` + // True iff `bundle.Manifest.Roots` was non-nil. `repeated string` can't + // distinguish nil (default to [""]) from explicit-empty (owns no paths). + RootsSet *bool `protobuf:"varint,7,opt,name=roots_set,json=rootsSet" json:"roots_set,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Manifest) Reset() { + *x = Manifest{} + mi := &file_v1_bundle_manifest_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Manifest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Manifest) ProtoMessage() {} + +func (x *Manifest) ProtoReflect() protoreflect.Message { + mi := &file_v1_bundle_manifest_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Manifest.ProtoReflect.Descriptor instead. +func (*Manifest) Descriptor() ([]byte, []int) { + return file_v1_bundle_manifest_proto_rawDescGZIP(), []int{0} +} + +func (x *Manifest) GetRevision() string { + if x != nil && x.Revision != nil { + return *x.Revision + } + return "" +} + +func (x *Manifest) GetRoots() []string { + if x != nil { + return x.Roots + } + return nil +} + +func (x *Manifest) GetWasm() []*WasmResolver { + if x != nil { + return x.Wasm + } + return nil +} + +func (x *Manifest) GetRegoVersion() int32 { + if x != nil && x.RegoVersion != nil { + return *x.RegoVersion + } + return 0 +} + +func (x *Manifest) GetFileRegoVersions() map[string]int32 { + if x != nil { + return x.FileRegoVersions + } + return nil +} + +func (x *Manifest) GetMetadata() *structpb.Struct { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *Manifest) GetRootsSet() bool { + if x != nil && x.RootsSet != nil { + return *x.RootsSet + } + return false +} + +// WasmResolver mirrors `bundle.WasmResolver` in v1/bundle/bundle.go. +type WasmResolver struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Entrypoint policy ref this resolver targets. + Entrypoint *string `protobuf:"bytes,1,opt,name=entrypoint" json:"entrypoint,omitempty"` + // Path to the wasm module within the bundle. + Module *string `protobuf:"bytes,2,opt,name=module" json:"module,omitempty"` + // Rego annotations attached to the entrypoint. + Annotations []*Annotations `protobuf:"bytes,3,rep,name=annotations" json:"annotations,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WasmResolver) Reset() { + *x = WasmResolver{} + mi := &file_v1_bundle_manifest_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WasmResolver) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WasmResolver) ProtoMessage() {} + +func (x *WasmResolver) ProtoReflect() protoreflect.Message { + mi := &file_v1_bundle_manifest_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WasmResolver.ProtoReflect.Descriptor instead. +func (*WasmResolver) Descriptor() ([]byte, []int) { + return file_v1_bundle_manifest_proto_rawDescGZIP(), []int{1} +} + +func (x *WasmResolver) GetEntrypoint() string { + if x != nil && x.Entrypoint != nil { + return *x.Entrypoint + } + return "" +} + +func (x *WasmResolver) GetModule() string { + if x != nil && x.Module != nil { + return *x.Module + } + return "" +} + +func (x *WasmResolver) GetAnnotations() []*Annotations { + if x != nil { + return x.Annotations + } + return nil +} + +// Annotations mirrors `ast.Annotations` in v1/ast/annotations.go. +type Annotations struct { + state protoimpl.MessageState `protogen:"open.v1"` + Scope *string `protobuf:"bytes,1,opt,name=scope" json:"scope,omitempty"` + Title *string `protobuf:"bytes,2,opt,name=title" json:"title,omitempty"` + Entrypoint *bool `protobuf:"varint,3,opt,name=entrypoint" json:"entrypoint,omitempty"` + Description *string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"` + Organizations []string `protobuf:"bytes,5,rep,name=organizations" json:"organizations,omitempty"` + RelatedResources []*RelatedResourceAnnotation `protobuf:"bytes,6,rep,name=related_resources,json=relatedResources" json:"related_resources,omitempty"` + Authors []*AuthorAnnotation `protobuf:"bytes,7,rep,name=authors" json:"authors,omitempty"` + Schemas []*SchemaAnnotation `protobuf:"bytes,8,rep,name=schemas" json:"schemas,omitempty"` + Compile *CompileAnnotation `protobuf:"bytes,9,opt,name=compile" json:"compile,omitempty"` + // `custom` and `labels` are `map[string]any` in Go — genuinely + // free-form, so `Struct` is the right model. + Custom *structpb.Struct `protobuf:"bytes,10,opt,name=custom" json:"custom,omitempty"` + Labels *structpb.Struct `protobuf:"bytes,11,opt,name=labels" json:"labels,omitempty"` + Location *Location `protobuf:"bytes,12,opt,name=location" json:"location,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Annotations) Reset() { + *x = Annotations{} + mi := &file_v1_bundle_manifest_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Annotations) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Annotations) ProtoMessage() {} + +func (x *Annotations) ProtoReflect() protoreflect.Message { + mi := &file_v1_bundle_manifest_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Annotations.ProtoReflect.Descriptor instead. +func (*Annotations) Descriptor() ([]byte, []int) { + return file_v1_bundle_manifest_proto_rawDescGZIP(), []int{2} +} + +func (x *Annotations) GetScope() string { + if x != nil && x.Scope != nil { + return *x.Scope + } + return "" +} + +func (x *Annotations) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *Annotations) GetEntrypoint() bool { + if x != nil && x.Entrypoint != nil { + return *x.Entrypoint + } + return false +} + +func (x *Annotations) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *Annotations) GetOrganizations() []string { + if x != nil { + return x.Organizations + } + return nil +} + +func (x *Annotations) GetRelatedResources() []*RelatedResourceAnnotation { + if x != nil { + return x.RelatedResources + } + return nil +} + +func (x *Annotations) GetAuthors() []*AuthorAnnotation { + if x != nil { + return x.Authors + } + return nil +} + +func (x *Annotations) GetSchemas() []*SchemaAnnotation { + if x != nil { + return x.Schemas + } + return nil +} + +func (x *Annotations) GetCompile() *CompileAnnotation { + if x != nil { + return x.Compile + } + return nil +} + +func (x *Annotations) GetCustom() *structpb.Struct { + if x != nil { + return x.Custom + } + return nil +} + +func (x *Annotations) GetLabels() *structpb.Struct { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Annotations) GetLocation() *Location { + if x != nil { + return x.Location + } + return nil +} + +// SchemaAnnotation mirrors `ast.SchemaAnnotation`. Path/Schema are +// `ast.Ref` in Go (a list of terms); the wire form is the canonical +// dotted ref string (e.g. `data.foo.bar`). Modeling the term tree +// faithfully would pull most of the AST into this schema and isn't +// worth the cost for annotations. +type SchemaAnnotation struct { + state protoimpl.MessageState `protogen:"open.v1"` + Path *string `protobuf:"bytes,1,opt,name=path" json:"path,omitempty"` + Schema *string `protobuf:"bytes,2,opt,name=schema" json:"schema,omitempty"` + // `*any` on the Go side — a parsed JSON Schema document or any + // JSON value. `Value` (not `Struct`) because the top level may be + // a scalar, list, or null, not just an object. + Definition *structpb.Value `protobuf:"bytes,3,opt,name=definition" json:"definition,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SchemaAnnotation) Reset() { + *x = SchemaAnnotation{} + mi := &file_v1_bundle_manifest_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SchemaAnnotation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SchemaAnnotation) ProtoMessage() {} + +func (x *SchemaAnnotation) ProtoReflect() protoreflect.Message { + mi := &file_v1_bundle_manifest_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SchemaAnnotation.ProtoReflect.Descriptor instead. +func (*SchemaAnnotation) Descriptor() ([]byte, []int) { + return file_v1_bundle_manifest_proto_rawDescGZIP(), []int{3} +} + +func (x *SchemaAnnotation) GetPath() string { + if x != nil && x.Path != nil { + return *x.Path + } + return "" +} + +func (x *SchemaAnnotation) GetSchema() string { + if x != nil && x.Schema != nil { + return *x.Schema + } + return "" +} + +func (x *SchemaAnnotation) GetDefinition() *structpb.Value { + if x != nil { + return x.Definition + } + return nil +} + +// CompileAnnotation mirrors `ast.CompileAnnotation`. Refs are the +// canonical dotted form; see SchemaAnnotation for the trade-off. +type CompileAnnotation struct { + state protoimpl.MessageState `protogen:"open.v1"` + Unknowns []string `protobuf:"bytes,1,rep,name=unknowns" json:"unknowns,omitempty"` + MaskRule *string `protobuf:"bytes,2,opt,name=mask_rule,json=maskRule" json:"mask_rule,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CompileAnnotation) Reset() { + *x = CompileAnnotation{} + mi := &file_v1_bundle_manifest_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CompileAnnotation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompileAnnotation) ProtoMessage() {} + +func (x *CompileAnnotation) ProtoReflect() protoreflect.Message { + mi := &file_v1_bundle_manifest_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CompileAnnotation.ProtoReflect.Descriptor instead. +func (*CompileAnnotation) Descriptor() ([]byte, []int) { + return file_v1_bundle_manifest_proto_rawDescGZIP(), []int{4} +} + +func (x *CompileAnnotation) GetUnknowns() []string { + if x != nil { + return x.Unknowns + } + return nil +} + +func (x *CompileAnnotation) GetMaskRule() string { + if x != nil && x.MaskRule != nil { + return *x.MaskRule + } + return "" +} + +// AuthorAnnotation mirrors `ast.AuthorAnnotation`. +type AuthorAnnotation struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Email *string `protobuf:"bytes,2,opt,name=email" json:"email,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AuthorAnnotation) Reset() { + *x = AuthorAnnotation{} + mi := &file_v1_bundle_manifest_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AuthorAnnotation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorAnnotation) ProtoMessage() {} + +func (x *AuthorAnnotation) ProtoReflect() protoreflect.Message { + mi := &file_v1_bundle_manifest_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthorAnnotation.ProtoReflect.Descriptor instead. +func (*AuthorAnnotation) Descriptor() ([]byte, []int) { + return file_v1_bundle_manifest_proto_rawDescGZIP(), []int{5} +} + +func (x *AuthorAnnotation) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *AuthorAnnotation) GetEmail() string { + if x != nil && x.Email != nil { + return *x.Email + } + return "" +} + +// RelatedResourceAnnotation mirrors `ast.RelatedResourceAnnotation`. +// `Ref` is a `url.URL` in Go, serialized to its `String()` form. +type RelatedResourceAnnotation struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ref *string `protobuf:"bytes,1,opt,name=ref" json:"ref,omitempty"` + Description *string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RelatedResourceAnnotation) Reset() { + *x = RelatedResourceAnnotation{} + mi := &file_v1_bundle_manifest_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RelatedResourceAnnotation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RelatedResourceAnnotation) ProtoMessage() {} + +func (x *RelatedResourceAnnotation) ProtoReflect() protoreflect.Message { + mi := &file_v1_bundle_manifest_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RelatedResourceAnnotation.ProtoReflect.Descriptor instead. +func (*RelatedResourceAnnotation) Descriptor() ([]byte, []int) { + return file_v1_bundle_manifest_proto_rawDescGZIP(), []int{6} +} + +func (x *RelatedResourceAnnotation) GetRef() string { + if x != nil && x.Ref != nil { + return *x.Ref + } + return "" +} + +func (x *RelatedResourceAnnotation) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +// Location mirrors `ast.Location` (= `location.Location`). Only the +// File/Row/Col triple is wire-relevant; `Text`, `Offset`, and `Tabs` +// are tagged `json:"-"` and intentionally absent. +// +// Distinct from `ir.Location`, which is promoted onto the `Stmt` +// envelope in plan.proto. The two are independent Go types. +type Location struct { + state protoimpl.MessageState `protogen:"open.v1"` + File *string `protobuf:"bytes,1,opt,name=file" json:"file,omitempty"` + Row *int32 `protobuf:"varint,2,opt,name=row" json:"row,omitempty"` + Col *int32 `protobuf:"varint,3,opt,name=col" json:"col,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Location) Reset() { + *x = Location{} + mi := &file_v1_bundle_manifest_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Location) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Location) ProtoMessage() {} + +func (x *Location) ProtoReflect() protoreflect.Message { + mi := &file_v1_bundle_manifest_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Location.ProtoReflect.Descriptor instead. +func (*Location) Descriptor() ([]byte, []int) { + return file_v1_bundle_manifest_proto_rawDescGZIP(), []int{7} +} + +func (x *Location) GetFile() string { + if x != nil && x.File != nil { + return *x.File + } + return "" +} + +func (x *Location) GetRow() int32 { + if x != nil && x.Row != nil { + return *x.Row + } + return 0 +} + +func (x *Location) GetCol() int32 { + if x != nil && x.Col != nil { + return *x.Col + } + return 0 +} + +var File_v1_bundle_manifest_proto protoreflect.FileDescriptor + +const file_v1_bundle_manifest_proto_rawDesc = "" + + "\n" + + "\x18v1/bundle/manifest.proto\x12\ropa.bundle.v1\x1a\x1cgoogle/protobuf/struct.proto\"\x84\x03\n" + + "\bManifest\x12\x1a\n" + + "\brevision\x18\x01 \x01(\tR\brevision\x12\x14\n" + + "\x05roots\x18\x02 \x03(\tR\x05roots\x12/\n" + + "\x04wasm\x18\x03 \x03(\v2\x1b.opa.bundle.v1.WasmResolverR\x04wasm\x12!\n" + + "\frego_version\x18\x04 \x01(\x05R\vregoVersion\x12[\n" + + "\x12file_rego_versions\x18\x05 \x03(\v2-.opa.bundle.v1.Manifest.FileRegoVersionsEntryR\x10fileRegoVersions\x123\n" + + "\bmetadata\x18\x06 \x01(\v2\x17.google.protobuf.StructR\bmetadata\x12\x1b\n" + + "\troots_set\x18\a \x01(\bR\brootsSet\x1aC\n" + + "\x15FileRegoVersionsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01\"\x84\x01\n" + + "\fWasmResolver\x12\x1e\n" + + "\n" + + "entrypoint\x18\x01 \x01(\tR\n" + + "entrypoint\x12\x16\n" + + "\x06module\x18\x02 \x01(\tR\x06module\x12<\n" + + "\vannotations\x18\x03 \x03(\v2\x1a.opa.bundle.v1.AnnotationsR\vannotations\"\xc1\x04\n" + + "\vAnnotations\x12\x14\n" + + "\x05scope\x18\x01 \x01(\tR\x05scope\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12\x1e\n" + + "\n" + + "entrypoint\x18\x03 \x01(\bR\n" + + "entrypoint\x12 \n" + + "\vdescription\x18\x04 \x01(\tR\vdescription\x12$\n" + + "\rorganizations\x18\x05 \x03(\tR\rorganizations\x12U\n" + + "\x11related_resources\x18\x06 \x03(\v2(.opa.bundle.v1.RelatedResourceAnnotationR\x10relatedResources\x129\n" + + "\aauthors\x18\a \x03(\v2\x1f.opa.bundle.v1.AuthorAnnotationR\aauthors\x129\n" + + "\aschemas\x18\b \x03(\v2\x1f.opa.bundle.v1.SchemaAnnotationR\aschemas\x12:\n" + + "\acompile\x18\t \x01(\v2 .opa.bundle.v1.CompileAnnotationR\acompile\x12/\n" + + "\x06custom\x18\n" + + " \x01(\v2\x17.google.protobuf.StructR\x06custom\x12/\n" + + "\x06labels\x18\v \x01(\v2\x17.google.protobuf.StructR\x06labels\x123\n" + + "\blocation\x18\f \x01(\v2\x17.opa.bundle.v1.LocationR\blocation\"v\n" + + "\x10SchemaAnnotation\x12\x12\n" + + "\x04path\x18\x01 \x01(\tR\x04path\x12\x16\n" + + "\x06schema\x18\x02 \x01(\tR\x06schema\x126\n" + + "\n" + + "definition\x18\x03 \x01(\v2\x16.google.protobuf.ValueR\n" + + "definition\"L\n" + + "\x11CompileAnnotation\x12\x1a\n" + + "\bunknowns\x18\x01 \x03(\tR\bunknowns\x12\x1b\n" + + "\tmask_rule\x18\x02 \x01(\tR\bmaskRule\"<\n" + + "\x10AuthorAnnotation\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + + "\x05email\x18\x02 \x01(\tR\x05email\"O\n" + + "\x19RelatedResourceAnnotation\x12\x10\n" + + "\x03ref\x18\x01 \x01(\tR\x03ref\x12 \n" + + "\vdescription\x18\x02 \x01(\tR\vdescription\"B\n" + + "\bLocation\x12\x12\n" + + "\x04file\x18\x01 \x01(\tR\x04file\x12\x10\n" + + "\x03row\x18\x02 \x01(\x05R\x03row\x12\x10\n" + + "\x03col\x18\x03 \x01(\x05R\x03colB3P\x01Z/github.com/open-policy-agent/opa/v1/bundle/v1pbb\beditionsp\xe8\a" + +var ( + file_v1_bundle_manifest_proto_rawDescOnce sync.Once + file_v1_bundle_manifest_proto_rawDescData []byte +) + +func file_v1_bundle_manifest_proto_rawDescGZIP() []byte { + file_v1_bundle_manifest_proto_rawDescOnce.Do(func() { + file_v1_bundle_manifest_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_v1_bundle_manifest_proto_rawDesc), len(file_v1_bundle_manifest_proto_rawDesc))) + }) + return file_v1_bundle_manifest_proto_rawDescData +} + +var file_v1_bundle_manifest_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_v1_bundle_manifest_proto_goTypes = []any{ + (*Manifest)(nil), // 0: opa.bundle.v1.Manifest + (*WasmResolver)(nil), // 1: opa.bundle.v1.WasmResolver + (*Annotations)(nil), // 2: opa.bundle.v1.Annotations + (*SchemaAnnotation)(nil), // 3: opa.bundle.v1.SchemaAnnotation + (*CompileAnnotation)(nil), // 4: opa.bundle.v1.CompileAnnotation + (*AuthorAnnotation)(nil), // 5: opa.bundle.v1.AuthorAnnotation + (*RelatedResourceAnnotation)(nil), // 6: opa.bundle.v1.RelatedResourceAnnotation + (*Location)(nil), // 7: opa.bundle.v1.Location + nil, // 8: opa.bundle.v1.Manifest.FileRegoVersionsEntry + (*structpb.Struct)(nil), // 9: google.protobuf.Struct + (*structpb.Value)(nil), // 10: google.protobuf.Value +} +var file_v1_bundle_manifest_proto_depIdxs = []int32{ + 1, // 0: opa.bundle.v1.Manifest.wasm:type_name -> opa.bundle.v1.WasmResolver + 8, // 1: opa.bundle.v1.Manifest.file_rego_versions:type_name -> opa.bundle.v1.Manifest.FileRegoVersionsEntry + 9, // 2: opa.bundle.v1.Manifest.metadata:type_name -> google.protobuf.Struct + 2, // 3: opa.bundle.v1.WasmResolver.annotations:type_name -> opa.bundle.v1.Annotations + 6, // 4: opa.bundle.v1.Annotations.related_resources:type_name -> opa.bundle.v1.RelatedResourceAnnotation + 5, // 5: opa.bundle.v1.Annotations.authors:type_name -> opa.bundle.v1.AuthorAnnotation + 3, // 6: opa.bundle.v1.Annotations.schemas:type_name -> opa.bundle.v1.SchemaAnnotation + 4, // 7: opa.bundle.v1.Annotations.compile:type_name -> opa.bundle.v1.CompileAnnotation + 9, // 8: opa.bundle.v1.Annotations.custom:type_name -> google.protobuf.Struct + 9, // 9: opa.bundle.v1.Annotations.labels:type_name -> google.protobuf.Struct + 7, // 10: opa.bundle.v1.Annotations.location:type_name -> opa.bundle.v1.Location + 10, // 11: opa.bundle.v1.SchemaAnnotation.definition:type_name -> google.protobuf.Value + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name +} + +func init() { file_v1_bundle_manifest_proto_init() } +func file_v1_bundle_manifest_proto_init() { + if File_v1_bundle_manifest_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_v1_bundle_manifest_proto_rawDesc), len(file_v1_bundle_manifest_proto_rawDesc)), + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_v1_bundle_manifest_proto_goTypes, + DependencyIndexes: file_v1_bundle_manifest_proto_depIdxs, + MessageInfos: file_v1_bundle_manifest_proto_msgTypes, + }.Build() + File_v1_bundle_manifest_proto = out.File + file_v1_bundle_manifest_proto_goTypes = nil + file_v1_bundle_manifest_proto_depIdxs = nil +} diff --git a/v1/compile/compile.go b/v1/compile/compile.go index 1b2a054f74..a2ceff27c3 100644 --- a/v1/compile/compile.go +++ b/v1/compile/compile.go @@ -19,6 +19,8 @@ import ( "sort" "strings" + "google.golang.org/protobuf/proto" + "github.com/open-policy-agent/opa/internal/compiler/wasm" "github.com/open-policy-agent/opa/internal/debug" "github.com/open-policy-agent/opa/internal/planner" @@ -50,6 +52,15 @@ const ( TargetPlan = "plan" ) +// Plan output formats. Only meaningful when Target == TargetPlan. +const ( + PlanFormatJSON = "json" + PlanFormatProto = "proto" +) + +// PlanFormats contains the list of plan output formats supported by the compiler. +var PlanFormats = []string{PlanFormatJSON, PlanFormatProto} + // Targets contains the list of targets supported by the compiler. var Targets = []string{ TargetRego, @@ -73,6 +84,7 @@ type Compiler struct { useRegoAnnotationEntrypoints bool // allow compiler to late-bind entrypoints from annotated rules in policies. optimizationLevel int // how aggressive should optimization be target string // target type (wasm, rego, etc.) + planFormat string // plan output format (json or proto) output *io.Writer // output stream to write bundle to entrypointrefs []*ast.Term // validated entrypoints computed from default decision or manually supplied entrypoints compiler *ast.Compiler // rego ast compiler used for semantic checks and rewriting @@ -97,6 +109,7 @@ func New() *Compiler { asBundle: false, optimizationLevel: 0, target: TargetRego, + planFormat: PlanFormatJSON, debug: debug.Discard(), regoVersion: ast.DefaultRegoVersion, } @@ -158,6 +171,12 @@ func (c *Compiler) WithTarget(t string) *Compiler { return c } +// WithPlanFormat sets the wire-format (json or proto) for plan-target builds. +func (c *Compiler) WithPlanFormat(f string) *Compiler { + c.planFormat = f + return c +} + // WithOutput sets the output stream to write the bundle to. func (c *Compiler) WithOutput(w io.Writer) *Compiler { c.output = &w @@ -315,6 +334,13 @@ func (c *Compiler) Build(ctx context.Context) error { return errors.New("rego-version not set") } + if !slices.Contains(PlanFormats, c.planFormat) { + return fmt.Errorf("unsupported plan format %q (want one of %v)", c.planFormat, PlanFormats) + } + if c.planFormat != PlanFormatJSON && c.target != TargetPlan { + return fmt.Errorf("plan format %q is only valid with target %q", c.planFormat, TargetPlan) + } + if err := c.init(); err != nil { return err } @@ -374,14 +400,31 @@ func (c *Compiler) Build(ctx context.Context) error { return err } - bs, err := json.Marshal(c.policy) + var ( + bs []byte + planPath string + err error + ) + switch c.planFormat { + case PlanFormatProto: + // Deterministic for byte-identical plan.pb across builds. + pbPolicy, perr := ir.PolicyToProto(c.policy) + if perr != nil { + return perr + } + bs, err = proto.MarshalOptions{Deterministic: true}.Marshal(pbPolicy) + planPath = bundle.PlanProtoFile + case PlanFormatJSON: + bs, err = json.Marshal(c.policy) + planPath = bundle.PlanFile + } if err != nil { return err } c.bundle.PlanModules = append(c.bundle.PlanModules, bundle.PlanModuleFile{ - Path: bundle.PlanFile, - URL: bundle.PlanFile, + Path: planPath, + URL: planPath, Raw: bs, }) case TargetRego: @@ -396,6 +439,8 @@ func (c *Compiler) Build(ctx context.Context) error { c.bundle.Manifest.Metadata = *c.metadata } + c.bundle.SetManifestProto(c.target == TargetPlan && c.planFormat == PlanFormatProto) + if err := c.bundle.FormatModulesWithOptions(bundle.BundleFormatOptions{ RegoVersion: c.regoVersion, Capabilities: c.capabilities, diff --git a/v1/compile/compile_test.go b/v1/compile/compile_test.go index 6d3581dcd3..acade246e8 100644 --- a/v1/compile/compile_test.go +++ b/v1/compile/compile_test.go @@ -104,6 +104,16 @@ func TestCompilerInitErrors(t *testing.T) { c: New().WithTarget("plan"), want: errors.New("plan compilation requires at least one entrypoint"), }, + { + note: "unsupported plan format", + c: New().WithPlanFormat("xml"), + want: fmt.Errorf("unsupported plan format %q (want one of %v)", "xml", PlanFormats), + }, + { + note: "plan format requires plan target", + c: New().WithPlanFormat(PlanFormatProto), + want: fmt.Errorf("plan format %q is only valid with target %q", PlanFormatProto, TargetPlan), + }, } for _, tc := range tests { @@ -1012,6 +1022,39 @@ func TestCompilerLoadFilesystemWithEnablePrintStatementsTrue(t *testing.T) { } } +func TestCompilerProtoPlanIsDeterministic(t *testing.T) { + files := map[string]string{ + "test.rego": ` + package test + import rego.v1 + + allow if { input.user == "alice" } + deny if { input.user == "mallory" } + `, + } + + // Single root keeps Static.Files (source paths) stable across builds. + test.WithTempFS(files, func(root string) { + build := func() []byte { + compiler := New(). + WithPaths(root). + WithTarget(TargetPlan). + WithPlanFormat(PlanFormatProto). + WithEntrypoints("test/allow", "test/deny") + if err := compiler.Build(t.Context()); err != nil { + t.Fatal(err) + } + return append([]byte(nil), compiler.Bundle().PlanModules[0].Raw...) + } + + a := build() + b := build() + if !bytes.Equal(a, b) { + t.Fatalf("plan.pb bytes differ across builds (len %d vs %d)", len(a), len(b)) + } + }) +} + func TestCompilerLoadHonorsFilter(t *testing.T) { files := map[string]string{ "test.rego": ` diff --git a/v1/ir/proto.go b/v1/ir/proto.go new file mode 100644 index 0000000000..0c89dcb105 --- /dev/null +++ b/v1/ir/proto.go @@ -0,0 +1,340 @@ +// Copyright 2026 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package ir + +import ( + "fmt" + "math" + + "google.golang.org/protobuf/proto" + + pb "github.com/open-policy-agent/opa/v1/ir/v1pb" +) + +// PolicyToProto converts an IR Policy to its protobuf wire-form, +// defined in v1/ir/plan.proto. Returns an error if the policy contains +// a Stmt or Val kind not yet covered by the encoder switch. +func PolicyToProto(p *Policy) (out *pb.Policy, err error) { + if p == nil { + return nil, nil + } + defer func() { + if r := recover(); r != nil { + out = nil + err = fmt.Errorf("ir: PolicyToProto: %v", r) + } + }() + return &pb.Policy{ + Static: staticToProto(p.Static), + Plans: plansToProto(p.Plans), + Funcs: funcsToProto(p.Funcs), + }, nil +} + +func staticToProto(s *Static) *pb.Static { + if s == nil { + return nil + } + out := &pb.Static{ + Strings: make([]*pb.StringConst, len(s.Strings)), + BuiltinFuncs: make([]*pb.BuiltinFunc, len(s.BuiltinFuncs)), + Files: make([]*pb.StringConst, len(s.Files)), + } + for i, sc := range s.Strings { + out.Strings[i] = stringConstToProto(sc) + } + for i, bf := range s.BuiltinFuncs { + out.BuiltinFuncs[i] = builtinFuncToProto(bf) + } + for i, f := range s.Files { + out.Files[i] = stringConstToProto(f) + } + return out +} + +func stringConstToProto(s *StringConst) *pb.StringConst { + if s == nil { + return nil + } + return &pb.StringConst{Value: proto.String(s.Value)} +} + +func builtinFuncToProto(b *BuiltinFunc) *pb.BuiltinFunc { + if b == nil { + return nil + } + return &pb.BuiltinFunc{Name: proto.String(b.Name)} +} + +func plansToProto(p *Plans) *pb.Plans { + if p == nil { + return nil + } + out := &pb.Plans{Plans: make([]*pb.Plan, len(p.Plans))} + for i, pl := range p.Plans { + out.Plans[i] = planToProto(pl) + } + return out +} + +func planToProto(p *Plan) *pb.Plan { + if p == nil { + return nil + } + out := &pb.Plan{Name: proto.String(p.Name), Blocks: make([]*pb.Block, len(p.Blocks))} + for i, b := range p.Blocks { + out.Blocks[i] = blockToProto(b) + } + return out +} + +func funcsToProto(f *Funcs) *pb.Funcs { + if f == nil { + return nil + } + out := &pb.Funcs{Funcs: make([]*pb.Func, len(f.Funcs))} + for i, fn := range f.Funcs { + out.Funcs[i] = funcToProto(fn) + } + return out +} + +func funcToProto(f *Func) *pb.Func { + if f == nil { + return nil + } + out := &pb.Func{ + Name: proto.String(f.Name), + Params: localsToInt32s(f.Params), + Result: proto.Int32(toInt32(f.Return)), + Blocks: make([]*pb.Block, len(f.Blocks)), + Path: f.Path, + } + for i, b := range f.Blocks { + out.Blocks[i] = blockToProto(b) + } + return out +} + +func blockToProto(b *Block) *pb.Block { + if b == nil { + return nil + } + out := &pb.Block{Stmts: make([]*pb.Stmt, len(b.Stmts))} + for i, s := range b.Stmts { + out.Stmts[i] = stmtToProto(s) + } + return out +} + +func operandToProto(o Operand) *pb.Operand { + return &pb.Operand{Value: valToProto(o.Value)} +} + +func operandsToProto(os []Operand) []*pb.Operand { + out := make([]*pb.Operand, len(os)) + for i, o := range os { + out[i] = operandToProto(o) + } + return out +} + +func valToProto(v Val) *pb.Val { + if v == nil { + return nil + } + switch x := v.(type) { + case Local: + return &pb.Val{Kind: &pb.Val_Local{Local: toInt32(x)}} + case StringIndex: + return &pb.Val{Kind: &pb.Val_StringIndex{StringIndex: toInt32(x)}} + case Bool: + return &pb.Val{Kind: &pb.Val_Bool{Bool: bool(x)}} + default: + panic(fmt.Sprintf("unsupported Val type %T", v)) + } +} + +// toInt32 narrows an int-based value to int32, panicking if it would +// overflow. PolicyToProto recovers from the panic and returns it as an +// error, so callers don't need to check the bound themselves. +func toInt32[T ~int](v T) int32 { + if int64(v) > math.MaxInt32 || int64(v) < math.MinInt32 { + panic(fmt.Sprintf("value %d overflows int32", int64(v))) + } + return int32(v) +} + +func localsToInt32s(ls []Local) []int32 { + out := make([]int32, len(ls)) + for i, l := range ls { + out[i] = toInt32(l) + } + return out +} + +func intsToInt32s(is []int) []int32 { + out := make([]int32, len(is)) + for i, v := range is { + out[i] = toInt32(v) + } + return out +} + +func stmtToProto(s Stmt) *pb.Stmt { + if s == nil { + return nil + } + loc := s.GetLocation() + out := &pb.Stmt{ + File: proto.Int32(toInt32(loc.File)), + Col: proto.Int32(toInt32(loc.Col)), + Row: proto.Int32(toInt32(loc.Row)), + } + switch x := s.(type) { + case *ArrayAppendStmt: + out.Kind = &pb.Stmt_ArrayAppendStmt{ArrayAppendStmt: &pb.ArrayAppendStmt{ + Value: operandToProto(x.Value), + Array: proto.Int32(toInt32(x.Array)), + }} + case *AssignIntStmt: + out.Kind = &pb.Stmt_AssignIntStmt{AssignIntStmt: &pb.AssignIntStmt{ + Value: proto.Int64(x.Value), + Target: proto.Int32(toInt32(x.Target)), + }} + case *AssignVarOnceStmt: + out.Kind = &pb.Stmt_AssignVarOnceStmt{AssignVarOnceStmt: &pb.AssignVarOnceStmt{ + Source: operandToProto(x.Source), + Target: proto.Int32(toInt32(x.Target)), + }} + case *AssignVarStmt: + out.Kind = &pb.Stmt_AssignVarStmt{AssignVarStmt: &pb.AssignVarStmt{ + Source: operandToProto(x.Source), + Target: proto.Int32(toInt32(x.Target)), + }} + case *BlockStmt: + body := &pb.BlockStmt{Blocks: make([]*pb.Block, len(x.Blocks))} + for i, b := range x.Blocks { + body.Blocks[i] = blockToProto(b) + } + out.Kind = &pb.Stmt_BlockStmt{BlockStmt: body} + case *BreakStmt: + out.Kind = &pb.Stmt_BreakStmt{BreakStmt: &pb.BreakStmt{Index: proto.Uint32(x.Index)}} + case *CallDynamicStmt: + out.Kind = &pb.Stmt_CallDynamicStmt{CallDynamicStmt: &pb.CallDynamicStmt{ + Args: localsToInt32s(x.Args), + Result: proto.Int32(toInt32(x.Result)), + Path: operandsToProto(x.Path), + }} + case *CallStmt: + out.Kind = &pb.Stmt_CallStmt{CallStmt: &pb.CallStmt{ + Function: proto.String(x.Func), + Args: operandsToProto(x.Args), + Result: proto.Int32(toInt32(x.Result)), + }} + case *DotStmt: + out.Kind = &pb.Stmt_DotStmt{DotStmt: &pb.DotStmt{ + Source: operandToProto(x.Source), + Key: operandToProto(x.Key), + Target: proto.Int32(toInt32(x.Target)), + }} + case *EqualStmt: + out.Kind = &pb.Stmt_EqualStmt{EqualStmt: &pb.EqualStmt{ + A: operandToProto(x.A), + B: operandToProto(x.B), + }} + case *IsArrayStmt: + out.Kind = &pb.Stmt_IsArrayStmt{IsArrayStmt: &pb.IsArrayStmt{Source: operandToProto(x.Source)}} + case *IsDefinedStmt: + out.Kind = &pb.Stmt_IsDefinedStmt{IsDefinedStmt: &pb.IsDefinedStmt{Source: proto.Int32(toInt32(x.Source))}} + case *IsObjectStmt: + out.Kind = &pb.Stmt_IsObjectStmt{IsObjectStmt: &pb.IsObjectStmt{Source: operandToProto(x.Source)}} + case *IsSetStmt: + out.Kind = &pb.Stmt_IsSetStmt{IsSetStmt: &pb.IsSetStmt{Source: operandToProto(x.Source)}} + case *IsUndefinedStmt: + out.Kind = &pb.Stmt_IsUndefinedStmt{IsUndefinedStmt: &pb.IsUndefinedStmt{Source: proto.Int32(toInt32(x.Source))}} + case *LenStmt: + out.Kind = &pb.Stmt_LenStmt{LenStmt: &pb.LenStmt{ + Source: operandToProto(x.Source), + Target: proto.Int32(toInt32(x.Target)), + }} + case *MakeArrayStmt: + out.Kind = &pb.Stmt_MakeArrayStmt{MakeArrayStmt: &pb.MakeArrayStmt{ + Capacity: proto.Int32(x.Capacity), + Target: proto.Int32(toInt32(x.Target)), + }} + case *MakeNullStmt: + out.Kind = &pb.Stmt_MakeNullStmt{MakeNullStmt: &pb.MakeNullStmt{Target: proto.Int32(toInt32(x.Target))}} + case *MakeNumberIntStmt: + out.Kind = &pb.Stmt_MakeNumberIntStmt{MakeNumberIntStmt: &pb.MakeNumberIntStmt{ + Value: proto.Int64(x.Value), + Target: proto.Int32(toInt32(x.Target)), + }} + case *MakeNumberRefStmt: + out.Kind = &pb.Stmt_MakeNumberRefStmt{MakeNumberRefStmt: &pb.MakeNumberRefStmt{ + Index: proto.Int32(toInt32(x.Index)), + Target: proto.Int32(toInt32(x.Target)), + }} + case *MakeObjectStmt: + out.Kind = &pb.Stmt_MakeObjectStmt{MakeObjectStmt: &pb.MakeObjectStmt{Target: proto.Int32(toInt32(x.Target))}} + case *MakeSetStmt: + out.Kind = &pb.Stmt_MakeSetStmt{MakeSetStmt: &pb.MakeSetStmt{Target: proto.Int32(toInt32(x.Target))}} + case *NopStmt: + out.Kind = &pb.Stmt_NopStmt{NopStmt: &pb.NopStmt{}} + case *NotEqualStmt: + out.Kind = &pb.Stmt_NotEqualStmt{NotEqualStmt: &pb.NotEqualStmt{ + A: operandToProto(x.A), + B: operandToProto(x.B), + }} + case *NotStmt: + out.Kind = &pb.Stmt_NotStmt{NotStmt: &pb.NotStmt{Block: blockToProto(x.Block)}} + case *ObjectInsertOnceStmt: + out.Kind = &pb.Stmt_ObjectInsertOnceStmt{ObjectInsertOnceStmt: &pb.ObjectInsertOnceStmt{ + Key: operandToProto(x.Key), + Value: operandToProto(x.Value), + Object: proto.Int32(toInt32(x.Object)), + }} + case *ObjectInsertStmt: + out.Kind = &pb.Stmt_ObjectInsertStmt{ObjectInsertStmt: &pb.ObjectInsertStmt{ + Key: operandToProto(x.Key), + Value: operandToProto(x.Value), + Object: proto.Int32(toInt32(x.Object)), + }} + case *ObjectMergeStmt: + out.Kind = &pb.Stmt_ObjectMergeStmt{ObjectMergeStmt: &pb.ObjectMergeStmt{ + A: proto.Int32(toInt32(x.A)), + B: proto.Int32(toInt32(x.B)), + Target: proto.Int32(toInt32(x.Target)), + }} + case *ResetLocalStmt: + out.Kind = &pb.Stmt_ResetLocalStmt{ResetLocalStmt: &pb.ResetLocalStmt{Target: proto.Int32(toInt32(x.Target))}} + case *ResultSetAddStmt: + out.Kind = &pb.Stmt_ResultSetAddStmt{ResultSetAddStmt: &pb.ResultSetAddStmt{Value: proto.Int32(toInt32(x.Value))}} + case *ReturnLocalStmt: + out.Kind = &pb.Stmt_ReturnLocalStmt{ReturnLocalStmt: &pb.ReturnLocalStmt{Source: proto.Int32(toInt32(x.Source))}} + case *ScanStmt: + out.Kind = &pb.Stmt_ScanStmt{ScanStmt: &pb.ScanStmt{ + Source: proto.Int32(toInt32(x.Source)), + Key: proto.Int32(toInt32(x.Key)), + Value: proto.Int32(toInt32(x.Value)), + Block: blockToProto(x.Block), + }} + case *SetAddStmt: + out.Kind = &pb.Stmt_SetAddStmt{SetAddStmt: &pb.SetAddStmt{ + Value: operandToProto(x.Value), + Set: proto.Int32(toInt32(x.Set)), + }} + case *WithStmt: + out.Kind = &pb.Stmt_WithStmt{WithStmt: &pb.WithStmt{ + Local: proto.Int32(toInt32(x.Local)), + Path: intsToInt32s(x.Path), + Value: operandToProto(x.Value), + Block: blockToProto(x.Block), + }} + default: + panic(fmt.Sprintf("unsupported Stmt type %T", s)) + } + return out +} diff --git a/v1/ir/proto_test.go b/v1/ir/proto_test.go new file mode 100644 index 0000000000..d14942e346 --- /dev/null +++ b/v1/ir/proto_test.go @@ -0,0 +1,184 @@ +// Copyright 2026 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +package ir_test + +import ( + "math" + "strings" + "testing" + + "google.golang.org/protobuf/proto" + + "github.com/open-policy-agent/opa/v1/ir" + pb "github.com/open-policy-agent/opa/v1/ir/v1pb" +) + +func TestPolicyToProtoRoundTrip(t *testing.T) { + loc := ir.Location{File: 1, Row: 2, Col: 3} + withLoc := func(s ir.Stmt) ir.Stmt { + s.SetLocation(loc.File, loc.Row, loc.Col, "", "") + return s + } + + p := &ir.Policy{ + Static: &ir.Static{ + Strings: []*ir.StringConst{{Value: "hello"}, {Value: "world"}}, + BuiltinFuncs: []*ir.BuiltinFunc{{Name: "eq"}}, + Files: []*ir.StringConst{{Value: "a.rego"}}, + }, + Plans: &ir.Plans{Plans: []*ir.Plan{{ + Name: "p", + Blocks: []*ir.Block{{Stmts: []ir.Stmt{ + withLoc(&ir.ReturnLocalStmt{Source: ir.Local(1)}), + withLoc(&ir.CallStmt{Func: "f", Args: []ir.Operand{{Value: ir.Local(2)}}, Result: ir.Local(3)}), + withLoc(&ir.CallDynamicStmt{Args: []ir.Local{1, 2}, Result: 3, Path: []ir.Operand{{Value: ir.StringIndex(0)}}}), + withLoc(&ir.BlockStmt{Blocks: []*ir.Block{{Stmts: []ir.Stmt{withLoc(&ir.NopStmt{})}}}}), + withLoc(&ir.BreakStmt{Index: 1}), + withLoc(&ir.DotStmt{Source: ir.Operand{Value: ir.Local(1)}, Key: ir.Operand{Value: ir.StringIndex(0)}, Target: ir.Local(2)}), + withLoc(&ir.LenStmt{Source: ir.Operand{Value: ir.Local(1)}, Target: ir.Local(2)}), + withLoc(&ir.ScanStmt{Source: 1, Key: 2, Value: 3, Block: &ir.Block{Stmts: []ir.Stmt{withLoc(&ir.NopStmt{})}}}), + withLoc(&ir.NotStmt{Block: &ir.Block{Stmts: []ir.Stmt{withLoc(&ir.NopStmt{})}}}), + withLoc(&ir.AssignIntStmt{Value: 42, Target: ir.Local(1)}), + withLoc(&ir.AssignVarStmt{Source: ir.Operand{Value: ir.Local(1)}, Target: ir.Local(2)}), + withLoc(&ir.AssignVarOnceStmt{Source: ir.Operand{Value: ir.Local(1)}, Target: ir.Local(2)}), + withLoc(&ir.ResetLocalStmt{Target: ir.Local(1)}), + withLoc(&ir.MakeNullStmt{Target: ir.Local(1)}), + withLoc(&ir.MakeNumberIntStmt{Value: 7, Target: ir.Local(1)}), + withLoc(&ir.MakeNumberRefStmt{Index: 0, Target: ir.Local(1)}), + withLoc(&ir.MakeArrayStmt{Capacity: 4, Target: ir.Local(1)}), + withLoc(&ir.MakeObjectStmt{Target: ir.Local(1)}), + withLoc(&ir.MakeSetStmt{Target: ir.Local(1)}), + withLoc(&ir.EqualStmt{A: ir.Operand{Value: ir.Local(1)}, B: ir.Operand{Value: ir.Bool(true)}}), + withLoc(&ir.NotEqualStmt{A: ir.Operand{Value: ir.Local(1)}, B: ir.Operand{Value: ir.Local(2)}}), + withLoc(&ir.IsArrayStmt{Source: ir.Operand{Value: ir.Local(1)}}), + withLoc(&ir.IsObjectStmt{Source: ir.Operand{Value: ir.Local(1)}}), + withLoc(&ir.IsSetStmt{Source: ir.Operand{Value: ir.Local(1)}}), + withLoc(&ir.IsDefinedStmt{Source: ir.Local(1)}), + withLoc(&ir.IsUndefinedStmt{Source: ir.Local(1)}), + withLoc(&ir.ArrayAppendStmt{Value: ir.Operand{Value: ir.Local(1)}, Array: ir.Local(2)}), + withLoc(&ir.ObjectInsertStmt{Key: ir.Operand{Value: ir.StringIndex(0)}, Value: ir.Operand{Value: ir.Local(1)}, Object: ir.Local(2)}), + withLoc(&ir.ObjectInsertOnceStmt{Key: ir.Operand{Value: ir.StringIndex(0)}, Value: ir.Operand{Value: ir.Local(1)}, Object: ir.Local(2)}), + withLoc(&ir.ObjectMergeStmt{A: 1, B: 2, Target: 3}), + withLoc(&ir.SetAddStmt{Value: ir.Operand{Value: ir.Local(1)}, Set: ir.Local(2)}), + withLoc(&ir.WithStmt{Local: 1, Path: []int{0, 1}, Value: ir.Operand{Value: ir.Local(2)}, Block: &ir.Block{Stmts: []ir.Stmt{withLoc(&ir.NopStmt{})}}}), + withLoc(&ir.ResultSetAddStmt{Value: ir.Local(1)}), + }}}, + }}}, + Funcs: &ir.Funcs{Funcs: []*ir.Func{{ + Name: "g", + Params: []ir.Local{1, 2}, + Return: ir.Local(3), + Path: []string{"a", "b"}, + Blocks: []*ir.Block{{Stmts: []ir.Stmt{withLoc(&ir.NopStmt{})}}}, + }}}, + } + + pbPolicy, err := ir.PolicyToProto(p) + if err != nil { + t.Fatalf("PolicyToProto: %v", err) + } + bs, err := proto.Marshal(pbPolicy) + if err != nil { + t.Fatalf("marshal: %v", err) + } + + decoded := &pb.Policy{} + if err := proto.Unmarshal(bs, decoded); err != nil { + t.Fatalf("unmarshal: %v", err) + } + + bs2, err := proto.Marshal(decoded) + if err != nil { + t.Fatalf("re-marshal: %v", err) + } + if !proto.Equal(pbPolicy, decoded) { + t.Fatal("decoded proto differs from original") + } + if len(bs) != len(bs2) { + t.Fatalf("re-encoded byte length differs: %d vs %d", len(bs), len(bs2)) + } +} + +func TestPolicyToProtoNil(t *testing.T) { + got, err := ir.PolicyToProto(nil) + if err != nil { + t.Fatal(err) + } + if got != nil { + t.Fatalf("expected nil for nil input, got %v", got) + } +} + +func TestPolicyToProtoEmitsLocationTripleAlways(t *testing.T) { + p := &ir.Policy{ + Plans: &ir.Plans{Plans: []*ir.Plan{{ + Name: "p", + Blocks: []*ir.Block{{Stmts: []ir.Stmt{ + &ir.NopStmt{}, // no SetLocation call + }}}, + }}}, + } + pbPolicy, err := ir.PolicyToProto(p) + if err != nil { + t.Fatal(err) + } + stmt := pbPolicy.Plans.Plans[0].Blocks[0].Stmts[0] + if stmt.File == nil || *stmt.File != 0 { + t.Errorf("File: want 0 (always present), got %v", stmt.File) + } + if stmt.Row == nil || *stmt.Row != 0 { + t.Errorf("Row: want 0 (always present), got %v", stmt.Row) + } + if stmt.Col == nil || *stmt.Col != 0 { + t.Errorf("Col: want 0 (always present), got %v", stmt.Col) + } +} + +// unsupportedStmt is a Stmt kind the encoder switch doesn't handle. +type unsupportedStmt struct{ ir.Location } + +func TestPolicyToProtoUnknownStmtReturnsError(t *testing.T) { + p := &ir.Policy{ + Plans: &ir.Plans{Plans: []*ir.Plan{{ + Name: "p", + Blocks: []*ir.Block{{Stmts: []ir.Stmt{ + &unsupportedStmt{}, + }}}, + }}}, + } + + got, err := ir.PolicyToProto(p) + if err == nil { + t.Fatal("expected error for unknown Stmt type, got nil") + } + if got != nil { + t.Fatalf("expected nil result on error, got %v", got) + } + if !strings.Contains(err.Error(), "unsupportedStmt") { + t.Fatalf("error should name the offending type: %v", err) + } +} + +func TestPolicyToProtoInt32OverflowReturnsError(t *testing.T) { + p := &ir.Policy{ + Plans: &ir.Plans{Plans: []*ir.Plan{{ + Name: "p", + Blocks: []*ir.Block{{Stmts: []ir.Stmt{ + &ir.ReturnLocalStmt{Source: ir.Local(math.MaxInt32 + 1)}, + }}}, + }}}, + } + + got, err := ir.PolicyToProto(p) + if err == nil { + t.Fatal("expected error for int32 overflow, got nil") + } + if got != nil { + t.Fatalf("expected nil result on error, got %v", got) + } + if !strings.Contains(err.Error(), "overflows int32") { + t.Fatalf("error should mention the overflow: %v", err) + } +} diff --git a/v1/ir/v1pb/plan.pb.go b/v1/ir/v1pb/plan.pb.go new file mode 100644 index 0000000000..a47afbcc0f --- /dev/null +++ b/v1/ir/v1pb/plan.pb.go @@ -0,0 +1,3449 @@ +// Copyright 2026 The OPA Authors. All rights reserved. +// Use of this source code is governed by an Apache2 +// license that can be found in the LICENSE file. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v7.35.1 +// source: v1/ir/plan.proto + +package v1pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +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) +) + +// Policy mirrors `ir.Policy` in v1/ir/ir.go. +type Policy struct { + state protoimpl.MessageState `protogen:"open.v1"` + Static *Static `protobuf:"bytes,1,opt,name=static" json:"static,omitempty"` + Plans *Plans `protobuf:"bytes,2,opt,name=plans" json:"plans,omitempty"` + Funcs *Funcs `protobuf:"bytes,3,opt,name=funcs" json:"funcs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Policy) Reset() { + *x = Policy{} + mi := &file_v1_ir_plan_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Policy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Policy) ProtoMessage() {} + +func (x *Policy) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Policy.ProtoReflect.Descriptor instead. +func (*Policy) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{0} +} + +func (x *Policy) GetStatic() *Static { + if x != nil { + return x.Static + } + return nil +} + +func (x *Policy) GetPlans() *Plans { + if x != nil { + return x.Plans + } + return nil +} + +func (x *Policy) GetFuncs() *Funcs { + if x != nil { + return x.Funcs + } + return nil +} + +// Static mirrors `ir.Static` in v1/ir/ir.go. +type Static struct { + state protoimpl.MessageState `protogen:"open.v1"` + Strings []*StringConst `protobuf:"bytes,1,rep,name=strings" json:"strings,omitempty"` + BuiltinFuncs []*BuiltinFunc `protobuf:"bytes,2,rep,name=builtin_funcs,json=builtinFuncs" json:"builtin_funcs,omitempty"` + Files []*StringConst `protobuf:"bytes,3,rep,name=files" json:"files,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Static) Reset() { + *x = Static{} + mi := &file_v1_ir_plan_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Static) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Static) ProtoMessage() {} + +func (x *Static) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Static.ProtoReflect.Descriptor instead. +func (*Static) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{1} +} + +func (x *Static) GetStrings() []*StringConst { + if x != nil { + return x.Strings + } + return nil +} + +func (x *Static) GetBuiltinFuncs() []*BuiltinFunc { + if x != nil { + return x.BuiltinFuncs + } + return nil +} + +func (x *Static) GetFiles() []*StringConst { + if x != nil { + return x.Files + } + return nil +} + +// BuiltinFunc mirrors `ir.BuiltinFunc` in v1/ir/ir.go. +// +// `ir.BuiltinFunc.Decl` (the function's `types.Function` signature) is +// intentionally not modeled. Consumers that execute plans need their +// own builtin registry to dispatch host-language implementations, and +// that registry is the source of truth for signatures — bundling +// `Decl` here would be redundant and prone to drift. +type BuiltinFunc struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BuiltinFunc) Reset() { + *x = BuiltinFunc{} + mi := &file_v1_ir_plan_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BuiltinFunc) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BuiltinFunc) ProtoMessage() {} + +func (x *BuiltinFunc) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BuiltinFunc.ProtoReflect.Descriptor instead. +func (*BuiltinFunc) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{2} +} + +func (x *BuiltinFunc) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +// Plans mirrors `ir.Plans` in v1/ir/ir.go. +type Plans struct { + state protoimpl.MessageState `protogen:"open.v1"` + Plans []*Plan `protobuf:"bytes,1,rep,name=plans" json:"plans,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Plans) Reset() { + *x = Plans{} + mi := &file_v1_ir_plan_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Plans) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Plans) ProtoMessage() {} + +func (x *Plans) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Plans.ProtoReflect.Descriptor instead. +func (*Plans) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{3} +} + +func (x *Plans) GetPlans() []*Plan { + if x != nil { + return x.Plans + } + return nil +} + +// Funcs mirrors `ir.Funcs` in v1/ir/ir.go. +type Funcs struct { + state protoimpl.MessageState `protogen:"open.v1"` + Funcs []*Func `protobuf:"bytes,1,rep,name=funcs" json:"funcs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Funcs) Reset() { + *x = Funcs{} + mi := &file_v1_ir_plan_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Funcs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Funcs) ProtoMessage() {} + +func (x *Funcs) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Funcs.ProtoReflect.Descriptor instead. +func (*Funcs) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{4} +} + +func (x *Funcs) GetFuncs() []*Func { + if x != nil { + return x.Funcs + } + return nil +} + +// Func mirrors `ir.Func` in v1/ir/ir.go. +// +// Each parameter and the return slot are local-variable indices; see +// `ir.Local` in v1/ir/ir.go. +type Func struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Params []int32 `protobuf:"varint,2,rep,packed,name=params" json:"params,omitempty"` + // The local that holds the function's return value. Renamed from + // `return` (the Go field is `Func.Return Local`, JSON-tagged `return`) + // to avoid colliding with a reserved keyword in many target languages + // when this proto is fed to protoc plugins. The JSON wire form + // continues to use `return`; only the proto-side identifier differs. + Result *int32 `protobuf:"varint,3,opt,name=result" json:"result,omitempty"` + Blocks []*Block `protobuf:"bytes,4,rep,name=blocks" json:"blocks,omitempty"` + Path []string `protobuf:"bytes,5,rep,name=path" json:"path,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Func) Reset() { + *x = Func{} + mi := &file_v1_ir_plan_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Func) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Func) ProtoMessage() {} + +func (x *Func) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Func.ProtoReflect.Descriptor instead. +func (*Func) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{5} +} + +func (x *Func) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *Func) GetParams() []int32 { + if x != nil { + return x.Params + } + return nil +} + +func (x *Func) GetResult() int32 { + if x != nil && x.Result != nil { + return *x.Result + } + return 0 +} + +func (x *Func) GetBlocks() []*Block { + if x != nil { + return x.Blocks + } + return nil +} + +func (x *Func) GetPath() []string { + if x != nil { + return x.Path + } + return nil +} + +// Plan mirrors `ir.Plan` in v1/ir/ir.go. +type Plan struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Blocks []*Block `protobuf:"bytes,2,rep,name=blocks" json:"blocks,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Plan) Reset() { + *x = Plan{} + mi := &file_v1_ir_plan_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Plan) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Plan) ProtoMessage() {} + +func (x *Plan) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Plan.ProtoReflect.Descriptor instead. +func (*Plan) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{6} +} + +func (x *Plan) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *Plan) GetBlocks() []*Block { + if x != nil { + return x.Blocks + } + return nil +} + +// Block mirrors `ir.Block` in v1/ir/ir.go. +type Block struct { + state protoimpl.MessageState `protogen:"open.v1"` + Stmts []*Stmt `protobuf:"bytes,1,rep,name=stmts" json:"stmts,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Block) Reset() { + *x = Block{} + mi := &file_v1_ir_plan_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Block) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Block) ProtoMessage() {} + +func (x *Block) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Block.ProtoReflect.Descriptor instead. +func (*Block) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{7} +} + +func (x *Block) GetStmts() []*Stmt { + if x != nil { + return x.Stmts + } + return nil +} + +// StringConst mirrors `ir.StringConst` in v1/ir/ir.go. +type StringConst struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value *string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StringConst) Reset() { + *x = StringConst{} + mi := &file_v1_ir_plan_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StringConst) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StringConst) ProtoMessage() {} + +func (x *StringConst) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StringConst.ProtoReflect.Descriptor instead. +func (*StringConst) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{8} +} + +func (x *StringConst) GetValue() string { + if x != nil && x.Value != nil { + return *x.Value + } + return "" +} + +// Operand mirrors `ir.Operand` in v1/ir/ir.go. The `value` field is a +// polymorphic `Val` union; see the `Val` message below. +type Operand struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value *Val `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Operand) Reset() { + *x = Operand{} + mi := &file_v1_ir_plan_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Operand) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Operand) ProtoMessage() {} + +func (x *Operand) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Operand.ProtoReflect.Descriptor instead. +func (*Operand) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{9} +} + +func (x *Operand) GetValue() *Val { + if x != nil { + return x.Value + } + return nil +} + +// Val mirrors the `ir.Val` interface in v1/ir/ir.go. Each oneof case +// corresponds to a concrete `Val` implementation; the case names match +// the JSON discriminator strings emitted by `*Operand.MarshalJSON`. +// +// Case-number assignments are a stability commitment. New cases must +// be added with the next unused number; existing numbers must never +// be repurposed. +type Val struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Kind: + // + // *Val_Bool + // *Val_Local + // *Val_StringIndex + Kind isVal_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Val) Reset() { + *x = Val{} + mi := &file_v1_ir_plan_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Val) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Val) ProtoMessage() {} + +func (x *Val) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Val.ProtoReflect.Descriptor instead. +func (*Val) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{10} +} + +func (x *Val) GetKind() isVal_Kind { + if x != nil { + return x.Kind + } + return nil +} + +func (x *Val) GetBool() bool { + if x != nil { + if x, ok := x.Kind.(*Val_Bool); ok { + return x.Bool + } + } + return false +} + +func (x *Val) GetLocal() int32 { + if x != nil { + if x, ok := x.Kind.(*Val_Local); ok { + return x.Local + } + } + return 0 +} + +func (x *Val) GetStringIndex() int32 { + if x != nil { + if x, ok := x.Kind.(*Val_StringIndex); ok { + return x.StringIndex + } + } + return 0 +} + +type isVal_Kind interface { + isVal_Kind() +} + +type Val_Bool struct { + Bool bool `protobuf:"varint,1,opt,name=bool,oneof"` +} + +type Val_Local struct { + Local int32 `protobuf:"varint,2,opt,name=local,oneof"` +} + +type Val_StringIndex struct { + StringIndex int32 `protobuf:"varint,3,opt,name=string_index,json=stringIndex,oneof"` +} + +func (*Val_Bool) isVal_Kind() {} + +func (*Val_Local) isVal_Kind() {} + +func (*Val_StringIndex) isVal_Kind() {} + +// Stmt mirrors the `ir.Stmt` interface in v1/ir/ir.go. Every Stmt carries +// the source-location triple (file, col, row) on this envelope; the body +// messages below describe only the kind-specific payload. +// +// On the Go side, `ir.Location` is embedded into every concrete Stmt +// implementation, so `encoding/json` flattens File/Col/Row into the +// emitted JSON body. The proto promotes those fields to the envelope +// because that's both more idiomatic protobuf and lets every body +// message start its own field numbering at 1. +// +// Case-number assignments (4–37) are a stability commitment. Field +// numbers 1–3 are reserved for the location triple. New cases must be +// added with the next unused number; existing numbers must never be +// repurposed. +type Stmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + File *int32 `protobuf:"varint,1,opt,name=file" json:"file,omitempty"` + Col *int32 `protobuf:"varint,2,opt,name=col" json:"col,omitempty"` + Row *int32 `protobuf:"varint,3,opt,name=row" json:"row,omitempty"` + // Types that are valid to be assigned to Kind: + // + // *Stmt_ArrayAppendStmt + // *Stmt_AssignIntStmt + // *Stmt_AssignVarOnceStmt + // *Stmt_AssignVarStmt + // *Stmt_BlockStmt + // *Stmt_BreakStmt + // *Stmt_CallDynamicStmt + // *Stmt_CallStmt + // *Stmt_DotStmt + // *Stmt_EqualStmt + // *Stmt_IsArrayStmt + // *Stmt_IsDefinedStmt + // *Stmt_IsObjectStmt + // *Stmt_IsSetStmt + // *Stmt_IsUndefinedStmt + // *Stmt_LenStmt + // *Stmt_MakeArrayStmt + // *Stmt_MakeNullStmt + // *Stmt_MakeNumberIntStmt + // *Stmt_MakeNumberRefStmt + // *Stmt_MakeObjectStmt + // *Stmt_MakeSetStmt + // *Stmt_NopStmt + // *Stmt_NotEqualStmt + // *Stmt_NotStmt + // *Stmt_ObjectInsertOnceStmt + // *Stmt_ObjectInsertStmt + // *Stmt_ObjectMergeStmt + // *Stmt_ResetLocalStmt + // *Stmt_ResultSetAddStmt + // *Stmt_ReturnLocalStmt + // *Stmt_ScanStmt + // *Stmt_SetAddStmt + // *Stmt_WithStmt + Kind isStmt_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Stmt) Reset() { + *x = Stmt{} + mi := &file_v1_ir_plan_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Stmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Stmt) ProtoMessage() {} + +func (x *Stmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Stmt.ProtoReflect.Descriptor instead. +func (*Stmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{11} +} + +func (x *Stmt) GetFile() int32 { + if x != nil && x.File != nil { + return *x.File + } + return 0 +} + +func (x *Stmt) GetCol() int32 { + if x != nil && x.Col != nil { + return *x.Col + } + return 0 +} + +func (x *Stmt) GetRow() int32 { + if x != nil && x.Row != nil { + return *x.Row + } + return 0 +} + +func (x *Stmt) GetKind() isStmt_Kind { + if x != nil { + return x.Kind + } + return nil +} + +func (x *Stmt) GetArrayAppendStmt() *ArrayAppendStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_ArrayAppendStmt); ok { + return x.ArrayAppendStmt + } + } + return nil +} + +func (x *Stmt) GetAssignIntStmt() *AssignIntStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_AssignIntStmt); ok { + return x.AssignIntStmt + } + } + return nil +} + +func (x *Stmt) GetAssignVarOnceStmt() *AssignVarOnceStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_AssignVarOnceStmt); ok { + return x.AssignVarOnceStmt + } + } + return nil +} + +func (x *Stmt) GetAssignVarStmt() *AssignVarStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_AssignVarStmt); ok { + return x.AssignVarStmt + } + } + return nil +} + +func (x *Stmt) GetBlockStmt() *BlockStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_BlockStmt); ok { + return x.BlockStmt + } + } + return nil +} + +func (x *Stmt) GetBreakStmt() *BreakStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_BreakStmt); ok { + return x.BreakStmt + } + } + return nil +} + +func (x *Stmt) GetCallDynamicStmt() *CallDynamicStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_CallDynamicStmt); ok { + return x.CallDynamicStmt + } + } + return nil +} + +func (x *Stmt) GetCallStmt() *CallStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_CallStmt); ok { + return x.CallStmt + } + } + return nil +} + +func (x *Stmt) GetDotStmt() *DotStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_DotStmt); ok { + return x.DotStmt + } + } + return nil +} + +func (x *Stmt) GetEqualStmt() *EqualStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_EqualStmt); ok { + return x.EqualStmt + } + } + return nil +} + +func (x *Stmt) GetIsArrayStmt() *IsArrayStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_IsArrayStmt); ok { + return x.IsArrayStmt + } + } + return nil +} + +func (x *Stmt) GetIsDefinedStmt() *IsDefinedStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_IsDefinedStmt); ok { + return x.IsDefinedStmt + } + } + return nil +} + +func (x *Stmt) GetIsObjectStmt() *IsObjectStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_IsObjectStmt); ok { + return x.IsObjectStmt + } + } + return nil +} + +func (x *Stmt) GetIsSetStmt() *IsSetStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_IsSetStmt); ok { + return x.IsSetStmt + } + } + return nil +} + +func (x *Stmt) GetIsUndefinedStmt() *IsUndefinedStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_IsUndefinedStmt); ok { + return x.IsUndefinedStmt + } + } + return nil +} + +func (x *Stmt) GetLenStmt() *LenStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_LenStmt); ok { + return x.LenStmt + } + } + return nil +} + +func (x *Stmt) GetMakeArrayStmt() *MakeArrayStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_MakeArrayStmt); ok { + return x.MakeArrayStmt + } + } + return nil +} + +func (x *Stmt) GetMakeNullStmt() *MakeNullStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_MakeNullStmt); ok { + return x.MakeNullStmt + } + } + return nil +} + +func (x *Stmt) GetMakeNumberIntStmt() *MakeNumberIntStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_MakeNumberIntStmt); ok { + return x.MakeNumberIntStmt + } + } + return nil +} + +func (x *Stmt) GetMakeNumberRefStmt() *MakeNumberRefStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_MakeNumberRefStmt); ok { + return x.MakeNumberRefStmt + } + } + return nil +} + +func (x *Stmt) GetMakeObjectStmt() *MakeObjectStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_MakeObjectStmt); ok { + return x.MakeObjectStmt + } + } + return nil +} + +func (x *Stmt) GetMakeSetStmt() *MakeSetStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_MakeSetStmt); ok { + return x.MakeSetStmt + } + } + return nil +} + +func (x *Stmt) GetNopStmt() *NopStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_NopStmt); ok { + return x.NopStmt + } + } + return nil +} + +func (x *Stmt) GetNotEqualStmt() *NotEqualStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_NotEqualStmt); ok { + return x.NotEqualStmt + } + } + return nil +} + +func (x *Stmt) GetNotStmt() *NotStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_NotStmt); ok { + return x.NotStmt + } + } + return nil +} + +func (x *Stmt) GetObjectInsertOnceStmt() *ObjectInsertOnceStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_ObjectInsertOnceStmt); ok { + return x.ObjectInsertOnceStmt + } + } + return nil +} + +func (x *Stmt) GetObjectInsertStmt() *ObjectInsertStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_ObjectInsertStmt); ok { + return x.ObjectInsertStmt + } + } + return nil +} + +func (x *Stmt) GetObjectMergeStmt() *ObjectMergeStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_ObjectMergeStmt); ok { + return x.ObjectMergeStmt + } + } + return nil +} + +func (x *Stmt) GetResetLocalStmt() *ResetLocalStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_ResetLocalStmt); ok { + return x.ResetLocalStmt + } + } + return nil +} + +func (x *Stmt) GetResultSetAddStmt() *ResultSetAddStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_ResultSetAddStmt); ok { + return x.ResultSetAddStmt + } + } + return nil +} + +func (x *Stmt) GetReturnLocalStmt() *ReturnLocalStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_ReturnLocalStmt); ok { + return x.ReturnLocalStmt + } + } + return nil +} + +func (x *Stmt) GetScanStmt() *ScanStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_ScanStmt); ok { + return x.ScanStmt + } + } + return nil +} + +func (x *Stmt) GetSetAddStmt() *SetAddStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_SetAddStmt); ok { + return x.SetAddStmt + } + } + return nil +} + +func (x *Stmt) GetWithStmt() *WithStmt { + if x != nil { + if x, ok := x.Kind.(*Stmt_WithStmt); ok { + return x.WithStmt + } + } + return nil +} + +type isStmt_Kind interface { + isStmt_Kind() +} + +type Stmt_ArrayAppendStmt struct { + ArrayAppendStmt *ArrayAppendStmt `protobuf:"bytes,4,opt,name=array_append_stmt,json=arrayAppendStmt,oneof"` +} + +type Stmt_AssignIntStmt struct { + AssignIntStmt *AssignIntStmt `protobuf:"bytes,5,opt,name=assign_int_stmt,json=assignIntStmt,oneof"` +} + +type Stmt_AssignVarOnceStmt struct { + AssignVarOnceStmt *AssignVarOnceStmt `protobuf:"bytes,6,opt,name=assign_var_once_stmt,json=assignVarOnceStmt,oneof"` +} + +type Stmt_AssignVarStmt struct { + AssignVarStmt *AssignVarStmt `protobuf:"bytes,7,opt,name=assign_var_stmt,json=assignVarStmt,oneof"` +} + +type Stmt_BlockStmt struct { + BlockStmt *BlockStmt `protobuf:"bytes,8,opt,name=block_stmt,json=blockStmt,oneof"` +} + +type Stmt_BreakStmt struct { + BreakStmt *BreakStmt `protobuf:"bytes,9,opt,name=break_stmt,json=breakStmt,oneof"` +} + +type Stmt_CallDynamicStmt struct { + CallDynamicStmt *CallDynamicStmt `protobuf:"bytes,10,opt,name=call_dynamic_stmt,json=callDynamicStmt,oneof"` +} + +type Stmt_CallStmt struct { + CallStmt *CallStmt `protobuf:"bytes,11,opt,name=call_stmt,json=callStmt,oneof"` +} + +type Stmt_DotStmt struct { + DotStmt *DotStmt `protobuf:"bytes,12,opt,name=dot_stmt,json=dotStmt,oneof"` +} + +type Stmt_EqualStmt struct { + EqualStmt *EqualStmt `protobuf:"bytes,13,opt,name=equal_stmt,json=equalStmt,oneof"` +} + +type Stmt_IsArrayStmt struct { + IsArrayStmt *IsArrayStmt `protobuf:"bytes,14,opt,name=is_array_stmt,json=isArrayStmt,oneof"` +} + +type Stmt_IsDefinedStmt struct { + IsDefinedStmt *IsDefinedStmt `protobuf:"bytes,15,opt,name=is_defined_stmt,json=isDefinedStmt,oneof"` +} + +type Stmt_IsObjectStmt struct { + IsObjectStmt *IsObjectStmt `protobuf:"bytes,16,opt,name=is_object_stmt,json=isObjectStmt,oneof"` +} + +type Stmt_IsSetStmt struct { + IsSetStmt *IsSetStmt `protobuf:"bytes,17,opt,name=is_set_stmt,json=isSetStmt,oneof"` +} + +type Stmt_IsUndefinedStmt struct { + IsUndefinedStmt *IsUndefinedStmt `protobuf:"bytes,18,opt,name=is_undefined_stmt,json=isUndefinedStmt,oneof"` +} + +type Stmt_LenStmt struct { + LenStmt *LenStmt `protobuf:"bytes,19,opt,name=len_stmt,json=lenStmt,oneof"` +} + +type Stmt_MakeArrayStmt struct { + MakeArrayStmt *MakeArrayStmt `protobuf:"bytes,20,opt,name=make_array_stmt,json=makeArrayStmt,oneof"` +} + +type Stmt_MakeNullStmt struct { + MakeNullStmt *MakeNullStmt `protobuf:"bytes,21,opt,name=make_null_stmt,json=makeNullStmt,oneof"` +} + +type Stmt_MakeNumberIntStmt struct { + MakeNumberIntStmt *MakeNumberIntStmt `protobuf:"bytes,22,opt,name=make_number_int_stmt,json=makeNumberIntStmt,oneof"` +} + +type Stmt_MakeNumberRefStmt struct { + MakeNumberRefStmt *MakeNumberRefStmt `protobuf:"bytes,23,opt,name=make_number_ref_stmt,json=makeNumberRefStmt,oneof"` +} + +type Stmt_MakeObjectStmt struct { + MakeObjectStmt *MakeObjectStmt `protobuf:"bytes,24,opt,name=make_object_stmt,json=makeObjectStmt,oneof"` +} + +type Stmt_MakeSetStmt struct { + MakeSetStmt *MakeSetStmt `protobuf:"bytes,25,opt,name=make_set_stmt,json=makeSetStmt,oneof"` +} + +type Stmt_NopStmt struct { + NopStmt *NopStmt `protobuf:"bytes,26,opt,name=nop_stmt,json=nopStmt,oneof"` +} + +type Stmt_NotEqualStmt struct { + NotEqualStmt *NotEqualStmt `protobuf:"bytes,27,opt,name=not_equal_stmt,json=notEqualStmt,oneof"` +} + +type Stmt_NotStmt struct { + NotStmt *NotStmt `protobuf:"bytes,28,opt,name=not_stmt,json=notStmt,oneof"` +} + +type Stmt_ObjectInsertOnceStmt struct { + ObjectInsertOnceStmt *ObjectInsertOnceStmt `protobuf:"bytes,29,opt,name=object_insert_once_stmt,json=objectInsertOnceStmt,oneof"` +} + +type Stmt_ObjectInsertStmt struct { + ObjectInsertStmt *ObjectInsertStmt `protobuf:"bytes,30,opt,name=object_insert_stmt,json=objectInsertStmt,oneof"` +} + +type Stmt_ObjectMergeStmt struct { + ObjectMergeStmt *ObjectMergeStmt `protobuf:"bytes,31,opt,name=object_merge_stmt,json=objectMergeStmt,oneof"` +} + +type Stmt_ResetLocalStmt struct { + ResetLocalStmt *ResetLocalStmt `protobuf:"bytes,32,opt,name=reset_local_stmt,json=resetLocalStmt,oneof"` +} + +type Stmt_ResultSetAddStmt struct { + ResultSetAddStmt *ResultSetAddStmt `protobuf:"bytes,33,opt,name=result_set_add_stmt,json=resultSetAddStmt,oneof"` +} + +type Stmt_ReturnLocalStmt struct { + ReturnLocalStmt *ReturnLocalStmt `protobuf:"bytes,34,opt,name=return_local_stmt,json=returnLocalStmt,oneof"` +} + +type Stmt_ScanStmt struct { + ScanStmt *ScanStmt `protobuf:"bytes,35,opt,name=scan_stmt,json=scanStmt,oneof"` +} + +type Stmt_SetAddStmt struct { + SetAddStmt *SetAddStmt `protobuf:"bytes,36,opt,name=set_add_stmt,json=setAddStmt,oneof"` +} + +type Stmt_WithStmt struct { + WithStmt *WithStmt `protobuf:"bytes,37,opt,name=with_stmt,json=withStmt,oneof"` +} + +func (*Stmt_ArrayAppendStmt) isStmt_Kind() {} + +func (*Stmt_AssignIntStmt) isStmt_Kind() {} + +func (*Stmt_AssignVarOnceStmt) isStmt_Kind() {} + +func (*Stmt_AssignVarStmt) isStmt_Kind() {} + +func (*Stmt_BlockStmt) isStmt_Kind() {} + +func (*Stmt_BreakStmt) isStmt_Kind() {} + +func (*Stmt_CallDynamicStmt) isStmt_Kind() {} + +func (*Stmt_CallStmt) isStmt_Kind() {} + +func (*Stmt_DotStmt) isStmt_Kind() {} + +func (*Stmt_EqualStmt) isStmt_Kind() {} + +func (*Stmt_IsArrayStmt) isStmt_Kind() {} + +func (*Stmt_IsDefinedStmt) isStmt_Kind() {} + +func (*Stmt_IsObjectStmt) isStmt_Kind() {} + +func (*Stmt_IsSetStmt) isStmt_Kind() {} + +func (*Stmt_IsUndefinedStmt) isStmt_Kind() {} + +func (*Stmt_LenStmt) isStmt_Kind() {} + +func (*Stmt_MakeArrayStmt) isStmt_Kind() {} + +func (*Stmt_MakeNullStmt) isStmt_Kind() {} + +func (*Stmt_MakeNumberIntStmt) isStmt_Kind() {} + +func (*Stmt_MakeNumberRefStmt) isStmt_Kind() {} + +func (*Stmt_MakeObjectStmt) isStmt_Kind() {} + +func (*Stmt_MakeSetStmt) isStmt_Kind() {} + +func (*Stmt_NopStmt) isStmt_Kind() {} + +func (*Stmt_NotEqualStmt) isStmt_Kind() {} + +func (*Stmt_NotStmt) isStmt_Kind() {} + +func (*Stmt_ObjectInsertOnceStmt) isStmt_Kind() {} + +func (*Stmt_ObjectInsertStmt) isStmt_Kind() {} + +func (*Stmt_ObjectMergeStmt) isStmt_Kind() {} + +func (*Stmt_ResetLocalStmt) isStmt_Kind() {} + +func (*Stmt_ResultSetAddStmt) isStmt_Kind() {} + +func (*Stmt_ReturnLocalStmt) isStmt_Kind() {} + +func (*Stmt_ScanStmt) isStmt_Kind() {} + +func (*Stmt_SetAddStmt) isStmt_Kind() {} + +func (*Stmt_WithStmt) isStmt_Kind() {} + +// ArrayAppendStmt mirrors `ir.ArrayAppendStmt` in v1/ir/ir.go. +type ArrayAppendStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value *Operand `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` + Array *int32 `protobuf:"varint,2,opt,name=array" json:"array,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ArrayAppendStmt) Reset() { + *x = ArrayAppendStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ArrayAppendStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArrayAppendStmt) ProtoMessage() {} + +func (x *ArrayAppendStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArrayAppendStmt.ProtoReflect.Descriptor instead. +func (*ArrayAppendStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{12} +} + +func (x *ArrayAppendStmt) GetValue() *Operand { + if x != nil { + return x.Value + } + return nil +} + +func (x *ArrayAppendStmt) GetArray() int32 { + if x != nil && x.Array != nil { + return *x.Array + } + return 0 +} + +// AssignIntStmt mirrors `ir.AssignIntStmt` in v1/ir/ir.go. +type AssignIntStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value *int64 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"` + Target *int32 `protobuf:"varint,2,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AssignIntStmt) Reset() { + *x = AssignIntStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AssignIntStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssignIntStmt) ProtoMessage() {} + +func (x *AssignIntStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssignIntStmt.ProtoReflect.Descriptor instead. +func (*AssignIntStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{13} +} + +func (x *AssignIntStmt) GetValue() int64 { + if x != nil && x.Value != nil { + return *x.Value + } + return 0 +} + +func (x *AssignIntStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// AssignVarOnceStmt mirrors `ir.AssignVarOnceStmt` in v1/ir/ir.go. +type AssignVarOnceStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *Operand `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"` + Target *int32 `protobuf:"varint,2,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AssignVarOnceStmt) Reset() { + *x = AssignVarOnceStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AssignVarOnceStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssignVarOnceStmt) ProtoMessage() {} + +func (x *AssignVarOnceStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssignVarOnceStmt.ProtoReflect.Descriptor instead. +func (*AssignVarOnceStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{14} +} + +func (x *AssignVarOnceStmt) GetSource() *Operand { + if x != nil { + return x.Source + } + return nil +} + +func (x *AssignVarOnceStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// AssignVarStmt mirrors `ir.AssignVarStmt` in v1/ir/ir.go. +type AssignVarStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *Operand `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"` + Target *int32 `protobuf:"varint,2,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AssignVarStmt) Reset() { + *x = AssignVarStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AssignVarStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssignVarStmt) ProtoMessage() {} + +func (x *AssignVarStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssignVarStmt.ProtoReflect.Descriptor instead. +func (*AssignVarStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{15} +} + +func (x *AssignVarStmt) GetSource() *Operand { + if x != nil { + return x.Source + } + return nil +} + +func (x *AssignVarStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// BlockStmt mirrors `ir.BlockStmt` in v1/ir/ir.go. +type BlockStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Blocks []*Block `protobuf:"bytes,1,rep,name=blocks" json:"blocks,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BlockStmt) Reset() { + *x = BlockStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BlockStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlockStmt) ProtoMessage() {} + +func (x *BlockStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlockStmt.ProtoReflect.Descriptor instead. +func (*BlockStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{16} +} + +func (x *BlockStmt) GetBlocks() []*Block { + if x != nil { + return x.Blocks + } + return nil +} + +// BreakStmt mirrors `ir.BreakStmt` in v1/ir/ir.go. +type BreakStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Index *uint32 `protobuf:"varint,1,opt,name=index" json:"index,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BreakStmt) Reset() { + *x = BreakStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BreakStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BreakStmt) ProtoMessage() {} + +func (x *BreakStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BreakStmt.ProtoReflect.Descriptor instead. +func (*BreakStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{17} +} + +func (x *BreakStmt) GetIndex() uint32 { + if x != nil && x.Index != nil { + return *x.Index + } + return 0 +} + +// CallDynamicStmt mirrors `ir.CallDynamicStmt` in v1/ir/ir.go. +type CallDynamicStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Args []int32 `protobuf:"varint,1,rep,packed,name=args" json:"args,omitempty"` + Result *int32 `protobuf:"varint,2,opt,name=result" json:"result,omitempty"` + Path []*Operand `protobuf:"bytes,3,rep,name=path" json:"path,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CallDynamicStmt) Reset() { + *x = CallDynamicStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CallDynamicStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallDynamicStmt) ProtoMessage() {} + +func (x *CallDynamicStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallDynamicStmt.ProtoReflect.Descriptor instead. +func (*CallDynamicStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{18} +} + +func (x *CallDynamicStmt) GetArgs() []int32 { + if x != nil { + return x.Args + } + return nil +} + +func (x *CallDynamicStmt) GetResult() int32 { + if x != nil && x.Result != nil { + return *x.Result + } + return 0 +} + +func (x *CallDynamicStmt) GetPath() []*Operand { + if x != nil { + return x.Path + } + return nil +} + +// CallStmt mirrors `ir.CallStmt` in v1/ir/ir.go. +type CallStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Renamed from `func` (Go field `CallStmt.Func`, JSON-tagged `func`) + // to avoid colliding with reserved keywords in target languages, + // mirroring the Func.return → result rename above. + Function *string `protobuf:"bytes,1,opt,name=function" json:"function,omitempty"` + Args []*Operand `protobuf:"bytes,2,rep,name=args" json:"args,omitempty"` + Result *int32 `protobuf:"varint,3,opt,name=result" json:"result,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CallStmt) Reset() { + *x = CallStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CallStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallStmt) ProtoMessage() {} + +func (x *CallStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallStmt.ProtoReflect.Descriptor instead. +func (*CallStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{19} +} + +func (x *CallStmt) GetFunction() string { + if x != nil && x.Function != nil { + return *x.Function + } + return "" +} + +func (x *CallStmt) GetArgs() []*Operand { + if x != nil { + return x.Args + } + return nil +} + +func (x *CallStmt) GetResult() int32 { + if x != nil && x.Result != nil { + return *x.Result + } + return 0 +} + +// DotStmt mirrors `ir.DotStmt` in v1/ir/ir.go. +type DotStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *Operand `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"` + Key *Operand `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"` + Target *int32 `protobuf:"varint,3,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DotStmt) Reset() { + *x = DotStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DotStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DotStmt) ProtoMessage() {} + +func (x *DotStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DotStmt.ProtoReflect.Descriptor instead. +func (*DotStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{20} +} + +func (x *DotStmt) GetSource() *Operand { + if x != nil { + return x.Source + } + return nil +} + +func (x *DotStmt) GetKey() *Operand { + if x != nil { + return x.Key + } + return nil +} + +func (x *DotStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// EqualStmt mirrors `ir.EqualStmt` in v1/ir/ir.go. +type EqualStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + A *Operand `protobuf:"bytes,1,opt,name=a" json:"a,omitempty"` + B *Operand `protobuf:"bytes,2,opt,name=b" json:"b,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EqualStmt) Reset() { + *x = EqualStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EqualStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EqualStmt) ProtoMessage() {} + +func (x *EqualStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EqualStmt.ProtoReflect.Descriptor instead. +func (*EqualStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{21} +} + +func (x *EqualStmt) GetA() *Operand { + if x != nil { + return x.A + } + return nil +} + +func (x *EqualStmt) GetB() *Operand { + if x != nil { + return x.B + } + return nil +} + +// IsArrayStmt mirrors `ir.IsArrayStmt` in v1/ir/ir.go. +type IsArrayStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *Operand `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IsArrayStmt) Reset() { + *x = IsArrayStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IsArrayStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IsArrayStmt) ProtoMessage() {} + +func (x *IsArrayStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IsArrayStmt.ProtoReflect.Descriptor instead. +func (*IsArrayStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{22} +} + +func (x *IsArrayStmt) GetSource() *Operand { + if x != nil { + return x.Source + } + return nil +} + +// IsDefinedStmt mirrors `ir.IsDefinedStmt` in v1/ir/ir.go. +type IsDefinedStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *int32 `protobuf:"varint,1,opt,name=source" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IsDefinedStmt) Reset() { + *x = IsDefinedStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IsDefinedStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IsDefinedStmt) ProtoMessage() {} + +func (x *IsDefinedStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IsDefinedStmt.ProtoReflect.Descriptor instead. +func (*IsDefinedStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{23} +} + +func (x *IsDefinedStmt) GetSource() int32 { + if x != nil && x.Source != nil { + return *x.Source + } + return 0 +} + +// IsObjectStmt mirrors `ir.IsObjectStmt` in v1/ir/ir.go. +type IsObjectStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *Operand `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IsObjectStmt) Reset() { + *x = IsObjectStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IsObjectStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IsObjectStmt) ProtoMessage() {} + +func (x *IsObjectStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IsObjectStmt.ProtoReflect.Descriptor instead. +func (*IsObjectStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{24} +} + +func (x *IsObjectStmt) GetSource() *Operand { + if x != nil { + return x.Source + } + return nil +} + +// IsSetStmt mirrors `ir.IsSetStmt` in v1/ir/ir.go. +type IsSetStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *Operand `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IsSetStmt) Reset() { + *x = IsSetStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IsSetStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IsSetStmt) ProtoMessage() {} + +func (x *IsSetStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IsSetStmt.ProtoReflect.Descriptor instead. +func (*IsSetStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{25} +} + +func (x *IsSetStmt) GetSource() *Operand { + if x != nil { + return x.Source + } + return nil +} + +// IsUndefinedStmt mirrors `ir.IsUndefinedStmt` in v1/ir/ir.go. +type IsUndefinedStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *int32 `protobuf:"varint,1,opt,name=source" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IsUndefinedStmt) Reset() { + *x = IsUndefinedStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IsUndefinedStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IsUndefinedStmt) ProtoMessage() {} + +func (x *IsUndefinedStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IsUndefinedStmt.ProtoReflect.Descriptor instead. +func (*IsUndefinedStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{26} +} + +func (x *IsUndefinedStmt) GetSource() int32 { + if x != nil && x.Source != nil { + return *x.Source + } + return 0 +} + +// LenStmt mirrors `ir.LenStmt` in v1/ir/ir.go. +type LenStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *Operand `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"` + Target *int32 `protobuf:"varint,2,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LenStmt) Reset() { + *x = LenStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LenStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LenStmt) ProtoMessage() {} + +func (x *LenStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LenStmt.ProtoReflect.Descriptor instead. +func (*LenStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{27} +} + +func (x *LenStmt) GetSource() *Operand { + if x != nil { + return x.Source + } + return nil +} + +func (x *LenStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// MakeArrayStmt mirrors `ir.MakeArrayStmt` in v1/ir/ir.go. +type MakeArrayStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Capacity *int32 `protobuf:"varint,1,opt,name=capacity" json:"capacity,omitempty"` + Target *int32 `protobuf:"varint,2,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MakeArrayStmt) Reset() { + *x = MakeArrayStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MakeArrayStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MakeArrayStmt) ProtoMessage() {} + +func (x *MakeArrayStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MakeArrayStmt.ProtoReflect.Descriptor instead. +func (*MakeArrayStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{28} +} + +func (x *MakeArrayStmt) GetCapacity() int32 { + if x != nil && x.Capacity != nil { + return *x.Capacity + } + return 0 +} + +func (x *MakeArrayStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// MakeNullStmt mirrors `ir.MakeNullStmt` in v1/ir/ir.go. +type MakeNullStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Target *int32 `protobuf:"varint,1,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MakeNullStmt) Reset() { + *x = MakeNullStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MakeNullStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MakeNullStmt) ProtoMessage() {} + +func (x *MakeNullStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[29] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MakeNullStmt.ProtoReflect.Descriptor instead. +func (*MakeNullStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{29} +} + +func (x *MakeNullStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// MakeNumberIntStmt mirrors `ir.MakeNumberIntStmt` in v1/ir/ir.go. +type MakeNumberIntStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value *int64 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"` + Target *int32 `protobuf:"varint,2,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MakeNumberIntStmt) Reset() { + *x = MakeNumberIntStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MakeNumberIntStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MakeNumberIntStmt) ProtoMessage() {} + +func (x *MakeNumberIntStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MakeNumberIntStmt.ProtoReflect.Descriptor instead. +func (*MakeNumberIntStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{30} +} + +func (x *MakeNumberIntStmt) GetValue() int64 { + if x != nil && x.Value != nil { + return *x.Value + } + return 0 +} + +func (x *MakeNumberIntStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// MakeNumberRefStmt mirrors `ir.MakeNumberRefStmt` in v1/ir/ir.go. +// +// The Go field is named `Index` (no `json` tag). The historical JSON +// shape emitted both `index` and `Index`; the canonical key going +// forward is `index` and the deprecated `Index` alias will be removed +// in a future major release. This proto models only the canonical +// `index` field. +type MakeNumberRefStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Index *int32 `protobuf:"varint,1,opt,name=index" json:"index,omitempty"` + Target *int32 `protobuf:"varint,2,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MakeNumberRefStmt) Reset() { + *x = MakeNumberRefStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MakeNumberRefStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MakeNumberRefStmt) ProtoMessage() {} + +func (x *MakeNumberRefStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[31] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MakeNumberRefStmt.ProtoReflect.Descriptor instead. +func (*MakeNumberRefStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{31} +} + +func (x *MakeNumberRefStmt) GetIndex() int32 { + if x != nil && x.Index != nil { + return *x.Index + } + return 0 +} + +func (x *MakeNumberRefStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// MakeObjectStmt mirrors `ir.MakeObjectStmt` in v1/ir/ir.go. +type MakeObjectStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Target *int32 `protobuf:"varint,1,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MakeObjectStmt) Reset() { + *x = MakeObjectStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MakeObjectStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MakeObjectStmt) ProtoMessage() {} + +func (x *MakeObjectStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[32] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MakeObjectStmt.ProtoReflect.Descriptor instead. +func (*MakeObjectStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{32} +} + +func (x *MakeObjectStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// MakeSetStmt mirrors `ir.MakeSetStmt` in v1/ir/ir.go. +type MakeSetStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Target *int32 `protobuf:"varint,1,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MakeSetStmt) Reset() { + *x = MakeSetStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MakeSetStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MakeSetStmt) ProtoMessage() {} + +func (x *MakeSetStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MakeSetStmt.ProtoReflect.Descriptor instead. +func (*MakeSetStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{33} +} + +func (x *MakeSetStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// NopStmt mirrors `ir.NopStmt` in v1/ir/ir.go. +type NopStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NopStmt) Reset() { + *x = NopStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NopStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NopStmt) ProtoMessage() {} + +func (x *NopStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[34] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NopStmt.ProtoReflect.Descriptor instead. +func (*NopStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{34} +} + +// NotEqualStmt mirrors `ir.NotEqualStmt` in v1/ir/ir.go. +type NotEqualStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + A *Operand `protobuf:"bytes,1,opt,name=a" json:"a,omitempty"` + B *Operand `protobuf:"bytes,2,opt,name=b" json:"b,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NotEqualStmt) Reset() { + *x = NotEqualStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NotEqualStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotEqualStmt) ProtoMessage() {} + +func (x *NotEqualStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[35] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotEqualStmt.ProtoReflect.Descriptor instead. +func (*NotEqualStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{35} +} + +func (x *NotEqualStmt) GetA() *Operand { + if x != nil { + return x.A + } + return nil +} + +func (x *NotEqualStmt) GetB() *Operand { + if x != nil { + return x.B + } + return nil +} + +// NotStmt mirrors `ir.NotStmt` in v1/ir/ir.go. +type NotStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Block *Block `protobuf:"bytes,1,opt,name=block" json:"block,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NotStmt) Reset() { + *x = NotStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NotStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotStmt) ProtoMessage() {} + +func (x *NotStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[36] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotStmt.ProtoReflect.Descriptor instead. +func (*NotStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{36} +} + +func (x *NotStmt) GetBlock() *Block { + if x != nil { + return x.Block + } + return nil +} + +// ObjectInsertOnceStmt mirrors `ir.ObjectInsertOnceStmt` in v1/ir/ir.go. +type ObjectInsertOnceStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key *Operand `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` + Value *Operand `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + Object *int32 `protobuf:"varint,3,opt,name=object" json:"object,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ObjectInsertOnceStmt) Reset() { + *x = ObjectInsertOnceStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ObjectInsertOnceStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ObjectInsertOnceStmt) ProtoMessage() {} + +func (x *ObjectInsertOnceStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[37] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ObjectInsertOnceStmt.ProtoReflect.Descriptor instead. +func (*ObjectInsertOnceStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{37} +} + +func (x *ObjectInsertOnceStmt) GetKey() *Operand { + if x != nil { + return x.Key + } + return nil +} + +func (x *ObjectInsertOnceStmt) GetValue() *Operand { + if x != nil { + return x.Value + } + return nil +} + +func (x *ObjectInsertOnceStmt) GetObject() int32 { + if x != nil && x.Object != nil { + return *x.Object + } + return 0 +} + +// ObjectInsertStmt mirrors `ir.ObjectInsertStmt` in v1/ir/ir.go. +type ObjectInsertStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key *Operand `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` + Value *Operand `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + Object *int32 `protobuf:"varint,3,opt,name=object" json:"object,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ObjectInsertStmt) Reset() { + *x = ObjectInsertStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ObjectInsertStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ObjectInsertStmt) ProtoMessage() {} + +func (x *ObjectInsertStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ObjectInsertStmt.ProtoReflect.Descriptor instead. +func (*ObjectInsertStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{38} +} + +func (x *ObjectInsertStmt) GetKey() *Operand { + if x != nil { + return x.Key + } + return nil +} + +func (x *ObjectInsertStmt) GetValue() *Operand { + if x != nil { + return x.Value + } + return nil +} + +func (x *ObjectInsertStmt) GetObject() int32 { + if x != nil && x.Object != nil { + return *x.Object + } + return 0 +} + +// ObjectMergeStmt mirrors `ir.ObjectMergeStmt` in v1/ir/ir.go. +type ObjectMergeStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + A *int32 `protobuf:"varint,1,opt,name=a" json:"a,omitempty"` + B *int32 `protobuf:"varint,2,opt,name=b" json:"b,omitempty"` + Target *int32 `protobuf:"varint,3,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ObjectMergeStmt) Reset() { + *x = ObjectMergeStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ObjectMergeStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ObjectMergeStmt) ProtoMessage() {} + +func (x *ObjectMergeStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ObjectMergeStmt.ProtoReflect.Descriptor instead. +func (*ObjectMergeStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{39} +} + +func (x *ObjectMergeStmt) GetA() int32 { + if x != nil && x.A != nil { + return *x.A + } + return 0 +} + +func (x *ObjectMergeStmt) GetB() int32 { + if x != nil && x.B != nil { + return *x.B + } + return 0 +} + +func (x *ObjectMergeStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// ResetLocalStmt mirrors `ir.ResetLocalStmt` in v1/ir/ir.go. +type ResetLocalStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Target *int32 `protobuf:"varint,1,opt,name=target" json:"target,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResetLocalStmt) Reset() { + *x = ResetLocalStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResetLocalStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetLocalStmt) ProtoMessage() {} + +func (x *ResetLocalStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[40] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetLocalStmt.ProtoReflect.Descriptor instead. +func (*ResetLocalStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{40} +} + +func (x *ResetLocalStmt) GetTarget() int32 { + if x != nil && x.Target != nil { + return *x.Target + } + return 0 +} + +// ResultSetAddStmt mirrors `ir.ResultSetAddStmt` in v1/ir/ir.go. +type ResultSetAddStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value *int32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResultSetAddStmt) Reset() { + *x = ResultSetAddStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResultSetAddStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResultSetAddStmt) ProtoMessage() {} + +func (x *ResultSetAddStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[41] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResultSetAddStmt.ProtoReflect.Descriptor instead. +func (*ResultSetAddStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{41} +} + +func (x *ResultSetAddStmt) GetValue() int32 { + if x != nil && x.Value != nil { + return *x.Value + } + return 0 +} + +// ReturnLocalStmt mirrors `ir.ReturnLocalStmt` in v1/ir/ir.go. +type ReturnLocalStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *int32 `protobuf:"varint,1,opt,name=source" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ReturnLocalStmt) Reset() { + *x = ReturnLocalStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ReturnLocalStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReturnLocalStmt) ProtoMessage() {} + +func (x *ReturnLocalStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[42] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReturnLocalStmt.ProtoReflect.Descriptor instead. +func (*ReturnLocalStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{42} +} + +func (x *ReturnLocalStmt) GetSource() int32 { + if x != nil && x.Source != nil { + return *x.Source + } + return 0 +} + +// ScanStmt mirrors `ir.ScanStmt` in v1/ir/ir.go. +type ScanStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *int32 `protobuf:"varint,1,opt,name=source" json:"source,omitempty"` + Key *int32 `protobuf:"varint,2,opt,name=key" json:"key,omitempty"` + Value *int32 `protobuf:"varint,3,opt,name=value" json:"value,omitempty"` + Block *Block `protobuf:"bytes,4,opt,name=block" json:"block,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ScanStmt) Reset() { + *x = ScanStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ScanStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ScanStmt) ProtoMessage() {} + +func (x *ScanStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[43] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ScanStmt.ProtoReflect.Descriptor instead. +func (*ScanStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{43} +} + +func (x *ScanStmt) GetSource() int32 { + if x != nil && x.Source != nil { + return *x.Source + } + return 0 +} + +func (x *ScanStmt) GetKey() int32 { + if x != nil && x.Key != nil { + return *x.Key + } + return 0 +} + +func (x *ScanStmt) GetValue() int32 { + if x != nil && x.Value != nil { + return *x.Value + } + return 0 +} + +func (x *ScanStmt) GetBlock() *Block { + if x != nil { + return x.Block + } + return nil +} + +// SetAddStmt mirrors `ir.SetAddStmt` in v1/ir/ir.go. +type SetAddStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value *Operand `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` + Set *int32 `protobuf:"varint,2,opt,name=set" json:"set,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SetAddStmt) Reset() { + *x = SetAddStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SetAddStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetAddStmt) ProtoMessage() {} + +func (x *SetAddStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[44] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetAddStmt.ProtoReflect.Descriptor instead. +func (*SetAddStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{44} +} + +func (x *SetAddStmt) GetValue() *Operand { + if x != nil { + return x.Value + } + return nil +} + +func (x *SetAddStmt) GetSet() int32 { + if x != nil && x.Set != nil { + return *x.Set + } + return 0 +} + +// WithStmt mirrors `ir.WithStmt` in v1/ir/ir.go. +type WithStmt struct { + state protoimpl.MessageState `protogen:"open.v1"` + Local *int32 `protobuf:"varint,1,opt,name=local" json:"local,omitempty"` + Path []int32 `protobuf:"varint,2,rep,packed,name=path" json:"path,omitempty"` + Value *Operand `protobuf:"bytes,3,opt,name=value" json:"value,omitempty"` + Block *Block `protobuf:"bytes,4,opt,name=block" json:"block,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WithStmt) Reset() { + *x = WithStmt{} + mi := &file_v1_ir_plan_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WithStmt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WithStmt) ProtoMessage() {} + +func (x *WithStmt) ProtoReflect() protoreflect.Message { + mi := &file_v1_ir_plan_proto_msgTypes[45] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WithStmt.ProtoReflect.Descriptor instead. +func (*WithStmt) Descriptor() ([]byte, []int) { + return file_v1_ir_plan_proto_rawDescGZIP(), []int{45} +} + +func (x *WithStmt) GetLocal() int32 { + if x != nil && x.Local != nil { + return *x.Local + } + return 0 +} + +func (x *WithStmt) GetPath() []int32 { + if x != nil { + return x.Path + } + return nil +} + +func (x *WithStmt) GetValue() *Operand { + if x != nil { + return x.Value + } + return nil +} + +func (x *WithStmt) GetBlock() *Block { + if x != nil { + return x.Block + } + return nil +} + +var File_v1_ir_plan_proto protoreflect.FileDescriptor + +const file_v1_ir_plan_proto_rawDesc = "" + + "\n" + + "\x10v1/ir/plan.proto\x12\topa.ir.v1\"\x83\x01\n" + + "\x06Policy\x12)\n" + + "\x06static\x18\x01 \x01(\v2\x11.opa.ir.v1.StaticR\x06static\x12&\n" + + "\x05plans\x18\x02 \x01(\v2\x10.opa.ir.v1.PlansR\x05plans\x12&\n" + + "\x05funcs\x18\x03 \x01(\v2\x10.opa.ir.v1.FuncsR\x05funcs\"\xa5\x01\n" + + "\x06Static\x120\n" + + "\astrings\x18\x01 \x03(\v2\x16.opa.ir.v1.StringConstR\astrings\x12;\n" + + "\rbuiltin_funcs\x18\x02 \x03(\v2\x16.opa.ir.v1.BuiltinFuncR\fbuiltinFuncs\x12,\n" + + "\x05files\x18\x03 \x03(\v2\x16.opa.ir.v1.StringConstR\x05files\"!\n" + + "\vBuiltinFunc\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\".\n" + + "\x05Plans\x12%\n" + + "\x05plans\x18\x01 \x03(\v2\x0f.opa.ir.v1.PlanR\x05plans\".\n" + + "\x05Funcs\x12%\n" + + "\x05funcs\x18\x01 \x03(\v2\x0f.opa.ir.v1.FuncR\x05funcs\"\x88\x01\n" + + "\x04Func\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n" + + "\x06params\x18\x02 \x03(\x05R\x06params\x12\x16\n" + + "\x06result\x18\x03 \x01(\x05R\x06result\x12(\n" + + "\x06blocks\x18\x04 \x03(\v2\x10.opa.ir.v1.BlockR\x06blocks\x12\x12\n" + + "\x04path\x18\x05 \x03(\tR\x04path\"D\n" + + "\x04Plan\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12(\n" + + "\x06blocks\x18\x02 \x03(\v2\x10.opa.ir.v1.BlockR\x06blocks\".\n" + + "\x05Block\x12%\n" + + "\x05stmts\x18\x01 \x03(\v2\x0f.opa.ir.v1.StmtR\x05stmts\"#\n" + + "\vStringConst\x12\x14\n" + + "\x05value\x18\x01 \x01(\tR\x05value\"/\n" + + "\aOperand\x12$\n" + + "\x05value\x18\x01 \x01(\v2\x0e.opa.ir.v1.ValR\x05value\"`\n" + + "\x03Val\x12\x14\n" + + "\x04bool\x18\x01 \x01(\bH\x00R\x04bool\x12\x16\n" + + "\x05local\x18\x02 \x01(\x05H\x00R\x05local\x12#\n" + + "\fstring_index\x18\x03 \x01(\x05H\x00R\vstringIndexB\x06\n" + + "\x04kind\"\xf5\x11\n" + + "\x04Stmt\x12\x12\n" + + "\x04file\x18\x01 \x01(\x05R\x04file\x12\x10\n" + + "\x03col\x18\x02 \x01(\x05R\x03col\x12\x10\n" + + "\x03row\x18\x03 \x01(\x05R\x03row\x12H\n" + + "\x11array_append_stmt\x18\x04 \x01(\v2\x1a.opa.ir.v1.ArrayAppendStmtH\x00R\x0farrayAppendStmt\x12B\n" + + "\x0fassign_int_stmt\x18\x05 \x01(\v2\x18.opa.ir.v1.AssignIntStmtH\x00R\rassignIntStmt\x12O\n" + + "\x14assign_var_once_stmt\x18\x06 \x01(\v2\x1c.opa.ir.v1.AssignVarOnceStmtH\x00R\x11assignVarOnceStmt\x12B\n" + + "\x0fassign_var_stmt\x18\a \x01(\v2\x18.opa.ir.v1.AssignVarStmtH\x00R\rassignVarStmt\x125\n" + + "\n" + + "block_stmt\x18\b \x01(\v2\x14.opa.ir.v1.BlockStmtH\x00R\tblockStmt\x125\n" + + "\n" + + "break_stmt\x18\t \x01(\v2\x14.opa.ir.v1.BreakStmtH\x00R\tbreakStmt\x12H\n" + + "\x11call_dynamic_stmt\x18\n" + + " \x01(\v2\x1a.opa.ir.v1.CallDynamicStmtH\x00R\x0fcallDynamicStmt\x122\n" + + "\tcall_stmt\x18\v \x01(\v2\x13.opa.ir.v1.CallStmtH\x00R\bcallStmt\x12/\n" + + "\bdot_stmt\x18\f \x01(\v2\x12.opa.ir.v1.DotStmtH\x00R\adotStmt\x125\n" + + "\n" + + "equal_stmt\x18\r \x01(\v2\x14.opa.ir.v1.EqualStmtH\x00R\tequalStmt\x12<\n" + + "\ris_array_stmt\x18\x0e \x01(\v2\x16.opa.ir.v1.IsArrayStmtH\x00R\visArrayStmt\x12B\n" + + "\x0fis_defined_stmt\x18\x0f \x01(\v2\x18.opa.ir.v1.IsDefinedStmtH\x00R\risDefinedStmt\x12?\n" + + "\x0eis_object_stmt\x18\x10 \x01(\v2\x17.opa.ir.v1.IsObjectStmtH\x00R\fisObjectStmt\x126\n" + + "\vis_set_stmt\x18\x11 \x01(\v2\x14.opa.ir.v1.IsSetStmtH\x00R\tisSetStmt\x12H\n" + + "\x11is_undefined_stmt\x18\x12 \x01(\v2\x1a.opa.ir.v1.IsUndefinedStmtH\x00R\x0fisUndefinedStmt\x12/\n" + + "\blen_stmt\x18\x13 \x01(\v2\x12.opa.ir.v1.LenStmtH\x00R\alenStmt\x12B\n" + + "\x0fmake_array_stmt\x18\x14 \x01(\v2\x18.opa.ir.v1.MakeArrayStmtH\x00R\rmakeArrayStmt\x12?\n" + + "\x0emake_null_stmt\x18\x15 \x01(\v2\x17.opa.ir.v1.MakeNullStmtH\x00R\fmakeNullStmt\x12O\n" + + "\x14make_number_int_stmt\x18\x16 \x01(\v2\x1c.opa.ir.v1.MakeNumberIntStmtH\x00R\x11makeNumberIntStmt\x12O\n" + + "\x14make_number_ref_stmt\x18\x17 \x01(\v2\x1c.opa.ir.v1.MakeNumberRefStmtH\x00R\x11makeNumberRefStmt\x12E\n" + + "\x10make_object_stmt\x18\x18 \x01(\v2\x19.opa.ir.v1.MakeObjectStmtH\x00R\x0emakeObjectStmt\x12<\n" + + "\rmake_set_stmt\x18\x19 \x01(\v2\x16.opa.ir.v1.MakeSetStmtH\x00R\vmakeSetStmt\x12/\n" + + "\bnop_stmt\x18\x1a \x01(\v2\x12.opa.ir.v1.NopStmtH\x00R\anopStmt\x12?\n" + + "\x0enot_equal_stmt\x18\x1b \x01(\v2\x17.opa.ir.v1.NotEqualStmtH\x00R\fnotEqualStmt\x12/\n" + + "\bnot_stmt\x18\x1c \x01(\v2\x12.opa.ir.v1.NotStmtH\x00R\anotStmt\x12X\n" + + "\x17object_insert_once_stmt\x18\x1d \x01(\v2\x1f.opa.ir.v1.ObjectInsertOnceStmtH\x00R\x14objectInsertOnceStmt\x12K\n" + + "\x12object_insert_stmt\x18\x1e \x01(\v2\x1b.opa.ir.v1.ObjectInsertStmtH\x00R\x10objectInsertStmt\x12H\n" + + "\x11object_merge_stmt\x18\x1f \x01(\v2\x1a.opa.ir.v1.ObjectMergeStmtH\x00R\x0fobjectMergeStmt\x12E\n" + + "\x10reset_local_stmt\x18 \x01(\v2\x19.opa.ir.v1.ResetLocalStmtH\x00R\x0eresetLocalStmt\x12L\n" + + "\x13result_set_add_stmt\x18! \x01(\v2\x1b.opa.ir.v1.ResultSetAddStmtH\x00R\x10resultSetAddStmt\x12H\n" + + "\x11return_local_stmt\x18\" \x01(\v2\x1a.opa.ir.v1.ReturnLocalStmtH\x00R\x0freturnLocalStmt\x122\n" + + "\tscan_stmt\x18# \x01(\v2\x13.opa.ir.v1.ScanStmtH\x00R\bscanStmt\x129\n" + + "\fset_add_stmt\x18$ \x01(\v2\x15.opa.ir.v1.SetAddStmtH\x00R\n" + + "setAddStmt\x122\n" + + "\twith_stmt\x18% \x01(\v2\x13.opa.ir.v1.WithStmtH\x00R\bwithStmtB\x06\n" + + "\x04kind\"Q\n" + + "\x0fArrayAppendStmt\x12(\n" + + "\x05value\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x05value\x12\x14\n" + + "\x05array\x18\x02 \x01(\x05R\x05array\"=\n" + + "\rAssignIntStmt\x12\x14\n" + + "\x05value\x18\x01 \x01(\x03R\x05value\x12\x16\n" + + "\x06target\x18\x02 \x01(\x05R\x06target\"W\n" + + "\x11AssignVarOnceStmt\x12*\n" + + "\x06source\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x06source\x12\x16\n" + + "\x06target\x18\x02 \x01(\x05R\x06target\"S\n" + + "\rAssignVarStmt\x12*\n" + + "\x06source\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x06source\x12\x16\n" + + "\x06target\x18\x02 \x01(\x05R\x06target\"5\n" + + "\tBlockStmt\x12(\n" + + "\x06blocks\x18\x01 \x03(\v2\x10.opa.ir.v1.BlockR\x06blocks\"!\n" + + "\tBreakStmt\x12\x14\n" + + "\x05index\x18\x01 \x01(\rR\x05index\"e\n" + + "\x0fCallDynamicStmt\x12\x12\n" + + "\x04args\x18\x01 \x03(\x05R\x04args\x12\x16\n" + + "\x06result\x18\x02 \x01(\x05R\x06result\x12&\n" + + "\x04path\x18\x03 \x03(\v2\x12.opa.ir.v1.OperandR\x04path\"f\n" + + "\bCallStmt\x12\x1a\n" + + "\bfunction\x18\x01 \x01(\tR\bfunction\x12&\n" + + "\x04args\x18\x02 \x03(\v2\x12.opa.ir.v1.OperandR\x04args\x12\x16\n" + + "\x06result\x18\x03 \x01(\x05R\x06result\"s\n" + + "\aDotStmt\x12*\n" + + "\x06source\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x06source\x12$\n" + + "\x03key\x18\x02 \x01(\v2\x12.opa.ir.v1.OperandR\x03key\x12\x16\n" + + "\x06target\x18\x03 \x01(\x05R\x06target\"O\n" + + "\tEqualStmt\x12 \n" + + "\x01a\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x01a\x12 \n" + + "\x01b\x18\x02 \x01(\v2\x12.opa.ir.v1.OperandR\x01b\"9\n" + + "\vIsArrayStmt\x12*\n" + + "\x06source\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x06source\"'\n" + + "\rIsDefinedStmt\x12\x16\n" + + "\x06source\x18\x01 \x01(\x05R\x06source\":\n" + + "\fIsObjectStmt\x12*\n" + + "\x06source\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x06source\"7\n" + + "\tIsSetStmt\x12*\n" + + "\x06source\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x06source\")\n" + + "\x0fIsUndefinedStmt\x12\x16\n" + + "\x06source\x18\x01 \x01(\x05R\x06source\"M\n" + + "\aLenStmt\x12*\n" + + "\x06source\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x06source\x12\x16\n" + + "\x06target\x18\x02 \x01(\x05R\x06target\"C\n" + + "\rMakeArrayStmt\x12\x1a\n" + + "\bcapacity\x18\x01 \x01(\x05R\bcapacity\x12\x16\n" + + "\x06target\x18\x02 \x01(\x05R\x06target\"&\n" + + "\fMakeNullStmt\x12\x16\n" + + "\x06target\x18\x01 \x01(\x05R\x06target\"A\n" + + "\x11MakeNumberIntStmt\x12\x14\n" + + "\x05value\x18\x01 \x01(\x03R\x05value\x12\x16\n" + + "\x06target\x18\x02 \x01(\x05R\x06target\"A\n" + + "\x11MakeNumberRefStmt\x12\x14\n" + + "\x05index\x18\x01 \x01(\x05R\x05index\x12\x16\n" + + "\x06target\x18\x02 \x01(\x05R\x06target\"(\n" + + "\x0eMakeObjectStmt\x12\x16\n" + + "\x06target\x18\x01 \x01(\x05R\x06target\"%\n" + + "\vMakeSetStmt\x12\x16\n" + + "\x06target\x18\x01 \x01(\x05R\x06target\"\t\n" + + "\aNopStmt\"R\n" + + "\fNotEqualStmt\x12 \n" + + "\x01a\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x01a\x12 \n" + + "\x01b\x18\x02 \x01(\v2\x12.opa.ir.v1.OperandR\x01b\"1\n" + + "\aNotStmt\x12&\n" + + "\x05block\x18\x01 \x01(\v2\x10.opa.ir.v1.BlockR\x05block\"~\n" + + "\x14ObjectInsertOnceStmt\x12$\n" + + "\x03key\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x03key\x12(\n" + + "\x05value\x18\x02 \x01(\v2\x12.opa.ir.v1.OperandR\x05value\x12\x16\n" + + "\x06object\x18\x03 \x01(\x05R\x06object\"z\n" + + "\x10ObjectInsertStmt\x12$\n" + + "\x03key\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x03key\x12(\n" + + "\x05value\x18\x02 \x01(\v2\x12.opa.ir.v1.OperandR\x05value\x12\x16\n" + + "\x06object\x18\x03 \x01(\x05R\x06object\"E\n" + + "\x0fObjectMergeStmt\x12\f\n" + + "\x01a\x18\x01 \x01(\x05R\x01a\x12\f\n" + + "\x01b\x18\x02 \x01(\x05R\x01b\x12\x16\n" + + "\x06target\x18\x03 \x01(\x05R\x06target\"(\n" + + "\x0eResetLocalStmt\x12\x16\n" + + "\x06target\x18\x01 \x01(\x05R\x06target\"(\n" + + "\x10ResultSetAddStmt\x12\x14\n" + + "\x05value\x18\x01 \x01(\x05R\x05value\")\n" + + "\x0fReturnLocalStmt\x12\x16\n" + + "\x06source\x18\x01 \x01(\x05R\x06source\"r\n" + + "\bScanStmt\x12\x16\n" + + "\x06source\x18\x01 \x01(\x05R\x06source\x12\x10\n" + + "\x03key\x18\x02 \x01(\x05R\x03key\x12\x14\n" + + "\x05value\x18\x03 \x01(\x05R\x05value\x12&\n" + + "\x05block\x18\x04 \x01(\v2\x10.opa.ir.v1.BlockR\x05block\"H\n" + + "\n" + + "SetAddStmt\x12(\n" + + "\x05value\x18\x01 \x01(\v2\x12.opa.ir.v1.OperandR\x05value\x12\x10\n" + + "\x03set\x18\x02 \x01(\x05R\x03set\"\x86\x01\n" + + "\bWithStmt\x12\x14\n" + + "\x05local\x18\x01 \x01(\x05R\x05local\x12\x12\n" + + "\x04path\x18\x02 \x03(\x05R\x04path\x12(\n" + + "\x05value\x18\x03 \x01(\v2\x12.opa.ir.v1.OperandR\x05value\x12&\n" + + "\x05block\x18\x04 \x01(\v2\x10.opa.ir.v1.BlockR\x05blockB/P\x01Z+github.com/open-policy-agent/opa/v1/ir/v1pbb\beditionsp\xe8\a" + +var ( + file_v1_ir_plan_proto_rawDescOnce sync.Once + file_v1_ir_plan_proto_rawDescData []byte +) + +func file_v1_ir_plan_proto_rawDescGZIP() []byte { + file_v1_ir_plan_proto_rawDescOnce.Do(func() { + file_v1_ir_plan_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_v1_ir_plan_proto_rawDesc), len(file_v1_ir_plan_proto_rawDesc))) + }) + return file_v1_ir_plan_proto_rawDescData +} + +var file_v1_ir_plan_proto_msgTypes = make([]protoimpl.MessageInfo, 46) +var file_v1_ir_plan_proto_goTypes = []any{ + (*Policy)(nil), // 0: opa.ir.v1.Policy + (*Static)(nil), // 1: opa.ir.v1.Static + (*BuiltinFunc)(nil), // 2: opa.ir.v1.BuiltinFunc + (*Plans)(nil), // 3: opa.ir.v1.Plans + (*Funcs)(nil), // 4: opa.ir.v1.Funcs + (*Func)(nil), // 5: opa.ir.v1.Func + (*Plan)(nil), // 6: opa.ir.v1.Plan + (*Block)(nil), // 7: opa.ir.v1.Block + (*StringConst)(nil), // 8: opa.ir.v1.StringConst + (*Operand)(nil), // 9: opa.ir.v1.Operand + (*Val)(nil), // 10: opa.ir.v1.Val + (*Stmt)(nil), // 11: opa.ir.v1.Stmt + (*ArrayAppendStmt)(nil), // 12: opa.ir.v1.ArrayAppendStmt + (*AssignIntStmt)(nil), // 13: opa.ir.v1.AssignIntStmt + (*AssignVarOnceStmt)(nil), // 14: opa.ir.v1.AssignVarOnceStmt + (*AssignVarStmt)(nil), // 15: opa.ir.v1.AssignVarStmt + (*BlockStmt)(nil), // 16: opa.ir.v1.BlockStmt + (*BreakStmt)(nil), // 17: opa.ir.v1.BreakStmt + (*CallDynamicStmt)(nil), // 18: opa.ir.v1.CallDynamicStmt + (*CallStmt)(nil), // 19: opa.ir.v1.CallStmt + (*DotStmt)(nil), // 20: opa.ir.v1.DotStmt + (*EqualStmt)(nil), // 21: opa.ir.v1.EqualStmt + (*IsArrayStmt)(nil), // 22: opa.ir.v1.IsArrayStmt + (*IsDefinedStmt)(nil), // 23: opa.ir.v1.IsDefinedStmt + (*IsObjectStmt)(nil), // 24: opa.ir.v1.IsObjectStmt + (*IsSetStmt)(nil), // 25: opa.ir.v1.IsSetStmt + (*IsUndefinedStmt)(nil), // 26: opa.ir.v1.IsUndefinedStmt + (*LenStmt)(nil), // 27: opa.ir.v1.LenStmt + (*MakeArrayStmt)(nil), // 28: opa.ir.v1.MakeArrayStmt + (*MakeNullStmt)(nil), // 29: opa.ir.v1.MakeNullStmt + (*MakeNumberIntStmt)(nil), // 30: opa.ir.v1.MakeNumberIntStmt + (*MakeNumberRefStmt)(nil), // 31: opa.ir.v1.MakeNumberRefStmt + (*MakeObjectStmt)(nil), // 32: opa.ir.v1.MakeObjectStmt + (*MakeSetStmt)(nil), // 33: opa.ir.v1.MakeSetStmt + (*NopStmt)(nil), // 34: opa.ir.v1.NopStmt + (*NotEqualStmt)(nil), // 35: opa.ir.v1.NotEqualStmt + (*NotStmt)(nil), // 36: opa.ir.v1.NotStmt + (*ObjectInsertOnceStmt)(nil), // 37: opa.ir.v1.ObjectInsertOnceStmt + (*ObjectInsertStmt)(nil), // 38: opa.ir.v1.ObjectInsertStmt + (*ObjectMergeStmt)(nil), // 39: opa.ir.v1.ObjectMergeStmt + (*ResetLocalStmt)(nil), // 40: opa.ir.v1.ResetLocalStmt + (*ResultSetAddStmt)(nil), // 41: opa.ir.v1.ResultSetAddStmt + (*ReturnLocalStmt)(nil), // 42: opa.ir.v1.ReturnLocalStmt + (*ScanStmt)(nil), // 43: opa.ir.v1.ScanStmt + (*SetAddStmt)(nil), // 44: opa.ir.v1.SetAddStmt + (*WithStmt)(nil), // 45: opa.ir.v1.WithStmt +} +var file_v1_ir_plan_proto_depIdxs = []int32{ + 1, // 0: opa.ir.v1.Policy.static:type_name -> opa.ir.v1.Static + 3, // 1: opa.ir.v1.Policy.plans:type_name -> opa.ir.v1.Plans + 4, // 2: opa.ir.v1.Policy.funcs:type_name -> opa.ir.v1.Funcs + 8, // 3: opa.ir.v1.Static.strings:type_name -> opa.ir.v1.StringConst + 2, // 4: opa.ir.v1.Static.builtin_funcs:type_name -> opa.ir.v1.BuiltinFunc + 8, // 5: opa.ir.v1.Static.files:type_name -> opa.ir.v1.StringConst + 6, // 6: opa.ir.v1.Plans.plans:type_name -> opa.ir.v1.Plan + 5, // 7: opa.ir.v1.Funcs.funcs:type_name -> opa.ir.v1.Func + 7, // 8: opa.ir.v1.Func.blocks:type_name -> opa.ir.v1.Block + 7, // 9: opa.ir.v1.Plan.blocks:type_name -> opa.ir.v1.Block + 11, // 10: opa.ir.v1.Block.stmts:type_name -> opa.ir.v1.Stmt + 10, // 11: opa.ir.v1.Operand.value:type_name -> opa.ir.v1.Val + 12, // 12: opa.ir.v1.Stmt.array_append_stmt:type_name -> opa.ir.v1.ArrayAppendStmt + 13, // 13: opa.ir.v1.Stmt.assign_int_stmt:type_name -> opa.ir.v1.AssignIntStmt + 14, // 14: opa.ir.v1.Stmt.assign_var_once_stmt:type_name -> opa.ir.v1.AssignVarOnceStmt + 15, // 15: opa.ir.v1.Stmt.assign_var_stmt:type_name -> opa.ir.v1.AssignVarStmt + 16, // 16: opa.ir.v1.Stmt.block_stmt:type_name -> opa.ir.v1.BlockStmt + 17, // 17: opa.ir.v1.Stmt.break_stmt:type_name -> opa.ir.v1.BreakStmt + 18, // 18: opa.ir.v1.Stmt.call_dynamic_stmt:type_name -> opa.ir.v1.CallDynamicStmt + 19, // 19: opa.ir.v1.Stmt.call_stmt:type_name -> opa.ir.v1.CallStmt + 20, // 20: opa.ir.v1.Stmt.dot_stmt:type_name -> opa.ir.v1.DotStmt + 21, // 21: opa.ir.v1.Stmt.equal_stmt:type_name -> opa.ir.v1.EqualStmt + 22, // 22: opa.ir.v1.Stmt.is_array_stmt:type_name -> opa.ir.v1.IsArrayStmt + 23, // 23: opa.ir.v1.Stmt.is_defined_stmt:type_name -> opa.ir.v1.IsDefinedStmt + 24, // 24: opa.ir.v1.Stmt.is_object_stmt:type_name -> opa.ir.v1.IsObjectStmt + 25, // 25: opa.ir.v1.Stmt.is_set_stmt:type_name -> opa.ir.v1.IsSetStmt + 26, // 26: opa.ir.v1.Stmt.is_undefined_stmt:type_name -> opa.ir.v1.IsUndefinedStmt + 27, // 27: opa.ir.v1.Stmt.len_stmt:type_name -> opa.ir.v1.LenStmt + 28, // 28: opa.ir.v1.Stmt.make_array_stmt:type_name -> opa.ir.v1.MakeArrayStmt + 29, // 29: opa.ir.v1.Stmt.make_null_stmt:type_name -> opa.ir.v1.MakeNullStmt + 30, // 30: opa.ir.v1.Stmt.make_number_int_stmt:type_name -> opa.ir.v1.MakeNumberIntStmt + 31, // 31: opa.ir.v1.Stmt.make_number_ref_stmt:type_name -> opa.ir.v1.MakeNumberRefStmt + 32, // 32: opa.ir.v1.Stmt.make_object_stmt:type_name -> opa.ir.v1.MakeObjectStmt + 33, // 33: opa.ir.v1.Stmt.make_set_stmt:type_name -> opa.ir.v1.MakeSetStmt + 34, // 34: opa.ir.v1.Stmt.nop_stmt:type_name -> opa.ir.v1.NopStmt + 35, // 35: opa.ir.v1.Stmt.not_equal_stmt:type_name -> opa.ir.v1.NotEqualStmt + 36, // 36: opa.ir.v1.Stmt.not_stmt:type_name -> opa.ir.v1.NotStmt + 37, // 37: opa.ir.v1.Stmt.object_insert_once_stmt:type_name -> opa.ir.v1.ObjectInsertOnceStmt + 38, // 38: opa.ir.v1.Stmt.object_insert_stmt:type_name -> opa.ir.v1.ObjectInsertStmt + 39, // 39: opa.ir.v1.Stmt.object_merge_stmt:type_name -> opa.ir.v1.ObjectMergeStmt + 40, // 40: opa.ir.v1.Stmt.reset_local_stmt:type_name -> opa.ir.v1.ResetLocalStmt + 41, // 41: opa.ir.v1.Stmt.result_set_add_stmt:type_name -> opa.ir.v1.ResultSetAddStmt + 42, // 42: opa.ir.v1.Stmt.return_local_stmt:type_name -> opa.ir.v1.ReturnLocalStmt + 43, // 43: opa.ir.v1.Stmt.scan_stmt:type_name -> opa.ir.v1.ScanStmt + 44, // 44: opa.ir.v1.Stmt.set_add_stmt:type_name -> opa.ir.v1.SetAddStmt + 45, // 45: opa.ir.v1.Stmt.with_stmt:type_name -> opa.ir.v1.WithStmt + 9, // 46: opa.ir.v1.ArrayAppendStmt.value:type_name -> opa.ir.v1.Operand + 9, // 47: opa.ir.v1.AssignVarOnceStmt.source:type_name -> opa.ir.v1.Operand + 9, // 48: opa.ir.v1.AssignVarStmt.source:type_name -> opa.ir.v1.Operand + 7, // 49: opa.ir.v1.BlockStmt.blocks:type_name -> opa.ir.v1.Block + 9, // 50: opa.ir.v1.CallDynamicStmt.path:type_name -> opa.ir.v1.Operand + 9, // 51: opa.ir.v1.CallStmt.args:type_name -> opa.ir.v1.Operand + 9, // 52: opa.ir.v1.DotStmt.source:type_name -> opa.ir.v1.Operand + 9, // 53: opa.ir.v1.DotStmt.key:type_name -> opa.ir.v1.Operand + 9, // 54: opa.ir.v1.EqualStmt.a:type_name -> opa.ir.v1.Operand + 9, // 55: opa.ir.v1.EqualStmt.b:type_name -> opa.ir.v1.Operand + 9, // 56: opa.ir.v1.IsArrayStmt.source:type_name -> opa.ir.v1.Operand + 9, // 57: opa.ir.v1.IsObjectStmt.source:type_name -> opa.ir.v1.Operand + 9, // 58: opa.ir.v1.IsSetStmt.source:type_name -> opa.ir.v1.Operand + 9, // 59: opa.ir.v1.LenStmt.source:type_name -> opa.ir.v1.Operand + 9, // 60: opa.ir.v1.NotEqualStmt.a:type_name -> opa.ir.v1.Operand + 9, // 61: opa.ir.v1.NotEqualStmt.b:type_name -> opa.ir.v1.Operand + 7, // 62: opa.ir.v1.NotStmt.block:type_name -> opa.ir.v1.Block + 9, // 63: opa.ir.v1.ObjectInsertOnceStmt.key:type_name -> opa.ir.v1.Operand + 9, // 64: opa.ir.v1.ObjectInsertOnceStmt.value:type_name -> opa.ir.v1.Operand + 9, // 65: opa.ir.v1.ObjectInsertStmt.key:type_name -> opa.ir.v1.Operand + 9, // 66: opa.ir.v1.ObjectInsertStmt.value:type_name -> opa.ir.v1.Operand + 7, // 67: opa.ir.v1.ScanStmt.block:type_name -> opa.ir.v1.Block + 9, // 68: opa.ir.v1.SetAddStmt.value:type_name -> opa.ir.v1.Operand + 9, // 69: opa.ir.v1.WithStmt.value:type_name -> opa.ir.v1.Operand + 7, // 70: opa.ir.v1.WithStmt.block:type_name -> opa.ir.v1.Block + 71, // [71:71] is the sub-list for method output_type + 71, // [71:71] is the sub-list for method input_type + 71, // [71:71] is the sub-list for extension type_name + 71, // [71:71] is the sub-list for extension extendee + 0, // [0:71] is the sub-list for field type_name +} + +func init() { file_v1_ir_plan_proto_init() } +func file_v1_ir_plan_proto_init() { + if File_v1_ir_plan_proto != nil { + return + } + file_v1_ir_plan_proto_msgTypes[10].OneofWrappers = []any{ + (*Val_Bool)(nil), + (*Val_Local)(nil), + (*Val_StringIndex)(nil), + } + file_v1_ir_plan_proto_msgTypes[11].OneofWrappers = []any{ + (*Stmt_ArrayAppendStmt)(nil), + (*Stmt_AssignIntStmt)(nil), + (*Stmt_AssignVarOnceStmt)(nil), + (*Stmt_AssignVarStmt)(nil), + (*Stmt_BlockStmt)(nil), + (*Stmt_BreakStmt)(nil), + (*Stmt_CallDynamicStmt)(nil), + (*Stmt_CallStmt)(nil), + (*Stmt_DotStmt)(nil), + (*Stmt_EqualStmt)(nil), + (*Stmt_IsArrayStmt)(nil), + (*Stmt_IsDefinedStmt)(nil), + (*Stmt_IsObjectStmt)(nil), + (*Stmt_IsSetStmt)(nil), + (*Stmt_IsUndefinedStmt)(nil), + (*Stmt_LenStmt)(nil), + (*Stmt_MakeArrayStmt)(nil), + (*Stmt_MakeNullStmt)(nil), + (*Stmt_MakeNumberIntStmt)(nil), + (*Stmt_MakeNumberRefStmt)(nil), + (*Stmt_MakeObjectStmt)(nil), + (*Stmt_MakeSetStmt)(nil), + (*Stmt_NopStmt)(nil), + (*Stmt_NotEqualStmt)(nil), + (*Stmt_NotStmt)(nil), + (*Stmt_ObjectInsertOnceStmt)(nil), + (*Stmt_ObjectInsertStmt)(nil), + (*Stmt_ObjectMergeStmt)(nil), + (*Stmt_ResetLocalStmt)(nil), + (*Stmt_ResultSetAddStmt)(nil), + (*Stmt_ReturnLocalStmt)(nil), + (*Stmt_ScanStmt)(nil), + (*Stmt_SetAddStmt)(nil), + (*Stmt_WithStmt)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_v1_ir_plan_proto_rawDesc), len(file_v1_ir_plan_proto_rawDesc)), + NumEnums: 0, + NumMessages: 46, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_v1_ir_plan_proto_goTypes, + DependencyIndexes: file_v1_ir_plan_proto_depIdxs, + MessageInfos: file_v1_ir_plan_proto_msgTypes, + }.Build() + File_v1_ir_plan_proto = out.File + file_v1_ir_plan_proto_goTypes = nil + file_v1_ir_plan_proto_depIdxs = nil +}