/*
 * Copyright (C) 2010 The Libphonenumber Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Definition of the class representing metadata for international telephone numbers. This class is
 * hand created based on the class file compiled from phonemetadata.proto. Please refer to that file
 * for detailed descriptions of the meaning of each field.
 *
 * <p>WARNING: This API isn't stable. It is considered libphonenumber-internal and can change at any
 * time. We only declare it as public for easy inclusion in our build tools not in this package.
 * Clients should not refer to this file, we do not commit to support backwards-compatibility or to
 * warn about breaking changes.
 */

package com.google.i18n.phonenumbers;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public final class Phonemetadata {
  private Phonemetadata() {}
  public static class NumberFormat implements Externalizable {
    private static final long serialVersionUID = 1;
    public NumberFormat() {}

    /**
     * Provides a dummy builder to 'emulate' the API of the code generated by the latest version of
     * Protocol Buffers. This lets BuildMetadataFromXml class to build with both this hand created
     * class and the one generated by the latest version of Protocol Buffers.
     */
    public static final class Builder extends NumberFormat {
      public NumberFormat build() {
        return this;
      }

      public Builder mergeFrom(NumberFormat other) {
        if (other.hasPattern()) {
          setPattern(other.getPattern());
        }
        if (other.hasFormat()) {
          setFormat(other.getFormat());
        }
        for (int i = 0; i < other.leadingDigitsPatternSize(); i++) {
          addLeadingDigitsPattern(other.getLeadingDigitsPattern(i));
        }
        if (other.hasNationalPrefixFormattingRule()) {
          setNationalPrefixFormattingRule(other.getNationalPrefixFormattingRule());
        }
        if (other.hasDomesticCarrierCodeFormattingRule()) {
          setDomesticCarrierCodeFormattingRule(other.getDomesticCarrierCodeFormattingRule());
        }
        if (other.hasNationalPrefixOptionalWhenFormatting()) {
          setNationalPrefixOptionalWhenFormatting(other.getNationalPrefixOptionalWhenFormatting());
        }
        return this;
      }
    }

    public static Builder newBuilder() {
      return new Builder();
    }

    // required string pattern = 1;
    private boolean hasPattern;
    private String pattern_ = "";
    public boolean hasPattern() { return hasPattern; }
    public String getPattern() { return pattern_; }
    public NumberFormat setPattern(String value) {
      hasPattern = true;
      pattern_ = value;
      return this;
    }

    // required string format = 2;
    private boolean hasFormat;
    private String format_ = "";
    public boolean hasFormat() { return hasFormat; }
    public String getFormat() { return format_; }
    public NumberFormat setFormat(String value) {
      hasFormat = true;
      format_ = value;
      return this;
    }

    // repeated string leading_digits_pattern = 3;
    private java.util.List<String> leadingDigitsPattern_ = new java.util.ArrayList<String>();
    public java.util.List<String> leadingDigitPatterns() {
      return leadingDigitsPattern_;
    }
    @Deprecated
    public int leadingDigitsPatternSize() { return getLeadingDigitsPatternCount(); }
    public int getLeadingDigitsPatternCount() { return leadingDigitsPattern_.size(); }
    public String getLeadingDigitsPattern(int index) {
      return leadingDigitsPattern_.get(index);
    }
    public NumberFormat addLeadingDigitsPattern(String value) {
      if (value == null) {
        throw new NullPointerException();
      }
      leadingDigitsPattern_.add(value);
      return this;
    }

    // optional string national_prefix_formatting_rule = 4;
    private boolean hasNationalPrefixFormattingRule;
    private String nationalPrefixFormattingRule_ = "";
    public boolean hasNationalPrefixFormattingRule() { return hasNationalPrefixFormattingRule; }
    public String getNationalPrefixFormattingRule() { return nationalPrefixFormattingRule_; }
    public NumberFormat setNationalPrefixFormattingRule(String value) {
      hasNationalPrefixFormattingRule = true;
      nationalPrefixFormattingRule_ = value;
      return this;
    }
    public NumberFormat clearNationalPrefixFormattingRule() {
      hasNationalPrefixFormattingRule = false;
      nationalPrefixFormattingRule_ = "";
      return this;
    }

    // optional bool national_prefix_optional_when_formatting = 6 [default = false];
    private boolean hasNationalPrefixOptionalWhenFormatting;
    private boolean nationalPrefixOptionalWhenFormatting_ = false;
    public boolean hasNationalPrefixOptionalWhenFormatting() {
      return hasNationalPrefixOptionalWhenFormatting; }
    public boolean getNationalPrefixOptionalWhenFormatting() {
      return nationalPrefixOptionalWhenFormatting_; }
    public NumberFormat setNationalPrefixOptionalWhenFormatting(boolean value) {
      hasNationalPrefixOptionalWhenFormatting = true;
      nationalPrefixOptionalWhenFormatting_ = value;
      return this;
    }

    // optional string domestic_carrier_code_formatting_rule = 5;
    private boolean hasDomesticCarrierCodeFormattingRule;
    private String domesticCarrierCodeFormattingRule_ = "";
    public boolean hasDomesticCarrierCodeFormattingRule() {
      return hasDomesticCarrierCodeFormattingRule; }
    public String getDomesticCarrierCodeFormattingRule() {
      return domesticCarrierCodeFormattingRule_; }
    public NumberFormat setDomesticCarrierCodeFormattingRule(String value) {
      hasDomesticCarrierCodeFormattingRule = true;
      domesticCarrierCodeFormattingRule_ = value;
      return this;
    }

    public void writeExternal(ObjectOutput objectOutput) throws IOException {
      objectOutput.writeUTF(pattern_);
      objectOutput.writeUTF(format_);
      int leadingDigitsPatternSize = leadingDigitsPatternSize();
      objectOutput.writeInt(leadingDigitsPatternSize);
      for (int i = 0; i < leadingDigitsPatternSize; i++) {
        objectOutput.writeUTF(leadingDigitsPattern_.get(i));
      }

      objectOutput.writeBoolean(hasNationalPrefixFormattingRule);
      if (hasNationalPrefixFormattingRule) {
        objectOutput.writeUTF(nationalPrefixFormattingRule_);
      }
      objectOutput.writeBoolean(hasDomesticCarrierCodeFormattingRule);
      if (hasDomesticCarrierCodeFormattingRule) {
        objectOutput.writeUTF(domesticCarrierCodeFormattingRule_);
      }
      objectOutput.writeBoolean(nationalPrefixOptionalWhenFormatting_);
    }

    public void readExternal(ObjectInput objectInput) throws IOException {
      setPattern(objectInput.readUTF());
      setFormat(objectInput.readUTF());
      int leadingDigitsPatternSize = objectInput.readInt();
      for (int i = 0; i < leadingDigitsPatternSize; i++) {
        leadingDigitsPattern_.add(objectInput.readUTF());
      }
      if (objectInput.readBoolean()) {
        setNationalPrefixFormattingRule(objectInput.readUTF());
      }
      if (objectInput.readBoolean()) {
        setDomesticCarrierCodeFormattingRule(objectInput.readUTF());
      }
      setNationalPrefixOptionalWhenFormatting(objectInput.readBoolean());
    }
  }

  public static class PhoneNumberDesc implements Externalizable {
    private static final long serialVersionUID = 1;
    public PhoneNumberDesc() {}

    /**
     * Provides a dummy builder.
     *
     * @see NumberFormat.Builder
     */
    public static final class Builder extends PhoneNumberDesc {
      public PhoneNumberDesc build() {
        return this;
      }

      public Builder mergeFrom(PhoneNumberDesc other) {
        if (other.hasNationalNumberPattern()) {
          setNationalNumberPattern(other.getNationalNumberPattern());
        }
        for (int i = 0; i < other.getPossibleLengthCount(); i++) {
          addPossibleLength(other.getPossibleLength(i));
        }
        for (int i = 0; i < other.getPossibleLengthLocalOnlyCount(); i++) {
          addPossibleLengthLocalOnly(other.getPossibleLengthLocalOnly(i));
        }
        if (other.hasExampleNumber()) {
          setExampleNumber(other.getExampleNumber());
        }
        return this;
      }
    }

    public static Builder newBuilder() {
      return new Builder();
    }

    // optional string national_number_pattern = 2;
    private boolean hasNationalNumberPattern;
    private String nationalNumberPattern_ = "";
    public boolean hasNationalNumberPattern() { return hasNationalNumberPattern; }
    public String getNationalNumberPattern() { return nationalNumberPattern_; }
    public PhoneNumberDesc setNationalNumberPattern(String value) {
      hasNationalNumberPattern = true;
      nationalNumberPattern_ = value;
      return this;
    }
    public PhoneNumberDesc clearNationalNumberPattern() {
      hasNationalNumberPattern = false;
      nationalNumberPattern_ = "";
      return this;
    }

    // repeated int32 possible_length = 9;
    private java.util.List<Integer> possibleLength_ = new java.util.ArrayList<Integer>();
    public java.util.List<Integer> getPossibleLengthList() {
      return possibleLength_;
    }
    public int getPossibleLengthCount() { return possibleLength_.size(); }
    public int getPossibleLength(int index) {
      return possibleLength_.get(index);
    }
    public PhoneNumberDesc addPossibleLength(int value) {
      possibleLength_.add(value);
      return this;
    }
    public PhoneNumberDesc clearPossibleLength() {
      possibleLength_.clear();
      return this;
    }

    // repeated int32 possible_length_local_only = 10;
    private java.util.List<Integer> possibleLengthLocalOnly_ = new java.util.ArrayList<Integer>();
    public java.util.List<Integer> getPossibleLengthLocalOnlyList() {
      return possibleLengthLocalOnly_;
    }
    public int getPossibleLengthLocalOnlyCount() { return possibleLengthLocalOnly_.size(); }
    public int getPossibleLengthLocalOnly(int index) {
      return possibleLengthLocalOnly_.get(index);
    }
    public PhoneNumberDesc addPossibleLengthLocalOnly(int value) {
      possibleLengthLocalOnly_.add(value);
      return this;
    }
    public PhoneNumberDesc clearPossibleLengthLocalOnly() {
      possibleLengthLocalOnly_.clear();
      return this;
    }

    // optional string example_number = 6;
    private boolean hasExampleNumber;
    private String exampleNumber_ = "";
    public boolean hasExampleNumber() { return hasExampleNumber; }
    public String getExampleNumber() { return exampleNumber_; }
    public PhoneNumberDesc setExampleNumber(String value) {
      hasExampleNumber = true;
      exampleNumber_ = value;
      return this;
    }
    public PhoneNumberDesc clearExampleNumber() {
      hasExampleNumber = false;
      exampleNumber_ = "";
      return this;
    }

    public boolean exactlySameAs(PhoneNumberDesc other) {
      return nationalNumberPattern_.equals(other.nationalNumberPattern_) &&
          possibleLength_.equals(other.possibleLength_) &&
          possibleLengthLocalOnly_.equals(other.possibleLengthLocalOnly_) &&
          exampleNumber_.equals(other.exampleNumber_);
    }

    public void writeExternal(ObjectOutput objectOutput) throws IOException {
      objectOutput.writeBoolean(hasNationalNumberPattern);
      if (hasNationalNumberPattern) {
        objectOutput.writeUTF(nationalNumberPattern_);
      }

      int possibleLengthSize = getPossibleLengthCount();
      objectOutput.writeInt(possibleLengthSize);
      for (int i = 0; i < possibleLengthSize; i++) {
        objectOutput.writeInt(possibleLength_.get(i));
      }

      int possibleLengthLocalOnlySize = getPossibleLengthLocalOnlyCount();
      objectOutput.writeInt(possibleLengthLocalOnlySize);
      for (int i = 0; i < possibleLengthLocalOnlySize; i++) {
        objectOutput.writeInt(possibleLengthLocalOnly_.get(i));
      }

      objectOutput.writeBoolean(hasExampleNumber);
      if (hasExampleNumber) {
        objectOutput.writeUTF(exampleNumber_);
      }
    }

    public void readExternal(ObjectInput objectInput) throws IOException {
      if (objectInput.readBoolean()) {
        setNationalNumberPattern(objectInput.readUTF());
      }

      int possibleLengthSize = objectInput.readInt();
      for (int i = 0; i < possibleLengthSize; i++) {
        possibleLength_.add(objectInput.readInt());
      }

      int possibleLengthLocalOnlySize = objectInput.readInt();
      for (int i = 0; i < possibleLengthLocalOnlySize; i++) {
        possibleLengthLocalOnly_.add(objectInput.readInt());
      }

      if (objectInput.readBoolean()) {
        setExampleNumber(objectInput.readUTF());
      }
    }
  }

  public static class PhoneMetadata implements Externalizable {
    private static final long serialVersionUID = 1;
    public PhoneMetadata() {}

    /**
     * Provides a dummy builder.
     *
     * @see NumberFormat.Builder
     */
    public static final class Builder extends PhoneMetadata {
      public PhoneMetadata build() {
        return this;
      }

      public Builder setId(String value) {
        super.setId(value);
        return this;
      }

      public Builder setInternationalPrefix(String value) {
        super.setInternationalPrefix(value);
        return this;
      }
    }
    public static Builder newBuilder() {
      return new Builder();
    }

    // optional PhoneNumberDesc general_desc = 1;
    private boolean hasGeneralDesc;
    private PhoneNumberDesc generalDesc_ = null;
    public boolean hasGeneralDesc() { return hasGeneralDesc; }
    public PhoneNumberDesc getGeneralDesc() { return generalDesc_; }
    public PhoneNumberDesc getGeneralDescBuilder() {
      if (generalDesc_ == null) {
        generalDesc_ = new PhoneNumberDesc();
      }
      return generalDesc_ ;
    }
    public PhoneMetadata setGeneralDesc(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasGeneralDesc = true;
      generalDesc_ = value;
      return this;
    }

    // optional PhoneNumberDesc fixed_line = 2;
    private boolean hasFixedLine;
    private PhoneNumberDesc fixedLine_ = null;
    public boolean hasFixedLine() { return hasFixedLine; }
    public PhoneNumberDesc getFixedLine() { return fixedLine_; }
    public PhoneMetadata setFixedLine(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasFixedLine = true;
      fixedLine_ = value;
      return this;
    }

    // optional PhoneNumberDesc mobile = 3;
    private boolean hasMobile;
    private PhoneNumberDesc mobile_ = null;
    public boolean hasMobile() { return hasMobile; }
    public PhoneNumberDesc getMobile() { return mobile_; }
    public PhoneMetadata setMobile(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasMobile = true;
      mobile_ = value;
      return this;
    }

    // optional PhoneNumberDesc toll_free = 4;
    private boolean hasTollFree;
    private PhoneNumberDesc tollFree_ = null;
    public boolean hasTollFree() { return hasTollFree; }
    public PhoneNumberDesc getTollFree() { return tollFree_; }
    public PhoneMetadata setTollFree(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasTollFree = true;
      tollFree_ = value;
      return this;
    }

    // optional PhoneNumberDesc premium_rate = 5;
    private boolean hasPremiumRate;
    private PhoneNumberDesc premiumRate_ = null;
    public boolean hasPremiumRate() { return hasPremiumRate; }
    public PhoneNumberDesc getPremiumRate() { return premiumRate_; }
    public PhoneMetadata setPremiumRate(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasPremiumRate = true;
      premiumRate_ = value;
      return this;
    }

    // optional PhoneNumberDesc shared_cost = 6;
    private boolean hasSharedCost;
    private PhoneNumberDesc sharedCost_ = null;
    public boolean hasSharedCost() { return hasSharedCost; }
    public PhoneNumberDesc getSharedCost() { return sharedCost_; }
    public PhoneMetadata setSharedCost(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasSharedCost = true;
      sharedCost_ = value;
      return this;
    }

    // optional PhoneNumberDesc personal_number = 7;
    private boolean hasPersonalNumber;
    private PhoneNumberDesc personalNumber_ = null;
    public boolean hasPersonalNumber() { return hasPersonalNumber; }
    public PhoneNumberDesc getPersonalNumber() { return personalNumber_; }
    public PhoneMetadata setPersonalNumber(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasPersonalNumber = true;
      personalNumber_ = value;
      return this;
    }

    // optional PhoneNumberDesc voip = 8;
    private boolean hasVoip;
    private PhoneNumberDesc voip_ = null;
    public boolean hasVoip() { return hasVoip; }
    public PhoneNumberDesc getVoip() { return voip_; }
    public PhoneMetadata setVoip(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasVoip = true;
      voip_ = value;
      return this;
    }

    // optional PhoneNumberDesc pager = 21;
    private boolean hasPager;
    private PhoneNumberDesc pager_ = null;
    public boolean hasPager() { return hasPager; }
    public PhoneNumberDesc getPager() { return pager_; }
    public PhoneMetadata setPager(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasPager = true;
      pager_ = value;
      return this;
    }

    // optional PhoneNumberDesc uan = 25;
    private boolean hasUan;
    private PhoneNumberDesc uan_ = null;
    public boolean hasUan() { return hasUan; }
    public PhoneNumberDesc getUan() { return uan_; }
    public PhoneMetadata setUan(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasUan = true;
      uan_ = value;
      return this;
    }

    // optional PhoneNumberDesc emergency = 27;
    private boolean hasEmergency;
    private PhoneNumberDesc emergency_ = null;
    public boolean hasEmergency() { return hasEmergency; }
    public PhoneNumberDesc getEmergency() { return emergency_; }
    public PhoneMetadata setEmergency(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasEmergency = true;
      emergency_ = value;
      return this;
    }

    // optional PhoneNumberDesc voicemail = 28;
    private boolean hasVoicemail;
    private PhoneNumberDesc voicemail_ = null;
    public boolean hasVoicemail() { return hasVoicemail; }
    public PhoneNumberDesc getVoicemail() { return voicemail_; }
    public PhoneMetadata setVoicemail(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasVoicemail = true;
      voicemail_ = value;
      return this;
    }

    // optional PhoneNumberDesc short_code = 29;
    private boolean hasShortCode;
    private PhoneNumberDesc shortCode_ = null;
    public boolean hasShortCode() { return hasShortCode; }
    public PhoneNumberDesc getShortCode() { return shortCode_; }
    public PhoneMetadata setShortCode(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasShortCode = true;
      shortCode_ = value;
      return this;
    }

    // optional PhoneNumberDesc standard_rate = 30;
    private boolean hasStandardRate;
    private PhoneNumberDesc standardRate_ = null;
    public boolean hasStandardRate() { return hasStandardRate; }
    public PhoneNumberDesc getStandardRate() { return standardRate_; }
    public PhoneMetadata setStandardRate(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasStandardRate = true;
      standardRate_ = value;
      return this;
    }

    // optional PhoneNumberDesc carrier_specific = 31;
    private boolean hasCarrierSpecific;
    private PhoneNumberDesc carrierSpecific_ = null;
    public boolean hasCarrierSpecific() { return hasCarrierSpecific; }
    public PhoneNumberDesc getCarrierSpecific() { return carrierSpecific_; }
    public PhoneMetadata setCarrierSpecific(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasCarrierSpecific = true;
      carrierSpecific_ = value;
      return this;
    }

    // optional PhoneNumberDesc sms_services = 33;
    private boolean hasSmsServices;
    private PhoneNumberDesc smsServices_ = null;
    public boolean hasSmsServices() { return hasSmsServices; }
    public PhoneNumberDesc getSmsServices() { return smsServices_; }
    public PhoneMetadata setSmsServices(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasSmsServices = true;
      smsServices_ = value;
      return this;
    }

    // optional PhoneNumberDesc noInternationalDialling = 24;
    private boolean hasNoInternationalDialling;
    private PhoneNumberDesc noInternationalDialling_ = null;
    public boolean hasNoInternationalDialling() { return hasNoInternationalDialling; }
    public PhoneNumberDesc getNoInternationalDialling() { return noInternationalDialling_; }
    public PhoneMetadata setNoInternationalDialling(PhoneNumberDesc value) {
      if (value == null) {
        throw new NullPointerException();
      }
      hasNoInternationalDialling = true;
      noInternationalDialling_ = value;
      return this;
    }

    // required string id = 9;
    private boolean hasId;
    private String id_ = "";
    public boolean hasId() { return hasId; }
    public String getId() { return id_; }
    public PhoneMetadata setId(String value) {
      hasId = true;
      id_ = value;
      return this;
    }

    // optional int32 country_code = 10;
    private boolean hasCountryCode;
    private int countryCode_ = 0;
    public boolean hasCountryCode() { return hasCountryCode; }
    public int getCountryCode() { return countryCode_; }
    public PhoneMetadata setCountryCode(int value) {
      hasCountryCode = true;
      countryCode_ = value;
      return this;
    }

    // optional string international_prefix = 11;
    private boolean hasInternationalPrefix;
    private String internationalPrefix_ = "";
    public boolean hasInternationalPrefix() { return hasInternationalPrefix; }
    public String getInternationalPrefix() { return internationalPrefix_; }
    public PhoneMetadata setInternationalPrefix(String value) {
      hasInternationalPrefix = true;
      internationalPrefix_ = value;
      return this;
    }

    // optional string preferred_international_prefix = 17;
    private boolean hasPreferredInternationalPrefix;
    private String preferredInternationalPrefix_ = "";
    public boolean hasPreferredInternationalPrefix() { return hasPreferredInternationalPrefix; }
    public String getPreferredInternationalPrefix() { return preferredInternationalPrefix_; }
    public PhoneMetadata setPreferredInternationalPrefix(String value) {
      hasPreferredInternationalPrefix = true;
      preferredInternationalPrefix_ = value;
      return this;
    }
    public PhoneMetadata clearPreferredInternationalPrefix() {
      hasPreferredInternationalPrefix = false;
      preferredInternationalPrefix_ = "";
      return this;
    }

    // optional string national_prefix = 12;
    private boolean hasNationalPrefix;
    private String nationalPrefix_ = "";
    public boolean hasNationalPrefix() { return hasNationalPrefix; }
    public String getNationalPrefix() { return nationalPrefix_; }
    public PhoneMetadata setNationalPrefix(String value) {
      hasNationalPrefix = true;
      nationalPrefix_ = value;
      return this;
    }
    public PhoneMetadata clearNationalPrefix() {
      hasNationalPrefix = false;
      nationalPrefix_ = "";
      return this;
    }

    // optional string preferred_extn_prefix = 13;
    private boolean hasPreferredExtnPrefix;
    private String preferredExtnPrefix_ = "";
    public boolean hasPreferredExtnPrefix() { return hasPreferredExtnPrefix; }
    public String getPreferredExtnPrefix() { return preferredExtnPrefix_; }
    public PhoneMetadata setPreferredExtnPrefix(String value) {
      hasPreferredExtnPrefix = true;
      preferredExtnPrefix_ = value;
      return this;
    }
    public PhoneMetadata clearPreferredExtnPrefix() {
      hasPreferredExtnPrefix = false;
      preferredExtnPrefix_ = "";
      return this;
    }

    // optional string national_prefix_for_parsing = 15;
    private boolean hasNationalPrefixForParsing;
    private String nationalPrefixForParsing_ = "";
    public boolean hasNationalPrefixForParsing() { return hasNationalPrefixForParsing; }
    public String getNationalPrefixForParsing() { return nationalPrefixForParsing_; }
    public PhoneMetadata setNationalPrefixForParsing(String value) {
      hasNationalPrefixForParsing = true;
      nationalPrefixForParsing_ = value;
      return this;
    }

    // optional string national_prefix_transform_rule = 16;
    private boolean hasNationalPrefixTransformRule;
    private String nationalPrefixTransformRule_ = "";
    public boolean hasNationalPrefixTransformRule() { return hasNationalPrefixTransformRule; }
    public String getNationalPrefixTransformRule() { return nationalPrefixTransformRule_; }
    public PhoneMetadata setNationalPrefixTransformRule(String value) {
      hasNationalPrefixTransformRule = true;
      nationalPrefixTransformRule_ = value;
      return this;
    }
    public PhoneMetadata clearNationalPrefixTransformRule() {
      hasNationalPrefixTransformRule = false;
      nationalPrefixTransformRule_ = "";
      return this;
    }

    // optional bool same_mobile_and_fixed_line_pattern = 18 [default = false];
    private boolean hasSameMobileAndFixedLinePattern;
    private boolean sameMobileAndFixedLinePattern_ = false;
    public boolean hasSameMobileAndFixedLinePattern() { return hasSameMobileAndFixedLinePattern; }
    public boolean getSameMobileAndFixedLinePattern() { return sameMobileAndFixedLinePattern_; }
    public PhoneMetadata setSameMobileAndFixedLinePattern(boolean value) {
      hasSameMobileAndFixedLinePattern = true;
      sameMobileAndFixedLinePattern_ = value;
      return this;
    }
    public PhoneMetadata clearSameMobileAndFixedLinePattern() {
      hasSameMobileAndFixedLinePattern = false;
      sameMobileAndFixedLinePattern_ = false;
      return this;
    }

    // repeated NumberFormat number_format = 19;
    private java.util.List<NumberFormat> numberFormat_ = new java.util.ArrayList<NumberFormat>();
    @Deprecated
    public java.util.List<NumberFormat> numberFormats() {
      return getNumberFormatList();
    }
    public java.util.List<NumberFormat> getNumberFormatList() {
      return numberFormat_;
    }
    @Deprecated
    public int numberFormatSize() { return getNumberFormatCount(); }
    public int getNumberFormatCount() { return numberFormat_.size(); }
    public NumberFormat getNumberFormat(int index) {
      return numberFormat_.get(index);
    }
    public PhoneMetadata addNumberFormat(NumberFormat value) {
      if (value == null) {
        throw new NullPointerException();
      }
      numberFormat_.add(value);
      return this;
    }

    // repeated NumberFormat intl_number_format = 20;
    private java.util.List<NumberFormat> intlNumberFormat_ =
        new java.util.ArrayList<NumberFormat>();
    @Deprecated
    public java.util.List<NumberFormat> intlNumberFormats() {
      return getIntlNumberFormatList();
    }
    public java.util.List<NumberFormat> getIntlNumberFormatList() {
      return intlNumberFormat_;
    }
    @Deprecated
    public int intlNumberFormatSize() { return getIntlNumberFormatCount(); }
    public int getIntlNumberFormatCount() { return intlNumberFormat_.size(); }
    public NumberFormat getIntlNumberFormat(int index) {
      return intlNumberFormat_.get(index);
    }

    public PhoneMetadata addIntlNumberFormat(NumberFormat value) {
      if (value == null) {
        throw new NullPointerException();
      }
      intlNumberFormat_.add(value);
      return this;
    }
    public PhoneMetadata clearIntlNumberFormat() {
      intlNumberFormat_.clear();
      return this;
    }

    // optional bool main_country_for_code = 22 [default = false];
    private boolean hasMainCountryForCode;
    private boolean mainCountryForCode_ = false;
    public boolean hasMainCountryForCode() { return hasMainCountryForCode; }
    public boolean isMainCountryForCode() { return mainCountryForCode_; }
    // Method that lets this class have the same interface as the one generated by Protocol Buffers
    // which is used by C++ build tools.
    public boolean getMainCountryForCode() { return mainCountryForCode_; }
    public PhoneMetadata setMainCountryForCode(boolean value) {
      hasMainCountryForCode = true;
      mainCountryForCode_ = value;
      return this;
    }
    public PhoneMetadata clearMainCountryForCode() {
      hasMainCountryForCode = false;
      mainCountryForCode_ = false;
      return this;
    }

    // optional string leading_digits = 23;
    private boolean hasLeadingDigits;
    private String leadingDigits_ = "";
    public boolean hasLeadingDigits() { return hasLeadingDigits; }
    public String getLeadingDigits() { return leadingDigits_; }
    public PhoneMetadata setLeadingDigits(String value) {
      hasLeadingDigits = true;
      leadingDigits_ = value;
      return this;
    }

    // optional bool leading_zero_possible = 26 [default = false];
    private boolean hasLeadingZeroPossible;
    private boolean leadingZeroPossible_ = false;
    public boolean hasLeadingZeroPossible() { return hasLeadingZeroPossible; }
    public boolean isLeadingZeroPossible() { return leadingZeroPossible_; }
    public PhoneMetadata setLeadingZeroPossible(boolean value) {
      hasLeadingZeroPossible = true;
      leadingZeroPossible_ = value;
      return this;
    }
    public PhoneMetadata clearLeadingZeroPossible() {
      hasLeadingZeroPossible = false;
      leadingZeroPossible_ = false;
      return this;
    }

    // optional bool mobile_number_portable_region = 32 [default = false];
    private boolean hasMobileNumberPortableRegion;
    private boolean mobileNumberPortableRegion_ = false;
    public boolean hasMobileNumberPortableRegion() { return hasMobileNumberPortableRegion; }
    @Deprecated
    public boolean isMobileNumberPortableRegion() { return getMobileNumberPortableRegion(); }
    public boolean getMobileNumberPortableRegion() { return mobileNumberPortableRegion_; }
    public PhoneMetadata setMobileNumberPortableRegion(boolean value) {
      hasMobileNumberPortableRegion = true;
      mobileNumberPortableRegion_ = value;
      return this;
    }
    public PhoneMetadata clearMobileNumberPortableRegion() {
      hasMobileNumberPortableRegion = false;
      mobileNumberPortableRegion_ = false;
      return this;
    }

    public void writeExternal(ObjectOutput objectOutput) throws IOException {
      objectOutput.writeBoolean(hasGeneralDesc);
      if (hasGeneralDesc) {
        generalDesc_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasFixedLine);
      if (hasFixedLine) {
        fixedLine_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasMobile);
      if (hasMobile) {
        mobile_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasTollFree);
      if (hasTollFree) {
        tollFree_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasPremiumRate);
      if (hasPremiumRate) {
        premiumRate_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasSharedCost);
      if (hasSharedCost) {
        sharedCost_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasPersonalNumber);
      if (hasPersonalNumber) {
        personalNumber_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasVoip);
      if (hasVoip) {
        voip_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasPager);
      if (hasPager) {
        pager_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasUan);
      if (hasUan) {
        uan_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasEmergency);
      if (hasEmergency) {
        emergency_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasVoicemail);
      if (hasVoicemail) {
        voicemail_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasShortCode);
      if (hasShortCode) {
        shortCode_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasStandardRate);
      if (hasStandardRate) {
        standardRate_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasCarrierSpecific);
      if (hasCarrierSpecific) {
        carrierSpecific_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasSmsServices);
      if (hasSmsServices) {
        smsServices_.writeExternal(objectOutput);
      }
      objectOutput.writeBoolean(hasNoInternationalDialling);
      if (hasNoInternationalDialling) {
        noInternationalDialling_.writeExternal(objectOutput);
      }

      objectOutput.writeUTF(id_);
      objectOutput.writeInt(countryCode_);
      objectOutput.writeUTF(internationalPrefix_);

      objectOutput.writeBoolean(hasPreferredInternationalPrefix);
      if (hasPreferredInternationalPrefix) {
        objectOutput.writeUTF(preferredInternationalPrefix_);
      }

      objectOutput.writeBoolean(hasNationalPrefix);
      if (hasNationalPrefix) {
        objectOutput.writeUTF(nationalPrefix_);
      }

      objectOutput.writeBoolean(hasPreferredExtnPrefix);
      if (hasPreferredExtnPrefix) {
        objectOutput.writeUTF(preferredExtnPrefix_);
      }

      objectOutput.writeBoolean(hasNationalPrefixForParsing);
      if (hasNationalPrefixForParsing) {
        objectOutput.writeUTF(nationalPrefixForParsing_);
      }

      objectOutput.writeBoolean(hasNationalPrefixTransformRule);
      if (hasNationalPrefixTransformRule) {
        objectOutput.writeUTF(nationalPrefixTransformRule_);
      }

      objectOutput.writeBoolean(sameMobileAndFixedLinePattern_);

      int numberFormatSize = numberFormatSize();
      objectOutput.writeInt(numberFormatSize);
      for (int i = 0; i < numberFormatSize; i++) {
        numberFormat_.get(i).writeExternal(objectOutput);
      }

      int intlNumberFormatSize = intlNumberFormatSize();
      objectOutput.writeInt(intlNumberFormatSize);
      for (int i = 0; i < intlNumberFormatSize; i++) {
        intlNumberFormat_.get(i).writeExternal(objectOutput);
      }

      objectOutput.writeBoolean(mainCountryForCode_);

      objectOutput.writeBoolean(hasLeadingDigits);
      if (hasLeadingDigits) {
        objectOutput.writeUTF(leadingDigits_);
      }

      objectOutput.writeBoolean(leadingZeroPossible_);

      objectOutput.writeBoolean(mobileNumberPortableRegion_);
    }

    public void readExternal(ObjectInput objectInput) throws IOException {
      boolean hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setGeneralDesc(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setFixedLine(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setMobile(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setTollFree(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setPremiumRate(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setSharedCost(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setPersonalNumber(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setVoip(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setPager(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setUan(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setEmergency(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setVoicemail(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setShortCode(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setStandardRate(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setCarrierSpecific(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setSmsServices(desc);
      }
      hasDesc = objectInput.readBoolean();
      if (hasDesc) {
        PhoneNumberDesc desc = new PhoneNumberDesc();
        desc.readExternal(objectInput);
        setNoInternationalDialling(desc);
      }

      setId(objectInput.readUTF());
      setCountryCode(objectInput.readInt());
      setInternationalPrefix(objectInput.readUTF());

      boolean hasString = objectInput.readBoolean();
      if (hasString) {
        setPreferredInternationalPrefix(objectInput.readUTF());
      }

      hasString = objectInput.readBoolean();
      if (hasString) {
        setNationalPrefix(objectInput.readUTF());
      }

      hasString = objectInput.readBoolean();
      if (hasString) {
        setPreferredExtnPrefix(objectInput.readUTF());
      }

      hasString = objectInput.readBoolean();
      if (hasString) {
        setNationalPrefixForParsing(objectInput.readUTF());
      }

      hasString = objectInput.readBoolean();
      if (hasString) {
        setNationalPrefixTransformRule(objectInput.readUTF());
      }

      setSameMobileAndFixedLinePattern(objectInput.readBoolean());

      int nationalFormatSize = objectInput.readInt();
      for (int i = 0; i < nationalFormatSize; i++) {
        NumberFormat numFormat = new NumberFormat();
        numFormat.readExternal(objectInput);
        numberFormat_.add(numFormat);
      }

      int intlNumberFormatSize = objectInput.readInt();
      for (int i = 0; i < intlNumberFormatSize; i++) {
        NumberFormat numFormat = new NumberFormat();
        numFormat.readExternal(objectInput);
        intlNumberFormat_.add(numFormat);
      }

      setMainCountryForCode(objectInput.readBoolean());

      hasString = objectInput.readBoolean();
      if (hasString) {
        setLeadingDigits(objectInput.readUTF());
      }

      setLeadingZeroPossible(objectInput.readBoolean());

      setMobileNumberPortableRegion(objectInput.readBoolean());
    }
  }

  public static class PhoneMetadataCollection implements Externalizable {
    private static final long serialVersionUID = 1;
    public PhoneMetadataCollection() {}

    /**
     * Provides a dummy builder.
     *
     * @see NumberFormat.Builder
     */
    public static final class Builder extends PhoneMetadataCollection {
      public PhoneMetadataCollection build() {
        return this;
      }
    }
    public static Builder newBuilder() {
      return new Builder();
    }

    // repeated PhoneMetadata metadata = 1;
    private java.util.List<PhoneMetadata> metadata_ = new java.util.ArrayList<PhoneMetadata>();

    public java.util.List<PhoneMetadata> getMetadataList() {
      return metadata_;
    }
    public int getMetadataCount() { return metadata_.size(); }

    public PhoneMetadataCollection addMetadata(PhoneMetadata value) {
      if (value == null) {
        throw new NullPointerException();
      }
      metadata_.add(value);
      return this;
    }

    public void writeExternal(ObjectOutput objectOutput) throws IOException {
      int size = getMetadataCount();
      objectOutput.writeInt(size);
      for (int i = 0; i < size; i++) {
        metadata_.get(i).writeExternal(objectOutput);
      }
    }

    public void readExternal(ObjectInput objectInput) throws IOException {
      int size = objectInput.readInt();
      for (int i = 0; i < size; i++) {
        PhoneMetadata metadata = new PhoneMetadata();
        metadata.readExternal(objectInput);
        metadata_.add(metadata);
      }
    }

    public PhoneMetadataCollection clear() {
      metadata_.clear();
      return this;
    }
  }
}
