All Downloads are FREE. Search and download functionalities are using the official Maven repository.

miksilo.modularLanguages.deltas.smithy.ResourceDelta.scala Maven / Gradle / Ivy

The newest version!
package miksilo.modularLanguages.deltas.smithy

import miksilo.modularLanguages.core.bigrammar.grammars.Keyword
import miksilo.modularLanguages.core.deltas.DeltaWithGrammar
import miksilo.modularLanguages.core.deltas.grammars.LanguageGrammars
import miksilo.modularLanguages.core.deltas.path.NodePath
import miksilo.modularLanguages.core.node.{NodeLike, NodeShape, NodeWrapper}
import miksilo.languageServer.core.language.{Compilation, Language}
import miksilo.languageServer.core.smarts.ConstraintBuilder
import miksilo.languageServer.core.smarts.scopes.objects.Scope
import miksilo.languageServer.core.smarts.types.objects.PrimitiveType
import miksilo.modularLanguages.deltas.expression.{ArrayLiteralDelta, StringLiteralDelta}
import miksilo.modularLanguages.deltas.expression.ArrayLiteralDelta.ArrayLiteral
import miksilo.modularLanguages.deltas.json.JsonObjectLiteralDelta.ObjectLiteral
import miksilo.modularLanguages.deltas.json.{JsonObjectLiteralDelta, JsonStringLiteralDelta}
import miksilo.modularLanguages.deltas.smithy.ServiceDelta.Body
import miksilo.modularLanguages.deltas.{FileWithMembersDelta, HasNameDelta}
import miksilo.modularLanguages.core.deltas.path.ConstraintBuilderExtension._
import miksilo.modularLanguages.deltas.classes.HasConstraintsDelta

object ResourceDelta extends DeltaWithGrammar with HasConstraintsDelta {
  object Shape extends NodeShape

  override def transformGrammars(grammars: LanguageGrammars, language: Language): Unit = {
    import grammars._
    val objectExpression = find(JsonObjectLiteralDelta.Shape)
    val grammar = Keyword("resource", reserved = false) ~~
      find(HasNameDelta.Name) ~~ objectExpression.as(Body) asNode Shape
    val members = find(FileWithMembersDelta.Members)
    members.addAlternative(grammar)
  }

  override def shape = Shape

  implicit class Resource[T <: NodeLike](val node: T) extends NodeWrapper[T] {
    def body: ObjectLiteral[T] = node(Body).asInstanceOf[T]
  }

  val resourceType = PrimitiveType("resource")
  val lifeCycleOperations = Seq("create","read","update","delete","list")
  override def collectConstraints(compilation: Compilation, builder: ConstraintBuilder, path: NodePath, parentScope: Scope): Unit = {
    val resource: Resource[NodePath] = path
    builder.declare(path.getField(HasNameDelta.Name), parentScope, resourceType)

    val body = resource.body
    addResources(builder, parentScope, body)

    val identifiersOption = resource.body.get("identifiers")
    identifiersOption.foreach(identifiers => {
      if (identifiers.shape == JsonObjectLiteralDelta.Shape) {
        val identifiersObject: ObjectLiteral[NodePath] = identifiers
        identifiersObject.members.foreach(identifierMember => {
          identifierMember.value
          val shapeReference = identifierMember.value
          if (shapeReference.shape == StringLiteralDelta.Shape) {
            builder.resolveToType(shapeReference.getField(JsonStringLiteralDelta.Value), parentScope,
              RelativeShapeIdentifierDelta.shapeType)
          }
        })
      }
    })

    lifeCycleOperations.foreach(lifeCycleOperation => {
      val operationOption = resource.body.get(lifeCycleOperation)
      operationOption.foreach(operation => {
        if (operation.shape == StringLiteralDelta.Shape) {
          builder.resolveToType(operation.getField(JsonStringLiteralDelta.Value), parentScope,
            OperationDelta.operationType)
        }
      })
    })
  }

  def addResources(builder: ConstraintBuilder, parentScope: Scope, body: ObjectLiteral[NodePath]): Unit = {
    val resourcesOption = body.get("resources")
    resourcesOption.foreach(resources => {
      if (resources.shape == ArrayLiteralDelta.Shape) {
        val resourcesArray: ArrayLiteral[NodePath] = resources
        resourcesArray.members.foreach(resource => {
          if (resource.shape == StringLiteralDelta.Shape) {
            builder.resolveToType(resource.getField(JsonStringLiteralDelta.Value), parentScope, resourceType)
          }
        })
      }
    })
  }

  override def description = "Add the resource statement"

  override def dependencies = Set(FileWithMembersDelta)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy