// Copyright 2019 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "libipp/ipp_parser.h"
#include <set>

#include "libipp/frame.h"
#include "libipp/ipp_encoding.h"

namespace ipp {

namespace {

// This parameter defines how deep can be a package with recursive collections.
// A collection placed directly in attributes group has level 1, each
// sub-collection belonging directly to it has level 2 etc..
constexpr int kMaxCollectionLevel = 16;

// Decodes 1-, 2- or 4-bytes integers (two's-complement binary encoding).
// Returns false if (data.size() != BytesCount) or (out == nullptr).
template <size_t BytesCount>
bool LoadInteger(const std::vector<uint8_t>& data, int32_t* out) {
  if ((data.size() != BytesCount) || (out == nullptr))
    return false;
  const uint8_t* ptr = data.data();
  ParseSignedInteger<BytesCount>(&ptr, out);
  return true;
}

// Reads simple string from buf.
std::string LoadString(const std::vector<uint8_t>& buf) {
  return std::string(buf.data(), buf.data() + buf.size());
}

// Reads textWithLanguage/nameWithLanguage (see [rfc8010], section 3.9) from
// buf. Returns false if given content is invalid or (out == nullptr).
bool LoadStringWithLanguage(const std::vector<uint8_t>& buf,
                            ipp::StringWithLanguage* out) {
  // The shortest possible value has 4 bytes: 2 times 2-bytes zero.
  if ((buf.size() < 4) || (out == nullptr))
    return false;
  const uint8_t* ptr = buf.data();
  size_t length;
  if (!ParseUnsignedInteger<2>(&ptr, &length))
    return false;
  if (buf.size() < 4 + length)
    return false;
  out->language.assign(ptr, ptr + length);
  ptr += length;
  if (!ParseUnsignedInteger<2>(&ptr, &length))
    return false;
  if (buf.size() != 4 + out->language.size() + length)
    return false;
  out->value.assign(ptr, ptr + length);
  return true;
}

// Reads dateTime (see [rfc8010]) from buf.
// Fails when binary representation has invalid size or (out == nullptr).
bool LoadDateTime(const std::vector<uint8_t>& buf, ipp::DateTime* out) {
  if ((buf.size() != 11) || (out == nullptr))
    return false;
  const uint8_t* ptr = buf.data();
  return (ParseUnsignedInteger<2>(&ptr, &out->year) &&
          ParseUnsignedInteger<1>(&ptr, &out->month) &&
          ParseUnsignedInteger<1>(&ptr, &out->day) &&
          ParseUnsignedInteger<1>(&ptr, &out->hour) &&
          ParseUnsignedInteger<1>(&ptr, &out->minutes) &&
          ParseUnsignedInteger<1>(&ptr, &out->seconds) &&
          ParseUnsignedInteger<1>(&ptr, &out->deci_seconds) &&
          ParseUnsignedInteger<1>(&ptr, &out->UTC_direction) &&
          ParseUnsignedInteger<1>(&ptr, &out->UTC_hours) &&
          ParseUnsignedInteger<1>(&ptr, &out->UTC_minutes));
}

// Reads resolution (see [rfc8010]) from buf.
// Fails when binary representation has invalid size or (out == nullptr).
bool LoadResolution(const std::vector<uint8_t>& buf, ipp::Resolution* out) {
  if ((buf.size() != 9) || (out == nullptr))
    return false;
  const uint8_t* ptr = buf.data();
  ParseSignedInteger<4>(&ptr, &out->xres);
  ParseSignedInteger<4>(&ptr, &out->yres);
  int8_t units;
  ParseSignedInteger<1>(&ptr, &units);
  out->units = static_cast<Resolution::Units>(units);
  return true;
}

// Reads rangeOfInteger (see [rfc8010]) from buf.
// Fails when binary representation has invalid size or (out == nullptr).
bool LoadRangeOfInteger(const std::vector<uint8_t>& buf,
                        ipp::RangeOfInteger* out) {
  if ((buf.size() != 8) || (out == nullptr))
    return false;
  const uint8_t* ptr = buf.data();
  ParseSignedInteger<4>(&ptr, &out->min_value);
  ParseSignedInteger<4>(&ptr, &out->max_value);
  return true;
}

// Scope guard to control the context path. Constructor adds new a element to
// the path while destructor removes it from the path.
class ContextPathGuard {
 public:
  ContextPathGuard(AttrPath* path, uint16_t index) : path_(path) {
    path_->PushBack(index, "");
  }
  ~ContextPathGuard() { path_->PopBack(); }

 private:
  ContextPathGuard(const ContextPathGuard&) = delete;
  ContextPathGuard(ContextPathGuard&&) = delete;
  ContextPathGuard& operator=(const ContextPathGuard&) = delete;
  ContextPathGuard& operator=(ContextPathGuard&&) = delete;
  AttrPath* path_;
};

// Return true if source type can be used in attribute of target type.
bool IsConvertibleTo(const ipp::ValueTag source, const ipp::ValueTag target) {
  if (source == target)
    return true;
  if (source == ipp::ValueTag::integer &&
      target == ipp::ValueTag::rangeOfInteger)
    return true;
  if (source == ipp::ValueTag::integer && target == ipp::ValueTag::enum_)
    return true;
  if (source == ipp::ValueTag::nameWithoutLanguage &&
      target == ipp::ValueTag::nameWithLanguage)
    return true;
  if (source == ipp::ValueTag::textWithoutLanguage &&
      target == ipp::ValueTag::textWithLanguage)
    return true;
  return false;
}

// Parses two bytes from `ptr` and move it forward by 2 bytes.
uint16_t ParseUInt16(const uint8_t*& ptr) {
  uint16_t val = *ptr;
  val <<= 8;
  val += *++ptr;
  ++ptr;
  return val;
}

}  //  namespace

void Parser::LogParserError(ParserCode error_code, const uint8_t* ptr) {
  ssize_t buf_offset = -1;
  if (ptr != nullptr && ptr >= buffer_begin_ && ptr <= buffer_end_) {
    // Current position in the buffer.
    buf_offset = ptr - buffer_begin_;
  }
  log_->AddParserError({parser_context_, error_code, buf_offset});
}

void Parser::LogParserErrors(const std::vector<ParserCode>& error_codes) {
  for (ParserCode error_code : error_codes) {
    LogParserError(error_code);
  }
}

// Temporary representation of an attribute's value parsed from TNVs.
struct RawValue {
  // original tag (IsValid(tag))
  ValueTag tag;
  // original data, empty when (tag == collection), content not verified
  std::vector<uint8_t> data;
  // (not nullptr) <=> (tag == collection)
  std::unique_ptr<RawCollection> collection;
  // create as standard value
  RawValue(ValueTag tag, const std::vector<uint8_t>& data)
      : tag(tag), data(data) {}
  // create as collection
  explicit RawValue(RawCollection* coll)
      : tag(ValueTag::collection), collection(coll) {}
};

struct RawCollection;

// Temporary representation of an attribute parsed from TNVs.
struct RawAttribute {
  // verified (non-empty)
  std::string name;
  // parsed values (see RawValue)
  std::vector<RawValue> values;
  explicit RawAttribute(const std::string& name) : name(name) {}
};

// Temporary representation of a collection parsed from TNVs.
struct RawCollection {
  // parsed attributes (may have duplicate names)
  std::vector<RawAttribute> attributes;
};

// Parse a value of type `attr_type` from `raw_value` to `output` when possible.
// Returns true <=> parsing was successful. All spotted errors are added to
// `errors`.
template <typename ApiType>
bool LoadAttrValue(ValueTag attr_type,
                   const RawValue& raw_value,
                   ApiType& output,
                   std::vector<ParserCode>& errors);

template <>
bool LoadAttrValue<std::string>(ValueTag attr_type,
                                const RawValue& raw_value,
                                std::string& output,
                                std::vector<ParserCode>& errors) {
  if (!IsString(raw_value.tag) && raw_value.tag != ValueTag::octetString) {
    errors.push_back(ParserCode::kValueMismatchTagOmitted);
    return false;
  }
  output = LoadString(raw_value.data);
  if (attr_type != raw_value.tag)
    errors.push_back(ParserCode::kValueMismatchTagConverted);
  return true;
}

template <>
bool LoadAttrValue<int32_t>(ValueTag attr_type,
                            const RawValue& raw_value,
                            int32_t& output,
                            std::vector<ParserCode>& errors) {
  switch (raw_value.tag) {
    case ValueTag::boolean: {
      if (!LoadInteger<1>(raw_value.data, &output)) {
        errors.push_back(ParserCode::kValueInvalidSize);
        return false;
      }
      if (attr_type != ValueTag::boolean) {
        errors.push_back(ParserCode::kValueMismatchTagConverted);
      }
      if (output < 0 || output > 1) {
        output = 1;
        errors.push_back(ParserCode::kBooleanValueOutOfRange);
      }
      return true;
    }
    case ValueTag::integer:
    case ValueTag::enum_: {
      if (!LoadInteger<4>(raw_value.data, &output)) {
        errors.push_back(ParserCode::kValueInvalidSize);
        return false;
      }
      if (attr_type != raw_value.tag) {
        errors.push_back(ParserCode::kValueMismatchTagConverted);
      }
      return true;
    }
    default:
      errors.push_back(ParserCode::kValueMismatchTagOmitted);
      return false;
  }
}

template <>
bool LoadAttrValue<DateTime>(ValueTag attr_type,
                             const RawValue& raw_value,
                             DateTime& output,
                             std::vector<ParserCode>& errors) {
  if (raw_value.tag != ValueTag::dateTime) {
    errors.push_back(ParserCode::kValueMismatchTagOmitted);
    return false;
  }
  if (!LoadDateTime(raw_value.data, &output)) {
    errors.push_back(ParserCode::kValueInvalidSize);
    return false;
  }
  return true;
}

template <>
bool LoadAttrValue<Resolution>(ValueTag attr_type,
                               const RawValue& raw_value,
                               Resolution& output,
                               std::vector<ParserCode>& errors) {
  if (raw_value.tag != ValueTag::resolution) {
    errors.push_back(ParserCode::kValueMismatchTagOmitted);
    return false;
  }
  if (!LoadResolution(raw_value.data, &output)) {
    errors.push_back(ParserCode::kValueInvalidSize);
    return false;
  }
  return true;
}

template <>
bool LoadAttrValue<RangeOfInteger>(ValueTag attr_type,
                                   const RawValue& raw_value,
                                   RangeOfInteger& output,
                                   std::vector<ParserCode>& errors) {
  if (raw_value.tag == ValueTag::integer) {
    if (!LoadInteger<4>(raw_value.data, &output.min_value)) {
      errors.push_back(ParserCode::kValueInvalidSize);
      return false;
    }
    output.max_value = output.min_value;
    return true;
  }
  if (raw_value.tag != ValueTag::rangeOfInteger) {
    errors.push_back(ParserCode::kValueMismatchTagOmitted);
    return false;
  }
  if (!LoadRangeOfInteger(raw_value.data, &output)) {
    errors.push_back(ParserCode::kValueInvalidSize);
    return false;
  }
  return true;
}

template <>
bool LoadAttrValue<StringWithLanguage>(ValueTag attr_type,
                                       const RawValue& raw_value,
                                       StringWithLanguage& output,
                                       std::vector<ParserCode>& errors) {
  if (raw_value.tag == ValueTag::nameWithLanguage ||
      raw_value.tag == ValueTag::textWithLanguage) {
    if (!LoadStringWithLanguage(raw_value.data, &output)) {
      errors.push_back(ParserCode::kValueInvalidSize);
      return false;
    }
    if (raw_value.tag != attr_type) {
      errors.push_back(ParserCode::kValueMismatchTagConverted);
    }
    return true;
  }
  if (IsString(raw_value.tag)) {
    output.language.clear();
    output.value = LoadString(raw_value.data);
    if (raw_value.tag == ValueTag::nameWithoutLanguage &&
        attr_type != ValueTag::nameWithLanguage) {
      errors.push_back(ParserCode::kValueMismatchTagConverted);
    }
    if (raw_value.tag == ValueTag::textWithoutLanguage &&
        attr_type != ValueTag::textWithLanguage) {
      errors.push_back(ParserCode::kValueMismatchTagConverted);
    }
    return true;
  }
  errors.push_back(ParserCode::kValueMismatchTagOmitted);
  return false;
}

// Parse an attribute of type `attr_type` from `raw_attr` and add it to `coll`
// when possible. Return a list of parser errors. `coll` must not be nullptr.
template <typename ApiType>
std::vector<ParserCode> LoadAttrValues(Collection* coll,
                                       ValueTag attr_type,
                                       const RawAttribute& raw_attr) {
  std::vector<ParserCode> errors;
  std::vector<ApiType> vals;
  vals.reserve(raw_attr.values.size());
  for (const RawValue& raw_value : raw_attr.values) {
    ApiType val;
    if (LoadAttrValue<ApiType>(attr_type, raw_value, val, errors)) {
      vals.push_back(std::move(val));
    }
  }
  if (vals.empty()) {
    errors.push_back(ParserCode::kAttributeNoValues);
  } else {
    const Code err = coll->AddAttr(raw_attr.name, attr_type, vals);
    if (err != Code::kOK) {
      errors.push_back(ParserCode::kErrorWhenAddingAttribute);
    }
  }
  return errors;
}

bool Parser::SaveFrameToPackage(Frame* package) {
  for (size_t i = 0; i < frame_->groups_tags_.size(); ++i) {
    GroupTag gn = frame_->groups_tags_[i];
    parser_context_ = AttrPath(gn);
    parser_context_.PushBack(package->Groups(gn).size(), "");
    CollsView::iterator coll;
    Code err = package->AddGroup(gn, coll);
    if (err != Code::kOK) {
      LogParserError(ParserCode::kErrorWhenAddingGroup);
      continue;
    }
    RawCollection raw_coll;
    if (!ParseRawGroup(&(frame_->groups_content_[i]), &raw_coll)) {
      return false;
    }
    DecodeCollection(&raw_coll, &*coll);
  }
  package->SetData(std::move(frame_->data_));
  return true;
}

bool Parser::ReadFrameFromBuffer(const uint8_t* ptr,
                                 const uint8_t* const buf_end) {
  parser_context_ = AttrPath(AttrPath::kHeader);
  buffer_begin_ = ptr;
  buffer_end_ = buf_end;
  if (buf_end - ptr < 9) {
    LogParserError(ParserCode::kUnexpectedEndOfFrame, ptr);
    return false;
  }
  frame_->version_ = ParseUInt16(ptr);
  ParseSignedInteger<2>(&ptr, &frame_->operation_id_or_status_code_);
  ParseSignedInteger<4>(&ptr, &frame_->request_id_);
  while (*ptr != end_of_attributes_tag) {
    GroupTag group_tag = static_cast<GroupTag>(*ptr);
    parser_context_ = AttrPath(group_tag);
    if (!IsValid(group_tag)) {
      // begin-attribute-group-tag was expected.
      LogParserError(ParserCode::kGroupTagWasExpected, ptr);
      return false;
    }
    if (frame_->groups_tags_.size() >= kMaxCountOfAttributeGroups) {
      LogParserError(ParserCode::kLimitOnGroupsCountExceeded, ptr);
      return false;
    }
    frame_->groups_tags_.push_back(group_tag);
    frame_->groups_content_.resize(frame_->groups_tags_.size());
    ++ptr;
    if (!ReadTNVsFromBuffer(&ptr, buf_end, &(frame_->groups_content_.back())))
      return false;
    if (ptr >= buf_end) {
      // begin-attribute-group-tag or end-of-attributes-tag was expected.
      LogParserError(ParserCode::kUnexpectedEndOfFrame);
      return false;
    }
  }
  ++ptr;
  frame_->data_.assign(ptr, buf_end);
  ptr = buf_end;
  return true;
}

// Parses TNVs from given buffer until the end of the buffer is reached or next
// begin-attribute-group-tag is spotted. The pointer ptr is shifted accordingly.
// returns true <=> (ptr == buf_end) or (*ptr is begin-attribute-group-tag)
// returns false <=> parsing error occurs, ptr points to incorrect field
// Parsed TNVs are added to the end of |tnvs|. If |tnvs| is nullptr then no
// output is saved but parsing occurs as usual.
bool Parser::ReadTNVsFromBuffer(const uint8_t** ptr2,
                                const uint8_t* const buf_end,
                                std::list<TagNameValue>* tnvs) {
  const uint8_t*& ptr = *ptr2;
  while ((ptr < buf_end) && (*ptr > max_begin_attribute_group_tag)) {
    TagNameValue tnv;

    if (buf_end - ptr < 5) {
      // Expected at least 1-byte tag, 2-bytes name-length and 2-bytes
      // value-length.
      LogParserError(ParserCode::kUnexpectedEndOfFrame, ptr);
      return false;
    }
    // *ptr is a ValueTag because it was already checked in while (...)
    tnv.tag = *ptr;
    ++ptr;
    int length = 0;
    if (!ParseUnsignedInteger<2>(&ptr, &length)) {
      LogParserError(ParserCode::kNegativeNameLengthInTNV, ptr);
      return false;
    }
    if (buf_end - ptr < length + 2) {
      // Expected at least `length`-bytes name and 2-bytes value-length.
      LogParserError(ParserCode::kUnexpectedEndOfFrame, ptr);
      return false;
    }
    tnv.name.assign(ptr, ptr + length);
    ptr += length;
    if (!ParseUnsignedInteger<2>(&ptr, &length)) {
      LogParserError(ParserCode::kNegativeValueLengthInTNV, ptr);
      return false;
    }
    if (buf_end - ptr < length) {
      LogParserError(ParserCode::kUnexpectedEndOfFrame, ptr);
      return false;
    }
    tnv.value.assign(ptr, ptr + length);
    ptr += length;
    if (tnvs != nullptr)
      tnvs->push_back(std::move(tnv));
  }
  return true;
}

void Parser::ResetContent() {
  buffer_begin_ = nullptr;
  buffer_end_ = nullptr;
  parser_context_ = AttrPath(AttrPath::kHeader);
}

// Parses single attribute's value and add it to |attr|. |tnv| is the first TNV
// with the value, |tnvs| contains all following TNVs. Both |tnvs| and |attr|
// cannot be nullptr. |coll_level| denotes how "deep" is the collection that
// contains the attribute; attributes defined directly in the attributes group
// have level 0. Returns false <=> critical parsing error was spotted.
// See section 3.5.2 from rfc8010 for details.
bool Parser::ParseRawValue(int coll_level,
                           const TagNameValue& tnv,
                           std::list<TagNameValue>* tnvs,
                           RawAttribute* attr) {
  // Is it correct attribute's value tag? If not then fail.
  if (tnv.tag == endCollection_value_tag ||
      tnv.tag == memberAttrName_value_tag) {
    LogParserError(ParserCode::kTNVWithUnexpectedValueTag);
    return false;
  }
  // Is it a collection ?
  if (tnv.tag == begCollection_value_tag) {
    ContextPathGuard path_update(&parser_context_, attr->values.size());
    if (!tnv.value.empty()) {
      LogParserError(ParserCode::kEmptyValueExpectedInTNV);
      return false;
    }
    std::unique_ptr<RawCollection> coll(new RawCollection);
    if (!ParseRawCollection(coll_level + 1, tnvs, coll.get()))
      return false;
    attr->values.emplace_back(coll.release());
    return true;
  }
  ValueTag type = static_cast<ValueTag>(tnv.tag);
  if (!IsValid(type)) {
    // unknown attribute's syntax
    LogParserError(ParserCode::kUnsupportedValueTag);
    return true;
  }
  attr->values.emplace_back(type, tnv.value);
  return true;
}

// Parses single collections from given TNVs. |coll_level| denotes how "deep"
// the collection is; collections defined directly in the attributes group
// have level 1. Both |tnvs| and |coll| cannot be nullptr.
// Returns false <=> critical parsing error was spotted.
bool Parser::ParseRawCollection(int coll_level,
                                std::list<TagNameValue>* tnvs,
                                RawCollection* coll) {
  if (coll_level > kMaxCollectionLevel) {
    LogParserError(ParserCode::kLimitOnCollectionsLevelExceeded);
    return false;
  }
  while (true) {
    if (tnvs->empty()) {
      LogParserError(ParserCode::kUnexpectedEndOfGroup);
      return false;
    }
    TagNameValue tnv = tnvs->front();
    tnvs->pop_front();
    // exit if the end of the collection was reached
    if (tnv.tag == endCollection_value_tag) {
      if (!tnv.name.empty()) {
        LogParserError(ParserCode::kEmptyNameExpectedInTNV);
        return false;
      }
      if (!tnv.value.empty()) {
        LogParserError(ParserCode::kEmptyValueExpectedInTNV);
        return false;
      }
      return true;
    }
    // still here, so we parse an attribute (collection's member)
    if (tnv.tag != memberAttrName_value_tag) {
      LogParserError(ParserCode::kTNVWithUnexpectedValueTag);
      return false;
    }
    // parse name & create attribute
    const std::string name = LoadString(tnv.value);
    parser_context_.Back().attribute_name = name;
    if (!tnv.name.empty()) {
      LogParserError(ParserCode::kEmptyNameExpectedInTNV);
      return false;
    }
    if (name.empty()) {
      LogParserErrors({ParserCode::kAttributeNameIsEmpty});
      return false;
    }
    coll->attributes.emplace_back(name);
    RawAttribute* attr = &coll->attributes.back();
    // parse tag
    if (tnvs->empty()) {
      LogParserError(ParserCode::kUnexpectedEndOfGroup);
      return false;
    }
    // parse all values
    while (!tnvs->empty() && tnvs->front().tag != endCollection_value_tag &&
           tnvs->front().tag != memberAttrName_value_tag) {
      tnv = tnvs->front();
      tnvs->pop_front();
      if (!tnv.name.empty()) {
        LogParserError(ParserCode::kEmptyNameExpectedInTNV);
        return false;
      }
      if (!ParseRawValue(coll_level, tnv, tnvs, attr))
        return false;
    }
  }
}

// Parses attributes group from given TNVs and saves it to |coll|. Both |tnvs|
// and |coll| cannot be nullptr. Returns false <=> critical parsing error was
// spotted.
bool Parser::ParseRawGroup(std::list<TagNameValue>* tnvs, RawCollection* coll) {
  while (!tnvs->empty()) {
    TagNameValue tnv = tnvs->front();
    tnvs->pop_front();
    // parse name & create attribute
    const std::string name = LoadString(tnv.name);
    parser_context_.Back().attribute_name = name;
    if (name.empty()) {
      LogParserErrors({ParserCode::kAttributeNameIsEmpty});
      return false;
    }
    coll->attributes.emplace_back(name);
    RawAttribute* attr = &coll->attributes.back();
    // parse all values
    while (true) {
      // parse value
      if (!ParseRawValue(0 /*collection level*/, tnv, tnvs, attr))
        return false;
      // go to the next value or attribute
      if (tnvs->empty() || !tnvs->front().name.empty())
        break;  // end of the attribute
      // next value
      tnv = tnvs->front();
      tnvs->pop_front();
    }
  }
  return true;
}

// Converts a collection/group saved in |raw_coll| to |coll|. Both |raw_coll|
// and |coll| must not be nullptr.
void Parser::DecodeCollection(RawCollection* raw_coll, Collection* coll) {
  for (RawAttribute& raw_attr : raw_coll->attributes) {
    // Tries to match the attribute to existing one by name.
    parser_context_.Back().attribute_name = raw_attr.name;
    if (coll->GetAttr(raw_attr.name) != coll->end()) {
      // The attribute exists.
      LogParserErrors({ParserCode::kAttributeNameConflict});
      continue;
    }

    if (raw_attr.values.empty()) {
      LogParserErrors({ParserCode::kAttributeNoValues});
      continue;
    }

    // Tries to detect an attribute's type.
    ValueTag detected_type = raw_attr.values.front().tag;
    for (auto& raw_val : raw_attr.values)
      if (IsConvertibleTo(detected_type, raw_val.tag))
        detected_type = raw_val.tag;

    // Is it an attribute with Ouf-Of-Band value? Then set it and finish.
    if (IsOutOfBand(detected_type)) {
      if (raw_attr.values.size() > 1) {
        LogParserError(ParserCode::kOutOfBandAttributeWithManyValues);
      }
      if (!raw_attr.values.front().data.empty()) {
        LogParserError(ParserCode::kOutOfBandValueWithNonEmptyData);
      }
      const Code err = coll->AddAttr(raw_attr.name, detected_type);
      if (err != Code::kOK) {
        LogParserErrors({ParserCode::kErrorWhenAddingAttribute});
      }
      continue;
    }

    // It is a collection?
    if (detected_type == ValueTag::collection) {
      std::vector<ParserCode> errors;
      std::vector<RawCollection*> raw_colls;
      raw_colls.reserve(raw_attr.values.size());
      for (const RawValue& raw_value : raw_attr.values) {
        if (raw_value.collection) {
          raw_colls.push_back(raw_value.collection.get());
        } else {
          errors.push_back(ParserCode::kValueMismatchTagOmitted);
        }
      }
      CollsView colls;
      Code err = coll->AddAttr(raw_attr.name, raw_colls.size(), colls);
      if (err == Code::kOK) {
        for (size_t i = 0; i < colls.size(); ++i) {
          ContextPathGuard path_update(&parser_context_, i);
          DecodeCollection(raw_colls[i], &colls[i]);
        }
      } else {
        errors.push_back(ParserCode::kErrorWhenAddingAttribute);
      }
      LogParserErrors(errors);
      continue;
    }

    // It is an attribute with standard values. Parse the values and create
    // a new attribute.
    if (IsInteger(detected_type)) {
      LogParserErrors(LoadAttrValues<int32_t>(coll, detected_type, raw_attr));
      continue;
    }
    if (IsString(detected_type) || detected_type == ValueTag::octetString) {
      LogParserErrors(
          LoadAttrValues<std::string>(coll, detected_type, raw_attr));
      continue;
    }
    switch (detected_type) {
      case ValueTag::dateTime:
        LogParserErrors(
            LoadAttrValues<DateTime>(coll, detected_type, raw_attr));
        break;
      case ValueTag::resolution:
        LogParserErrors(
            LoadAttrValues<Resolution>(coll, detected_type, raw_attr));
        break;
      case ValueTag::rangeOfInteger:
        LogParserErrors(
            LoadAttrValues<RangeOfInteger>(coll, detected_type, raw_attr));
        break;
      case ValueTag::nameWithLanguage:
      case ValueTag::textWithLanguage:
        LogParserErrors(
            LoadAttrValues<StringWithLanguage>(coll, detected_type, raw_attr));
        break;
      default:
        LogParserErrors({ParserCode::kErrorWhenAddingAttribute});
        break;
    }
  }
}

}  // namespace ipp
