// Copyright (c) 2009-2017 The OTS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "silf.h"

#include "name.h"
#include "lz4.h"
#include <cmath>

namespace ots {

bool OpenTypeSILF::Parse(const uint8_t* data, size_t length,
                         bool prevent_decompression) {
  if (GetFont()->dropped_graphite) {
    return Drop("Skipping Graphite table");
  }
  Buffer table(data, length);

  if (!table.ReadU32(&this->version)) {
    return DropGraphite("Failed to read version");
  }
  if (this->version >> 16 != 1 &&
      this->version >> 16 != 2 &&
      this->version >> 16 != 3 &&
      this->version >> 16 != 4 &&
      this->version >> 16 != 5) {
    return DropGraphite("Unsupported table version: %u", this->version >> 16);
  }
  if (this->version >> 16 >= 3 && !table.ReadU32(&this->compHead)) {
    return DropGraphite("Failed to read compHead");
  }
  if (this->version >> 16 >= 5) {
    switch ((this->compHead & SCHEME) >> 27) {
      case 0:  // uncompressed
        break;
      case 1: {  // lz4
        if (prevent_decompression) {
          return DropGraphite("Illegal nested compression");
        }
        std::vector<uint8_t> decompressed(this->compHead & FULL_SIZE);
        int ret = LZ4_decompress_safe_partial(
            reinterpret_cast<const char*>(data + table.offset()),
            reinterpret_cast<char*>(decompressed.data()),
            table.remaining(),  // input buffer size (input size + padding)
            decompressed.size(),  // target output size
            decompressed.size());  // output buffer size
        if (ret != decompressed.size()) {
          return DropGraphite("Decompression failed with error code %d", ret);
        }
        return this->Parse(decompressed.data(), decompressed.size(), true);
      }
      default:
        return DropGraphite("Unknown compression scheme");
    }
  }
  if (!table.ReadU16(&this->numSub)) {
    return DropGraphite("Failed to read numSub");
  }
  if (this->version >> 16 >= 2 && !table.ReadU16(&this->reserved)) {
    return DropGraphite("Failed to read reserved");
  }
  if (this->version >> 16 >= 2 && this->reserved != 0) {
    Warning("Nonzero reserved");
  }

  unsigned long last_offset = 0;
  //this->offset.resize(this->numSub);
  for (unsigned i = 0; i < this->numSub; ++i) {
    this->offset.emplace_back();
    if (!table.ReadU32(&this->offset[i]) || this->offset[i] < last_offset) {
      return DropGraphite("Failed to read offset[%u]", i);
    }
    last_offset = this->offset[i];
  }

  for (unsigned i = 0; i < this->numSub; ++i) {
    if (table.offset() != this->offset[i]) {
      return DropGraphite("Offset check failed for tables[%lu]", i);
    }
    SILSub subtable(this);
    if (!subtable.ParsePart(table)) {
      return DropGraphite("Failed to read tables[%u]", i);
    }
    tables.push_back(subtable);
  }

  if (table.remaining()) {
    return Warning("%zu bytes unparsed", table.remaining());
  }
  return true;
}

bool OpenTypeSILF::Serialize(OTSStream* out) {
  if (!out->WriteU32(this->version) ||
      (this->version >> 16 >= 3 && !out->WriteU32(this->compHead)) ||
      !out->WriteU16(this->numSub) ||
      (this->version >> 16 >= 2 && !out->WriteU16(this->reserved)) ||
      !SerializeParts(this->offset, out) ||
      !SerializeParts(this->tables, out)) {
    return Error("Failed to write table");
  }
  return true;
}

bool OpenTypeSILF::SILSub::ParsePart(Buffer& table) {
  size_t init_offset = table.offset();
  if (parent->version >> 16 >= 3) {
    if (!table.ReadU32(&this->ruleVersion)) {
      return parent->Error("SILSub: Failed to read ruleVersion");
    }
    if (!table.ReadU16(&this->passOffset)) {
      return parent->Error("SILSub: Failed to read passOffset");
    }
    if (!table.ReadU16(&this->pseudosOffset)) {
      return parent->Error("SILSub: Failed to read pseudosOffset");
    }
  }
  if (!table.ReadU16(&this->maxGlyphID)) {
    return parent->Error("SILSub: Failed to read maxGlyphID");
  }
  if (!table.ReadS16(&this->extraAscent)) {
    return parent->Error("SILSub: Failed to read extraAscent");
  }
  if (!table.ReadS16(&this->extraDescent)) {
    return parent->Error("SILSub: Failed to read extraDescent");
  }
  if (!table.ReadU8(&this->numPasses)) {
    return parent->Error("SILSub: Failed to read numPasses");
  }
  if (!table.ReadU8(&this->iSubst) || this->iSubst > this->numPasses) {
    return parent->Error("SILSub: Failed to read valid iSubst");
  }
  if (!table.ReadU8(&this->iPos) || this->iPos > this->numPasses) {
    return parent->Error("SILSub: Failed to read valid iPos");
  }
  if (!table.ReadU8(&this->iJust) || this->iJust > this->numPasses) {
    return parent->Error("SILSub: Failed to read valid iJust");
  }
  if (!table.ReadU8(&this->iBidi) ||
      !(iBidi == 0xFF || this->iBidi <= this->iPos)) {
    return parent->Error("SILSub: Failed to read valid iBidi");
  }
  if (!table.ReadU8(&this->flags)) {
    return parent->Error("SILSub: Failed to read flags");
    // checks omitted
  }
  if (!table.ReadU8(&this->maxPreContext)) {
    return parent->Error("SILSub: Failed to read maxPreContext");
  }
  if (!table.ReadU8(&this->maxPostContext)) {
    return parent->Error("SILSub: Failed to read maxPostContext");
  }
  if (!table.ReadU8(&this->attrPseudo)) {
    return parent->Error("SILSub: Failed to read attrPseudo");
  }
  if (!table.ReadU8(&this->attrBreakWeight)) {
    return parent->Error("SILSub: Failed to read attrBreakWeight");
  }
  if (!table.ReadU8(&this->attrDirectionality)) {
    return parent->Error("SILSub: Failed to read attrDirectionality");
  }
  if (parent->version >> 16 >= 2) {
    if (!table.ReadU8(&this->attrMirroring)) {
      return parent->Error("SILSub: Failed to read attrMirroring");
    }
    if (parent->version >> 16 < 4 && this->attrMirroring != 0) {
      parent->Warning("SILSub: Nonzero attrMirroring (reserved before v4)");
    }
    if (!table.ReadU8(&this->attrSkipPasses)) {
      return parent->Error("SILSub: Failed to read attrSkipPasses");
    }
    if (parent->version >> 16 < 4 && this->attrSkipPasses != 0) {
      parent->Warning("SILSub: Nonzero attrSkipPasses (reserved2 before v4)");
    }

    if (!table.ReadU8(&this->numJLevels)) {
      return parent->Error("SILSub: Failed to read numJLevels");
    }
    //this->jLevels.resize(this->numJLevels, parent);
    for (unsigned i = 0; i < this->numJLevels; ++i) {
      this->jLevels.emplace_back(parent);
      if (!this->jLevels[i].ParsePart(table)) {
        return parent->Error("SILSub: Failed to read jLevels[%u]", i);
      }
    }
  }

  if (!table.ReadU16(&this->numLigComp)) {
    return parent->Error("SILSub: Failed to read numLigComp");
  }
  if (!table.ReadU8(&this->numUserDefn)) {
    return parent->Error("SILSub: Failed to read numUserDefn");
  }
  if (!table.ReadU8(&this->maxCompPerLig)) {
    return parent->Error("SILSub: Failed to read maxCompPerLig");
  }
  if (!table.ReadU8(&this->direction)) {
    return parent->Error("SILSub: Failed to read direction");
  }
  if (!table.ReadU8(&this->attCollisions)) {
    return parent->Error("SILSub: Failed to read attCollisions");
  }
  if (parent->version >> 16 < 5 && this->attCollisions != 0) {
    parent->Warning("SILSub: Nonzero attCollisions (reserved before v5)");
  }
  if (!table.ReadU8(&this->reserved4)) {
    return parent->Error("SILSub: Failed to read reserved4");
  }
  if (this->reserved4 != 0) {
    parent->Warning("SILSub: Nonzero reserved4");
  }
  if (!table.ReadU8(&this->reserved5)) {
    return parent->Error("SILSub: Failed to read reserved5");
  }
  if (this->reserved5 != 0) {
    parent->Warning("SILSub: Nonzero reserved5");
  }
  if (parent->version >> 16 >= 2) {
    if (!table.ReadU8(&this->reserved6)) {
      return parent->Error("SILSub: Failed to read reserved6");
    }
    if (this->reserved6 != 0) {
      parent->Warning("SILSub: Nonzero reserved6");
    }

    if (!table.ReadU8(&this->numCritFeatures)) {
      return parent->Error("SILSub: Failed to read numCritFeatures");
    }
    //this->critFeatures.resize(this->numCritFeatures);
    for (unsigned i = 0; i < this->numCritFeatures; ++i) {
      this->critFeatures.emplace_back();
      if (!table.ReadU16(&this->critFeatures[i])) {
        return parent->Error("SILSub: Failed to read critFeatures[%u]", i);
      }
    }

    if (!table.ReadU8(&this->reserved7)) {
      return parent->Error("SILSub: Failed to read reserved7");
    }
    if (this->reserved7 != 0) {
      parent->Warning("SILSub: Nonzero reserved7");
    }
  }

  if (!table.ReadU8(&this->numScriptTag)) {
    return parent->Error("SILSub: Failed to read numScriptTag");
  }
  //this->scriptTag.resize(this->numScriptTag);
  for (unsigned i = 0; i < this->numScriptTag; ++i) {
    this->scriptTag.emplace_back();
    if (!table.ReadU32(&this->scriptTag[i])) {
      return parent->Error("SILSub: Failed to read scriptTag[%u]", i);
    }
  }

  if (!table.ReadU16(&this->lbGID)) {
    return parent->Error("SILSub: Failed to read lbGID");
  }
  if (this->lbGID > this->maxGlyphID) {
    parent->Warning("SILSub: lbGID %u outside range 0..%u, replaced with 0",
                    this->lbGID, this->maxGlyphID);
    this->lbGID = 0;
  }

  if (parent->version >> 16 >= 3 &&
      table.offset() != init_offset + this->passOffset) {
    return parent->Error("SILSub: passOffset check failed");
  }
  unsigned long last_oPass = 0;
  //this->oPasses.resize(static_cast<unsigned>(this->numPasses) + 1);
  for (unsigned i = 0; i <= this->numPasses; ++i) {
    this->oPasses.emplace_back();
    if (!table.ReadU32(&this->oPasses[i]) || this->oPasses[i] < last_oPass) {
      return false;
    }
    last_oPass = this->oPasses[i];
  }

  if (parent->version >> 16 >= 3 &&
      table.offset() != init_offset + this->pseudosOffset) {
    return parent->Error("SILSub: pseudosOffset check failed");
  }
  if (!table.ReadU16(&this->numPseudo)) {
    return parent->Error("SILSub: Failed to read numPseudo");
  }

  // The following three fields are deprecated and ignored. We fix them up here
  // just for internal consistency, but the Graphite engine doesn't care.
  if (!table.ReadU16(&this->searchPseudo) ||
      !table.ReadU16(&this->pseudoSelector) ||
      !table.ReadU16(&this->pseudoShift)) {
    return parent->Error("SILSub: Failed to read searchPseudo..pseudoShift");
  }
  if (this->numPseudo == 0) {
    if (this->searchPseudo != 0 || this->pseudoSelector != 0 || this->pseudoShift != 0) {
      this->searchPseudo = this->pseudoSelector = this->pseudoShift = 0;
    }
  } else {
    unsigned floorLog2 = std::floor(log2(this->numPseudo));
    if (this->searchPseudo != 6 * (unsigned)std::pow(2, floorLog2) ||
        this->pseudoSelector != floorLog2 ||
        this->pseudoShift != 6 * this->numPseudo - this->searchPseudo) {
      this->searchPseudo = 6 * (unsigned)std::pow(2, floorLog2);
      this->pseudoSelector = floorLog2;
      this->pseudoShift = 6 * this->numPseudo - this->searchPseudo;
    }
  }

  //this->pMaps.resize(this->numPseudo, parent);
  for (unsigned i = 0; i < numPseudo; i++) {
    this->pMaps.emplace_back(parent);
    if (!this->pMaps[i].ParsePart(table)) {
      return parent->Error("SILSub: Failed to read pMaps[%u]", i);
    }
  }

  if (!this->classes.ParsePart(table)) {
    return parent->Error("SILSub: Failed to read classes");
  }

  //this->passes.resize(this->numPasses, parent);
  for (unsigned i = 0; i < this->numPasses; ++i) {
    this->passes.emplace_back(parent);
    if (table.offset() != init_offset + this->oPasses[i]) {
      return parent->Error("SILSub: Offset check failed for passes[%u]", i);
    }
    if (!this->passes[i].ParsePart(table, init_offset, this->oPasses[i+1])) {
      return parent->Error("SILSub: Failed to read passes[%u]", i);
    }
  }
  return true;
}

bool OpenTypeSILF::SILSub::SerializePart(OTSStream* out) const {
  if ((parent->version >> 16 >= 3 &&
       (!out->WriteU32(this->ruleVersion) ||
        !out->WriteU16(this->passOffset) ||
        !out->WriteU16(this->pseudosOffset))) ||
      !out->WriteU16(this->maxGlyphID) ||
      !out->WriteS16(this->extraAscent) ||
      !out->WriteS16(this->extraDescent) ||
      !out->WriteU8(this->numPasses) ||
      !out->WriteU8(this->iSubst) ||
      !out->WriteU8(this->iPos) ||
      !out->WriteU8(this->iJust) ||
      !out->WriteU8(this->iBidi) ||
      !out->WriteU8(this->flags) ||
      !out->WriteU8(this->maxPreContext) ||
      !out->WriteU8(this->maxPostContext) ||
      !out->WriteU8(this->attrPseudo) ||
      !out->WriteU8(this->attrBreakWeight) ||
      !out->WriteU8(this->attrDirectionality) ||
      (parent->version >> 16 >= 2 &&
       (!out->WriteU8(this->attrMirroring) ||
        !out->WriteU8(this->attrSkipPasses) ||
        !out->WriteU8(this->numJLevels) ||
        !SerializeParts(this->jLevels, out))) ||
      !out->WriteU16(this->numLigComp) ||
      !out->WriteU8(this->numUserDefn) ||
      !out->WriteU8(this->maxCompPerLig) ||
      !out->WriteU8(this->direction) ||
      !out->WriteU8(this->attCollisions) ||
      !out->WriteU8(this->reserved4) ||
      !out->WriteU8(this->reserved5) ||
      (parent->version >> 16 >= 2 &&
       (!out->WriteU8(this->reserved6) ||
        !out->WriteU8(this->numCritFeatures) ||
        !SerializeParts(this->critFeatures, out) ||
        !out->WriteU8(this->reserved7))) ||
      !out->WriteU8(this->numScriptTag) ||
      !SerializeParts(this->scriptTag, out) ||
      !out->WriteU16(this->lbGID) ||
      !SerializeParts(this->oPasses, out) ||
      !out->WriteU16(this->numPseudo) ||
      !out->WriteU16(this->searchPseudo) ||
      !out->WriteU16(this->pseudoSelector) ||
      !out->WriteU16(this->pseudoShift) ||
      !SerializeParts(this->pMaps, out) ||
      !this->classes.SerializePart(out) ||
      !SerializeParts(this->passes, out)) {
    return parent->Error("SILSub: Failed to write");
  }
  return true;
}

bool OpenTypeSILF::SILSub::
JustificationLevel::ParsePart(Buffer& table) {
  if (!table.ReadU8(&this->attrStretch)) {
    return parent->Error("JustificationLevel: Failed to read attrStretch");
  }
  if (!table.ReadU8(&this->attrShrink)) {
    return parent->Error("JustificationLevel: Failed to read attrShrink");
  }
  if (!table.ReadU8(&this->attrStep)) {
    return parent->Error("JustificationLevel: Failed to read attrStep");
  }
  if (!table.ReadU8(&this->attrWeight)) {
    return parent->Error("JustificationLevel: Failed to read attrWeight");
  }
  if (!table.ReadU8(&this->runto)) {
    return parent->Error("JustificationLevel: Failed to read runto");
  }
  if (!table.ReadU8(&this->reserved)) {
    return parent->Error("JustificationLevel: Failed to read reserved");
  }
  if (this->reserved != 0) {
    parent->Warning("JustificationLevel: Nonzero reserved");
  }
  if (!table.ReadU8(&this->reserved2)) {
    return parent->Error("JustificationLevel: Failed to read reserved2");
  }
  if (this->reserved2 != 0) {
    parent->Warning("JustificationLevel: Nonzero reserved2");
  }
  if (!table.ReadU8(&this->reserved3)) {
    return parent->Error("JustificationLevel: Failed to read reserved3");
  }
  if (this->reserved3 != 0) {
    parent->Warning("JustificationLevel: Nonzero reserved3");
  }
  return true;
}

bool OpenTypeSILF::SILSub::
JustificationLevel::SerializePart(OTSStream* out) const {
  if (!out->WriteU8(this->attrStretch) ||
      !out->WriteU8(this->attrShrink) ||
      !out->WriteU8(this->attrStep) ||
      !out->WriteU8(this->attrWeight) ||
      !out->WriteU8(this->runto) ||
      !out->WriteU8(this->reserved) ||
      !out->WriteU8(this->reserved2) ||
      !out->WriteU8(this->reserved3)) {
    return parent->Error("JustificationLevel: Failed to write");
  }
  return true;
}

bool OpenTypeSILF::SILSub::
PseudoMap::ParsePart(Buffer& table) {
  if (parent->version >> 16 >= 2 && !table.ReadU32(&this->unicode)) {
    return parent->Error("PseudoMap: Failed to read unicode");
  }
  if (parent->version >> 16 == 1) {
    uint16_t unicode;
    if (!table.ReadU16(&unicode)) {
      return parent->Error("PseudoMap: Failed to read unicode");
    }
    this->unicode = unicode;
  }
  if (!table.ReadU16(&this->nPseudo)) {
    return parent->Error("PseudoMap: Failed to read nPseudo");
  }
  return true;
}

bool OpenTypeSILF::SILSub::
PseudoMap::SerializePart(OTSStream* out) const {
  if ((parent->version >> 16 >= 2 && !out->WriteU32(this->unicode)) ||
      (parent->version >> 16 == 1 &&
       !out->WriteU16(static_cast<uint16_t>(this->unicode))) ||
      !out->WriteU16(this->nPseudo)) {
    return parent->Error("PseudoMap: Failed to write");
  }
  return true;
}

bool OpenTypeSILF::SILSub::
ClassMap::ParsePart(Buffer& table) {
  size_t init_offset = table.offset();
  if (!table.ReadU16(&this->numClass)) {
    return parent->Error("ClassMap: Failed to read numClass");
  }
  if (!table.ReadU16(&this->numLinear) || this->numLinear > this->numClass) {
    return parent->Error("ClassMap: Failed to read valid numLinear");
  }

  //this->oClass.resize(static_cast<unsigned long>(this->numClass) + 1);
  if (parent->version >> 16 >= 4) {
    unsigned long last_oClass = 0;
    for (unsigned long i = 0; i <= this->numClass; ++i) {
      this->oClass.emplace_back();
      if (!table.ReadU32(&this->oClass[i]) || this->oClass[i] < last_oClass) {
        return parent->Error("ClassMap: Failed to read oClass[%lu]", i);
      }
      last_oClass = this->oClass[i];
    }
  }
  if (parent->version >> 16 < 4) {
    unsigned last_oClass = 0;
    for (unsigned long i = 0; i <= this->numClass; ++i) {
      uint16_t offset;
      if (!table.ReadU16(&offset) || offset < last_oClass) {
        return parent->Error("ClassMap: Failed to read oClass[%lu]", i);
      }
      last_oClass = offset;
      this->oClass.push_back(static_cast<uint32_t>(offset));
    }
  }

  if (table.offset() - init_offset > this->oClass[this->numLinear]) {
    return parent->Error("ClassMap: Failed to calculate length of glyphs");
  }
  unsigned long glyphs_len = (this->oClass[this->numLinear] -
                             (table.offset() - init_offset))/2;
  //this->glyphs.resize(glyphs_len);
  for (unsigned long i = 0; i < glyphs_len; ++i) {
    this->glyphs.emplace_back();
    if (!table.ReadU16(&this->glyphs[i])) {
      return parent->Error("ClassMap: Failed to read glyphs[%lu]", i);
    }
  }

  unsigned lookups_len = this->numClass - this->numLinear;
    // this->numLinear <= this->numClass
  //this->lookups.resize(lookups_len, parent);
  for (unsigned i = 0; i < lookups_len; ++i) {
    this->lookups.emplace_back(parent);
    if (table.offset() != init_offset + oClass[this->numLinear + i]) {
      return parent->Error("ClassMap: Offset check failed for lookups[%u]", i);
    }
    if (!this->lookups[i].ParsePart(table)) {
      return parent->Error("ClassMap: Failed to read lookups[%u]", i);
    }
  }
  return true;
}

bool OpenTypeSILF::SILSub::
ClassMap::SerializePart(OTSStream* out) const {
  if (!out->WriteU16(this->numClass) ||
      !out->WriteU16(this->numLinear) ||
      (parent->version >> 16 >= 4 && !SerializeParts(this->oClass, out)) ||
      (parent->version >> 16 < 4 &&
       ![&] {
         for (uint32_t offset : this->oClass) {
           if (!out->WriteU16(static_cast<uint16_t>(offset))) {
             return false;
           }
         }
         return true;
       }()) ||
      !SerializeParts(this->glyphs, out) ||
      !SerializeParts(this->lookups, out)) {
    return parent->Error("ClassMap: Failed to write");
  }
  return true;
}

bool OpenTypeSILF::SILSub::ClassMap::
LookupClass::ParsePart(Buffer& table) {
  if (!table.ReadU16(&this->numIDs)) {
    return parent->Error("LookupClass: Failed to read numIDs");
  }
  if (!table.ReadU16(&this->searchRange) ||
      !table.ReadU16(&this->entrySelector) ||
      !table.ReadU16(&this->rangeShift)) {
    return parent->Error("LookupClass: Failed to read searchRange..rangeShift");
  }
  if (this->numIDs == 0) {
    if (this->searchRange != 0 || this->entrySelector != 0 || this->rangeShift != 0) {
      parent->Warning("LookupClass: Correcting binary-search header for zero-length LookupPair list");
      this->searchRange = this->entrySelector = this->rangeShift = 0;
    }
  } else {
    unsigned floorLog2 = std::floor(log2(this->numIDs));
    if (this->searchRange != (unsigned)std::pow(2, floorLog2) ||
        this->entrySelector != floorLog2 ||
        this->rangeShift != this->numIDs - this->searchRange) {
      parent->Warning("LookupClass: Correcting binary-search header for LookupPair list");
      this->searchRange = (unsigned)std::pow(2, floorLog2);
      this->entrySelector = floorLog2;
      this->rangeShift = this->numIDs - this->searchRange;
    }
  }

  //this->lookups.resize(this->numIDs, parent);
  for (unsigned i = 0; i < numIDs; ++i) {
    this->lookups.emplace_back(parent);
    if (!this->lookups[i].ParsePart(table)) {
      return parent->Error("LookupClass: Failed to read lookups[%u]", i);
    }
  }
  return true;
}

bool OpenTypeSILF::SILSub::ClassMap::
LookupClass::SerializePart(OTSStream* out) const {
  if (!out->WriteU16(this->numIDs) ||
      !out->WriteU16(this->searchRange) ||
      !out->WriteU16(this->entrySelector) ||
      !out->WriteU16(this->rangeShift) ||
      !SerializeParts(this->lookups, out)) {
    return parent->Error("LookupClass: Failed to write");
  }
  return true;
}

bool OpenTypeSILF::SILSub::ClassMap::LookupClass::
LookupPair::ParsePart(Buffer& table) {
  if (!table.ReadU16(&this->glyphId)) {
    return parent->Error("LookupPair: Failed to read glyphId");
  }
  if (!table.ReadU16(&this->index)) {
    return parent->Error("LookupPair: Failed to read index");
  }
  return true;
}

bool OpenTypeSILF::SILSub::ClassMap::LookupClass::
LookupPair::SerializePart(OTSStream* out) const {
  if (!out->WriteU16(this->glyphId) ||
      !out->WriteU16(this->index)) {
    return parent->Error("LookupPair: Failed to write");
  }
  return true;
}

bool OpenTypeSILF::SILSub::
SILPass::ParsePart(Buffer& table, const size_t SILSub_init_offset,
                                  const size_t next_pass_offset) {
  size_t init_offset = table.offset();
  if (!table.ReadU8(&this->flags)) {
    return parent->Error("SILPass: Failed to read flags");
      // checks omitted
  }
  if (!table.ReadU8(&this->maxRuleLoop)) {
    return parent->Error("SILPass: Failed to read valid maxRuleLoop");
  }
  if (!table.ReadU8(&this->maxRuleContext)) {
    return parent->Error("SILPass: Failed to read maxRuleContext");
  }
  if (!table.ReadU8(&this->maxBackup)) {
    return parent->Error("SILPass: Failed to read maxBackup");
  }
  if (!table.ReadU16(&this->numRules)) {
    return parent->Error("SILPass: Failed to read numRules");
  }
  if (parent->version >> 16 >= 2) {
    if (!table.ReadU16(&this->fsmOffset)) {
      return parent->Error("SILPass: Failed to read fsmOffset");
    }
    if (parent->version >> 16 == 2 && this->fsmOffset != 0) {
      parent->Warning("SILPass: Nonzero fsmOffset (reserved in SILSub v2)");
    }
    if (!table.ReadU32(&this->pcCode) ||
        (parent->version >= 3 && this->pcCode < this->fsmOffset)) {
      return parent->Error("SILPass: Failed to read pcCode");
    }
  }
  if (!table.ReadU32(&this->rcCode) ||
      (parent->version >> 16 >= 2 && this->rcCode < this->pcCode)) {
    return parent->Error("SILPass: Failed to read valid rcCode");
  }
  if (!table.ReadU32(&this->aCode) || this->aCode < this->rcCode) {
    return parent->Error("SILPass: Failed to read valid aCode");
  }
  if (!table.ReadU32(&this->oDebug) ||
      (this->oDebug && this->oDebug < this->aCode)) {
    return parent->Error("SILPass: Failed to read valid oDebug");
  }
  if (parent->version >> 16 >= 3 &&
      table.offset() != init_offset + this->fsmOffset) {
    return parent->Error("SILPass: fsmOffset check failed");
  }
  if (!table.ReadU16(&this->numRows) ||
      (this->oDebug && this->numRows < this->numRules)) {
    return parent->Error("SILPass: Failed to read valid numRows");
  }
  if (!table.ReadU16(&this->numTransitional)) {
    return parent->Error("SILPass: Failed to read numTransitional");
  }
  if (!table.ReadU16(&this->numSuccess)) {
    return parent->Error("SILPass: Failed to read numSuccess");
  }
  if (!table.ReadU16(&this->numColumns)) {
    return parent->Error("SILPass: Failed to read numColumns");
  }
  if (!table.ReadU16(&this->numRange)) {
    return parent->Error("SILPass: Failed to read numRange");
  }

  // The following three fields are deprecated and ignored. We fix them up here
  // just for internal consistency, but the Graphite engine doesn't care.
  if (!table.ReadU16(&this->searchRange) ||
      !table.ReadU16(&this->entrySelector) ||
      !table.ReadU16(&this->rangeShift)) {
    return parent->Error("SILPass: Failed to read searchRange..rangeShift");
  }
  if (this->numRange == 0) {
    if (this->searchRange != 0 || this->entrySelector != 0 || this->rangeShift != 0) {
      this->searchRange = this->entrySelector = this->rangeShift = 0;
    }
  } else {
    unsigned floorLog2 = std::floor(log2(this->numRange));
    if (this->searchRange != 6 * (unsigned)std::pow(2, floorLog2) ||
        this->entrySelector != floorLog2 ||
        this->rangeShift != 6 * this->numRange - this->searchRange) {
      this->searchRange = 6 * (unsigned)std::pow(2, floorLog2);
      this->entrySelector = floorLog2;
      this->rangeShift = 6 * this->numRange - this->searchRange;
    }
  }

  //this->ranges.resize(this->numRange, parent);
  for (unsigned i = 0 ; i < this->numRange; ++i) {
    this->ranges.emplace_back(parent);
    if (!this->ranges[i].ParsePart(table)) {
      return parent->Error("SILPass: Failed to read ranges[%u]", i);
    }
  }
  unsigned ruleMap_len = 0;  // maximum value in oRuleMap
  //this->oRuleMap.resize(static_cast<unsigned long>(this->numSuccess) + 1);
  for (unsigned long i = 0; i <= this->numSuccess; ++i) {
    this->oRuleMap.emplace_back();
    if (!table.ReadU16(&this->oRuleMap[i])) {
      return parent->Error("SILPass: Failed to read oRuleMap[%u]", i);
    }
    if (oRuleMap[i] > ruleMap_len) {
      ruleMap_len = oRuleMap[i];
    }
  }

  //this->ruleMap.resize(ruleMap_len);
  for (unsigned i = 0; i < ruleMap_len; ++i) {
    this->ruleMap.emplace_back();
    if (!table.ReadU16(&this->ruleMap[i])) {
      return parent->Error("SILPass: Failed to read ruleMap[%u]", i);
    }
  }

  if (!table.ReadU8(&this->minRulePreContext)) {
    return parent->Error("SILPass: Failed to read minRulePreContext");
  }
  if (!table.ReadU8(&this->maxRulePreContext) ||
      this->maxRulePreContext < this->minRulePreContext) {
    return parent->Error("SILPass: Failed to read valid maxRulePreContext");
  }

  unsigned startStates_len = this->maxRulePreContext - this->minRulePreContext
                             + 1;
    // this->minRulePreContext <= this->maxRulePreContext
  //this->startStates.resize(startStates_len);
  for (unsigned i = 0; i < startStates_len; ++i) {
    this->startStates.emplace_back();
    if (!table.ReadS16(&this->startStates[i])) {
      return parent->Error("SILPass: Failed to read startStates[%u]", i);
    }
  }

  //this->ruleSortKeys.resize(this->numRules);
  for (unsigned i = 0; i < this->numRules; ++i) {
    this->ruleSortKeys.emplace_back();
    if (!table.ReadU16(&this->ruleSortKeys[i])) {
      return parent->Error("SILPass: Failed to read ruleSortKeys[%u]", i);
    }
  }

  //this->rulePreContext.resize(this->numRules);
  for (unsigned i = 0; i < this->numRules; ++i) {
    this->rulePreContext.emplace_back();
    if (!table.ReadU8(&this->rulePreContext[i])) {
      return parent->Error("SILPass: Failed to read rulePreContext[%u]", i);
    }
  }

  if (parent->version >> 16 >= 2) {
    if (!table.ReadU8(&this->collisionThreshold)) {
      return parent->Error("SILPass: Failed to read collisionThreshold");
    }
    if (parent->version >> 16 < 5 && this->collisionThreshold != 0) {
      parent->Warning("SILPass: Nonzero collisionThreshold"
                      " (reserved before v5)");
    }
    if (!table.ReadU16(&this->pConstraint)) {
      return parent->Error("SILPass: Failed to read pConstraint");
    }
  }

  unsigned long ruleConstraints_len = this->aCode - this->rcCode;
    // this->rcCode <= this->aCode
  //this->oConstraints.resize(static_cast<unsigned long>(this->numRules) + 1);
  for (unsigned long i = 0; i <= this->numRules; ++i) {
    this->oConstraints.emplace_back();
    if (!table.ReadU16(&this->oConstraints[i]) ||
        this->oConstraints[i] > ruleConstraints_len) {
      return parent->Error("SILPass: Failed to read valid oConstraints[%lu]",
                           i);
    }
  }

  if (!this->oDebug && this->aCode > next_pass_offset) {
    return parent->Error("SILPass: Failed to calculate length of actions");
  }
  unsigned long actions_len = this->oDebug ? this->oDebug - this->aCode :
                                             next_pass_offset - this->aCode;
    // if this->oDebug, then this->aCode <= this->oDebug
  //this->oActions.resize(static_cast<unsigned long>(this->numRules) + 1);
  for (unsigned long i = 0; i <= this->numRules; ++i) {
    this->oActions.emplace_back();
    if (!table.ReadU16(&this->oActions[i]) ||
        (this->oActions[i] > actions_len)) {
      return parent->Error("SILPass: Failed to read valid oActions[%lu]", i);
    }
  }

  //this->stateTrans.resize(this->numTransitional);
  for (unsigned i = 0; i < this->numTransitional; ++i) {
    this->stateTrans.emplace_back();
    //this->stateTrans[i].resize(this->numColumns);
    for (unsigned j = 0; j < this->numColumns; ++j) {
      this->stateTrans[i].emplace_back();
      if (!table.ReadU16(&stateTrans[i][j])) {
        return parent->Error("SILPass: Failed to read stateTrans[%u][%u]",
                             i, j);
      }
    }
  }

  if (parent->version >> 16 >= 2) {
    if (!table.ReadU8(&this->reserved2)) {
      return parent->Error("SILPass: Failed to read reserved2");
    }
    if (this->reserved2 != 0) {
      parent->Warning("SILPass: Nonzero reserved2");
    }

    if (table.offset() != SILSub_init_offset + this->pcCode) {
      return parent->Error("SILPass: pcCode check failed");
    }
    //this->passConstraints.resize(this->pConstraint);
    for (unsigned i = 0; i < this->pConstraint; ++i) {
      this->passConstraints.emplace_back();
      if (!table.ReadU8(&this->passConstraints[i])) {
        return parent->Error("SILPass: Failed to read passConstraints[%u]", i);
      }
    }
  }

  if (table.offset() != SILSub_init_offset + this->rcCode) {
    return parent->Error("SILPass: rcCode check failed");
  }
  //this->ruleConstraints.resize(ruleConstraints_len);  // calculated above
  for (unsigned long i = 0; i < ruleConstraints_len; ++i) {
    this->ruleConstraints.emplace_back();
    if (!table.ReadU8(&this->ruleConstraints[i])) {
      return parent->Error("SILPass: Failed to read ruleConstraints[%u]", i);
    }
  }

  if (table.offset() != SILSub_init_offset + this->aCode) {
    return parent->Error("SILPass: aCode check failed");
  }
  //this->actions.resize(actions_len);  // calculated above
  for (unsigned long i = 0; i < actions_len; ++i) {
    this->actions.emplace_back();
    if (!table.ReadU8(&this->actions[i])) {
      return parent->Error("SILPass: Failed to read actions[%u]", i);
    }
  }

  if (this->oDebug) {
    OpenTypeNAME* name = static_cast<OpenTypeNAME*>(
        parent->GetFont()->GetTypedTable(OTS_TAG_NAME));
    if (!name) {
      return parent->Error("SILPass: Required name table is missing");
    }

    if (table.offset() != SILSub_init_offset + this->oDebug) {
      return parent->Error("SILPass: oDebug check failed");
    }
    //this->dActions.resize(this->numRules);
    for (unsigned i = 0; i < this->numRules; ++i) {
      this->dActions.emplace_back();
      if (!table.ReadU16(&this->dActions[i]) ||
          !name->IsValidNameId(this->dActions[i])) {
        return parent->Error("SILPass: Failed to read valid dActions[%u]", i);
      }
    }

    unsigned dStates_len = this->numRows - this->numRules;
      // this->numRules <= this->numRows
    //this->dStates.resize(dStates_len);
    for (unsigned i = 0; i < dStates_len; ++i) {
      this->dStates.emplace_back();
      if (!table.ReadU16(&this->dStates[i]) ||
          !name->IsValidNameId(this->dStates[i])) {
        return parent->Error("SILPass: Failed to read valid dStates[%u]", i);
      }
    }

    //this->dCols.resize(this->numRules);
    for (unsigned i = 0; i < this->numRules; ++i) {
      this->dCols.emplace_back();
      if (!table.ReadU16(&this->dCols[i]) ||
          !name->IsValidNameId(this->dCols[i])) {
        return parent->Error("SILPass: Failed to read valid dCols[%u]");
      }
    }
  }
  return true;
}

bool OpenTypeSILF::SILSub::
SILPass::SerializePart(OTSStream* out) const {
  if (!out->WriteU8(this->flags) ||
      !out->WriteU8(this->maxRuleLoop) ||
      !out->WriteU8(this->maxRuleContext) ||
      !out->WriteU8(this->maxBackup) ||
      !out->WriteU16(this->numRules) ||
      (parent->version >> 16 >= 2 &&
       (!out->WriteU16(this->fsmOffset) ||
        !out->WriteU32(this->pcCode))) ||
      !out->WriteU32(this->rcCode) ||
      !out->WriteU32(this->aCode) ||
      !out->WriteU32(this->oDebug) ||
      !out->WriteU16(this->numRows) ||
      !out->WriteU16(this->numTransitional) ||
      !out->WriteU16(this->numSuccess) ||
      !out->WriteU16(this->numColumns) ||
      !out->WriteU16(this->numRange) ||
      !out->WriteU16(this->searchRange) ||
      !out->WriteU16(this->entrySelector) ||
      !out->WriteU16(this->rangeShift) ||
      !SerializeParts(this->ranges, out) ||
      !SerializeParts(this->oRuleMap, out) ||
      !SerializeParts(this->ruleMap, out) ||
      !out->WriteU8(this->minRulePreContext) ||
      !out->WriteU8(this->maxRulePreContext) ||
      !SerializeParts(this->startStates, out) ||
      !SerializeParts(this->ruleSortKeys, out) ||
      !SerializeParts(this->rulePreContext, out) ||
      (parent->version >> 16 >= 2 &&
       (!out->WriteU8(this->collisionThreshold) ||
        !out->WriteU16(this->pConstraint))) ||
      !SerializeParts(this->oConstraints, out) ||
      !SerializeParts(this->oActions, out) ||
      !SerializeParts(this->stateTrans, out) ||
      (parent->version >> 16 >= 2 &&
       (!out->WriteU8(this->reserved2) ||
        !SerializeParts(this->passConstraints, out))) ||
      !SerializeParts(this->ruleConstraints, out) ||
      !SerializeParts(this->actions, out) ||
      !SerializeParts(this->dActions, out) ||
      !SerializeParts(this->dStates, out) ||
      !SerializeParts(this->dCols, out)) {
    return parent->Error("SILPass: Failed to write");
  }
  return true;
}

bool OpenTypeSILF::SILSub::SILPass::
PassRange::ParsePart(Buffer& table) {
  if (!table.ReadU16(&this->firstId)) {
    return parent->Error("PassRange: Failed to read firstId");
  }
  if (!table.ReadU16(&this->lastId)) {
    return parent->Error("PassRange: Failed to read lastId");
  }
  if (!table.ReadU16(&this->colId)) {
    return parent->Error("PassRange: Failed to read colId");
  }
  return true;
}

bool OpenTypeSILF::SILSub::SILPass::
PassRange::SerializePart(OTSStream* out) const {
  if (!out->WriteU16(this->firstId) ||
      !out->WriteU16(this->lastId) ||
      !out->WriteU16(this->colId)) {
    return parent->Error("PassRange: Failed to write");
  }
  return true;
}

}  // namespace ots
