Skip to content

Commit

Permalink
Decoder optimization - Remove orElse from all 3 versions of Morphir I…
Browse files Browse the repository at this point in the history
…R Decoders (#387)

* TagBasedParser

* MorphirJsonDecodingSupport

* MorphirJsonDecodingSupport

* MorphirJsonDecodingSupport

* MorphirJsonDecodingSupport

* MorphirJsonDecodingSupport

* MorphirJsonDecodingSupportV1

* MorphirJsonDecodingSupportV1

* more changes

* more changes

* MorphirJsonDecodingSupportV2

* some more

* more changes

* more changes version 2
  • Loading branch information
dmitrykozinets authored Sep 6, 2023
1 parent 618220c commit 1e742a8
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 138 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
package org.finos.morphir.ir
package json

import org.finos.morphir.naming.*
import zio.*
import zio.json.*
import zio._
import zio.json._
import zio.json.ast.Json
import org.finos.morphir.naming._
import org.finos.morphir.ir.distribution.Distribution
import org.finos.morphir.ir.distribution.Distribution.*
import org.finos.morphir.ir.distribution.Distribution._
import org.finos.morphir.ir.Literal.Literal
import org.finos.morphir.ir.Literal.Literal.*
import org.finos.morphir.ir.Literal.Literal._
import org.finos.morphir.ir.PackageModule.{
Definition as PackageDefinition,
Specification as PackageSpecification,
USpecification as UPackageSpecification
Definition => PackageDefinition,
Specification => PackageSpecification,
USpecification => UPackageSpecification
}
import org.finos.morphir.ir.Type.{Constructors, Type, Definition as TypeDefinition, Specification as TypeSpecification}
import org.finos.morphir.ir.Value.{Definition as ValueDefinition, Specification as ValueSpecification}
import org.finos.morphir.ir.Value.{Value, *}
import org.finos.morphir.ir.module.{Definition as ModuleDefinition, Specification as ModuleSpecification}
import zio.json.JsonDecoder.{JsonError, UnsafeJson}
import zio.json.internal.RetractReader

import java.nio.CharBuffer
import org.finos.morphir.ir.Type.{Constructors, Definition => TypeDefinition, Specification => TypeSpecification, Type}
import org.finos.morphir.ir.Value.{Definition => ValueDefinition, Specification => ValueSpecification}
import org.finos.morphir.ir.Value.{Value, _}
import org.finos.morphir.ir.module.{Definition => ModuleDefinition, Specification => ModuleSpecification}

import scala.annotation.{nowarn, unused}
import scala.util.control.Breaks._

trait MorphirJsonDecodingSupport {
implicit val unitDecoder: JsonDecoder[Unit] = Json.decoder.map(_ => ())
Expand Down Expand Up @@ -78,12 +74,14 @@ trait MorphirJsonDecodingSupport {
}

implicit def literalDecoder: JsonDecoder[Literal] =
literalBoolDecoder.widen[Literal] orElse
literalCharDecoder.widen[Literal] orElse
literalDecimalDecoder.widen[Literal] orElse
literalFloatDecoder.widen[Literal] orElse
literalStringDecoder.widen[Literal] orElse
literalWholeNumberDecoder.widen[Literal]
zio.json.TagBasedParser[Literal] {
case "BoolLiteral" => literalBoolDecoder.widen[Literal]
case "CharLiteral" => literalCharDecoder.widen[Literal]
case "DecimalLiteral" => literalDecimalDecoder.widen[Literal]
case "FloatLiteral" => literalFloatDecoder.widen[Literal]
case "StringLiteral" => literalStringDecoder.widen[Literal]
case "WholeNumberLiteral" => literalWholeNumberDecoder.widen[Literal]
}

implicit def fieldDecoder[A: JsonDecoder]: JsonDecoder[Field[A]] = {
final case class FieldLike(name: Name, tpe: A)
Expand Down Expand Up @@ -177,15 +175,16 @@ trait MorphirJsonDecodingSupport {
)
}

@nowarn("msg=Implicit resolves to enclosing method typeDecoder")
implicit def typeDecoder[A: JsonDecoder]: JsonDecoder[Type[A]] =
unitCaseTypeDecoder[A].widen[Type[A]] orElse
variableCaseTypeDecoder[A].widen[Type[A]] orElse
tupleCaseTypeDecoder[A].widen[Type[A]] orElse
recordCaseTypeDecoder[A].widen[Type[A]] orElse
extensibleRecordCaseTypeDecoder[A].widen[Type[A]] orElse
functionCaseTypeDecoder[A].widen[Type[A]] orElse
referenceCaseTypeDecoder[A].widen[Type[A]]
zio.json.TagBasedParser[Type[A]] {
case "ExtensibleRecord" => extensibleRecordCaseTypeDecoder[A].widen
case "Function" => functionCaseTypeDecoder[A].widen
case "Record" => recordCaseTypeDecoder[A].widen
case "Reference" => referenceCaseTypeDecoder[A].widen
case "Tuple" => tupleCaseTypeDecoder[A].widen
case "Unit" => unitCaseTypeDecoder[A].widen
case "Variable" => variableCaseTypeDecoder[A].widen
}

implicit def constructorDecoder[A: JsonDecoder]: JsonDecoder[Constructors[A]] =
JsonDecoder.list[(Name, Chunk[(Name, Type[A])])].map {
Expand All @@ -210,8 +209,10 @@ trait MorphirJsonDecodingSupport {
}

implicit def typeDefinitionDecoder[A: JsonDecoder]: JsonDecoder[TypeDefinition[A]] =
typeDefinitionTypeAliasDecoder[A].widen[TypeDefinition[A]] orElse
typeDefinitionCustomTypeDecoder[A].widen[TypeDefinition[A]]
zio.json.TagBasedParser[TypeDefinition[A]] {
case "CustomTypeDefinition" => typeDefinitionCustomTypeDecoder[A].widen
case "TypeAliasDefinition" => typeDefinitionTypeAliasDecoder[A].widen
}

implicit def typeSpecificationTypeAliasDecoder[A: JsonDecoder]
: JsonDecoder[TypeSpecification.TypeAliasSpecification[A]] =
Expand Down Expand Up @@ -240,9 +241,11 @@ trait MorphirJsonDecodingSupport {
}

implicit def typeSpecificationDecoder[A: JsonDecoder]: JsonDecoder[TypeSpecification[A]] =
typeSpecificationTypeAliasDecoder[A].widen[TypeSpecification[A]] orElse
typeSpecificationCustomTypeDecoder[A].widen[TypeSpecification[A]] orElse
typeSpecificationOpaqueTypeDecoder.widen[TypeSpecification[A]]
zio.json.TagBasedParser[TypeSpecification[A]] {
case "CustomTypeSpecification" => typeSpecificationCustomTypeDecoder[A].widen
case "OpaqueTypeSpecification" => typeSpecificationOpaqueTypeDecoder.widen
case "TypeAliasSpecification" => typeSpecificationTypeAliasDecoder[A].widen
}

implicit def valueDefinitionDecoder[TA: JsonDecoder, VA: JsonDecoder]: JsonDecoder[ValueDefinition[TA, VA]] = {
lazy val dec: JsonDecoder[ValueDefinition[TA, VA]] = DeriveJsonDecoder.gen
Expand Down Expand Up @@ -328,14 +331,16 @@ trait MorphirJsonDecodingSupport {
}

implicit def patternDecoder[A: JsonDecoder]: JsonDecoder[Pattern[A]] =
patternEmptyListPatternDecoder[A].widen[Pattern[A]] orElse
patternWildcardPatternDecoder[A].widen[Pattern[A]] orElse
patternUnitPatternDecoder[A].widen[Pattern[A]] orElse
patternLiteralPatternDecoder[A].widen[Pattern[A]] orElse
patternTuplePatternDecoder[A].widen[Pattern[A]] orElse
patternHeadTailPatternDecoder[A].widen[Pattern[A]] orElse
patternConstructorPatternDecoder[A].widen[Pattern[A]] orElse
patternAsPatternDecoder[A].widen[Pattern[A]]
zio.json.TagBasedParser[Pattern[A]] {
case "AsPattern" => patternAsPatternDecoder[A].widen
case "ConstructorPattern" => patternConstructorPatternDecoder[A].widen
case "EmptyListPattern" => patternEmptyListPatternDecoder[A].widen
case "HeadTailPattern" => patternHeadTailPatternDecoder[A].widen
case "LiteralPattern" => patternLiteralPatternDecoder[A].widen
case "TuplePattern" => patternTuplePatternDecoder[A].widen
case "UnitPattern" => patternUnitPatternDecoder[A].widen
case "WildcardPattern" => patternWildcardPatternDecoder[A].widen
}

implicit def moduleSpecificationDecoder[TA](implicit
@unused decoder: JsonDecoder[TA]
Expand Down Expand Up @@ -569,7 +574,6 @@ trait MorphirJsonDecodingSupport {
)
}

@nowarn("msg=Implicit resolves to enclosing method valueDecoder")
implicit def valueDecoder[TA: JsonDecoder, VA: JsonDecoder]: JsonDecoder[Value[TA, VA]] =
zio.json.TagBasedParser[Value[TA, VA]] {
case "Constructor" => constructorValueJsonDecoder[VA].widen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,14 @@ trait MorphirJsonDecodingSupportV1 {
}

implicit def literalDecoder: JsonDecoder[Literal] =
literalBoolDecoder.widen[Literal] orElse
literalCharDecoder.widen[Literal] orElse
literalDecimalDecoder.widen[Literal] orElse
literalFloatDecoder.widen[Literal] orElse
literalStringDecoder.widen[Literal] orElse
literalWholeNumberDecoder.widen[Literal]
zio.json.TagBasedParser[Literal] {
case "bool_literal" => literalBoolDecoder.widen[Literal]
case "char_literal" => literalCharDecoder.widen[Literal]
case "decimal_literal" => literalDecimalDecoder.widen[Literal]
case "float_literal" => literalFloatDecoder.widen[Literal]
case "string_literal" => literalStringDecoder.widen[Literal]
case "int_literal" => literalWholeNumberDecoder.widen[Literal]
}

implicit def fieldDecoder[A: JsonDecoder]: JsonDecoder[Field[A]] =
JsonDecoder.tuple2[Name, A].map { case (name, fieldType) => Field(name, fieldType) }
Expand Down Expand Up @@ -169,15 +171,16 @@ trait MorphirJsonDecodingSupportV1 {
)
}

@nowarn("msg=Implicit resolves to enclosing method typeDecoder")
implicit def typeDecoder[A: JsonDecoder]: JsonDecoder[Type[A]] =
unitCaseTypeDecoder[A].widen[Type[A]] orElse
variableCaseTypeDecoder[A].widen[Type[A]] orElse
tupleCaseTypeDecoder[A].widen[Type[A]] orElse
recordCaseTypeDecoder[A].widen[Type[A]] orElse
extensibleRecordCaseTypeDecoder[A].widen[Type[A]] orElse
functionCaseTypeDecoder[A].widen[Type[A]] orElse
referenceCaseTypeDecoder[A].widen[Type[A]]
zio.json.TagBasedParser[Type[A]] {
case "extensible_record" => extensibleRecordCaseTypeDecoder[A].widen
case "function" => functionCaseTypeDecoder[A].widen
case "record" => recordCaseTypeDecoder[A].widen
case "reference" => referenceCaseTypeDecoder[A].widen
case "tuple" => tupleCaseTypeDecoder[A].widen
case "unit" => unitCaseTypeDecoder[A].widen
case "variable" => variableCaseTypeDecoder[A].widen
}

implicit def constructorDecoder[A: JsonDecoder]: JsonDecoder[Constructors[A]] =
JsonDecoder.list[(Name, Chunk[(Name, Type[A])])].map {
Expand All @@ -202,8 +205,10 @@ trait MorphirJsonDecodingSupportV1 {
}

implicit def typeDefinitionDecoder[A: JsonDecoder]: JsonDecoder[TypeDefinition[A]] =
typeDefinitionTypeAliasDecoder[A].widen[TypeDefinition[A]] orElse
typeDefinitionCustomTypeDecoder[A].widen[TypeDefinition[A]]
zio.json.TagBasedParser[TypeDefinition[A]] {
case "custom_type_definition" => typeDefinitionCustomTypeDecoder[A].widen
case "type_alias_definition" => typeDefinitionTypeAliasDecoder[A].widen
}

implicit def typeSpecificationTypeAliasDecoder[A: JsonDecoder]
: JsonDecoder[TypeSpecification.TypeAliasSpecification[A]] =
Expand Down Expand Up @@ -232,9 +237,11 @@ trait MorphirJsonDecodingSupportV1 {
}

implicit def typeSpecificationDecoder[A: JsonDecoder]: JsonDecoder[TypeSpecification[A]] =
typeSpecificationTypeAliasDecoder[A].widen[TypeSpecification[A]] orElse
typeSpecificationCustomTypeDecoder[A].widen[TypeSpecification[A]] orElse
typeSpecificationOpaqueTypeDecoder.widen[TypeSpecification[A]]
zio.json.TagBasedParser[TypeSpecification[A]] {
case "custom_type_specification" => typeSpecificationCustomTypeDecoder[A].widen
case "opaque_type_specification" => typeSpecificationOpaqueTypeDecoder.widen
case "type_alias_specification" => typeSpecificationTypeAliasDecoder[A].widen
}

implicit def valueDefinitionDecoder[TA: JsonDecoder, VA: JsonDecoder]: JsonDecoder[ValueDefinition[TA, VA]] = {
lazy val dec: JsonDecoder[ValueDefinition[TA, VA]] = DeriveJsonDecoder.gen
Expand Down Expand Up @@ -320,14 +327,16 @@ trait MorphirJsonDecodingSupportV1 {
}

implicit def patternDecoder[A: JsonDecoder]: JsonDecoder[Pattern[A]] =
patternEmptyListPatternDecoder[A].widen[Pattern[A]] orElse
patternWildcardPatternDecoder[A].widen[Pattern[A]] orElse
patternUnitPatternDecoder[A].widen[Pattern[A]] orElse
patternLiteralPatternDecoder[A].widen[Pattern[A]] orElse
patternTuplePatternDecoder[A].widen[Pattern[A]] orElse
patternHeadTailPatternDecoder[A].widen[Pattern[A]] orElse
patternConstructorPatternDecoder[A].widen[Pattern[A]] orElse
patternAsPatternDecoder[A].widen[Pattern[A]]
zio.json.TagBasedParser[Pattern[A]] {
case "as_pattern" => patternAsPatternDecoder[A].widen
case "constructor_pattern" => patternConstructorPatternDecoder[A].widen
case "empty_list_pattern" => patternEmptyListPatternDecoder[A].widen
case "head_tail_pattern" => patternHeadTailPatternDecoder[A].widen
case "literal_pattern" => patternLiteralPatternDecoder[A].widen
case "tuple_pattern" => patternTuplePatternDecoder[A].widen
case "unit_pattern" => patternUnitPatternDecoder[A].widen
case "wildcard_pattern" => patternWildcardPatternDecoder[A].widen
}

implicit def moduleSpecificationDecoder[TA](implicit
@unused decoder: JsonDecoder[TA]
Expand Down Expand Up @@ -569,26 +578,27 @@ trait MorphirJsonDecodingSupportV1 {
)
}

@nowarn("msg=Implicit resolves to enclosing method valueDecoder")
implicit def valueDecoder[TA: JsonDecoder, VA: JsonDecoder]: JsonDecoder[Value[TA, VA]] =
constructorValueJsonDecoder[VA].widen[Value[TA, VA]] orElse
fieldFunctionValueJsonDecoder[VA].widen[Value[TA, VA]] orElse
literalValueJsonDecoder[VA].widen[Value[TA, VA]] orElse
referenceValueJsonDecoder[VA].widen[Value[TA, VA]] orElse
unitValueJsonDecoder[VA].widen[Value[TA, VA]] orElse
variableValueJsonDecoder[VA].widen[Value[TA, VA]] orElse
applyValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
destructureValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
fieldValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
ifThenElseValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
lambdaValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
letDefinitionValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
letRecursionValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
listValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
patternMatchValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
recordValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
tupleValueJsonDecoder[TA, VA].widen[Value[TA, VA]] orElse
updateRecordValueJsonDecoder[TA, VA].widen[Value[TA, VA]]
zio.json.TagBasedParser[Value[TA, VA]] {
case "constructor" => constructorValueJsonDecoder[VA].widen
case "field_function" => fieldFunctionValueJsonDecoder[VA].widen
case "literal" => literalValueJsonDecoder[VA].widen
case "reference" => referenceValueJsonDecoder[VA].widen
case "unit" => unitValueJsonDecoder[VA].widen
case "variable" => variableValueJsonDecoder[VA].widen
case "apply" => applyValueJsonDecoder[TA, VA].widen
case "destructure" => destructureValueJsonDecoder[TA, VA].widen
case "field" => fieldValueJsonDecoder[TA, VA].widen
case "if_then_else" => ifThenElseValueJsonDecoder[TA, VA].widen
case "lambda" => lambdaValueJsonDecoder[TA, VA].widen
case "let_definition" => letDefinitionValueJsonDecoder[TA, VA].widen
case "let_recursion" => letRecursionValueJsonDecoder[TA, VA].widen
case "list" => listValueJsonDecoder[TA, VA].widen
case "pattern_match" => patternMatchValueJsonDecoder[TA, VA].widen
case "record" => recordValueJsonDecoder[TA, VA].widen
case "tuple" => tupleValueJsonDecoder[TA, VA].widen
case "update_record" => updateRecordValueJsonDecoder[TA, VA].widen
}

implicit def distributionLibraryJsonDecoder: JsonDecoder[Library] =
JsonDecoder
Expand Down
Loading

0 comments on commit 1e742a8

Please sign in to comment.