functions.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package ottl // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
  4. import (
  5. "errors"
  6. "fmt"
  7. "reflect"
  8. "strings"
  9. "github.com/iancoleman/strcase"
  10. )
  11. type PathExpressionParser[K any] func(*Path) (GetSetter[K], error)
  12. type EnumParser func(*EnumSymbol) (*Enum, error)
  13. type Enum int64
  14. func (p *Parser[K]) newFunctionCall(ed editor) (Expr[K], error) {
  15. f, ok := p.functions[ed.Function]
  16. if !ok {
  17. return Expr[K]{}, fmt.Errorf("undefined function %q", ed.Function)
  18. }
  19. defaultArgs := f.CreateDefaultArguments()
  20. var args Arguments
  21. // A nil value indicates the function takes no arguments.
  22. if defaultArgs != nil {
  23. // Pointer values are necessary to fulfill the Go reflection
  24. // settability requirements. Non-pointer values are not
  25. // modifiable through reflection.
  26. if reflect.TypeOf(defaultArgs).Kind() != reflect.Pointer {
  27. return Expr[K]{}, fmt.Errorf("factory for %q must return a pointer to an Arguments value in its CreateDefaultArguments method", ed.Function)
  28. }
  29. args = reflect.New(reflect.ValueOf(defaultArgs).Elem().Type()).Interface()
  30. err := p.buildArgs(ed, reflect.ValueOf(args).Elem())
  31. if err != nil {
  32. return Expr[K]{}, fmt.Errorf("error while parsing arguments for call to %q: %w", ed.Function, err)
  33. }
  34. }
  35. fn, err := f.CreateFunction(FunctionContext{Set: p.telemetrySettings}, args)
  36. if err != nil {
  37. return Expr[K]{}, fmt.Errorf("couldn't create function: %w", err)
  38. }
  39. return Expr[K]{exprFunc: fn}, err
  40. }
  41. func (p *Parser[K]) buildArgs(ed editor, argsVal reflect.Value) error {
  42. requiredArgs := 0
  43. seenNamed := false
  44. for i := 0; i < len(ed.Arguments); i++ {
  45. if !seenNamed && ed.Arguments[i].Name != "" {
  46. seenNamed = true
  47. } else if seenNamed && ed.Arguments[i].Name == "" {
  48. return errors.New("unnamed argument used after named argument")
  49. }
  50. }
  51. for i := 0; i < argsVal.NumField(); i++ {
  52. if !strings.HasPrefix(argsVal.Field(i).Type().Name(), "Optional") {
  53. requiredArgs++
  54. }
  55. }
  56. if len(ed.Arguments) < requiredArgs || len(ed.Arguments) > argsVal.NumField() {
  57. return fmt.Errorf("incorrect number of arguments. Expected: %d Received: %d", argsVal.NumField(), len(ed.Arguments))
  58. }
  59. for i, edArg := range ed.Arguments {
  60. var field reflect.Value
  61. var fieldType reflect.Type
  62. var isOptional bool
  63. var arg argument
  64. if edArg.Name == "" {
  65. field = argsVal.Field(i)
  66. fieldType = field.Type()
  67. isOptional = strings.HasPrefix(fieldType.Name(), "Optional")
  68. arg = ed.Arguments[i]
  69. } else {
  70. field = argsVal.FieldByName(strcase.ToCamel(edArg.Name))
  71. if !field.IsValid() {
  72. return fmt.Errorf("no such parameter: %s", edArg.Name)
  73. }
  74. fieldType = field.Type()
  75. isOptional = strings.HasPrefix(fieldType.Name(), "Optional")
  76. arg = edArg
  77. }
  78. var val any
  79. var manager optionalManager
  80. var err error
  81. var ok bool
  82. if isOptional {
  83. manager, ok = field.Interface().(optionalManager)
  84. if !ok {
  85. return errors.New("optional type is not manageable by the OTTL parser. This is an error in the OTTL")
  86. }
  87. fieldType = manager.get().Type()
  88. }
  89. switch {
  90. case strings.HasPrefix(fieldType.Name(), "FunctionGetter"):
  91. var name string
  92. switch {
  93. case arg.Value.Enum != nil:
  94. name = string(*arg.Value.Enum)
  95. case arg.Value.FunctionName != nil:
  96. name = *arg.Value.FunctionName
  97. default:
  98. return fmt.Errorf("invalid function name given")
  99. }
  100. f, ok := p.functions[name]
  101. if !ok {
  102. return fmt.Errorf("undefined function %s", name)
  103. }
  104. val = StandardFunctionGetter[K]{FCtx: FunctionContext{Set: p.telemetrySettings}, Fact: f}
  105. case fieldType.Kind() == reflect.Slice:
  106. val, err = p.buildSliceArg(arg.Value, fieldType)
  107. default:
  108. val, err = p.buildArg(arg.Value, fieldType)
  109. }
  110. if err != nil {
  111. return fmt.Errorf("invalid argument at position %v: %w", i, err)
  112. }
  113. if isOptional {
  114. field.Set(manager.set(val))
  115. } else {
  116. field.Set(reflect.ValueOf(val))
  117. }
  118. }
  119. return nil
  120. }
  121. func (p *Parser[K]) buildSliceArg(argVal value, argType reflect.Type) (any, error) {
  122. name := argType.Elem().Name()
  123. switch {
  124. case name == reflect.Uint8.String():
  125. if argVal.Bytes == nil {
  126. return nil, fmt.Errorf("slice parameter must be a byte slice literal")
  127. }
  128. return ([]byte)(*argVal.Bytes), nil
  129. case name == reflect.String.String():
  130. arg, err := buildSlice[string](argVal, argType, p.buildArg, name)
  131. if err != nil {
  132. return nil, err
  133. }
  134. return arg, nil
  135. case name == reflect.Float64.String():
  136. arg, err := buildSlice[float64](argVal, argType, p.buildArg, name)
  137. if err != nil {
  138. return nil, err
  139. }
  140. return arg, nil
  141. case name == reflect.Int64.String():
  142. arg, err := buildSlice[int64](argVal, argType, p.buildArg, name)
  143. if err != nil {
  144. return nil, err
  145. }
  146. return arg, nil
  147. case strings.HasPrefix(name, "Getter"):
  148. arg, err := buildSlice[Getter[K]](argVal, argType, p.buildArg, name)
  149. if err != nil {
  150. return nil, err
  151. }
  152. return arg, nil
  153. case strings.HasPrefix(name, "PMapGetter"):
  154. arg, err := buildSlice[PMapGetter[K]](argVal, argType, p.buildArg, name)
  155. if err != nil {
  156. return nil, err
  157. }
  158. return arg, nil
  159. case strings.HasPrefix(name, "StringGetter"):
  160. arg, err := buildSlice[StringGetter[K]](argVal, argType, p.buildArg, name)
  161. if err != nil {
  162. return nil, err
  163. }
  164. return arg, nil
  165. case strings.HasPrefix(name, "StringLikeGetter"):
  166. arg, err := buildSlice[StringLikeGetter[K]](argVal, argType, p.buildArg, name)
  167. if err != nil {
  168. return nil, err
  169. }
  170. return arg, nil
  171. case strings.HasPrefix(name, "FloatGetter"):
  172. arg, err := buildSlice[FloatGetter[K]](argVal, argType, p.buildArg, name)
  173. if err != nil {
  174. return nil, err
  175. }
  176. return arg, nil
  177. case strings.HasPrefix(name, "FloatLikeGetter"):
  178. arg, err := buildSlice[FloatLikeGetter[K]](argVal, argType, p.buildArg, name)
  179. if err != nil {
  180. return nil, err
  181. }
  182. return arg, nil
  183. case strings.HasPrefix(name, "IntGetter"):
  184. arg, err := buildSlice[IntGetter[K]](argVal, argType, p.buildArg, name)
  185. if err != nil {
  186. return nil, err
  187. }
  188. return arg, nil
  189. case strings.HasPrefix(name, "IntLikeGetter"):
  190. arg, err := buildSlice[IntLikeGetter[K]](argVal, argType, p.buildArg, name)
  191. if err != nil {
  192. return nil, err
  193. }
  194. return arg, nil
  195. case strings.HasPrefix(name, "DurationGetter"):
  196. arg, err := buildSlice[DurationGetter[K]](argVal, argType, p.buildArg, name)
  197. if err != nil {
  198. return nil, err
  199. }
  200. return arg, nil
  201. case strings.HasPrefix(name, "TimeGetter"):
  202. arg, err := buildSlice[TimeGetter[K]](argVal, argType, p.buildArg, name)
  203. if err != nil {
  204. return nil, err
  205. }
  206. return arg, nil
  207. default:
  208. return nil, fmt.Errorf("unsupported slice type %q for function", argType.Elem().Name())
  209. }
  210. }
  211. // Handle interfaces that can be passed as arguments to OTTL functions.
  212. func (p *Parser[K]) buildArg(argVal value, argType reflect.Type) (any, error) {
  213. name := argType.Name()
  214. switch {
  215. case strings.HasPrefix(name, "Setter"):
  216. fallthrough
  217. case strings.HasPrefix(name, "GetSetter"):
  218. if argVal.Literal == nil || argVal.Literal.Path == nil {
  219. return nil, fmt.Errorf("must be a Path")
  220. }
  221. arg, err := p.pathParser(argVal.Literal.Path)
  222. if err != nil {
  223. return nil, err
  224. }
  225. return arg, nil
  226. case strings.HasPrefix(name, "Getter"):
  227. arg, err := p.newGetter(argVal)
  228. if err != nil {
  229. return nil, err
  230. }
  231. return arg, nil
  232. case strings.HasPrefix(name, "StringGetter"):
  233. arg, err := p.newGetter(argVal)
  234. if err != nil {
  235. return nil, err
  236. }
  237. return StandardStringGetter[K]{Getter: arg.Get}, nil
  238. case strings.HasPrefix(name, "StringLikeGetter"):
  239. arg, err := p.newGetter(argVal)
  240. if err != nil {
  241. return nil, err
  242. }
  243. return StandardStringLikeGetter[K]{Getter: arg.Get}, nil
  244. case strings.HasPrefix(name, "FloatGetter"):
  245. arg, err := p.newGetter(argVal)
  246. if err != nil {
  247. return nil, err
  248. }
  249. return StandardFloatGetter[K]{Getter: arg.Get}, nil
  250. case strings.HasPrefix(name, "FloatLikeGetter"):
  251. arg, err := p.newGetter(argVal)
  252. if err != nil {
  253. return nil, err
  254. }
  255. return StandardFloatLikeGetter[K]{Getter: arg.Get}, nil
  256. case strings.HasPrefix(name, "IntGetter"):
  257. arg, err := p.newGetter(argVal)
  258. if err != nil {
  259. return nil, err
  260. }
  261. return StandardIntGetter[K]{Getter: arg.Get}, nil
  262. case strings.HasPrefix(name, "IntLikeGetter"):
  263. arg, err := p.newGetter(argVal)
  264. if err != nil {
  265. return nil, err
  266. }
  267. return StandardIntLikeGetter[K]{Getter: arg.Get}, nil
  268. case strings.HasPrefix(name, "PMapGetter"):
  269. arg, err := p.newGetter(argVal)
  270. if err != nil {
  271. return nil, err
  272. }
  273. return StandardPMapGetter[K]{Getter: arg.Get}, nil
  274. case strings.HasPrefix(name, "DurationGetter"):
  275. arg, err := p.newGetter(argVal)
  276. if err != nil {
  277. return nil, err
  278. }
  279. return StandardDurationGetter[K]{Getter: arg.Get}, nil
  280. case strings.HasPrefix(name, "TimeGetter"):
  281. arg, err := p.newGetter(argVal)
  282. if err != nil {
  283. return nil, err
  284. }
  285. return StandardTimeGetter[K]{Getter: arg.Get}, nil
  286. case name == "Enum":
  287. arg, err := p.enumParser(argVal.Enum)
  288. if err != nil {
  289. return nil, fmt.Errorf("must be an Enum")
  290. }
  291. return *arg, nil
  292. case name == reflect.String.String():
  293. if argVal.String == nil {
  294. return nil, fmt.Errorf("must be a string")
  295. }
  296. return *argVal.String, nil
  297. case name == reflect.Float64.String():
  298. if argVal.Literal == nil || argVal.Literal.Float == nil {
  299. return nil, fmt.Errorf("must be a float")
  300. }
  301. return *argVal.Literal.Float, nil
  302. case name == reflect.Int64.String():
  303. if argVal.Literal == nil || argVal.Literal.Int == nil {
  304. return nil, fmt.Errorf("must be an int")
  305. }
  306. return *argVal.Literal.Int, nil
  307. case name == reflect.Bool.String():
  308. if argVal.Bool == nil {
  309. return nil, fmt.Errorf("must be a bool")
  310. }
  311. return bool(*argVal.Bool), nil
  312. default:
  313. return nil, fmt.Errorf("unsupported argument type: %s", name)
  314. }
  315. }
  316. type buildArgFunc func(value, reflect.Type) (any, error)
  317. func buildSlice[T any](argVal value, argType reflect.Type, buildArg buildArgFunc, name string) (any, error) {
  318. if argVal.List == nil {
  319. return nil, fmt.Errorf("must be a list of type %v", name)
  320. }
  321. vals := []T{}
  322. values := argVal.List.Values
  323. for j := 0; j < len(values); j++ {
  324. untypedVal, err := buildArg(values[j], argType.Elem())
  325. if err != nil {
  326. return nil, fmt.Errorf("error while parsing list argument at index %v: %w", j, err)
  327. }
  328. val, ok := untypedVal.(T)
  329. if !ok {
  330. return nil, fmt.Errorf("invalid element type at list index %v, must be of type %v", j, name)
  331. }
  332. vals = append(vals, val)
  333. }
  334. return vals, nil
  335. }
  336. // optionalManager provides a way for the parser to handle Optional[T] structs
  337. // without needing to know the concrete type of T, which is inaccessible through
  338. // the reflect package.
  339. // Would likely be resolved by https://github.com/golang/go/issues/54393.
  340. type optionalManager interface {
  341. // set takes a non-reflection value and returns a reflect.Value of
  342. // an Optional[T] struct with this value set.
  343. set(val any) reflect.Value
  344. // get returns a reflect.Value value of the value contained within
  345. // an Optional[T]. This allows obtaining a reflect.Type for T.
  346. get() reflect.Value
  347. }
  348. type Optional[T any] struct {
  349. val T
  350. hasValue bool
  351. }
  352. // This is called only by reflection.
  353. // nolint:unused
  354. func (o Optional[T]) set(val any) reflect.Value {
  355. return reflect.ValueOf(Optional[T]{
  356. val: val.(T),
  357. hasValue: true,
  358. })
  359. }
  360. func (o Optional[T]) IsEmpty() bool {
  361. return !o.hasValue
  362. }
  363. func (o Optional[T]) Get() T {
  364. return o.val
  365. }
  366. func (o Optional[T]) get() reflect.Value {
  367. // `(reflect.Value).Call` will create a reflect.Value containing a zero-valued T.
  368. // Trying to create a reflect.Value for T by calling reflect.TypeOf or
  369. // reflect.ValueOf on an empty T value creates an invalid reflect.Value object,
  370. // the `Call` method appears to do extra processing to capture the type.
  371. return reflect.ValueOf(o).MethodByName("Get").Call(nil)[0]
  372. }
  373. // Allows creating an Optional with a value already populated for use in testing
  374. // OTTL functions.
  375. func NewTestingOptional[T any](val T) Optional[T] {
  376. return Optional[T]{
  377. val: val,
  378. hasValue: true,
  379. }
  380. }