mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-24 17:25:16 -06:00
ffd0036e7c
This adds a new option for eval which will disable indexing so that variable bindings for rules that would otherwise not evaluate can be found. This also adds to (and corrects) the JSON marshalled trace events. We now have extra metadata about the local variables, a working JSON marshaller for the `Locals` (which includes type info), and the event nodes location information. Fixes: #1697 Signed-off-by: Patrick East <east.patrick@gmail.com>
134 lines
2.7 KiB
Go
134 lines
2.7 KiB
Go
// Copyright 2016 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 ast
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/open-policy-agent/opa/util"
|
|
)
|
|
|
|
// ValueMap represents a key/value map between AST term values. Any type of term
|
|
// can be used as a key in the map.
|
|
type ValueMap struct {
|
|
hashMap *util.HashMap
|
|
}
|
|
|
|
// NewValueMap returns a new ValueMap.
|
|
func NewValueMap() *ValueMap {
|
|
vs := &ValueMap{
|
|
hashMap: util.NewHashMap(valueEq, valueHash),
|
|
}
|
|
return vs
|
|
}
|
|
|
|
// MarshalJSON provides a custom marshaller for the ValueMap which
|
|
// will include the key, value, and value type.
|
|
func (vs *ValueMap) MarshalJSON() ([]byte, error) {
|
|
var tmp []map[string]interface{}
|
|
vs.Iter(func(k Value, v Value) bool {
|
|
tmp = append(tmp, map[string]interface{}{
|
|
"name": k.String(),
|
|
"type": TypeName(v),
|
|
"value": v,
|
|
})
|
|
return false
|
|
})
|
|
return json.Marshal(tmp)
|
|
}
|
|
|
|
// Copy returns a shallow copy of the ValueMap.
|
|
func (vs *ValueMap) Copy() *ValueMap {
|
|
if vs == nil {
|
|
return nil
|
|
}
|
|
cpy := NewValueMap()
|
|
cpy.hashMap = vs.hashMap.Copy()
|
|
return cpy
|
|
}
|
|
|
|
// Equal returns true if this ValueMap equals the other.
|
|
func (vs *ValueMap) Equal(other *ValueMap) bool {
|
|
if vs == nil {
|
|
return other == nil || other.Len() == 0
|
|
}
|
|
if other == nil {
|
|
return vs == nil || vs.Len() == 0
|
|
}
|
|
return vs.hashMap.Equal(other.hashMap)
|
|
}
|
|
|
|
// Len returns the number of elements in the map.
|
|
func (vs *ValueMap) Len() int {
|
|
if vs == nil {
|
|
return 0
|
|
}
|
|
return vs.hashMap.Len()
|
|
}
|
|
|
|
// Get returns the value in the map for k.
|
|
func (vs *ValueMap) Get(k Value) Value {
|
|
if vs != nil {
|
|
if v, ok := vs.hashMap.Get(k); ok {
|
|
return v.(Value)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Hash returns a hash code for this ValueMap.
|
|
func (vs *ValueMap) Hash() int {
|
|
if vs == nil {
|
|
return 0
|
|
}
|
|
return vs.hashMap.Hash()
|
|
}
|
|
|
|
// Iter calls the iter function for each key/value pair in the map. If the iter
|
|
// function returns true, iteration stops.
|
|
func (vs *ValueMap) Iter(iter func(Value, Value) bool) bool {
|
|
if vs == nil {
|
|
return false
|
|
}
|
|
return vs.hashMap.Iter(func(kt, vt util.T) bool {
|
|
k := kt.(Value)
|
|
v := vt.(Value)
|
|
return iter(k, v)
|
|
})
|
|
}
|
|
|
|
// Put inserts a key k into the map with value v.
|
|
func (vs *ValueMap) Put(k, v Value) {
|
|
if vs == nil {
|
|
panic("put on nil value map")
|
|
}
|
|
vs.hashMap.Put(k, v)
|
|
}
|
|
|
|
// Delete removes a key k from the map.
|
|
func (vs *ValueMap) Delete(k Value) {
|
|
if vs == nil {
|
|
return
|
|
}
|
|
vs.hashMap.Delete(k)
|
|
}
|
|
|
|
func (vs *ValueMap) String() string {
|
|
if vs == nil {
|
|
return "{}"
|
|
}
|
|
return vs.hashMap.String()
|
|
}
|
|
|
|
func valueHash(v util.T) int {
|
|
return v.(Value).Hash()
|
|
}
|
|
|
|
func valueEq(a, b util.T) bool {
|
|
av := a.(Value)
|
|
bv := b.(Value)
|
|
return av.Compare(bv) == 0
|
|
}
|