/* GENERATED SOURCE. DO NOT MODIFY. */
/*
 * 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.android.i18n.phonenumbers;

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

/**
 * @hide This class is not part of the Android public SDK API
 */
public final class Phonemetadata {
  private Phonemetadata() {}
  /**
   * @hide This class is not part of the Android public SDK API
   */
  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.
     * @hide This class is not part of the Android public SDK API
     */
    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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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_;
    }
    @dalvik.annotation.compat.UnsupportedAppUsage
    public int leadingDigitsPatternSize() { return leadingDigitsPattern_.size(); }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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());
    }
  }

  /**
   * @hide This class is not part of the Android public SDK API
   */
  public static class PhoneNumberDesc implements Externalizable {
    private static final long serialVersionUID = 1;
    public PhoneNumberDesc() {}

    /**
     * Provides a dummy builder.
     *
     * @see NumberFormat.Builder
     * @hide This class is not part of the Android public SDK API
     */
    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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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());
      }
    }
  }

  /**
   * @hide This class is not part of the Android public SDK API
   */
  public static class PhoneMetadata implements Externalizable {
    private static final long serialVersionUID = 1;
    public PhoneMetadata() {}

    /**
     * Provides a dummy builder.
     *
     * @see NumberFormat.Builder
     * @hide This class is not part of the Android public SDK API
     */
    public static final class Builder extends PhoneMetadata {
      public PhoneMetadata build() {
        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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    public PhoneNumberDesc getGeneralDesc() { 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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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_ = "";
    @dalvik.annotation.compat.UnsupportedAppUsage
    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_ = "";
    @dalvik.annotation.compat.UnsupportedAppUsage
    public boolean hasPreferredExtnPrefix() { return hasPreferredExtnPrefix; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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; }
    @dalvik.annotation.compat.UnsupportedAppUsage
    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>();
    @dalvik.annotation.compat.UnsupportedAppUsage
    public java.util.List<NumberFormat> numberFormats() {
      return numberFormat_;
    }
    public int numberFormatSize() { 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>();
    @dalvik.annotation.compat.UnsupportedAppUsage
    public java.util.List<NumberFormat> intlNumberFormats() {
      return intlNumberFormat_;
    }
    public int intlNumberFormatSize() { 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; }
    public boolean isMobileNumberPortableRegion() { 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());
    }
  }

  /**
   * @hide This class is not part of the Android public SDK API
   */
  public static class PhoneMetadataCollection implements Externalizable {
    private static final long serialVersionUID = 1;
    @dalvik.annotation.compat.UnsupportedAppUsage
    public PhoneMetadataCollection() {}

    /**
     * Provides a dummy builder.
     *
     * @see NumberFormat.Builder
     * @hide This class is not part of the Android public SDK API
     */
    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>();

    @dalvik.annotation.compat.UnsupportedAppUsage
    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;
    }
  }
}
