package zeenea.connector.zdf.model;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;
import org.immutables.value.Generated;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Immutable implementation of {@link ZdfDataset}.
 * <p>
 * Use the builder to create immutable instances:
 * {@code ImmutableZdfDataset.builder()}.
 */
@Generated(from = "ZdfDataset", generator = "Immutables")
@SuppressWarnings({"all"})
@SuppressFBWarnings
@ParametersAreNonnullByDefault
@javax.annotation.processing.Generated("org.immutables.processor.ProxyProcessor")
@Immutable
public final class ImmutableZdfDataset implements ZdfDataset {
  private final @Nullable String path;
  @NotNull
  private final String name;
  private final @Nullable String description;
  private final @Nullable ZdfOwner owner;
  @NotNull
  private final List<ZdfField> fields;
  private final List<ZdfForeignKey> foreignKeys;
  private final @Nullable String type;
  private final @Nullable String label;
  private final @Nullable String format;
  private final @Nullable String numberOfRows;
  private final @Nullable String diskUsage;
  private final @Nullable String location;
  private final @Nullable String project;
  private final @Nullable String catalog;
  private final @Nullable String schema;
  private final @Nullable String database;
  private final @Nullable String replicationFactor;
  private final @Nullable String tags;
  private final @Nullable String sourceSystem;
  private final @Nullable String origin;
  private final @Nullable String creationDate;
  private final @Nullable String updateDate;
  private final @Nullable String createdBy;
  private final @Nullable String updatedBy;
  private final @Nullable String comments;

  private ImmutableZdfDataset(ImmutableZdfDataset.Builder builder) {
    this.path = builder.path;
    this.name = builder.name;
    this.description = builder.description;
    this.owner = builder.owner;
    this.fields = List.copyOf(builder.fields);
    this.type = builder.type;
    this.label = builder.label;
    this.format = builder.format;
    this.numberOfRows = builder.numberOfRows;
    this.diskUsage = builder.diskUsage;
    this.location = builder.location;
    this.project = builder.project;
    this.catalog = builder.catalog;
    this.schema = builder.schema;
    this.database = builder.database;
    this.replicationFactor = builder.replicationFactor;
    this.tags = builder.tags;
    this.sourceSystem = builder.sourceSystem;
    this.origin = builder.origin;
    this.creationDate = builder.creationDate;
    this.updateDate = builder.updateDate;
    this.createdBy = builder.createdBy;
    this.updatedBy = builder.updatedBy;
    this.comments = builder.comments;
    this.foreignKeys = builder.foreignKeysIsSet()
        ? List.copyOf(builder.foreignKeys)
        : ZdfDataset.super.foreignKeys() instanceof Collection<?>
       ? List.copyOf((Collection<? extends ZdfForeignKey>) ZdfDataset.super.foreignKeys())
       : StreamSupport.stream(ZdfDataset.super.foreignKeys().spliterator(), false)
             .collect(Collectors.toUnmodifiableList());
  }

  private ImmutableZdfDataset(
      @Nullable String path,
      String name,
      @Nullable String description,
      @Nullable ZdfOwner owner,
      List<ZdfField> fields,
      List<ZdfForeignKey> foreignKeys,
      @Nullable String type,
      @Nullable String label,
      @Nullable String format,
      @Nullable String numberOfRows,
      @Nullable String diskUsage,
      @Nullable String location,
      @Nullable String project,
      @Nullable String catalog,
      @Nullable String schema,
      @Nullable String database,
      @Nullable String replicationFactor,
      @Nullable String tags,
      @Nullable String sourceSystem,
      @Nullable String origin,
      @Nullable String creationDate,
      @Nullable String updateDate,
      @Nullable String createdBy,
      @Nullable String updatedBy,
      @Nullable String comments) {
    this.path = path;
    this.name = name;
    this.description = description;
    this.owner = owner;
    this.fields = fields;
    this.foreignKeys = foreignKeys;
    this.type = type;
    this.label = label;
    this.format = format;
    this.numberOfRows = numberOfRows;
    this.diskUsage = diskUsage;
    this.location = location;
    this.project = project;
    this.catalog = catalog;
    this.schema = schema;
    this.database = database;
    this.replicationFactor = replicationFactor;
    this.tags = tags;
    this.sourceSystem = sourceSystem;
    this.origin = origin;
    this.creationDate = creationDate;
    this.updateDate = updateDate;
    this.createdBy = createdBy;
    this.updatedBy = updatedBy;
    this.comments = comments;
  }

  /**
   * @return The value of the {@code path} attribute
   */
  @JsonProperty("path")
  @Override
  public @Nullable String path() {
    return path;
  }

  /**
   * @return The value of the {@code name} attribute
   */
  @JsonProperty("name")
  @NotNull
  @Override
  public String name() {
    return name;
  }

  /**
   * @return The value of the {@code description} attribute
   */
  @JsonProperty("description")
  @Override
  public @Nullable String description() {
    return description;
  }

  /**
   * @return The value of the {@code owner} attribute
   */
  @JsonProperty("owner")
  @Override
  public @Nullable ZdfOwner owner() {
    return owner;
  }

  /**
   * @return The value of the {@code fields} attribute
   */
  @JsonProperty("fields")
  @NotNull
  @Override
  public List<ZdfField> fields() {
    return fields;
  }

  /**
   * @return The value of the {@code foreignKeys} attribute
   */
  @JsonProperty("foreignKeys")
  @Override
  public List<ZdfForeignKey> foreignKeys() {
    return foreignKeys;
  }

  /**
   * @return The value of the {@code type} attribute
   */
  @JsonProperty("type")
  @Override
  public @Nullable String type() {
    return type;
  }

  /**
   * @return The value of the {@code label} attribute
   */
  @JsonProperty("label")
  @Override
  public @Nullable String label() {
    return label;
  }

  /**
   * @return The value of the {@code format} attribute
   */
  @JsonProperty("format")
  @Override
  public @Nullable String format() {
    return format;
  }

  /**
   * @return The value of the {@code numberOfRows} attribute
   */
  @JsonProperty("numberOfRows")
  @Override
  public @Nullable String numberOfRows() {
    return numberOfRows;
  }

  /**
   * @return The value of the {@code diskUsage} attribute
   */
  @JsonProperty("diskUsage")
  @Override
  public @Nullable String diskUsage() {
    return diskUsage;
  }

  /**
   * @return The value of the {@code location} attribute
   */
  @JsonProperty("location")
  @Override
  public @Nullable String location() {
    return location;
  }

  /**
   * @return The value of the {@code project} attribute
   */
  @JsonProperty("project")
  @Override
  public @Nullable String project() {
    return project;
  }

  /**
   * @return The value of the {@code catalog} attribute
   */
  @JsonProperty("catalog")
  @Override
  public @Nullable String catalog() {
    return catalog;
  }

  /**
   * @return The value of the {@code schema} attribute
   */
  @JsonProperty("schema")
  @Override
  public @Nullable String schema() {
    return schema;
  }

  /**
   * @return The value of the {@code database} attribute
   */
  @JsonProperty("database")
  @Override
  public @Nullable String database() {
    return database;
  }

  /**
   * @return The value of the {@code replicationFactor} attribute
   */
  @JsonProperty("replicationFactor")
  @Override
  public @Nullable String replicationFactor() {
    return replicationFactor;
  }

  /**
   * @return The value of the {@code tags} attribute
   */
  @JsonProperty("tags")
  @Override
  public @Nullable String tags() {
    return tags;
  }

  /**
   * @return The value of the {@code sourceSystem} attribute
   */
  @JsonProperty("sourceSystem")
  @Override
  public @Nullable String sourceSystem() {
    return sourceSystem;
  }

  /**
   * @return The value of the {@code origin} attribute
   */
  @JsonProperty("origin")
  @Override
  public @Nullable String origin() {
    return origin;
  }

  /**
   * @return The value of the {@code creationDate} attribute
   */
  @JsonProperty("creationDate")
  @Override
  public @Nullable String creationDate() {
    return creationDate;
  }

  /**
   * @return The value of the {@code updateDate} attribute
   */
  @JsonProperty("updateDate")
  @Override
  public @Nullable String updateDate() {
    return updateDate;
  }

  /**
   * @return The value of the {@code createdBy} attribute
   */
  @JsonProperty("createdBy")
  @Override
  public @Nullable String createdBy() {
    return createdBy;
  }

  /**
   * @return The value of the {@code updatedBy} attribute
   */
  @JsonProperty("updatedBy")
  @Override
  public @Nullable String updatedBy() {
    return updatedBy;
  }

  /**
   * @return The value of the {@code comments} attribute
   */
  @JsonProperty("comments")
  @Override
  public @Nullable String comments() {
    return comments;
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#path() path} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for path (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withPath(@Nullable String value) {
    if (Objects.equals(this.path, value)) return this;
    return new ImmutableZdfDataset(
        value,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#name() name} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for name
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withName(String value) {
    String newValue = Objects.requireNonNull(value, "name");
    if (this.name.equals(newValue)) return this;
    return new ImmutableZdfDataset(
        this.path,
        newValue,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#description() description} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for description (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withDescription(@Nullable String value) {
    if (Objects.equals(this.description, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        value,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#owner() owner} attribute.
   * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for owner (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withOwner(@Nullable ZdfOwner value) {
    if (this.owner == value) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        value,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object with elements that replace the content of {@link ZdfDataset#fields() fields}.
   * @param elements The elements to set
   * @return A modified copy of {@code this} object
   */
  public final ImmutableZdfDataset withFields(ZdfField... elements) {
    List<ZdfField> newValue = List.of(elements);
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        newValue,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object with elements that replace the content of {@link ZdfDataset#fields() fields}.
   * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
   * @param elements An iterable of fields elements to set
   * @return A modified copy of {@code this} object
   */
  public final ImmutableZdfDataset withFields(Iterable<? extends ZdfField> elements) {
    if (this.fields == elements) return this;
    List<ZdfField> newValue = elements instanceof Collection<?>
        ? List.copyOf((Collection<? extends ZdfField>) elements)
        : StreamSupport.stream(elements.spliterator(), false)
            .collect(Collectors.toUnmodifiableList());
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        newValue,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object with elements that replace the content of {@link ZdfDataset#foreignKeys() foreignKeys}.
   * @param elements The elements to set
   * @return A modified copy of {@code this} object
   */
  public final ImmutableZdfDataset withForeignKeys(ZdfForeignKey... elements) {
    List<ZdfForeignKey> newValue = List.of(elements);
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        newValue,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object with elements that replace the content of {@link ZdfDataset#foreignKeys() foreignKeys}.
   * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
   * @param elements An iterable of foreignKeys elements to set
   * @return A modified copy of {@code this} object
   */
  public final ImmutableZdfDataset withForeignKeys(Iterable<? extends ZdfForeignKey> elements) {
    if (this.foreignKeys == elements) return this;
    List<ZdfForeignKey> newValue = elements instanceof Collection<?>
        ? List.copyOf((Collection<? extends ZdfForeignKey>) elements)
        : StreamSupport.stream(elements.spliterator(), false)
            .collect(Collectors.toUnmodifiableList());
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        newValue,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#type() type} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for type (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withType(@Nullable String value) {
    if (Objects.equals(this.type, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        value,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#label() label} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for label (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withLabel(@Nullable String value) {
    if (Objects.equals(this.label, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        value,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#format() format} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for format (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withFormat(@Nullable String value) {
    if (Objects.equals(this.format, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        value,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#numberOfRows() numberOfRows} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for numberOfRows (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withNumberOfRows(@Nullable String value) {
    if (Objects.equals(this.numberOfRows, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        value,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#diskUsage() diskUsage} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for diskUsage (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withDiskUsage(@Nullable String value) {
    if (Objects.equals(this.diskUsage, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        value,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#location() location} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for location (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withLocation(@Nullable String value) {
    if (Objects.equals(this.location, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        value,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#project() project} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for project (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withProject(@Nullable String value) {
    if (Objects.equals(this.project, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        value,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#catalog() catalog} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for catalog (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withCatalog(@Nullable String value) {
    if (Objects.equals(this.catalog, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        value,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#schema() schema} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for schema (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withSchema(@Nullable String value) {
    if (Objects.equals(this.schema, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        value,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#database() database} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for database (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withDatabase(@Nullable String value) {
    if (Objects.equals(this.database, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        value,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#replicationFactor() replicationFactor} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for replicationFactor (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withReplicationFactor(@Nullable String value) {
    if (Objects.equals(this.replicationFactor, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        value,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#tags() tags} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for tags (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withTags(@Nullable String value) {
    if (Objects.equals(this.tags, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        value,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#sourceSystem() sourceSystem} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for sourceSystem (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withSourceSystem(@Nullable String value) {
    if (Objects.equals(this.sourceSystem, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        value,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#origin() origin} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for origin (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withOrigin(@Nullable String value) {
    if (Objects.equals(this.origin, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        value,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#creationDate() creationDate} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for creationDate (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withCreationDate(@Nullable String value) {
    if (Objects.equals(this.creationDate, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        value,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#updateDate() updateDate} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for updateDate (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withUpdateDate(@Nullable String value) {
    if (Objects.equals(this.updateDate, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        value,
        this.createdBy,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#createdBy() createdBy} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for createdBy (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withCreatedBy(@Nullable String value) {
    if (Objects.equals(this.createdBy, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        value,
        this.updatedBy,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#updatedBy() updatedBy} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for updatedBy (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withUpdatedBy(@Nullable String value) {
    if (Objects.equals(this.updatedBy, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        value,
        this.comments);
  }

  /**
   * Copy the current immutable object by setting a value for the {@link ZdfDataset#comments() comments} attribute.
   * An equals check used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for comments (can be {@code null})
   * @return A modified copy of the {@code this} object
   */
  public final ImmutableZdfDataset withComments(@Nullable String value) {
    if (Objects.equals(this.comments, value)) return this;
    return new ImmutableZdfDataset(
        this.path,
        this.name,
        this.description,
        this.owner,
        this.fields,
        this.foreignKeys,
        this.type,
        this.label,
        this.format,
        this.numberOfRows,
        this.diskUsage,
        this.location,
        this.project,
        this.catalog,
        this.schema,
        this.database,
        this.replicationFactor,
        this.tags,
        this.sourceSystem,
        this.origin,
        this.creationDate,
        this.updateDate,
        this.createdBy,
        this.updatedBy,
        value);
  }

  /**
   * This instance is equal to all instances of {@code ImmutableZdfDataset} that have equal attribute values.
   * @return {@code true} if {@code this} is equal to {@code another} instance
   */
  @Override
  public boolean equals(@javax.annotation.Nullable Object another) {
    if (this == another) return true;
    return another instanceof ImmutableZdfDataset
        && equalTo(0, (ImmutableZdfDataset) another);
  }

  private boolean equalTo(int synthetic, ImmutableZdfDataset another) {
    return Objects.equals(path, another.path)
        && name.equals(another.name)
        && Objects.equals(description, another.description)
        && Objects.equals(owner, another.owner)
        && fields.equals(another.fields)
        && foreignKeys.equals(another.foreignKeys)
        && Objects.equals(type, another.type)
        && Objects.equals(label, another.label)
        && Objects.equals(format, another.format)
        && Objects.equals(numberOfRows, another.numberOfRows)
        && Objects.equals(diskUsage, another.diskUsage)
        && Objects.equals(location, another.location)
        && Objects.equals(project, another.project)
        && Objects.equals(catalog, another.catalog)
        && Objects.equals(schema, another.schema)
        && Objects.equals(database, another.database)
        && Objects.equals(replicationFactor, another.replicationFactor)
        && Objects.equals(tags, another.tags)
        && Objects.equals(sourceSystem, another.sourceSystem)
        && Objects.equals(origin, another.origin)
        && Objects.equals(creationDate, another.creationDate)
        && Objects.equals(updateDate, another.updateDate)
        && Objects.equals(createdBy, another.createdBy)
        && Objects.equals(updatedBy, another.updatedBy)
        && Objects.equals(comments, another.comments);
  }

  /**
   * Computes a hash code from attributes: {@code path}, {@code name}, {@code description}, {@code owner}, {@code fields}, {@code foreignKeys}, {@code type}, {@code label}, {@code format}, {@code numberOfRows}, {@code diskUsage}, {@code location}, {@code project}, {@code catalog}, {@code schema}, {@code database}, {@code replicationFactor}, {@code tags}, {@code sourceSystem}, {@code origin}, {@code creationDate}, {@code updateDate}, {@code createdBy}, {@code updatedBy}, {@code comments}.
   * @return hashCode value
   */
  @Override
  public int hashCode() {
    int h = 5381;
    h += (h << 5) + Objects.hashCode(path);
    h += (h << 5) + name.hashCode();
    h += (h << 5) + Objects.hashCode(description);
    h += (h << 5) + Objects.hashCode(owner);
    h += (h << 5) + fields.hashCode();
    h += (h << 5) + foreignKeys.hashCode();
    h += (h << 5) + Objects.hashCode(type);
    h += (h << 5) + Objects.hashCode(label);
    h += (h << 5) + Objects.hashCode(format);
    h += (h << 5) + Objects.hashCode(numberOfRows);
    h += (h << 5) + Objects.hashCode(diskUsage);
    h += (h << 5) + Objects.hashCode(location);
    h += (h << 5) + Objects.hashCode(project);
    h += (h << 5) + Objects.hashCode(catalog);
    h += (h << 5) + Objects.hashCode(schema);
    h += (h << 5) + Objects.hashCode(database);
    h += (h << 5) + Objects.hashCode(replicationFactor);
    h += (h << 5) + Objects.hashCode(tags);
    h += (h << 5) + Objects.hashCode(sourceSystem);
    h += (h << 5) + Objects.hashCode(origin);
    h += (h << 5) + Objects.hashCode(creationDate);
    h += (h << 5) + Objects.hashCode(updateDate);
    h += (h << 5) + Objects.hashCode(createdBy);
    h += (h << 5) + Objects.hashCode(updatedBy);
    h += (h << 5) + Objects.hashCode(comments);
    return h;
  }

  /**
   * Prints the immutable value {@code ZdfDataset} with attribute values.
   * @return A string representation of the value
   */
  @Override
  public String toString() {
    return "ZdfDataset{"
        + "path=" + path
        + ", name=" + name
        + ", description=" + description
        + ", owner=" + owner
        + ", fields=" + fields
        + ", foreignKeys=" + foreignKeys
        + ", type=" + type
        + ", label=" + label
        + ", format=" + format
        + ", numberOfRows=" + numberOfRows
        + ", diskUsage=" + diskUsage
        + ", location=" + location
        + ", project=" + project
        + ", catalog=" + catalog
        + ", schema=" + schema
        + ", database=" + database
        + ", replicationFactor=" + replicationFactor
        + ", tags=" + tags
        + ", sourceSystem=" + sourceSystem
        + ", origin=" + origin
        + ", creationDate=" + creationDate
        + ", updateDate=" + updateDate
        + ", createdBy=" + createdBy
        + ", updatedBy=" + updatedBy
        + ", comments=" + comments
        + "}";
  }

  /**
   * Utility type used to correctly read immutable object from JSON representation.
   * @deprecated Do not use this type directly, it exists only for the <em>Jackson</em>-binding infrastructure
   */
  @Generated(from = "ZdfDataset", generator = "Immutables")
  @Deprecated
  @JsonDeserialize
  @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE)
  static final class Json implements ZdfDataset {
    @javax.annotation.Nullable String path;
    @javax.annotation.Nullable String name;
    @javax.annotation.Nullable String description;
    @javax.annotation.Nullable ZdfOwner owner;
    @javax.annotation.Nullable List<ZdfField> fields = List.of();
    @javax.annotation.Nullable List<ZdfForeignKey> foreignKeys = List.of();
    boolean foreignKeysIsSet;
    @javax.annotation.Nullable String type;
    @javax.annotation.Nullable String label;
    @javax.annotation.Nullable String format;
    @javax.annotation.Nullable String numberOfRows;
    @javax.annotation.Nullable String diskUsage;
    @javax.annotation.Nullable String location;
    @javax.annotation.Nullable String project;
    @javax.annotation.Nullable String catalog;
    @javax.annotation.Nullable String schema;
    @javax.annotation.Nullable String database;
    @javax.annotation.Nullable String replicationFactor;
    @javax.annotation.Nullable String tags;
    @javax.annotation.Nullable String sourceSystem;
    @javax.annotation.Nullable String origin;
    @javax.annotation.Nullable String creationDate;
    @javax.annotation.Nullable String updateDate;
    @javax.annotation.Nullable String createdBy;
    @javax.annotation.Nullable String updatedBy;
    @javax.annotation.Nullable String comments;
    @JsonProperty("path")
    public void setPath(@Nullable String path) {
      this.path = path;
    }
    @JsonProperty("name")
    public void setName(String name) {
      this.name = name;
    }
    @JsonProperty("description")
    public void setDescription(@Nullable String description) {
      this.description = description;
    }
    @JsonProperty("owner")
    public void setOwner(@Nullable ZdfOwner owner) {
      this.owner = owner;
    }
    @JsonProperty("fields")
    public void setFields(List<ZdfField> fields) {
      this.fields = fields;
    }
    @JsonProperty("foreignKeys")
    public void setForeignKeys(List<ZdfForeignKey> foreignKeys) {
      this.foreignKeys = foreignKeys;
      this.foreignKeysIsSet = null != foreignKeys;
    }
    @JsonProperty("type")
    public void setType(@Nullable String type) {
      this.type = type;
    }
    @JsonProperty("label")
    public void setLabel(@Nullable String label) {
      this.label = label;
    }
    @JsonProperty("format")
    public void setFormat(@Nullable String format) {
      this.format = format;
    }
    @JsonProperty("numberOfRows")
    public void setNumberOfRows(@Nullable String numberOfRows) {
      this.numberOfRows = numberOfRows;
    }
    @JsonProperty("diskUsage")
    public void setDiskUsage(@Nullable String diskUsage) {
      this.diskUsage = diskUsage;
    }
    @JsonProperty("location")
    public void setLocation(@Nullable String location) {
      this.location = location;
    }
    @JsonProperty("project")
    public void setProject(@Nullable String project) {
      this.project = project;
    }
    @JsonProperty("catalog")
    public void setCatalog(@Nullable String catalog) {
      this.catalog = catalog;
    }
    @JsonProperty("schema")
    public void setSchema(@Nullable String schema) {
      this.schema = schema;
    }
    @JsonProperty("database")
    public void setDatabase(@Nullable String database) {
      this.database = database;
    }
    @JsonProperty("replicationFactor")
    public void setReplicationFactor(@Nullable String replicationFactor) {
      this.replicationFactor = replicationFactor;
    }
    @JsonProperty("tags")
    public void setTags(@Nullable String tags) {
      this.tags = tags;
    }
    @JsonProperty("sourceSystem")
    public void setSourceSystem(@Nullable String sourceSystem) {
      this.sourceSystem = sourceSystem;
    }
    @JsonProperty("origin")
    public void setOrigin(@Nullable String origin) {
      this.origin = origin;
    }
    @JsonProperty("creationDate")
    public void setCreationDate(@Nullable String creationDate) {
      this.creationDate = creationDate;
    }
    @JsonProperty("updateDate")
    public void setUpdateDate(@Nullable String updateDate) {
      this.updateDate = updateDate;
    }
    @JsonProperty("createdBy")
    public void setCreatedBy(@Nullable String createdBy) {
      this.createdBy = createdBy;
    }
    @JsonProperty("updatedBy")
    public void setUpdatedBy(@Nullable String updatedBy) {
      this.updatedBy = updatedBy;
    }
    @JsonProperty("comments")
    public void setComments(@Nullable String comments) {
      this.comments = comments;
    }
    @Override
    public String path() { throw new UnsupportedOperationException(); }
    @Override
    public String name() { throw new UnsupportedOperationException(); }
    @Override
    public String description() { throw new UnsupportedOperationException(); }
    @Override
    public ZdfOwner owner() { throw new UnsupportedOperationException(); }
    @Override
    public List<ZdfField> fields() { throw new UnsupportedOperationException(); }
    @Override
    public List<ZdfForeignKey> foreignKeys() { throw new UnsupportedOperationException(); }
    @Override
    public String type() { throw new UnsupportedOperationException(); }
    @Override
    public String label() { throw new UnsupportedOperationException(); }
    @Override
    public String format() { throw new UnsupportedOperationException(); }
    @Override
    public String numberOfRows() { throw new UnsupportedOperationException(); }
    @Override
    public String diskUsage() { throw new UnsupportedOperationException(); }
    @Override
    public String location() { throw new UnsupportedOperationException(); }
    @Override
    public String project() { throw new UnsupportedOperationException(); }
    @Override
    public String catalog() { throw new UnsupportedOperationException(); }
    @Override
    public String schema() { throw new UnsupportedOperationException(); }
    @Override
    public String database() { throw new UnsupportedOperationException(); }
    @Override
    public String replicationFactor() { throw new UnsupportedOperationException(); }
    @Override
    public String tags() { throw new UnsupportedOperationException(); }
    @Override
    public String sourceSystem() { throw new UnsupportedOperationException(); }
    @Override
    public String origin() { throw new UnsupportedOperationException(); }
    @Override
    public String creationDate() { throw new UnsupportedOperationException(); }
    @Override
    public String updateDate() { throw new UnsupportedOperationException(); }
    @Override
    public String createdBy() { throw new UnsupportedOperationException(); }
    @Override
    public String updatedBy() { throw new UnsupportedOperationException(); }
    @Override
    public String comments() { throw new UnsupportedOperationException(); }
  }

  /**
   * @param json A JSON-bindable data structure
   * @return An immutable value type
   * @deprecated Do not use this method directly, it exists only for the <em>Jackson</em>-binding infrastructure
   */
  @Deprecated
  @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
  static ImmutableZdfDataset fromJson(Json json) {
    ImmutableZdfDataset.Builder builder = ImmutableZdfDataset.builder();
    if (json.path != null) {
      builder.path(json.path);
    }
    if (json.name != null) {
      builder.name(json.name);
    }
    if (json.description != null) {
      builder.description(json.description);
    }
    if (json.owner != null) {
      builder.owner(json.owner);
    }
    if (json.fields != null) {
      builder.addAllFields(json.fields);
    }
    if (json.foreignKeysIsSet) {
      builder.addAllForeignKeys(json.foreignKeys);
    }
    if (json.type != null) {
      builder.type(json.type);
    }
    if (json.label != null) {
      builder.label(json.label);
    }
    if (json.format != null) {
      builder.format(json.format);
    }
    if (json.numberOfRows != null) {
      builder.numberOfRows(json.numberOfRows);
    }
    if (json.diskUsage != null) {
      builder.diskUsage(json.diskUsage);
    }
    if (json.location != null) {
      builder.location(json.location);
    }
    if (json.project != null) {
      builder.project(json.project);
    }
    if (json.catalog != null) {
      builder.catalog(json.catalog);
    }
    if (json.schema != null) {
      builder.schema(json.schema);
    }
    if (json.database != null) {
      builder.database(json.database);
    }
    if (json.replicationFactor != null) {
      builder.replicationFactor(json.replicationFactor);
    }
    if (json.tags != null) {
      builder.tags(json.tags);
    }
    if (json.sourceSystem != null) {
      builder.sourceSystem(json.sourceSystem);
    }
    if (json.origin != null) {
      builder.origin(json.origin);
    }
    if (json.creationDate != null) {
      builder.creationDate(json.creationDate);
    }
    if (json.updateDate != null) {
      builder.updateDate(json.updateDate);
    }
    if (json.createdBy != null) {
      builder.createdBy(json.createdBy);
    }
    if (json.updatedBy != null) {
      builder.updatedBy(json.updatedBy);
    }
    if (json.comments != null) {
      builder.comments(json.comments);
    }
    return builder.build();
  }

  /**
   * Creates an immutable copy of a {@link ZdfDataset} value.
   * Uses accessors to get values to initialize the new immutable instance.
   * If an instance is already immutable, it is returned as is.
   * @param instance The instance to copy
   * @return A copied immutable ZdfDataset instance
   */
  public static ImmutableZdfDataset copyOf(ZdfDataset instance) {
    if (instance instanceof ImmutableZdfDataset) {
      return (ImmutableZdfDataset) instance;
    }
    return ImmutableZdfDataset.builder()
        .from(instance)
        .build();
  }

  /**
   * Creates a builder for {@link ImmutableZdfDataset ImmutableZdfDataset}.
   * <pre>
   * ImmutableZdfDataset.builder()
   *    .path(String | null) // nullable {@link ZdfDataset#path() path}
   *    .name(String) // required {@link ZdfDataset#name() name}
   *    .description(String | null) // nullable {@link ZdfDataset#description() description}
   *    .owner(zeenea.connector.zdf.model.ZdfOwner | null) // nullable {@link ZdfDataset#owner() owner}
   *    .addFields|addAllFields(zeenea.connector.zdf.model.ZdfField) // {@link ZdfDataset#fields() fields} elements
   *    .addForeignKeys|addAllForeignKeys(zeenea.connector.zdf.model.ZdfForeignKey) // {@link ZdfDataset#foreignKeys() foreignKeys} elements
   *    .type(String | null) // nullable {@link ZdfDataset#type() type}
   *    .label(String | null) // nullable {@link ZdfDataset#label() label}
   *    .format(String | null) // nullable {@link ZdfDataset#format() format}
   *    .numberOfRows(String | null) // nullable {@link ZdfDataset#numberOfRows() numberOfRows}
   *    .diskUsage(String | null) // nullable {@link ZdfDataset#diskUsage() diskUsage}
   *    .location(String | null) // nullable {@link ZdfDataset#location() location}
   *    .project(String | null) // nullable {@link ZdfDataset#project() project}
   *    .catalog(String | null) // nullable {@link ZdfDataset#catalog() catalog}
   *    .schema(String | null) // nullable {@link ZdfDataset#schema() schema}
   *    .database(String | null) // nullable {@link ZdfDataset#database() database}
   *    .replicationFactor(String | null) // nullable {@link ZdfDataset#replicationFactor() replicationFactor}
   *    .tags(String | null) // nullable {@link ZdfDataset#tags() tags}
   *    .sourceSystem(String | null) // nullable {@link ZdfDataset#sourceSystem() sourceSystem}
   *    .origin(String | null) // nullable {@link ZdfDataset#origin() origin}
   *    .creationDate(String | null) // nullable {@link ZdfDataset#creationDate() creationDate}
   *    .updateDate(String | null) // nullable {@link ZdfDataset#updateDate() updateDate}
   *    .createdBy(String | null) // nullable {@link ZdfDataset#createdBy() createdBy}
   *    .updatedBy(String | null) // nullable {@link ZdfDataset#updatedBy() updatedBy}
   *    .comments(String | null) // nullable {@link ZdfDataset#comments() comments}
   *    .build();
   * </pre>
   * @return A new ImmutableZdfDataset builder
   */
  public static ImmutableZdfDataset.Builder builder() {
    return new ImmutableZdfDataset.Builder();
  }

  /**
   * Builds instances of type {@link ImmutableZdfDataset ImmutableZdfDataset}.
   * Initialize attributes and then invoke the {@link #build()} method to create an
   * immutable instance.
   * <p><em>{@code Builder} is not thread-safe and generally should not be stored in a field or collection,
   * but instead used immediately to create instances.</em>
   */
  @Generated(from = "ZdfDataset", generator = "Immutables")
  @NotThreadSafe
  public static final class Builder {
    private static final long INIT_BIT_NAME = 0x1L;
    private static final long OPT_BIT_FOREIGN_KEYS = 0x1L;
    private long initBits = 0x1L;
    private long optBits;

    private @javax.annotation.Nullable String path;
    private @javax.annotation.Nullable String name;
    private @javax.annotation.Nullable String description;
    private @javax.annotation.Nullable ZdfOwner owner;
    private List<ZdfField> fields = new ArrayList<ZdfField>();
    private List<ZdfForeignKey> foreignKeys = new ArrayList<ZdfForeignKey>();
    private @javax.annotation.Nullable String type;
    private @javax.annotation.Nullable String label;
    private @javax.annotation.Nullable String format;
    private @javax.annotation.Nullable String numberOfRows;
    private @javax.annotation.Nullable String diskUsage;
    private @javax.annotation.Nullable String location;
    private @javax.annotation.Nullable String project;
    private @javax.annotation.Nullable String catalog;
    private @javax.annotation.Nullable String schema;
    private @javax.annotation.Nullable String database;
    private @javax.annotation.Nullable String replicationFactor;
    private @javax.annotation.Nullable String tags;
    private @javax.annotation.Nullable String sourceSystem;
    private @javax.annotation.Nullable String origin;
    private @javax.annotation.Nullable String creationDate;
    private @javax.annotation.Nullable String updateDate;
    private @javax.annotation.Nullable String createdBy;
    private @javax.annotation.Nullable String updatedBy;
    private @javax.annotation.Nullable String comments;

    private Builder() {
    }

    /**
     * Fill a builder with attribute values from the provided {@code zeenea.connector.zdf.model.ZdfItem} instance.
     * @param instance The instance from which to copy values
     * @return {@code this} builder for use in a chained invocation
     */
    public final Builder from(ZdfItem instance) {
      Objects.requireNonNull(instance, "instance");
      from((short) 0, (Object) instance);
      return this;
    }

    /**
     * Fill a builder with attribute values from the provided {@code zeenea.connector.zdf.model.ZdfDataset} instance.
     * @param instance The instance from which to copy values
     * @return {@code this} builder for use in a chained invocation
     */
    public final Builder from(ZdfDataset instance) {
      Objects.requireNonNull(instance, "instance");
      from((short) 0, (Object) instance);
      return this;
    }

    private void from(short _unused, Object object) {
      long bits = 0;
      if (object instanceof ZdfItem) {
        ZdfItem instance = (ZdfItem) object;
        if ((bits & 0x4L) == 0) {
          @Nullable ZdfOwner ownerValue = instance.owner();
          if (ownerValue != null) {
            owner(ownerValue);
          }
          bits |= 0x4L;
        }
        if ((bits & 0x8L) == 0) {
          this.name(instance.name());
          bits |= 0x8L;
        }
        if ((bits & 0x1L) == 0) {
          @Nullable String descriptionValue = instance.description();
          if (descriptionValue != null) {
            description(descriptionValue);
          }
          bits |= 0x1L;
        }
        if ((bits & 0x2L) == 0) {
          @Nullable String pathValue = instance.path();
          if (pathValue != null) {
            path(pathValue);
          }
          bits |= 0x2L;
        }
      }
      if (object instanceof ZdfDataset) {
        ZdfDataset instance = (ZdfDataset) object;
        @Nullable String schemaValue = instance.schema();
        if (schemaValue != null) {
          schema(schemaValue);
        }
        @Nullable String replicationFactorValue = instance.replicationFactor();
        if (replicationFactorValue != null) {
          replicationFactor(replicationFactorValue);
        }
        addAllForeignKeys(instance.foreignKeys());
        @Nullable String updateDateValue = instance.updateDate();
        if (updateDateValue != null) {
          updateDate(updateDateValue);
        }
        @Nullable String catalogValue = instance.catalog();
        if (catalogValue != null) {
          catalog(catalogValue);
        }
        @Nullable String sourceSystemValue = instance.sourceSystem();
        if (sourceSystemValue != null) {
          sourceSystem(sourceSystemValue);
        }
        @Nullable String originValue = instance.origin();
        if (originValue != null) {
          origin(originValue);
        }
        if ((bits & 0x1L) == 0) {
          @Nullable String descriptionValue = instance.description();
          if (descriptionValue != null) {
            description(descriptionValue);
          }
          bits |= 0x1L;
        }
        @Nullable String projectValue = instance.project();
        if (projectValue != null) {
          project(projectValue);
        }
        @Nullable String typeValue = instance.type();
        if (typeValue != null) {
          type(typeValue);
        }
        if ((bits & 0x2L) == 0) {
          @Nullable String pathValue = instance.path();
          if (pathValue != null) {
            path(pathValue);
          }
          bits |= 0x2L;
        }
        @Nullable String databaseValue = instance.database();
        if (databaseValue != null) {
          database(databaseValue);
        }
        if ((bits & 0x4L) == 0) {
          @Nullable ZdfOwner ownerValue = instance.owner();
          if (ownerValue != null) {
            owner(ownerValue);
          }
          bits |= 0x4L;
        }
        @Nullable String updatedByValue = instance.updatedBy();
        if (updatedByValue != null) {
          updatedBy(updatedByValue);
        }
        @Nullable String commentsValue = instance.comments();
        if (commentsValue != null) {
          comments(commentsValue);
        }
        @Nullable String formatValue = instance.format();
        if (formatValue != null) {
          format(formatValue);
        }
        @Nullable String labelValue = instance.label();
        if (labelValue != null) {
          label(labelValue);
        }
        @Nullable String creationDateValue = instance.creationDate();
        if (creationDateValue != null) {
          creationDate(creationDateValue);
        }
        @Nullable String tagsValue = instance.tags();
        if (tagsValue != null) {
          tags(tagsValue);
        }
        @Nullable String createdByValue = instance.createdBy();
        if (createdByValue != null) {
          createdBy(createdByValue);
        }
        if ((bits & 0x8L) == 0) {
          this.name(instance.name());
          bits |= 0x8L;
        }
        @Nullable String diskUsageValue = instance.diskUsage();
        if (diskUsageValue != null) {
          diskUsage(diskUsageValue);
        }
        @Nullable String locationValue = instance.location();
        if (locationValue != null) {
          location(locationValue);
        }
        @Nullable String numberOfRowsValue = instance.numberOfRows();
        if (numberOfRowsValue != null) {
          numberOfRows(numberOfRowsValue);
        }
        addAllFields(instance.fields());
      }
    }

    /**
     * Initializes the value for the {@link ZdfDataset#path() path} attribute.
     * @param path The value for path (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("path")
    public final Builder path(@Nullable String path) {
      this.path = path;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#name() name} attribute.
     * @param name The value for name 
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("name")
    public final Builder name(String name) {
      this.name = Objects.requireNonNull(name, "name");
      initBits &= ~INIT_BIT_NAME;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#description() description} attribute.
     * @param description The value for description (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("description")
    public final Builder description(@Nullable String description) {
      this.description = description;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#owner() owner} attribute.
     * @param owner The value for owner (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("owner")
    public final Builder owner(@Nullable ZdfOwner owner) {
      this.owner = owner;
      return this;
    }

    /**
     * Adds one element to {@link ZdfDataset#fields() fields} list.
     * @param element A fields element
     * @return {@code this} builder for use in a chained invocation
     */
    public final Builder addFields(ZdfField element) {
      this.fields.add(Objects.requireNonNull(element, "fields element"));
      return this;
    }

    /**
     * Adds elements to {@link ZdfDataset#fields() fields} list.
     * @param elements An array of fields elements
     * @return {@code this} builder for use in a chained invocation
     */
    public final Builder addFields(ZdfField... elements) {
      for (ZdfField element : elements) {
        this.fields.add(Objects.requireNonNull(element, "fields element"));
      }
      return this;
    }


    /**
     * Sets or replaces all elements for {@link ZdfDataset#fields() fields} list.
     * @param elements An iterable of fields elements
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("fields")
    public final Builder fields(Iterable<? extends ZdfField> elements) {
      this.fields.clear();
      return addAllFields(elements);
    }

    /**
     * Adds elements to {@link ZdfDataset#fields() fields} list.
     * @param elements An iterable of fields elements
     * @return {@code this} builder for use in a chained invocation
     */
    public final Builder addAllFields(Iterable<? extends ZdfField> elements) {
      for (ZdfField element : elements) {
        this.fields.add(Objects.requireNonNull(element, "fields element"));
      }
      return this;
    }

    /**
     * Adds one element to {@link ZdfDataset#foreignKeys() foreignKeys} list.
     * @param element A foreignKeys element
     * @return {@code this} builder for use in a chained invocation
     */
    public final Builder addForeignKeys(ZdfForeignKey element) {
      this.foreignKeys.add(Objects.requireNonNull(element, "foreignKeys element"));
      optBits |= OPT_BIT_FOREIGN_KEYS;
      return this;
    }

    /**
     * Adds elements to {@link ZdfDataset#foreignKeys() foreignKeys} list.
     * @param elements An array of foreignKeys elements
     * @return {@code this} builder for use in a chained invocation
     */
    public final Builder addForeignKeys(ZdfForeignKey... elements) {
      for (ZdfForeignKey element : elements) {
        this.foreignKeys.add(Objects.requireNonNull(element, "foreignKeys element"));
      }
      optBits |= OPT_BIT_FOREIGN_KEYS;
      return this;
    }


    /**
     * Sets or replaces all elements for {@link ZdfDataset#foreignKeys() foreignKeys} list.
     * @param elements An iterable of foreignKeys elements
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("foreignKeys")
    public final Builder foreignKeys(Iterable<? extends ZdfForeignKey> elements) {
      this.foreignKeys.clear();
      return addAllForeignKeys(elements);
    }

    /**
     * Adds elements to {@link ZdfDataset#foreignKeys() foreignKeys} list.
     * @param elements An iterable of foreignKeys elements
     * @return {@code this} builder for use in a chained invocation
     */
    public final Builder addAllForeignKeys(Iterable<? extends ZdfForeignKey> elements) {
      for (ZdfForeignKey element : elements) {
        this.foreignKeys.add(Objects.requireNonNull(element, "foreignKeys element"));
      }
      optBits |= OPT_BIT_FOREIGN_KEYS;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#type() type} attribute.
     * @param type The value for type (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("type")
    public final Builder type(@Nullable String type) {
      this.type = type;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#label() label} attribute.
     * @param label The value for label (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("label")
    public final Builder label(@Nullable String label) {
      this.label = label;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#format() format} attribute.
     * @param format The value for format (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("format")
    public final Builder format(@Nullable String format) {
      this.format = format;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#numberOfRows() numberOfRows} attribute.
     * @param numberOfRows The value for numberOfRows (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("numberOfRows")
    public final Builder numberOfRows(@Nullable String numberOfRows) {
      this.numberOfRows = numberOfRows;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#diskUsage() diskUsage} attribute.
     * @param diskUsage The value for diskUsage (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("diskUsage")
    public final Builder diskUsage(@Nullable String diskUsage) {
      this.diskUsage = diskUsage;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#location() location} attribute.
     * @param location The value for location (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("location")
    public final Builder location(@Nullable String location) {
      this.location = location;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#project() project} attribute.
     * @param project The value for project (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("project")
    public final Builder project(@Nullable String project) {
      this.project = project;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#catalog() catalog} attribute.
     * @param catalog The value for catalog (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("catalog")
    public final Builder catalog(@Nullable String catalog) {
      this.catalog = catalog;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#schema() schema} attribute.
     * @param schema The value for schema (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("schema")
    public final Builder schema(@Nullable String schema) {
      this.schema = schema;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#database() database} attribute.
     * @param database The value for database (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("database")
    public final Builder database(@Nullable String database) {
      this.database = database;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#replicationFactor() replicationFactor} attribute.
     * @param replicationFactor The value for replicationFactor (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("replicationFactor")
    public final Builder replicationFactor(@Nullable String replicationFactor) {
      this.replicationFactor = replicationFactor;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#tags() tags} attribute.
     * @param tags The value for tags (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("tags")
    public final Builder tags(@Nullable String tags) {
      this.tags = tags;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#sourceSystem() sourceSystem} attribute.
     * @param sourceSystem The value for sourceSystem (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("sourceSystem")
    public final Builder sourceSystem(@Nullable String sourceSystem) {
      this.sourceSystem = sourceSystem;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#origin() origin} attribute.
     * @param origin The value for origin (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("origin")
    public final Builder origin(@Nullable String origin) {
      this.origin = origin;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#creationDate() creationDate} attribute.
     * @param creationDate The value for creationDate (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("creationDate")
    public final Builder creationDate(@Nullable String creationDate) {
      this.creationDate = creationDate;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#updateDate() updateDate} attribute.
     * @param updateDate The value for updateDate (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("updateDate")
    public final Builder updateDate(@Nullable String updateDate) {
      this.updateDate = updateDate;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#createdBy() createdBy} attribute.
     * @param createdBy The value for createdBy (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("createdBy")
    public final Builder createdBy(@Nullable String createdBy) {
      this.createdBy = createdBy;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#updatedBy() updatedBy} attribute.
     * @param updatedBy The value for updatedBy (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("updatedBy")
    public final Builder updatedBy(@Nullable String updatedBy) {
      this.updatedBy = updatedBy;
      return this;
    }

    /**
     * Initializes the value for the {@link ZdfDataset#comments() comments} attribute.
     * @param comments The value for comments (can be {@code null})
     * @return {@code this} builder for use in a chained invocation
     */
    @JsonProperty("comments")
    public final Builder comments(@Nullable String comments) {
      this.comments = comments;
      return this;
    }

    /**
     * Builds a new {@link ImmutableZdfDataset ImmutableZdfDataset}.
     * @return An immutable instance of ZdfDataset
     * @throws java.lang.IllegalStateException if any required attributes are missing
     */
    public ImmutableZdfDataset build() {
      if (initBits != 0) {
        throw new IllegalStateException(formatRequiredAttributesMessage());
      }
      return new ImmutableZdfDataset(this);
    }

    private boolean foreignKeysIsSet() {
      return (optBits & OPT_BIT_FOREIGN_KEYS) != 0;
    }

    private String formatRequiredAttributesMessage() {
      List<String> attributes = new ArrayList<>();
      if ((initBits & INIT_BIT_NAME) != 0) attributes.add("name");
      return "Cannot build ZdfDataset, some of required attributes are not set " + attributes;
    }
  }
}
