private static string GetTypeHint(TypeDecl decl, ElementDecl element)
        {
            string GetParamNamespace(TypeDecl declaration, IDeclKey key) =>
            !PyExtensions.IsPackageEquals(declaration, key) ? PyExtensions.GetAlias(key) + "." : "";

            string GetFinalHint(string typeHint) =>
            element.Vector == YesNo.Y ? $"List[{typeHint}]" : typeHint;

            if (element.Value != null)
            {
                string hint = GetValue(element.Value);
                return(GetFinalHint(hint));
            }
            else if (element.Data != null)
            {
                string paramNamespace = GetParamNamespace(decl, element.Data);
                string hint           = $"{paramNamespace}{element.Data.Name}";
                return(GetFinalHint(hint));
            }
            else if (element.Key != null)
            {
                return(GetFinalHint("str"));
            }
            else if (element.Enum != null)
            {
                string paramNamespace = GetParamNamespace(decl, element.Enum);
                string hint           = $"{paramNamespace}{element.Enum.Name}";
                return(GetFinalHint(hint));
            }
            else
            {
                throw new ArgumentException("Can't deduct type");
            }
        }
        public static string GetType(ElementDecl element)
        {
            string type = element.Value != null?GetValue(element.Value) :
                              element.Data != null  ? $"{element.Data.Name.Underscore()}_data" :
                              element.Key != null   ? $"{element.Key.Name.Underscore()}_key" :
                              element.Enum != null?element.Enum.Name.Underscore() :
                                  throw new ArgumentException("Can't deduct type");

            return(element.Vector == YesNo.Y ? $"dot::list<{type}>" : type);
        }
        private static string GetMetaData(ElementDecl element)
        {
            var meta = new List <string>();

            if (element.Optional == YesNo.Y)
            {
                meta.Add("'optional': True");
            }

            if (element.Value != null && (element.Value.Type == ValueParamType.Long ||
                                          element.Value.Type == ValueParamType.NullableLong))
            {
                meta.Add("'type': 'long'");
            }
            if (element.Value != null && (element.Value.Type == ValueParamType.Date ||
                                          element.Value.Type == ValueParamType.NullableDate))
            {
                meta.Add("'type': 'LocalDate'");
            }
            if (element.Value != null && (element.Value.Type == ValueParamType.Minute ||
                                          element.Value.Type == ValueParamType.NullableMinute))
            {
                meta.Add("'type': 'LocalMinute'");
            }
            if (element.Value != null && (element.Value.Type == ValueParamType.Time ||
                                          element.Value.Type == ValueParamType.NullableTime))
            {
                meta.Add("'type': 'LocalTime'");
            }
            if (element.Value != null && (element.Value.Type == ValueParamType.DateTime ||
                                          element.Value.Type == ValueParamType.NullableDateTime))
            {
                meta.Add("'type': 'LocalDateTime'");
            }
            if (element.Value != null && (element.Value.Type == ValueParamType.Instant ||
                                          element.Value.Type == ValueParamType.NullableInstant))
            {
                meta.Add("'type': 'Instant'");
            }

            if (element.Key != null)
            {
                meta.Add($"'key': '{element.Key.Name}'");
            }

            return(meta.Any()
                ? $", metadata={{{string.Join(", ", meta)}}}"
                : "");
        }