-
Notifications
You must be signed in to change notification settings - Fork 8
/
model.go
1439 lines (1119 loc) · 46.8 KB
/
model.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package model provides an ELM-like data structure for an intermediate representation of CQL.
package model
import (
"github.com/google/cql/types"
"github.com/kylelemons/godebug/pretty"
)
// TODO(b/302631773): We should make this model 1:1 with ELM, utilize the language and terms
// used by ELM's spec and XSD even if we do not automatically generate go code from the XSD.
// As long as this is hand-rolled though, we should comply with go conventions, some of which
// being violated here such as Functions should not have a "get" prefix, and interface names
// should not be `I` prefixed.
// Library represents a base level CQL library, typically from one CQL file.
type Library struct {
Identifier *LibraryIdentifier
Usings []*Using
Includes []*Include
Parameters []*ParameterDef
CodeSystems []*CodeSystemDef
Concepts []*ConceptDef
Valuesets []*ValuesetDef
Codes []*CodeDef
Statements *Statements
}
func (l *Library) String() string {
return pretty.Sprint(l)
}
// IElement is an interface implemented by all CQL Element structs.
type IElement interface {
Row() int
Col() int
GetResultType() types.IType
}
// Element is the base for all CQL nodes.
type Element struct {
// TODO(b/298104167): Add common row, column.
ResultType types.IType
}
// Row returns the element's row in the source file.
func (t *Element) Row() int {
// TODO(b/298104167): Add row information.
return 0
}
// Col returns the element's column in the source file.
func (t *Element) Col() int {
// TODO(b/298104167): Add column information.
return 0
}
// GetResultType returns the type of the result which may be nil if unknown or not yet implemented.
func (t *Element) GetResultType() types.IType {
if t == nil {
return types.Unset
}
return t.ResultType
}
// DateTimePrecision represents the precision of a DateTimeValue (or soon, TimeValue).
// This is a string and not an integer value so that the default JSON marshaled value is readable
// and useful.
type DateTimePrecision string
const (
// UNSETDATETIMEPRECISION represents unknown precision.
UNSETDATETIMEPRECISION DateTimePrecision = ""
// YEAR represents year precision.
YEAR DateTimePrecision = "year"
// MONTH represents month precision.
MONTH DateTimePrecision = "month"
// WEEK represents a week precision. Not valid for Date / DateTime values.
WEEK DateTimePrecision = "week"
// DAY represents day precision.
DAY DateTimePrecision = "day"
// HOUR represents an hour precision.
HOUR DateTimePrecision = "hour"
// MINUTE represents a minute precision.
MINUTE DateTimePrecision = "minute"
// SECOND represents second precision.
SECOND DateTimePrecision = "second"
// MILLISECOND represents millisecond precision.
MILLISECOND DateTimePrecision = "millisecond"
)
// Unit represents the unit for a QuantityValue.
type Unit string
// TODO(b/319155752) Add support for UCUM values.
const (
// UNSETUNIT represents unknown unit.
UNSETUNIT Unit = ""
// ONEUNIT defines a base unit.
// This is often the result of dividing quantities with the same unit, canceling the unit out.
ONEUNIT Unit = "1"
// YEARUNIT represents year unit.
YEARUNIT Unit = "year"
// MONTHUNIT represents month unit.
MONTHUNIT Unit = "month"
// WEEKUNIT represents a week unit.
WEEKUNIT Unit = "week"
// DAYUNIT represents day unit.
DAYUNIT Unit = "day"
// HOURUNIT represents an hour unit.
HOURUNIT Unit = "hour"
// MINUTEUNIT represents a minute unit.
MINUTEUNIT Unit = "minute"
// SECONDUNIT represents second unit.
SECONDUNIT Unit = "second"
// MILLISECONDUNIT represents millisecond unit.
MILLISECONDUNIT Unit = "millisecond"
)
// AccessLevel defines the access modifier for a definition (ExpressionDef, ParameterDef,
// ValueSetDef). If the user does not specify an access modifier the default is public. If the
// library is unnamed then the interpreter should treat all definitions as private even if the
// access modifier is public.
type AccessLevel string
const (
// Public means other CQL libraries can access the definition.
Public AccessLevel = "PUBLIC"
// Private means only the local CQL libraries can access the definition.
Private AccessLevel = "PRIVATE"
)
// ValuesetDef is a named valueset definition that references a value set by ID.
type ValuesetDef struct {
*Element
Name string
ID string // 1..1
Version string // 0..1
CodeSystems []*CodeSystemRef // 0..*
AccessLevel AccessLevel
}
// CodeSystemDef is a named definition that references an external code system by ID and version.
type CodeSystemDef struct {
*Element
Name string
ID string // 1..1
Version string // 0..1
AccessLevel AccessLevel
}
// ConceptDef is a named definition that represents a terminology concept. It is made up of code(s)
// from one or more CodeSystems. At least one code is required.
type ConceptDef struct {
*Element
Name string
Codes []*CodeRef // 1..*
Display string // 0..1
AccessLevel AccessLevel
}
// CodeDef is a named definition that references an external code from a CodeSystem by ID.
type CodeDef struct {
*Element
Name string
Code string // 1..1
CodeSystem *CodeSystemRef // 0..1
Display string // 0..1
AccessLevel AccessLevel
}
// ParameterDef is a top-level statement that defines a named CQL parameter.
type ParameterDef struct {
*Element
Name string
Default IExpression
AccessLevel AccessLevel
}
// LibraryIdentifier for the library definition. This matches up with the ELM VersionedIdentifier
// (https://cql.hl7.org/04-logicalspecification.html#versionedidentifier). If nil then this is an
// unnamed library.
type LibraryIdentifier struct {
*Element
Local string
Qualified string // The full identifier of the library.
Version string
}
// Using defines a Using directive in CQL.
type Using struct {
*Element
LocalIdentifier string
// URI is the URL specified at the top of the modelinfo, for FHIR "http://hl7.org/fhir".
URI string
Version string
}
// Include defines an Include library statement in CQL.
type Include struct {
*Element
Identifier *LibraryIdentifier
}
// Statements is a collection of expression and function definitions, similar to the ELM structure.
type Statements struct {
Defs []IExpressionDef
}
// IExpressionDef is implemented by both ExpressionDef and FunctionDef.
type IExpressionDef interface {
IElement
GetName() string
GetContext() string
GetExpression() IExpression
GetAccessLevel() AccessLevel
}
// ExpressionDef is a top-level named definition of a CQL expression.
type ExpressionDef struct {
*Element
Name string
Context string
Expression IExpression
AccessLevel AccessLevel
}
// GetName returns the name of the definition.
func (e *ExpressionDef) GetName() string { return e.Name }
// GetContext returns the context of the definition.
func (e *ExpressionDef) GetContext() string { return e.Context }
// GetExpression returns the expression of the definition.
func (e *ExpressionDef) GetExpression() IExpression { return e.Expression }
// GetAccessLevel returns the access level of the definition.
func (e *ExpressionDef) GetAccessLevel() AccessLevel { return e.AccessLevel }
// FunctionDef represents a user defined function. All CQL built-in functions have their own struct
// defined below.
type FunctionDef struct {
// The body of the function is represented by the Expression field in the ExpressionDef. The
// return type is the ResultType set in the Element.
*ExpressionDef
Operands []OperandDef
Fluent bool
// External functions do not have a function body.
External bool
}
// OperandDef defines an operand for a user defined function.
type OperandDef struct {
// The type of the operand is the ResultType set in the Element.
*Expression
Name string
}
// All items below are for CQL expressions. All CQL expressions embed the base Expression struct
// and implement the IExpression interface. This allows for dynamic trees and sequences of
// expression types, matching CQL's structure.
// IExpression is an interface implemented by all CQL Expression structs
type IExpression interface {
IElement
isExpression()
}
// Expression is a base type containing common metadata for all CQL expression types.
type Expression struct {
*Element
}
func (e *Expression) isExpression() {}
// GetResultType returns the type of the result which may be nil if unknown or not yet implemented.
func (e *Expression) GetResultType() types.IType {
if e == nil {
return types.Unset
}
return e.Element.GetResultType()
}
// Literal represents a CQL literal.
type Literal struct {
*Expression
Value string
}
// An Interval expression.
type Interval struct {
*Expression
Low IExpression
High IExpression
// Either LowClosedExpression or LowInclusive should be set.
LowClosedExpression IExpression
LowInclusive bool
// Either HighClosedExpression or HighInclusive should be set.
HighClosedExpression IExpression
HighInclusive bool
}
// Quantity is an expression representation of a clinical quantity.
// https://cql.hl7.org/04-logicalspecification.html#quantity
type Quantity struct {
*Expression
Value float64
Unit Unit
}
// A Ratio is an expression that expresses a ratio between two Quantities.
// https://cql.hl7.org/04-logicalspecification.html#ratio
type Ratio struct {
*Expression
Numerator Quantity
Denominator Quantity
}
// A List expression.
type List struct {
*Expression
List []IExpression
}
// Code is a literal code selector.
type Code struct {
*Expression
System *CodeSystemRef
Code string
Display string
}
// Tuple represents a tuple (aka Structured Value), see
// https://cql.hl7.org/04-logicalspecification.html#tuple
type Tuple struct {
*Expression
Elements []*TupleElement
}
// TupleElement is an element in a CQL Tuple.
type TupleElement struct {
Name string
Value IExpression
}
// Instance represents an instance of a Class (aka Named Structured Value), see
// https://cql.hl7.org/04-logicalspecification.html#instance
type Instance struct {
*Expression
ClassType types.IType
Elements []*InstanceElement
}
// InstanceElement is an element in a CQL structure Instance.
type InstanceElement struct {
Name string
Value IExpression
}
// A MessageSeverity determines the type of the message and how it will be processed.
type MessageSeverity string
const (
// UNSETMESSAGESEVERITY denotes a message severity that shouldn't be allowed.
UNSETMESSAGESEVERITY MessageSeverity = ""
// TRACE denotes a message that should be printed with trace information.
TRACE MessageSeverity = "Trace"
// MESSAGE denotes a simple message that should be printed.
MESSAGE MessageSeverity = "Message"
// WARNING denotes a message that should log a warning to users.
WARNING MessageSeverity = "Warning"
// ERROR denotes an error message that should also halt execution.
ERROR MessageSeverity = "Error"
)
// Message is a CQL expression that represents a message, which is the equivalent of print in most
// other languages.
// https://cql.hl7.org/04-logicalspecification.html#message
type Message struct {
*Expression
Source IExpression
Condition IExpression
Code IExpression
Severity IExpression
Message IExpression
}
// A SortDirection determines what ordering to use for a query if sorting is enabled.
type SortDirection string
const (
// UNSETSORTDIRECTION denotes a sort direction that shouldn't be allowed.
UNSETSORTDIRECTION SortDirection = ""
// ASCENDING denotes query sorting from smallest to largest values.
ASCENDING SortDirection = "ASCENDING"
// DESCENDING denotes query sorting from largest to smallest values.
DESCENDING SortDirection = "DESCENDING"
)
// A Query expression.
type Query struct {
*Expression
Source []*AliasedSource
Let []*LetClause
Relationship []IRelationshipClause
Where IExpression
Sort *SortClause
Aggregate *AggregateClause // Only aggregate or Return can be populated, not both.
Return *ReturnClause
}
// LetClause is https://cql.hl7.org/04-logicalspecification.html#letclause.
type LetClause struct {
*Element
Expression IExpression
Identifier string
}
// IRelationshipClause is an interface that all With and Without meet.
type IRelationshipClause interface {
IElement
isRelationshipClause()
}
// RelationshipClause for a Query expression.
type RelationshipClause struct {
*Element
// Expression is the source of the inclusion clause.
Expression IExpression
Alias string
SuchThat IExpression
}
func (c *RelationshipClause) isRelationshipClause() {}
// With is https://cql.hl7.org/04-logicalspecification.html#with.
type With struct{ *RelationshipClause }
// Without is https://cql.hl7.org/04-logicalspecification.html#without.
type Without struct{ *RelationshipClause }
// SortClause for a Query expression.
type SortClause struct {
*Element
ByItems []ISortByItem
}
// AggregateClause for a Query expression.
type AggregateClause struct {
*Element
Expression IExpression
// Starting is the starting value of the aggregate variable. It is always set. If the user does
// not set it the parser will insert a null literal.
Starting IExpression
// Identifier is the alias for the aggregate variable.
Identifier string
Distinct bool
}
// ReturnClause for a Query expression.
type ReturnClause struct {
*Element
Expression IExpression
Distinct bool
}
// ISortByItem defines one or more items that a query can be sorted by.
// Follows format outlined in https://cql.hl7.org/elm/schema/expression.xsd.
type ISortByItem interface {
IElement
SortDirection() SortDirection
}
// SortByItem is the base abstract type for all query types.
type SortByItem struct {
*Element
Direction SortDirection
}
// SortDirection returns the direction of the sort, e.g. ASCENDING or DESCENDING.
func (s *SortByItem) SortDirection() SortDirection { return s.Direction }
// SortByDirection enables sorting non-tuple values by direction
type SortByDirection struct {
*SortByItem
}
// SortByColumn enables sorting by a given column and direction.
type SortByColumn struct {
*SortByItem
Path string
}
// SortByExpression enables sorting by an expression and direction.
type SortByExpression struct {
*SortByItem
SortExpression IExpression
}
// AliasedSource is a query source with an alias.
type AliasedSource struct {
*Expression
Alias string
Source IExpression
}
// Property gets a property from an expression. In ELM if the expression is an AliasRef then Scope
// is set instead of Source. In our model Source is set to AliasRef; there is no Scope.
type Property struct {
*Expression
Source IExpression
Path string
}
// A Retrieve expression.
type Retrieve struct {
*Expression
// TODO(b/312172420): Changing DataType to a named type would make life much easier.
DataType string
TemplateID string
CodeProperty string
// Codes is an expression that returns a list of code values.
Codes IExpression
}
// Case is a conditional case expression https://cql.hl7.org/04-logicalspecification.html#case.
type Case struct {
*Expression
// If comparand is provided it is compared against each When in the CaseItems. The CaseItems are
// expected to be of the same type or implicitly convertible to the same type as the Comparand. If
// the comparand is not provided then each When must have resultType boolean.
Comparand IExpression
CaseItem []*CaseItem
// Else must always be provided.
Else IExpression
}
// CaseItem is a single case item in a Case expression.
type CaseItem struct {
*Element
When IExpression
Then IExpression
}
// IfThenElse Elm expression from https://cql.hl7.org/04-logicalspecification.html#if
type IfThenElse struct {
*Expression
Condition IExpression
Then IExpression
Else IExpression
}
// MaxValue ELM expression from https://cql.hl7.org/04-logicalspecification.html#maxvalue
type MaxValue struct {
*Expression
ValueType types.IType
}
// MinValue ELM expression from https://cql.hl7.org/04-logicalspecification.html#minvalue
type MinValue struct {
*Expression
ValueType types.IType
}
// IUnaryExpression is an interface that all Unary expressions meet.
type IUnaryExpression interface {
IExpression
GetName() string
GetOperand() IExpression
SetOperand(IExpression)
// To differentiate IUnaryExpression from other interfaces like IBinaryExpression.
isUnaryExpression()
}
// UnaryExpression is a CQL expression that has one operand. The ELM representation may have
// additional operands.
type UnaryExpression struct {
*Expression
Operand IExpression
}
// GetOperand returns the unary expression's operand.
func (a *UnaryExpression) GetOperand() IExpression { return a.Operand }
// SetOperand sets the unary expression's operand.
func (a *UnaryExpression) SetOperand(operand IExpression) { a.Operand = operand }
func (a *UnaryExpression) isUnaryExpression() {}
// TODO(b/297089208): eventually consider moving all UnaryExpressions into their own file for
// organization.
// As is https://cql.hl7.org/09-b-cqlreference.html#as.
type As struct {
*UnaryExpression
AsTypeSpecifier types.IType
Strict bool
}
var _ IUnaryExpression = &As{}
// Is is https://cql.hl7.org/04-logicalspecification.html#is.
type Is struct {
*UnaryExpression
IsTypeSpecifier types.IType
}
var _ IUnaryExpression = &Is{}
// Exp is https://cql.hl7.org/04-logicalspecification.html#exp.
type Exp struct{ *UnaryExpression }
var _ IUnaryExpression = &Exp{}
// Negate is https://cql.hl7.org/04-logicalspecification.html#negate.
type Negate struct{ *UnaryExpression }
var _ IUnaryExpression = &Negate{}
// Truncate ELM expression https://cql.hl7.org/04-logicalspecification.html#truncate
type Truncate struct{ *UnaryExpression }
var _ IUnaryExpression = &Truncate{}
// Exists is https://cql.hl7.org/04-logicalspecification.html#exists.
type Exists struct{ *UnaryExpression }
var _ IUnaryExpression = &Exists{}
// Not is https://cql.hl7.org/04-logicalspecification.html#not.
type Not struct{ *UnaryExpression }
var _ IUnaryExpression = &Not{}
// First ELM expression from https://cql.hl7.org/04-logicalspecification.html#first
type First struct {
*UnaryExpression
// TODO(b/301606416): Support the orderBy parameter.
}
// Last ELM expression from https://cql.hl7.org/04-logicalspecification.html#last.
type Last struct {
*UnaryExpression
// TODO(b/301606416): Support the orderBy parameter.
}
var _ IUnaryExpression = &Last{}
// Abs is https://cql.hl7.org/04-logicalspecification.html#abs.
type Abs struct{ *UnaryExpression }
// Ceiling is https://cql.hl7.org/04-logicalspecification.html#ceiling.
type Ceiling struct{ *UnaryExpression }
// Floor is https://cql.hl7.org/04-logicalspecification.html#floor.
type Floor struct{ *UnaryExpression }
// Ln is https://cql.hl7.org/04-logicalspecification.html#ln.
type Ln struct{ *UnaryExpression }
// Precision is https://cql.hl7.org/04-logicalspecification.html#precision.
type Precision struct{ *UnaryExpression }
// SingletonFrom is https://cql.hl7.org/04-logicalspecification.html#singletonfrom.
type SingletonFrom struct{ *UnaryExpression }
var _ IUnaryExpression = &SingletonFrom{}
// Start is https://cql.hl7.org/04-logicalspecification.html#start.
type Start struct{ *UnaryExpression }
var _ IUnaryExpression = &Start{}
// End is https://cql.hl7.org/04-logicalspecification.html#end.
type End struct{ *UnaryExpression }
var _ IUnaryExpression = &End{}
// Predecessor ELM expression from https://cql.hl7.org/04-logicalspecification.html#predecessor.
type Predecessor struct{ *UnaryExpression }
var _ IUnaryExpression = &Predecessor{}
// Successor ELM expression from https://cql.hl7.org/04-logicalspecification.html#successor.
type Successor struct{ *UnaryExpression }
var _ IUnaryExpression = &Successor{}
// IsNull is https://cql.hl7.org/04-logicalspecification.html#isnull.
type IsNull struct{ *UnaryExpression }
var _ IUnaryExpression = &IsNull{}
// IsFalse is https://cql.hl7.org/04-logicalspecification.html#isfalse.
type IsFalse struct{ *UnaryExpression }
var _ IUnaryExpression = &IsFalse{}
// IsTrue is https://cql.hl7.org/04-logicalspecification.html#istrue.
type IsTrue struct{ *UnaryExpression }
var _ IUnaryExpression = &IsTrue{}
// ToBoolean ELM expression from https://cql.hl7.org/09-b-cqlreference.html#toboolean.
type ToBoolean struct{ *UnaryExpression }
var _ IUnaryExpression = &ToBoolean{}
// ToDateTime ELM expression from https://cql.hl7.org/04-logicalspecification.html#todatetime
type ToDateTime struct{ *UnaryExpression }
var _ IUnaryExpression = &ToDateTime{}
// ToDate ELM expression from https://cql.hl7.org/04-logicalspecification.html#todate.
type ToDate struct{ *UnaryExpression }
var _ IUnaryExpression = &ToDate{}
// ToDecimal ELM expression from https://cql.hl7.org/04-logicalspecification.html#todecimal.
type ToDecimal struct{ *UnaryExpression }
var _ IUnaryExpression = &ToDecimal{}
// ToLong ELM expression from https://cql.hl7.org/04-logicalspecification.html#tolong.
type ToLong struct{ *UnaryExpression }
var _ IUnaryExpression = &ToLong{}
// ToInteger ELM expression from https://cql.hl7.org/09-b-cqlreference.html#tointeger.
type ToInteger struct{ *UnaryExpression }
var _ IUnaryExpression = &ToInteger{}
// ToQuantity ELM expression from https://cql.hl7.org/04-logicalspecification.html#toquantity.
type ToQuantity struct{ *UnaryExpression }
var _ IUnaryExpression = &ToQuantity{}
// ToConcept ELM expression from https://cql.hl7.org/09-b-cqlreference.html#toconcept.
type ToConcept struct{ *UnaryExpression }
var _ IUnaryExpression = &ToConcept{}
// ToString ELM expression from https://cql.hl7.org/09-b-cqlreference.html#tostring.
type ToString struct{ *UnaryExpression }
var _ IUnaryExpression = &ToString{}
// ToTime ELM expression from https://cql.hl7.org/09-b-cqlreference.html#totime.
type ToTime struct{ *UnaryExpression }
var _ IUnaryExpression = &ToTime{}
// AllTrue ELM expression from https://cql.hl7.org/04-logicalspecification.html#alltrue.
// TODO: b/347346351 - In ELM it's modeled as an AggregateExpression, but for now we model it as an
// UnaryExpression since there is no way to set the AggregateExpression's "path" property for CQL as
// far as we can tell.
type AllTrue struct{ *UnaryExpression }
var _ IUnaryExpression = &AllTrue{}
// AnyTrue ELM expression from https://cql.hl7.org/04-logicalspecification.html#anytrue.
// TODO: b/347346351 - In ELM it's modeled as an AggregateExpression, but for now we model it as an
// UnaryExpression since there is no way to set the AggregateExpression's "path" property for CQL as
// far as we can tell.
type AnyTrue struct{ *UnaryExpression }
var _ IUnaryExpression = &AnyTrue{}
// Avg ELM expression from https://cql.hl7.org/04-logicalspecification.html#avg.
// TODO: b/347346351 - In ELM it's modeled as an AggregateExpression, but for now we model it as an
// UnaryExpression since there is no way to set the AggregateExpression's "path" property for CQL as
// far as we can tell.
type Avg struct{ *UnaryExpression }
// Count ELM expression from https://cql.hl7.org/09-b-cqlreference.html#count.
// TODO: b/347346351 - In ELM it's modeled as an AggregateExpression, but for now we model it as an
// UnaryExpression since there is no way to set the AggregateExpression's "path" property for CQL as
// far as we can tell.
type Count struct{ *UnaryExpression }
var _ IUnaryExpression = &Count{}
// Max ELM expression from https://cql.hl7.org/09-b-cqlreference.html#max.
// TODO: b/347346351 - In ELM it's modeled as an AggregateExpression, but for now we model it as an
// UnaryExpression since there is no way to set the AggregateExpression's "path" property for CQL as
// far as we can tell.
type Max struct{ *UnaryExpression }
// Min ELM expression from https://cql.hl7.org/09-b-cqlreference.html#min.
// TODO: b/347346351 - In ELM it's modeled as an AggregateExpression, but for now we model it as an
// UnaryExpression since there is no way to set the AggregateExpression's "path" property for CQL as
// far as we can tell.
type Min struct{ *UnaryExpression }
// Sum ELM expression from https://cql.hl7.org/09-b-cqlreference.html#sum.
// TODO: b/347346351 - In ELM it's modeled as an AggregateExpression, but for now we model it as an
// UnaryExpression since there is no way to set the AggregateExpression's "path" property for CQL as
// far as we can tell.
type Sum struct{ *UnaryExpression }
// Median ELM expression from https://cql.hl7.org/09-b-cqlreference.html#median
// TODO: b/347346351 - In ELM it's modeled as an AggregateExpression, but for now we model it as an
// UnaryExpression since there is no way to set the AggregateExpression's "path" property for CQL as
// far as we can tell.
type Median struct{ *UnaryExpression }
// CalculateAge CQL expression type
type CalculateAge struct {
*UnaryExpression
Precision DateTimePrecision
}
// BinaryExpression is a CQL expression that has two operands. The ELM representation may have
// additional operands (ex BinaryExpressionWithPrecision).
type BinaryExpression struct {
*Expression
Operands []IExpression
}
// Left returns the Left expression (first operand) of the BinaryExpression. If not present,
// returns nil.
func (b *BinaryExpression) Left() IExpression {
if len(b.Operands) < 1 {
return nil
}
return b.Operands[0]
}
// Right returns the Right expression (second operand) of the BinaryExpression. If not present,
// returns nil.
func (b *BinaryExpression) Right() IExpression {
if len(b.Operands) < 2 {
return nil
}
return b.Operands[1]
}
// SetOperands sets the BinaryExpression's operands.
func (b *BinaryExpression) SetOperands(left, right IExpression) {
b.Operands = []IExpression{left, right}
}
func (b *BinaryExpression) isBinaryExpression() {}
// IBinaryExpression is an interface that all Binary Expressions meet.
// Get prefixes are used below so as to not conflict with struct property names.
type IBinaryExpression interface {
IExpression
// GetName returns the name of the BinaryExpression.
GetName() string
// Left returns the Left expression (first operand) of the BinaryExpression. If not present,
// returns nil.
Left() IExpression
// Right returns the Right expression (second operand) of the BinaryExpression. If not present,
// returns nil.
Right() IExpression
SetOperands(left, right IExpression)
// To differentiate IBinaryExpression from other interfaces like INaryExpression.
isBinaryExpression()
}
// CanConvertQuantity ELM Expression from https://cql.hl7.org/04-logicalspecification.html#canconvertquantity.
type CanConvertQuantity struct{ *BinaryExpression }
var _ IBinaryExpression = &CanConvertQuantity{}
// Equal ELM Expression from https://cql.hl7.org/04-logicalspecification.html#equal.
type Equal struct{ *BinaryExpression }
var _ IBinaryExpression = &Equal{}
// Equivalent ELM Expression from https://cql.hl7.org/04-logicalspecification.html#equivalent.
type Equivalent struct{ *BinaryExpression }
var _ IBinaryExpression = &Equivalent{}
// Less ELM Expression https://cql.hl7.org/04-logicalspecification.html#less
type Less struct{ *BinaryExpression }
var _ IBinaryExpression = &Less{}
// Greater ELM Expression https://cql.hl7.org/04-logicalspecification.html#greater
type Greater struct{ *BinaryExpression }
var _ IBinaryExpression = &Greater{}
// LessOrEqual ELM Expression https://cql.hl7.org/04-logicalspecification.html#lessorequal
type LessOrEqual struct{ *BinaryExpression }
var _ IBinaryExpression = &LessOrEqual{}
// GreaterOrEqual ELM Expression https://cql.hl7.org/04-logicalspecification.html#greaterorequal
type GreaterOrEqual struct{ *BinaryExpression }
var _ IBinaryExpression = &GreaterOrEqual{}
// And is https://cql.hl7.org/04-logicalspecification.html#and.
type And struct{ *BinaryExpression }
// Or is https://cql.hl7.org/04-logicalspecification.html#or
type Or struct{ *BinaryExpression }
// XOr is https://cql.hl7.org/04-logicalspecification.html#xor
type XOr struct{ *BinaryExpression }
// Implies is https://cql.hl7.org/04-logicalspecification.html#implies
type Implies struct{ *BinaryExpression }
// Add ELM Expression https://cql.hl7.org/04-logicalspecification.html#add
type Add struct{ *BinaryExpression }
// Subtract ELM Expression https://cql.hl7.org/04-logicalspecification.html#subtract
type Subtract struct{ *BinaryExpression }
// Multiply ELM Expression https://cql.hl7.org/04-logicalspecification.html#multiply
type Multiply struct{ *BinaryExpression }
// Divide ELM Expression https://cql.hl7.org/04-logicalspecification.html#divide
type Divide struct{ *BinaryExpression }
// Modulo ELM Expression https://cql.hl7.org/04-logicalspecification.html#modulo
type Modulo struct{ *BinaryExpression }
// Power ELM Expression https://cql.hl7.org/04-logicalspecification.html#power
type Power struct{ *BinaryExpression }
// TruncatedDivide ELM Expression https://cql.hl7.org/04-logicalspecification.html#truncateddivide
type TruncatedDivide struct{ *BinaryExpression }
// Except ELM Expression https://cql.hl7.org/04-logicalspecification.html#except
// Except is a nary expression but we are only supporting two operands.
type Except struct{ *BinaryExpression }
// Intersect ELM Expression https://cql.hl7.org/04-logicalspecification.html#intersect
// Intersect is a nary expression but we are only supporting two operands.
type Intersect struct{ *BinaryExpression }
// Union ELM Expression https://cql.hl7.org/04-logicalspecification.html#union
// Union is a nary expression but we are only supporting two operands.
type Union struct{ *BinaryExpression }
// Split ELM Expression https://cql.hl7.org/04-logicalspecification.html#split
// Split is an OperatorExpression in ELM, but we're modeling it as a BinaryExpression since in CQL
// it always takes two arguments.
type Split struct{ *BinaryExpression }
// Indexer ELM Expression https://cql.hl7.org/04-logicalspecification.html#indexer.
type Indexer struct{ *BinaryExpression }
// BinaryExpressionWithPrecision represents a BinaryExpression with a precision property.
type BinaryExpressionWithPrecision struct {
*BinaryExpression
// Precision returns the precision of this BinaryExpression. It must be one of the following:
// https://cql.hl7.org/19-l-cqlsyntaxdiagrams.html#dateTimePrecision.
Precision DateTimePrecision
}
// Before ELM expression from https://cql.hl7.org/04-logicalspecification.html#before.
type Before BinaryExpressionWithPrecision
var _ IBinaryExpression = &Before{}
// After ELM expression from https://cql.hl7.org/04-logicalspecification.html#after.
type After BinaryExpressionWithPrecision
// SameOrBefore ELM expression from https://cql.hl7.org/04-logicalspecification.html#sameorbefore.
type SameOrBefore BinaryExpressionWithPrecision
// SameOrAfter ELM expression from https://cql.hl7.org/04-logicalspecification.html#sameorafter.
type SameOrAfter BinaryExpressionWithPrecision
// DifferenceBetween ELM expression from https://cql.hl7.org/04-logicalspecification.html#differencebetween.
type DifferenceBetween BinaryExpressionWithPrecision
// In ELM expression from https://cql.hl7.org/04-logicalspecification.html#in.
type In BinaryExpressionWithPrecision
// IncludedIn ELM expression from https://cql.hl7.org/04-logicalspecification.html#included-in.
type IncludedIn BinaryExpressionWithPrecision
// InCodeSystem is https://cql.hl7.org/09-b-cqlreference.html#in-codesystem.
// This is not technically 1:1 with the ELM definition. The ELM defines Code, CodeSystem and
// CodeSystemExpression arguments, the last being seemingly impossible to set for for now we're
// treating this as a binary expression.