// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: phonemetadata.proto

package com.google.i18n.phonenumbers;

public final class Phonemetadata {
  private Phonemetadata() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }
  public static final class NumberFormat extends
      com.google.protobuf.GeneratedMessageLite {
    // Use NumberFormat.newBuilder() to construct.
    private NumberFormat() {
      initFields();
    }
    private NumberFormat(boolean noInit) {}
    
    private static final NumberFormat defaultInstance;
    public static NumberFormat getDefaultInstance() {
      return defaultInstance;
    }
    
    public NumberFormat getDefaultInstanceForType() {
      return defaultInstance;
    }
    
    // required string pattern = 1;
    public static final int PATTERN_FIELD_NUMBER = 1;
    private boolean hasPattern;
    private java.lang.String pattern_ = "";
    public boolean hasPattern() { return hasPattern; }
    public java.lang.String getPattern() { return pattern_; }
    
    // required string format = 2;
    public static final int FORMAT_FIELD_NUMBER = 2;
    private boolean hasFormat;
    private java.lang.String format_ = "";
    public boolean hasFormat() { return hasFormat; }
    public java.lang.String getFormat() { return format_; }
    
    // optional string leading_digits = 3;
    public static final int LEADING_DIGITS_FIELD_NUMBER = 3;
    private boolean hasLeadingDigits;
    private java.lang.String leadingDigits_ = "";
    public boolean hasLeadingDigits() { return hasLeadingDigits; }
    public java.lang.String getLeadingDigits() { return leadingDigits_; }
    
    // optional string national_prefix_formatting_rule = 4;
    public static final int NATIONAL_PREFIX_FORMATTING_RULE_FIELD_NUMBER = 4;
    private boolean hasNationalPrefixFormattingRule;
    private java.lang.String nationalPrefixFormattingRule_ = "";
    public boolean hasNationalPrefixFormattingRule() { return hasNationalPrefixFormattingRule; }
    public java.lang.String getNationalPrefixFormattingRule() { return nationalPrefixFormattingRule_; }
    
    private void initFields() {
    }
    public final boolean isInitialized() {
      if (!hasPattern) return false;
      if (!hasFormat) return false;
      return true;
    }
    
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (hasPattern()) {
        output.writeString(1, getPattern());
      }
      if (hasFormat()) {
        output.writeString(2, getFormat());
      }
      if (hasLeadingDigits()) {
        output.writeString(3, getLeadingDigits());
      }
      if (hasNationalPrefixFormattingRule()) {
        output.writeString(4, getNationalPrefixFormattingRule());
      }
    }
    
    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;
    
      size = 0;
      if (hasPattern()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(1, getPattern());
      }
      if (hasFormat()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(2, getFormat());
      }
      if (hasLeadingDigits()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(3, getLeadingDigits());
      }
      if (hasNationalPrefixFormattingRule()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(4, getNationalPrefixFormattingRule());
      }
      memoizedSerializedSize = size;
      return size;
    }
    
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.NumberFormat parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    
    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(com.google.i18n.phonenumbers.Phonemetadata.NumberFormat prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }
    
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageLite.Builder<
          com.google.i18n.phonenumbers.Phonemetadata.NumberFormat, Builder> {
      private com.google.i18n.phonenumbers.Phonemetadata.NumberFormat result;
      
      // Construct using com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.newBuilder()
      private Builder() {}
      
      private static Builder create() {
        Builder builder = new Builder();
        builder.result = new com.google.i18n.phonenumbers.Phonemetadata.NumberFormat();
        return builder;
      }
      
      protected com.google.i18n.phonenumbers.Phonemetadata.NumberFormat internalGetResult() {
        return result;
      }
      
      public Builder clear() {
        if (result == null) {
          throw new IllegalStateException(
            "Cannot call clear() after build().");
        }
        result = new com.google.i18n.phonenumbers.Phonemetadata.NumberFormat();
        return this;
      }
      
      public Builder clone() {
        return create().mergeFrom(result);
      }
      
      public com.google.i18n.phonenumbers.Phonemetadata.NumberFormat getDefaultInstanceForType() {
        return com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.getDefaultInstance();
      }
      
      public boolean isInitialized() {
        return result.isInitialized();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.NumberFormat build() {
        if (result != null && !isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return buildPartial();
      }
      
      private com.google.i18n.phonenumbers.Phonemetadata.NumberFormat buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        if (!isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return buildPartial();
      }
      
      public com.google.i18n.phonenumbers.Phonemetadata.NumberFormat buildPartial() {
        if (result == null) {
          throw new IllegalStateException(
            "build() has already been called on this Builder.");
        }
        com.google.i18n.phonenumbers.Phonemetadata.NumberFormat returnMe = result;
        result = null;
        return returnMe;
      }
      
      public Builder mergeFrom(com.google.i18n.phonenumbers.Phonemetadata.NumberFormat other) {
        if (other == com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.getDefaultInstance()) return this;
        if (other.hasPattern()) {
          setPattern(other.getPattern());
        }
        if (other.hasFormat()) {
          setFormat(other.getFormat());
        }
        if (other.hasLeadingDigits()) {
          setLeadingDigits(other.getLeadingDigits());
        }
        if (other.hasNationalPrefixFormattingRule()) {
          setNationalPrefixFormattingRule(other.getNationalPrefixFormattingRule());
        }
        return this;
      }
      
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              return this;
            default: {
              if (!parseUnknownField(input, extensionRegistry, tag)) {
                return this;
              }
              break;
            }
            case 10: {
              setPattern(input.readString());
              break;
            }
            case 18: {
              setFormat(input.readString());
              break;
            }
            case 26: {
              setLeadingDigits(input.readString());
              break;
            }
            case 34: {
              setNationalPrefixFormattingRule(input.readString());
              break;
            }
          }
        }
      }
      
      
      // required string pattern = 1;
      public boolean hasPattern() {
        return result.hasPattern();
      }
      public java.lang.String getPattern() {
        return result.getPattern();
      }
      public Builder setPattern(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasPattern = true;
        result.pattern_ = value;
        return this;
      }
      public Builder clearPattern() {
        result.hasPattern = false;
        result.pattern_ = getDefaultInstance().getPattern();
        return this;
      }
      
      // required string format = 2;
      public boolean hasFormat() {
        return result.hasFormat();
      }
      public java.lang.String getFormat() {
        return result.getFormat();
      }
      public Builder setFormat(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasFormat = true;
        result.format_ = value;
        return this;
      }
      public Builder clearFormat() {
        result.hasFormat = false;
        result.format_ = getDefaultInstance().getFormat();
        return this;
      }
      
      // optional string leading_digits = 3;
      public boolean hasLeadingDigits() {
        return result.hasLeadingDigits();
      }
      public java.lang.String getLeadingDigits() {
        return result.getLeadingDigits();
      }
      public Builder setLeadingDigits(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasLeadingDigits = true;
        result.leadingDigits_ = value;
        return this;
      }
      public Builder clearLeadingDigits() {
        result.hasLeadingDigits = false;
        result.leadingDigits_ = getDefaultInstance().getLeadingDigits();
        return this;
      }
      
      // optional string national_prefix_formatting_rule = 4;
      public boolean hasNationalPrefixFormattingRule() {
        return result.hasNationalPrefixFormattingRule();
      }
      public java.lang.String getNationalPrefixFormattingRule() {
        return result.getNationalPrefixFormattingRule();
      }
      public Builder setNationalPrefixFormattingRule(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasNationalPrefixFormattingRule = true;
        result.nationalPrefixFormattingRule_ = value;
        return this;
      }
      public Builder clearNationalPrefixFormattingRule() {
        result.hasNationalPrefixFormattingRule = false;
        result.nationalPrefixFormattingRule_ = getDefaultInstance().getNationalPrefixFormattingRule();
        return this;
      }
      
      // @@protoc_insertion_point(builder_scope:i18n.phonenumbers.NumberFormat)
    }
    
    static {
      defaultInstance = new NumberFormat(true);
      com.google.i18n.phonenumbers.Phonemetadata.internalForceInit();
      defaultInstance.initFields();
    }
    
    // @@protoc_insertion_point(class_scope:i18n.phonenumbers.NumberFormat)
  }
  
  public static final class PhoneNumberDesc extends
      com.google.protobuf.GeneratedMessageLite {
    // Use PhoneNumberDesc.newBuilder() to construct.
    private PhoneNumberDesc() {
      initFields();
    }
    private PhoneNumberDesc(boolean noInit) {}
    
    private static final PhoneNumberDesc defaultInstance;
    public static PhoneNumberDesc getDefaultInstance() {
      return defaultInstance;
    }
    
    public PhoneNumberDesc getDefaultInstanceForType() {
      return defaultInstance;
    }
    
    // optional string national_number_pattern = 2;
    public static final int NATIONAL_NUMBER_PATTERN_FIELD_NUMBER = 2;
    private boolean hasNationalNumberPattern;
    private java.lang.String nationalNumberPattern_ = "";
    public boolean hasNationalNumberPattern() { return hasNationalNumberPattern; }
    public java.lang.String getNationalNumberPattern() { return nationalNumberPattern_; }
    
    // optional string possible_number_pattern = 3;
    public static final int POSSIBLE_NUMBER_PATTERN_FIELD_NUMBER = 3;
    private boolean hasPossibleNumberPattern;
    private java.lang.String possibleNumberPattern_ = "";
    public boolean hasPossibleNumberPattern() { return hasPossibleNumberPattern; }
    public java.lang.String getPossibleNumberPattern() { return possibleNumberPattern_; }
    
    // optional string example_number = 6;
    public static final int EXAMPLE_NUMBER_FIELD_NUMBER = 6;
    private boolean hasExampleNumber;
    private java.lang.String exampleNumber_ = "";
    public boolean hasExampleNumber() { return hasExampleNumber; }
    public java.lang.String getExampleNumber() { return exampleNumber_; }
    
    private void initFields() {
    }
    public final boolean isInitialized() {
      return true;
    }
    
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (hasNationalNumberPattern()) {
        output.writeString(2, getNationalNumberPattern());
      }
      if (hasPossibleNumberPattern()) {
        output.writeString(3, getPossibleNumberPattern());
      }
      if (hasExampleNumber()) {
        output.writeString(6, getExampleNumber());
      }
    }
    
    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;
    
      size = 0;
      if (hasNationalNumberPattern()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(2, getNationalNumberPattern());
      }
      if (hasPossibleNumberPattern()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(3, getPossibleNumberPattern());
      }
      if (hasExampleNumber()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(6, getExampleNumber());
      }
      memoizedSerializedSize = size;
      return size;
    }
    
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    
    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }
    
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageLite.Builder<
          com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc, Builder> {
      private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc result;
      
      // Construct using com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder()
      private Builder() {}
      
      private static Builder create() {
        Builder builder = new Builder();
        builder.result = new com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc();
        return builder;
      }
      
      protected com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc internalGetResult() {
        return result;
      }
      
      public Builder clear() {
        if (result == null) {
          throw new IllegalStateException(
            "Cannot call clear() after build().");
        }
        result = new com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc();
        return this;
      }
      
      public Builder clone() {
        return create().mergeFrom(result);
      }
      
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getDefaultInstanceForType() {
        return com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
      }
      
      public boolean isInitialized() {
        return result.isInitialized();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc build() {
        if (result != null && !isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return buildPartial();
      }
      
      private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        if (!isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return buildPartial();
      }
      
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc buildPartial() {
        if (result == null) {
          throw new IllegalStateException(
            "build() has already been called on this Builder.");
        }
        com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc returnMe = result;
        result = null;
        return returnMe;
      }
      
      public Builder mergeFrom(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc other) {
        if (other == com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) return this;
        if (other.hasNationalNumberPattern()) {
          setNationalNumberPattern(other.getNationalNumberPattern());
        }
        if (other.hasPossibleNumberPattern()) {
          setPossibleNumberPattern(other.getPossibleNumberPattern());
        }
        if (other.hasExampleNumber()) {
          setExampleNumber(other.getExampleNumber());
        }
        return this;
      }
      
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              return this;
            default: {
              if (!parseUnknownField(input, extensionRegistry, tag)) {
                return this;
              }
              break;
            }
            case 18: {
              setNationalNumberPattern(input.readString());
              break;
            }
            case 26: {
              setPossibleNumberPattern(input.readString());
              break;
            }
            case 50: {
              setExampleNumber(input.readString());
              break;
            }
          }
        }
      }
      
      
      // optional string national_number_pattern = 2;
      public boolean hasNationalNumberPattern() {
        return result.hasNationalNumberPattern();
      }
      public java.lang.String getNationalNumberPattern() {
        return result.getNationalNumberPattern();
      }
      public Builder setNationalNumberPattern(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasNationalNumberPattern = true;
        result.nationalNumberPattern_ = value;
        return this;
      }
      public Builder clearNationalNumberPattern() {
        result.hasNationalNumberPattern = false;
        result.nationalNumberPattern_ = getDefaultInstance().getNationalNumberPattern();
        return this;
      }
      
      // optional string possible_number_pattern = 3;
      public boolean hasPossibleNumberPattern() {
        return result.hasPossibleNumberPattern();
      }
      public java.lang.String getPossibleNumberPattern() {
        return result.getPossibleNumberPattern();
      }
      public Builder setPossibleNumberPattern(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasPossibleNumberPattern = true;
        result.possibleNumberPattern_ = value;
        return this;
      }
      public Builder clearPossibleNumberPattern() {
        result.hasPossibleNumberPattern = false;
        result.possibleNumberPattern_ = getDefaultInstance().getPossibleNumberPattern();
        return this;
      }
      
      // optional string example_number = 6;
      public boolean hasExampleNumber() {
        return result.hasExampleNumber();
      }
      public java.lang.String getExampleNumber() {
        return result.getExampleNumber();
      }
      public Builder setExampleNumber(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasExampleNumber = true;
        result.exampleNumber_ = value;
        return this;
      }
      public Builder clearExampleNumber() {
        result.hasExampleNumber = false;
        result.exampleNumber_ = getDefaultInstance().getExampleNumber();
        return this;
      }
      
      // @@protoc_insertion_point(builder_scope:i18n.phonenumbers.PhoneNumberDesc)
    }
    
    static {
      defaultInstance = new PhoneNumberDesc(true);
      com.google.i18n.phonenumbers.Phonemetadata.internalForceInit();
      defaultInstance.initFields();
    }
    
    // @@protoc_insertion_point(class_scope:i18n.phonenumbers.PhoneNumberDesc)
  }
  
  public static final class PhoneMetadata extends
      com.google.protobuf.GeneratedMessageLite {
    // Use PhoneMetadata.newBuilder() to construct.
    private PhoneMetadata() {
      initFields();
    }
    private PhoneMetadata(boolean noInit) {}
    
    private static final PhoneMetadata defaultInstance;
    public static PhoneMetadata getDefaultInstance() {
      return defaultInstance;
    }
    
    public PhoneMetadata getDefaultInstanceForType() {
      return defaultInstance;
    }
    
    // required .i18n.phonenumbers.PhoneNumberDesc general_desc = 1;
    public static final int GENERAL_DESC_FIELD_NUMBER = 1;
    private boolean hasGeneralDesc;
    private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc generalDesc_;
    public boolean hasGeneralDesc() { return hasGeneralDesc; }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getGeneralDesc() { return generalDesc_; }
    
    // required .i18n.phonenumbers.PhoneNumberDesc fixed_line = 2;
    public static final int FIXED_LINE_FIELD_NUMBER = 2;
    private boolean hasFixedLine;
    private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc fixedLine_;
    public boolean hasFixedLine() { return hasFixedLine; }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getFixedLine() { return fixedLine_; }
    
    // required .i18n.phonenumbers.PhoneNumberDesc mobile = 3;
    public static final int MOBILE_FIELD_NUMBER = 3;
    private boolean hasMobile;
    private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc mobile_;
    public boolean hasMobile() { return hasMobile; }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getMobile() { return mobile_; }
    
    // required .i18n.phonenumbers.PhoneNumberDesc toll_free = 4;
    public static final int TOLL_FREE_FIELD_NUMBER = 4;
    private boolean hasTollFree;
    private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc tollFree_;
    public boolean hasTollFree() { return hasTollFree; }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getTollFree() { return tollFree_; }
    
    // required .i18n.phonenumbers.PhoneNumberDesc premium_rate = 5;
    public static final int PREMIUM_RATE_FIELD_NUMBER = 5;
    private boolean hasPremiumRate;
    private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc premiumRate_;
    public boolean hasPremiumRate() { return hasPremiumRate; }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getPremiumRate() { return premiumRate_; }
    
    // required .i18n.phonenumbers.PhoneNumberDesc shared_cost = 6;
    public static final int SHARED_COST_FIELD_NUMBER = 6;
    private boolean hasSharedCost;
    private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc sharedCost_;
    public boolean hasSharedCost() { return hasSharedCost; }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getSharedCost() { return sharedCost_; }
    
    // required .i18n.phonenumbers.PhoneNumberDesc personal_number = 7;
    public static final int PERSONAL_NUMBER_FIELD_NUMBER = 7;
    private boolean hasPersonalNumber;
    private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc personalNumber_;
    public boolean hasPersonalNumber() { return hasPersonalNumber; }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getPersonalNumber() { return personalNumber_; }
    
    // required .i18n.phonenumbers.PhoneNumberDesc voip = 8;
    public static final int VOIP_FIELD_NUMBER = 8;
    private boolean hasVoip;
    private com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc voip_;
    public boolean hasVoip() { return hasVoip; }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getVoip() { return voip_; }
    
    // required string id = 9;
    public static final int ID_FIELD_NUMBER = 9;
    private boolean hasId;
    private java.lang.String id_ = "";
    public boolean hasId() { return hasId; }
    public java.lang.String getId() { return id_; }
    
    // required int32 country_code = 10;
    public static final int COUNTRY_CODE_FIELD_NUMBER = 10;
    private boolean hasCountryCode;
    private int countryCode_ = 0;
    public boolean hasCountryCode() { return hasCountryCode; }
    public int getCountryCode() { return countryCode_; }
    
    // required string international_prefix = 11;
    public static final int INTERNATIONAL_PREFIX_FIELD_NUMBER = 11;
    private boolean hasInternationalPrefix;
    private java.lang.String internationalPrefix_ = "";
    public boolean hasInternationalPrefix() { return hasInternationalPrefix; }
    public java.lang.String getInternationalPrefix() { return internationalPrefix_; }
    
    // optional string preferred_international_prefix = 17;
    public static final int PREFERRED_INTERNATIONAL_PREFIX_FIELD_NUMBER = 17;
    private boolean hasPreferredInternationalPrefix;
    private java.lang.String preferredInternationalPrefix_ = "";
    public boolean hasPreferredInternationalPrefix() { return hasPreferredInternationalPrefix; }
    public java.lang.String getPreferredInternationalPrefix() { return preferredInternationalPrefix_; }
    
    // optional string national_prefix = 12;
    public static final int NATIONAL_PREFIX_FIELD_NUMBER = 12;
    private boolean hasNationalPrefix;
    private java.lang.String nationalPrefix_ = "";
    public boolean hasNationalPrefix() { return hasNationalPrefix; }
    public java.lang.String getNationalPrefix() { return nationalPrefix_; }
    
    // optional string preferred_extn_prefix = 13;
    public static final int PREFERRED_EXTN_PREFIX_FIELD_NUMBER = 13;
    private boolean hasPreferredExtnPrefix;
    private java.lang.String preferredExtnPrefix_ = "";
    public boolean hasPreferredExtnPrefix() { return hasPreferredExtnPrefix; }
    public java.lang.String getPreferredExtnPrefix() { return preferredExtnPrefix_; }
    
    // optional string national_prefix_for_parsing = 15;
    public static final int NATIONAL_PREFIX_FOR_PARSING_FIELD_NUMBER = 15;
    private boolean hasNationalPrefixForParsing;
    private java.lang.String nationalPrefixForParsing_ = "";
    public boolean hasNationalPrefixForParsing() { return hasNationalPrefixForParsing; }
    public java.lang.String getNationalPrefixForParsing() { return nationalPrefixForParsing_; }
    
    // optional string national_prefix_transform_rule = 16;
    public static final int NATIONAL_PREFIX_TRANSFORM_RULE_FIELD_NUMBER = 16;
    private boolean hasNationalPrefixTransformRule;
    private java.lang.String nationalPrefixTransformRule_ = "";
    public boolean hasNationalPrefixTransformRule() { return hasNationalPrefixTransformRule; }
    public java.lang.String getNationalPrefixTransformRule() { return nationalPrefixTransformRule_; }
    
    // optional bool same_mobile_and_fixed_line_pattern = 18 [default = false];
    public static final int SAME_MOBILE_AND_FIXED_LINE_PATTERN_FIELD_NUMBER = 18;
    private boolean hasSameMobileAndFixedLinePattern;
    private boolean sameMobileAndFixedLinePattern_ = false;
    public boolean hasSameMobileAndFixedLinePattern() { return hasSameMobileAndFixedLinePattern; }
    public boolean getSameMobileAndFixedLinePattern() { return sameMobileAndFixedLinePattern_; }
    
    // repeated .i18n.phonenumbers.NumberFormat number_format = 19;
    public static final int NUMBER_FORMAT_FIELD_NUMBER = 19;
    private java.util.List<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat> numberFormat_ =
      java.util.Collections.emptyList();
    public java.util.List<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat> getNumberFormatList() {
      return numberFormat_;
    }
    public int getNumberFormatCount() { return numberFormat_.size(); }
    public com.google.i18n.phonenumbers.Phonemetadata.NumberFormat getNumberFormat(int index) {
      return numberFormat_.get(index);
    }
    
    // repeated .i18n.phonenumbers.NumberFormat intl_number_format = 20;
    public static final int INTL_NUMBER_FORMAT_FIELD_NUMBER = 20;
    private java.util.List<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat> intlNumberFormat_ =
      java.util.Collections.emptyList();
    public java.util.List<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat> getIntlNumberFormatList() {
      return intlNumberFormat_;
    }
    public int getIntlNumberFormatCount() { return intlNumberFormat_.size(); }
    public com.google.i18n.phonenumbers.Phonemetadata.NumberFormat getIntlNumberFormat(int index) {
      return intlNumberFormat_.get(index);
    }
    
    // optional string national_prefix_formatting_rule = 21;
    public static final int NATIONAL_PREFIX_FORMATTING_RULE_FIELD_NUMBER = 21;
    private boolean hasNationalPrefixFormattingRule;
    private java.lang.String nationalPrefixFormattingRule_ = "";
    public boolean hasNationalPrefixFormattingRule() { return hasNationalPrefixFormattingRule; }
    public java.lang.String getNationalPrefixFormattingRule() { return nationalPrefixFormattingRule_; }
    
    private void initFields() {
      generalDesc_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
      fixedLine_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
      mobile_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
      tollFree_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
      premiumRate_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
      sharedCost_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
      personalNumber_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
      voip_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
    }
    public final boolean isInitialized() {
      if (!hasGeneralDesc) return false;
      if (!hasFixedLine) return false;
      if (!hasMobile) return false;
      if (!hasTollFree) return false;
      if (!hasPremiumRate) return false;
      if (!hasSharedCost) return false;
      if (!hasPersonalNumber) return false;
      if (!hasVoip) return false;
      if (!hasId) return false;
      if (!hasCountryCode) return false;
      if (!hasInternationalPrefix) return false;
      for (com.google.i18n.phonenumbers.Phonemetadata.NumberFormat element : getNumberFormatList()) {
        if (!element.isInitialized()) return false;
      }
      for (com.google.i18n.phonenumbers.Phonemetadata.NumberFormat element : getIntlNumberFormatList()) {
        if (!element.isInitialized()) return false;
      }
      return true;
    }
    
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (hasGeneralDesc()) {
        output.writeMessage(1, getGeneralDesc());
      }
      if (hasFixedLine()) {
        output.writeMessage(2, getFixedLine());
      }
      if (hasMobile()) {
        output.writeMessage(3, getMobile());
      }
      if (hasTollFree()) {
        output.writeMessage(4, getTollFree());
      }
      if (hasPremiumRate()) {
        output.writeMessage(5, getPremiumRate());
      }
      if (hasSharedCost()) {
        output.writeMessage(6, getSharedCost());
      }
      if (hasPersonalNumber()) {
        output.writeMessage(7, getPersonalNumber());
      }
      if (hasVoip()) {
        output.writeMessage(8, getVoip());
      }
      if (hasId()) {
        output.writeString(9, getId());
      }
      if (hasCountryCode()) {
        output.writeInt32(10, getCountryCode());
      }
      if (hasInternationalPrefix()) {
        output.writeString(11, getInternationalPrefix());
      }
      if (hasNationalPrefix()) {
        output.writeString(12, getNationalPrefix());
      }
      if (hasPreferredExtnPrefix()) {
        output.writeString(13, getPreferredExtnPrefix());
      }
      if (hasNationalPrefixForParsing()) {
        output.writeString(15, getNationalPrefixForParsing());
      }
      if (hasNationalPrefixTransformRule()) {
        output.writeString(16, getNationalPrefixTransformRule());
      }
      if (hasPreferredInternationalPrefix()) {
        output.writeString(17, getPreferredInternationalPrefix());
      }
      if (hasSameMobileAndFixedLinePattern()) {
        output.writeBool(18, getSameMobileAndFixedLinePattern());
      }
      for (com.google.i18n.phonenumbers.Phonemetadata.NumberFormat element : getNumberFormatList()) {
        output.writeMessage(19, element);
      }
      for (com.google.i18n.phonenumbers.Phonemetadata.NumberFormat element : getIntlNumberFormatList()) {
        output.writeMessage(20, element);
      }
      if (hasNationalPrefixFormattingRule()) {
        output.writeString(21, getNationalPrefixFormattingRule());
      }
    }
    
    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;
    
      size = 0;
      if (hasGeneralDesc()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getGeneralDesc());
      }
      if (hasFixedLine()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getFixedLine());
      }
      if (hasMobile()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getMobile());
      }
      if (hasTollFree()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getTollFree());
      }
      if (hasPremiumRate()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, getPremiumRate());
      }
      if (hasSharedCost()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(6, getSharedCost());
      }
      if (hasPersonalNumber()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(7, getPersonalNumber());
      }
      if (hasVoip()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, getVoip());
      }
      if (hasId()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(9, getId());
      }
      if (hasCountryCode()) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(10, getCountryCode());
      }
      if (hasInternationalPrefix()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(11, getInternationalPrefix());
      }
      if (hasNationalPrefix()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(12, getNationalPrefix());
      }
      if (hasPreferredExtnPrefix()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(13, getPreferredExtnPrefix());
      }
      if (hasNationalPrefixForParsing()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(15, getNationalPrefixForParsing());
      }
      if (hasNationalPrefixTransformRule()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(16, getNationalPrefixTransformRule());
      }
      if (hasPreferredInternationalPrefix()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(17, getPreferredInternationalPrefix());
      }
      if (hasSameMobileAndFixedLinePattern()) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(18, getSameMobileAndFixedLinePattern());
      }
      for (com.google.i18n.phonenumbers.Phonemetadata.NumberFormat element : getNumberFormatList()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(19, element);
      }
      for (com.google.i18n.phonenumbers.Phonemetadata.NumberFormat element : getIntlNumberFormatList()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(20, element);
      }
      if (hasNationalPrefixFormattingRule()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(21, getNationalPrefixFormattingRule());
      }
      memoizedSerializedSize = size;
      return size;
    }
    
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    
    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }
    
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageLite.Builder<
          com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata, Builder> {
      private com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata result;
      
      // Construct using com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata.newBuilder()
      private Builder() {}
      
      private static Builder create() {
        Builder builder = new Builder();
        builder.result = new com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata();
        return builder;
      }
      
      protected com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata internalGetResult() {
        return result;
      }
      
      public Builder clear() {
        if (result == null) {
          throw new IllegalStateException(
            "Cannot call clear() after build().");
        }
        result = new com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata();
        return this;
      }
      
      public Builder clone() {
        return create().mergeFrom(result);
      }
      
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata getDefaultInstanceForType() {
        return com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata.getDefaultInstance();
      }
      
      public boolean isInitialized() {
        return result.isInitialized();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata build() {
        if (result != null && !isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return buildPartial();
      }
      
      private com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        if (!isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return buildPartial();
      }
      
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata buildPartial() {
        if (result == null) {
          throw new IllegalStateException(
            "build() has already been called on this Builder.");
        }
        if (result.numberFormat_ != java.util.Collections.EMPTY_LIST) {
          result.numberFormat_ =
            java.util.Collections.unmodifiableList(result.numberFormat_);
        }
        if (result.intlNumberFormat_ != java.util.Collections.EMPTY_LIST) {
          result.intlNumberFormat_ =
            java.util.Collections.unmodifiableList(result.intlNumberFormat_);
        }
        com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata returnMe = result;
        result = null;
        return returnMe;
      }
      
      public Builder mergeFrom(com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata other) {
        if (other == com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata.getDefaultInstance()) return this;
        if (other.hasGeneralDesc()) {
          mergeGeneralDesc(other.getGeneralDesc());
        }
        if (other.hasFixedLine()) {
          mergeFixedLine(other.getFixedLine());
        }
        if (other.hasMobile()) {
          mergeMobile(other.getMobile());
        }
        if (other.hasTollFree()) {
          mergeTollFree(other.getTollFree());
        }
        if (other.hasPremiumRate()) {
          mergePremiumRate(other.getPremiumRate());
        }
        if (other.hasSharedCost()) {
          mergeSharedCost(other.getSharedCost());
        }
        if (other.hasPersonalNumber()) {
          mergePersonalNumber(other.getPersonalNumber());
        }
        if (other.hasVoip()) {
          mergeVoip(other.getVoip());
        }
        if (other.hasId()) {
          setId(other.getId());
        }
        if (other.hasCountryCode()) {
          setCountryCode(other.getCountryCode());
        }
        if (other.hasInternationalPrefix()) {
          setInternationalPrefix(other.getInternationalPrefix());
        }
        if (other.hasPreferredInternationalPrefix()) {
          setPreferredInternationalPrefix(other.getPreferredInternationalPrefix());
        }
        if (other.hasNationalPrefix()) {
          setNationalPrefix(other.getNationalPrefix());
        }
        if (other.hasPreferredExtnPrefix()) {
          setPreferredExtnPrefix(other.getPreferredExtnPrefix());
        }
        if (other.hasNationalPrefixForParsing()) {
          setNationalPrefixForParsing(other.getNationalPrefixForParsing());
        }
        if (other.hasNationalPrefixTransformRule()) {
          setNationalPrefixTransformRule(other.getNationalPrefixTransformRule());
        }
        if (other.hasSameMobileAndFixedLinePattern()) {
          setSameMobileAndFixedLinePattern(other.getSameMobileAndFixedLinePattern());
        }
        if (!other.numberFormat_.isEmpty()) {
          if (result.numberFormat_.isEmpty()) {
            result.numberFormat_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat>();
          }
          result.numberFormat_.addAll(other.numberFormat_);
        }
        if (!other.intlNumberFormat_.isEmpty()) {
          if (result.intlNumberFormat_.isEmpty()) {
            result.intlNumberFormat_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat>();
          }
          result.intlNumberFormat_.addAll(other.intlNumberFormat_);
        }
        if (other.hasNationalPrefixFormattingRule()) {
          setNationalPrefixFormattingRule(other.getNationalPrefixFormattingRule());
        }
        return this;
      }
      
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              return this;
            default: {
              if (!parseUnknownField(input, extensionRegistry, tag)) {
                return this;
              }
              break;
            }
            case 10: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder();
              if (hasGeneralDesc()) {
                subBuilder.mergeFrom(getGeneralDesc());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setGeneralDesc(subBuilder.buildPartial());
              break;
            }
            case 18: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder();
              if (hasFixedLine()) {
                subBuilder.mergeFrom(getFixedLine());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setFixedLine(subBuilder.buildPartial());
              break;
            }
            case 26: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder();
              if (hasMobile()) {
                subBuilder.mergeFrom(getMobile());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setMobile(subBuilder.buildPartial());
              break;
            }
            case 34: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder();
              if (hasTollFree()) {
                subBuilder.mergeFrom(getTollFree());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setTollFree(subBuilder.buildPartial());
              break;
            }
            case 42: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder();
              if (hasPremiumRate()) {
                subBuilder.mergeFrom(getPremiumRate());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setPremiumRate(subBuilder.buildPartial());
              break;
            }
            case 50: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder();
              if (hasSharedCost()) {
                subBuilder.mergeFrom(getSharedCost());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setSharedCost(subBuilder.buildPartial());
              break;
            }
            case 58: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder();
              if (hasPersonalNumber()) {
                subBuilder.mergeFrom(getPersonalNumber());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setPersonalNumber(subBuilder.buildPartial());
              break;
            }
            case 66: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder();
              if (hasVoip()) {
                subBuilder.mergeFrom(getVoip());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setVoip(subBuilder.buildPartial());
              break;
            }
            case 74: {
              setId(input.readString());
              break;
            }
            case 80: {
              setCountryCode(input.readInt32());
              break;
            }
            case 90: {
              setInternationalPrefix(input.readString());
              break;
            }
            case 98: {
              setNationalPrefix(input.readString());
              break;
            }
            case 106: {
              setPreferredExtnPrefix(input.readString());
              break;
            }
            case 122: {
              setNationalPrefixForParsing(input.readString());
              break;
            }
            case 130: {
              setNationalPrefixTransformRule(input.readString());
              break;
            }
            case 138: {
              setPreferredInternationalPrefix(input.readString());
              break;
            }
            case 144: {
              setSameMobileAndFixedLinePattern(input.readBool());
              break;
            }
            case 154: {
              com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.newBuilder();
              input.readMessage(subBuilder, extensionRegistry);
              addNumberFormat(subBuilder.buildPartial());
              break;
            }
            case 162: {
              com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.newBuilder();
              input.readMessage(subBuilder, extensionRegistry);
              addIntlNumberFormat(subBuilder.buildPartial());
              break;
            }
            case 170: {
              setNationalPrefixFormattingRule(input.readString());
              break;
            }
          }
        }
      }
      
      
      // required .i18n.phonenumbers.PhoneNumberDesc general_desc = 1;
      public boolean hasGeneralDesc() {
        return result.hasGeneralDesc();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getGeneralDesc() {
        return result.getGeneralDesc();
      }
      public Builder setGeneralDesc(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.hasGeneralDesc = true;
        result.generalDesc_ = value;
        return this;
      }
      public Builder setGeneralDesc(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder builderForValue) {
        result.hasGeneralDesc = true;
        result.generalDesc_ = builderForValue.build();
        return this;
      }
      public Builder mergeGeneralDesc(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (result.hasGeneralDesc() &&
            result.generalDesc_ != com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) {
          result.generalDesc_ =
            com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder(result.generalDesc_).mergeFrom(value).buildPartial();
        } else {
          result.generalDesc_ = value;
        }
        result.hasGeneralDesc = true;
        return this;
      }
      public Builder clearGeneralDesc() {
        result.hasGeneralDesc = false;
        result.generalDesc_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
        return this;
      }
      
      // required .i18n.phonenumbers.PhoneNumberDesc fixed_line = 2;
      public boolean hasFixedLine() {
        return result.hasFixedLine();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getFixedLine() {
        return result.getFixedLine();
      }
      public Builder setFixedLine(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.hasFixedLine = true;
        result.fixedLine_ = value;
        return this;
      }
      public Builder setFixedLine(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder builderForValue) {
        result.hasFixedLine = true;
        result.fixedLine_ = builderForValue.build();
        return this;
      }
      public Builder mergeFixedLine(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (result.hasFixedLine() &&
            result.fixedLine_ != com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) {
          result.fixedLine_ =
            com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder(result.fixedLine_).mergeFrom(value).buildPartial();
        } else {
          result.fixedLine_ = value;
        }
        result.hasFixedLine = true;
        return this;
      }
      public Builder clearFixedLine() {
        result.hasFixedLine = false;
        result.fixedLine_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
        return this;
      }
      
      // required .i18n.phonenumbers.PhoneNumberDesc mobile = 3;
      public boolean hasMobile() {
        return result.hasMobile();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getMobile() {
        return result.getMobile();
      }
      public Builder setMobile(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.hasMobile = true;
        result.mobile_ = value;
        return this;
      }
      public Builder setMobile(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder builderForValue) {
        result.hasMobile = true;
        result.mobile_ = builderForValue.build();
        return this;
      }
      public Builder mergeMobile(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (result.hasMobile() &&
            result.mobile_ != com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) {
          result.mobile_ =
            com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder(result.mobile_).mergeFrom(value).buildPartial();
        } else {
          result.mobile_ = value;
        }
        result.hasMobile = true;
        return this;
      }
      public Builder clearMobile() {
        result.hasMobile = false;
        result.mobile_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
        return this;
      }
      
      // required .i18n.phonenumbers.PhoneNumberDesc toll_free = 4;
      public boolean hasTollFree() {
        return result.hasTollFree();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getTollFree() {
        return result.getTollFree();
      }
      public Builder setTollFree(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.hasTollFree = true;
        result.tollFree_ = value;
        return this;
      }
      public Builder setTollFree(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder builderForValue) {
        result.hasTollFree = true;
        result.tollFree_ = builderForValue.build();
        return this;
      }
      public Builder mergeTollFree(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (result.hasTollFree() &&
            result.tollFree_ != com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) {
          result.tollFree_ =
            com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder(result.tollFree_).mergeFrom(value).buildPartial();
        } else {
          result.tollFree_ = value;
        }
        result.hasTollFree = true;
        return this;
      }
      public Builder clearTollFree() {
        result.hasTollFree = false;
        result.tollFree_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
        return this;
      }
      
      // required .i18n.phonenumbers.PhoneNumberDesc premium_rate = 5;
      public boolean hasPremiumRate() {
        return result.hasPremiumRate();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getPremiumRate() {
        return result.getPremiumRate();
      }
      public Builder setPremiumRate(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.hasPremiumRate = true;
        result.premiumRate_ = value;
        return this;
      }
      public Builder setPremiumRate(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder builderForValue) {
        result.hasPremiumRate = true;
        result.premiumRate_ = builderForValue.build();
        return this;
      }
      public Builder mergePremiumRate(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (result.hasPremiumRate() &&
            result.premiumRate_ != com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) {
          result.premiumRate_ =
            com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder(result.premiumRate_).mergeFrom(value).buildPartial();
        } else {
          result.premiumRate_ = value;
        }
        result.hasPremiumRate = true;
        return this;
      }
      public Builder clearPremiumRate() {
        result.hasPremiumRate = false;
        result.premiumRate_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
        return this;
      }
      
      // required .i18n.phonenumbers.PhoneNumberDesc shared_cost = 6;
      public boolean hasSharedCost() {
        return result.hasSharedCost();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getSharedCost() {
        return result.getSharedCost();
      }
      public Builder setSharedCost(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.hasSharedCost = true;
        result.sharedCost_ = value;
        return this;
      }
      public Builder setSharedCost(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder builderForValue) {
        result.hasSharedCost = true;
        result.sharedCost_ = builderForValue.build();
        return this;
      }
      public Builder mergeSharedCost(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (result.hasSharedCost() &&
            result.sharedCost_ != com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) {
          result.sharedCost_ =
            com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder(result.sharedCost_).mergeFrom(value).buildPartial();
        } else {
          result.sharedCost_ = value;
        }
        result.hasSharedCost = true;
        return this;
      }
      public Builder clearSharedCost() {
        result.hasSharedCost = false;
        result.sharedCost_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
        return this;
      }
      
      // required .i18n.phonenumbers.PhoneNumberDesc personal_number = 7;
      public boolean hasPersonalNumber() {
        return result.hasPersonalNumber();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getPersonalNumber() {
        return result.getPersonalNumber();
      }
      public Builder setPersonalNumber(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.hasPersonalNumber = true;
        result.personalNumber_ = value;
        return this;
      }
      public Builder setPersonalNumber(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder builderForValue) {
        result.hasPersonalNumber = true;
        result.personalNumber_ = builderForValue.build();
        return this;
      }
      public Builder mergePersonalNumber(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (result.hasPersonalNumber() &&
            result.personalNumber_ != com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) {
          result.personalNumber_ =
            com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder(result.personalNumber_).mergeFrom(value).buildPartial();
        } else {
          result.personalNumber_ = value;
        }
        result.hasPersonalNumber = true;
        return this;
      }
      public Builder clearPersonalNumber() {
        result.hasPersonalNumber = false;
        result.personalNumber_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
        return this;
      }
      
      // required .i18n.phonenumbers.PhoneNumberDesc voip = 8;
      public boolean hasVoip() {
        return result.hasVoip();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc getVoip() {
        return result.getVoip();
      }
      public Builder setVoip(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.hasVoip = true;
        result.voip_ = value;
        return this;
      }
      public Builder setVoip(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.Builder builderForValue) {
        result.hasVoip = true;
        result.voip_ = builderForValue.build();
        return this;
      }
      public Builder mergeVoip(com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc value) {
        if (result.hasVoip() &&
            result.voip_ != com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance()) {
          result.voip_ =
            com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.newBuilder(result.voip_).mergeFrom(value).buildPartial();
        } else {
          result.voip_ = value;
        }
        result.hasVoip = true;
        return this;
      }
      public Builder clearVoip() {
        result.hasVoip = false;
        result.voip_ = com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc.getDefaultInstance();
        return this;
      }
      
      // required string id = 9;
      public boolean hasId() {
        return result.hasId();
      }
      public java.lang.String getId() {
        return result.getId();
      }
      public Builder setId(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasId = true;
        result.id_ = value;
        return this;
      }
      public Builder clearId() {
        result.hasId = false;
        result.id_ = getDefaultInstance().getId();
        return this;
      }
      
      // required int32 country_code = 10;
      public boolean hasCountryCode() {
        return result.hasCountryCode();
      }
      public int getCountryCode() {
        return result.getCountryCode();
      }
      public Builder setCountryCode(int value) {
        result.hasCountryCode = true;
        result.countryCode_ = value;
        return this;
      }
      public Builder clearCountryCode() {
        result.hasCountryCode = false;
        result.countryCode_ = 0;
        return this;
      }
      
      // required string international_prefix = 11;
      public boolean hasInternationalPrefix() {
        return result.hasInternationalPrefix();
      }
      public java.lang.String getInternationalPrefix() {
        return result.getInternationalPrefix();
      }
      public Builder setInternationalPrefix(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasInternationalPrefix = true;
        result.internationalPrefix_ = value;
        return this;
      }
      public Builder clearInternationalPrefix() {
        result.hasInternationalPrefix = false;
        result.internationalPrefix_ = getDefaultInstance().getInternationalPrefix();
        return this;
      }
      
      // optional string preferred_international_prefix = 17;
      public boolean hasPreferredInternationalPrefix() {
        return result.hasPreferredInternationalPrefix();
      }
      public java.lang.String getPreferredInternationalPrefix() {
        return result.getPreferredInternationalPrefix();
      }
      public Builder setPreferredInternationalPrefix(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasPreferredInternationalPrefix = true;
        result.preferredInternationalPrefix_ = value;
        return this;
      }
      public Builder clearPreferredInternationalPrefix() {
        result.hasPreferredInternationalPrefix = false;
        result.preferredInternationalPrefix_ = getDefaultInstance().getPreferredInternationalPrefix();
        return this;
      }
      
      // optional string national_prefix = 12;
      public boolean hasNationalPrefix() {
        return result.hasNationalPrefix();
      }
      public java.lang.String getNationalPrefix() {
        return result.getNationalPrefix();
      }
      public Builder setNationalPrefix(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasNationalPrefix = true;
        result.nationalPrefix_ = value;
        return this;
      }
      public Builder clearNationalPrefix() {
        result.hasNationalPrefix = false;
        result.nationalPrefix_ = getDefaultInstance().getNationalPrefix();
        return this;
      }
      
      // optional string preferred_extn_prefix = 13;
      public boolean hasPreferredExtnPrefix() {
        return result.hasPreferredExtnPrefix();
      }
      public java.lang.String getPreferredExtnPrefix() {
        return result.getPreferredExtnPrefix();
      }
      public Builder setPreferredExtnPrefix(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasPreferredExtnPrefix = true;
        result.preferredExtnPrefix_ = value;
        return this;
      }
      public Builder clearPreferredExtnPrefix() {
        result.hasPreferredExtnPrefix = false;
        result.preferredExtnPrefix_ = getDefaultInstance().getPreferredExtnPrefix();
        return this;
      }
      
      // optional string national_prefix_for_parsing = 15;
      public boolean hasNationalPrefixForParsing() {
        return result.hasNationalPrefixForParsing();
      }
      public java.lang.String getNationalPrefixForParsing() {
        return result.getNationalPrefixForParsing();
      }
      public Builder setNationalPrefixForParsing(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasNationalPrefixForParsing = true;
        result.nationalPrefixForParsing_ = value;
        return this;
      }
      public Builder clearNationalPrefixForParsing() {
        result.hasNationalPrefixForParsing = false;
        result.nationalPrefixForParsing_ = getDefaultInstance().getNationalPrefixForParsing();
        return this;
      }
      
      // optional string national_prefix_transform_rule = 16;
      public boolean hasNationalPrefixTransformRule() {
        return result.hasNationalPrefixTransformRule();
      }
      public java.lang.String getNationalPrefixTransformRule() {
        return result.getNationalPrefixTransformRule();
      }
      public Builder setNationalPrefixTransformRule(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasNationalPrefixTransformRule = true;
        result.nationalPrefixTransformRule_ = value;
        return this;
      }
      public Builder clearNationalPrefixTransformRule() {
        result.hasNationalPrefixTransformRule = false;
        result.nationalPrefixTransformRule_ = getDefaultInstance().getNationalPrefixTransformRule();
        return this;
      }
      
      // optional bool same_mobile_and_fixed_line_pattern = 18 [default = false];
      public boolean hasSameMobileAndFixedLinePattern() {
        return result.hasSameMobileAndFixedLinePattern();
      }
      public boolean getSameMobileAndFixedLinePattern() {
        return result.getSameMobileAndFixedLinePattern();
      }
      public Builder setSameMobileAndFixedLinePattern(boolean value) {
        result.hasSameMobileAndFixedLinePattern = true;
        result.sameMobileAndFixedLinePattern_ = value;
        return this;
      }
      public Builder clearSameMobileAndFixedLinePattern() {
        result.hasSameMobileAndFixedLinePattern = false;
        result.sameMobileAndFixedLinePattern_ = false;
        return this;
      }
      
      // repeated .i18n.phonenumbers.NumberFormat number_format = 19;
      public java.util.List<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat> getNumberFormatList() {
        return java.util.Collections.unmodifiableList(result.numberFormat_);
      }
      public int getNumberFormatCount() {
        return result.getNumberFormatCount();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.NumberFormat getNumberFormat(int index) {
        return result.getNumberFormat(index);
      }
      public Builder setNumberFormat(int index, com.google.i18n.phonenumbers.Phonemetadata.NumberFormat value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.numberFormat_.set(index, value);
        return this;
      }
      public Builder setNumberFormat(int index, com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.Builder builderForValue) {
        result.numberFormat_.set(index, builderForValue.build());
        return this;
      }
      public Builder addNumberFormat(com.google.i18n.phonenumbers.Phonemetadata.NumberFormat value) {
        if (value == null) {
          throw new NullPointerException();
        }
        if (result.numberFormat_.isEmpty()) {
          result.numberFormat_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat>();
        }
        result.numberFormat_.add(value);
        return this;
      }
      public Builder addNumberFormat(com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.Builder builderForValue) {
        if (result.numberFormat_.isEmpty()) {
          result.numberFormat_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat>();
        }
        result.numberFormat_.add(builderForValue.build());
        return this;
      }
      public Builder addAllNumberFormat(
          java.lang.Iterable<? extends com.google.i18n.phonenumbers.Phonemetadata.NumberFormat> values) {
        if (result.numberFormat_.isEmpty()) {
          result.numberFormat_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat>();
        }
        super.addAll(values, result.numberFormat_);
        return this;
      }
      public Builder clearNumberFormat() {
        result.numberFormat_ = java.util.Collections.emptyList();
        return this;
      }
      
      // repeated .i18n.phonenumbers.NumberFormat intl_number_format = 20;
      public java.util.List<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat> getIntlNumberFormatList() {
        return java.util.Collections.unmodifiableList(result.intlNumberFormat_);
      }
      public int getIntlNumberFormatCount() {
        return result.getIntlNumberFormatCount();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.NumberFormat getIntlNumberFormat(int index) {
        return result.getIntlNumberFormat(index);
      }
      public Builder setIntlNumberFormat(int index, com.google.i18n.phonenumbers.Phonemetadata.NumberFormat value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.intlNumberFormat_.set(index, value);
        return this;
      }
      public Builder setIntlNumberFormat(int index, com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.Builder builderForValue) {
        result.intlNumberFormat_.set(index, builderForValue.build());
        return this;
      }
      public Builder addIntlNumberFormat(com.google.i18n.phonenumbers.Phonemetadata.NumberFormat value) {
        if (value == null) {
          throw new NullPointerException();
        }
        if (result.intlNumberFormat_.isEmpty()) {
          result.intlNumberFormat_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat>();
        }
        result.intlNumberFormat_.add(value);
        return this;
      }
      public Builder addIntlNumberFormat(com.google.i18n.phonenumbers.Phonemetadata.NumberFormat.Builder builderForValue) {
        if (result.intlNumberFormat_.isEmpty()) {
          result.intlNumberFormat_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat>();
        }
        result.intlNumberFormat_.add(builderForValue.build());
        return this;
      }
      public Builder addAllIntlNumberFormat(
          java.lang.Iterable<? extends com.google.i18n.phonenumbers.Phonemetadata.NumberFormat> values) {
        if (result.intlNumberFormat_.isEmpty()) {
          result.intlNumberFormat_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.NumberFormat>();
        }
        super.addAll(values, result.intlNumberFormat_);
        return this;
      }
      public Builder clearIntlNumberFormat() {
        result.intlNumberFormat_ = java.util.Collections.emptyList();
        return this;
      }
      
      // optional string national_prefix_formatting_rule = 21;
      public boolean hasNationalPrefixFormattingRule() {
        return result.hasNationalPrefixFormattingRule();
      }
      public java.lang.String getNationalPrefixFormattingRule() {
        return result.getNationalPrefixFormattingRule();
      }
      public Builder setNationalPrefixFormattingRule(java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  result.hasNationalPrefixFormattingRule = true;
        result.nationalPrefixFormattingRule_ = value;
        return this;
      }
      public Builder clearNationalPrefixFormattingRule() {
        result.hasNationalPrefixFormattingRule = false;
        result.nationalPrefixFormattingRule_ = getDefaultInstance().getNationalPrefixFormattingRule();
        return this;
      }
      
      // @@protoc_insertion_point(builder_scope:i18n.phonenumbers.PhoneMetadata)
    }
    
    static {
      defaultInstance = new PhoneMetadata(true);
      com.google.i18n.phonenumbers.Phonemetadata.internalForceInit();
      defaultInstance.initFields();
    }
    
    // @@protoc_insertion_point(class_scope:i18n.phonenumbers.PhoneMetadata)
  }
  
  public static final class PhoneMetadataCollection extends
      com.google.protobuf.GeneratedMessageLite {
    // Use PhoneMetadataCollection.newBuilder() to construct.
    private PhoneMetadataCollection() {
      initFields();
    }
    private PhoneMetadataCollection(boolean noInit) {}
    
    private static final PhoneMetadataCollection defaultInstance;
    public static PhoneMetadataCollection getDefaultInstance() {
      return defaultInstance;
    }
    
    public PhoneMetadataCollection getDefaultInstanceForType() {
      return defaultInstance;
    }
    
    // repeated .i18n.phonenumbers.PhoneMetadata metadata = 1;
    public static final int METADATA_FIELD_NUMBER = 1;
    private java.util.List<com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata> metadata_ =
      java.util.Collections.emptyList();
    public java.util.List<com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata> getMetadataList() {
      return metadata_;
    }
    public int getMetadataCount() { return metadata_.size(); }
    public com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata getMetadata(int index) {
      return metadata_.get(index);
    }
    
    private void initFields() {
    }
    public final boolean isInitialized() {
      for (com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata element : getMetadataList()) {
        if (!element.isInitialized()) return false;
      }
      return true;
    }
    
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata element : getMetadataList()) {
        output.writeMessage(1, element);
      }
    }
    
    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;
    
      size = 0;
      for (com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata element : getMetadataList()) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, element);
      }
      memoizedSerializedSize = size;
      return size;
    }
    
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    
    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }
    
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageLite.Builder<
          com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection, Builder> {
      private com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection result;
      
      // Construct using com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection.newBuilder()
      private Builder() {}
      
      private static Builder create() {
        Builder builder = new Builder();
        builder.result = new com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection();
        return builder;
      }
      
      protected com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection internalGetResult() {
        return result;
      }
      
      public Builder clear() {
        if (result == null) {
          throw new IllegalStateException(
            "Cannot call clear() after build().");
        }
        result = new com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection();
        return this;
      }
      
      public Builder clone() {
        return create().mergeFrom(result);
      }
      
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection getDefaultInstanceForType() {
        return com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection.getDefaultInstance();
      }
      
      public boolean isInitialized() {
        return result.isInitialized();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection build() {
        if (result != null && !isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return buildPartial();
      }
      
      private com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        if (!isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return buildPartial();
      }
      
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection buildPartial() {
        if (result == null) {
          throw new IllegalStateException(
            "build() has already been called on this Builder.");
        }
        if (result.metadata_ != java.util.Collections.EMPTY_LIST) {
          result.metadata_ =
            java.util.Collections.unmodifiableList(result.metadata_);
        }
        com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection returnMe = result;
        result = null;
        return returnMe;
      }
      
      public Builder mergeFrom(com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection other) {
        if (other == com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection.getDefaultInstance()) return this;
        if (!other.metadata_.isEmpty()) {
          if (result.metadata_.isEmpty()) {
            result.metadata_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata>();
          }
          result.metadata_.addAll(other.metadata_);
        }
        return this;
      }
      
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              return this;
            default: {
              if (!parseUnknownField(input, extensionRegistry, tag)) {
                return this;
              }
              break;
            }
            case 10: {
              com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata.Builder subBuilder = com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata.newBuilder();
              input.readMessage(subBuilder, extensionRegistry);
              addMetadata(subBuilder.buildPartial());
              break;
            }
          }
        }
      }
      
      
      // repeated .i18n.phonenumbers.PhoneMetadata metadata = 1;
      public java.util.List<com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata> getMetadataList() {
        return java.util.Collections.unmodifiableList(result.metadata_);
      }
      public int getMetadataCount() {
        return result.getMetadataCount();
      }
      public com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata getMetadata(int index) {
        return result.getMetadata(index);
      }
      public Builder setMetadata(int index, com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata value) {
        if (value == null) {
          throw new NullPointerException();
        }
        result.metadata_.set(index, value);
        return this;
      }
      public Builder setMetadata(int index, com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata.Builder builderForValue) {
        result.metadata_.set(index, builderForValue.build());
        return this;
      }
      public Builder addMetadata(com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata value) {
        if (value == null) {
          throw new NullPointerException();
        }
        if (result.metadata_.isEmpty()) {
          result.metadata_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata>();
        }
        result.metadata_.add(value);
        return this;
      }
      public Builder addMetadata(com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata.Builder builderForValue) {
        if (result.metadata_.isEmpty()) {
          result.metadata_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata>();
        }
        result.metadata_.add(builderForValue.build());
        return this;
      }
      public Builder addAllMetadata(
          java.lang.Iterable<? extends com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata> values) {
        if (result.metadata_.isEmpty()) {
          result.metadata_ = new java.util.ArrayList<com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata>();
        }
        super.addAll(values, result.metadata_);
        return this;
      }
      public Builder clearMetadata() {
        result.metadata_ = java.util.Collections.emptyList();
        return this;
      }
      
      // @@protoc_insertion_point(builder_scope:i18n.phonenumbers.PhoneMetadataCollection)
    }
    
    static {
      defaultInstance = new PhoneMetadataCollection(true);
      com.google.i18n.phonenumbers.Phonemetadata.internalForceInit();
      defaultInstance.initFields();
    }
    
    // @@protoc_insertion_point(class_scope:i18n.phonenumbers.PhoneMetadataCollection)
  }
  
  
  static {
  }
  
  public static void internalForceInit() {}
  
  // @@protoc_insertion_point(outer_class_scope)
}
