code: public int getFieldIndex(String fieldName) {
      Preconditions.checkState(code == Code.STRUCT, "Illegal call for non-STRUCT type");
  
      if (fieldsByName == null) {
        Map<String, Integer> tmp = new TreeMap<>();
        for (int i = 0; i < getStructFields().size(); ++i) {
          Type.StructField field = getStructFields().get(i);
          if (tmp.put(field.getName(), i) != null) {
            // Column name appears more than once: mark as ambiguous.
            tmp.put(field.getName(), AMBIGUOUS_FIELD);
          }
        }
        // Benign race: Java's final field semantics mean that if we see a non-null "fieldsByName",
        // we are guaranteed to see it in a fully initialized state.  It is thus important that we
        // use an ImmutableMap here, which necessarily uses final fields or equivalent reasoning.
        // Since all computations of "fieldsByName" produce the same value, there is no risk of
        // inconsistency.
        fieldsByName = ImmutableMap.copyOf(tmp);
      }
  
      Integer index = fieldsByName.get(fieldName);
      if (index == null) {
        throw new IllegalArgumentException("Field not found: " + fieldName);
      }
      if (index == AMBIGUOUS_FIELD) {
        throw new IllegalArgumentException("Ambiguous field name: " + fieldName);
      }
      return index;
    }
docs: Returns the index of the field named {@code fieldName} in this {@code STRUCT} type.
  
  @throws IllegalArgumentException if there is not exactly one element of {@link
  #getStructFields()} with {@link StructField#getName()} equal to {@code fieldName}
  @throws IllegalStateException if {@code code() != Code.STRUCT}