text: import { Type, defaultTags } from '../constants.js'
  import { YAMLSemanticError, YAMLWarning } from '../errors.js'
  
  function resolveTagHandle(doc, node) {
    const { handle, suffix } = node.tag
    let prefix = doc.tagPrefixes.find(p => p.handle === handle)
    if (!prefix) {
      const dtp = doc.getDefaults().tagPrefixes
      if (dtp) prefix = dtp.find(p => p.handle === handle)
      if (!prefix)
        throw new YAMLSemanticError(
          node,
          `The ${handle} tag handle is non-default and was not declared.`
        )
    }
    if (!suffix)
      throw new YAMLSemanticError(node, `The ${handle} tag has no suffix.`)
  
    if (handle === '!' && (doc.version || doc.options.version) === '1.0') {
      if (suffix[0] === '^') {
        doc.warnings.push(
          new YAMLWarning(node, 'YAML 1.0 ^ tag expansion is not supported')
        )
        return suffix
      }
      if (/[:/]/.test(suffix)) {
        // word/foo -> tag:word.yaml.org,2002:foo
        const vocab = suffix.match(/^([a-z0-9-]+)\/(.*)/i)
        return vocab
          ? `tag:${vocab[1]}.yaml.org,2002:${vocab[2]}`
          : `tag:${suffix}`
      }
    }
  
    return prefix.prefix + decodeURIComponent(suffix)
  }
  
  export function resolveTagName(doc, node) {
    const { tag, type } = node
    let nonSpecific = false
    if (tag) {
      const { handle, suffix, verbatim } = tag
      if (verbatim) {
        if (verbatim !== '!' && verbatim !== '!!') return verbatim
        const msg = `Verbatim tags aren't resolved, so ${verbatim} is invalid.`
        doc.errors.push(new YAMLSemanticError(node, msg))
      } else if (handle === '!' && !suffix) {
        nonSpecific = true
      } else {
        try {
          return resolveTagHandle(doc, node)
        } catch (error) {
          doc.errors.push(error)
        }
      }
    }
  
    switch (type) {
      case Type.BLOCK_FOLDED:
      case Type.BLOCK_LITERAL:
      case Type.QUOTE_DOUBLE:
      case Type.QUOTE_SINGLE:
        return defaultTags.STR
      case Type.FLOW_MAP:
      case Type.MAP:
        return defaultTags.MAP
      case Type.FLOW_SEQ:
      case Type.SEQ:
        return defaultTags.SEQ
      case Type.PLAIN:
        return nonSpecific ? defaultTags.STR : null
      default:
        return null
    }
  }
  