1// Copyright 2016 The OPA Authors. All rights reserved. 2// Use of this source code is governed by an Apache2 3// license that can be found in the LICENSE file. 4 5package ast 6 7import ( 8 "strings" 9 10 "github.com/open-policy-agent/opa/types" 11) 12 13// Builtins is the registry of built-in functions supported by OPA. 14// Call RegisterBuiltin to add a new built-in. 15var Builtins []*Builtin 16 17// RegisterBuiltin adds a new built-in function to the registry. 18func RegisterBuiltin(b *Builtin) { 19 Builtins = append(Builtins, b) 20 BuiltinMap[b.Name] = b 21 if len(b.Infix) > 0 { 22 BuiltinMap[b.Infix] = b 23 } 24} 25 26// DefaultBuiltins is the registry of built-in functions supported in OPA 27// by default. When adding a new built-in function to OPA, update this 28// list. 29var DefaultBuiltins = [...]*Builtin{ 30 31 // Unification/equality ("=") 32 Equality, 33 34 // Assignment (":=") 35 Assign, 36 37 // Comparisons 38 GreaterThan, 39 GreaterThanEq, 40 LessThan, 41 LessThanEq, 42 NotEqual, 43 Equal, 44 45 // Arithmetic 46 Plus, 47 Minus, 48 Multiply, 49 Divide, 50 Round, 51 Abs, 52 Rem, 53 54 // Binary 55 And, 56 Or, 57 58 // Aggregates 59 Count, 60 Sum, 61 Product, 62 Max, 63 Min, 64 65 // Casting 66 ToNumber, 67 68 // Regular Expressions 69 RegexMatch, 70 GlobsMatch, 71 72 // Sets 73 SetDiff, 74 Intersection, 75 Union, 76 77 // Strings 78 Concat, 79 FormatInt, 80 IndexOf, 81 Substring, 82 Lower, 83 Upper, 84 Contains, 85 StartsWith, 86 EndsWith, 87 Split, 88 Replace, 89 Trim, 90 Sprintf, 91 92 // Encoding 93 JSONMarshal, 94 JSONUnmarshal, 95 Base64Encode, 96 Base64Decode, 97 Base64UrlEncode, 98 Base64UrlDecode, 99 URLQueryDecode, 100 URLQueryEncode, 101 URLQueryEncodeObject, 102 YAMLMarshal, 103 YAMLUnmarshal, 104 105 // Tokens 106 JWTDecode, 107 JWTVerifyRS256, 108 JWTVerifyHS256, 109 110 // Time 111 NowNanos, 112 ParseNanos, 113 ParseRFC3339Nanos, 114 ParseDurationNanos, 115 Date, 116 Clock, 117 118 // Crypto 119 CryptoX509ParseCertificates, 120 121 // Graphs 122 WalkBuiltin, 123 124 // Sort 125 Sort, 126 127 // Types 128 IsNumber, 129 IsString, 130 IsBoolean, 131 IsArray, 132 IsSet, 133 IsObject, 134 IsNull, 135 TypeNameBuiltin, 136 137 // HTTP 138 HTTPSend, 139 140 // Tracing 141 Trace, 142} 143 144// BuiltinMap provides a convenient mapping of built-in names to 145// built-in definitions. 146var BuiltinMap map[string]*Builtin 147 148// IgnoreDuringPartialEval is a set of built-in functions that should not be 149// evaluated during partial evaluation. These functions are not partially 150// evaluated because they are not pure. 151var IgnoreDuringPartialEval = []*Builtin{ 152 NowNanos, 153 HTTPSend, 154} 155 156/** 157 * Unification 158 */ 159 160// Equality represents the "=" operator. 161var Equality = &Builtin{ 162 Name: "eq", 163 Infix: "=", 164 Decl: types.NewFunction( 165 types.Args(types.A, types.A), 166 types.B, 167 ), 168} 169 170/** 171 * Assignment 172 */ 173 174// Assign represents the assignment (":=") operator. 175var Assign = &Builtin{ 176 Name: "assign", 177 Infix: ":=", 178 Decl: types.NewFunction( 179 types.Args(types.A, types.A), 180 types.B, 181 ), 182} 183 184/** 185 * Comparisons 186 */ 187 188// GreaterThan represents the ">" comparison operator. 189var GreaterThan = &Builtin{ 190 Name: "gt", 191 Infix: ">", 192 Decl: types.NewFunction( 193 types.Args(types.A, types.A), 194 types.B, 195 ), 196} 197 198// GreaterThanEq represents the ">=" comparison operator. 199var GreaterThanEq = &Builtin{ 200 Name: "gte", 201 Infix: ">=", 202 Decl: types.NewFunction( 203 types.Args(types.A, types.A), 204 types.B, 205 ), 206} 207 208// LessThan represents the "<" comparison operator. 209var LessThan = &Builtin{ 210 Name: "lt", 211 Infix: "<", 212 Decl: types.NewFunction( 213 types.Args(types.A, types.A), 214 types.B, 215 ), 216} 217 218// LessThanEq represents the "<=" comparison operator. 219var LessThanEq = &Builtin{ 220 Name: "lte", 221 Infix: "<=", 222 Decl: types.NewFunction( 223 types.Args(types.A, types.A), 224 types.B, 225 ), 226} 227 228// NotEqual represents the "!=" comparison operator. 229var NotEqual = &Builtin{ 230 Name: "neq", 231 Infix: "!=", 232 Decl: types.NewFunction( 233 types.Args(types.A, types.A), 234 types.B, 235 ), 236} 237 238// Equal represents the "==" comparison operator. 239var Equal = &Builtin{ 240 Name: "equal", 241 Infix: "==", 242 Decl: types.NewFunction( 243 types.Args(types.A, types.A), 244 types.B, 245 ), 246} 247 248/** 249 * Arithmetic 250 */ 251 252// Plus adds two numbers together. 253var Plus = &Builtin{ 254 Name: "plus", 255 Infix: "+", 256 Decl: types.NewFunction( 257 types.Args(types.N, types.N), 258 types.N, 259 ), 260} 261 262// Minus subtracts the second number from the first number or computes the diff 263// between two sets. 264var Minus = &Builtin{ 265 Name: "minus", 266 Infix: "-", 267 Decl: types.NewFunction( 268 types.Args( 269 types.NewAny(types.N, types.NewSet(types.A)), 270 types.NewAny(types.N, types.NewSet(types.A)), 271 ), 272 types.NewAny(types.N, types.NewSet(types.A)), 273 ), 274} 275 276// Multiply multiplies two numbers together. 277var Multiply = &Builtin{ 278 Name: "mul", 279 Infix: "*", 280 Decl: types.NewFunction( 281 types.Args(types.N, types.N), 282 types.N, 283 ), 284} 285 286// Divide divides the first number by the second number. 287var Divide = &Builtin{ 288 Name: "div", 289 Infix: "/", 290 Decl: types.NewFunction( 291 types.Args(types.N, types.N), 292 types.N, 293 ), 294} 295 296// Round rounds the number up to the nearest integer. 297var Round = &Builtin{ 298 Name: "round", 299 Decl: types.NewFunction( 300 types.Args(types.N), 301 types.N, 302 ), 303} 304 305// Abs returns the number without its sign. 306var Abs = &Builtin{ 307 Name: "abs", 308 Decl: types.NewFunction( 309 types.Args(types.N), 310 types.N, 311 ), 312} 313 314// Rem returns the remainder for x%y for y != 0. 315var Rem = &Builtin{ 316 Name: "rem", 317 Infix: "%", 318 Decl: types.NewFunction( 319 types.Args(types.N, types.N), 320 types.N, 321 ), 322} 323 324/** 325 * Binary 326 */ 327 328// TODO(tsandall): update binary operators to support integers. 329 330// And performs an intersection operation on sets. 331var And = &Builtin{ 332 Name: "and", 333 Infix: "&", 334 Decl: types.NewFunction( 335 types.Args( 336 types.NewSet(types.A), 337 types.NewSet(types.A), 338 ), 339 types.NewSet(types.A), 340 ), 341} 342 343// Or performs a union operation on sets. 344var Or = &Builtin{ 345 Name: "or", 346 Infix: "|", 347 Decl: types.NewFunction( 348 types.Args( 349 types.NewSet(types.A), 350 types.NewSet(types.A), 351 ), 352 types.NewSet(types.A), 353 ), 354} 355 356/** 357 * Aggregates 358 */ 359 360// Count takes a collection or string and counts the number of elements in it. 361var Count = &Builtin{ 362 Name: "count", 363 Decl: types.NewFunction( 364 types.Args( 365 types.NewAny( 366 types.NewSet(types.A), 367 types.NewArray(nil, types.A), 368 types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), 369 types.S, 370 ), 371 ), 372 types.N, 373 ), 374} 375 376// Sum takes an array or set of numbers and sums them. 377var Sum = &Builtin{ 378 Name: "sum", 379 Decl: types.NewFunction( 380 types.Args( 381 types.NewAny( 382 types.NewSet(types.N), 383 types.NewArray(nil, types.N), 384 ), 385 ), 386 types.N, 387 ), 388} 389 390// Product takes an array or set of numbers and multiplies them. 391var Product = &Builtin{ 392 Name: "product", 393 Decl: types.NewFunction( 394 types.Args( 395 types.NewAny( 396 types.NewSet(types.N), 397 types.NewArray(nil, types.N), 398 ), 399 ), 400 types.N, 401 ), 402} 403 404// Max returns the maximum value in a collection. 405var Max = &Builtin{ 406 Name: "max", 407 Decl: types.NewFunction( 408 types.Args( 409 types.NewAny( 410 types.NewSet(types.A), 411 types.NewArray(nil, types.A), 412 ), 413 ), 414 types.A, 415 ), 416} 417 418// Min returns the minimum value in a collection. 419var Min = &Builtin{ 420 Name: "min", 421 Decl: types.NewFunction( 422 types.Args( 423 types.NewAny( 424 types.NewSet(types.A), 425 types.NewArray(nil, types.A), 426 ), 427 ), 428 types.A, 429 ), 430} 431 432/** 433 * Casting 434 */ 435 436// ToNumber takes a string, bool, or number value and converts it to a number. 437// Strings are converted to numbers using strconv.Atoi. 438// Boolean false is converted to 0 and boolean true is converted to 1. 439var ToNumber = &Builtin{ 440 Name: "to_number", 441 Decl: types.NewFunction( 442 types.Args( 443 types.NewAny( 444 types.N, 445 types.S, 446 types.B, 447 types.NewNull(), 448 ), 449 ), 450 types.N, 451 ), 452} 453 454/** 455 * Regular Expressions 456 */ 457 458// RegexMatch takes two strings and evaluates to true if the string in the second 459// position matches the pattern in the first position. 460var RegexMatch = &Builtin{ 461 Name: "re_match", 462 Decl: types.NewFunction( 463 types.Args( 464 types.S, 465 types.S, 466 ), 467 types.B, 468 ), 469} 470 471// GlobsMatch takes two strings regexp-style strings and evaluates to true if their 472// intersection matches a non-empty set of non-empty strings. 473// Examples: 474// - "a.a." and ".b.b" -> true. 475// - "[a-z]*" and [0-9]+" -> not true. 476var GlobsMatch = &Builtin{ 477 Name: "regex.globs_match", 478 Decl: types.NewFunction( 479 types.Args( 480 types.S, 481 types.S, 482 ), 483 types.B, 484 ), 485} 486 487/** 488 * Strings 489 */ 490 491// Concat joins an array of strings with an input string. 492var Concat = &Builtin{ 493 Name: "concat", 494 Decl: types.NewFunction( 495 types.Args( 496 types.S, 497 types.NewAny( 498 types.NewSet(types.S), 499 types.NewArray(nil, types.S), 500 ), 501 ), 502 types.S, 503 ), 504} 505 506// FormatInt returns the string representation of the number in the given base after converting it to an integer value. 507var FormatInt = &Builtin{ 508 Name: "format_int", 509 Decl: types.NewFunction( 510 types.Args( 511 types.N, 512 types.N, 513 ), 514 types.S, 515 ), 516} 517 518// IndexOf returns the index of a substring contained inside a string 519var IndexOf = &Builtin{ 520 Name: "indexof", 521 Decl: types.NewFunction( 522 types.Args( 523 types.S, 524 types.S, 525 ), 526 types.N, 527 ), 528} 529 530// Substring returns the portion of a string for a given start index and a length. 531// If the length is less than zero, then substring returns the remainder of the string. 532var Substring = &Builtin{ 533 Name: "substring", 534 Decl: types.NewFunction( 535 types.Args( 536 types.S, 537 types.N, 538 types.N, 539 ), 540 types.S, 541 ), 542} 543 544// Contains returns true if the search string is included in the base string 545var Contains = &Builtin{ 546 Name: "contains", 547 Decl: types.NewFunction( 548 types.Args( 549 types.S, 550 types.S, 551 ), 552 types.B, 553 ), 554} 555 556// StartsWith returns true if the search string begins with the base string 557var StartsWith = &Builtin{ 558 Name: "startswith", 559 Decl: types.NewFunction( 560 types.Args( 561 types.S, 562 types.S, 563 ), 564 types.B, 565 ), 566} 567 568// EndsWith returns true if the search string begins with the base string 569var EndsWith = &Builtin{ 570 Name: "endswith", 571 Decl: types.NewFunction( 572 types.Args( 573 types.S, 574 types.S, 575 ), 576 types.B, 577 ), 578} 579 580// Lower returns the input string but with all characters in lower-case 581var Lower = &Builtin{ 582 Name: "lower", 583 Decl: types.NewFunction( 584 types.Args(types.S), 585 types.S, 586 ), 587} 588 589// Upper returns the input string but with all characters in upper-case 590var Upper = &Builtin{ 591 Name: "upper", 592 Decl: types.NewFunction( 593 types.Args(types.S), 594 types.S, 595 ), 596} 597 598// Split returns an array containing elements of the input string split on a delimiter. 599var Split = &Builtin{ 600 Name: "split", 601 Decl: types.NewFunction( 602 types.Args( 603 types.S, 604 types.S, 605 ), 606 types.NewArray(nil, types.S), 607 ), 608} 609 610// Replace returns the given string with all instances of the second argument replaced 611// by the third. 612var Replace = &Builtin{ 613 Name: "replace", 614 Decl: types.NewFunction( 615 types.Args( 616 types.S, 617 types.S, 618 types.S, 619 ), 620 types.S, 621 ), 622} 623 624// Trim returns the given string will all leading or trailing instances of the second 625// argument removed. 626var Trim = &Builtin{ 627 Name: "trim", 628 Decl: types.NewFunction( 629 types.Args( 630 types.S, 631 types.S, 632 ), 633 types.S, 634 ), 635} 636 637// Sprintf returns the given string, formatted. 638var Sprintf = &Builtin{ 639 Name: "sprintf", 640 Decl: types.NewFunction( 641 types.Args( 642 types.S, 643 types.NewArray(nil, types.A), 644 ), 645 types.S, 646 ), 647} 648 649/** 650 * JSON 651 */ 652 653// JSONMarshal serializes the input term. 654var JSONMarshal = &Builtin{ 655 Name: "json.marshal", 656 Decl: types.NewFunction( 657 types.Args(types.A), 658 types.S, 659 ), 660} 661 662// JSONUnmarshal deserializes the input string. 663var JSONUnmarshal = &Builtin{ 664 Name: "json.unmarshal", 665 Decl: types.NewFunction( 666 types.Args(types.S), 667 types.A, 668 ), 669} 670 671// Base64Encode serializes the input string into base64 encoding. 672var Base64Encode = &Builtin{ 673 Name: "base64.encode", 674 Decl: types.NewFunction( 675 types.Args(types.S), 676 types.S, 677 ), 678} 679 680// Base64Decode deserializes the base64 encoded input string. 681var Base64Decode = &Builtin{ 682 Name: "base64.decode", 683 Decl: types.NewFunction( 684 types.Args(types.S), 685 types.S, 686 ), 687} 688 689// Base64UrlEncode serializes the input string into base64url encoding. 690var Base64UrlEncode = &Builtin{ 691 Name: "base64url.encode", 692 Decl: types.NewFunction( 693 types.Args(types.S), 694 types.S, 695 ), 696} 697 698// Base64UrlDecode deserializes the base64url encoded input string. 699var Base64UrlDecode = &Builtin{ 700 Name: "base64url.decode", 701 Decl: types.NewFunction( 702 types.Args(types.S), 703 types.S, 704 ), 705} 706 707// URLQueryDecode decodes a URL encoded input string. 708var URLQueryDecode = &Builtin{ 709 Name: "urlquery.decode", 710 Decl: types.NewFunction( 711 types.Args(types.S), 712 types.S, 713 ), 714} 715 716// URLQueryEncode encodes the input string into a URL encoded string. 717var URLQueryEncode = &Builtin{ 718 Name: "urlquery.encode", 719 Decl: types.NewFunction( 720 types.Args(types.S), 721 types.S, 722 ), 723} 724 725// URLQueryEncodeObject encodes the given JSON into a URL encoded query string. 726var URLQueryEncodeObject = &Builtin{ 727 Name: "urlquery.encode_object", 728 Decl: types.NewFunction( 729 types.Args( 730 types.NewObject( 731 nil, 732 types.NewDynamicProperty( 733 types.S, 734 types.NewAny( 735 types.S, 736 types.NewArray(nil, types.S), 737 types.NewSet(types.S))))), 738 types.S, 739 ), 740} 741 742// YAMLMarshal serializes the input term. 743var YAMLMarshal = &Builtin{ 744 Name: "yaml.marshal", 745 Decl: types.NewFunction( 746 types.Args(types.A), 747 types.S, 748 ), 749} 750 751// YAMLUnmarshal deserializes the input string. 752var YAMLUnmarshal = &Builtin{ 753 Name: "yaml.unmarshal", 754 Decl: types.NewFunction( 755 types.Args(types.S), 756 types.A, 757 ), 758} 759 760/** 761 * Tokens 762 */ 763 764// JWTDecode decodes a JSON Web Token and outputs it as an Object. 765var JWTDecode = &Builtin{ 766 Name: "io.jwt.decode", 767 Decl: types.NewFunction( 768 types.Args(types.S), 769 types.NewArray([]types.Type{ 770 types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), 771 types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), 772 types.S, 773 }, nil), 774 ), 775} 776 777// JWTVerifyRS256 verifies if a RS256 JWT signature is valid or not. 778var JWTVerifyRS256 = &Builtin{ 779 Name: "io.jwt.verify_rs256", 780 Decl: types.NewFunction( 781 types.Args( 782 types.S, 783 types.S, 784 ), 785 types.B, 786 ), 787} 788 789// JWTVerifyHS256 verifies if a HS256 (secret) JWT signature is valid or not. 790var JWTVerifyHS256 = &Builtin{ 791 Name: "io.jwt.verify_hs256", 792 Decl: types.NewFunction( 793 types.Args( 794 types.S, 795 types.S, 796 ), 797 types.B, 798 ), 799} 800 801/** 802 * Time 803 */ 804 805// NowNanos returns the current time since epoch in nanoseconds. 806var NowNanos = &Builtin{ 807 Name: "time.now_ns", 808 Decl: types.NewFunction( 809 nil, 810 types.N, 811 ), 812} 813 814// ParseNanos returns the time in nanoseconds parsed from the string in the given format. 815var ParseNanos = &Builtin{ 816 Name: "time.parse_ns", 817 Decl: types.NewFunction( 818 types.Args( 819 types.S, 820 types.S, 821 ), 822 types.N, 823 ), 824} 825 826// ParseRFC3339Nanos returns the time in nanoseconds parsed from the string in RFC3339 format. 827var ParseRFC3339Nanos = &Builtin{ 828 Name: "time.parse_rfc3339_ns", 829 Decl: types.NewFunction( 830 types.Args(types.S), 831 types.N, 832 ), 833} 834 835// ParseDurationNanos returns the duration in nanoseconds represented by a duration string. 836// Duration string is similar to the Go time.ParseDuration string 837var ParseDurationNanos = &Builtin{ 838 Name: "time.parse_duration_ns", 839 Decl: types.NewFunction( 840 types.Args(types.S), 841 types.N, 842 ), 843} 844 845// Date returns the [year, month, day] for the nanoseconds since epoch. 846var Date = &Builtin{ 847 Name: "time.date", 848 Decl: types.NewFunction( 849 types.Args(types.N), 850 types.NewArray([]types.Type{types.N, types.N, types.N}, nil), 851 ), 852} 853 854// Clock returns the [hour, minute, second] of the day for the nanoseconds since epoch. 855var Clock = &Builtin{ 856 Name: "time.clock", 857 Decl: types.NewFunction( 858 types.Args(types.N), 859 types.NewArray([]types.Type{types.N, types.N, types.N}, nil), 860 ), 861} 862 863/** 864 * Crypto. 865 */ 866 867// CryptoX509ParseCertificates returns one or more certificates from the given 868// base64 encoded string containing DER encoded certificates that have been 869// concatenated. 870var CryptoX509ParseCertificates = &Builtin{ 871 Name: "crypto.x509.parse_certificates", 872 Decl: types.NewFunction( 873 types.Args(types.S), 874 types.NewArray(nil, types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), 875 ), 876} 877 878/** 879 * Graphs. 880 */ 881 882// WalkBuiltin generates [path, value] tuples for all nested documents 883// (recursively). 884var WalkBuiltin = &Builtin{ 885 Name: "walk", 886 Relation: true, 887 Decl: types.NewFunction( 888 types.Args(types.A), 889 types.NewArray( 890 []types.Type{ 891 types.NewArray(nil, types.A), 892 types.A, 893 }, 894 nil, 895 ), 896 ), 897} 898 899/** 900 * Sorting 901 */ 902 903// Sort returns a sorted array. 904var Sort = &Builtin{ 905 Name: "sort", 906 Decl: types.NewFunction( 907 types.Args( 908 types.NewAny( 909 types.NewArray(nil, types.A), 910 types.NewSet(types.A), 911 ), 912 ), 913 types.NewArray(nil, types.A), 914 ), 915} 916 917/** 918 * Type 919 */ 920 921// IsNumber returns true if the input value is a number 922var IsNumber = &Builtin{ 923 Name: "is_number", 924 Decl: types.NewFunction( 925 types.Args( 926 types.A, 927 ), 928 types.B, 929 ), 930} 931 932// IsString returns true if the input value is a string. 933var IsString = &Builtin{ 934 Name: "is_string", 935 Decl: types.NewFunction( 936 types.Args( 937 types.A, 938 ), 939 types.B, 940 ), 941} 942 943// IsBoolean returns true if the input value is a boolean. 944var IsBoolean = &Builtin{ 945 Name: "is_boolean", 946 Decl: types.NewFunction( 947 types.Args( 948 types.A, 949 ), 950 types.B, 951 ), 952} 953 954// IsArray returns true if the input value is an array. 955var IsArray = &Builtin{ 956 Name: "is_array", 957 Decl: types.NewFunction( 958 types.Args( 959 types.A, 960 ), 961 types.B, 962 ), 963} 964 965// IsSet returns true if the input value is a set. 966var IsSet = &Builtin{ 967 Name: "is_set", 968 Decl: types.NewFunction( 969 types.Args( 970 types.A, 971 ), 972 types.B, 973 ), 974} 975 976// IsObject returns true if the input value is an object. 977var IsObject = &Builtin{ 978 Name: "is_object", 979 Decl: types.NewFunction( 980 types.Args( 981 types.A, 982 ), 983 types.B, 984 ), 985} 986 987// IsNull returns true if the input value is null. 988var IsNull = &Builtin{ 989 Name: "is_null", 990 Decl: types.NewFunction( 991 types.Args( 992 types.A, 993 ), 994 types.B, 995 ), 996} 997 998/** 999 * Type Name 1000 */ 1001 1002// TypeNameBuiltin returns the type of the input. 1003var TypeNameBuiltin = &Builtin{ 1004 Name: "type_name", 1005 Decl: types.NewFunction( 1006 types.Args( 1007 types.NewAny( 1008 types.A, 1009 ), 1010 ), 1011 types.S, 1012 ), 1013} 1014 1015/** 1016 * HTTP Request 1017 */ 1018 1019// HTTPSend returns a HTTP response to the given HTTP request. 1020var HTTPSend = &Builtin{ 1021 Name: "http.send", 1022 Decl: types.NewFunction( 1023 types.Args( 1024 types.NewObject(nil, types.NewDynamicProperty(types.S, types.A)), 1025 ), 1026 types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), 1027 ), 1028} 1029 1030/** 1031 * Trace 1032 */ 1033 1034// Trace prints a note that is included in the query explanation. 1035var Trace = &Builtin{ 1036 Name: "trace", 1037 Decl: types.NewFunction( 1038 types.Args( 1039 types.S, 1040 ), 1041 types.B, 1042 ), 1043} 1044 1045/** 1046 * Set 1047 */ 1048 1049// Intersection returns the intersection of the given input sets 1050var Intersection = &Builtin{ 1051 Name: "intersection", 1052 Decl: types.NewFunction( 1053 types.Args( 1054 types.NewSet(types.NewSet(types.A)), 1055 ), 1056 types.NewSet(types.A), 1057 ), 1058} 1059 1060// Union returns the union of the given input sets 1061var Union = &Builtin{ 1062 Name: "union", 1063 Decl: types.NewFunction( 1064 types.Args( 1065 types.NewSet(types.NewSet(types.A)), 1066 ), 1067 types.NewSet(types.A), 1068 ), 1069} 1070 1071/** 1072 * Deprecated built-ins. 1073 */ 1074 1075// SetDiff has been replaced by the minus built-in. 1076var SetDiff = &Builtin{ 1077 Name: "set_diff", 1078 Decl: types.NewFunction( 1079 types.Args( 1080 types.NewSet(types.A), 1081 types.NewSet(types.A), 1082 ), 1083 types.NewSet(types.A), 1084 ), 1085} 1086 1087// Builtin represents a built-in function supported by OPA. Every built-in 1088// function is uniquely identified by a name. 1089type Builtin struct { 1090 Name string // Unique name of built-in function, e.g., <name>(arg1,arg2,...,argN) 1091 Infix string // Unique name of infix operator. Default should be unset. 1092 Decl *types.Function // Built-in function type declaration. 1093 Relation bool // Indicates if the built-in acts as a relation. 1094} 1095 1096// Expr creates a new expression for the built-in with the given operands. 1097func (b *Builtin) Expr(operands ...*Term) *Expr { 1098 ts := make([]*Term, len(operands)+1) 1099 ts[0] = NewTerm(b.Ref()) 1100 for i := range operands { 1101 ts[i+1] = operands[i] 1102 } 1103 return &Expr{ 1104 Terms: ts, 1105 } 1106} 1107 1108// Call creates a new term for the built-in with the given operands. 1109func (b *Builtin) Call(operands ...*Term) *Term { 1110 call := make(Call, len(operands)+1) 1111 call[0] = NewTerm(b.Ref()) 1112 for i := range operands { 1113 call[i+1] = operands[i] 1114 } 1115 return NewTerm(call) 1116} 1117 1118// Ref returns a Ref that refers to the built-in function. 1119func (b *Builtin) Ref() Ref { 1120 parts := strings.Split(b.Name, ".") 1121 ref := make(Ref, len(parts)) 1122 ref[0] = VarTerm(parts[0]) 1123 for i := 1; i < len(parts); i++ { 1124 ref[i] = StringTerm(parts[i]) 1125 } 1126 return ref 1127} 1128 1129// IsTargetPos returns true if a variable in the i-th position will be bound by 1130// evaluating the call expression. 1131func (b *Builtin) IsTargetPos(i int) bool { 1132 return len(b.Decl.Args()) == i 1133} 1134 1135func init() { 1136 BuiltinMap = map[string]*Builtin{} 1137 for _, b := range DefaultBuiltins { 1138 RegisterBuiltin(b) 1139 } 1140} 1141