# mypy: ignore-errors
# flake8: noqa

# This file is autogenerated by /metadata-ingestion/scripts/avro_codegen.py
# Do not modify manually!

# pylint: skip-file
# fmt: off

# This file contains classes corresponding to entity URNs.

from typing import ClassVar, List, Optional, Type, TYPE_CHECKING

import functools
from deprecated.sphinx import deprecated as _sphinx_deprecated

from datahub.utilities.urn_encoder import UrnEncoder
from datahub.utilities.urns._urn_base import _SpecificUrn, Urn
from datahub.utilities.urns.error import InvalidUrnError

deprecated = functools.partial(_sphinx_deprecated, version="0.12.0.2")

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import SchemaFieldKeyClass

class SchemaFieldUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "schemaField"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, parent: str, field_path: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            field_path = UrnEncoder.encode_string(field_path)

        # Validation logic.
        if not parent:
            raise InvalidUrnError("parent cannot be empty")
        parent = str(parent)
        assert Urn.from_string(parent)
        if not field_path:
            raise InvalidUrnError("field_path cannot be empty")
        assert not UrnEncoder.contains_reserved_char(field_path)

        super().__init__(self.ENTITY_TYPE, [parent, field_path])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "SchemaFieldUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"SchemaFieldUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(parent=entity_ids[0], field_path=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["SchemaFieldKeyClass"]:
        from datahub.metadata.schema_classes import SchemaFieldKeyClass

        return SchemaFieldKeyClass

    def to_key_aspect(self) -> "SchemaFieldKeyClass":
        from datahub.metadata.schema_classes import SchemaFieldKeyClass

        return SchemaFieldKeyClass(parent=self.parent, fieldPath=self.field_path)

    @classmethod
    def from_key_aspect(cls, key_aspect: "SchemaFieldKeyClass") -> "SchemaFieldUrn":
        return cls(parent=key_aspect.parent, field_path=key_aspect.fieldPath)

    @property
    def parent(self) -> str:
        return self.entity_ids[0]

    @property
    def field_path(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataFlowKeyClass

class DataFlowUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataFlow"
    URN_PARTS: ClassVar[int] = 3

    def __init__(self, orchestrator: str, flow_id: str, cluster: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            orchestrator = UrnEncoder.encode_string(orchestrator)
            flow_id = UrnEncoder.encode_string(flow_id)
            cluster = UrnEncoder.encode_string(cluster)

        # Validation logic.
        if not orchestrator:
            raise InvalidUrnError("orchestrator cannot be empty")
        assert not UrnEncoder.contains_reserved_char(orchestrator)
        if not flow_id:
            raise InvalidUrnError("flow_id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(flow_id)
        if not cluster:
            raise InvalidUrnError("cluster cannot be empty")
        assert not UrnEncoder.contains_reserved_char(cluster)

        super().__init__(self.ENTITY_TYPE, [orchestrator, flow_id, cluster])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataFlowUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataFlowUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(orchestrator=entity_ids[0], flow_id=entity_ids[1], cluster=entity_ids[2], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataFlowKeyClass"]:
        from datahub.metadata.schema_classes import DataFlowKeyClass

        return DataFlowKeyClass

    def to_key_aspect(self) -> "DataFlowKeyClass":
        from datahub.metadata.schema_classes import DataFlowKeyClass

        return DataFlowKeyClass(orchestrator=self.orchestrator, flowId=self.flow_id, cluster=self.cluster)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataFlowKeyClass") -> "DataFlowUrn":
        return cls(orchestrator=key_aspect.orchestrator, flow_id=key_aspect.flowId, cluster=key_aspect.cluster)

    @classmethod
    def create_from_ids(
        cls,
        orchestrator: str,
        flow_id: str,
        env: str,
        platform_instance: Optional[str] = None,
    ) -> "DataFlowUrn":
        return cls(
            orchestrator=orchestrator,
            flow_id=f"{platform_instance}.{flow_id}" if platform_instance else flow_id,
            cluster=env,
        )

    @deprecated(reason="Use .orchestrator instead")
    def get_orchestrator_name(self) -> str:
        return self.orchestrator

    @deprecated(reason="Use .flow_id instead")
    def get_flow_id(self) -> str:
        return self.flow_id

    @deprecated(reason="Use .cluster instead")
    def get_env(self) -> str:
        return self.cluster

    @property
    def orchestrator(self) -> str:
        return self.entity_ids[0]

    @property
    def flow_id(self) -> str:
        return self.entity_ids[1]

    @property
    def cluster(self) -> str:
        return self.entity_ids[2]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DomainKeyClass

class DomainUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "domain"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DomainUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DomainUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DomainKeyClass"]:
        from datahub.metadata.schema_classes import DomainKeyClass

        return DomainKeyClass

    def to_key_aspect(self) -> "DomainKeyClass":
        from datahub.metadata.schema_classes import DomainKeyClass

        return DomainKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DomainKeyClass") -> "DomainUrn":
        return cls(id=key_aspect.id)

    @classmethod
    @deprecated(reason="Use the constructor instead")
    def create_from_id(cls, id: str) -> "DomainUrn":
        return cls(id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import ContainerKeyClass

class ContainerUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "container"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, guid: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            guid = UrnEncoder.encode_string(guid)

        # Validation logic.
        if not guid:
            raise InvalidUrnError("guid cannot be empty")
        assert not UrnEncoder.contains_reserved_char(guid)

        super().__init__(self.ENTITY_TYPE, [guid])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "ContainerUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"ContainerUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(guid=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["ContainerKeyClass"]:
        from datahub.metadata.schema_classes import ContainerKeyClass

        return ContainerKeyClass

    def to_key_aspect(self) -> "ContainerKeyClass":
        from datahub.metadata.schema_classes import ContainerKeyClass

        return ContainerKeyClass(guid=self.guid)

    @classmethod
    def from_key_aspect(cls, key_aspect: "ContainerKeyClass") -> "ContainerUrn":
        return cls(guid=key_aspect.guid)

    @property
    def guid(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import NotebookKeyClass

class NotebookUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "notebook"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, notebook_tool: str, notebook_id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            notebook_tool = UrnEncoder.encode_string(notebook_tool)
            notebook_id = UrnEncoder.encode_string(notebook_id)

        # Validation logic.
        if not notebook_tool:
            raise InvalidUrnError("notebook_tool cannot be empty")
        assert not UrnEncoder.contains_reserved_char(notebook_tool)
        if not notebook_id:
            raise InvalidUrnError("notebook_id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(notebook_id)

        super().__init__(self.ENTITY_TYPE, [notebook_tool, notebook_id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "NotebookUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"NotebookUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(notebook_tool=entity_ids[0], notebook_id=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["NotebookKeyClass"]:
        from datahub.metadata.schema_classes import NotebookKeyClass

        return NotebookKeyClass

    def to_key_aspect(self) -> "NotebookKeyClass":
        from datahub.metadata.schema_classes import NotebookKeyClass

        return NotebookKeyClass(notebookTool=self.notebook_tool, notebookId=self.notebook_id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "NotebookKeyClass") -> "NotebookUrn":
        return cls(notebook_tool=key_aspect.notebookTool, notebook_id=key_aspect.notebookId)

    @deprecated(reason="Use .notebook_tool instead")
    def get_platform_id(self) -> str:
        return self.notebook_tool

    @deprecated(reason="Use .notebook_id instead")
    def get_notebook_id(self) -> str:
        return self.notebook_id

    @property
    def notebook_tool(self) -> str:
        return self.entity_ids[0]

    @property
    def notebook_id(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import TagKeyClass

class TagUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "tag"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, name: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            name = UrnEncoder.encode_string(name)

        # Validation logic.
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)

        super().__init__(self.ENTITY_TYPE, [name])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "TagUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"TagUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(name=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["TagKeyClass"]:
        from datahub.metadata.schema_classes import TagKeyClass

        return TagKeyClass

    def to_key_aspect(self) -> "TagKeyClass":
        from datahub.metadata.schema_classes import TagKeyClass

        return TagKeyClass(name=self.name)

    @classmethod
    def from_key_aspect(cls, key_aspect: "TagKeyClass") -> "TagUrn":
        return cls(name=key_aspect.name)

    @classmethod
    @deprecated(reason="Use the constructor instead")
    def create_from_id(cls, id: str) -> "TagUrn":
        return cls(id)

    @property
    def name(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import MLModelGroupKeyClass

class MlModelGroupUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "mlModelGroup"
    URN_PARTS: ClassVar[int] = 3

    def __init__(self, platform: str, name: str, env: str = "PROD", *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            platform = DataPlatformUrn(platform).urn()
            name = UrnEncoder.encode_string(name)
            env = env.upper()
            env = UrnEncoder.encode_string(env)

        # Validation logic.
        if not platform:
            raise InvalidUrnError("platform cannot be empty")
        platform = str(platform)
        assert DataPlatformUrn.from_string(platform)
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)
        if not env:
            raise InvalidUrnError("env cannot be empty")
        assert not UrnEncoder.contains_reserved_char(env)

        super().__init__(self.ENTITY_TYPE, [platform, name, env])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "MlModelGroupUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"MlModelGroupUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(platform=entity_ids[0], name=entity_ids[1], env=entity_ids[2], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["MLModelGroupKeyClass"]:
        from datahub.metadata.schema_classes import MLModelGroupKeyClass

        return MLModelGroupKeyClass

    def to_key_aspect(self) -> "MLModelGroupKeyClass":
        from datahub.metadata.schema_classes import MLModelGroupKeyClass

        return MLModelGroupKeyClass(platform=self.platform, name=self.name, origin=self.env)

    @classmethod
    def from_key_aspect(cls, key_aspect: "MLModelGroupKeyClass") -> "MlModelGroupUrn":
        return cls(platform=key_aspect.platform, name=key_aspect.name, env=key_aspect.origin)

    @property
    def platform(self) -> str:
        return self.entity_ids[0]

    @property
    def name(self) -> str:
        return self.entity_ids[1]

    @property
    def env(self) -> str:
        return self.entity_ids[2]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import AnomalyKeyClass

class AnomalyUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "anomaly"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "AnomalyUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"AnomalyUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["AnomalyKeyClass"]:
        from datahub.metadata.schema_classes import AnomalyKeyClass

        return AnomalyKeyClass

    def to_key_aspect(self) -> "AnomalyKeyClass":
        from datahub.metadata.schema_classes import AnomalyKeyClass

        return AnomalyKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "AnomalyKeyClass") -> "AnomalyUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataJobKeyClass

class DataJobUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataJob"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, flow: str, job_id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            job_id = UrnEncoder.encode_string(job_id)

        # Validation logic.
        if not flow:
            raise InvalidUrnError("flow cannot be empty")
        flow = str(flow)
        assert DataFlowUrn.from_string(flow)
        if not job_id:
            raise InvalidUrnError("job_id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(job_id)

        super().__init__(self.ENTITY_TYPE, [flow, job_id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataJobUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataJobUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(flow=entity_ids[0], job_id=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataJobKeyClass"]:
        from datahub.metadata.schema_classes import DataJobKeyClass

        return DataJobKeyClass

    def to_key_aspect(self) -> "DataJobKeyClass":
        from datahub.metadata.schema_classes import DataJobKeyClass

        return DataJobKeyClass(flow=self.flow, jobId=self.job_id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataJobKeyClass") -> "DataJobUrn":
        return cls(flow=key_aspect.flow, job_id=key_aspect.jobId)

    @classmethod
    def create_from_ids(cls, data_flow_urn: str, job_id: str) -> "DataJobUrn":
        return cls(data_flow_urn, job_id)

    def get_data_flow_urn(self) -> "DataFlowUrn":
        return DataFlowUrn.from_string(self.flow)

    @deprecated(reason="Use .job_id instead")
    def get_job_id(self) -> str:
        return self.job_id

    @property
    def flow(self) -> str:
        return self.entity_ids[0]

    @property
    def job_id(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import ChartKeyClass

class ChartUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "chart"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, dashboard_tool: str, chart_id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            dashboard_tool = UrnEncoder.encode_string(dashboard_tool)
            chart_id = UrnEncoder.encode_string(chart_id)

        # Validation logic.
        if not dashboard_tool:
            raise InvalidUrnError("dashboard_tool cannot be empty")
        assert not UrnEncoder.contains_reserved_char(dashboard_tool)
        if not chart_id:
            raise InvalidUrnError("chart_id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(chart_id)

        super().__init__(self.ENTITY_TYPE, [dashboard_tool, chart_id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "ChartUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"ChartUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(dashboard_tool=entity_ids[0], chart_id=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["ChartKeyClass"]:
        from datahub.metadata.schema_classes import ChartKeyClass

        return ChartKeyClass

    def to_key_aspect(self) -> "ChartKeyClass":
        from datahub.metadata.schema_classes import ChartKeyClass

        return ChartKeyClass(dashboardTool=self.dashboard_tool, chartId=self.chart_id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "ChartKeyClass") -> "ChartUrn":
        return cls(dashboard_tool=key_aspect.dashboardTool, chart_id=key_aspect.chartId)

    @property
    def dashboard_tool(self) -> str:
        return self.entity_ids[0]

    @property
    def chart_id(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import MLModelDeploymentKeyClass

class MlModelDeploymentUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "mlModelDeployment"
    URN_PARTS: ClassVar[int] = 3

    def __init__(self, platform: str, name: str, env: str = "PROD", *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            platform = DataPlatformUrn(platform).urn()
            name = UrnEncoder.encode_string(name)
            env = env.upper()
            env = UrnEncoder.encode_string(env)

        # Validation logic.
        if not platform:
            raise InvalidUrnError("platform cannot be empty")
        platform = str(platform)
        assert DataPlatformUrn.from_string(platform)
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)
        if not env:
            raise InvalidUrnError("env cannot be empty")
        assert not UrnEncoder.contains_reserved_char(env)

        super().__init__(self.ENTITY_TYPE, [platform, name, env])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "MlModelDeploymentUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"MlModelDeploymentUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(platform=entity_ids[0], name=entity_ids[1], env=entity_ids[2], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["MLModelDeploymentKeyClass"]:
        from datahub.metadata.schema_classes import MLModelDeploymentKeyClass

        return MLModelDeploymentKeyClass

    def to_key_aspect(self) -> "MLModelDeploymentKeyClass":
        from datahub.metadata.schema_classes import MLModelDeploymentKeyClass

        return MLModelDeploymentKeyClass(platform=self.platform, name=self.name, origin=self.env)

    @classmethod
    def from_key_aspect(cls, key_aspect: "MLModelDeploymentKeyClass") -> "MlModelDeploymentUrn":
        return cls(platform=key_aspect.platform, name=key_aspect.name, env=key_aspect.origin)

    @property
    def platform(self) -> str:
        return self.entity_ids[0]

    @property
    def name(self) -> str:
        return self.entity_ids[1]

    @property
    def env(self) -> str:
        return self.entity_ids[2]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataHubRoleKeyClass

class DataHubRoleUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataHubRole"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataHubRoleUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataHubRoleUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataHubRoleKeyClass"]:
        from datahub.metadata.schema_classes import DataHubRoleKeyClass

        return DataHubRoleKeyClass

    def to_key_aspect(self) -> "DataHubRoleKeyClass":
        from datahub.metadata.schema_classes import DataHubRoleKeyClass

        return DataHubRoleKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataHubRoleKeyClass") -> "DataHubRoleUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import MLFeatureKeyClass

class MlFeatureUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "mlFeature"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, feature_namespace: str, name: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            feature_namespace = UrnEncoder.encode_string(feature_namespace)
            name = UrnEncoder.encode_string(name)

        # Validation logic.
        if not feature_namespace:
            raise InvalidUrnError("feature_namespace cannot be empty")
        assert not UrnEncoder.contains_reserved_char(feature_namespace)
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)

        super().__init__(self.ENTITY_TYPE, [feature_namespace, name])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "MlFeatureUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"MlFeatureUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(feature_namespace=entity_ids[0], name=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["MLFeatureKeyClass"]:
        from datahub.metadata.schema_classes import MLFeatureKeyClass

        return MLFeatureKeyClass

    def to_key_aspect(self) -> "MLFeatureKeyClass":
        from datahub.metadata.schema_classes import MLFeatureKeyClass

        return MLFeatureKeyClass(featureNamespace=self.feature_namespace, name=self.name)

    @classmethod
    def from_key_aspect(cls, key_aspect: "MLFeatureKeyClass") -> "MlFeatureUrn":
        return cls(feature_namespace=key_aspect.featureNamespace, name=key_aspect.name)

    @property
    def feature_namespace(self) -> str:
        return self.entity_ids[0]

    @property
    def name(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataProcessInstanceKeyClass

class DataProcessInstanceUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataProcessInstance"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataProcessInstanceUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataProcessInstanceUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataProcessInstanceKeyClass"]:
        from datahub.metadata.schema_classes import DataProcessInstanceKeyClass

        return DataProcessInstanceKeyClass

    def to_key_aspect(self) -> "DataProcessInstanceKeyClass":
        from datahub.metadata.schema_classes import DataProcessInstanceKeyClass

        return DataProcessInstanceKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataProcessInstanceKeyClass") -> "DataProcessInstanceUrn":
        return cls(id=key_aspect.id)

    @classmethod
    @deprecated(reason="Use the constructor instead")
    def create_from_id(cls, id: str) -> "DataProcessInstanceUrn":
        return cls(id)

    @deprecated(reason="Use .id instead")
    def get_dataprocessinstance_id(self) -> str:
        return self.id

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import QueryKeyClass

class QueryUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "query"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "QueryUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"QueryUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["QueryKeyClass"]:
        from datahub.metadata.schema_classes import QueryKeyClass

        return QueryKeyClass

    def to_key_aspect(self) -> "QueryKeyClass":
        from datahub.metadata.schema_classes import QueryKeyClass

        return QueryKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "QueryKeyClass") -> "QueryUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataProcessKeyClass

class DataProcessUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataProcess"
    URN_PARTS: ClassVar[int] = 3

    def __init__(self, name: str, orchestrator: str, env: str = "PROD", *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            name = UrnEncoder.encode_string(name)
            orchestrator = UrnEncoder.encode_string(orchestrator)
            env = env.upper()
            env = UrnEncoder.encode_string(env)

        # Validation logic.
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)
        if not orchestrator:
            raise InvalidUrnError("orchestrator cannot be empty")
        assert not UrnEncoder.contains_reserved_char(orchestrator)
        if not env:
            raise InvalidUrnError("env cannot be empty")
        assert not UrnEncoder.contains_reserved_char(env)

        super().__init__(self.ENTITY_TYPE, [name, orchestrator, env])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataProcessUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataProcessUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(name=entity_ids[0], orchestrator=entity_ids[1], env=entity_ids[2], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataProcessKeyClass"]:
        from datahub.metadata.schema_classes import DataProcessKeyClass

        return DataProcessKeyClass

    def to_key_aspect(self) -> "DataProcessKeyClass":
        from datahub.metadata.schema_classes import DataProcessKeyClass

        return DataProcessKeyClass(name=self.name, orchestrator=self.orchestrator, origin=self.env)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataProcessKeyClass") -> "DataProcessUrn":
        return cls(name=key_aspect.name, orchestrator=key_aspect.orchestrator, env=key_aspect.origin)

    @property
    def name(self) -> str:
        return self.entity_ids[0]

    @property
    def orchestrator(self) -> str:
        return self.entity_ids[1]

    @property
    def env(self) -> str:
        return self.entity_ids[2]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataContractKeyClass

class DataContractUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataContract"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataContractUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataContractUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataContractKeyClass"]:
        from datahub.metadata.schema_classes import DataContractKeyClass

        return DataContractKeyClass

    def to_key_aspect(self) -> "DataContractKeyClass":
        from datahub.metadata.schema_classes import DataContractKeyClass

        return DataContractKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataContractKeyClass") -> "DataContractUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DashboardKeyClass

class DashboardUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dashboard"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, dashboard_tool: str, dashboard_id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            dashboard_tool = UrnEncoder.encode_string(dashboard_tool)
            dashboard_id = UrnEncoder.encode_string(dashboard_id)

        # Validation logic.
        if not dashboard_tool:
            raise InvalidUrnError("dashboard_tool cannot be empty")
        assert not UrnEncoder.contains_reserved_char(dashboard_tool)
        if not dashboard_id:
            raise InvalidUrnError("dashboard_id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(dashboard_id)

        super().__init__(self.ENTITY_TYPE, [dashboard_tool, dashboard_id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DashboardUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DashboardUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(dashboard_tool=entity_ids[0], dashboard_id=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DashboardKeyClass"]:
        from datahub.metadata.schema_classes import DashboardKeyClass

        return DashboardKeyClass

    def to_key_aspect(self) -> "DashboardKeyClass":
        from datahub.metadata.schema_classes import DashboardKeyClass

        return DashboardKeyClass(dashboardTool=self.dashboard_tool, dashboardId=self.dashboard_id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DashboardKeyClass") -> "DashboardUrn":
        return cls(dashboard_tool=key_aspect.dashboardTool, dashboard_id=key_aspect.dashboardId)

    @property
    def dashboard_tool(self) -> str:
        return self.entity_ids[0]

    @property
    def dashboard_id(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import OwnershipTypeKeyClass

class OwnershipTypeUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "ownershipType"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "OwnershipTypeUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"OwnershipTypeUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["OwnershipTypeKeyClass"]:
        from datahub.metadata.schema_classes import OwnershipTypeKeyClass

        return OwnershipTypeKeyClass

    def to_key_aspect(self) -> "OwnershipTypeKeyClass":
        from datahub.metadata.schema_classes import OwnershipTypeKeyClass

        return OwnershipTypeKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "OwnershipTypeKeyClass") -> "OwnershipTypeUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import RoleKeyClass

class RoleUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "role"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "RoleUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"RoleUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["RoleKeyClass"]:
        from datahub.metadata.schema_classes import RoleKeyClass

        return RoleKeyClass

    def to_key_aspect(self) -> "RoleKeyClass":
        from datahub.metadata.schema_classes import RoleKeyClass

        return RoleKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "RoleKeyClass") -> "RoleUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataHubViewKeyClass

class DataHubViewUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataHubView"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataHubViewUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataHubViewUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataHubViewKeyClass"]:
        from datahub.metadata.schema_classes import DataHubViewKeyClass

        return DataHubViewKeyClass

    def to_key_aspect(self) -> "DataHubViewKeyClass":
        from datahub.metadata.schema_classes import DataHubViewKeyClass

        return DataHubViewKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataHubViewKeyClass") -> "DataHubViewUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import ConstraintKeyClass

class ConstraintUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "constraint"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "ConstraintUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"ConstraintUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["ConstraintKeyClass"]:
        from datahub.metadata.schema_classes import ConstraintKeyClass

        return ConstraintKeyClass

    def to_key_aspect(self) -> "ConstraintKeyClass":
        from datahub.metadata.schema_classes import ConstraintKeyClass

        return ConstraintKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "ConstraintKeyClass") -> "ConstraintUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import MLModelKeyClass

class MlModelUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "mlModel"
    URN_PARTS: ClassVar[int] = 3

    def __init__(self, platform: str, name: str, env: str = "PROD", *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            platform = DataPlatformUrn(platform).urn()
            name = UrnEncoder.encode_string(name)
            env = env.upper()
            env = UrnEncoder.encode_string(env)

        # Validation logic.
        if not platform:
            raise InvalidUrnError("platform cannot be empty")
        platform = str(platform)
        assert DataPlatformUrn.from_string(platform)
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)
        if not env:
            raise InvalidUrnError("env cannot be empty")
        assert not UrnEncoder.contains_reserved_char(env)

        super().__init__(self.ENTITY_TYPE, [platform, name, env])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "MlModelUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"MlModelUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(platform=entity_ids[0], name=entity_ids[1], env=entity_ids[2], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["MLModelKeyClass"]:
        from datahub.metadata.schema_classes import MLModelKeyClass

        return MLModelKeyClass

    def to_key_aspect(self) -> "MLModelKeyClass":
        from datahub.metadata.schema_classes import MLModelKeyClass

        return MLModelKeyClass(platform=self.platform, name=self.name, origin=self.env)

    @classmethod
    def from_key_aspect(cls, key_aspect: "MLModelKeyClass") -> "MlModelUrn":
        return cls(platform=key_aspect.platform, name=key_aspect.name, env=key_aspect.origin)

    @property
    def platform(self) -> str:
        return self.entity_ids[0]

    @property
    def name(self) -> str:
        return self.entity_ids[1]

    @property
    def env(self) -> str:
        return self.entity_ids[2]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import CorpUserKeyClass

class CorpUserUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "corpuser"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, username: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            username = UrnEncoder.encode_string(username)

        # Validation logic.
        if not username:
            raise InvalidUrnError("username cannot be empty")
        assert not UrnEncoder.contains_reserved_char(username)

        super().__init__(self.ENTITY_TYPE, [username])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "CorpUserUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"CorpUserUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(username=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["CorpUserKeyClass"]:
        from datahub.metadata.schema_classes import CorpUserKeyClass

        return CorpUserKeyClass

    def to_key_aspect(self) -> "CorpUserKeyClass":
        from datahub.metadata.schema_classes import CorpUserKeyClass

        return CorpUserKeyClass(username=self.username)

    @classmethod
    def from_key_aspect(cls, key_aspect: "CorpUserKeyClass") -> "CorpUserUrn":
        return cls(username=key_aspect.username)

    @classmethod
    @deprecated(reason="Use the constructor instead")
    def create_from_id(cls, id: str) -> "CorpUserUrn":
        return cls(id)

    @property
    def username(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DatasetKeyClass

class DatasetUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataset"
    URN_PARTS: ClassVar[int] = 3

    def __init__(self, platform: str, name: str, env: str = "PROD", *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            platform = DataPlatformUrn(platform).urn()
            name = UrnEncoder.encode_string(name)
            env = env.upper()
            env = UrnEncoder.encode_string(env)

        # Validation logic.
        if not platform:
            raise InvalidUrnError("platform cannot be empty")
        platform = str(platform)
        assert DataPlatformUrn.from_string(platform)
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)
        if not env:
            raise InvalidUrnError("env cannot be empty")
        assert not UrnEncoder.contains_reserved_char(env)

        super().__init__(self.ENTITY_TYPE, [platform, name, env])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DatasetUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DatasetUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(platform=entity_ids[0], name=entity_ids[1], env=entity_ids[2], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DatasetKeyClass"]:
        from datahub.metadata.schema_classes import DatasetKeyClass

        return DatasetKeyClass

    def to_key_aspect(self) -> "DatasetKeyClass":
        from datahub.metadata.schema_classes import DatasetKeyClass

        return DatasetKeyClass(platform=self.platform, name=self.name, origin=self.env)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DatasetKeyClass") -> "DatasetUrn":
        return cls(platform=key_aspect.platform, name=key_aspect.name, env=key_aspect.origin)

    @classmethod
    def create_from_ids(
        cls,
        platform_id: str,
        table_name: str,
        env: str,
        platform_instance: Optional[str] = None,
    ) -> "DatasetUrn":
        return DatasetUrn(
            platform=platform_id,
            name=f"{platform_instance}.{table_name}" if platform_instance else table_name,
            env=env,
        )

    from datahub.utilities.urns.field_paths import get_simple_field_path_from_v2_field_path as _get_simple_field_path_from_v2_field_path

    get_simple_field_path_from_v2_field_path = staticmethod(deprecated(reason='Use the function from the field_paths module instead')(_get_simple_field_path_from_v2_field_path))

    def get_data_platform_urn(self) -> "DataPlatformUrn":
        return DataPlatformUrn.from_string(self.platform)

    @deprecated(reason="Use .name instead")
    def get_dataset_name(self) -> str:
        return self.name

    @deprecated(reason="Use .env instead")
    def get_env(self) -> str:
        return self.env

    @property
    def platform(self) -> str:
        return self.entity_ids[0]

    @property
    def name(self) -> str:
        return self.entity_ids[1]

    @property
    def env(self) -> str:
        return self.entity_ids[2]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import MLPrimaryKeyKeyClass

class MlPrimaryKeyUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "mlPrimaryKey"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, feature_namespace: str, name: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            feature_namespace = UrnEncoder.encode_string(feature_namespace)
            name = UrnEncoder.encode_string(name)

        # Validation logic.
        if not feature_namespace:
            raise InvalidUrnError("feature_namespace cannot be empty")
        assert not UrnEncoder.contains_reserved_char(feature_namespace)
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)

        super().__init__(self.ENTITY_TYPE, [feature_namespace, name])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "MlPrimaryKeyUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"MlPrimaryKeyUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(feature_namespace=entity_ids[0], name=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["MLPrimaryKeyKeyClass"]:
        from datahub.metadata.schema_classes import MLPrimaryKeyKeyClass

        return MLPrimaryKeyKeyClass

    def to_key_aspect(self) -> "MLPrimaryKeyKeyClass":
        from datahub.metadata.schema_classes import MLPrimaryKeyKeyClass

        return MLPrimaryKeyKeyClass(featureNamespace=self.feature_namespace, name=self.name)

    @classmethod
    def from_key_aspect(cls, key_aspect: "MLPrimaryKeyKeyClass") -> "MlPrimaryKeyUrn":
        return cls(feature_namespace=key_aspect.featureNamespace, name=key_aspect.name)

    @property
    def feature_namespace(self) -> str:
        return self.entity_ids[0]

    @property
    def name(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import GlossaryTermKeyClass

class GlossaryTermUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "glossaryTerm"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, name: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            name = UrnEncoder.encode_string(name)

        # Validation logic.
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)

        super().__init__(self.ENTITY_TYPE, [name])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "GlossaryTermUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"GlossaryTermUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(name=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["GlossaryTermKeyClass"]:
        from datahub.metadata.schema_classes import GlossaryTermKeyClass

        return GlossaryTermKeyClass

    def to_key_aspect(self) -> "GlossaryTermKeyClass":
        from datahub.metadata.schema_classes import GlossaryTermKeyClass

        return GlossaryTermKeyClass(name=self.name)

    @classmethod
    def from_key_aspect(cls, key_aspect: "GlossaryTermKeyClass") -> "GlossaryTermUrn":
        return cls(name=key_aspect.name)

    @property
    def name(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import PostKeyClass

class PostUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "post"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "PostUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"PostUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["PostKeyClass"]:
        from datahub.metadata.schema_classes import PostKeyClass

        return PostKeyClass

    def to_key_aspect(self) -> "PostKeyClass":
        from datahub.metadata.schema_classes import PostKeyClass

        return PostKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "PostKeyClass") -> "PostUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import IncidentKeyClass

class IncidentUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "incident"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "IncidentUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"IncidentUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["IncidentKeyClass"]:
        from datahub.metadata.schema_classes import IncidentKeyClass

        return IncidentKeyClass

    def to_key_aspect(self) -> "IncidentKeyClass":
        from datahub.metadata.schema_classes import IncidentKeyClass

        return IncidentKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "IncidentKeyClass") -> "IncidentUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import TestKeyClass

class TestUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "test"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "TestUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"TestUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["TestKeyClass"]:
        from datahub.metadata.schema_classes import TestKeyClass

        return TestKeyClass

    def to_key_aspect(self) -> "TestKeyClass":
        from datahub.metadata.schema_classes import TestKeyClass

        return TestKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "TestKeyClass") -> "TestUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataPlatformKeyClass

class DataPlatformUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataPlatform"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, platform_name: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            if platform_name.startswith("urn:li:dataPlatform:"):
                platform_name = DataPlatformUrn.from_string(platform_name).platform_name
            platform_name = UrnEncoder.encode_string(platform_name)

        # Validation logic.
        if not platform_name:
            raise InvalidUrnError("platform_name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(platform_name)

        super().__init__(self.ENTITY_TYPE, [platform_name])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataPlatformUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataPlatformUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(platform_name=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataPlatformKeyClass"]:
        from datahub.metadata.schema_classes import DataPlatformKeyClass

        return DataPlatformKeyClass

    def to_key_aspect(self) -> "DataPlatformKeyClass":
        from datahub.metadata.schema_classes import DataPlatformKeyClass

        return DataPlatformKeyClass(platformName=self.platform_name)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataPlatformKeyClass") -> "DataPlatformUrn":
        return cls(platform_name=key_aspect.platformName)

    @classmethod
    @deprecated(reason="Use the constructor instead")
    def create_from_id(cls, id: str) -> "DataPlatformUrn":
        return cls(id)

    @property
    def platform_name(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import GlossaryNodeKeyClass

class GlossaryNodeUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "glossaryNode"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, name: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            name = UrnEncoder.encode_string(name)

        # Validation logic.
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)

        super().__init__(self.ENTITY_TYPE, [name])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "GlossaryNodeUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"GlossaryNodeUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(name=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["GlossaryNodeKeyClass"]:
        from datahub.metadata.schema_classes import GlossaryNodeKeyClass

        return GlossaryNodeKeyClass

    def to_key_aspect(self) -> "GlossaryNodeKeyClass":
        from datahub.metadata.schema_classes import GlossaryNodeKeyClass

        return GlossaryNodeKeyClass(name=self.name)

    @classmethod
    def from_key_aspect(cls, key_aspect: "GlossaryNodeKeyClass") -> "GlossaryNodeUrn":
        return cls(name=key_aspect.name)

    @property
    def name(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import SubscriptionKeyClass

class SubscriptionUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "subscription"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "SubscriptionUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"SubscriptionUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["SubscriptionKeyClass"]:
        from datahub.metadata.schema_classes import SubscriptionKeyClass

        return SubscriptionKeyClass

    def to_key_aspect(self) -> "SubscriptionKeyClass":
        from datahub.metadata.schema_classes import SubscriptionKeyClass

        return SubscriptionKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "SubscriptionKeyClass") -> "SubscriptionUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import MonitorKeyClass

class MonitorUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "monitor"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, entity: str, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not entity:
            raise InvalidUrnError("entity cannot be empty")
        entity = str(entity)
        assert DatasetUrn.from_string(entity)
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [entity, id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "MonitorUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"MonitorUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(entity=entity_ids[0], id=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["MonitorKeyClass"]:
        from datahub.metadata.schema_classes import MonitorKeyClass

        return MonitorKeyClass

    def to_key_aspect(self) -> "MonitorKeyClass":
        from datahub.metadata.schema_classes import MonitorKeyClass

        return MonitorKeyClass(entity=self.entity, id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "MonitorKeyClass") -> "MonitorUrn":
        return cls(entity=key_aspect.entity, id=key_aspect.id)

    @property
    def entity(self) -> str:
        return self.entity_ids[0]

    @property
    def id(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import AssertionKeyClass

class AssertionUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "assertion"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, assertion_id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            assertion_id = UrnEncoder.encode_string(assertion_id)

        # Validation logic.
        if not assertion_id:
            raise InvalidUrnError("assertion_id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(assertion_id)

        super().__init__(self.ENTITY_TYPE, [assertion_id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "AssertionUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"AssertionUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(assertion_id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["AssertionKeyClass"]:
        from datahub.metadata.schema_classes import AssertionKeyClass

        return AssertionKeyClass

    def to_key_aspect(self) -> "AssertionKeyClass":
        from datahub.metadata.schema_classes import AssertionKeyClass

        return AssertionKeyClass(assertionId=self.assertion_id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "AssertionKeyClass") -> "AssertionUrn":
        return cls(assertion_id=key_aspect.assertionId)

    @property
    def assertion_id(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import RecommendationModuleKeyClass

class RecommendationModuleUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "recommendationModule"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, module_id: str, identifier: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            module_id = UrnEncoder.encode_string(module_id)
            identifier = UrnEncoder.encode_string(identifier)

        # Validation logic.
        if not module_id:
            raise InvalidUrnError("module_id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(module_id)
        if not identifier:
            raise InvalidUrnError("identifier cannot be empty")
        assert not UrnEncoder.contains_reserved_char(identifier)

        super().__init__(self.ENTITY_TYPE, [module_id, identifier])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "RecommendationModuleUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"RecommendationModuleUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(module_id=entity_ids[0], identifier=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["RecommendationModuleKeyClass"]:
        from datahub.metadata.schema_classes import RecommendationModuleKeyClass

        return RecommendationModuleKeyClass

    def to_key_aspect(self) -> "RecommendationModuleKeyClass":
        from datahub.metadata.schema_classes import RecommendationModuleKeyClass

        return RecommendationModuleKeyClass(moduleId=self.module_id, identifier=self.identifier)

    @classmethod
    def from_key_aspect(cls, key_aspect: "RecommendationModuleKeyClass") -> "RecommendationModuleUrn":
        return cls(module_id=key_aspect.moduleId, identifier=key_aspect.identifier)

    @property
    def module_id(self) -> str:
        return self.entity_ids[0]

    @property
    def identifier(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import MLFeatureTableKeyClass

class MlFeatureTableUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "mlFeatureTable"
    URN_PARTS: ClassVar[int] = 2

    def __init__(self, platform: str, name: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            platform = DataPlatformUrn(platform).urn()
            name = UrnEncoder.encode_string(name)

        # Validation logic.
        if not platform:
            raise InvalidUrnError("platform cannot be empty")
        platform = str(platform)
        assert DataPlatformUrn.from_string(platform)
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)

        super().__init__(self.ENTITY_TYPE, [platform, name])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "MlFeatureTableUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"MlFeatureTableUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(platform=entity_ids[0], name=entity_ids[1], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["MLFeatureTableKeyClass"]:
        from datahub.metadata.schema_classes import MLFeatureTableKeyClass

        return MLFeatureTableKeyClass

    def to_key_aspect(self) -> "MLFeatureTableKeyClass":
        from datahub.metadata.schema_classes import MLFeatureTableKeyClass

        return MLFeatureTableKeyClass(platform=self.platform, name=self.name)

    @classmethod
    def from_key_aspect(cls, key_aspect: "MLFeatureTableKeyClass") -> "MlFeatureTableUrn":
        return cls(platform=key_aspect.platform, name=key_aspect.name)

    @property
    def platform(self) -> str:
        return self.entity_ids[0]

    @property
    def name(self) -> str:
        return self.entity_ids[1]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import CorpGroupKeyClass

class CorpGroupUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "corpGroup"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, name: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            name = UrnEncoder.encode_string(name)

        # Validation logic.
        if not name:
            raise InvalidUrnError("name cannot be empty")
        assert not UrnEncoder.contains_reserved_char(name)

        super().__init__(self.ENTITY_TYPE, [name])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "CorpGroupUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"CorpGroupUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(name=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["CorpGroupKeyClass"]:
        from datahub.metadata.schema_classes import CorpGroupKeyClass

        return CorpGroupKeyClass

    def to_key_aspect(self) -> "CorpGroupKeyClass":
        from datahub.metadata.schema_classes import CorpGroupKeyClass

        return CorpGroupKeyClass(name=self.name)

    @classmethod
    def from_key_aspect(cls, key_aspect: "CorpGroupKeyClass") -> "CorpGroupUrn":
        return cls(name=key_aspect.name)

    @classmethod
    @deprecated(reason="Use the constructor instead")
    def create_from_id(cls, id: str) -> "CorpGroupUrn":
        return cls(id)

    @property
    def name(self) -> str:
        return self.entity_ids[0]

if TYPE_CHECKING:
    from datahub.metadata.schema_classes import DataProductKeyClass

class DataProductUrn(_SpecificUrn):
    ENTITY_TYPE: ClassVar[str] = "dataProduct"
    URN_PARTS: ClassVar[int] = 1

    def __init__(self, id: str, *, _allow_coercion: bool = True) -> None:
        if _allow_coercion:
            # Field coercion logic (if any is required).
            id = UrnEncoder.encode_string(id)

        # Validation logic.
        if not id:
            raise InvalidUrnError("id cannot be empty")
        assert not UrnEncoder.contains_reserved_char(id)

        super().__init__(self.ENTITY_TYPE, [id])

    @classmethod
    def _parse_ids(cls, entity_ids: List[str]) -> "DataProductUrn":
        if len(entity_ids) != cls.URN_PARTS:
            raise InvalidUrnError(f"DataProductUrn should have {cls.URN_PARTS} parts, got {len(entity_ids)}: {entity_ids}")
        return cls(id=entity_ids[0], _allow_coercion=False)

    @classmethod
    def underlying_key_aspect_type(cls) -> Type["DataProductKeyClass"]:
        from datahub.metadata.schema_classes import DataProductKeyClass

        return DataProductKeyClass

    def to_key_aspect(self) -> "DataProductKeyClass":
        from datahub.metadata.schema_classes import DataProductKeyClass

        return DataProductKeyClass(id=self.id)

    @classmethod
    def from_key_aspect(cls, key_aspect: "DataProductKeyClass") -> "DataProductUrn":
        return cls(id=key_aspect.id)

    @property
    def id(self) -> str:
        return self.entity_ids[0]

# fmt: on
