private void checkFieldRead(FieldDescriptor fd, boolean expectRepeated) {
    if (expectRepeated) {
      if (!fd.isRepeated()) {
        throw new IllegalArgumentException(
            "This field is not repeated and cannot be read with the methods intended for collections or arrays: "
                + fd.getFullName());
      }
    } else {
      if (fd.isRepeated()) {
        throw new IllegalArgumentException(
            "A repeated field should be read with one of the methods intended for collections or arrays: "
                + fd.getFullName());
      }
    }

    if (!messageContext.markField(fd.getNumber())) {
      throw new IllegalStateException("A field cannot be read twice : " + fd.getFullName());
    }

    if (ctx.getConfiguration().logOutOfSequenceReads()
        && log.isEnabled(Logger.Level.WARN)
        && messageContext.getMaxSeenFieldNumber() > fd.getNumber()) {
      log.fieldReadOutOfSequence(fd.getFullName());
    }
  }
 void popContext() {
   messageContext = messageContext.getParentContext();
 }